[code] Win32 Moving/Showing/Hiding Toolbars and Dialogs
-
The Win32API.so file does not support the use of callbacks needed by EnumWindows and EnumChildWindows. So I have had to move to win32/api.so, which does support callbacks. But this will also allow more interesting things to be done, such as finding resizing Sketchup by its drawing area, and sending values to the Measurements box via a plugin.
-
When there is multiple SketchUp windows open - how do you find the one you want?
-
Hopefully, the window titles are different. If not, I'm not sure.
-
So you look for windows with "<filename> - SketchUp (Pro)"
-
Too fast... here's how to get the exact name. (But is_pro? is for windows 7+)
def su_window_name pro = Sketchup.is_pro? ? " Pro" ; "" if ((title = Sketchup.active_model.title).empty?) return ("Untitled - SketchUp" + pro) else return (title += ".skp - SketchUp" + pro) end end
-
But when there is two untitled windows there could be problems?
-
Yes, but in that case how would any program know which one the user meant?
You can find all of the matching windows. It's just hard to know which the user meant to use.
-
@jim said:
Yes, but in that case how would any program know which one the user meant?
If you'd created the window then you'd get the handle from there. (Would be nice if the API could expose the handles in the Ruby API)
I suppose that if it is possible to get an array of matching windows one could filter out the window you want by checking if one of them is the active - if it's the active SU window you want. (Assuming SU is the currently active window)
Or maybe by Z-Order? Assuming that the top most is the most recent - again if that is what you want... -
In most cases you'd get the window the user is working on, right?
So how about
GetForegroundWindow - then, in case one of the toolbars or webdialogs are the active window, iterate down the hierarchy using GetParent - checking for matching window title? -
If you have an API which supports EnumWindows, you can use GetProcessId and GetWindowThreadProcessId to filter on windows in the current process.
-
@jim said:
But I didn't see a lag when applying the ToolWIndow class immediately after .showing the webdialog.
You got a snippet of how you applied the ToolWindow style?
-
'N' instead of 'L'?
hm.. I'm a wee bit confused to exactly when to use what type... -
From the pick-axe book:
@unknownuser said:
Strings
n'' and
l'' represent numbers,
i'' represent integers,
p'' represents pointers to data stored in a string
``v'' represents a void type (used for export parameters only).
These strings are case-insensitive.So I guessed you just use the type that is the best match to the API call parameters. In other words, your guess is as good as mine.
-
is N === L ? "Number" vs Integer? Number == Float?
-
I got lots of errors when I tried the Toolwindow snippet in the first post. Seems that a few constants where missing from the snippet.
I found them though, and I tried another way to get the window handle.
<span class="syntaxdefault"><br /></span><span class="syntaxcomment"># http://ruby-doc.org/docs/ProgrammingRuby/html/lib_windows.html#Win32API.new<br /><br /></span><span class="syntaxkeyword">require </span><span class="syntaxstring">'Win32API'<br /><br /></span><span class="syntaxdefault">WS_CAPTION </span><span class="syntaxkeyword">= </span><span class="syntaxdefault">0x00C00000<br />WS_EX_TOOLWINDOW </span><span class="syntaxkeyword">= </span><span class="syntaxdefault">0x00000080<br /><br />GWL_STYLE </span><span class="syntaxkeyword">= -</span><span class="syntaxdefault">16<br />GWL_EXSTYLE </span><span class="syntaxkeyword">= -</span><span class="syntaxdefault">20<br /><br /></span><span class="syntaxcomment"># SetWindowPos() flags<br /></span><span class="syntaxdefault">SWP_NOSIZE </span><span class="syntaxkeyword">= </span><span class="syntaxdefault">0x0001<br />SWP_NOMOVE </span><span class="syntaxkeyword">= </span><span class="syntaxdefault">0x0002<br />SWP_DRAWFRAME </span><span class="syntaxkeyword">= </span><span class="syntaxdefault">0x0020<br />SWP_FRAMECHANGED </span><span class="syntaxkeyword">= </span><span class="syntaxdefault">0x0020<br />SWP_NOREPOSITION </span><span class="syntaxkeyword">= </span><span class="syntaxdefault">0x0200<br /><br /></span><span class="syntaxcomment"># Windows Functions<br />#FindWindow = Win32API.new("user32.dll" , "FindWindow" , 'PP' , 'L')<br />#FindWindowEx = Win32API.new("user32.dll", "FindWindowEx" , 'LLPP', 'L')<br /></span><span class="syntaxdefault">SetWindowPos </span><span class="syntaxkeyword">= </span><span class="syntaxdefault">Win32API</span><span class="syntaxkeyword">.new(</span><span class="syntaxstring">"user32.dll" </span><span class="syntaxkeyword">, </span><span class="syntaxstring">"SetWindowPos" </span><span class="syntaxkeyword">, </span><span class="syntaxstring">'LLIIIII'</span><span class="syntaxkeyword">, </span><span class="syntaxstring">'I'</span><span class="syntaxkeyword">)<br /></span><span class="syntaxdefault">SetWindowLong </span><span class="syntaxkeyword">= </span><span class="syntaxdefault">Win32API</span><span class="syntaxkeyword">.new(</span><span class="syntaxstring">"user32.dll" </span><span class="syntaxkeyword">, </span><span class="syntaxstring">"SetWindowLong"</span><span class="syntaxkeyword">, </span><span class="syntaxstring">'LIL'</span><span class="syntaxkeyword">, </span><span class="syntaxstring">'L'</span><span class="syntaxkeyword">)<br /></span><span class="syntaxdefault">GetWindowLong </span><span class="syntaxkeyword">= </span><span class="syntaxdefault">Win32API</span><span class="syntaxkeyword">.new(</span><span class="syntaxstring">"user32.dll" </span><span class="syntaxkeyword">, </span><span class="syntaxstring">"GetWindowLong"</span><span class="syntaxkeyword">, </span><span class="syntaxstring">'LI' </span><span class="syntaxkeyword">, </span><span class="syntaxstring">'L'</span><span class="syntaxkeyword">)<br /></span><span class="syntaxdefault">GetActiveWindow </span><span class="syntaxkeyword">= </span><span class="syntaxdefault">Win32API</span><span class="syntaxkeyword">.new(</span><span class="syntaxstring">"user32.dll"</span><span class="syntaxkeyword">, </span><span class="syntaxstring">"GetActiveWindow"</span><span class="syntaxkeyword">, </span><span class="syntaxstring">''</span><span class="syntaxkeyword">, </span><span class="syntaxstring">'L'</span><span class="syntaxkeyword">)<br /></span><span class="syntaxcomment">#GetForegroundWindow = Win32API.new("user32.dll", "GetForegroundWindow", '', 'L')<br /></span><span class="syntaxdefault">GetWindowText </span><span class="syntaxkeyword">= </span><span class="syntaxdefault">Win32API</span><span class="syntaxkeyword">.new(</span><span class="syntaxstring">"user32.dll"</span><span class="syntaxkeyword">, </span><span class="syntaxstring">"GetWindowText"</span><span class="syntaxkeyword">, </span><span class="syntaxstring">'LPI'</span><span class="syntaxkeyword">, </span><span class="syntaxstring">'I'</span><span class="syntaxkeyword">)<br /></span><span class="syntaxdefault">GetWindowTextLength </span><span class="syntaxkeyword">= </span><span class="syntaxdefault">Win32API</span><span class="syntaxkeyword">.new(</span><span class="syntaxstring">"user32.dll"</span><span class="syntaxkeyword">, </span><span class="syntaxstring">"GetWindowTextLength"</span><span class="syntaxkeyword">, </span><span class="syntaxstring">'L'</span><span class="syntaxkeyword">, </span><span class="syntaxstring">'I'</span><span class="syntaxkeyword">)<br /><br /><br /></span><span class="syntaxdefault">def create_toolbar_window<br /> window </span><span class="syntaxkeyword">= </span><span class="syntaxdefault">UI</span><span class="syntaxkeyword">;;</span><span class="syntaxdefault">WebDialog</span><span class="syntaxkeyword">.new(</span><span class="syntaxstring">'My Test Window'</span><span class="syntaxkeyword">, </span><span class="syntaxdefault">false</span><span class="syntaxkeyword">)<br /> </span><span class="syntaxdefault">window</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">set_html</span><span class="syntaxkeyword">(</span><span class="syntaxstring">'<br /> <html><br /> <head><br /> <style type="text/css"><br /> html {<br /> font; caption;<br /> background; ButtonFace;<br /> }<br /> hr {<br /> border; none;<br /> border-top; 1px solid ThreeDShadow;<br /> border-bottom; 1px solid ThreeDHighlight;<br /> }<br /> </style><br /> </head><br /> <body><br /> <b>My very own window</b><br /> <hr /><br /> Neato!<br /> </body><br /> </html><br /> '</span><span class="syntaxkeyword">)<br /> </span><span class="syntaxdefault">window</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">show<br /> <br /> </span><span class="syntaxcomment"># Find the new window - should get it by GetActiveWindow since wd.show brings<br /> # the window to front.<br /> </span><span class="syntaxdefault">hwnd </span><span class="syntaxkeyword">= </span><span class="syntaxdefault">GetActiveWindow</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">call<br /> </span><span class="syntaxcomment">#hwnd = GetForegroundWindow.call<br /> #hwnd = FindWindow.call(DIALOG_CLASS, window_title)<br /> </span><span class="syntaxdefault">p hwnd<br /><br /> puts </span><span class="syntaxstring">'Check Window Text'<br /> </span><span class="syntaxdefault">buf_len </span><span class="syntaxkeyword">= </span><span class="syntaxdefault">GetWindowTextLength</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">call</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">hwnd</span><span class="syntaxkeyword">)<br /> </span><span class="syntaxdefault">str </span><span class="syntaxkeyword">= </span><span class="syntaxstring">' ' </span><span class="syntaxkeyword">* (</span><span class="syntaxdefault">buf_len </span><span class="syntaxkeyword">+ </span><span class="syntaxdefault">1</span><span class="syntaxkeyword">)<br /> </span><span class="syntaxdefault">p GetWindowText</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">call</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">hwnd</span><span class="syntaxkeyword">, </span><span class="syntaxdefault">str</span><span class="syntaxkeyword">, </span><span class="syntaxdefault">str</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">length</span><span class="syntaxkeyword">)<br /> </span><span class="syntaxdefault">p str<br /> p str</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">strip<br /> <br /> </span><span class="syntaxcomment"># Change Window Style<br /> </span><span class="syntaxdefault">style </span><span class="syntaxkeyword">= </span><span class="syntaxdefault">GetWindowLong</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">call</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">hwnd</span><span class="syntaxkeyword">, </span><span class="syntaxdefault">GWL_EXSTYLE</span><span class="syntaxkeyword">)<br /> </span><span class="syntaxdefault">p style<br /> p SetWindowLong</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">call</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">hwnd</span><span class="syntaxkeyword">, </span><span class="syntaxdefault">GWL_EXSTYLE</span><span class="syntaxkeyword">, </span><span class="syntaxdefault">style </span><span class="syntaxkeyword">| </span><span class="syntaxdefault">WS_EX_TOOLWINDOW</span><span class="syntaxkeyword">)<br /> </span><span class="syntaxdefault">p SetWindowPos</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">call</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">hwnd</span><span class="syntaxkeyword">, </span><span class="syntaxdefault">0</span><span class="syntaxkeyword">, </span><span class="syntaxdefault">0</span><span class="syntaxkeyword">, </span><span class="syntaxdefault">0</span><span class="syntaxkeyword">, </span><span class="syntaxdefault">0</span><span class="syntaxkeyword">, </span><span class="syntaxdefault">0</span><span class="syntaxkeyword">, </span><span class="syntaxdefault">SWP_FRAMECHANGED</span><span class="syntaxkeyword">|</span><span class="syntaxdefault">SWP_NOSIZE</span><span class="syntaxkeyword">|</span><span class="syntaxdefault">SWP_NOMOVE</span><span class="syntaxkeyword">)<br /></span><span class="syntaxdefault">end<br /></span>
The code needs error checking and such.
(maybe it's because I'm not error checking yet that I some times experience that the window automatically closes after a few seconds. it has happened only sporadically...)
-
Removing the maximize and minimize button: (Addition to the code in my previous post)
<span class="syntaxdefault"><br /> WS_MAXIMIZEBOX </span><span class="syntaxkeyword">= </span><span class="syntaxdefault">0x10000<br /> WS_MINIMIZEBOX </span><span class="syntaxkeyword">= </span><span class="syntaxdefault">0x20000<br /> WS_SIZEBOX </span><span class="syntaxkeyword">= </span><span class="syntaxdefault">0x40000<br /><br /> </span><span class="syntaxcomment"># Remove Buttons<br /> # http://support.microsoft.com/kb/137033<br /> </span><span class="syntaxdefault">style </span><span class="syntaxkeyword">= </span><span class="syntaxdefault">GetWindowLong</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">call</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">hwnd</span><span class="syntaxkeyword">, </span><span class="syntaxdefault">GWL_STYLE</span><span class="syntaxkeyword">)<br /> </span><span class="syntaxdefault">p style<br /> style </span><span class="syntaxkeyword">= </span><span class="syntaxdefault">style </span><span class="syntaxkeyword">& ~</span><span class="syntaxdefault">WS_MINIMIZEBOX<br /> style </span><span class="syntaxkeyword">= </span><span class="syntaxdefault">style </span><span class="syntaxkeyword">& ~</span><span class="syntaxdefault">WS_MAXIMIZEBOX<br /> </span><span class="syntaxcomment">#style = style & ~WS_SIZEBOX<br /> </span><span class="syntaxdefault">p SetWindowLong</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">call</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">hwnd</span><span class="syntaxkeyword">, </span><span class="syntaxdefault">GWL_STYLE</span><span class="syntaxkeyword">, </span><span class="syntaxdefault">style</span><span class="syntaxkeyword">)<br /> </span><span class="syntaxdefault"></span>
This prevents the window from maximising when double-clicking. Seems to introduce some frame flicker.
Can GWL_STYLE and GWL_EXSTYLE changes be combines into one call? -
As implemented in TT_Lib2 with error checking:
<span class="syntaxdefault"><br /> </span><span class="syntaxcomment"># Call after webdialog.show to change the window into a toolwindow. Spesify the<br /></span><span class="syntaxdefault"> </span><span class="syntaxcomment"># window title so the method can verify it changes the correct window.<br /></span><span class="syntaxdefault"> </span><span class="syntaxcomment">#<br /></span><span class="syntaxdefault"> </span><span class="syntaxcomment"># @param [String] window_title<br /></span><span class="syntaxdefault"> </span><span class="syntaxcomment">#<br /></span><span class="syntaxdefault"> </span><span class="syntaxcomment"># @return [Nil]<br /></span><span class="syntaxdefault"> </span><span class="syntaxcomment"># @since 2.5.0<br /></span><span class="syntaxdefault"> def self</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">make_toolwindow_frame</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">window_title</span><span class="syntaxkeyword">)<br /></span><span class="syntaxdefault"> </span><span class="syntaxcomment"># Retrieves the window handle to the active window attached to the calling<br /></span><span class="syntaxdefault"> </span><span class="syntaxcomment"># thread's message queue. <br /></span><span class="syntaxdefault"> hwnd </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> GetActiveWindow</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">call<br /> return nil if hwnd</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">nil</span><span class="syntaxkeyword">?<br /></span><span class="syntaxdefault"> <br /> </span><span class="syntaxcomment"># Verify window text as extra security to ensure it's the correct window.<br /></span><span class="syntaxdefault"> buf_len </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> GetWindowTextLength</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">call</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">hwnd</span><span class="syntaxkeyword">)<br /></span><span class="syntaxdefault"> return nil if buf_len </span><span class="syntaxkeyword">==</span><span class="syntaxdefault"> 0<br /> <br /> str </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> </span><span class="syntaxstring">' '</span><span class="syntaxdefault"> </span><span class="syntaxkeyword">*</span><span class="syntaxdefault"> </span><span class="syntaxkeyword">(</span><span class="syntaxdefault">buf_len </span><span class="syntaxkeyword">+</span><span class="syntaxdefault"> 1</span><span class="syntaxkeyword">)<br /></span><span class="syntaxdefault"> result </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> GetWindowText</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">call</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">hwnd</span><span class="syntaxkeyword">,</span><span class="syntaxdefault"> str</span><span class="syntaxkeyword">,</span><span class="syntaxdefault"> str</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">length</span><span class="syntaxkeyword">)<br /></span><span class="syntaxdefault"> return nil if result </span><span class="syntaxkeyword">==</span><span class="syntaxdefault"> 0<br /> <br /> return nil unless str</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">strip </span><span class="syntaxkeyword">==</span><span class="syntaxdefault"> window_title</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">strip<br /> <br /> </span><span class="syntaxcomment"># Set frame to Toolwindow<br /></span><span class="syntaxdefault"> style </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> GetWindowLong</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">call</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">hwnd</span><span class="syntaxkeyword">,</span><span class="syntaxdefault"> GWL_EXSTYLE</span><span class="syntaxkeyword">)<br /></span><span class="syntaxdefault"> return nil if style </span><span class="syntaxkeyword">==</span><span class="syntaxdefault"> 0<br /> <br /> result </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> SetWindowLong</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">call</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">hwnd</span><span class="syntaxkeyword">,</span><span class="syntaxdefault"> GWL_EXSTYLE</span><span class="syntaxkeyword">,</span><span class="syntaxdefault"> style </span><span class="syntaxkeyword">|</span><span class="syntaxdefault"> WS_EX_TOOLWINDOW</span><span class="syntaxkeyword">)<br /></span><span class="syntaxdefault"> return nil if result </span><span class="syntaxkeyword">==</span><span class="syntaxdefault"> 0<br /> <br /> </span><span class="syntaxcomment"># Remove and disable minimze and maximize<br /></span><span class="syntaxdefault"> </span><span class="syntaxcomment"># http://support.microsoft.com/kb/137033<br /></span><span class="syntaxdefault"> style </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> GetWindowLong</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">call</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">hwnd</span><span class="syntaxkeyword">,</span><span class="syntaxdefault"> GWL_STYLE</span><span class="syntaxkeyword">)<br /></span><span class="syntaxdefault"> return nil if style </span><span class="syntaxkeyword">==</span><span class="syntaxdefault"> 0<br /> <br /> style </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> style </span><span class="syntaxkeyword">&</span><span class="syntaxdefault"> </span><span class="syntaxkeyword">~</span><span class="syntaxdefault">WS_MINIMIZEBOX<br /> style </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> style </span><span class="syntaxkeyword">&</span><span class="syntaxdefault"> </span><span class="syntaxkeyword">~</span><span class="syntaxdefault">WS_MAXIMIZEBOX<br /> result </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> SetWindowLong</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">call</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">hwnd</span><span class="syntaxkeyword">,</span><span class="syntaxdefault"> GWL_STYLE</span><span class="syntaxkeyword">,</span><span class="syntaxdefault"> style</span><span class="syntaxkeyword">)<br /></span><span class="syntaxdefault"> return nil if result </span><span class="syntaxkeyword">==</span><span class="syntaxdefault"> 0<br /> <br /> </span><span class="syntaxcomment"># Refresh the window frame<br /></span><span class="syntaxdefault"> result </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> SetWindowPos</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">call</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">hwnd</span><span class="syntaxkeyword">,</span><span class="syntaxdefault"> 0</span><span class="syntaxkeyword">,</span><span class="syntaxdefault"> 0</span><span class="syntaxkeyword">,</span><span class="syntaxdefault"> 0</span><span class="syntaxkeyword">,</span><span class="syntaxdefault"> 0</span><span class="syntaxkeyword">,</span><span class="syntaxdefault"> 0</span><span class="syntaxkeyword">,</span><span class="syntaxdefault"> SWP_FRAMECHANGED</span><span class="syntaxkeyword">|</span><span class="syntaxdefault">SWP_NOSIZE</span><span class="syntaxkeyword">|</span><span class="syntaxdefault">SWP_NOMOVE</span><span class="syntaxkeyword">)<br /></span><span class="syntaxdefault"> result </span><span class="syntaxkeyword">!=</span><span class="syntaxdefault"> 0<br /> end<br /></span>
-
Can we have code blocks that expand similar to when you click on images?
-
What are possible advantages of using toolwindows instead of webdialogs?
And is the communication between SU and the toolwindow still done in the same way? -
It's not different windows - it's just different window frames. The code examples changes the window frame of webdialogs to toolwindows - which takes up less space and look neater.
Advertisement