[code] Win32 Moving/Showing/Hiding Toolbars and Dialogs
-
Not a plugin - just some example codes for manipulating the toolbar and dialog windows by name using the Win32API.so library file. The documentation for these constants and functions can be found by searching msdn.
These functions are for floating toolbars and dialogs. Docked toolbars will not be changed.
move_toolbar("Views", [x, y, w, h]) hide_toolbar("Standard") remove_caption("Styles") show_toolbar("Standard") restore_caption("Styles")
Remove Caption
pw = FindWindow.call(c, name) style = GetWindowLong.call(pw, GWL_STYLE) SetWindowLong.call(pw, GWL_STYLE, style & ~WS_CAPTION)
Restore Caption
pw = FindWindow.call(clss, name) style = GetWindowLong.call(pw, GWL_STYLE) SetWindowLong.call(pw, GWL_STYLE, style | WS_CAPTION) SetWindowPos.call(pw, 0, 0, 0, 0, 0, SWP_FRAMECHANGED|SWP_NOSIZE|SWP_NOMOVE)
WebDialog -> ToolWindow
w = UI;;WebDialog.new("New Web Dialog") w.show hwnd = FindWindow.call(DIALOG_CLASS, "New Web Dialog") style = GetWindowLong.call(hwnd, GWL_EXSTYLE) SetWindowLong.call(hwnd, GWL_EXSTYLE, style | WS_EX_TOOLWINDOW) SetWindowPos.call(hwnd, 0, 0, 0, 0, 0, SWP_FRAMECHANGED|SWP_NOSIZE|SWP_NOMOVE)
require 'sketchup' require 'Win32API' # ShowWindow() flags SW_HIDE = 0 SW_SHOWNORMAL = 1 SW_SHOWDEFAULT = 1 SW_MAXIMIZE = 3 SW_SHOW = 5 SW_MINIMIZE = 6 SW_RESTORE = 9 WS_CAPTION = 0x00C00000 GWL_STYLE = -16 # SetWindowPos() flags SWP_NOSIZE = 0x0001 SWP_NOMOVE = 0x0002 SWP_DRAWFRAME = 0x0020 SWP_FRAMECHANGED = 0x0020 SWP_NOREPOSITION = 0x0200 # SketchUp Info SKETCHUP_CLASS = "Afx;00400000;b;00010011;00000006;3EFB027F" TOOLBAR_CLASS = "Afx;00400000;8;00010011;00000000;00000000" DIALOG_CLASS = "#32770" # Dialogs, WebDialogs, and everything else. # Windows Functions FindWindow = Win32API.new("user32.dll" , "FindWindow" , ['P', 'P'] , 'N') #FindWindowEx = Win32API.new("user32.dll", "FindWindowEx" , ['N', 'N' , 'P' , 'P'], 'N') SetWindowPos = Win32API.new("user32.dll" , "SetWindowPos" , ['P', 'P' , 'N' , 'N' , 'N' , 'N', 'N'], 'N') GetClassName = Win32API.new("user32.dll" , "GetClassName" , ['P', 'P' , 'I'], 'N') GetWindowRect = Win32API.new("user32.dll" , "GetWindowRect", ['P', 'PP'], 'N') SetWindowLong = Win32API.new("user32.dll" , "SetWindowLong", ['P', 'N' , 'N'], 'N') GetWindowLong = Win32API.new("user32.dll" , "GetWindowLong", ['P', 'N'] , 'L') ShowWindow = Win32API.new("user32.dll" , "ShowWindow" , ['P', 'N'] , 'N') # Originally in SketchyPhysic by Chris Phillips def get_window_rect(name) pw = FindWindow.call(0, name) rect = Array.new.fill(0.chr,0..4*4).join GetWindowRect.call(pw, rect); rect=rect.unpack("i*") #turn rectangle into [top, left, width, height] instead of [top, left, right, bottom] rect[2]=rect[2]-rect[0] #w=x2-x1 rect[3]=rect[3]-rect[1] #h=y2-y1 return rect end def show_toolbar(name, sw=1) pw = FindWindow.call(TOOLBAR_CLASS, name) ShowWindow.call(pw, sw) end def hide_toolbar(name) pw = FindWindow.call(TOOLBAR_CLASS, name) ShowWindow.call(pw, SW_HIDE) end def move_toolbar(name, rect, flags = 0) pw = FindWindow.call(TOOLBAR_CLASS, name) return unless pw rect.flatten! x, y, w, h = rect SetWindowPos.call(pw, 0, x, y, w, h, flags) end def move_dialog(name, rect, flags=SWP_NOSIZE) pw = FindWindow.call(DIALOG_CLASS, name) return unless pw rect.flatten! x, y, w, h = rect SetWindowPos.call(pw, 0, x, y, w, h, flags) end
-
What I wanted to do was work out what flags to change to make a WebDialog into a ToolWindow. You haven't looked into that by any chance?
-
That would be an extended style WS_EX_TOOLWINDOW. I'm not sure that can be changed after run=time, but I will try it.
Styles:
http://msdn.microsoft.com/en-us/library/czada357%28VS.80%29.aspxExtended Styles:
http://msdn.microsoft.com/en-us/library/61fe4bte%28VS.71%29.aspx -
It can - I used to do it in Visual Basic when VB didn't offer full control over the windows. You can in fact change any window of any app - as long as you get its handle.
-
Yep, just did it. I'm just wondering of I am not writing a library that has already been written...
-
How quickly can you get the window handle when opening webdialogs? Can you avoid a flicker of change?
-
Good question I don't know the answer to, but wouldn't the reliable way be to have the dialog send a message back to ruby when it's ready?
Or can you change the dialog to a toolwindow before you .show() it? Will need to test.
-
Maybe the .show event of the dialog triggers as it's displayed? But I'm not sure if it wait for the HTML - which you do not want - as that will lag.
And can you do anything before calling show? You need a handle to the window - how are you getting that at the moment?
-
What does it mean when I get a negative value for a window style? How do I decode it into it's positive representation?
-
From GetWindowLong?
-
yeah.
s = get_style("Ruby Console") -1798569916
-
hm....
Are you receiving the data in the correct data type?
-
Turns out the negative return value is not a problem - I just wasn't using it right.
-
@thomthom said:
Maybe the .show event of the dialog triggers as it's displayed? But I'm not sure if it wait for the HTML - which you do not want - as that will lag.
And can you do anything before calling show? You need a handle to the window - how are you getting that at the moment?
Using FindWindow - which is a basic search by window name and class.
-
For a WebDialog, I couldn't find a handle until it was shown. I used EnumWindows and EnumChildWidows to locate it.
But I didn't see a lag when applying the ToolWIndow class immediately after .showing the webdialog.
-
Neat!
-
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)"
Advertisement