第11章 对话框_11.1 模态对话框

对话框管理器——Windows内置的对话框代码

①负责创建对话框窗口及其上面的子窗口控件;在创建对话框函数的内部,Windows使用用户自定义的对话框模板,并且使用Windows内部定义的窗口类(一般类名是“#32770”)来创建对话框。

②提供内置的窗口过程来处理对话框消息(包括所有鼠标和键盘输入)

③内置的窗口过程会将消息传递给我们自定义的“对话框过程”(也叫“对话过程”)。

④对话框中,Windows负责处理在多个控件中转移输入焦点的相关逻辑。

11.1 模态对话框

11.1.1 对话框及其模板

(1)对话框的坐标单位——基于对话框所用的字体的大小(本例为“"MS Shell Dlg"”)

X轴:以字符的平均宽度的1/4为单位。如x=32表示8个字符宽度处

Y轴:以字符的平均高度的1/8为单位。如y=32表示4个字符高度处。

★一般字体的字符高度是宽度的两倍,所以X轴与Y轴的尺寸基本相同
       ★可通过MapDialogRect函数将字符为单位的坐标转换为对话框客户区的像素坐标。

(2)对话框模板

①STYLE语句与CreateWindow中的样式相似,模态对话框用WS_POPUP|DS_MODALFRAME


样式


功能


备注


WM_POPUP


弹出式窗口


模态对话框用WS_POPUP|DS_MODALFRAME


DS_MODALFRAME


去边框


WM_CAPTION


标题栏,允许移动对话框


CAPTION “DialogBox Caption”

SetWindowText(hDlg,TEXT(“对话框”));


WS_SYSMENU


添加系统菜单


允许Move或Close对话框


WS_THICKFRAME


允许改变对话框大小


等价于对话框Border属性中选择Resizing

②MNEU 菜单名  ——允许为对话框添加菜单

③FONT 字号,字体名称 ——发布程序要一起打包

④CLASS “类名”

A、没指定窗口类名时——Windows会自动提供一个特殊的窗口类,该窗口类的内置过程会调用我们定义的对话框过程(由DialogBox最后一个参数提供)

B、指定窗口类名时——可以使用自己的窗口类及窗口过程来处理对话框消息,窗口类的cbWndExtra必须设定为DLGWINDOWEXTRA。

⑤定义子窗口控件格式

控件类型  “文本”,ID,xPos,yPos,xWidth,yHeight,iStyle

CONTROL “文本”,ID,“类”,iStyle,xPos,yPos,xWidth,yHeight //通用格式

A、控件类型


控件类型


窗口类


窗口样式


PUSHBUTTON


button


BS_PUSHBUTTON|WS_TABSTOP


DEFPUSHBUTTON


button


BS_DEFPUSHBUTTON|WS_TABSTOP


CHECKBOX


button


BS_CHECKBOX|WS_TABSTOP


RADIOBUTTON


button


BS_RADIOBUTTON|WS_TABSTOP


GROUPBOX


button


BS_GROUPBOX


LTEXT


static


SS_LEFT|WS_GROUP


CTEXT


static


SS_CENTER|WS_GROUP


RTEXT


static


SS_RIGHT|WS_GROUP


ICON


static


SS_ICON


EDITTEXT


edit


ES_LEFT|WS_BORDER|WS_TABSTOP


SCROLLBAR


scrollbar


SBS_HORZ


LISTBOX


listbox


LBS_NOTIFY|WS_BORDER


COMBOBOX


combobox


CBS_SIMPLE|WS_TABSTOP

★子控件除以上样式外,还有WS_CHILD|WS_VISIBLE样式

★除EDITTEXT、SCROLLBAR、LISTBOX、COMBOBOX没“文本”,其他都有。

控件类型  ID,xPos,yPos,xWidth,yHeight,iStyle//注意,没“文本”这项。

B、文本字段中的符号加“&”会添加一个键盘接口,如“&Red”,按R时,焦点会转过来。

C、应用举例


功能需求


相应的模板语句


复选框,文本左侧


CHECKBOX “TEXT”,ID,xPos,yPos,xWidth,yHeight,BS_LEFTTEXT


没边框的编辑框


EDITTEXT,ID,xPos,yPos,xWidth,yHeight,NOT WS_BORDER


按钮及等价代码


PUSHBUTTON “OK”,IDOK,10,20,32,14

CONTROL “OK”,IDOK,“button”,WS_CHILD|WS_VISIBLE|

BS_PUSHBUTTON|WS_TABSTOP,10,20,32,14

D、模板语句及等价调用(以上面创建按钮的模板语句为例)

hCtrl =CreateWindow(TEXT(“button”,TEXT(“OK”),

WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON|WS_TABSTOP|BS_PUSHBUTTON,10*cxChar/4 ,20*cyChar /8,32*cxChar/4, 14*cyChar/8,

hDlg,IDOK,hInstance,NULL);

⑥WS_TABSTOP——可以通过TAB键获得输入焦点,按TAB键,焦点只会在有WS_TABSTOP的控件间转移。

⑦WS_GROUP——定义一组控件

A、从第一个含有WS_GROUP样式开始,到下一个含有该样式的控件之间的为一组

B、组内控件可以通过方向键循环转移焦点。

C、同组中随着光标移动键,不但会转移焦点,还会赋于新的焦点控件WS_TABSTOP样式,这样下次再按Tab时会定位到该控件上。

⑧不向父窗口发送消息的子控件(如文本和图标),ID设为IDC_STATIC(-1)。

⑨IDOK、IDCANCEL在WINUSER.H中分别被定义为1、2

11.1.2 对话框过程

(1)子窗口向父窗口发送WM_COMMAND过程:子窗口→父窗口(对话框)内置的窗口过程→自定义的对话框过程

(2)对话框过程

BOOL CALLBACK AboutDlgProc(HWND hDlg,UINT msg,WPARAM wParam,lPARAMlParam)

{

switch(message)

{

case WM_INITDIALOG:

return TRUE;  //表示消息处理过了,不让对话框内置的窗口过程处理了。

case WM_COMMAND:

switch(LOWORD(wParam)) //子控件ID

{

case IDOK:

case IDCANCEL:

EndDialog(hDlg,0); //结束模态对话框,0会返回给创建模态对话框的那个函数,如作为DialobBox函数的返回值。

return TRUE; //该消息处理好了,不让内置的窗口过程处理了。

}

}

return FALSE; //False表示其余消息不处理,留给内置对话框窗口过程去处理

}


对话框过程


一般窗口过程


返回值


BOOL


LRESULT


默认处理


当返回值为

①TRUE时表示该消息在对话框过程巳处理,不再传递给内置的对话框处理。

②FALSE 表示该消息未处理好,得再交给内置的对话框过程。


DefWindowProc


接收的第1条消息


①WM_INIDIALOG消息(对话框独有的)进行初始化工作,并把焦点设置为第1个含有WS_TABSTOP的子窗口控件。自定义的对话框过程不会收到WM_CREATE。

②在该消息中可手动设置焦点(SetFocus),但返回值有点特殊,应设为FALSE。如果为TRUE,Windows会自动将输入焦点设置到第一个有WS_TABSTOP的子控件上。


WM_CREATE


创建


DialogBox或DialogBoxIndirectParam——模态

CreateDialog——非模态


CreateWindow


销毁


用EndDialog通知Windows销毁(内部会调用WM_DESTROY)


WM_DESTROY


WM_COMMAND


LOWORD(wParam):子控件、菜单、加速键ID

HIWORD(wParam):通知码,加速键时为1,菜单为0,其它为子控件的通知码

LParam:子控件句柄

【About1程序】

/*------------------------------------------
ABOUT1.C -- About Box Demo Program No. 1
(c) Charles Petzold, 1998
------------------------------------------*/
#include <windows.h>
#include "resource.h"
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
BOOL    CALLBACK AboutDlgProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                   PSTR szCmdLine, int iCmdShow)
{
    static TCHAR szAppName[] = TEXT("About1");
    MSG          msg;
    HWND         hwnd;
    WNDCLASS     wndclass;

    wndclass.style = CS_HREDRAW | CS_VREDRAW;
    wndclass.lpfnWndProc = WndProc;
    wndclass.cbClsExtra = 0;
    wndclass.cbWndExtra = 0;
    wndclass.hInstance = hInstance;
    wndclass.hIcon = LoadIcon(hInstance, szAppName);
    wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
    wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    wndclass.lpszMenuName = szAppName;
    wndclass.lpszClassName = szAppName;

    if (!RegisterClass(&wndclass))
    {
        MessageBox(NULL, TEXT("This program requires Windows NT!"),
                   szAppName, MB_ICONERROR);
        return 0;
    }

    hwnd = CreateWindow(szAppName, TEXT("About Box Demo Program"),
                        WS_OVERLAPPEDWINDOW,
                        CW_USEDEFAULT, CW_USEDEFAULT,
                        CW_USEDEFAULT, CW_USEDEFAULT,
                        NULL, NULL, hInstance, NULL);

    ShowWindow(hwnd, iCmdShow);
    UpdateWindow(hwnd);

    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    static HINSTANCE hInstance;

    switch (message)
    {
    case WM_CREATE:
        hInstance = ((LPCREATESTRUCT)lParam)->hInstance;
        return 0;

    case WM_COMMAND:
        switch (LOWORD(wParam))
        {
        case IDM_APP_ABOUT:
            DialogBox(hInstance, TEXT("AboutBox"), hwnd, AboutDlgProc);
            break;
        }
        return 0;

    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    }
    return DefWindowProc(hwnd, message, wParam, lParam);
}
BOOL CALLBACK AboutDlgProc(HWND hDlg, UINT message,
                           WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_INITDIALOG:
        return TRUE;

    case WM_COMMAND:
        switch (LOWORD(wParam))
        {
        case IDOK:
        case IDCANCEL:
            EndDialog(hDlg, 0);
            return TRUE;
        }
        break;
    }
    return FALSE;
}

