1 #include <Windows.h>
2 #include <CommCtrl.h>
3 #include <tchar.h>
4 /**
5 // 正确的按钮创建
6 CreateWindowW(
7 L"BUTTON", // 窗口类名
8 L"按钮1", // 按钮文本
9 WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON, // 样式:可见 + 子窗口 + 标准按钮
10 120, 60, 120, 60, // 位置和大小
11 hwndParent, // 正确的父窗口句柄
12 (HMENU)1001, // 控件ID(用于消息识别)
13 hInstance, // 实例句柄
14 NULL // 创建参数
15 );
16
17 WM_COMMAND 是Windows编程中非常重要的消息,用于处理菜单、控件和加速键的命令。让我为你详细解释:
18 WM_COMMAND // 当用户选择菜单项、点击控件或使用加速键时发送
19 WM_COMMAND 消息的参数:
20 - wParam:
21 LOWORD(wParam) = 控件ID 或 菜单ID
22 HIWORD(wParam) = 通知代码
23 - lParam:
24 控件句柄(如果是控件消息)
25 0(如果是菜单或加速键消息)
26 case WM_COMMAND:
27 {
28 int controlId = LOWORD(wParam); // 控件ID或菜单ID
29 int notificationCode = HIWORD(wParam); // 通知代码
30 HWND hControl = (HWND)lParam; // 控件句柄(可能为NULL)
31
32 switch (controlId)
33 {
34 // 处理不同的控件或菜单命令
35 }
36 break;
37 }
38 */
39 void print(LPCWSTR format, ...)
40 {
41 WCHAR wchar_buff[100]{ 0 };
42 va_list arglist;
43 va_start(arglist, format);
44 wvsprintfW(wchar_buff, format, arglist);
45 va_end(arglist);
46 OutputDebugStringW(wchar_buff);
47 }
48
49 // 读取编辑框内容并打印的函数
50 void ReadAndPrintEditBox(HWND hwnd, HWND hEditBox)
51 {
52 if (!hEditBox) {
53 MessageBoxW(hwnd, L"编辑框句柄无效", L"错误", MB_ICONERROR);
54 return;
55 }
56 // 方法1: 使用 GetWindowTextLengthW + GetWindowTextW
57 int textLength = GetWindowTextLengthW(hEditBox);
58 if (textLength == 0) {
59 MessageBoxW(hwnd, L"编辑框为空", L"提示", MB_OK);
60 print(L"编辑框内容: [空]\n");
61 return;
62 }
63
64 // 分配缓冲区 (+1 用于null终止符)
65 WCHAR* buffer = new WCHAR[textLength + 1];
66 // 获取文本内容
67 int actualLength = GetWindowTextW(hEditBox, buffer, textLength + 1);
68 if (actualLength > 0) {
69
70 // 打印到调试输出
71 print(L"编辑框内容 (%d 字符): \"%s\"\n", actualLength, buffer);
72
73 // 显示在消息框中
74 WCHAR message[512];
75 swprintf(message, 512, L"编辑框内容 (%d 字符):\n%s", actualLength, buffer);
76 MessageBoxW(hwnd, message, L"编辑框内容", MB_OK);
77
78 }
79 else {
80 MessageBoxW(hwnd, L"读取编辑框内容失败", L"错误", MB_ICONERROR);
81 }
82
83
84 }
85
86
87 //添加了 CALLBACK 调用约定
88 LRESULT CALLBACK Wndproc(
89 HWND hwnd,
90 UINT uMsg,
91 WPARAM wParam,
92 LPARAM lParam
93 )
94 {
95 // 获取当前的实例句柄
96 HINSTANCE hInstance = GetModuleHandle(0);
97 static HWND hEditBox = NULL; // 保存编辑框句柄
98
99
100 switch (uMsg)
101 {
102 case WM_CREATE:
103 {
104 // add ... 要接收 BN_DOUBLECLICKED 通知,按钮需要 BS_NOTIFY 样式:
105 CreateWindowW(WC_BUTTON, L"按钮1",
106 WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON , // 添加 BS_NOTIFY
107 10, 10, 120, 30, hwnd,(HMENU)0x1001,hInstance, NULL);
108 CreateWindowW(WC_BUTTON, L"按钮2", WS_VISIBLE | WS_CHILD, 10, 50, 120, 30, hwnd, (HMENU)0x1002, hInstance, 0);
109 hEditBox = CreateWindowW(WC_EDIT, L"文本框内容", WS_CHILD | WS_BORDER | WS_VISIBLE, 10, 320, 320, 80, hwnd, (HMENU)0x1003, hInstance, 0);
110 break;
111 }
112 case WM_COMMAND:
113 {
114 int controlId = LOWORD(wParam);
115 int notificationCode = HIWORD(wParam);
116 HWND hControl = (HWND)lParam;
117
118
119 wchar_t debugMsg[100];
120 swprintf(debugMsg, 100, L"控件ID: 0x%X, 通知代码: %d\n", controlId, notificationCode);
121 OutputDebugString(debugMsg);
122
123
124 switch (controlId)
125 {
126 case 0x1001:
127 {
128 //MessageBoxW(hwnd, L"按钮1被触发", L"提示", MB_OK);
129 /* wchar_t debugMsg[100];
130 swprintf(debugMsg, 100, L"xPos: %d\n", notificationCode);
131 OutputDebugString(debugMsg);*/
132
133 if (notificationCode == 0) //BN_CLICKED
134 {
135 MessageBoxW(hwnd, L"按钮1被点击了", L"提示", MB_OK);
136 }
137 else if (notificationCode == 5) //BN_DOUBLECLICKED
138 {
139 MessageBoxW(hwnd, L"按钮1被双击了", L"提示", MB_OK);
140 }
141 else
142 {
143 // 忽略其他通知代码
144 swprintf(debugMsg, 100, L"忽略未知通知代码: %d\n", notificationCode);
145 OutputDebugString(debugMsg);
146 }
147
148 break;
149 }
150 case 0x1002:
151 {
152 MessageBoxW(hwnd, L"按钮2被触发", L"提示", MB_OK);
153 // 读取编辑框的内容并打印
154 ReadAndPrintEditBox(hwnd, hEditBox);
155 break;
156 }
157
158 default:
159 break;
160 }
161
162
163
164 break;
165 }
166 case WM_DESTROY:
167 PostQuitMessage(0); // 必须要有,否则无法退出程序
168 break;
169 default:
170 break;
171 }
172
173 return DefWindowProcW(hwnd, uMsg, wParam, lParam); // 修正函数名
174
175
176 }
177 int WINAPI WinMain(
178 HINSTANCE hInstance, // 当前应用程序实例的句柄
179 HINSTANCE hPreInstance, // 前一个实例的句柄(在32位以后总是NULL)
180 LPSTR lpCmdLine, // 命令行参数字符串
181 int nCmdShow // 窗口显示方式(最大化、最小化、正常等) 常用值:SW_SHOW, SW_MAXIMIZE, SW_MINIMIZE等
182 )
183 {
184 //1、创建一个窗口类
185 WNDCLASSW mainWindowClass = { 0 };
186 mainWindowClass.lpszClassName = L"按钮组件";
187 mainWindowClass.lpfnWndProc = Wndproc;
188 mainWindowClass.hCursor = LoadCursor(NULL, IDC_ARROW); // 设置光标
189 // 2、注册窗口类
190 if (!RegisterClassW(&mainWindowClass)) {
191 MessageBox(NULL, L"窗口类注册失败!", L"错误", MB_ICONERROR);
192 return 1;
193 }
194
195 //3、创建窗口 通常是CreateWindow或CreateWindowEx的返回值
196
197 HWND hwindow = CreateWindowW(
198 mainWindowClass.lpszClassName,
199 L"按钮组件",
200 WS_OVERLAPPEDWINDOW, // 标准窗口样式(包含标题栏、边框等)
201 CW_USEDEFAULT,
202 0,
203 CW_USEDEFAULT,
204 0,
205 NULL,
206 NULL,
207 hInstance,
208 0
209 );
210
211 if (hwindow) {
212 print(L"窗口创建成功,句柄: %p\n", hwindow);
213 //4、显示窗口
214 ShowWindow(hwindow, SW_SHOWNORMAL);
215 UpdateWindow(hwindow);
216
217 MSG msg = { 0 };
218 while (GetMessageW(&msg, 0, 0, 0))
219 {
220 TranslateMessage(&msg); // 添加了键盘消息翻译
221 DispatchMessageW(&msg);
222 }
223
224 }
225 return 0;
226
227 }