DialogBox不显示对话框的原因分析

本文介绍单纯使用 win API 进行界面开发时,遇到DialogBox失败或不弹出对话框的解决方式。

0. 确认主窗口正常显示

这一步都不对的话,可以不用往下看了。

1. 检查资源文件格式是否正确

.rc文件中需要有两部分定义:

1.1 确认窗口布局定义正确

#include "resource.h"
/
//
// Dialog
//
IDD_IMGINF DIALOGEX 0, 0, 287, 135		//IDD_IMGINF为窗口ID
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION	//风格一般包括这些
CAPTION "Fill image info"					//窗口的名字
FONT 8, "MS Shell Dlg", 400, 0, 0x1			//窗口使用字体
BEGIN
LTEXT           "Width:", IDC_STATIC, 45, 10, 20, 8			//显示两个Text控件
LTEXT           "Height:", IDC_STATIC, 155, 10, 20, 8
EDITTEXT        IDC_WIDTH, 42, 22, 80, 14					//显示两个Edit控件
EDITTEXT        IDC_HEIGHT, 151, 22, 80, 14
DEFPUSHBUTTON   "Ensure", IDOK, 85, 114, 50, 14				//显示连两个Button控件
PUSHBUTTON      "Cancel", IDCANCEL, 151, 114, 50, 14
END

此部分代码的关键点是为窗口 id 要与 resource.h 中定义的 id 对应。此外控件的 id (IDC_WIDTH,IDC_HEIGHT)也需要与头文件中的定义对应。

1.2 确认有窗口大小边框坐标定义

/
//
// DESIGNINFO
//

#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO
BEGIN
    IDD_IMGINF, DIALOG		//注意窗口id 为 IDD_IMGINF
    BEGIN
        LEFTMARGIN, 7
        RIGHTMARGIN, 302
        TOPMARGIN, 7
        BOTTOMMARGIN, 169
    END
END
#endif    // APSTUDIO_INVOKED

此部分代码的关键也是 id 要与上面匹配

2.检查窗口ID是否正确定义

Resource.h 中我们需要定义一个窗口 id ,其值选择一个其他 id 未使用的值。

//创建WIN API 窗口应用程序时 VS 自己创建的定义
#define IDC_MYICON                      2
#define IDD_BZVIEWER_DIALOG             102
#define IDS_APP_TITLE                   103
#define IDD_ABOUTBOX                    103
#define IDM_ABOUT                       104
#define IDM_EXIT                        105
#define IDI_BZVIEWER                    107
#define IDI_SMALL                       108
#define IDC_BZVIEWER                    109
#define IDR_MAINFRAME                   128
#define IDCANCEL                        1000
#define IDC_STATIC                      -1

//自己添加的id定义
#define IDD_ADDIMGINF                   200		//此作为窗口ID
#define IDC_WIDTH						210		//此作为控件ID
#define IDC_HEIGHT						211		//此作为控件

// Next default values for new objects
// 
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NO_MFC                     1
#define _APS_NEXT_RESOURCE_VALUE        134
#define _APS_NEXT_COMMAND_VALUE         32771
#define _APS_NEXT_CONTROL_VALUE         1001
#define _APS_NEXT_SYMED_VALUE           110
#endif
#endif

这部分代码的关键点是, 将 .rc 资源文件中使用的自定义的对话框的 Id 定义好。若资源文件使用了没有定义的 id, 对话框将创建失败

3. 检查DialogBox的调用

在任意可以获取主窗口句柄或父窗口句柄的 .cpp 文件中调用就行

INT_PTR CALLBACK AddWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);

void xxxxxFunc(HINSTANCE hInstance, HWND Hwnd){
	DialogBox(hInstance, (LPCWSTR)IDD_IMGINF, *pHwnd, AddWndProc);	//AddWndProc为自定义的对话框响应函数
}

INT_PTR CALLBACK AddWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
    UNREFERENCED_PARAMETER(lParam);
    switch (message)
    {
    case WM_INITDIALOG:
        return (INT_PTR)TRUE;

    case WM_COMMAND:
        if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
        {
            EndDialog(hDlg, LOWORD(wParam));
            return (INT_PTR)TRUE;
        }
        break;
        /*待添加控件的响应*/
    }
    return (INT_PTR)FALSE;
}

DialogBox的调用不必像网上很多人说的必须放在窗口响应回调函数中,它可以在任意地方调用,但需要获取父窗口句柄,否则不能实现模态对话框优先处理顶层对话框的特性,即主窗口线程将不会被锁住。

  1. 确定调用的地方可以获取父窗口句柄,若此句柄为空则为非模态对话框。
  2. 确认对话框响应的回调函数正确定义,此函数可以先拷贝一个创建程序时 vs 自己创建的,修改函数名,确认窗口正确显示后再详细添加响应功能。
  3. 确认对话框 id 再 resource.h 中正确定义,其控件的 id 也正确定义。

4. 删除编译文件,重新编译

若前3步都检查完毕,没有错误的情况下还是不能正确显示一个对话框,可以尝试第4步。
我的问题就是第4步的问题,查了两天前3步,最终尝试出此方法。

修改.rc文件后直接点击调试,Visual Studio 貌似并没有将我的修改重新编译。导致的结果就是无论我怎么改,是一直不能显示对话框。因此需要删掉链接文件,重新编译。

如果你使用的是Visual Studio创建的项目,请删除编译输出的链接文件的所在文件夹,这个文件夹会根据x64或是 x86编译器的不同而有不同的名字,但里面的文件类都一样。

  1. 删除包含.log,.obj,.res,.pdb,.idb的文件夹以及其子文件夹,一般此文件夹是在项目文件夹的下一层,叫Debug。
  2. 重新编译调试。

最终弹出对话框!
在这里插入图片描述

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值