从资源生成的 C++/Win32 对话框行为不正常

标签 c++ winapi dialog resources

我为应该包含编辑控件(用于显示非编辑日志报告)的(无模式)对话框编写了一个资源脚本:

IDD_LOG DIALOGEX 10, 10, 300, 200, 0
STYLE WS_VISIBLE | WS_POPUP | WS_CAPTION | WS_BORDER | WS_SYSMENU | DS_CENTER
CAPTION "Last Log Report"
{
    EDITTEXT 301, 0, 0, 250, 180, WS_VISIBLE | WS_CHILD | WS_VSCROLL | ES_MULTILINE | ES_READONLY
}   

当我通过菜单调用对话框时

hwndLogDlg = CreateDialog(NULL, MAKEINTRESOURCE(IDD_LOG), hwnd, (DLGPROC)LogDlgProc)

它有以下几点不对:

  1. 对话窗口包含一个编辑控件,但在其上方还有另一个大小相同的编辑控件。该编辑控件似乎是一个非子窗口。 此外,当我在调用 SetDlgItemText(hwndLogDlg, IDDE_LOGTXT, "<Could not load log data>"); 的编辑控件中设置文本时, 两者都已设置。
    我怀疑资源编译器将脚本中的编辑控件视为对话框的子项,并且第二次将其视为单独的窗口,尽管设置了 WS_CHILD。
  2. 创建对话框时主窗口被阻塞,尽管对话框是无模式的。
  3. 单击对话窗口的关闭按钮不会导致它关闭,即使我调用了DestroyWindow(hwndDlg);。在 WM_QUIT 和 WM_DESTROY 上。加上主窗口被阻塞的问题,我关闭所有内容的唯一方法是从任务栏或任务管理器中关闭窗口。

消息循环:

while(GetMessage(&Msg, NULL, 0, 0) > 0) {
    if (!IsDialogMessage(hwndDlg, &Msg)){
        TranslateMessage(&Msg); 
        DispatchMessage(&Msg);
    }
}

对话框窗口过程:

INT_PTR CALLBACK LogDlgProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam){
switch (message){
    case WM_INITDIALOG:{
        hwndLogTxt = GetDlgItem(hwndDlg, IDDE_LOGTXT);

        fileHandler fH;
        if (!fH.init("report.log")){
            SetDlgItemText(hwndLogTxt, IDDE_LOGTXT, "<Could not load log data>");
            err(ERR_CUSTOM,"Failed to extract log file!","Extraction Error!");
        }
        else SetDlgItemText(hwndLogTxt, IDDE_LOGTXT, fH.getStr());
        break;
    }
    case WM_DESTROY:{
        DestroyWindow(hwndDlg);
        break;
    }
}
return true;
}

所以我最终想要得到的是一个包含(只读)编辑控件(占据对话框窗口的所有客户区)的无模式对话框。 这个问题是关于我的资源语法还是关于我调用它的方式?我什至可能错过了 WM_INITDIALOG 上的必要步骤吗?

最佳答案

一些评论:

a) 我想您实际上在调用 CreateDialog() 时使用了 LogDlgProcCreateDialog() 之后还有 ShowWindow(hwndDlg, SW_SHOW); 吗?

b) 你的 EDITTEXT 控件在资源文件中声明了一个数字作为 id,你的逻辑使用 IDDE_TXT -- 改变你的对话框资源有 编辑 IDDE_TXT...

c) 更改代码以将编辑控件设置为 SetDlgItemText(hwndDlg, IDDE_TXT, ...);;确保 fH.getStr() 返回正确的字符串值

d) 如有必要,在读取后关闭 fH(取决于 fileHandler 的实现方式)

e) 为未处理的消息返回FALSE

f) 在调用 DestroyWindow 之前,您不会得到 WM_DESTROY,我认为处理 IDCANCEL 就足够了

你的对话过程应该是这样的

INT_PTR CALLBACK LogDlgProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam)
{   switch (message)
    {   case WM_INITDIALOG:
        {   fileHandler fH;
            if (fH.init("report.log"))
            {   SetDlgItemText(hwndDlg, IDDE_TXT, fH.getStr());
                // close fH
            }
            else
            {   SetDlgItemText(hwndDlg, IDDE_TXT, "<Could not load log data>");
                err(ERR_CUSTOM,"Failed to extract log file!","Extraction Error!");
            }
            return TRUE;
        }

        case WM_COMMAND: 
            if (LOWORD(wParam) == IDCANCEL) 
            {   DestroyWindow(hwndDlg);
                return TRUE;
            }
//EDIT start
            if (HIWORD(wParam) == EN_SETFOCUS && LOWORD(wParam) == IDDE_TXT)
            {   SendDlgItemMessage(hwndDlg, IDDE_TXT, EM_SETSEL, -1, -1);
                return TRUE;
            }
//EDIT end

    }
    return FALSE;
}

关于从资源生成的 C++/Win32 对话框行为不正常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25465651/

相关文章:

c++ - 标准头文件中的错误

c++ - 如何使用 Win32 消除 C++ 中原始音频信号中的随机不连续性?

python 在 win32 : how to get absolute timing/CPU cycle-count

windows - 为什么另一个线程中的阻塞 IO 会阻止 CreateWindowEx() 返回

ios - 更改 AlertController 的布局

java - SWT - 关闭不同类的对话框窗口

c++ - 如何在 C++ 中正确使用命名空间?

c++ - OpenGL 4,错误的缓冲区偏移值

java - 用 DialogInterface.OnClickListener 区分单个 Dialog

c++ - QPushButton 改变颜色后调整大小