translatemessage,C语言如何模拟键盘输入?
C语言模拟键盘代码如下:
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR szCmdLine,int iCmdShow)
{
MSG msg;
if(!MyRegisterClass(hInstance))
{
return FALSE;
}
if(!InitInstance(hInstance,iCmdShow))
{
return FALSE;
}
while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg);
DispatchMessage (&msg);
}
return msg.wParam;
}
//函数:ShowKey
//作用:实现在窗口中显示按键信息
void ShowKey (HWND hwnd, int iType,char *szMessage,WPARAM wParam,LPARAM lParam)
{
static char *szFormat[2] ={"%-14s %3d %c %6u %4d %5s %5s %6s %6s",
"%-14s %3d %c %6u %4d %5s %5s %6s %6s" };
char szBuffer[80];
HDC hdc;
ScrollWindowEx(hwnd, 0, -yChar, &rc,&rc,NULL,NULL,SW_INVALIDATE);
hdc = GetDC (hwnd);
SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT));
TextOut (hdc,
xChar,
rc.bottom - yChar,
szBuffer,
wsprintf szBuffer,
szFormat[iType]。
win32怎么触发窗口wm?
1.程序初始化时候,窗口创建完毕,调用UpdateWindow(hwnd);可以触发WM_PAINT消息.
#include <windows.h>
LRESULT CALLBACK myWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);//给消息线程发送WM_QUIET消息,导致 GetMessage()返回0,从而结束程序
break;
case WM_PAINT:
{
OutputDebugStringA("wm paint message \n\n");
int i; //使用目前的方式会导致系统不断的重发WM_PAINT消息
}
break;
default:
return DefWindowProc(hwnd, message, wParam, lParam);
}
return 0;//返回0,表示应用程序处理了.
}
int WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nShowCmd)
{
//1.注册窗口类
WNDCLASS wnd;
wnd.cbClsExtra = 0;
wnd.cbWndExtra = 0;
wnd.hInstance = hInstance;
wnd.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wnd.hCursor = LoadCursor(hInstance, IDC_ARROW);
wnd.hIcon = LoadIcon(hInstance, IDI_APPLICATION);
wnd.lpszClassName = L"hello";
wnd.lpszMenuName = NULL;
wnd.style = CS_VREDRAW | CS_HREDRAW;
wnd.lpfnWndProc = myWndProc;
int ec = RegisterClass(&wnd);
if (ec == 0)
{
int errorCode = GetLastError();
return -1;
}
//创建窗口
HWND hwnd = CreateWindow(L"hello", L"windows title", WS_OVERLAPPEDWINDOW, 0, 0, 500, 500, NULL, NULL, hInstance, NULL);
if (hwnd == NULL)
{
//创建窗口失败
return -1;
}
ShowWindow(hwnd,nShowCmd);
UpdateWindow(hwnd);//会发送WM_PAINT消息--不经过消息队列
msg msg;
while (GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
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
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
这个时候我们会发现,我们会不断的接收到WM_PAINT消息,这是为什么呢?
原因是这样的:
1.首先当我们调用UpdateWindow后,系统会直接像窗口处理函数发送WM_PAINT消息,不会把这消息塞入到窗口的消息队列中,如果我们不做任何处理,也不把WM_PAINT交给DefWndProc,类似上面的代码:
case WM_PAINT:
{
OutputDebugStringA("wm paint message \n\n");
int i; //使用目前的方式会导致系统不断的重发WM_PAINT消息
}
1
2
3
4
5
1
2
3
4
5
(因为这个时候系统检测到窗口还是无效的,所以给窗口消息处理线程发送WM_PAINT消息,告诉应用层需要处理WM_PAINT)
如果不做任何处理,系统就会把WM_PAINT塞入到窗口的消息队列中,我们可以消息GetMessage后,对WM_PAINT消息进行捕捉,绝对可以捕捉到.
while (GetMessage(&msg,NULL,0,0))
{
if ( msg.message == WM_PAINT)
{
int i = 0; /
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
1
2
3
4
5
6
7
8
9
1
2
3
4
5
6
7
8
9
正确的做法是:
case WM_PAINT:
{
OutputDebugStringA("wm paint message \n\n");
int i; //使用目前的方式会导致系统不断的重发WM_PAINT消息
//开始绘制,变为有效区域
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
//draw something
EndPaint(hwnd, &ps);
}
break
1
2
3
4
5
6
7
8
9
10
11
12
13
14
1
2
3
4
5
6
7
8
9
10
11
12
13
14
或者直接调用DefWindowProc(hwnd, message, wParam, lParam),WM_PAINT就不会不停的发送了.
当我们不断的调整窗口大小的时候,会导致WM_PAINT的消息触发,注意正常的拖动窗口并不会导致WM_PAINT消息的触发,但是当当前当窗口拖动到屏幕外时,会触发WM_PAINT消息.
3.窗口最小化的时候不会触发WM_PAINT消息,但是当窗口最大化后,会触发WM_PAINT消息,但是注意:这个触发的消息机制是系统往窗口的消息队列中发送了消息,并非直接调用的窗口函数.
4.当调用invalidateRect函数调用时,也会触发WM_PAINT消息.
上面的窗口显示区域无效和有效的理解,个人认为百度词条的解释还是相当的靠谱的:
个人的理解就是:
有效就是当我们自己在窗口上绘制之后,窗口区域就变为了有效。
当窗口区域需要被重绘时,就是无效区域,窗口什么时候需要被重绘? 比如放大/缩小窗口都会导致窗口client区域变为无效区域,这个时候需要重绘.
还没有评论,来说两句吧...