c++ - Winapi:已注册但未创建的子窗口为父窗口提供背景色
问题描述
我正在尝试使用 winapi 创建一个 Windows 应用程序。所以我想要一个父窗口和一个子窗口。这是我的代码:
#include <windows.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK ChildProc(HWND, UINT, WPARAM, LPARAM);
const char szChildName[] = "Child window title";
const UINT PM_COLORCHANGED = WM_APP + 1;
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
MSG msg;
HWND hWnd;
WNDCLASS wc;
char szAppName[] = "title";
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hIcon = NULL;
wc.hInstance = hInstance;
wc.lpfnWndProc = WndProc;
wc.lpszClassName = (LPCWSTR)szAppName;
wc.lpszMenuName = NULL;
wc.style = CS_HREDRAW | CS_VREDRAW;
RegisterClass(&wc);
wc.hbrBackground = (HBRUSH)GetStockObject(LTGRAY_BRUSH);
wc.hIcon = NULL;
wc.lpfnWndProc = ChildProc;
wc.lpszClassName = (LPCWSTR)szChildName;
RegisterClass(&wc);
hWnd = CreateWindow((LPCWSTR)szAppName,
(LPCWSTR)szAppName,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL);
ShowWindow(hWnd, iCmdShow);
UpdateWindow(hWnd);
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static HWND hChild;
static RECT rect;
switch (message)
{
case WM_CREATE:
{
GetClientRect(hWnd, &rect);
hChild = CreateWindow((LPCWSTR)szChildName,
NULL,
WS_CHILD | WS_VISIBLE | WS_DLGFRAME,
5,
rect.bottom - 35,
rect.right - 10,
30,
hWnd,
NULL,
((LPCREATESTRUCT)lParam)->hInstance,
NULL);
return 0;
}
case WM_SIZE:
{
return 0;
}
case PM_COLORCHANGED:
{
return 0;
}
case WM_PAINT:
{
return 0;
}
case WM_DESTROY:
{
PostQuitMessage(0);
return 0;
}
}
return DefWindowProc(hWnd, message, wParam, lParam);
}
LRESULT CALLBACK ChildProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_SIZE:
{
return 0;
}
case WM_LBUTTONDOWN:
{
return 0;
}
case WM_PAINT:
{
return 0;
}
}
return DefWindowProc(hWnd, message, wParam, lParam);
}
这很完美,所以我在应用程序底部看到了子窗口。但是,而不是WNDCLASS
我想使用WNDCLASSEX
,这迫使我使用RegisterClassEx()
来注册窗口。我也想使用CreateWindowEx
,我的代码如下所示:
#include <windows.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK ChildProc(HWND, UINT, WPARAM, LPARAM);
const char szChildName[] = "Child name";
const UINT PM_COLORCHANGED = WM_APP + 1;
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
MSG msg;
HWND hWnd;
WNDCLASSEX wc;
char szAppName[] = "The Child Window";
ZeroMemory(&wc, sizeof(WNDCLASSEX));
wc.cbClsExtra = 0;
wc.cbSize = sizeof(WNDCLASSEX);
wc.cbWndExtra = 0;
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hIcon = NULL;
wc.hIconSm = NULL;
wc.hInstance = hInstance;
wc.lpfnWndProc = (WNDPROC)WndProc;
wc.lpszClassName = (LPCWSTR)szAppName;
wc.lpszMenuName = NULL;
wc.style = CS_HREDRAW | CS_VREDRAW;
RegisterClassEx(&wc);
wc.hbrBackground = (HBRUSH)GetStockObject(LTGRAY_BRUSH);
wc.hIcon = NULL;
wc.lpfnWndProc = (WNDPROC)ChildProc;
wc.lpszClassName = (LPCWSTR)szChildName;
RegisterClassEx(&wc);
hWnd = CreateWindowEx(NULL,
wc.lpszClassName,
L"parent window",
(WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU),
200,
150,
1000,
1000,
NULL,
NULL,
hInstance,
NULL
);
ShowWindow(hWnd, iCmdShow);
UpdateWindow(hWnd);
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static HWND hChild;
static RECT rect;
switch (message)
{
case WM_CREATE:
{
GetClientRect(hWnd, &rect);
hChild = CreateWindowEx(NULL,
(LPCWSTR)szChildName,
L"child window",
(WS_CHILD | WS_VISIBLE | WS_DLGFRAME),
200,
150,
200,
200,
hWnd,
NULL,
((LPCREATESTRUCT)lParam)->hInstance,
NULL
);
return 0;
}
case WM_SIZE:
{
return 0;
}
case PM_COLORCHANGED:
{
return 0;
}
case WM_PAINT:
{
return 0;
}
case WM_DESTROY:
{
PostQuitMessage(0);
return 0;
}
}
return DefWindowProc(hWnd, message, wParam, lParam);
}
LRESULT CALLBACK ChildProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_SIZE:
{
return 0;
}
case WM_LBUTTONDOWN:
{
return 0;
}
case WM_PAINT:
{
return 0;
}
}
return DefWindowProc(hWnd, message, wParam, lParam);
}
问题:现在我只看到子窗口的颜色,所以整个应用程序都有子窗口的背景颜色,所以电脑以某种方式重新绘制了子窗口颜色的所有内容。(甚至没有子窗口可见,我看到的只是子窗口的这个 LTGRAY_Brush。
奇怪的是:如果我删除创建子窗口的行,那么这一行:
hChild = CreateWindowEx(NULL,
(LPCWSTR)szChildName,
L"child window",
(WS_CHILD | WS_VISIBLE | WS_DLGFRAME),
200,
150,
200,
200,
hWnd,
NULL,
((LPCREATESTRUCT)lParam)->hInstance,
NULL
然后即使是现在,背景颜色也与我注册子类的颜色相同。尽管尚未创建子类。谢谢你的帮助。
解决方案
推荐阅读
- ios - UIView 动画 - 动画正确但再次出现在同一位置
- c++ - C++14 从可变参数模板创建向量
- apache-spark - 在 rapidminer 上运行 sparkRM:提交或启动 spark 作业时出错
- python - 从 CSV 文件读取并插入数据库 Python
- docker - 当 apk 添加失败时,如何在 gliderlabs/alpine Docker 映像中安装 Alpine Linux 软件包?
- android - 如何为 API 级别 < 23 的项目设置重力
- mysql - 需要帮助来定义查询,我试图从 3 个不同的表中获取数据
- android - 在 Flutter ListView 中只重建一行?
- mysql - 以特定方式汇总一列中的值
- c# - ASP.NET MVC 5“当 ModelState 无效时”