Fing click mosue winapi

Hello,

Please help, I’ve been suffering for the fourth day to find out when the mouse button is clicked.
If I understand correctly, I need to use such functions and structures as: GetRawInputData, RAWINPUT, WM_INPUT, WindowProc.
But I just can not understand how to use them and in what sequence (((((
It would be more helpful if you give more information of what you are doing.
Is this a Windows app?
In a windows app you normally handle mouse messages inside the main window function.
https://docs.microsoft.com/en-us/windows/win32/learnwin32/mouse-clicks
Yes it's windows.

Thanks for the link. There is text:

"If the user clicks a mouse button while the cursor is over the client area of a window, the window receives one of the following messages."

I can’t understand what is meant by "the client area of a window".
If I do not have this client window?
The client area is the inside area of window without the title bar, menu, statusbar.
Every main window has one.
And if for example, if the mouse cursor is simply located on the desktop?
Parts of a Windows app window:
https://docs.microsoft.com/en-us/windows/win32/winmsg/images/cswin-02.png

Win32 API code for processing a single click mouse message:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#include <windows.h>
#include <strsafe.h>

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int nWinMode)
{
   const TCHAR szWinName[] = TEXT("WIN0203");
   WNDCLASSEX  wc;

   wc.cbSize        = sizeof(WNDCLASSEX);
   wc.style         = CS_HREDRAW | CS_VREDRAW;
   wc.lpfnWndProc   = WndProc;
   wc.cbClsExtra    = 0;
   wc.cbWndExtra    = 0;
   wc.hInstance     = hInstance;
   wc.hIcon         = (HICON)   LoadImage(NULL, IDI_APPLICATION, IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR);
   wc.hIconSm       = (HICON)   LoadImage(NULL, IDI_APPLICATION, IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR);
   wc.hCursor       = (HCURSOR) LoadImage(NULL, IDC_ARROW, IMAGE_CURSOR, 0, 0, LR_SHARED);
   wc.hbrBackground = (HBRUSH)  (COLOR_WINDOW + 1);
   wc.lpszMenuName  = NULL;
   wc.lpszClassName = szWinName;

   if (0 == RegisterClassEx(&wc))
   {
      MessageBox(NULL, TEXT("Couldn't Register the Window Class!"), TEXT("ERROR"), MB_OK | MB_ICONERROR);
      return E_FAIL;
   }

   const TCHAR szAppTitle[] = TEXT("Processing Mouse Messages");

   HWND hwnd = CreateWindow(szWinName, szAppTitle,
                            WS_OVERLAPPEDWINDOW,
                            CW_USEDEFAULT, CW_USEDEFAULT,
                            CW_USEDEFAULT, CW_USEDEFAULT,
                            NULL, NULL, hInstance, NULL);

   if (hwnd == NULL)
   {
      MessageBox(NULL, TEXT("Couldn't Create the Main Window!"), TEXT("ERROR"), MB_OK | MB_ICONERROR);
      return E_FAIL;
   }

   ShowWindow(hwnd, nWinMode);
   UpdateWindow(hwnd);

   MSG msg;

   while (GetMessage(&msg, NULL, 0, 0))
   {
      TranslateMessage(&msg);
      DispatchMessage(&msg);
   }

   return (int) msg.wParam;
}


LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
   const size_t  strSize      = 255;
   static TCHAR  str[strSize] = TEXT(" ");
   static size_t strLen       = 0;
   HDC           hdc;

   switch(message)
   {
      // process left mouse button
      case WM_LBUTTONDOWN:
         hdc = GetDC(hwnd);

         // stringize where the left mouse button was pressed
         StringCchPrintf(str, strSize, TEXT("Left button is down at %d x %d"), LOWORD(lParam), HIWORD(lParam));
         StringCchLength(str, (int) strSize, &strLen);
         TextOut(hdc, LOWORD(lParam), HIWORD(lParam), str, (int) strLen);

         ReleaseDC(hwnd, hdc);
         return S_OK;

      // process right mouse button
      case WM_RBUTTONDOWN:
         hdc = GetDC(hwnd);

         // stringize where the right mouse button was pressed
         StringCchPrintf(str, strSize, TEXT("Right button is down at %d x %d"), LOWORD(lParam), HIWORD(lParam));
         StringCchLength(str, (int) strSize, &strLen);
         TextOut(hdc, LOWORD(lParam), HIWORD(lParam), str, (int) strLen);

         ReleaseDC(hwnd, hdc);
         return S_OK;

      case WM_DESTROY:
         PostQuitMessage(0);
         return S_OK;
   }

   return DefWindowProc(hwnd, message, wParam, lParam);
}
Adding double-click support is not complicated, even if you want to be able to modify the double-click time interval in the app, just for the app:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
#include <windows.h>
#include <strsafe.h>

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int nWinMode)
{
   const TCHAR szWinName[] = TEXT("WIN0204");
   WNDCLASSEX  wc;

   UINT        OrgDblClkTime;  // holds original double-click interval

   wc.cbSize        = sizeof(WNDCLASSEX);
   wc.hInstance     = hInstance;
   wc.lpszClassName = szWinName;
   wc.lpfnWndProc   = WndProc;

   // enable double-clicks
   wc.style         = CS_DBLCLKS;

   wc.hIcon         = (HICON)   LoadImage(NULL, IDI_APPLICATION, IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR);
   wc.hIconSm       = (HICON)   LoadImage(NULL, IDI_APPLICATION, IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR);
   wc.hCursor       = (HCURSOR) LoadImage(NULL, IDC_ARROW, IMAGE_CURSOR, 0, 0, LR_SHARED);
   wc.lpszMenuName  = NULL;
   wc.cbClsExtra    = 0;
   wc.cbWndExtra    = 0;
   wc.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);

   if (RegisterClassEx(&wc) == 0)
   {
      MessageBox(NULL, TEXT("Couldn't Register the Window Class!"), TEXT("ERROR"), MB_OK | MB_ICONERROR);
      return E_FAIL;
   }

   const TCHAR szAppTitle[] = TEXT("Processing Double-Click Messages");

   HWND hwnd = CreateWindow(szWinName, szAppTitle,
                            WS_OVERLAPPEDWINDOW,
                            CW_USEDEFAULT, CW_USEDEFAULT,
                            CW_USEDEFAULT, CW_USEDEFAULT,
                            NULL, NULL, hInstance, NULL);

   if (hwnd == NULL)
   {
      MessageBox(NULL, TEXT("Couldn't Create the Main Window!"), TEXT("ERROR"), MB_OK | MB_ICONERROR);
      return E_FAIL;
   }

   // save the original double-click time
   OrgDblClkTime = GetDoubleClickTime();

   ShowWindow(hwnd, nWinMode);
   UpdateWindow(hwnd);

   MSG msg;

   while (GetMessage(&msg, NULL, 0, 0))
   {
      TranslateMessage(&msg);
      DispatchMessage(&msg);
   }

   // restore original double-click interval
   SetDoubleClickTime(OrgDblClkTime);

   return (int) msg.wParam;
}


LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
   const size_t  strSize      = 255;
   static TCHAR  str[strSize] = TEXT("");
   static size_t strLen       = 0;
   HDC           hdc;
   UINT          interval;

   switch(message)
   {
      case WM_CHAR:
         // does the user want to increase the interval? (Slower)
         if (toupper((TCHAR) wParam) == TEXT('S'))
         {
            // increase the interval
            interval = GetDoubleClickTime();
            interval += 100;

            SetDoubleClickTime(interval);
         }
         // does the user want to decrease the interval? (Faster)
         else if (toupper((TCHAR) wParam) == TEXT('F'))
         {
            // decrease the interval
            interval = GetDoubleClickTime();
            interval -= 100;

            if (interval < 0)
            {
               interval = 0;
            }

            SetDoubleClickTime(interval);
         }
         else
         {
            // leave the interval the same
            interval = GetDoubleClickTime();
         }

         hdc = GetDC(hwnd);

         StringCchPrintf(str, strSize, TEXT("Interval is %u milliseconds.     "), interval);
         StringCchLength(str, (int) strSize, &strLen);
         TextOut(hdc, 4, 1, str, (int) strLen);

         ReleaseDC(hwnd, hdc);
         return S_OK;

      case WM_LBUTTONDOWN:
         hdc = GetDC(hwnd);

         StringCchPrintf(str, strSize, TEXT("Left button is down at %d x %d"), LOWORD(lParam), HIWORD(lParam));
         StringCchLength(str, (int) strSize, &strLen);
         TextOut(hdc, LOWORD(lParam), HIWORD(lParam), str, (int) strLen);

         ReleaseDC(hwnd, hdc);
         return S_OK;

      case WM_RBUTTONDOWN:
         hdc = GetDC(hwnd);

         StringCchPrintf(str, strSize, TEXT("Right button is down at %d x %d"), LOWORD(lParam), HIWORD(lParam));
         StringCchLength(str, (int) strSize, &strLen);
         TextOut(hdc, LOWORD(lParam), HIWORD(lParam), str, (int) strLen);

         ReleaseDC(hwnd, hdc);
         return S_OK;

      case WM_LBUTTONDBLCLK:
         interval = GetDoubleClickTime();
         hdc      = GetDC(hwnd);

         StringCchPrintf(str, strSize, TEXT("Left Button Double-Click is %u milliseconds.  "), interval);
         StringCchLength(str, (int) strSize, &strLen);
         TextOut(hdc, LOWORD(lParam), HIWORD(lParam), str, (int) strLen);

         ReleaseDC(hwnd, hdc);
         return S_OK;

      case WM_RBUTTONDBLCLK:
         interval = GetDoubleClickTime();
         hdc      = GetDC(hwnd);

         StringCchPrintf(str, strSize, TEXT("Right Button Double-Click is %u milliseconds.  "), interval);
         StringCchLength(str, (int) strSize, &strLen);
         TextOut(hdc, LOWORD(lParam), HIWORD(lParam), str, (int) strLen);

         ReleaseDC(hwnd, hdc);
         return S_OK;

      case WM_DESTROY:
         PostQuitMessage(0);
         return S_OK;
   }

   return DefWindowProc(hwnd, message, wParam, lParam);
}
Thanks, I didn’t understand anything.
Maybe you should start from the beginning: http://www.winprog.org/tutorial/
The problem is that for some reason all these functions are tied to windows, that is, I can’t just count the mouse clicks without being bound to any particular window, I always need to know which window the mouse cursor is in and for this window to catch mouse messages .
I think this is very inconvenient.
Did you even bother to look at the link Ganado gave you?

What you think you are trying to do won't be easy, and could be seen as a virus by anti-virus software if you aren't careful.

I didn’t understand anything.

If you don't understand even the simplest WinApi code for detecting and responding to mouse single and double clicks in an app's client area, then you need some serious study time.

Trying to do a global mouse hook is not for a noob.
Topic archived. No new replies allowed.