//resource.h

//resource.h

//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by About1.rc
//
#define IDM_APP_ABOUT                   40001
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE        104
#define _APS_NEXT_COMMAND_VALUE         40004
#define _APS_NEXT_CONTROL_VALUE         1003
#define _APS_NEXT_SYMED_VALUE           101
#endif
#endif

//About1.rc

//Microsoft Developer Studio generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE DISCARDABLE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE DISCARDABLE
BEGIN
"#include ""afxres.h""\r\n"
"\0"
END
3 TEXTINCLUDE DISCARDABLE
BEGIN
"\r\n"
"\0"
END
#endif    // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
ABOUTBOX DIALOG DISCARDABLE  32, 32, 180, 102
STYLE DS_MODALFRAME | WS_POPUP
FONT 8, "MS Sans Serif"
BEGIN
DEFPUSHBUTTON   "OK", IDOK, 66, 81, 50, 14
ICON            "ABOUT1", IDC_STATIC, 7, 7, 21, 20
CTEXT           "About1", IDC_STATIC, 40, 12, 100, 8
CTEXT           "About Box Demo Program", IDC_STATIC, 7, 40, 166, 8
CTEXT           "(c) Charles Petzold, 1998", IDC_STATIC, 7, 52, 166, 8
END
/////////////////////////////////////////////////////////////////////////////
//
// Menu
//
ABOUT1 MENU DISCARDABLE
BEGIN
POPUP "&Help"
BEGIN
MENUITEM "&About About1...", IDM_APP_ABOUT
END
END
/////////////////////////////////////////////////////////////////////////////
//
// Icon
//
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
ABOUT1                  ICON    DISCARDABLE     "About1.ico"
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO DISCARDABLE
BEGIN
"ABOUTBOX", DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 173
TOPMARGIN, 7
BOTTOMMARGIN, 95
END
END
#endif    // APSTUDIO_INVOKED
#endif    // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif    // not APSTUDIO_INVOKED

