Summary of vc6 Mouse capture events (move, click, etc.) (MFC message, driectinput, Hook)

Source: Internet
Author: User

To achieve Remote Control recently, you need to capture local mouse information and transmit it to a remote computer.

Mouse events are nothing more than wm_lbuttondown, wm_lbuttonup, and wm_mousemove (Let's talk about these basic three commands). In the beginning, we thought it was easy to get these events, but in the implementation process, it is not as simple as imagined:

① In the dialog box Application Based on MFC, you can obtain it in pretranslatemessage (the pretranslatemessage in the [Main Dialog Box] or [cwinapp]. It should be said that the pretranslatemessage in [cwinapp] is better ), as follows:

Bool ctestapp: pretranslatemessage (MSG * PMSG) {If (PMSG-> message = wm_lbuttondown) // left click to press {If (m_bsend) {cpoint pt; getcursorpos (& pt ); memset (szmsg, '\ 0', sizeof (szmsg); sprintf (szmsg, "wm_lbd; % d; 0; \ 0", PT. x, PT. y, keyflags); lansend (szmsg, strlen (szmsg) ;}} else if (PMSG-> message = wm_lbuttonup) // left-click lift {If (m_bsend) {cpoint pt; getcursorpos (& pt); memset (szmsg, '\ 0', sizeof (szmsg); sprintf (szmsg, "wm_lbu; % d; % d; 0; \ 0 ", PT. x, PT. y, keyflags); lansend (szmsg, strlen (szmsg) ;}} else if (PMSG-> message = wm_mousemove) // move the cursor {If (m_bsend) {point pt;: getcursorpos (& pt); memset (szmsg, '\ 0', sizeof (szmsg); // sprintf (szmsg, "wm_mm; % d; % d; 0; \ 0 ", get_x_lparam (PMSG-> lparam), get_y_lparam (PMSG-> lparam), 0); sprintf (szmsg," wm_mm; % d; 0; \ 0 ", PT. x, PT. y, 0); lansend (szmsg, strlen (szmsg) ;}} else if (PMSG-> message = wm_keydown) // press the keyboard {If (m_bsend) {memset (szmsg, '\ 0', sizeof (szmsg); sprintf (szmsg, "wm_kd; % d; \ 0 ", PMSG-> wparam, 0, 0, 0); lansend (szmsg, strlen (szmsg) ;}} else if (PMSG-> message = wm_keyup) // keyboard lift {If (m_bsend) {memset (szmsg, '\ 0', sizeof (szmsg); sprintf (szmsg, "wm_ku; % d; % d; \ 0 ", PMSG-> wparam, 0, 0, 0); lansend (szmsg, strlen (szmsg);} return cdialog :: pretranslatemessage (PMSG );}

Three basic commands are implemented above, but there is a problem: when the current position of the mouse leaves the application (dialog box), the mouse data cannot be captured.
Why is there such an application? For example, if you click a button in an application to open a cmd command line Console window (to verify whether the other party can ping), the mouse data cannot be captured in the pop-up cmd window;
Why is pretranslatemessage in [cwinapp] Better "? If the application to be compiled has multiple dialog S, isn't it necessary to write a pretranslatemessage for each window!

② How to get the mouse in the "entire system? Think of driectinput and mouse hooks in driectx. First, let's talk about driectinput. Below is a section that gets mouse data from a timer or thread: (the initialization part will not be pasted)

Hresult readimmediatedata (hwnd hdlg) {hresult hr; tchar strnewtext [128] = text (""); // output string dimousestate2 dims2; // directinput mouse state structure if (null = g_pmouse) return s_ OK; // get the input's device state, and put the state in dims zeromemory (& dims2, sizeof (dims2); HR = g_pmouse-> getdevicestate (sizeof (dimousestate2), & dims2); If (failed (HR) {// directinput may be Tel Ling us that the input stream has been // interrupted. we aren't tracking any state between polls, so // we don't have any special reset that needs to be done. // We just re-acquire and try again. // If input is lost then acquire and keep trying hR = g_pmouse-> acquire (); While (hR = dierr_inputlost) HR = g_pmouse-> acquire (); // update the dialog text if (hR = dierr_otherapphasprio | hR = Dier R_notacquired) setdlgitemtext (hdlg, idc_data, text ("unacquired"); // HR may be dierr_otherapphasprio or other errors. this // may occur when the app is minimized or in the process of // switching, so just try again later return s_ OK ;} // The dims structure now has the state of the mouse, so // display mouse coordinates (x, y, z) and buttons. stringcchprintf (strnewtext, 128, text ("(x = % 3.3d, Y = % 3.3d, Z = % 3.3d) b0 = % C b1 = % C b2 = % C B3 = % C B4 = % C B5 = % C B6 = % C B7 = % C "), dims2.lx, dims2.ly, dims2.lz, (dims2.rgbbuttons [0] & 0x80 )? '1': '0', (dims2.rgbbuttons [1] & 0x80 )? '1': '0', (dims2.rgbbuttons [2] & 0x80 )? '1': '0', (dims2.rgbbuttons [3] & 0x80 )? '1': '0', (dims2.rgbbuttons [4] & 0x80 )? '1': '0', (dims2.rgbbuttons [5] & 0x80 )? '1': '0', (dims2.rgbbuttons [6] & 0x80 )? '1': '0', (dims2.rgbbuttons [7] & 0x80 )? '1': '0'); // get the old text in the text box tchar stroldtext [128]; getdlgitemtext (hdlg, idc_data, stroldtext, 127 ); // if nothing changed then don't repaint-avoid flicker if (0! = Lstrcmp (stroldtext, strnewtext) setdlgitemtext (hdlg, idc_data, strnewtext); // still use :: absolute position of the cursor sent by getcursorpos // char szmsg [100] = {0}; point pt;: getcursorpos (& pt); sprintf (szmsg, "wm_mm; % d; % d; 0; \ 0 ", PT. x, PT. y, 0); lansend (szmsg, strlen (szmsg )); //// send the "Press" and "lift" events of the mouse. // The mouse lift events cannot be identified in driectinput, here we can only simulate lift // If (dims2.rgbbuttons [0] & 0x80) {getcursorpos (& pt); sprintf (szmsg, "wm_lbd; % d; 0; \ 0 ", PT. x, PT. y, 0); lansend (szmsg, strlen (szmsg); sleep (2); sprintf (szmsg, "wm_lbu; % d; 0; \ 0 ", PT. x, PT. y, 0); lansend (szmsg, strlen (szmsg);} return s_ OK ;}

There are several limitations in using directinput. One is that the above program shows that moving the mouse gives "relative position" rather than "absolute position" (how can the two convert in directinput, I didn't try it out). I still had to use: getcursorpos in Win32; second, I could only judge that the mouse was "clicked" and the mouse was not recognized as "lifted, I simulated a "lift" Event 2 ms after the click delay, but this is not the real behavior of the user in the operation;
③ Continue with the low-level mouse HOOK: wh_mouse_ll is used, and the corresponding hook function is lowlevelmouseproc. The advantage is that you do not need to write a dll library and use it directly in the application;

/// Global variables and global function definitions // hhook hhookms = NULL; lresult callback lowlevelmouseproc (INT ncode, wparam, lparam); bool uninstallkbhook (); bool installkbhook (); // install the mouse hook // void ctestmfcdlg: onbutton1 () {installkbhook () ;}/// unload the keyboard hook // void ctestmfcdlg :: onbutton2 () {uninstallkbhook ();} lresult callback lowlevelmouseproc (INT ncode, wparam, lparam) {msllhookstruct * pkbhs = (msllhookst Ruct *) lparam; char strmsg [100] = {0}; Switch (ncode) {Case hc_action: {// move the mouse if (wparam = wm_mousemove) {sprintf (strmsg, "wm_mousemove: x = % d, y = % d \ n", pkbhs-> PT. x, pkbhs-> PT. y); outputdebugstring (strmsg);} // left-click if (wparam = wm_lbuttondown) {sprintf (strmsg, "wm_lbuttondown: x = % d, y = % d \ n ", pkbhs-> PT. x, pkbhs-> PT. y); outputdebugstring (strmsg);} // scroll wheel event // If (wparam = wm_mousewheel) // {// sprintf (Strmsg, "wm_mousewheel: % d \ n", hiword (pkbhs-> mousedata); // outputdebugstring (strmsg); //} default: break ;} return callback (null, ncode, wparam, lparam);} bool installkbhook () {If (hhookms) uninstallkbhook (); hhookms = callback (wh_mouse_ll, (hookproc) callback, afxgetapp () -> m_hinstance, null); Return (hhookms! = NULL);} bool uninstallkbhook () {bool Fok = false; If (hhookms) {Fok = unhookwindowshookex (hhookms); hhookms = NULL;} return (FOK );}

A low-level mouse hook is global. If the hook is successfully installed, it is effective throughout the system and basically solves this problem.
To sum up, we decided to use a low-level mouse hook.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.