我的目标是创建5组单选按钮(我知道它与标题相矛盾,但你仍然得到点),供用户选择使用Win32 API(所以这里没有窗口形式)。
我尝试使用组框和SetWindowLongPtr
的组合,但它仍然没有像预期的那样工作(请注意,我使用GWLP_WNDPROC
作为索引)。如果我使用SetWindowLongPtr
到组框,那么组框就会消失,其他一切都按预期工作。
我可以使用"虚拟"组框,但它降低了我的代码效率。有些人可能会建议使用WS_GROUP
,但它只适用于如果有2组单选按钮(我认为)。我也不喜欢使用资源,所以这个问题有什么解决方案吗?或者我只能坚持使用"虚拟"。集团箱子吗?
最小可复制样本:
#include <Windows.h>
LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wp, LPARAM lp)
{
switch (uMsg)
{
default:
return DefWindowProc(hwnd, uMsg, wp, lp);
}
}
int WINAPI wWinMain(HINSTANCE hinst, HINSTANCE hiprevinst, PWSTR nCmdLine, int ncmdshow)
{
const wchar_t CLASS_NAME[] = L"Sample";
WNDCLASS wc = { };
wc.lpfnWndProc = WndProc;
wc.hInstance = hinst;
wc.lpszClassName = CLASS_NAME;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
RegisterClass(&wc);
HWND hwnd = CreateWindowEx(
0,
CLASS_NAME,
L"Sample window",
WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX, // Window style
CW_USEDEFAULT, CW_USEDEFAULT, 800, 600,
NULL,
NULL,
hinst,
NULL);
HWND groupbox = CreateWindowEx(0, L"Button", L"Groupbox", WS_VISIBLE | WS_CHILD | BS_GROUPBOX, 10, 10, 100, 100, NULL, NULL, hinst, NULL);
HWND radiobutton1 = CreateWindowEx(0, L"Button", L"Groupbox", WS_VISIBLE | WS_CHILD | BS_AUTORADIOBUTTON, 10, 10, 60, 60, groupbox, NULL, hinst, NULL);
SetWindowLongPtr(groupbox, GWLP_WNDPROC, (LONG)WndProc);
SendMessage(groupbox, NULL, NULL, TRUE);
ShowWindow(hwnd, ncmdshow);
MSG msg;
while (GetMessage(&msg, NULL, NULL, NULL))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
由于我剥离了这么多必要的功能,你需要去任务管理器并杀死名为"Autoclicker"进程由于某种原因,能够重新编译它
请确保您处理了WM_DESTROY
,否则窗口将无法正常关闭。
单选按钮、所有子对话框项和所有子窗口都应该创建在父窗口的WM_CREATE
部分。它们需要父窗口的HWND
句柄。
SetWindowLongPtr(.. GWLP_WNDPROC ...)
是用于子类化的旧方法。你的用法不正确。反正你也不需要了。
不清楚SendMessage(groupbox, NULL, NULL, TRUE);
应该做什么。
添加单选按钮,确保第一个单选按钮添加了WS_TABSTOP|WS_GROUP
,如下所示
LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wp, LPARAM lp)
{
switch (uMsg)
{
case WM_CREATE:
{
HINSTANCE hinst = GetModuleHandle(0);
auto add = [&](const wchar_t* name,
int id, int x, int y, int w, int h, bool first = false)
{
DWORD style = WS_VISIBLE | WS_CHILD | BS_AUTORADIOBUTTON;
if (first) style |= WS_GROUP | WS_TABSTOP;
return CreateWindowEx(0, L"Button", name, style,
x, y, w, h, hwnd, (HMENU)id, hinst, NULL);
};
HWND groupbox1 = CreateWindowEx(0, L"Button", L"Groupbox1",
WS_VISIBLE | WS_CHILD | BS_GROUPBOX, 2, 2, 250, 120, hwnd, NULL, hinst, NULL);
HWND radio1 = add(L"radio1", 1, 10, 30, 200, 20, true);
HWND radio2 = add(L"radio2", 2, 10, 51, 200, 20);
HWND radio3 = add(L"radio3", 3, 10, 72, 200, 20);
HWND radio4 = add(L"radio4", 4, 10, 93, 200, 20);
HWND groupbox2 = CreateWindowEx(0, L"Button", L"Groupbox2",
WS_VISIBLE | WS_CHILD | BS_GROUPBOX, 280, 2, 250, 120, hwnd, NULL, hinst, NULL);
HWND radio11 = add(L"radio1", 11, 300, 30, 200, 20, true);
HWND radio12 = add(L"radio2", 12, 300, 51, 200, 20);
HWND radio13 = add(L"radio3", 13, 300, 72, 200, 20);
HWND radio14 = add(L"radio4", 14, 300, 93, 200, 20);
return 0;
}
case WM_DESTROY:
PostQuitMessage(0);
return 0;
default:
return DefWindowProc(hwnd, uMsg, wp, lp);
}
}
int WINAPI wWinMain(HINSTANCE hinst, HINSTANCE hiprevinst, PWSTR nCmdLine, int ncmdshow)
{
const wchar_t CLASS_NAME[] = L"Sample";
WNDCLASS wc = { };
wc.lpfnWndProc = WndProc;
wc.hInstance = hinst;
wc.lpszClassName = CLASS_NAME;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
RegisterClass(&wc);
HWND hwnd = CreateWindowEx(0, CLASS_NAME, L"Sample window",
WS_OVERLAPPEDWINDOW, 0, 0, 800, 600,
NULL, NULL, hinst, NULL);
ShowWindow(hwnd, ncmdshow);
MSG msg;
while (GetMessage(&msg, NULL, NULL, NULL))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}