11.1.3 更复杂的对话框

【About2程序】
效果图:

/*------------------------------------------------------------
About2.C -- About Box Demo Program No.2
(c) Charles Petzold, 1998
------------------------------------------------------------*/
#include <windows.h>
#include "resource.h"
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
BOOL    CALLBACK AboutDlgProc(HWND, UINT, WPARAM, LPARAM);
TCHAR szAppName[] = TEXT("About2");
int iCurrentColor = IDC_BLACK,
iCurrentFigure = IDC_RECT;
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                   PSTR szCmdLine, int iCmdShow)
{
    HWND         hwnd;
    MSG          msg;
    WNDCLASSEX     wndclass;
    wndclass.style = CS_HREDRAW | CS_VREDRAW;
    wndclass.cbSize = sizeof(WNDCLASSEX);
    wndclass.lpfnWndProc = WndProc;
    wndclass.cbClsExtra = 0;
    wndclass.cbWndExtra = 0;
    wndclass.hInstance = hInstance;
    wndclass.hIcon = LoadIcon(hInstance, szAppName);
    wndclass.hIconSm = LoadIcon(hInstance, szAppName);
    wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
    wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    wndclass.lpszMenuName = szAppName;
    wndclass.lpszClassName = szAppName;
    if (!RegisterClassEx(&wndclass))
    {
        MessageBox(NULL, TEXT("This program requires Windows NT!"),
                   szAppName, MB_ICONERROR);
        return 0;
    }

    hwnd = CreateWindow(szAppName,                  // window class name
                        TEXT("About Box Demo Program"), // window caption
                        WS_OVERLAPPEDWINDOW,        // window style
                        CW_USEDEFAULT,              // initial x position
                        CW_USEDEFAULT,              // initial y position
                        CW_USEDEFAULT,              // initial x size
                        CW_USEDEFAULT,              // initial y size
                        NULL,                       // parent window handle
                        NULL,                       // window menu handle
                        hInstance,                  // program instance handle
                        NULL);                     // creation parameters

    ShowWindow(hwnd, iCmdShow);
    UpdateWindow(hwnd);

    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;
}
void PaintWindow(HWND hwnd, int iColor, int iFigure)
{
    static COLORREF crColor[8] = {
        RGB(0, 0, 0),        //Black
        RGB(0, 0, 255),      //Blue
        RGB(0, 255, 0),      //Green
        RGB(0, 255, 255),    //Cyan
        RGB(255, 0, 0),      //Red
        RGB(255, 0, 255),    //Meganta
        RGB(255, 255, 0),    //Yellow
        RGB(255, 255, 255)   //White
    };
    HDC hdc;
    HBRUSH hBrush;
    RECT rect;

    hBrush = CreateSolidBrush(crColor[iColor - IDC_BLACK]);
    hdc = GetDC(hwnd);
    GetClientRect(hwnd, &rect);
    hBrush = SelectObject(hdc, hBrush);
    if (iFigure == IDC_RECT)  //矩形按钮ID
        Rectangle(hdc, rect.left, rect.top, rect.right, rect.bottom);
    else
        Ellipse(hdc, rect.left, rect.top, rect.right, rect.bottom);
    DeleteObject(SelectObject(hdc, hBrush));
    ReleaseDC(hwnd, hdc);
}
void PaintTheBlock(HWND hCtrl, int iColor, int iFigure)
{
    InvalidateRect(hCtrl, NULL, TRUE);
    //UpdateWindow很重要,要立即生效,原因如下:
    /*
    1、因为经过InvalidateRect后,会向子窗口(IDC_PAINT)发送WM_PAINT到子窗口
    内置的窗口过程
    2、而此时如果不立即UpdateWindow,让子窗口先画出背景,而是直接去执行后
    面那条PaintWindow语句,虽然图形画出了,但会被随后来的WM_PAINT消息重绘掉
    即被背景色覆盖了。会让人误认为PaintWindow没执行的错误。
    */
    UpdateWindow(hCtrl);
    PaintWindow(hCtrl, iColor, iFigure);
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    HDC         hdc;
    PAINTSTRUCT ps;
    static HINSTANCE   hInst;
    switch (message)
    {
    case WM_CREATE:
        hInst = ((LPCREATESTRUCT)lParam)->hInstance;
        return 0;
    case WM_COMMAND:
        switch (LOWORD(wParam)) //子控件ID
        {
        case IDM_APP_ABOUT:
            if (DialogBox(hInst, szAppName, hwnd, AboutDlgProc))
                InvalidateRect(hwnd, NULL, TRUE);
            return 0;
        }
        break;
    case WM_PAINT:
        hdc = BeginPaint(hwnd, &ps);
        EndPaint(hwnd, &ps);
        PaintWindow(hwnd, iCurrentColor, iCurrentFigure);
        return 0;

    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    }
    return DefWindowProc(hwnd, message, wParam, lParam);
}
BOOL CALLBACK AboutDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
    static int iColor, iFigure;
    static HWND hCtrlBlock;
    switch (message)
    {
    case WM_INITDIALOG:
        iColor = iCurrentColor;
        iFigure = iCurrentFigure;
        CheckRadioButton(hDlg, IDC_BLACK, IDC_WHITE, iColor);
        CheckRadioButton(hDlg, IDC_RECT, IDC_ELLIPSE, iFigure);
        hCtrlBlock = GetDlgItem(hDlg, IDC_PAINT);
        SetFocus(GetDlgItem(hDlg, iColor));
        return FALSE;
    case WM_COMMAND:
        switch (LOWORD(wParam))
        {
        case IDOK:
            iCurrentColor = iColor;
            iCurrentFigure = iFigure;
            EndDialog(hDlg, TRUE); //将TRUE作为DialogBox的返回值,用来决定是否重绘主窗口
            return TRUE;
        case IDCANCEL:
            EndDialog(hDlg, FALSE); //将FALSE作为DialogBox的返回值
        case IDC_BLACK:
        case IDC_RED:
        case IDC_GREEN:
        case IDC_YELLOW:
        case IDC_BLUE:
        case IDC_MAGENTA:
        case IDC_CYAN:
        case IDC_WHITE:
            iColor = LOWORD(wParam);
            CheckRadioButton(hDlg, IDC_BLACK, IDC_WHITE, iColor);
            PaintTheBlock(hCtrlBlock, iColor, iFigure);
            return TRUE;
        case IDC_RECT:
        case IDC_ELLIPSE:
            iFigure = LOWORD(wParam);
            CheckRadioButton(hDlg, IDC_RECT, IDC_ELLIPSE, iFigure);
            PaintTheBlock(hCtrlBlock, iColor, iFigure);
            return TRUE;
        }
        break;
    case WM_PAINT:
        PaintTheBlock(hCtrlBlock, iColor, iFigure);
        break; //不能直接return TRUE; 要交默认处理,因为无效区要通过BeginPaint有效化。
    }
    return FALSE;
}

