Community
    • Login

    How to start a search automatically

    Scheduled Pinned Locked Moved Help wanted · · · – – – · · ·
    41 Posts 7 Posters 5.9k Views
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • PeterJonesP
      PeterJones @Alan Kilborn
      last edited by

      @Alan-Kilborn said in How to start a search automatically:

      But could you do it ALL, from end-to-end, with just SendMessage calls?

      I guess that is a good caveat to what I said. The SendMessage interface will be how it communicates instructions to Notepad++ and/or the embedded Scintilla. But the script or program (whether it’s PythonScript, my external Perl interface, or writing your own SendMessage commands from external or plugin C/C++/C#/…) will also have to do other things, especially the search-and-replace in the text. Or the script/app could trigger calling a macro which has the search/replace call already embedded.

      (In Perl, I’d do it with Perl’s built-in regex handling on the text from SCI_GETTEXT – or calling the macro, if you wanted to go that way. In PythonScript, I’d use its editor.rereplace() helper method, which makes full-text search-and-replace easy. I wouldn’t personally do text processing in C-family languages, if I could help it; though if you had the boost library or similar available to you, it wouldn’t be as bad.)

      Alan KilbornA 1 Reply Last reply Reply Quote 2
      • Alan KilbornA
        Alan Kilborn @PeterJones
        last edited by

        Some things to be aware of with the -z approach (which was already in my mind for this):

        • It probably only works when N++ is not currently running. Not sure of what the OP’s need is in this regard…

        • Specifying a search string on the command-line may be a bit “dicey” if the search string is long, complicated or contains “special characters”. Again, not sure of what the OP’s need is in this regard…

        So before we’d be expending effort to assist, I’d like to see the OP flesh out the need with a full example scenario. Much like a poorly-specified regex problem, I could easily see some effort put in only to have OP come back and say “Oh…I really wanted/needed THIS and you gave me THAT” even though THAT was the only thing previously specified.

        1 Reply Last reply Reply Quote 2
        • Alan KilbornA
          Alan Kilborn @PeterJones
          last edited by

          @PeterJones said in How to start a search automatically:

          Or the script/app could trigger calling a macro which has the search/replace call already embedded.

          But that would require the search text to be fixed, which I seriously doubt is what OP intends.

          OP needs to speak! :-)

          1 Reply Last reply Reply Quote 1
          • kaifuziK
            kaifuzi @PeterJones
            last edited by

            @PeterJones At first, I’d like to try SendMessage without PythonScript plugin. Because I don’t want to ask normal users to do this extra step.
            Here are the steps what I’m thinking:

            1. Using ShellExecute to start Notepad++ and open a certain file.
            2. Using SendMessage to start Search
            3. Using SendMessage to send search string to the Search text box
            4. Find all in current document.
              I’m not sure I can do it successfully by myself…
            PeterJonesP Alan KilbornA 2 Replies Last reply Reply Quote 0
            • PeterJonesP
              PeterJones @kaifuzi
              last edited by

              @kaifuzi ,

              Based on that description – wanting to run an external program which will launch Notepad++ and fill out dialogs manually, just to edit the file for the user – I am not sure why you don’t want to just create an application that will open the file itself (without Notepad++), do the search-and-replace, save the file, and then launch Notepad++ to open the results of that already-accomplished substitution.

              For example, using a batch file to launch Perl, I could do something as simple as:

              perl -pi -e "s/PERL REGEX/REPLACEMENT/g" "%1"
              notepad++.exe "%1"
              

              If your “replacement” was really more complicated than that, you could write as much perl as you needed to accomplish that task (and use the appropriate perl command-line sytnax to launch a script rather than the one-liner shown).

              (And before you say, “but I don’t want normal users to have to install Perl any more than I want them to install a plugin for Notepad++”: there are ways to compile perl – well outside the scope of this Notepad++ forum – or you could use any compilable language you were more familiar with to make this search-replace-and-launch app.)

              If you really want to do things the hard way, you manually craft all the SendMessage commands (the NPPM_MENUCOMMAND would be what you would use to launch the arbitrary menu command – in this case, the replace dialog), and then figure out how to navigate through the Search dialog’s various entry fields using Microsoft’s standard dialog access messages. But that doesn’t sound fun to me.

              And there are libraries designed for testing GUI applications, which can be used equally well to just remote-control an app, accessing its menus and dialog fields, etc. I don’t know what those libraries would be for C-family, but Perl has Win32::GuiTest (which is what I use for testing my Perl-based Notepad++ automation library).

              I think the best options for you:

              1. it would be easiest, really, to just tell users to "launch Notepad++, do Search > Replace, type xxx in the find and yyy in the replace, tick these options, and click Replace All
              2. Write the replacement yourself using your favorite programming language and the search-replace you’re most familiar with, generating an .exe which will do the edits then launches Notepad++ on the already-edited file to use as the viewer (or for them to continuing to edit); then somehow convince your users to use this launcher under the appropriate circumstances.
              3. Write a custom Plugin which is watching for a -z -autoreplace command line option; this might be more complicated for you, but it would be easier than helping your users through the PythonScript solution, since there are more steps than just installing PythonScript plugin in order to set things up).
              4. Write a script using PythonScript which does it, install it; create a zipfile distribution which includes Notepad++ pre-installed with PythonScript and this script already set up, and tell your users that they have to use your distribution of Notepad++ to have the feature you want them to have
              5. Write the PythonScript, and explain users how to set it up.

              Of course, if the search/replace expression is always the same, you could do a modified #4, which is create a pre-bundled Notepad++ zip which includes the search-and-replace macro already recorded, assigned to a simple-to-remember keystroke, and just tell your users “run Notepad++, open the file, and hit Ctrl-Alt-Shift-F12” or what have you.

              Alan KilbornA 1 Reply Last reply Reply Quote 1
              • Alan KilbornA
                Alan Kilborn @PeterJones
                last edited by Alan Kilborn

                @PeterJones

                …do the search-and-replace…

                Not sure the OP ever said anything about a replacement.
                Appears they just want a Find All in Current Document to have those search results pre-run and populated.

                PeterJonesP kaifuziK 2 Replies Last reply Reply Quote 2
                • PeterJonesP
                  PeterJones @Alan Kilborn
                  last edited by

                  @Alan-Kilborn said in How to start a search automatically:

                  Not sure the OP ever said anything about a replacement.

                  You’re right, in OP posts, I only see “search”, not “replace”. That was my addition.

                  @kaifuzi ,

                  With that clarification, I will sum up my position:

                  • Notepad++ doesn’t natively allow for automation of the search action from startup
                  • PythonScript is the simplest solution to implement, but you seem to reject that extra step
                    • if you are willing to use this solution, @Alan-Kilborn appears willing to give you a starting script; but he doesn’t look like he’ll put in the effort if it’s not likely you’ll use it
                  • it might be possible with SendMessages
                    • I’ve pointed you to the Notepad+±specific messages, especially the one for launching the Search dialog via a menu command
                    • for manipulating the contents of the search dialog window, there are Windows messages which can handle that, assuming you can figure out the control IDs and craft the appropriate instructions to those dialog elements
                    • this is a complicated solution, and I don’t have the time to do more research to hand it to you. If you can’t “do it successfully by [yourself]”, this may not be the best solution for you
                  • if the search term is fixed, then you can record a macro, and even distribute the XML for that macro, and explain the steps to your users on how to edit their shortcuts.xml and run the macro themselves – not quite as automatic, but it’s the easiest to implement, overall, IMO.
                  1 Reply Last reply Reply Quote 1
                  • kaifuziK
                    kaifuzi @Alan Kilborn
                    last edited by

                    @Alan-Kilborn @PeterJones Now I can use FindWindow to get Notepad++ window handle, and I can send message by SendMessage, but I checked the manual, there is only message NPPM_LAUNCHFINDINFILESDLG which I can find, I can’t use it to find all in current document. Do you have any idea? Thanks!

                    PeterJonesP 1 Reply Last reply Reply Quote 0
                    • Alan KilbornA
                      Alan Kilborn @kaifuzi
                      last edited by Alan Kilborn

                      @kaifuzi said in How to start a search automatically:

                      Using ShellExecute to start Notepad++ and open a certain file.
                      Using SendMessage to start Search
                      Using SendMessage to send search string to the Search text box
                      Find all in current document.

                      I may be more optimistic about this sequencing description. :-)
                      It seems doable, but of course I am thinking about it from a Pythonscript perspective, not a purely “SendMessage” approach…
                      If you have questions about specific portions as you do it, just fire away and we’ll try to answer.

                      1 Reply Last reply Reply Quote 0
                      • PeterJonesP
                        PeterJones @kaifuzi
                        last edited by PeterJones

                        @kaifuzi said in How to start a search automatically:

                        NPPM_LAUNCHFINDINFILESDLG

                        Notepad++ was not written with scripted control of the search dialog in mind.

                        As I’ve said, you can use NPPM_MENUCOMMAND to launch any menu entry; the menuCmdID.h file in sourcecode shows all the menu command IDs that you would pass to the message. However, that just opens the dialog, it won’t let you populate it.

                        There are other Windows API commands you could use to explore that dialog and fill it out, but it’s more complicated than we can help you through – those steps would be the same no matter what application the dialog is in, so it’s a general programming question, rather than Notepad++ specific. That’s where a GuiTest-style library would come in handy. We cannot write that for you.

                        Again, if you are just using a fixed search string – always the same for every user – then recording and sharing the macro would seem the easiest solution.

                        Alan KilbornA 1 Reply Last reply Reply Quote 1
                        • Alan KilbornA
                          Alan Kilborn @PeterJones
                          last edited by PeterJones

                          @PeterJones said in How to start a search automatically:

                          However, that just opens the dialog, it won’t let you populate it.

                          You can populate it after you get a handle to it, using the dialog control IDs in FindReplaceDlg_rc.h.
                          Set up your search text (still not 100% how you obtain that, in the final solution…) and then use code to “press” the Find All in Current Document button.
                          It doesn’t sound “horrible”, but a bit of a devil in the details.

                          if you are just using a fixed search string – always the same for every user – then recording and sharing the macro would seem the easiest solution.

                          I continue to get the feeling that this is NOT the case.

                          PeterJonesP 1 Reply Last reply Reply Quote 2
                          • PeterJonesP
                            PeterJones @Alan Kilborn
                            last edited by

                            @Alan-Kilborn said in How to start a search automatically:

                            You can populate it after you get a handle to it, using the dialog control IDs in FindReplaceDlg_rc.h.

                            I had never noticed that before. And now I know where the 1700 and similar IDs come from, as referenced in the search-and-replace macros docs. Thanks!

                            I continue to get the feeling that this is NOT the case.

                            And the OP continues to be mum on the subject, neither confirming nor denying, no matter how many times it is brought up. It is an answer that would definitely help craft any future discussion.

                            However, at this point, I probably won’t weigh in much more, because you seem to understand the OP’s desires better than I do, and I don’t want to get in the way or muddle things any more.

                            kaifuziK 1 Reply Last reply Reply Quote 1
                            • kaifuziK
                              kaifuzi @PeterJones
                              last edited by

                              @PeterJones @Alan-Kilborn I did it, thanks a lot for your help!!!
                              I use FindWindow and FindWindowEx to get window handles which I need, then I use SendMessage to control them, with NPPM_MENUCOMMAND I can open Find dialog.

                              kaifuziK Alan KilbornA 2 Replies Last reply Reply Quote 2
                              • kaifuziK
                                kaifuzi @kaifuzi
                                last edited by

                                @Alan-Kilborn @PeterJones In fact, I sitll have a small issue. When I use ShellExexute to open a file by Notepad++, I don’t know when it’s ready, I mean I can get the handle of Notepad++. So I use a loop to wait, once the handle value of Notepad++ is greater than 0, then I think Notepad++ it’s ready, then I can start search. I’m not sure is there any other best way.

                                Alan KilbornA 1 Reply Last reply Reply Quote 0
                                • Alan KilbornA
                                  Alan Kilborn @kaifuzi
                                  last edited by

                                  @kaifuzi said in How to start a search automatically:

                                  I did it, thanks a lot for your help!!!

                                  Well, that’s good.
                                  It is sort of tradition to provide more details in the form of code about your working solution, for those that read this later wanting to do the same or a similar thing.
                                  Not mandatory, though.

                                  kaifuziK 1 Reply Last reply Reply Quote 2
                                  • kaifuziK
                                    kaifuzi @Alan Kilborn
                                    last edited by

                                    @Alan-Kilborn Yes, that’s good, I will post my code in there. I did it in VB.net, same for C#.

                                    1 Reply Last reply Reply Quote 1
                                    • kaifuziK
                                      kaifuzi
                                      last edited by

                                      Public Sub NppFindAllInCurDoc(ByVal fileFullPath As String, ByVal searchString As String)
                                          Dim i As Integer = 0
                                          Dim hNppWnd As IntPtr = IntPtr.Zero
                                          While CInt(hNppWnd) = 0
                                              hNppWnd = FindWindow("Notepad++", fileFullPath & " - Notepad++")  'Notepad++ handle
                                              i += 1
                                              If i > 10 ^ 5 Then
                                                  MsgBox("Timeout!" & Environment.NewLine & "Please run this command again.", MsgBoxStyle.Exclamation, "Warning")
                                                  Exit While
                                              End If
                                          End While
                                      
                                          If CInt(hNppWnd) > 0 Then
                                              'Open find dialog
                                              SendMessage(hNppWnd, NppMessage.NPPM_MENUCOMMAND, 0, New IntPtr(NppCmdID.IDM_SEARCH_FIND))
                                              'Get find dialog
                                              Dim hFindWnd As IntPtr = IntPtr.Zero
                                              Dim hChildWnd As IntPtr = IntPtr.Zero
                                              hFindWnd = FindWindow("#32770", "Find")  'Find dialog handle
                                              hChildWnd = FindWindowEx(hFindWnd, IntPtr.Zero, "ComboBox", vbNullString)
                                              hChildWnd = FindWindowEx(hChildWnd, IntPtr.Zero, "Edit", vbNullString)
                                              SendMessage(hChildWnd, WindowMessage.WM_SETTEXT, 0, searchString)
                                              'Start search
                                              hChildWnd = FindWindowEx(hFindWnd, IntPtr.Zero, "Button", "Find All in Current &Document")
                                              SendMessage(hChildWnd, WindowMessage.BM_CLICK, 0, IntPtr.Zero)
                                          End If
                                      End Sub
                                      
                                      1 Reply Last reply Reply Quote 2
                                      • Alan KilbornA
                                        Alan Kilborn @kaifuzi
                                        last edited by

                                        @kaifuzi said in How to start a search automatically:

                                        When I use ShellExexute to open a file by Notepad++, I don’t know when it’s ready, I mean I can get the handle of Notepad++. So I use a loop to wait, once the handle value of Notepad++ is greater than 0, then I think Notepad++ it’s ready, then I can start search.

                                        It appears from your code that you found a solution to this?

                                        kaifuziK 1 Reply Last reply Reply Quote 0
                                        • kaifuziK
                                          kaifuzi @Alan Kilborn
                                          last edited by

                                          @Alan-Kilborn Yes, in my code, I use a loop to wait the Notepad++ handle. But I don’t think this is a good solution:

                                          Dim hNppWnd As IntPtr = IntPtr.Zero
                                          While CInt(hNppWnd) = 0
                                              hNppWnd = FindWindow("Notepad++", fileFullPath & " - Notepad++")  'Notepad++ handle
                                              i += 1
                                              If i > 10 ^ 5 Then
                                                  MsgBox("Timeout!" & Environment.NewLine & "Please run this command again.", MsgBoxStyle.Exclamation, "Warning")
                                                  Exit While
                                              End If
                                          End While
                                          
                                          PeterJonesP 1 Reply Last reply Reply Quote 1
                                          • PeterJonesP
                                            PeterJones @kaifuzi
                                            last edited by

                                            @kaifuzi ,

                                            I use a loop to wait the Notepad++ handle. But I don’t think this is a good solution

                                            Waiting for a handle is not bad practice. In the Perl Win32::GuiTest library previously mentioned, two of the commonly-used wrapper functions are WaitWindow and WaitWindowLike, which wrap around the FindWindow interface, like you’ve done. That’s really the best way to make sure the Window exists after you’ve created it.

                                            Unfortunately, there isn’t a similar “it exists, but is it ready for me?” call. Sometimes, I’ve found that trying to edit the text or launch menus immediately after the window exists will intermittently fail; in those cases, I add a 100ms or 1s delay (normally, what I’m automating in Notepad++ isn’t time critical; one second difference doesn’t matter).

                                            So I think wait-for-hwnd is a good first step; if that’s not sufficient, wait a bit after you have the handle before trying to do something with it.

                                            kaifuziK 1 Reply Last reply Reply Quote 2
                                            • First post
                                              Last post
                                            The Community of users of the Notepad++ text editor.
                                            Powered by NodeBB | Contributors