18.对话框窗口

1.对话框分类

  (1)模式对话框

     当对话框显示时,会禁止本进程其他窗口的输入等用户交互操作

  (2)无模式对话框

     在对话框显示时,本进程其他窗口同样可以接受输入等用户交互操作

2.模式对话框基本使用

  (1)对话框窗口处理函数(并非真正的对话框处理函数,缺省处理函数会调用自定义的处理函数)

     INT CALLBACK DialogProc( HWND       hWndDlg,  //窗口句柄

                                                     UINT         uMsg,        //消息ID

                                                     WPARAM   wParam,    //消息参数

                                                     LPARAM     lParam);    //消息参数

     返回TRUE - 表示DialogProc函数中处理了这个消息,缺省处理函数不需要处理

     返回FALSE - 表示DialogProc函数未处理这个消息,交给缺省处理函数处理

     缺省处理函数的大致过程:

       缺省函数( ... )

       {

         ...   //确定调用提交上来的哪个函数

         if ( DlgProc )

           return ...;

         ...  //给各种消息做默认处理

       }

  (2)注册窗口类(可选,基本不使用)

  (3)创建对话框

     INT DialogBox( HINSTANCE   hInstance,      //应用程序实例句柄

                                    LPCTSTR       lpTemplate,     //对话框模板资源ID

                                    HWND           hWndParent,   //对话框父窗口

                                    DLGPROC      lpDialogFunc);  //自定义的处理函数

     需要添加对话框资源。DialogBox是一个阻塞函数,只有当对话框关闭后,才会返回,继续执行后续代码。

     返回值通过EndDialog设置。

  (4)关闭对话框

     BOOL EndDialog( HWND  hDlg,        //对话框窗口句柄

                                       INT       nResult);  //关闭返回值

     关闭模式对话框只能使用EndDialog,不能使用DestroyWindow等函数。

     nResult是DialogBox函数退出时的返回值

  (5)对话框消息

     WM_INITDIALOG - 对话框创建之后显示之前产生,用于通知对话框处理函数完成初始化相关操作。

     (普通窗口创建之后显示之前出现的是WM_CREATE消息)

3.无模式对话框

  (1)对话框窗口处理函数DialogProc

  (2)创建对话框

     HWND CreateDialog( HINSTANCE  hInstance,

                                            LPCTSTR      lpTemplate,

                                            HWND         hWndParent,

                                            DLGPROC     lpDialogFunc);

     非阻塞函数,创建成功返回窗口句柄,需要使用ShowWindow函数显示对话框。

  (3)关闭对话框

     关闭时,使用DestroyWindow销毁窗口,不能使用EndDialog关闭对话框。

4.对话框和普通窗口比较

  (1)创建

     模式对话框 - DialogBox,阻塞函数

     无模式对话框 - CreateDialog,非阻塞函数

     普通窗口 - CreateWindow/Ex

  (2)窗口处理函数

     对话框 - DialogProc(并非真正对话框处理函数)

     普通窗口 - WindowProc,需要调用缺省窗口处理函数

  (3)窗口消息

     对话框 - WM_INITDIALOG

     普通窗口 - WM_CREATE

  (4)窗口关闭

     模式对话框 - EndDialog

     无模式对话框/普通窗口 - DestroyWindow

相关代码:

#include "stdafx.h"

HINSTANCE g_hInstance = 0;  //接收当前程序实例句柄

int CALLBACK DlgProc(HWND hWndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch (msg)
    {
    case WM_INITDIALOG:
        MessageBox(hWndDlg, "WM_INITDIALOG", "Info", MB_OK);
        break;
    case WM_CREATE:
        MessageBox(hWndDlg, "WM_CREATE", "Info", MB_OK);
        break;
    case WM_SYSCOMMAND:
        if (SC_CLOSE == wParam)
        {
            //销毁模式对话框
            EndDialog(hWndDlg, 1001);
            //DestroyWindow(hWndDlg);
            return TRUE;
        }
        break;
    case WM_DESTROY:
        break;
    }
    return FALSE; //将消息交给真正的对话框处理函数做默认处理
}

int CALLBACK NoModelDlgProc(HWND hWndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch (msg)
    {
    case WM_INITDIALOG:
        MessageBox(hWndDlg, "WM_INITDIALOG", "Info", MB_OK);
        break;
    case WM_CREATE:
        MessageBox(hWndDlg, "WM_CREATE", "Info", MB_OK);
        break;
    case WM_DESTROY:
        MessageBox(hWndDlg, "我要销毁了", "Info", MB_OK);
        break;
    case WM_SYSCOMMAND:
        if (SC_CLOSE == wParam)
        {
            DestroyWindow(hWndDlg);
            //EndDialog(hWndDlg, 12345);//只能将无模式对话框隐藏
        }
        break;
    }
    return FALSE;
}

void OnModel(HWND hWnd)
{
    int nRet = DialogBox(g_hInstance, MAKEINTRESOURCE(IDD_DIALOG1), hWnd, DlgProc);
    if (nRet == 1001)
    {
        MessageBox(hWnd, "successful", "Info", MB_OK);
    }
}

void OnNoModel(HWND hWnd)
{
    HWND hDlg = CreateDialog(g_hInstance, MAKEINTRESOURCE(IDD_DIALOG2), hWnd, NoModelDlgProc);
    ShowWindow(hDlg, SW_SHOW);
}

void OnCommand(HWND hWnd, WPARAM wParam)
{
    switch (LOWORD(wParam))
    {
    case ID_MODEL:
        OnModel(hWnd);
        break;
    case ID_NOMODEL:
        OnNoModel(hWnd);
        break;
    }
}

//窗口处理函数
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch (msg)
    {
    case WM_COMMAND:
        OnCommand(hWnd, wParam);
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    }
    return DefWindowProc(hWnd, msg, wParam, lParam);
}
//注册窗口类
BOOL Register(LPSTR lpClassName, WNDPROC wndProc)
{
    WNDCLASSEX wce = { 0 };

    wce.cbSize        = sizeof(wce);
    wce.cbClsExtra    = 200;
    wce.cbClsExtra    = 200;
    wce.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    wce.hCursor       = NULL;
    wce.hIcon         = NULL;
    wce.hIconSm       = NULL;
    wce.hInstance     = g_hInstance;
    wce.lpfnWndProc   = wndProc;
    wce.lpszClassName = lpClassName;
    wce.lpszMenuName  = MAKEINTRESOURCE(IDR_MENU1);
    wce.style         = CS_HREDRAW | CS_VREDRAW;

    ATOM nAtom = RegisterClassEx(&wce);
    if (0 == nAtom)
    {
        return FALSE;
    }
    return TRUE;
}
//创建主窗口
HWND CreateMainWindow(LPSTR lpClassName, LPSTR lpWndName)
{
    HWND hWnd = CreateWindowEx(0, lpClassName, lpWndName, WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
        NULL, NULL, g_hInstance, NULL);
    return hWnd;
}
//显示窗口
void Display(HWND hWnd)
{
    ShowWindow(hWnd, SW_SHOW);
    UpdateWindow(hWnd);
}
//消息循环
void Message()
{
    MSG nMsg = { 0 };
    while (GetMessage(&nMsg, NULL, 0, 0))
    {
        TranslateMessage(&nMsg);
        DispatchMessage(&nMsg);
    }
}

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
{
    g_hInstance = hInstance;
    Register("Main", WndProc);
    HWND hWnd = CreateMainWindow("Main", "window");
    Display(hWnd);
    Message();

    return 0;
}
View Code

运行结果:

  

  

原文地址:https://www.cnblogs.com/csqtech/p/5639067.html