设置菜单值时按钮不显示,未设置时显示奇怪的样式
Button didn't show up when menu value is set and shows odd style when not set
我想将特定 window 设置为按钮的父级,但我得到了预期的行为。
设置 CreateWindow()
上的 hMenu
值时,按钮不显示:
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);
我不会将主要 window 的 CreateWindow()
返回的 HWND
传递到按钮的 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
的 window 的“父级”时,您实际上是在设置它的“所有者”。 Owner and Parent are not the same thing. Also see A window can have a parent or an owner but not both.
您的按钮没有出现在主按钮 window 中,因为该按钮不是主按钮的子按钮 window。
因此,在创建按钮时,您需要包含 WS_CHILD
样式。您还应该包括 WS_VISIBLE
样式而不是使用 ShowWindow()
(除非您想要创建最初隐藏的按钮)。并且你应该在创建时指定父级window,而不是使用SetParent()
.
您还应该将创建的按钮移动到主 window 的 WndProc()
的 WM_CREATE
处理程序中。
试试这个:
#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);
}
我想将特定 window 设置为按钮的父级,但我得到了预期的行为。
设置 CreateWindow()
上的 hMenu
值时,按钮不显示:
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);
我不会将主要 window 的 CreateWindow()
返回的 HWND
传递到按钮的 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
的 window 的“父级”时,您实际上是在设置它的“所有者”。 Owner and Parent are not the same thing. Also see A window can have a parent or an owner but not both.
您的按钮没有出现在主按钮 window 中,因为该按钮不是主按钮的子按钮 window。
因此,在创建按钮时,您需要包含 WS_CHILD
样式。您还应该包括 WS_VISIBLE
样式而不是使用 ShowWindow()
(除非您想要创建最初隐藏的按钮)。并且你应该在创建时指定父级window,而不是使用SetParent()
.
您还应该将创建的按钮移动到主 window 的 WndProc()
的 WM_CREATE
处理程序中。
试试这个:
#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);
}