对话框

模态对话框

image.png
对话框提升了我们创建可视化界面的方便性 但底层依旧是我们前面学习的Win32 底层api创建
对话框分为模态对话框和非模态对话框 区别
模式对话框(modal dialog box模态对话框):在关闭模式对话框之前,程序不能进行其他工作(如一般的“打开文件”对话框) 阻塞
无模式对话框(modeless dialog box 非模态对话框):模式对话框打开后,程序仍然能够进行其他工作(如一般的“查找与替换”对话框) 非阻塞
在WInMain里面可以构造一个对话框 通过使用`DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), NULL, Dlgproc);
原型为

INT_PTR WINAPI DialogBox(
In_opt HINSTANCE hInstance,//必须从WinMain的第一个参数获取
In LPCTSTR lpTemplate,
In_opt HWND hWndParent,
In_opt DLGPROC lpDialogFunc
);

Dlgproc是对话的窗口过程函数 和我们之前在win32窗口创建中一样 窗口过程函数是处理消息最重要的地方
原型为
INT_PTR CALLBACK theProc(HWND, UINT, WPARAM, LPARAM)
这里需要说明一下前面加上的CALLBACK

image.png
即函数调用约定
__cdecl和__stdcall的区别和联系_stdcall和cdecl-CSDN博客这篇文章很详细
一般我们windows使用的是_stdcall 声明一下函数的调用约定 不然无法通过编译

对话框响应消息


#include<Windows.h>

#include<CommCtrl.h>

#include"resource.h"

INT_PTR WINAPI Dlgproc(HWND, UINT, WPARAM, LPARAM);

int WINAPI WinMain(HINSTANCE hIstance, HINSTANCE hPreinstance, PSTR szCmdline, int nShow)

{

    DialogBox(hIstance, MAKEINTRESOURCE(IDD_DIALOG1), NULL, Dlgproc);

}

  

INT_PTR WINAPI Dlgproc(HWND hwnd,UINT message,WPARAM wParam,LPARAM unnamedParam4)

{

    switch (message)

    {

    case WM_COMMAND:

    {

        UINT ncode = HIWORD(wParam);

        UINT nID = LOWORD(wParam);

        if (nID == IDC_BUTTON1)

        {

            MessageBox(NULL, TEXT("按钮1被单击"), TEXT("tips"), MB_OK);

  

        }

        else if (nID == IDC_BUTTON2)

        {

            MessageBox(NULL, TEXT("按钮2被单击"), TEXT("tips"), MB_OK);

        }

        else if (nID == IDCANCEL)

        {

            EndDialog(hwnd, 888);

        }

    }

  

    default:

        break;

    }

    return false;

}

非模态对话框

基本上和模态对话框是一样的 不一样的地方在于 主窗口线程的创建 HWND hDlg = CreateDialog(hIstance, MAKEINTRESOURCE(IDD_DIALOG1), NULL, Dlgproc);创建完之后我们会发现并没有出现窗口  可以加入showwindow()   Sleep(INFINITE); 这时候发现窗口会被卡死 因为我们阻塞了窗口处理消息 用sleep 在模态对话框中默认会有一个处理消息的函数 所以我们可以在这里加上


    MSG msg = { 0 };

    while (GetMessage(&msg,NULL,0,0))

    {

        TranslateMessage(&msg);

        DispatchMessage(&msg);

    }

保证我们可以继续处理消息 不会被阻断
非模态对话框退出 需要使用   DestroyWindow(hwnd); 如果使用Enddialog会造成进程无法完全退出
但是我们经过试验之后发现进程还是无法退出 如图
QQ截图20231206235901(1).png
我们经过分析可以知道是getmessage一直在接收消息没有退出 我们可以在发送退出消息的时候调用   PostQuitMessage(888);这样就可以完全退出了
代码如下


#include<Windows.h>

#include<CommCtrl.h>

#include"resource.h"

INT_PTR WINAPI Dlgproc(HWND, UINT, WPARAM, LPARAM);

int WINAPI WinMain(HINSTANCE hIstance, HINSTANCE hPreinstance, PSTR szCmdline, int nShow)

{

    HWND hDlg = CreateDialog(hIstance, MAKEINTRESOURCE(IDD_DIALOG1), NULL, Dlgproc);

    ShowWindow(hDlg, nShow);

  

    MSG msg = { 0 };

    while (GetMessage(&msg,NULL,0,0))

    {

        TranslateMessage(&msg);

        DispatchMessage(&msg);

    }

    return 0;

}

  

INT_PTR WINAPI Dlgproc(HWND hwnd, UINT message, WPARAM wParam, LPARAM unnamedParam4)

{

    switch (message)

    {

    case WM_COMMAND:

    {

        UINT ncode = HIWORD(wParam);

        UINT nID = LOWORD(wParam);

        if (nID == IDC_BUTTON1)

        {

            MessageBox(NULL, TEXT("按钮1被单击"), TEXT("tips"), MB_OK);

        }

        else if (nID == IDC_BUTTON2)

        {

            MessageBox(NULL, TEXT("按钮2被单击"), TEXT("tips"), MB_OK);

        }

        else if (nID == IDCANCEL)

        {

            DestroyWindow(hwnd);

            PostQuitMessage(888);

        }

    }

  

    default:

        break;

    }

    return false;

}

网站标题:CV鼻祖洋芋

原创文章,作者:locus,如若转载,请注明出处:https://blog.cvpotato.cn/forward-code/287/

本博客所发布的内容,部分为原创文章,转载注明来源,网络转载文章如有侵权请联系站长!

(0)
上一篇 6天前
下一篇 6天前

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注