//resource.h

//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ 生成的包含文件。
// 供 About2.rc 使用
//
#define IDC_BLACK                       1001
#define IDC_BLUE                        1002
#define IDC_GREEN                       1003
#define IDC_CYAN                        1004
#define IDC_RED                         1005
#define IDC_MAGENTA                     1006
#define IDC_YELLOW                      1007
#define IDC_WHITE                       1008
#define IDC_RECT                        1009
#define IDC_ELLIPSE                     1010
#define IDC_PAINT                       1011
#define IDM_APP_ABOUT                   40001
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE        104
#define _APS_NEXT_COMMAND_VALUE         40004
#define _APS_NEXT_CONTROL_VALUE         1012
#define _APS_NEXT_SYMED_VALUE           101
#endif
#endif

//About2.rc

// Microsoft Visual C++ generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "winres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// 中文(简体,中国) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)
LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE
BEGIN
"#include ""winres.h""\r\n"
"\0"
END
3 TEXTINCLUDE
BEGIN
"\r\n"
"\0"
END
#endif    // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Icon
//
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
ABOUT2                  ICON                    "About2.ico"
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
ABOUT2 DIALOGEX 32, 32, 200, 234
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
DEFPUSHBUTTON   "&Ok", IDOK, 36, 205, 50, 14
PUSHBUTTON      "Cancel", IDCANCEL, 99, 204, 50, 14
ICON            "ABOUT2", IDC_STATIC, 7, 7, 21, 20
LTEXT           "About2", IDC_STATIC, 95, 14, 24, 8
LTEXT           "About Box Demo Program", IDC_STATIC, 69, 31, 83, 8
LTEXT           "", IDC_PAINT, 102, 55, 77, 79
GROUPBOX        "&Color", IDC_STATIC, 17, 49, 73, 141
CONTROL         "&Black", IDC_BLACK, "Button", BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP, 25, 61, 32, 10
CONTROL         "B&lue", IDC_BLUE, "Button", BS_AUTORADIOBUTTON, 25, 77, 29, 10
CONTROL         "&Green", IDC_GREEN, "Button", BS_AUTORADIOBUTTON, 25, 93, 35, 10
CONTROL         "Cya&n", IDC_CYAN, "Button", BS_AUTORADIOBUTTON, 25, 109, 33, 10
CONTROL         "&Red", IDC_RED, "Button", BS_AUTORADIOBUTTON, 25, 125, 29, 10
CONTROL         "&Megenta", IDC_MAGENTA, "Button", BS_AUTORADIOBUTTON, 25, 141, 44, 10
CONTROL         "&Yellow", IDC_YELLOW, "Button", BS_AUTORADIOBUTTON, 25, 157, 36, 10
CONTROL         "&White", IDC_WHITE, "Button", BS_AUTORADIOBUTTON, 26, 173, 35, 10
GROUPBOX        "&Figure", IDC_STATIC, 100, 146, 82, 43
CONTROL         "Rec&tangle", IDC_RECT, "Button", BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP, 112, 158, 48, 10
CONTROL         "&Ellipse", IDC_ELLIPSE, "Button", BS_AUTORADIOBUTTON, 112, 175, 35, 10
END
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO
BEGIN
"ABOUT2", DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 192
TOPMARGIN, 7
BOTTOMMARGIN, 228
END
END
#endif    // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Menu
//
ABOUT2 MENU
BEGIN
POPUP "&Help"
BEGIN
MENUITEM "&About", IDM_APP_ABOUT
END
END
#endif    // 中文(简体,中国) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif    // not APSTUDIO_INVOKED

