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

WM_LBUTTONDOWN and LPARAM

Expand Messages
  • pkaluski
    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
    Message 1 of 5 , Feb 2 4:02 AM
    • 0 Attachment
      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
    • Chris Hilton
      There s a macro for use in C programming that puts this together for you called MAKELPARAM (you can see an example of it in use in some random code I found
      Message 2 of 5 , Feb 2 11:52 AM
      • 0 Attachment
        There's a macro for use in C programming that puts this together for you
        called MAKELPARAM (you can see an example of it in use in some random code I
        found here:
        http://koders.com/c++/fid79F5331FDCF11E46A2A0C5B6F6B7681D81B5E1DB.aspx
        <http://koders.com/c++/fid79F5331FDCF11E46A2A0C5B6F6B7681D81B5E1DB.aspx> ).
        So, you want to replicate that behavior in Perl. MAKELPARAM is defined in
        winuser.h, where I see:

        #define MAKELPARAM(l, h) (LPARAM)MAKELONG(l, h)

        So it just passes through to the MAKELONG macro. MAKELONG is defined in
        windef.h, where I see:

        #define MAKELONG(a, b) ((LONG)(((WORD)(a)) | ((DWORD)((WORD)(b))) <<
        16))

        Translating that to Perl, it looks to me like you just need something like:

        $LPARAM = $x | ($y << 16);

        Your mileage may vary.

        Chris

        -----Original Message-----
        From: pkaluski [mailto:pkaluski@...]
        Sent: Wednesday, 02 February, 2005 06:03
        To: perlguitest@yahoogroups.com
        Subject: [perlguitest] WM_LBUTTONDOWN and LPARAM



        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 ) ?




        [Non-text portions of this message have been removed]
      • Dennis K. Paulsen
        You could also use one of the Win32::GUITest functions or the MouseClick function mentioned in this group -D
        Message 3 of 5 , Feb 2 3:21 PM
        • 0 Attachment
          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 4 of 5 , Feb 2 10:47 PM
          • 0 Attachment
            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 5 of 5 , Feb 3 11:13 AM
            • 0 Attachment
              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.