窗口操作函数的使用
1 #include <Windows.h> 2 #include <CommCtrl.h> 3 #include <tchar.h> 4 /** 5 窗口操作函数的使用 6 7 */ 8 static HBRUSH hBackgroundBrush; 9 10 void print(LPCWSTR format, ...) 11 { 12 WCHAR wchar_buff[100]{ 0 }; 13 va_list arglist; 14 va_start(arglist, format); 15 wvsprintfW(wchar_buff, format, arglist); 16 va_end(arglist); 17 OutputDebugStringW(wchar_buff); 18 } 19 20 // 读取编辑框内容并打印的函数 21 void ReadAndPrintEditBox(HWND hwnd, HWND hEditBox) 22 { 23 if (!hEditBox) { 24 MessageBoxW(hwnd, L"编辑框句柄无效", L"错误", MB_ICONERROR); 25 return; 26 } 27 // 方法1: 使用 GetWindowTextLengthW + GetWindowTextW 28 int textLength = GetWindowTextLengthW(hEditBox); 29 if (textLength == 0) { 30 MessageBoxW(hwnd, L"编辑框为空", L"提示", MB_OK); 31 print(L"编辑框内容: [空]\n"); 32 return; 33 } 34 35 // 分配缓冲区 (+1 用于null终止符) 36 WCHAR* buffer = new WCHAR[textLength + 1]; 37 // 获取文本内容 38 int actualLength = GetWindowTextW(hEditBox, buffer, textLength + 1); 39 if (actualLength > 0) { 40 41 // 打印到调试输出 42 print(L"编辑框内容 (%d 字符): \"%s\"\n", actualLength, buffer); 43 44 // 显示在消息框中 45 WCHAR message[512]; 46 swprintf(message, 512, L"编辑框内容 (%d 字符):\n%s", actualLength, buffer); 47 MessageBoxW(hwnd, message, L"编辑框内容", MB_OK); 48 49 } 50 else { 51 MessageBoxW(hwnd, L"读取编辑框内容失败", L"错误", MB_ICONERROR); 52 } 53 54 55 } 56 57 58 //添加了 CALLBACK 调用约定 59 LRESULT CALLBACK Wndproc( 60 HWND hwnd, 61 UINT uMsg, 62 WPARAM wParam, 63 LPARAM lParam 64 ) 65 { 66 // 获取当前的实例句柄 67 HINSTANCE hInstance = GetModuleHandle(0); 68 static HWND hEditBox = NULL; // 保存编辑框句柄 69 70 71 switch (uMsg) 72 { 73 case WM_CREATE: 74 { 75 // add ... 要接收 BN_DOUBLECLICKED 通知,按钮需要 BS_NOTIFY 样式: 76 CreateWindowW(WC_BUTTON, L"移动按钮", 77 WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON, // 添加 BS_NOTIFY 78 10, 10, 120, 30, hwnd, (HMENU)0x1001, hInstance, NULL); 79 CreateWindowW(WC_BUTTON, L"获取文本框内容", WS_VISIBLE | WS_CHILD, 10, 50, 120, 30, hwnd, (HMENU)0x1002, hInstance, 0); 80 CreateWindowW(WC_BUTTON, L"设置文本框内容", WS_VISIBLE | WS_CHILD, 10, 90, 120, 30, hwnd, (HMENU)0x1003, hInstance, 0); 81 CreateWindowW(WC_BUTTON, L"获取父窗口", WS_VISIBLE | WS_CHILD, 10, 130, 120, 30, hwnd, (HMENU)0x1004, hInstance, 0); 82 hEditBox = CreateWindowW(WC_EDIT, L"文本框内容", WS_CHILD | WS_BORDER | WS_VISIBLE, 10, 170, 320, 80, hwnd, (HMENU)0x1005, hInstance, 0); 83 break; 84 } 85 case WM_COMMAND: 86 { 87 /** 消息源 wParam (高字) wParam (低字) lParam 88 菜单 0 菜单标识符(IDM_ * ) 0 89 加速器 1 加速器标识符(IDM_ * ) 0 90 控件 控件定义的通知代码 控制标识符 控制窗口的句柄 91 92 -lParam: 93 控件句柄(如果是控件消息) 94 0(如果是菜单或加速键消息) 95 96 */ 97 WORD controlId = LOWORD(wParam); // wParam (低字) 控制标识符 LOWORD(wParam) = 控件ID 或 菜单ID 98 WORD notificationCode = HIWORD(wParam); // wParam (高字) 控件定义的通知代码 HIWORD(wParam) = 通知代码 99 HWND hControl = (HWND)lParam; // 如果消息源是控件 则可以拿到控制窗口的句柄 100 101 switch (controlId) 102 { 103 case 0x1001: 104 { 105 106 // 移动按钮 107 RECT controlRect = {0}; 108 GetClientRect(hwnd,&controlRect); 109 print(L"left=%d\n", controlRect.left); 110 print(L"top=%d\n", controlRect.top); 111 print(L"right=%d\n", controlRect.right); 112 print(L"bottom=%d\n", controlRect.bottom); 113 114 DWORD x = rand() % (controlRect.right - 120); 115 DWORD y = rand() % (controlRect.bottom - 30 ); 116 117 MoveWindow(hControl, x, y, 120, 30, TRUE); 118 119 break; 120 } 121 case 0x1002: 122 { 123 //MessageBoxW(hwnd, L"按钮2被触发", L"提示", MB_OK); 124 // 读取编辑框的内容并打印 // 获取文本内容 125 //int actualLength = GetWindowTextW(hEditBox, buffer, textLength + 1); 126 //ReadAndPrintEditBox(hwnd, hEditBox); 127 128 // 获取一个窗口的句柄 129 HWND hedit = GetDlgItem(hwnd, 0x1005); 130 131 WCHAR buff[100] = { 0 }; 132 133 GetWindowTextW(hedit, buff,100); 134 MessageBoxW(hwnd, buff, L"内容", MB_OK); 135 break; 136 } 137 case 0x1003: 138 { 139 // 获取一个窗口的句柄 140 /* HWND hedit = GetDlgItem(hwnd, 0x1005); 141 SetWindowTextW(hedit, L"测试有西i啊");*/ 142 143 SetDlgItemTextW(hwnd, 0x1005, L"测试一下,是否设置成功"); 144 145 break; 146 } 147 case 0x1004: 148 { 149 // 查找目标窗口 150 HWND hTargetWnd = FindWindowW(NULL, L"无标题"); // 更具体的窗口标题 151 if (!hTargetWnd) { 152 // 如果没找到,尝试其他常见的无标题窗口 153 hTargetWnd = FindWindowW(L"Notepad", NULL); // 记事本类名 154 if (!hTargetWnd) { 155 hTargetWnd = FindWindowW(L"0x003314E0", NULL); // 对话框类名 156 } 157 } 158 159 if (hTargetWnd) { 160 SetParent(hControl, hTargetWnd); 161 162 } 163 else { 164 MessageBoxW(hwnd, 165 L"找不到标题为'无标题'的窗口!\n\n" 166 L"请先打开一个记事本或其他应用程序窗口。", 167 L"错误", MB_ICONWARNING); 168 } 169 170 171 break; 172 } 173 174 default: 175 break; 176 } 177 178 179 180 break; 181 } 182 case WM_DESTROY: 183 // 在程序退出时(如 WM_DESTROY)删除画刷 184 DeleteObject(hBackgroundBrush); 185 PostQuitMessage(0); // 必须要有,否则无法退出程序 186 break; 187 default: 188 break; 189 } 190 191 return DefWindowProcW(hwnd, uMsg, wParam, lParam); // 修正函数名 192 193 194 } 195 int WINAPI WinMain( 196 HINSTANCE hInstance, // 当前应用程序实例的句柄 197 HINSTANCE hPreInstance, // 前一个实例的句柄(在32位以后总是NULL) 198 LPSTR lpCmdLine, // 命令行参数字符串 199 int nCmdShow // 窗口显示方式(最大化、最小化、正常等) 常用值:SW_SHOW, SW_MAXIMIZE, SW_MINIMIZE等 200 ) 201 { 202 //1、创建一个窗口类 203 WNDCLASSW mainWindowClass = { 0 }; 204 mainWindowClass.lpszClassName = L"按钮组件"; 205 mainWindowClass.lpfnWndProc = Wndproc; 206 mainWindowClass.hCursor = LoadCursor(NULL, IDC_ARROW); // 设置光标 207 //mainWindowClass.hbrBackground = CreateSolidBrush(RGB(255, 255,255)); 208 // // 保存画刷句柄 209 //// 推荐使用系统颜色,会自动适应Windows主题 210 //mainWindowClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); 211 hBackgroundBrush = CreateSolidBrush(RGB(255, 255, 255)); 212 mainWindowClass.hbrBackground = hBackgroundBrush; 213 // 2、注册窗口类 214 if (!RegisterClassW(&mainWindowClass)) { 215 MessageBox(NULL, L"窗口类注册失败!", L"错误", MB_ICONERROR); 216 return 1; 217 } 218 219 //3、创建窗口 通常是CreateWindow或CreateWindowEx的返回值 220 221 HWND hwindow = CreateWindowW( 222 mainWindowClass.lpszClassName, 223 L"按钮组件", 224 WS_OVERLAPPEDWINDOW, // 标准窗口样式(包含标题栏、边框等) 225 CW_USEDEFAULT, 226 0, 227 CW_USEDEFAULT, 228 0, 229 NULL, 230 NULL, 231 hInstance, 232 0 233 ); 234 235 if (hwindow) { 236 print(L"窗口创建成功,句柄: %p\n", hwindow); 237 //4、显示窗口 238 ShowWindow(hwindow, SW_SHOWNORMAL); 239 UpdateWindow(hwindow); 240 241 MSG msg = { 0 }; 242 while (GetMessageW(&msg, 0, 0, 0)) 243 { 244 TranslateMessage(&msg); // 添加了键盘消息翻译 没有这句代码,文本框无法输入信息 245 DispatchMessageW(&msg); 246 } 247 248 } 249 return 0; 250 251 }