• 第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"
    END
    2 TEXTINCLUDE DISCARDABLE
    BEGIN
    "#include ""afxres.h""
    "
    ""
    END
    3 TEXTINCLUDE DISCARDABLE
    BEGIN
    "
    "
    ""
    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); //这句意思是,在绘制新图像前,先把hCtrl上旧的内容清除掉。
        
    //UpdateWindow的意思是,上述的操作要立即生效。然后再去执行PaintWindow,画出新的内容。
    //这个顺序很好理解,因为要绘制新内容前,得先清除旧的内容。
    //UpdateWindow很重要,要立即生效,原因如下: /* 1、如果不UpdateWindow的话,经过InvalidateRect,系统会向hCtrl窗口内置的窗口过程发送WM_PAINT消息
    但这条消息不会被马上执行。换句话讲,程序执行完InvalidateRect后,会直接执行PaintWindow,此时此
    刻新的内容确实在hCtrl上画出来了。
    2、但问题来了,当本函数执行完后,因消息队列中,还有一条WM_PAINT消息。所以程序会转去执行这条消息。这
    意味着,对于hCtrl来说,那个“清除”操作延迟到现在才执行,所以就会把新的内容给“清除”掉。结果表现出来,
    好象这个函数就只擦除以前的以容,然后什么事都没做。
    */ 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"
    END
    2 TEXTINCLUDE
    BEGIN
    "#include ""winres.h""
    "
    ""
    END
    3 TEXTINCLUDE
    BEGIN
    "
    "
    ""
    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"
    END
    2 TEXTINCLUDE
    BEGIN
    "#include ""winres.h""
    "
    ""
    END
    3 TEXTINCLUDE
    BEGIN
    "
    "
    ""
    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
  • 相关阅读:
    Coding 账户与 本地 Git 客户端的配置
    leetcode_sort-list
    leetcode_insertion-sort-list
    leetcode_move-zeroes
    search-insert-position
    leetcode_remove-nth-node-from-end-of-list
    leetcode_queue-reconstruction-by-height
    leetcode_valid-parentheses
    leetcode_swap-nodes-in-pairs
    20201115-东北师范大学-助教-周总结-第9次
  • 原文地址:https://www.cnblogs.com/5iedu/p/4695071.html
Copyright © 2020-2023  润新知