Need help with structures in callbacks
-
Can win32 api callback function return structures?
In my script it only return's pointer to the structure, but not the whole structure.
Script:require "Sketchup.rb" require "win32/api.rb" #version 1.4.8 for ruby 1.8.x or 1.9.x include Win32 SetWindowsHookEx=API.new('SetWindowsHookEx', 'IKII', 'I', 'User32') #http://msdn.microsoft.com/en-us/library/ms644990(VS.85).aspx UnhookWindowsHookEx=API.new('UnhookWindowsHookEx', 'I', 'I', 'User32') #http://msdn.microsoft.com/en-us/library/ms644993(v=VS.85).aspx GetCurrentThreadId=API.new('GetCurrentThreadId', 'V', 'I', 'Kernel32') #http://msdn.microsoft.com/en-us/library/ms683183(VS.85).aspx GetModuleHandle=API.new('GetModuleHandle', 'V', 'I', 'Kernel32') #http://msdn.microsoft.com/en-us/library/ms683199(v=VS.85).aspx $inputText=[nil, [], 0] def logLine(str, lines=40) $inputText[0]=Sketchup.active_model.add_note("Sketchup Hook Procedure", 0.01, 0.2) if ($inputText[0]==nil or $inputText[0].deleted?) $inputText[1].push(str) $inputText[1][0,($inputText[1].length-lines)]=nil if $inputText[1].length>lines $inputText[0].text=$inputText[1].join("\n") end class LowLevelMouseHookProc @@hhk=nil @@lowLevelMouseProc=API;;Callback.new("ILP", 'I'){|nCode, wParam, p| #http://msdn.microsoft.com/en-us/library/ms644986(v=VS.85).aspx param=[p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8], p[9]] #MSLLHOOKSTRUCT; http://msdn.microsoft.com/en-us/library/ms644970(v=VS.85).aspx x=p[0].to_i + (p[1].to_i<<8) + (p[2].to_i<<16) + (p[3].to_i<<24) y=p[4].to_i + (p[5].to_i<<8) + (p[6].to_i<<16) + (p[7].to_i<<24) mouseData=p[8].to_i + (p[9].to_i<<8) + (p[10].to_i<<16) + (p[11].to_i<<24) $inputText[2]+=1 logLine("#{$inputText[2]} code; #{nCode} wParam; #{wParam} lParam; #{param.inspect} x; #{x} y; #{y} mouseData; #{mouseData}") nCode #proccess the message as it states to proccess } def setHook(hMod=0, threadID=0) UnhookWindowsHookEx.call(@@hhk) if @@hhk #First, if exists then unhook the hook before setting it again. @@hhk=SetWindowsHookEx.call(14, @@lowLevelMouseProc, hMod, threadID) end def unhook() UnhookWindowsHookEx.call(@@hhk) if @@hhk @@hhk=nil end end class MyAPPObserver < Sketchup;;AppObserver #Need to use that because it's highly recommended to unhook the procedure. def onQuit() #Will unhook it when sketchup will be closed $lowLevelMouseProc.unhook end end Sketchup.add_observer(MyAPPObserver.new) $lowLevelMouseProc=LowLevelMouseHookProc.new threadID=GetCurrentThreadId.call hMod=GetModuleHandle.call file_name=File.basename(__FILE__) unless file_loaded?(file_name) $procState=0 submenu=UI.menu("Plugins") item=submenu.add_item("LowLevelMouseHookProc"){ if $procState==0 $procState=1 $lowLevelMouseProc.setHook(hMod) #Since 'lowLevel' stands for global or module handle then it will work only on mudule handle. else $procState=0 $lowLevelMouseProc.unhook $inputText[0].erase! unless ($inputText[0]==nil or $inputText[0].deleted?) $inputText=[nil, [], 0] end } submenu.set_validation_proc(item){if $procState==0 then MF_UNCHECKED else MF_CHECKED end} file_loaded(file_name) end
Here's some result of what I get:
22 code; 0 msg; 522 lParam; [31, 1, nil, nil, nil, nil, nil, nil, nil, nil] x; 287 y; 0 mouseData; 0 23 code; 0 msg; 513 lParam; [31, 1, nil, nil, nil, nil, nil, nil, nil, nil] x; 287 y; 0 mouseData; 0 24 code; 0 msg; 514 lParam; [31, 1, nil, nil, nil, nil, nil, nil, nil, nil] x; 287 y; 0 mouseData; 0 25 code; 0 msg; 513 lParam; [31, 1, nil, nil, nil, nil, nil, nil, nil, nil] x; 287 y; 0 mouseData; 0 26 code; 0 msg; 514 lParam; [31, 1, nil, nil, nil, nil, nil, nil, nil, nil] x; 287 y; 0 mouseData; 0 27 code; 0 msg; 516 lParam; [31, 1, nil, nil, nil, nil, nil, nil, nil, nil] x; 287 y; 0 mouseData; 0 28 code; 0 msg; 517 lParam; [31, 1, nil, nil, nil, nil, nil, nil, nil, nil] x; 287 y; 0 mouseData; 0 29 code; 0 msg; 513 lParam; [31, 1, nil, nil, nil, nil, nil, nil, nil, nil] x; 287 y; 0 mouseData; 0 30 code; 0 msg; 514 lParam; [31, 1, nil, nil, nil, nil, nil, nil, nil, nil] x; 287 y; 0 mouseData; 0 31 code; 0 msg; 516 lParam; [31, 1, nil, nil, nil, nil, nil, nil, nil, nil] x; 287 y; 0 mouseData; 0 32 code; 0 msg; 517 lParam; [31, 1, nil, nil, nil, nil, nil, nil, nil, nil] x; 287 y; 0 mouseData; 0 33 code; 0 msg; 512 lParam; [31, 1, nil, nil, nil, nil, nil, nil, nil, nil] x; 287 y; 0 mouseData; 0 34 code; 0 msg; 512 lParam; [34, 1, nil, nil, nil, nil, nil, nil, nil, nil] x; 290 y; 0 mouseData; 0 35 code; 0 msg; 512 lParam; [39, 1, nil, nil, nil, nil, nil, nil, nil, nil] x; 295 y; 0 mouseData; 0 36 code; 0 msg; 512 lParam; [46, 1, nil, nil, nil, nil, nil, nil, nil, nil] x; 302 y; 0 mouseData; 0 37 code; 0 msg; 512 lParam; [53, 1, nil, nil, nil, nil, nil, nil, nil, nil] x; 309 y; 0 mouseData; 0 38 code; 0 msg; 512 lParam; [55, 1, nil, nil, nil, nil, nil, nil, nil, nil] x; 311 y; 0 mouseData; 0 39 code; 0 msg; 512 lParam; [55, 1, nil, nil, nil, nil, nil, nil, nil, nil] x; 311 y; 0 mouseData; 0 40 code; 0 msg; 512 lParam; [55, 1, nil, nil, nil, nil, nil, nil, nil, nil] x; 311 y; 0 mouseData; 0 41 code; 0 msg; 512 lParam; [55, 1, nil, nil, nil, nil, nil, nil, nil, nil] x; 311 y; 0 mouseData; 0 42 code; 0 msg; 512 lParam; [52, 1, nil, nil, nil, nil, nil, nil, nil, nil] x; 308 y; 0 mouseData; 0 43 code; 0 msg; 512 lParam; [47, 1, nil, nil, nil, nil, nil, nil, nil, nil] x; 303 y; 0 mouseData; 0 44 code; 0 msg; 512 lParam; [45, 1, nil, nil, nil, nil, nil, nil, nil, nil] x; 301 y; 0 mouseData; 0 45 code; 0 msg; 513 lParam; [45, 1, nil, nil, nil, nil, nil, nil, nil, nil] x; 301 y; 0 mouseData; 0 46 code; 0 msg; 512 lParam; [42, 1, nil, nil, nil, nil, nil, nil, nil, nil] x; 298 y; 0 mouseData; 0 47 code; 0 msg; 512 lParam; [41, 1, nil, nil, nil, nil, nil, nil, nil, nil] x; 297 y; 0 mouseData; 0 48 code; 0 msg; 512 lParam; [46, 1, nil, nil, nil, nil, nil, nil, nil, nil] x; 302 y; 0 mouseData; 0 49 code; 0 msg; 512 lParam; [47, 1, nil, nil, nil, nil, nil, nil, nil, nil] x; 303 y; 0 mouseData; 0 50 code; 0 msg; 512 lParam; [48, 1, nil, nil, nil, nil, nil, nil, nil, nil] x; 304 y; 0 mouseData; 0 51 code; 0 msg; 512 lParam; [49, 1, nil, nil, nil, nil, nil, nil, nil, nil] x; 305 y; 0 mouseData; 0 52 code; 0 msg; 512 lParam; [49, 1, nil, nil, nil, nil, nil, nil, nil, nil] x; 305 y; 0 mouseData; 0 53 code; 0 msg; 514 lParam; [49, 1, nil, nil, nil, nil, nil, nil, nil, nil] x; 305 y; 0 mouseData; 0 54 code; 0 msg; 512 lParam; [47, 1, nil, nil, nil, nil, nil, nil, nil, nil] x; 303 y; 0 mouseData; 0 55 code; 0 msg; 512 lParam; [47, 1, nil, nil, nil, nil, nil, nil, nil, nil] x; 303 y; 0 mouseData; 0 56 code; 0 msg; 512 lParam; [46, 1, nil, nil, nil, nil, nil, nil, nil, nil] x; 302 y; 0 mouseData; 0 57 code; 0 msg; 512 lParam; [46, 1, nil, nil, nil, nil, nil, nil, nil, nil] x; 302 y; 0 mouseData; 0 58 code; 0 msg; 512 lParam; [46, 1, nil, nil, nil, nil, nil, nil, nil, nil] x; 302 y; 0 mouseData; 0 59 code; 0 msg; 512 lParam; [46, 1, nil, nil, nil, nil, nil, nil, nil, nil] x; 302 y; 0 mouseData; 0 60 code; 0 msg; 512 lParam; [46, 1, nil, nil, nil, nil, nil, nil, nil, nil] x; 302 y; 0 mouseData; 0 61 code; 0 msg; 513 lParam; [46, 1, nil, nil, nil, nil, nil, nil, nil, nil] x; 302 y; 0 mouseData; 0
But Should the lParam struct give the whole structure?
- From that structure I can only get the x-coordinate and sometimes the y-coordinate when cursor x-pos is 0. But I cannnot get the rest of the info. Like when I spin the mouse wheel wParam returns the message 522, but doesn't return the whole pointer to MSLLHOOKSTRUCT. I tested it on Borland Delphi 6 and it does returns the whole structure, but on ruby it doesn't. By many observations I came-up with an evidence:
if some part of the pointer in ruby is nil then ruby assumes that the rest of the strucure is also nil and states it to the end of the pointer. It does that because if some part is nil then it would have to raise an error that it can't set nil value.
Example:a=0.chr*16 a[4]=2 #Works! a[4]=nil #Raises an Error
So, is there a way to get the whole structure without writing a dll?
All references to urls are in my script.
Plugin(unzip it to plugins and test):
-
For some reasons I don't get replies , does this topic makes sense>?
-
Well.. I have not had time to test it.
And it's Windows only. We really need a solution that works on both platforms (Mac and Windows,) and that means it needs to be built into the Sketchup API by Google.
-
@anton_s said:
For some reasons I don't get replies , does this topic makes sense>?
I think it's more of a matter of people now knowing the answer.
-
@dan rathbun said:
And it's Windows only. We really need a solution that works on both platforms (Mac and Windows,) and that means it needs to be built into the Sketchup API by Google.
That depends if he is aiming to support both platforms...
-
Just a few things I can see wrong.
Including a library file (
Win32
,) in the global ObjectSpace is a big no no. Your code needs to be wrapped within a module.Once module wrapped... all those global vars can become module @@vars, or local module vars, or module constants.
-
If you look at some of the pure Ruby source in Dan Berger's windows-pr package, you'll come across examples of accessing C structures from Ruby using
Array.pack
andString.unpack
-
@thomthom said:
@dan rathbun said:
And it's Windows only. We really need a solution that works on both platforms (Mac and Windows,) and that means it needs to be built into the Sketchup API by Google.
That depends if he is aiming to support both platforms...
Well, yes, I do want to support those for both platforms, but its just a starting test for platform that I'm using. And its not I'm the only one who want's that, I know there is much more people that would also want that ability in their plugins. So, yes after a solution to this topic, the code will be extended into more abilities of using on other platforms.
@dan rathbun said:
Including a library file (Win32,) in the global ObjectSpace is a big no no. Your code needs to be wrapped within a module.
BIG Thanks Dan This thing was bugging me all the time I've need to wtite a code. This was a thing I needed to be sure of.@dan rathbun said:
If you look at some of the pure Ruby source in Dan Berger's windows-pr package, you'll come across examples of accessing C structures from Ruby using
Array.pack
andString.unpack
Thanks , think this is a solution. I no doubt, WILL examine the pakage!!!
Advertisement