gpt4 book ai didi

c - DS_CONTROL | DS_控制WS_CHILD组合导致无限循环

转载 作者:行者123 更新时间:2023-11-30 14:45:19 25 4
gpt4 key购买 nike

您好。

我正在尝试使用 WinAPI 和 C 创建一个“对话框中的对话框”示例。此示例包含一个带有自动复选框的子对话框,并且一个主对话框,其中包含一个静态黑色矩形(它是子对话框的父级)和一个按钮,该按钮在消息框中显示带有复选框状态的文本。

当我设置标志 DS_CONTROL | WS_CHILD 时对于子对话框,每当我尝试更改复选框状态时,应用程序都会进入无限循环,我必须强制关闭它。当我删除DS_CONTROL时标志,按预期工作,但我无法使用 Tab 键在控件之间循环。

我该怎么做才能使其按预期工作使用 DS_CONTROL标志?

这是我的 main.c 的内容文件:

#include <windows.h>

#pragma comment (lib, "user32")


HINSTANCE hInst;
BOOL isChecked;
const unsigned char checkedStr[] = "Checkbox is checked";
const unsigned char notCheckedStr[] = "Checkbox is not checked";


BOOL CALLBACK ChildDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_COMMAND:
switch (LOWORD(wParam))
{
case 21:
isChecked = IsDlgButtonChecked(hwndDlg, 21);
return TRUE;
}

return FALSE;
}

return FALSE;
}


BOOL CALLBACK DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_INITDIALOG:
{
HWND hContainer, hChilddDlg;

hContainer = GetDlgItem(hwndDlg, 11);
hChilddDlg = CreateDialogParam(hInst, MAKEINTRESOURCE(20), hContainer, ChildDlgProc, 0);
ShowWindow(hChilddDlg, SW_SHOW);

return TRUE;
}

case WM_COMMAND:
switch (LOWORD(wParam))
{
case 12:
{
const unsigned char *ptr;

if (isChecked)
{
ptr = checkedStr;
}
else
{
ptr = notCheckedStr;
}

MessageBox(hwndDlg, ptr, TEXT("Checkbox status"), MB_OK | MB_ICONINFORMATION);

return TRUE;
}
}

return FALSE;

case WM_CLOSE:
EndDialog(hwndDlg, 0);
return TRUE;
}


return FALSE;
}


int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
hInst = hInstance;
isChecked = FALSE;

return DialogBoxParam(hInstance, MAKEINTRESOURCE(10), NULL, DialogProc, 0);
}

这是我的 rsrc.rc 的内容文件:

#include <windows.h>

10 DIALOGEX 0, 0, 130, 47
STYLE DS_CENTER | DS_SETFONT | WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU
CAPTION "Checkbox status"
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
FONT 9, "Segoe UI"
{
CONTROL "", 11, STATIC, SS_BLACKRECT | WS_CHILD | WS_VISIBLE, 5, 5, 120, 20
CONTROL "&Status", 12, BUTTON, BS_DEFPUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 75, 30, 50, 12
}


20 DIALOGEX 0, 0, 120, 20
STYLE DS_SETFONT | DS_CONTROL | WS_CHILD
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
FONT 9, "Segoe UI"
{
CONTROL "Checkbox", 21, BUTTON, BS_AUTOCHECKBOX | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 0, 5, 50, 10
}

我在 Visual C++ 命令提示符下编译它:cl /c main.c && rc rsrc.rc && link /SUBSYSTEM:WINDOWS /OUT:test.exe main.obj rsrc.res .

预先感谢您的帮助。

最佳答案

在NSIS源代码中找到了解决方案。问题是我将子对话框作为 blackrect 的子对话框,因此它脱离了主对话框的事件循环,导致挂起。为了解决这个问题,我必须将其作为主对话框的子级并将其移到 blackrect 上。

这是主对话框中 WM_INITDIALOG 情况的更新代码过程:

// ...
case WM_INITDIALOG:
{
HWND hChilddDlg;

hChilddDlg = CreateDialogParam(hInst, MAKEINTRESOURCE(20), hwndDlg, ChildDlgProc, 0);

if (hChilddDlg)
{
RECT rect;

GetWindowRect(GetDlgItem(hwndDlg, 11), &rect);
ScreenToClient(hwndDlg, (LPPOINT)&rect);
SetWindowPos(hChilddDlg, 0, rect.left, rect.top, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER);
ShowWindow(hChilddDlg, SW_SHOWNA);
}

return TRUE;
}
// ...

这样我就可以在控件之间使用 DS_CONTROL 标志和 Tab 循环。

关于c - DS_CONTROL | DS_控制WS_CHILD组合导致无限循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53124912/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com