Loading ...
Sorry, an error occurred while loading the content.
 

Re: WM_LBUTTONDOWN and LPARAM

Expand Messages
  • Dennis K. Paulsen
    You could also use one of the Win32::GUITest functions or the MouseClick function mentioned in this group -D
    Message 1 of 5 , Feb 2, 2005
      You could also use one of the Win32::GUITest functions or the
      MouseClick function mentioned in this group
      -D
      --- In perlguitest@yahoogroups.com, "pkaluski" <pkaluski@p...> wrote:
      >
      > Hi,
      > $x and $y contain coordinates of a point I want to click.
      > How do I build LPARAM for PostMessage( hwnd, WM_BUTTONDOWN, 0,
      > LPARAM ) ?
      >
      > -Piotr
    • pkaluski
      Hi, I had a look at your function from post http://groups.yahoo.com/group/perlguitest/message/306 . I am doing my mouse clicks in almost similar way. However,
      Message 2 of 5 , Feb 2, 2005
        Hi,
        I had a look at your function from post
        http://groups.yahoo.com/group/perlguitest/message/306 .
        I am doing my mouse clicks in almost similar way. However, I believe
        that both, my and your code have one subtle problem (I may be wrong).
        They recalculate the point of click from client coordinates to global
        coordinates. So if you resize the window so it clips the button you
        are about to click, the mouse will click outside the window.
        If you send a WM_LBUTTONDOWN message to a client area, the button
        would be pressed even if it's not visible (I am not sure of what I am
        writing. Correct me if I am wrong).
        This is minor problem though.

        The main reason I posted this question was pure curriosity.
        I know there are some C macros for doing this. But my question was
        how do you do it in pure perl.
        So once again. The question is: Having the code below:

        my $x = xxx; # X coordinate
        my $y = yyy; # Y coordinate

        # AND NOW WHAT ?

        PostMessage( $client_handle, WM_LBUTTONDOWN, 0, $lparam );


        what do you put in place of "# AND NOW WHAT ?" (perl code) to make
        the thing work?

        -Piotr

        --- In perlguitest@yahoogroups.com, "Dennis K. Paulsen"
        <ctrondlpaulsden@y...> wrote:
        >
        > You could also use one of the Win32::GUITest functions or the
        > MouseClick function mentioned in this group
        > -D
        > --- In perlguitest@yahoogroups.com, "pkaluski" <pkaluski@p...>
        wrote:
        > >
        > > Hi,
        > > $x and $y contain coordinates of a point I want to click.
        > > How do I build LPARAM for PostMessage( hwnd, WM_BUTTONDOWN, 0,
        > > LPARAM ) ?
        > >
        > > -Piotr
      • Coleman Tom
        short answer: use left bit operator
        Message 3 of 5 , Feb 3, 2005
          short answer: use left bit operator << 16 times on the y value to make it
          the "hi word", then add it to the x value to make the lparam.

          my $x = xxx; # X coordinate
          my $y = yyy; # Y coordinate

          # AND NOW WHAT ?
          my $lparam = $x + ( $y << 16 );

          PostMessage( $client_handle, WM_LBUTTONDOWN, 0, $lparam );


          >> long answer >>

          disclaimer:
          I did not try actually posting a message with this. I only wrote test code
          to experiment and figure out how things are assembled, and how we can do the
          same in Perl.

          note:
          I did the research thinking that it was a WPARAM that we needed. when it
          was all done and I was posting the solution... only then did I see it was a
          LPARAM you wanted. it appears that WPARAM and LPARAM are the same. just
          different types to help C++ keep track of the two.



          LPARAM is a double word, it is a combination of two WORDs, a hi word and a
          lo word. There are several macros ( in C++ ) to assemble and pull apart
          these combinations.

          WORD 0x0 to 0xFF
          DWORD 0x0 to 0xFFFF

          windows uses the DWORD LPARAM to carry two WORDs...

          0x4466 LPARAM for mouse click
          0x44 Y value for mouse click
          0x66 X value for mouse click

          so to prepare them first make Y 0xFF larger, or bit shift it 16 times
          0x0044 Y value for mouse click, before shift
          0x4400 Y value for mouse click, after shift

          some of them include:

          WORD hi = HIWORD( dwValue );
          WORD lo = LOWORD( dwValue );
          MAKELPARAM, MAKEWPARAM ( same thing just different return types )
          GET_X_LPARAM The return value is the low-order int of the specified value.
          GET_Y_LPARAM The return value is the high-order int of the specified value.


          below is C++ and perl code that I used to experiment.

          >> start of Perl code >>


          # in C++ we have this WORD and WPARAM deal
          # WORD lo = 1;
          # WORD hi = 1;
          # WPARAM wp;
          # wp = MAKEWPARAM( lo, hi );
          # // so now wp is 65537
          # // which is also hi >> 16 + lo
          # // which is also 2**16 + 1


          my $loword = 1;
          my $hiword = 1;
          my $wparam;

          # from Programming Perl chapter 2, "The Gory Details"
          # by the way, the books on CD make this MUCH
          # easier to search for.

          print "lo = $loword\n";
          print "hi = $hiword\n";
          print "goal:: combine them to get 65537\n";

          my $shifty = $hiword << 16;

          print "after left shift 16 aka 1 << 16 we get: $shifty\n";

          print "to get WPARAM from lo and hi words...\n";
          print 'try: $loword + $hiword << 16' . "\n";

          # note that parens are needed
          # otherwise <<16 is applied to the sum.

          $wparam = $loword + ( $hiword << 16 );

          print "$loword + ( $hiword << 16 ) = $wparam\n";

          # postmessage
          # WM_LBUTTONDOWN
          #
          # Use the following code to obtain the horizontal and vertical position:
          #
          # xPos = GET_X_LPARAM(lParam);
          # yPos = GET_Y_LPARAM(lParam);

          # output:
          # lo = 1
          # hi = 1
          # goal:: combine them to get 65537
          # after left shift 16 aka 1 << 16 we get: 65536
          # to get WPARAM from lo and hi words...
          # try: $loword + $hiword << 16
          # 1 + ( 1 << 16 ) = 65537
          << end of Perl code <<

          >> start of C++ code >>

          // wparam2.cpp : Defines the entry point for the console application.
          //

          #include "stdafx.h"
          #include "wparam2.h"

          #ifdef _DEBUG
          #define new DEBUG_NEW
          #undef THIS_FILE
          static char THIS_FILE[] = __FILE__;
          #endif

          ////////////////////////////////////////////////////////////////////////////
          /
          // The one and only application object

          CWinApp theApp;

          using namespace std;

          int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
          {
          int nRetCode = 0;

          // initialize MFC and print and error on failure
          if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(),
          0))
          {
          // TODO: change error code to suit your needs
          cerr << _T("Fatal Error: MFC initialization failed") <<
          endl;
          nRetCode = 1;
          }
          else
          {
          // TODO: code your application's behavior here.
          CString strHello;
          strHello.LoadString(IDS_HELLO);
          cout << (LPCTSTR)strHello << endl;
          }

          // postmessage

          WORD lo;
          WORD hi;
          WPARAM wparam = 0;
          LPARAM lparam = 0;


          lo = 1;
          hi = 1;
          wparam = 0;
          lparam = 0;

          wparam = MAKEWPARAM( lo, hi );
          lparam = MAKELPARAM( lo, hi );

          cout << "lo:" << lo << endl;
          cout << "hi:" << hi << endl;
          cout << "wparam:" << wparam << endl;
          cout << "lparam:" << lparam << endl;


          lo = 0;
          hi = 1;
          wparam = 0;

          wparam = MAKEWPARAM( lo, hi );

          cout << "lo:" << lo << endl;
          cout << "hi:" << hi << endl;
          cout << "wparam:" << wparam << endl;


          lo = 0xff;
          hi = 0xFF;
          wparam = 0;

          wparam = MAKEWPARAM( lo, hi );

          cout << "lo:" << lo << endl;
          cout << "hi:" << hi << endl;
          cout << "wparam:" << wparam << endl;

          int bit = 1;
          int i = 0;
          cout << i << ": bit = " << bit << endl;
          for( i = 0 ; i < 16 ; i ++ )
          {
          bit = bit << 1;
          cout << i << ": bit = " << bit << endl;
          }

          WPARAM hand_rolled = bit;

          cout << "hand_rolled:" << hand_rolled << endl;

          LPARAM lParam = hand_rolled;

          // I get compile errors, and I'm too lazy to find the includes
          // int xPos = GET_X_LPARAM(lParam);
          // int yPos = GET_Y_LPARAM(lParam);

          // cout << "xPos:" << xPos << endl;
          // cout << "yPos:" << yPos << endl;

          return nRetCode;
          }



          // the output from this is:


          // C:\tom\code\wparam2\Debug>wparam2.exe
          // Hello from MFC!
          // lo:1
          // hi:1
          // wparam:65537
          // lparam:65537
          // lo:0
          // hi:1
          // wparam:65536
          // lo:65535
          // hi:65535
          // wparam:4294967295
          // 0: bit = 1
          // 0: bit = 2
          // 1: bit = 4
          // 2: bit = 8
          // 3: bit = 16
          // 4: bit = 32
          // 5: bit = 64
          // 6: bit = 128
          // 7: bit = 256
          // 8: bit = 512
          // 9: bit = 1024
          // 10: bit = 2048
          // 11: bit = 4096
          // 12: bit = 8192
          // 13: bit = 16384
          // 14: bit = 32768
          // 15: bit = 65536
          // hand_rolled:65536
          //


          << end of C++ code <<


          -------------------------------------------------------------------------------
          This message and any included attachments are from Siemens Medical Solutions
          USA, Inc. and are intended only for the addressee(s).
          The information contained herein may include trade secrets or privileged or
          otherwise confidential information. Unauthorized review, forwarding, printing,
          copying, distributing, or using such information is strictly prohibited and may
          be unlawful. If you received this message in error, or have reason to believe
          you are not authorized to receive it, please promptly delete this message and
          notify the sender by e-mail with a copy to Central.SecurityOffice@...

          Thank you

          [Non-text portions of this message have been removed]
        Your message has been successfully submitted and would be delivered to recipients shortly.