(1)对话框控件的应用

① 对比三种设置控件状态函数


将一组单选按钮的第3个设为Checked状态


第1种


for (i=idFirst,i<=idLast,i++)

{

SendMessage(GetDlgItem(hDlg,i),BM_SETCHECK,i==3,0);

}


第2种


for (i=idFirst,i<=idLast,i++)

{

SendDlgItemMessage(hDlg,i,BM_SETCHECK,i==3,0);

}


第3种


CheckRadioButton(hDlg,idFirst,idLast,3);

②设置和获到复选框的状态

CheckDlgButton(hDlg,idCheckBox,iCheck);

iCheck = IsDlgButtonChecked(hDlg,idCheckBox);

(2)避免全局变量——iCurrentColor和iCurrentFigure是全局变量,应尽量避免!

①先定义结构体

typedef struct

{

int iColor,iFigure;

}ABOUTBOX_DATA;

②WndProc的改动

A、声明部分:Static ABOUTBOX_DATA ad = {IDC_BLACK,IDC_RECT};

B、创建对话框: DialogBoxParam(hInst,TEXT(“AboutBox”),hwnd,AboutDlgProc,&ad);

③对话框过程的变动

A、声明部分:static ABOUTBOX_DATA ad, *pad;

B、WM_INITDIALOG: pad = (ABOUT_DATA*)lParam;//从lParam取出传进来的ad

