From: Len W. <le...@we...> - 2009-07-18 01:17:53
|
perl-win32-gui-users list,<br /><br />I wrote:<br />> But how do I find and read the [COPYDATASTRUCT] structure pointed <br />> to by the integer $lParam ?<br /><br />Well, I figured it out.<br />Here's a sub, not completely general, but handles the case<br />of a scalar message string.<br /><br />Thanks for your indulgence.<br />(Maybe this will be useful for someone else searching the list archive.)<br /><br />Cheers,<br />-Len<br /><br />use Tie::Array::Pointer ;<br /><br />sub read_COPYDATASTRUCT {<br /> ## input: $CopyData_p (eg from an lParam)<br /> ## output (scalar): $Msg (list): ($Msg, dwData_p)<br /> my $CopyData_p = shift ;<br /><br /> my @CopyData_a ;<br /> tie @CopyData_a, 'Tie::Array::Pointer',<br /> {length => 3, type => 'L', address => $CopyData_p } ;<br /> my ($dwData_p, $cbData_len, $lpData_p) = @CopyData_a ;<br /><br /> my @Msg_a ;<br /> tie @Msg_a, 'Tie::Array::Pointer',<br /> {length => $cbData_len, type => 'C', address => $lpData_p } ;<br /><br /> pop @Msg_a if @Msg_a[-1] eq "\0" ; ## pop off trailing null (more??)<br /> my $Msg = pack "C$#Msg_a", @Msg_a ;<br /> wantarray ? ($Msg, $dwData_p) : $Msg ;<br />}<br /><br /><br /><br /> <p>On Jul 17, 2009, <strong>le...@we...</strong> wrote:</p> <div class="replyBody"> <blockquote class="email_quote" style="border-left: 2px solid #267fdb; margin: 0pt 0pt 0pt 1.8ex; padding-left: 1ex;">I am trying to use Win32::GUI from a Perl/Tk program<br />to receive and interpret a message sent from another window.<br /><br />I have successfully set up a window to receive and a hook to<br /> handle the message.<br /> Using the example in Win32::GUI::Reference/Methods.pod, I have<br /><br /> sub msg_handler {<br /> ($object, $wParam, $lParam, $type, $msgcode) = @_;<br /> print "Click handler called!\n";<br /> }<br /><br />The result looks reasonable in the debugger, <br />and $lParam is supposed to be a pointer to a WM_COPYDATA structure.<br /><br />But how do I find and read the structure pointed to by the integer $lParam ?<br />I have a hunch that Win32::API::Struct could help, but I don't quite see how.<br /><br />Thanks,<br />-Len<br /></blockquote> </div> |
From: Kevin M. <kej...@ho...> - 2009-07-18 12:24:15
|
Hey everyone, Here is an alternative method for extracting a structure out of a wParam or lParam parameter. I pieced this together from various posts on the mailing list. This method is message specific and requires knowledge of the size and members of the specific structure. This example uses the WM_HELP message, which is sent when a user click the '?' button in the top-right corner: $win->Hook(WM_HELP, sub { my ($this, $wParam, $lParam, $type, $msgcode) = @_; return unless $type == 0; return unless $msgcode == WM_HELP; my %helpinfo; #Here's how to get a stucture when only given a memory address: # 1. Pack the $lParam arg into a Long using pack "L" This turns the number into a usable memory address # 2. Unpack the result into a string using the size of the structure in bytes using unpack "P28" # 3. Unpack the result using the typedef for the structure and the appropriate pack formats @helpinfo{qw(cbSize iContextType iCtrlId hItemHandle dwContextId X Y)} = unpack("IiiLLll", unpack("P28", pack("L", $lParam))); #The internal Win32::GUI::GetWindowObject can get a window object from its handle my $control = Win32::GUI::GetWindowObject($helpinfo{hItemHandle}); #process message... return 1; }); Remember, that if the structure contains any structures as parameters, they have to unpacked as well. For example, the X and Y above is part of a POINT structure. Refer to the Windows SDK documentation for information about the various messages and structures. Hope this helps. Kevin. Date: Sat, 18 Jul 2009 01:17:40 +0000 From: le...@we... To: per...@li... Subject: Re: [perl-win32-gui-users] Interpreting an lParam pointer perl-win32-gui-users list, I wrote: > But how do I find and read the [COPYDATASTRUCT] structure pointed > to by the integer $lParam ? Well, I figured it out. Here's a sub, not completely general, but handles the case of a scalar message string. Thanks for your indulgence. (Maybe this will be useful for someone else searching the list archive.) Cheers, -Len use Tie::Array::Pointer ; sub read_COPYDATASTRUCT { ## input: $CopyData_p (eg from an lParam) ## output (scalar): $Msg (list): ($Msg, dwData_p) my $CopyData_p = shift ; my @CopyData_a ; tie @CopyData_a, 'Tie::Array::Pointer', {length => 3, type => 'L', address => $CopyData_p } ; my ($dwData_p, $cbData_len, $lpData_p) = @CopyData_a ; my @Msg_a ; tie @Msg_a, 'Tie::Array::Pointer', {length => $cbData_len, type => 'C', address => $lpData_p } ; pop @Msg_a if @Msg_a[-1] eq "\0" ; ## pop off trailing null (more??) my $Msg = pack "C$#Msg_a", @Msg_a ; wantarray ? ($Msg, $dwData_p) : $Msg ; } On Jul 17, 2009, le...@we... wrote: I am trying to use Win32::GUI from a Perl/Tk program to receive and interpret a message sent from another window. I have successfully set up a window to receive and a hook to handle the message. Using the example in Win32::GUI::Reference/Methods.pod, I have sub msg_handler { ($object, $wParam, $lParam, $type, $msgcode) = @_; print "Click handler called!\n"; } The result looks reasonable in the debugger, and $lParam is supposed to be a pointer to a WM_COPYDATA structure. But how do I find and read the structure pointed to by the integer $lParam ? I have a hunch that Win32::API::Struct could help, but I don't quite see how. Thanks, -Len _________________________________________________________________ What goes online, stays online Check the daily blob for the latest on what's happening around the web http://windowslive.ninemsn.com.au/blog.aspx |