Finding available shortcut keys (originally "Where's the 'New Window' command?")
-
The pest is back! 😁 (I thank you in advance for your patience with me.)
-
Can I use PythonScript to display a Windows MessageBox? Can I create my own custom dialogs in Windows style?
-
How can I prematurely end my script (if something weird happens)? I found
sys.exit()
, but this apparently terminates all of Notepad++ along with the script.
-
-
@TBugReporter said in Finding available shortcut keys (originally “Where’s the ‘New Window’ command?”):
- Can I use PythonScript to display a Windows MessageBox?
Yes. 😉1
Can I create my own custom dialogs in Windows style?
Not easily. 😉2
- How can I prematurely end my script (if something weird happens)? I found
sys.exit()
, but this apparently terminates all of Notepad++ along with the script.
The best way I’ve found is to have a bunch of “if” processing so that it keeps on dumping out without running any of your code
----
WinkNotes: 😉3
😉1:
notepad.messageBox()
😉2: Alan tends to get around this by doing a bunch of free-form
editor.input()
notepad.prompt()
calls, and then processing the text that the user types in to make the decisions. In theory, since PythonScript comes with the libraries necessary to access any of the win32 API functions: see plenty of examples in the forum with accessing SendMessage; searching the forum on theSendMessage
from win32 API, and narrowing it down to @Ekopalypse’s posts, will get you some good examples pretty quickly – you would then have to extrapolate from that on how to access the various win32 API functions you want. But that said, I don’t know how practical it is to build a whole window using raw API calls – normally when programming win32 API, you would use resource files or equivalents, but I have no clue if you can define a resource file and easily give access to that resource file to the Python interpreter in PythonScript. (If you figure out a way, let me know, because I want to use that to reduce my library requirements in PerlScript some day.)😉3: wink notes are similar to footnotes, but made more annoying because I hid my actual answer inside the footnotes rather than in the main flow of the conversation
-
@PeterJones said in Finding available shortcut keys (originally “Where’s the ‘New Window’ command?”):
The best way I’ve found is to have a bunch of “if” processing
If I have to resort to something like that, I’d use
while True: pass
instead. (Still an evil hack, but it seems slightly more elegant.)
-
With ctypes you have access to the Windows Api and can therefore do everything it offers. E.g. create a TaskDialog.
You can also build your own dialogs with the included Tkinter module, see for example the Formatter.py script from the demo directory.
As for sys.exit, I found out that calling a “main” function and returning from that function serve the same purpose.
def main(): if x != 0: return main()
-
@PeterJones said in Finding available shortcut keys (originally “Where’s the ‘New Window’ command?”):
free-form
editor.input()
callsIt 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. -
@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 theDec 16, 2017, 11:03 PM
posting. -
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)?
-
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.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. -
tested with PS 2 and 3.
Note the comment on FindResourceExA
If something is unclear, let me know. -
@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…
-
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.
-
@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.
-
@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
-
@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
-
-
(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?
-
something like this
while True: result = notepad.messageBox('','', MESSAGEBOXFLAGS.ABORTRETRYIGNORE) if result != MESSAGEBOXFLAGS.RESULTRETRY: break
-
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. -
@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.
-
@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