c - 设置菜单值时按钮不显示,未设置时显示奇怪的样式
问题描述
我想将特定窗口设置为按钮的父级,但我得到了预期的行为。
当设置hMenu
值 on时CreateWindow()
,按钮不显示:
CreateWindow(L"Button",
L"Click me!",
WS_TABSTOP,
20,
50,
60,
90,
NULL,
(HMENU)1,
NULL, NULL);
但是当我删除hMenu
参数时,按钮确实显示出来了,但是样式很奇怪:
CreateWindow(L"Button",
L"Click me!",
WS_TABSTOP,
20,
50,
60,
90,
NULL,
NULL,
NULL, NULL);
我没有将主窗口HWND
返回的值传递给按钮,因为它们不是按那个顺序调用的。CreateWindow()
hwndParent
下面的代码是我真实代码的简化版本。
我错过了什么?
完整代码:
#pragma comment(lib, "user32.lib")
#pragma comment(lib, "Comctl32.lib")
#pragma comment(lib, "Gdi32.lib")
#define WIN32_LEAN_AND_MEAN
#define UNICODE
#define _UNICODE
#include <windows.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
PWSTR pCmdLine, int nCmdShow) {
MSG msg = {0};
WNDCLASSW wc = {0};
wc.lpszClassName = L"Window";
wc.hInstance = hInstance;
wc.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
wc.lpfnWndProc = WndProc;
wc.hCursor = LoadCursor(0, IDC_ARROW);
RegisterClassW(&wc);
HWND
hwndMainWindow = CreateWindow(wc.lpszClassName, L"Window",
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
CW_USEDEFAULT, CW_USEDEFAULT, 500, 350,
NULL, NULL, hInstance, NULL);
HWND hButton = CreateWindow(L"Button",
L"Click me!",
WS_TABSTOP,
20,
50,
60,
90,
NULL,
NULL,
NULL, NULL);
SetParent(hButton, hwndMainWindow);
ShowWindow(hButton, SW_SHOWNORMAL);
UpdateWindow(hwndMainWindow);
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int) msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProcW(hwnd, msg, wParam, lParam);
}
解决方案
您没有WS_CHILD
在按钮上指定样式。 SetParent()
不会为您设置此样式。
当您设置没有 的窗口的“父级”时,WS_CHILD
实际上是在设置它的“所有者”。 Owner 和 Parent 不是一回事。另请参阅窗口可以有父级或所有者,但不能同时拥有。
您的按钮不会出现在主窗口中,因为该按钮不是主窗口的子窗口。
因此,在创建按钮时,您需要包含WS_CHILD
样式。您还应该包含WS_VISIBLE
样式而不是使用ShowWindow()
(除非您想创建最初隐藏的按钮)。并且您应该在创建时指定父窗口,而不是使用SetParent()
.
您还应该将按钮创建移动到WM_CREATE
主窗口的处理程序中WndProc()
。
尝试这个:
#pragma comment(lib, "user32.lib")
#pragma comment(lib, "Comctl32.lib")
#pragma comment(lib, "Gdi32.lib")
#define WIN32_LEAN_AND_MEAN
#define UNICODE
#define _UNICODE
#include <windows.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
PWSTR pCmdLine, int nCmdShow) {
MSG msg = {0};
WNDCLASS wc = {0};
wc.lpszClassName = L"Window";
wc.hInstance = hInstance;
wc.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
wc.lpfnWndProc = WndProc;
wc.hCursor = LoadCursor(0, IDC_ARROW);
RegisterClass(&wc);
HWNDhwndMainWindow = CreateWindow(wc.lpszClassName, L"Window",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 500, 350,
NULL, NULL, hInstance, NULL);
ShowWindow(hwndMainWindow, SW_SHOWNORMAL);
UpdateWindow(hwndMainWindow);
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int) msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_CREATE:
CreateWindow(L"Button",
L"Click me!",
WS_CHILD | WS_VISIBLE | WS_TABSTOP,
20,
50,
60,
90,
hwnd,
(HMENU)1,
NULL, NULL);
break;
case WM_COMMAND:
if ((LOWORD(wParam) == 1) && (HIWORD(wParam) == BN_CLICKED)) {
MessageBox(hwnd, L"Yea, you clicked me!", L"Window", MB_OK);
return 0;
}
break;
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}
推荐阅读
- javascript - Javascript无法从回调函数调用函数
- node.js - 如何比较nodejs中的字符串?
- javascript - Vue.js - 如何在数据数组为空时禁用按钮
- python - 有人可以解释为什么我的 Python 列表索引对于不同的索引是相同的吗
- sql-server - 程序集“System.Threading.Channels”引用程序集“system.threading.tasks.extensions, v.”,当前数据库中不存在该程序集
- javascript - 在同一个模块中使用 module.export
- python - 为什么有一个括号python
- azure - 如何在 Azure HDInsight 上安装 apache atlas?
- c# - 我怎样才能使我的用户输入只接受特定的符号?
- amazon-web-services - 将存储过程结果集保存在表中