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

Re: WM_LBUTTONDOWN and LPARAM

Expand Messages
  • 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 1 of 5 , Feb 2, 2005
    View Source
    • 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 2 of 5 , Feb 3, 2005
      View Source
      • 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.