ad =*pad;

(3)禁用或启用子控件:EnableWindow(hwndCtrl,bEnable);

11.1.4 定义自己的控件

(1)定义自己的子控件,并运用于对话框,并用自己定义的子窗口过程来处理子窗口消息。

(2)自定义子控件:在CONTROL语句中,指定自己的窗口类。

/*------------------------------------------------------------
About3.C -- About Box Demo Program No.3
(c) Charles Petzold, 1998
------------------------------------------------------------*/
#include <windows.h>
#include "resource.h"
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK EllipsePushWndProc(HWND, UINT, WPARAM, LPARAM);
BOOL    CALLBACK AboutDlgProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                   PSTR szCmdLine, int iCmdShow)
{
    static TCHAR szAppName[] = TEXT("About3");
    HWND         hwnd;
    MSG          msg;
    WNDCLASSEX     wndclass;
    wndclass.style = CS_HREDRAW | CS_VREDRAW;
    wndclass.cbSize = sizeof(WNDCLASSEX);
    wndclass.lpfnWndProc = EllipsePushWndProc;
    wndclass.cbClsExtra = 0;
    wndclass.cbWndExtra = 0;
    wndclass.hInstance = hInstance;
    wndclass.hIcon = NULL;
    wndclass.hIconSm = NULL;
    wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
    wndclass.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
    wndclass.lpszMenuName = NULL;
    wndclass.lpszClassName = TEXT("EllipsePush");
    if (!RegisterClassEx(&wndclass))
    {
        MessageBox(NULL, TEXT("This program requires Windows NT!"),
                   szAppName, MB_ICONERROR);
        return 0;
    }

    wndclass.style = CS_HREDRAW | CS_VREDRAW;
    wndclass.cbSize = sizeof(WNDCLASSEX);
    wndclass.lpfnWndProc = WndProc;
    wndclass.cbClsExtra = 0;
    wndclass.cbWndExtra = 0;
    wndclass.hInstance = hInstance;
    wndclass.hIcon = LoadIcon(hInstance, szAppName);
    wndclass.hIconSm = LoadIcon(hInstance, szAppName);
    wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
    wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    wndclass.lpszMenuName = szAppName;
    wndclass.lpszClassName = szAppName;
    RegisterClassEx(&wndclass);
    hwnd = CreateWindow(szAppName,                  // window class name
                        TEXT("About Box Demo Program"), // window caption
                        WS_OVERLAPPEDWINDOW,        // window style
                        CW_USEDEFAULT,              // initial x position
                        CW_USEDEFAULT,              // initial y position
                        CW_USEDEFAULT,              // initial x size
                        CW_USEDEFAULT,              // initial y size
                        NULL,                       // parent window handle
                        NULL,                       // window menu handle
                        hInstance,                  // program instance handle
                        NULL);                     // creation parameters

    ShowWindow(hwnd, iCmdShow);
    UpdateWindow(hwnd);

    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    HDC         hdc;
    PAINTSTRUCT ps;
    static HINSTANCE hInst;

    switch (message)
    {
    case WM_CREATE:
        hInst = ((LPCREATESTRUCT)lParam)->hInstance;
        return 0;
    case WM_COMMAND:
        switch (LOWORD(wParam))
        {
        case IDM_APP_ABOUT:
            DialogBox(hInst, TEXT("About3"), hwnd, AboutDlgProc);
            return 0;
        }
        break;
    case WM_PAINT:
        hdc = BeginPaint(hwnd, &ps);

        EndPaint(hwnd, &ps);
        return 0;

    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    }
    return DefWindowProc(hwnd, message, wParam, lParam);
}
BOOL    CALLBACK AboutDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_INITDIALOG:
        return TRUE;
    case WM_COMMAND:
        switch (LOWORD(wParam))
        {
        case IDOK:
            EndDialog(hDlg, 0);
            return TRUE;
        }
        break;
    }
    return  FALSE;
}
//子窗口(按钮)过程
LRESULT CALLBACK EllipsePushWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    TCHAR  szText[40];
    HBRUSH hBrush;
    HDC hdc;
    PAINTSTRUCT ps;
    RECT rc;
    switch (message)
    {
    case WM_PAINT:
        GetClientRect(hwnd, &rc);
        GetWindowText(hwnd, szText, sizeof(szText));
        hdc = BeginPaint(hwnd, &ps);
        hBrush = CreateSolidBrush(GetSysColor(COLOR_WINDOW));
        hBrush = SelectObject(hdc, (HGDIOBJ)hBrush);
        SetBkColor(hdc, GetSysColor(COLOR_WINDOW));
        SetTextColor(hdc, GetSysColor(COLOR_WINDOWTEXT));
        Ellipse(hdc, rc.left, rc.top, rc.right, rc.bottom);
        DrawText(hdc, szText, -1, &rc,
                 DT_SINGLELINE | DT_CENTER | DT_VCENTER);
        DeleteObject(hBrush);
        EndPaint(hwnd, &ps);
        return 0;
    case WM_KEYUP:
        if (wParam != VK_SPACE)
            break;
        //继续执行下去,处理空格键
    case WM_LBUTTONUP:
        SendMessage(GetParent(hwnd), WM_COMMAND, GetWindowLong(hwnd, GWL_ID), (LPARAM)hwnd);
        return 0;
    }
    return DefWindowProc(hwnd, message, wParam, lParam);
}

