DS_CONTROL | WS_CHILD组合会导致无限循环

时间:2018-11-02 19:41:11

标签: c winapi dialog cl

你好。

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

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

如何使用{{1 }}标志?

这是我的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

我在Visual C ++命令提示符中使用以下命令进行编译:{{1​​}}。

在此先感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

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

这是主对话框proc中WM_INITDIALOG案例的更新代码:< / p>

// ...
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标志和制表符循环。