- 了解窗口
每个GUI应用程序至少要创建一个窗口,称为主窗口。每个窗口都在显示输出和从用户取得输入方面起着一定的作用。
窗口客户区是应用程序显示输出的部分。应用程序必须提供一个称为窗口函数的回调函数来处理窗口的输入,向客户区显示输出。
- 第一个窗口程序
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20int APIENTRY WinMain( HINSTANCE hInstance, //本模块的实例句柄 HINSTANCE hPrevInstance, //win16留下的产物,现在已经不用了 LPSTR lpCmdLine, //命令行参数 int nCmdShow //主窗口初始化时的显示方式 ) GUI应用程序的入口函数是WinMain,这是一个自定义的回调函数。 APIENTRY的宏定义是__stdcall hInstance = (HINSTANCE)GetModuleHandle(NULL); //取得应用程序的实例句柄(即模块句柄) 参数为NULL时,返回可执行文件所在模块的模块句柄,而不管是在哪个模块中做调用的。 int MessageBox( HWND hWnd, //一个窗口句柄,它指定哪一个窗口将拥有要创建的消息框 LPCTSTR lpText, //将要显示的消息 LPCTSTR lpCaption, //对话框标题 UINT uType //指定对话框的内容和行为 ); 返回值: IDOK、IDYES、IDNO、IDCANCEL、IDABORT、IDRETRY、IDIGNORE等
-
MessageBox中的uType参数
-
示例:简单的win32
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18// 04Win32AppDemo.cpp : Defines the entry point for the application. // #include "stdafx.h" int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { // 弹出一个对话框 MessageBox(NULL,"Hello,Win32 Application","04Win32AppDemo",MB_OK); MessageBox(NULL,"Hello,Win32 Application","04Win32AppDemo",MB_YESNOCANCEL|MB_ICONQUESTION|MB_DEFBUTTON3) return 0; }
- windows消息驱动
鼠标或键盘在桌面操作时,windows会源源不段地向程序发送消息,操作这个过程的函数为窗口函数。原型如下:
复制代码
1
2
3
4
5LRESULT CALLBACK WindowProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam); CALLBACK 宏定义是__stdcall uMsg:消息ID号,诸如MessageBox中的IDYES等等 wParam和lParam是消息ID的附加参数
- 示例:收到WM_CLOSE消息关闭窗口
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23// 04TellToClose.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include "windows.h" #include "stdio.h" int main(int argc, char* argv[]) { HWND hWnd = FindWindow(NULL,"无标题 - 记事本"); if(hWnd != NULL) { //向目标窗口发送WM_CLOSE消息 SendMessage(hWnd,WM_CLOSE,0,0); } return 0; }
桌面显示一个窗口的具体步骤:
- 注册窗口类(RegisterClassEx)
- 创建窗口 (CreateWindowEx)
- 在桌面显示窗口 (ShowWindow)
- 更新窗口客户区(UpdateWindow)
- 进入无限的消息循环处理
- 获取消息GetMessage
- DispatchMessage
- 消息处理MainWndProc函数
示例:最简单的windows程序
复制代码
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// 04FirstWindow.cpp : Defines the entry point for the application. // #include "stdafx.h" #include "windows.h" #include "stdio.h" LRESULT CALLBACK MainWndProc(HWND,UINT,WPARAM,LPARAM); int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { char szClassName[] = "MainClass"; WNDCLASSEX wndclass; //用于描述主窗口的参数填充WNDCLASSEX结构 wndclass.cbSize = sizeof(wndclass); //结构的大小 wndclass.style = CS_HREDRAW | CS_VREDRAW; //指定如果大小改变就重画 wndclass.lpfnWndProc = MainWndProc; //窗口函数指针 wndclass.cbClsExtra = 0; //没有额外的类内存 wndclass.cbWndExtra = 0; //没有额外的窗口内存 wndclass.hInstance = hInstance; //实例句柄 wndclass.hIcon = LoadIcon(NULL,IDI_APPLICATION); //使用预定义图标 wndclass.hCursor = LoadCursor(NULL,IDC_ARROW); //使用预定义光标 wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); //使用白色背景画刷 wndclass.lpszMenuName = NULL; //不指定菜单 wndclass.lpszClassName = szClassName; //窗口类的名称 wndclass.hIconSm = NULL; //没有类的小图标 //注册这个窗口类 RegisterClassEx(&wndclass); //创建主窗口 HWND hwnd = CreateWindowEx( 0, //dwExSytle,扩展 szClassName, //lpClassName,窗口类名 "My first Window!", //lpWindowName,标题 WS_OVERLAPPEDWINDOW, //dwStyle,窗口风格 CW_USEDEFAULT, //X,初始化X坐标 CW_USEDEFAULT, //y,初始化Y坐标 CW_USEDEFAULT, //nWidth,宽度 CW_USEDEFAULT, //nHeight,高度 NULL, //hWindParent 父窗口句柄 NULL, //hMenu 菜单句柄 hInstance, //hInstance,程序实例句柄 NULL //lpParam,用户数据 ); if(hwnd == NULL) { MessageBox(NULL,"创建窗口出错!","error",MB_OK); return -1; } //显示窗口,刷新窗口客户区 ShowWindow(hwnd,nCmdShow); UpdateWindow(hwnd); //从消息队列中取出消息,交给窗口函数处理,直到GetMessage返回FALSE,结束消息循环 MSG msg; while(GetMessage(&msg,NULL,0,0)) { //转化为键盘消息 TranslateMessage(&msg); //将消息发送到相应的窗口函数 DispatchMessage(&msg); } //当GetMessage返回FALSE时程序结束 return msg.wParam; } LRESULT CALLBACK MainWndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam) { char szText[] = "最简单的窗口程序"; switch(message) { case WM_PAINT: //窗口客户区需要重画 { HDC hdc; PAINTSTRUCT ps; //使无效的客户区变的有效,并取得设备环境句柄 hdc = BeginPaint(hwnd,&ps); //显示文字 TextOut(hdc,10,10,szText,strlen(szText)); EndPaint(hwnd,&ps); return 0; } case WM_DESTROY: //正在销毁窗口 //向消息队列发送一个WM_QUIT消息,促使GetMessage函数返回0,结束消息循环 PostQuitMessage(0); return 0; } //我们不处理的消息交给系统做默认处理 return DefWindowProc(hwnd,message,wParam,lParam); }
- 使用资源
资源是一些二进制数据,它能够添加到基于窗口的应用程序的可执行文件中。资源的源文件是以.rc为扩展名的脚本文件。
在原来的工程下新建一个资源脚本,命令为resource
程序左侧会生成一个resource.rc文件和resource.h文件(隐藏,得去工程目录下查找)
IDI_ICON1和IDR_TYPER可以自定义,且在函数中会使用到
然后右键resource.rc文件,选择插入图标和菜单
插入菜单举例右键打开:
里面的内容通过修改标明项即可自定义内容
ID可以设置为ID_FILE_EXIT
复制代码
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#include "stdafx.h" #include "windows.h" #include "stdio.h" #include "resource.h" LRESULT CALLBACK MainWndProc(HWND,UINT,WPARAM,LPARAM); int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { char szClassName[] = "MainClass"; WNDCLASSEX wndclass; //用于描述主窗口的参数填充WNDCLASSEX结构 wndclass.cbSize = sizeof(wndclass); //结构的大小 wndclass.style = CS_HREDRAW | CS_VREDRAW; //指定如果大小改变就重画 wndclass.lpfnWndProc = MainWndProc; //窗口函数指针 wndclass.cbClsExtra = 0; //没有额外的类内存 wndclass.cbWndExtra = 0; //没有额外的窗口内存 wndclass.hInstance = hInstance; //实例句柄 wndclass.hIcon = LoadIcon(hInstance,(LPSTR)IDI_ICON1); //使用预定义图标 wndclass.hCursor = LoadCursor(NULL,IDC_ARROW); //使用预定义光标 wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); //使用白色背景画刷 wndclass.lpszMenuName = (LPSTR)IDR_TYPER; //指定自定义的菜单 wndclass.lpszClassName = szClassName; //窗口类的名称 wndclass.hIconSm = NULL; //没有类的小图标 //注册这个窗口类 RegisterClassEx(&wndclass); //创建主窗口 HWND hwnd = CreateWindowEx( 0, //dwExSytle,扩展 szClassName, //lpClassName,窗口类名 "My first Window!", //lpWindowName,标题 WS_OVERLAPPEDWINDOW, //dwStyle,窗口风格 CW_USEDEFAULT, //X,初始化X坐标 CW_USEDEFAULT, //y,初始化Y坐标 CW_USEDEFAULT, //nWidth,宽度 CW_USEDEFAULT, //nHeight,高度 NULL, //hWindParent 父窗口句柄 NULL, //hMenu 菜单句柄 hInstance, //hInstance,程序实例句柄 NULL //lpParam,用户数据 ); if(hwnd == NULL) { MessageBox(NULL,"创建窗口出错!","error",MB_OK); return -1; } //显示窗口,刷新窗口客户区 ShowWindow(hwnd,nCmdShow); UpdateWindow(hwnd); //从消息队列中取出消息,交给窗口函数处理,直到GetMessage返回FALSE,结束消息循环 MSG msg; while(GetMessage(&msg,NULL,0,0)) { //转化为键盘消息 TranslateMessage(&msg); //将消息发送到相应的窗口函数 DispatchMessage(&msg); } //当GetMessage返回FALSE时程序结束 return msg.wParam; } LRESULT CALLBACK MainWndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam) { char szText[] = "最简单的窗口程序"; switch(message) { case WM_PAINT: //窗口客户区需要重画 { HDC hdc; PAINTSTRUCT ps; //使无效的客户区变的有效,并取得设备环境句柄 hdc = BeginPaint(hwnd,&ps); //显示文字 TextOut(hdc,10,10,szText,strlen(szText)); EndPaint(hwnd,&ps); return 0; } case WM_COMMAND: switch(LOWORD(wParam)) { case ID_FILE_EXIT: //向hwnd指定的窗口发送一个WM_CLOSE消息 SendMessage(hwnd,WM_CLOSE,0,0); break; } return 0; case WM_CLOSE: //任务管理器还是能干掉 return 0; case WM_DESTROY: //正在销毁窗口 //向消息队列发送一个WM_QUIT消息,促使GetMessage函数返回0,结束消息循环 PostQuitMessage(0); return 0; } //我们不处理的消息交给系统做默认处理 return DefWindowProc(hwnd,message,wParam,lParam); }
生成的图标和菜单如下所示:图标是瞎画的
单击菜单会发送WM_COMMAND消息,而wParam低字节包含了用户单击菜单的ID号
- 接受键盘输入消息
按下一个键时,windows会获得窗口消息队列中传递的WM_KEYDOWN或WM_SYSKEYDOWN消息。释放这个键时,会产生WM_KEYUP或WM_SYSTEMKEYUP消息。 - wParam
wParam包含敲击键的虚拟键码,也包含按键的ANSI码,比如敲“A”键,窗口会受到3个消息:
复制代码
1
2
3
4WM_KETDOWN lParam的含义为虚拟键码“A”(0x41) WM_CHAR lParam的含义为虚拟键码“a”(0x61) WM_KEYUP lParam的含义为虚拟键码“A”(0x41)
示例:打字程序
复制代码
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#include "stdafx.h" #include "windows.h" #include "stdio.h" #include "resource.h" #include <string> LRESULT CALLBACK MainWndProc(HWND,UINT,WPARAM,LPARAM); int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { char szClassName[] = "MainClass"; WNDCLASSEX wndclass; //用于描述主窗口的参数填充WNDCLASSEX结构 wndclass.cbSize = sizeof(wndclass); //结构的大小 wndclass.style = CS_HREDRAW | CS_VREDRAW; //指定如果大小改变就重画 wndclass.lpfnWndProc = MainWndProc; //窗口函数指针 wndclass.cbClsExtra = 0; //没有额外的类内存 wndclass.cbWndExtra = 0; //没有额外的窗口内存 wndclass.hInstance = hInstance; //实例句柄 wndclass.hIcon = LoadIcon(hInstance,(LPSTR)IDI_ICON1); //使用预定义图标 wndclass.hCursor = LoadCursor(NULL,IDC_ARROW); //使用预定义光标 wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); //使用白色背景画刷 wndclass.lpszMenuName = (LPSTR)IDR_TYPER; //指定自定义的菜单 wndclass.lpszClassName = szClassName; //窗口类的名称 wndclass.hIconSm = NULL; //没有类的小图标 //注册这个窗口类 RegisterClassEx(&wndclass); //创建主窗口 HWND hwnd = CreateWindowEx( 0, //dwExSytle,扩展 szClassName, //lpClassName,窗口类名 "My first Window!", //lpWindowName,标题 WS_OVERLAPPEDWINDOW, //dwStyle,窗口风格 CW_USEDEFAULT, //X,初始化X坐标 CW_USEDEFAULT, //y,初始化Y坐标 CW_USEDEFAULT, //nWidth,宽度 CW_USEDEFAULT, //nHeight,高度 NULL, //hWindParent 父窗口句柄 NULL, //hMenu 菜单句柄 hInstance, //hInstance,程序实例句柄 NULL //lpParam,用户数据 ); if(hwnd == NULL) { MessageBox(NULL,"创建窗口出错!","error",MB_OK); return -1; } //显示窗口,刷新窗口客户区 ShowWindow(hwnd,nCmdShow); UpdateWindow(hwnd); //从消息队列中取出消息,交给窗口函数处理,直到GetMessage返回FALSE,结束消息循环 MSG msg; while(GetMessage(&msg,NULL,0,0)) { //转化为键盘消息 TranslateMessage(&msg); //将消息发送到相应的窗口函数 DispatchMessage(&msg); } //当GetMessage返回FALSE时程序结束 return msg.wParam; } LRESULT CALLBACK MainWndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam) { //str对象用于保存窗口客户区显示的字符串 //为了使用string类,包含头文件#include <string> static std::string str; char szText[] = "最简单的窗口程序"; switch(message) { case WM_CREATE: { //设置窗口的标题 SetWindowText(hwnd,"最简陋的打字程序"); return 0; } case WM_PAINT: //窗口客户区需要重画 { HDC hdc; PAINTSTRUCT ps; //使无效的客户区变的有效,并取得设备环境句柄 hdc = BeginPaint(hwnd,&ps); //显示文字 TextOut(hdc,0,0,str.c_str(),str.length()); EndPaint(hwnd,&ps); return 0; } case WM_CHAR: { //保存ANSI码 str = str + char(wParam); //使整个客户区无效 InvalidateRect(hwnd,NULL,0); return 0; } case WM_COMMAND: switch(LOWORD(wParam)) { case ID_FILE_EXIT: //向hwnd指定的窗口发送一个WM_CLOSE消息 SendMessage(hwnd,WM_CLOSE,0,0); break; } return 0; //case WM_CLOSE: //任务管理器还是能干掉 // return 0; case WM_DESTROY: //正在销毁窗口 //向消息队列发送一个WM_QUIT消息,促使GetMessage函数返回0,结束消息循环 PostQuitMessage(0); return 0; } //我们不处理的消息交给系统做默认处理 return DefWindowProc(hwnd,message,wParam,lParam); }
- 接受鼠标输入
按下 | 弹起 | 双击 | |
---|---|---|---|
左键 | WM_LBUTTONDOWN | WM_LBUTTONUP | WM_LBUTTONBLCLK |
中键 | WM_MBUTTONDOWN | WM_MBUTTONUP | WM_MBUTTONBLCLK |
右键 | WM_RBUTTONDOWN | WM_RBUTTONUP | WM_RBUTTONBLCLK |
发送这些消息时,lParam包含了客户区坐标信息
复制代码
1
2
3xPos = LOWORD(lParam); yPos = HIWORD(lParam);
转化为屏幕的坐标信息
复制代码
1
2
3BOOL ClientToScreen(HWND hWnd,LPPOINT lpPoint); //客户区转化为屏幕坐标 BOOL ScreenToClient(HWND hWnd,LPPOINT lpPoint); //屏幕坐标转化为客户区
- wParam参数鼠标按钮信息,以MK_为前缀
复制代码
1
2
3
4
5
6MK_LBUTTON 左键按下 MK_MBUTTON 中间的键按下 MK_RBUTTON 右键按下 MK_SHIFT <Shift>键按下 MK_CONTROL <Ctrl>键按下
- 示例:简陋打字程序之鼠标位置显示
复制代码
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#include "stdafx.h" #include "windows.h" #include "stdio.h" #include "resource.h" #include <string> LRESULT CALLBACK MainWndProc(HWND,UINT,WPARAM,LPARAM); int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { char szClassName[] = "MainClass"; WNDCLASSEX wndclass; //用于描述主窗口的参数填充WNDCLASSEX结构 wndclass.cbSize = sizeof(wndclass); //结构的大小 wndclass.style = CS_HREDRAW | CS_VREDRAW; //指定如果大小改变就重画 wndclass.lpfnWndProc = MainWndProc; //窗口函数指针 wndclass.cbClsExtra = 0; //没有额外的类内存 wndclass.cbWndExtra = 0; //没有额外的窗口内存 wndclass.hInstance = hInstance; //实例句柄 wndclass.hIcon = LoadIcon(hInstance,(LPSTR)IDI_ICON1); //使用预定义图标 wndclass.hCursor = LoadCursor(NULL,IDC_ARROW); //使用预定义光标 wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); //使用白色背景画刷 wndclass.lpszMenuName = (LPSTR)IDR_TYPER; //指定自定义的菜单 wndclass.lpszClassName = szClassName; //窗口类的名称 wndclass.hIconSm = NULL; //没有类的小图标 //注册这个窗口类 RegisterClassEx(&wndclass); //创建主窗口 HWND hwnd = CreateWindowEx( 0, //dwExSytle,扩展 szClassName, //lpClassName,窗口类名 "My first Window!", //lpWindowName,标题 WS_OVERLAPPEDWINDOW, //dwStyle,窗口风格 CW_USEDEFAULT, //X,初始化X坐标 CW_USEDEFAULT, //y,初始化Y坐标 CW_USEDEFAULT, //nWidth,宽度 CW_USEDEFAULT, //nHeight,高度 NULL, //hWindParent 父窗口句柄 NULL, //hMenu 菜单句柄 hInstance, //hInstance,程序实例句柄 NULL //lpParam,用户数据 ); if(hwnd == NULL) { MessageBox(NULL,"创建窗口出错!","error",MB_OK); return -1; } //显示窗口,刷新窗口客户区 ShowWindow(hwnd,nCmdShow); UpdateWindow(hwnd); //从消息队列中取出消息,交给窗口函数处理,直到GetMessage返回FALSE,结束消息循环 MSG msg; while(GetMessage(&msg,NULL,0,0)) { //转化为键盘消息 TranslateMessage(&msg); //将消息发送到相应的窗口函数 DispatchMessage(&msg); } //当GetMessage返回FALSE时程序结束 return msg.wParam; } LRESULT CALLBACK MainWndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam) { //str对象用于保存窗口客户区显示的字符串 //为了使用string类,包含头文件#include <string> static std::string str; char szText[] = "最简单的窗口程序"; switch(message) { case WM_CREATE: { //设置窗口的标题 SetWindowText(hwnd,"最简陋的打字程序"); return 0; } case WM_PAINT: //窗口客户区需要重画 { HDC hdc; PAINTSTRUCT ps; //使无效的客户区变的有效,并取得设备环境句柄 hdc = BeginPaint(hwnd,&ps); //显示文字 TextOut(hdc,0,0,str.c_str(),str.length()); EndPaint(hwnd,&ps); return 0; } case WM_CHAR: { //保存ANSI码 str = str + char(wParam); //使整个客户区无效 InvalidateRect(hwnd,NULL,0); return 0; } case WM_COMMAND: switch(LOWORD(wParam)) { case ID_FILE_EXIT: //向hwnd指定的窗口发送一个WM_CLOSE消息 SendMessage(hwnd,WM_CLOSE,0,0); break; } return 0; case WM_LBUTTONDOWN: //用户单击鼠标左键 { char szPoint[56]; //保存坐标信息 wsprintf(szPoint,"X = %d,Y = %d",LOWORD(lParam),HIWORD(lParam)); str = szPoint; if(wParam & MK_SHIFT) str = str+" Shift Key is down"; InvalidateRect(hwnd,NULL,1); return 0; } //case WM_CLOSE: //任务管理器还是能干掉 // return 0; case WM_DESTROY: //正在销毁窗口 //向消息队列发送一个WM_QUIT消息,促使GetMessage函数返回0,结束消息循环 PostQuitMessage(0); return 0; } //我们不处理的消息交给系统做默认处理 return DefWindowProc(hwnd,message,wParam,lParam); }
- 示例:简陋打字程序完成版
复制代码
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#include "stdafx.h" #include "windows.h" #include "stdio.h" #include "resource.h" #include <string> LRESULT CALLBACK MainWndProc(HWND,UINT,WPARAM,LPARAM); int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { char szClassName[] = "MainClass"; WNDCLASSEX wndclass; //用于描述主窗口的参数填充WNDCLASSEX结构 wndclass.cbSize = sizeof(wndclass); //结构的大小 wndclass.style = CS_HREDRAW | CS_VREDRAW; //指定如果大小改变就重画 wndclass.lpfnWndProc = MainWndProc; //窗口函数指针 wndclass.cbClsExtra = 0; //没有额外的类内存 wndclass.cbWndExtra = 0; //没有额外的窗口内存 wndclass.hInstance = hInstance; //实例句柄 wndclass.hIcon = LoadIcon(hInstance,(LPSTR)IDI_ICON1); //使用预定义图标 wndclass.hCursor = LoadCursor(NULL,IDC_ARROW); //使用预定义光标 wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); //使用白色背景画刷 wndclass.lpszMenuName = (LPSTR)IDR_TYPER; //指定自定义的菜单 wndclass.lpszClassName = szClassName; //窗口类的名称 wndclass.hIconSm = NULL; //没有类的小图标 //注册这个窗口类 RegisterClassEx(&wndclass); //创建主窗口 HWND hwnd = CreateWindowEx( 0, //dwExSytle,扩展 szClassName, //lpClassName,窗口类名 "My first Window!", //lpWindowName,标题 WS_OVERLAPPEDWINDOW, //dwStyle,窗口风格 CW_USEDEFAULT, //X,初始化X坐标 CW_USEDEFAULT, //y,初始化Y坐标 CW_USEDEFAULT, //nWidth,宽度 CW_USEDEFAULT, //nHeight,高度 NULL, //hWindParent 父窗口句柄 NULL, //hMenu 菜单句柄 hInstance, //hInstance,程序实例句柄 NULL //lpParam,用户数据 ); if(hwnd == NULL) { MessageBox(NULL,"创建窗口出错!","error",MB_OK); return -1; } //显示窗口,刷新窗口客户区 ShowWindow(hwnd,nCmdShow); UpdateWindow(hwnd); //从消息队列中取出消息,交给窗口函数处理,直到GetMessage返回FALSE,结束消息循环 MSG msg; while(GetMessage(&msg,NULL,0,0)) { //转化为键盘消息 TranslateMessage(&msg); //将消息发送到相应的窗口函数 DispatchMessage(&msg); } //当GetMessage返回FALSE时程序结束 return msg.wParam; } LRESULT CALLBACK MainWndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam) { //str对象用于保存窗口客户区显示的字符串 //为了使用string类,包含头文件#include <string> static std::string str; char szText[] = "最简单的窗口程序"; switch(message) { case WM_CREATE: { //设置窗口的标题 SetWindowText(hwnd,"最简陋的打字程序"); return 0; } case WM_PAINT: //窗口客户区需要重画 { HDC hdc; PAINTSTRUCT ps; //使无效的客户区变的有效,并取得设备环境句柄 hdc = BeginPaint(hwnd,&ps); //设置输出文本的背景颜色和文字颜色 SetTextColor(hdc,RGB(255,0,0)); //红色文本 SetBkColor(hdc,GetSysColor(COLOR_3DFACE)); //windows预定显示元素COLOR_3DFACE //显示文字 TextOut(hdc,0,0,str.c_str(),str.length()); EndPaint(hwnd,&ps); return 0; } case WM_CHAR: { //保存ANSI码 str = str + char(wParam); //使整个客户区无效 InvalidateRect(hwnd,NULL,0); return 0; } case WM_COMMAND: switch(LOWORD(wParam)) { case ID_FILE_EXIT: //向hwnd指定的窗口发送一个WM_CLOSE消息 SendMessage(hwnd,WM_CLOSE,0,0); break; } return 0; case WM_LBUTTONDOWN: //用户单击鼠标左键 { char szPoint[56]; //保存坐标信息 wsprintf(szPoint,"X = %d,Y = %d",LOWORD(lParam),HIWORD(lParam)); str = szPoint; if(wParam & MK_SHIFT) str = str+" Shift Key is down"; InvalidateRect(hwnd,NULL,1); return 0; } //case WM_CLOSE: //任务管理器还是能干掉 // return 0; case WM_DESTROY: //正在销毁窗口 //向消息队列发送一个WM_QUIT消息,促使GetMessage函数返回0,结束消息循环 PostQuitMessage(0); return 0; } //我们不处理的消息交给系统做默认处理 return DefWindowProc(hwnd,message,wParam,lParam); }
最后
以上就是单薄汽车最近收集整理的关于3.windows图形界面的全部内容,更多相关3内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复