//resource.h

//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ 生成的包含文件。
// 供 About3.rc 使用
//
#define IDM_APP_ABOUT                   40002
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE        104
#define _APS_NEXT_COMMAND_VALUE         40003
#define _APS_NEXT_CONTROL_VALUE         1002
#define _APS_NEXT_SYMED_VALUE           101
#endif
#endif

//About3.rc

// Microsoft Visual C++ generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "winres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// 中文(简体,中国) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)
LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE
BEGIN
"#include ""winres.h""\r\n"
"\0"
END
3 TEXTINCLUDE
BEGIN
"\r\n"
"\0"
END
#endif    // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Menu
//
ABOUT3 MENU
BEGIN
POPUP "&Help"
BEGIN
MENUITEM "About About3...", IDM_APP_ABOUT
END
END
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
ABOUT3 DIALOGEX 0, 0, 167, 150
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
ICON            "ABOUT3", IDC_STATIC, 7, 7, 20, 20
LTEXT           "About3", IDC_STATIC, 68, 33, 24, 8
LTEXT           "About Box Demo Program", IDC_STATIC, 44, 55, 83, 8
LTEXT           "(c) Charles PetZold,1998", IDC_STATIC, 44, 77, 80, 8
CONTROL         "OK", IDOK, "EllipsePush", WS_TABSTOP, 54, 113, 50, 14 //这里EllipsePush为自定义的 窗口类,很重要!
END
/////////////////////////////////////////////////////////////////////////////
//
// Icon
//
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
ABOUT3                  ICON                    "ICON1.ICO"
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO
BEGIN
"ABOUT3", DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 157
TOPMARGIN, 7
BOTTOMMARGIN, 142
END
END
#endif    // APSTUDIO_INVOKED
#endif    // 中文(简体,中国) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif    // not APSTUDIO_INVOKED
时间: 2024-10-10 00:23:07

第11章 对话框_11.1 模态对话框的相关文章

MFC 模态对话框与非模态对话框

1 1 模态对话框与非模态对话框 2 //1 3 CChatDlg *pChatDlg = new CChatDlg; //pChatDlg会被释放 4 if (FALSE == pChatDlg->Create(IDD_CHAT_DLG, this)) 5 { 6 return; 7 } 8 pChatDlg->ShowWindow(SW_SHOW); //不show看不到的 9 10 //2 再次点击不能用了 11 12 CChatDlg pChatDlg; //.h 13 if (FAL

QT笔记之模态对话框及非模态对话框

模态对话框(Modal Dialog)与非模态对话框(Modeless Dialog)的概念不是Qt所独有的,在各种不同的平台下都存在.又有叫法是称为模式对话框,无模式对话框等.所谓模态对话框就是在其没有被关闭之前,用户不能与同一个应用程序的其他窗口进行交互,直到该对话框关闭.对于非模态对话框,当被打开时,用户既可选择和该对话框进行交互,也可以选择同应用程序的其他窗口交互. 在Qt中,显示一个对话框一般有两种方式,一种是使用exec()方法,它总是以模态来显示对话框:另一种是使用show()方法

