Community
    • Login

    Finding available shortcut keys (originally "Where's the 'New Window' command?")

    Scheduled Pinned Locked Moved Help wanted · · · – – – · · ·
    53 Posts 7 Posters 5.8k 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 @PeterJones
      last edited by PeterJones

      @PeterJones said in Finding available shortcut keys (originally “Where’s the ‘New Window’ command?”):

      free-form editor.input() calls

      It was pointed out to me that it should have said notepad.prompt() . sorry for the confusion. I have updated the original post to not confuse future readers.

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

        @Ekopalypse said in Finding available shortcut keys (originally “Where’s the ‘New Window’ command?”):

        You can also build your own dialogs with the included Tkinter module

        For me, this approach is just “too much” as in “complication” but to each his own. Maybe I’ve just never liked Tkinter in general.

        I don’t know, I’ve felt that the “mini UIs” I’ve been able to create with the notepad.prompt() window are lightweight and workable… A classic example would be in this THREAD; see the script in the Dec 16, 2017, 11:03 PM posting.

        EkopalypseE 1 Reply Last reply Reply Quote 1
        • PeterJonesP
          PeterJones @Ekopalypse
          last edited by

          @Ekopalypse ,

          Was your screenshot created with the Tkinter library, or with raw calls to the TaskDialog? If with raw calls, could you share the code (as a gist if it’s too long to fit nicely in the forum)?

          EkopalypseE 1 Reply Last reply Reply Quote 0
          • EkopalypseE
            Ekopalypse @Alan Kilborn
            last edited by

            @Alan-Kilborn

            I don’t use Tkinter either, but as you said it is an alternative.
            90% of my scripts I use have a configuration section, so no dialog at all. The rest use dialogs like the task dialog.
            Just my preference - could be done differently.

            @PeterJones

            The screenshot with the TaskDialog was created with ctypes and the corresponding Win32 API calls.
            Give me a few minutes to create a standalone, callable version. I’ll post the link to the gist once I’m done.

            1 Reply Last reply Reply Quote 1
            • EkopalypseE
              Ekopalypse @PeterJones
              last edited by

              @PeterJones

              tested with PS 2 and 3.
              Note the comment on FindResourceExA
              If something is unclear, let me know.

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

                @Ekopalypse said:

                (provided code link)
                tested with PS 2 and 3.
                Note the comment on FindResourceExA
                If something is unclear, let me know.

                I’m sure it works great.
                IMO though, it seems “heavy”.
                But…it depends on how much effort one wants to put in, I guess.

                I mean, that is a lot of lines of code, just for a UI for a script.
                When considering that the non-UI part of the code is only going to add to that already large line count, well…

                Also, there’s no “edit box” type of input demo’d, which seems kind of important when one considers what we’ve been able to do in the past to gather user input from the workhorse notepad.prompt() function.

                This is by no means an insult to the code provided, just some comments…

                EkopalypseE 1 Reply Last reply Reply Quote 1
                • EkopalypseE
                  Ekopalypse @Alan Kilborn
                  last edited by

                  @Alan-Kilborn

                  Yes, it is larger than a “prompt” solution, and the TaskDialog is strictly defined by MS. You can only have what it provides.

                  If you want a custom dialog, you have to wrap DialogBoxes
                  but that is just as heavy, if not heavier, than the TaskDialog.

                  The prompt solution may be fine for simple scripts, but as soon as you need to parameterize a script with different settings depending on different models, it is much easier to use a guided dialog, at least in my opinion.

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

                    @Ekopalypse said in Finding available shortcut keys (originally “Where’s the ‘New Window’ command?”):

                    The prompt solution may be fine for simple scripts

                    “Simple” scripts are really all we should be doing, with a tool such as the PythonScript plugin.

                    Of course, and probably more of late, some of mine haven’t exactly been “simple”, so I’m a violator of my above edict. :-)

                    And maybe sadly, I’ve got a doozy in the in-progress pipeline. Maybe my excuse for it is, let’s push the limits of a PS.

                    But maybe my overall point is, if I can keep the UI relatively simple-minded, I can spend more time on the “meat” of whatever the script is trying to accomplish.

                    Others can go off and make the UI part as polished (and as complicated and lengthy) as they want to, in their own scripts.

                    EkopalypseE 1 Reply Last reply Reply Quote 2
                    • EkopalypseE
                      Ekopalypse @Alan Kilborn
                      last edited by

                      @Alan-Kilborn said in Finding available shortcut keys (originally “Where’s the ‘New Window’ command?”):

                      Of course, and probably more of late, some of mine haven’t exactly been “simple”

                      :-D for sure !! :-D

                      1 Reply Last reply Reply Quote 2
                      • TBugReporterT
                        TBugReporter @TBugReporter
                        last edited by

                        @Ekopalypse said in Finding available shortcut keys (originally "Where's the 'New Window' command?"):

                        As for sys.exit, I found out that calling a “main” function and returning from that function serve the same purpose.

                        Due to the scope errors I’ve been getting, I decided to forego that, and just put everything as immediate commands.

                        @Alan-Kilborn said in Finding available shortcut keys (originally “Where’s the ‘New Window’ command?”):

                        I’m sure it works great.
                        IMO though, it seems “heavy”.

                        At 445 lines for do-nothing sample code, “heavy” seems an understatement. 😁

                        @TBugReporter said in Finding available shortcut keys (originally “Where’s the ‘New Window’ command?”):

                        How can I prematurely end my script (if something weird happens)?

                        Here’s what I came up with for this:

                        def bailout(msg):                               # routine to display error message and exit
                            print(msg)                                  # duplicate msg to console
                            notepad.messageBox(msg, "Error", 0)
                            user32.keybd_event(VK_MENU,   0, 0,     0)  # press alt key
                            user32.keybd_event(VK_P,      0, 0,     0)  # press P key (to activate "Plugins" menu)
                            user32.keybd_event(VK_P,      0, KEYUP, 0)  # release P key
                            user32.keybd_event(VK_MENU,   0, KEYUP, 0)  # release alt key
                            user32.keybd_event(VK_P,      0, 0,     0)  # press P key (to activate "Python Script" submenu)
                            # above assumes no other Plugins starting with "P" are installed
                            user32.keybd_event(VK_P,      0, KEYUP, 0)  # release P key
                            user32.keybd_event(VK_RIGHT,  0, 0,     0)  # press cursor right key (to enter submenu)
                            user32.keybd_event(VK_RIGHT,  0, KEYUP, 0)  # release cursor right key
                            user32.keybd_event(VK_DOWN,   0, 0,     0)  # press cursor down key
                            user32.keybd_event(VK_DOWN,   0, KEYUP, 0)  # release cursor down key
                            user32.keybd_event(VK_DOWN,   0, 0,     0)  # press cursor down key again (to move to "Stop Script")
                            user32.keybd_event(VK_DOWN,   0, KEYUP, 0)  # release cursor down key
                            user32.keybd_event(VK_RETURN, 0, 0,     0)  # press enter key
                            user32.keybd_event(VK_RETURN, 0, KEYUP, 0)  # release enter key
                        
                        EkopalypseE 1 Reply Last reply Reply Quote 0
                        • EkopalypseE
                          Ekopalypse @TBugReporter
                          last edited by

                          @TBugReporter

                          … or you could have used

                          notepad.runPluginCommand('Python Script', 'Stop Script')
                          
                          TBugReporterT 1 Reply Last reply Reply Quote 1
                          • TBugReporterT
                            TBugReporter @Ekopalypse
                            last edited by TBugReporter

                            @Ekopalypse

                            !
                            (When the only tools you know about are hammers, all your problems tend to look like nails.)


                            And now, question number umpteen-plus-one, regarding this part of your script:

                                sk_mapper_hwnd = user32.FindWindowW(None, u'Shortcut mapper')
                                if not sk_mapper_hwnd:
                                    print('Shortcut mapper was not found')
                                    return
                            
                                sys_tab_hwnd = user32.FindWindowExW(sk_mapper_hwnd, None, u'SysTabControl32', None)
                                if not sys_tab_hwnd:
                                    print('SysTabControl32 was not found')
                                    return
                            
                                item_count = user32.SendMessageW(sys_tab_hwnd, TCM_GETITEMCOUNT, 0, 0)
                                if not item_count:
                                    print('TCM_GETITEMCOUNT returned 0')
                                    return
                            
                                babygrid = user32.FindWindowExW(sk_mapper_hwnd, None, u'BABYGRID', None)
                                if not babygrid:
                                    print('BABYGRID was not found')
                                    return
                            

                            I’d like to add “Abort, Retry, Ignore?” dialogs to these, but I’m getting tripped up on the “Retry” part. What would you consider to be the best practice for this?

                            EkopalypseE 1 Reply Last reply Reply Quote 0
                            • EkopalypseE
                              Ekopalypse @TBugReporter
                              last edited by

                              @TBugReporter

                              something like this

                              while True:
                                  result = notepad.messageBox('','', MESSAGEBOXFLAGS.ABORTRETRYIGNORE)
                                  if result != MESSAGEBOXFLAGS.RESULTRETRY:
                                      break
                              
                              Alan KilbornA 1 Reply Last reply Reply Quote 1
                              • Alan KilbornA
                                Alan Kilborn @Ekopalypse
                                last edited by

                                It boggles the mind that someone would ever think to use the Stop Script menu item, in code, to “bail out”. Just write code that nicely returns, like @Ekopalypse 's main example from earlier. Stop Script should only be run from the menus as a last resort, a “kill my script” kind of thing. And I don’t think I’ve ever had a need to use it.

                                TBugReporterT 1 Reply Last reply Reply Quote 1
                                • TBugReporterT
                                  TBugReporter @Alan Kilborn
                                  last edited by

                                  @Ekopalypse said in Finding available shortcut keys (originally “Where’s the ‘New Window’ command?”):

                                  while True:
                                      result = notepad.messageBox('','', MESSAGEBOXFLAGS.ABORTRETRYIGNORE)
                                      if result != MESSAGEBOXFLAGS.RESULTRETRY:
                                          break
                                  

                                  Okay, but where do I put the code that I want it to retry, and where do I put the code that tests whether to show the MessageBox? (without having to duplicate either of those?)

                                  @Alan-Kilborn said in Finding available shortcut keys (originally “Where’s the ‘New Window’ command?”):

                                  It boggles the mind

                                  Yeah, but isn’t it nice to know that your mind can still be boggled? 😁

                                  Stop Script should only be run from the menus as a last resort

                                  This was a stopgap measure for me - a placeholder until I could understand my difficulties with scope for variables. I think I got that under control; I just need to test it out and then I’ll do like you said.

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

                                    @TBugReporter said in Finding available shortcut keys (originally “Where’s the ‘New Window’ command?”):

                                    Okay, but where do I put the code that I want it to retry

                                    while True:
                                        result = notepad.messageBox('','', MESSAGEBOXFLAGS.ABORTRETRYIGNORE)
                                        if result != MESSAGEBOXFLAGS.RESULTRETRY:
                                            break
                                        # code to redo goes here
                                    

                                    or alternately, if it makes more sense to you,

                                    while True:
                                        result = notepad.messageBox('','', MESSAGEBOXFLAGS.ABORTRETRYIGNORE)
                                        if result == MESSAGEBOXFLAGS.RESULTRETRY:
                                            # code to redo goes here
                                        else:
                                            break
                                        # code to redo goes here
                                    
                                    TBugReporterT 1 Reply Last reply Reply Quote 0
                                    • TBugReporterT
                                      TBugReporter @PeterJones
                                      last edited by

                                      @PeterJones

                                      It seems to me that that structure won’t do the “code to redo” a first time without first putting up the A/R/I box…?

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

                                        @TBugReporter ,

                                        It seems to me that that structure won’t do the “code to redo” a first time without first putting up the A/R/I box…?

                                        Then put the code in whatever order you think is logical for your needs.

                                        while True:
                                           # code to do every loop goes here 
                                           result = notepad.messageBox('','', MESSAGEBOXFLAGS.ABORTRETRYIGNORE)
                                           if result != MESSAGEBOXFLAGS.RESULTRETRY:
                                                break
                                        
                                        TBugReporterT 1 Reply Last reply Reply Quote 0
                                        • TBugReporterT
                                          TBugReporter @PeterJones
                                          last edited by

                                          @PeterJones
                                          I’ve now tried this …

                                          def bailout(msg):
                                              print(msg)
                                              user_response = notepad.messageBox(msg, "Error", MB_CANCELTRYCONTINUE | MB_ICONWARNING)
                                              if user_response == MB_RESULTCANCEL:
                                                  notepad.runPluginCommand('Python Script', 'Stop Script')
                                              else:
                                                  return user_response
                                          
                                          def main():
                                              # ...
                                              while True:
                                                  sk_mapper_hwnd = user32.FindWindowW(None, u"Shortcut mapper")
                                                  if not sk_mapper_hwnd:
                                                      action_to_take = bailout("Mapper window not found!")
                                                  if action_to_take != MB_RESULTTRYAGAIN:
                                                      break
                                              # ...
                                          

                                          … but that gives me …

                                          UnboundLocalError: local variable 'action_to_take' referenced before assignment
                                          

                                          Where did I go wrong?

                                          EkopalypseE 1 Reply Last reply Reply Quote 0
                                          • EkopalypseE
                                            Ekopalypse @TBugReporter
                                            last edited by

                                            @TBugReporter

                                            Scope problem. An if-block introduces a new scope and the variables defined there are only valid within this scope. Either the comparison with MB_RESULTTRYAGAIN is indented to have it in the same scope, or action_to_take must be defined at the same scoping level as the comparison.

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