MFC中模态对话框和非模态对话框

MFC的对话框非为两种,一种叫模态对话框(Modal  Dialog  Box,又叫做模式对话框),一种叫做非模式对话框(Modaless Dialog Box,又叫无模式对话框).两者的区别在于当对话框打开的时候,是否允许用户进行其他对象的操作. 一.模态对话框 模态对话框指,当用户需要对该对话框之外的其他对话框或者模块进行操作时,必须该对话框关闭,才能去编辑其他对话框或者模块. 创建如下: //创建模态对话框 CModalDialog modalDialog; modalDialog.DoM

MFC中模态对话框和非模态对话框的区别

在MFC中有模态对话框和非模态对话框,那这两种有什么区别呢.又都是用于什么场合呢. 首先,要弄清楚2种对话框是如何创建的. 然后要弄清楚2种对话框有什么区别,可能从表面上看,模态会阻塞主对话框,可原理是什么呢. 还有就是,当有模态和非模态对话框没有关闭的时候,在任务栏中,关闭主窗体,会有什么样的效果呢. 虽然,现在有很多优秀的开源库比如QT,DUI等,但是这些原理,我们还是要了解的,不能停留在用的层面.有人说MFC过时了,有人说,现在有很多开源库,知道怎么用就可以了.但是现在界面要的交互好,界面

模态对话框与非模态对话框

①.区别 模态对话框:创建后,程序的其他窗口便不能进行操作,必须将该窗口关闭后,其他窗口才能进行操作.------父线程阻塞,子线程运行 非模态对话框:无需像模态对话框那样,它不强制要求用户立即反应,而是与其他窗口同时接受用户操作.-----父子线程同时运行 ②.添加资源与类绑定 资源窗口添加Dlg资源,Dlg窗口右键Add Class 绑定类.选择继承类 CDialog. ②.对话框创建与显示 模态对话框:CDialog::DoModal CMyDialog dlg;//继承CDialog类的

VC++模态对话框和非模态对话框

MFC中有两种类型的对话框:模态对话框和非模态对话框. 模态对话框是指当其显示时,程序会暂停执行,直到关闭这个模态对话框后,才能继续执行程序中其他任务.非模态对话框是指当其显示时,允许转而执行程序中其他任务,而不用关闭这个对话框. 模态对话框的创建:创建模态对话框需要调用CDialog类的成员函数:DoModal,该函数的功能是创建并显示一个模态对话框,其返回值将作为CDialog类的另一个成员函数:EndDialog的参数,后者的功能是关闭模态对话框.一般显示模态对话框的实现代码如下: voi

VS2010/MFC对话框:非模态对话框的创建及显示

非模态对话框的创建及显示 上一节讲了模态对话框及其弹出过程,本节接着讲另一种对话框--非模态对话框的创建及显示. 已经说过,非模态对话框显示后,程序其他窗口仍能正常运行,可以响应用户输入,还可以相互切换.鸡啄米会将上一讲中创建的Tip模态对话框改为非模态对话框,让大家看下效果. 非模态对话框的对话框资源和对话框类 实际上,模态对话框和非模态对话框在创建对话框资源和生成对话框类上是没有区别的,所以上一讲中创建的IDD_TIP_DIALOG对话框资源和CTipDlg类都不需要修改. 创建及显示非模态

QT模态对话框及非模态对话框

QT模态对话框及非模态对话框 模态对话框(Modal Dialog)与非模态对话框(Modeless Dialog)的概念不是Qt所独有的,在各种不同的平台下都存在.又有叫法是称为模式对话框,无模式对话框等.所谓模态对话框就是在其没有被关闭之前,用户不能与同一个应用程序的其他窗口进行交互,直到该对话框关闭.对于非模态对话框,当被打开时,用户既可选择和该对话框进行交互,也可以选择同应用程序的其他窗口交互. 在Qt中,显示一个对话框一般有两种方式,一种是使用exec()方法,它总是以模态来显示对话框

第11章 对话框_11.3 通用对话框

11.3 通用对话框 11.3.1 完善POPAD (1)通用对话框:#include<commdlg.h> (2)OPENFILENAME结构 字段 含义 备注 lStructSize 结构体的大小 hwndOwner 所属窗口,可以为NULL hInstance lpstrFilter 文件筛选字符串 TCHAR szFilter[] = TEXT ("Text Files (*.TXT)\0*.txt\0")\ TEXT ("ASCII Files (*.A