为您推荐:
精华内容
最热下载
问答
  • 5星
    1.56MB m0_52957036 2020-10-30 02:50:05
  • 155KB weixin_42097189 2021-02-05 01:45:23
  • 要把一个对话框添加到Visual C++ Developer Studio会有的应用程序上,可以先从Insert菜单中选择Resource,然后选择Dialog Box。现在一个对话框出现在您的眼前,该对话框带有标题列、标题(Dialog)以及OK和Cancel按钮...

    要把一个对话框添加到Visual C++ Developer Studio会有的应用程序上,可以先从Insert菜单中选择Resource,然后选择Dialog Box。现在一个对话框出现在您的眼前,该对话框带有标题列、标题(Dialog)以及OK和Cancel按钮。Controls工具列允许您在对话框中插入不同的控件。

    Developer Studio将对话框的ID设为标准的IDD_DIALOG1。您可以在此名称上(或者在对话框本身)单击右键,然后从菜单中选择Properties。在本程序中,将ID改为「AboutBox」(带有引号)。为了与我建立的对话框保持一致,请将X Pos和Y Pos字段改为32。这表示对话框相对于程序窗口显示区域左上角的显示位置待会会有关于对话框坐标的详细讨论)。

    现在,继续在Properties对话框中选择Styles页面标签。因为此对话框没有标题列,所以不要选取Title Bar复选框。然后请单击Properties对话框的关闭按钮。

    现在可以设计对话框了。因为不需要Cancel按钮,所以先单击该按钮,然后按下键盘上的Delete键。接着单击OK按钮,将其移动到对话框的底部。在Developer Studio窗口下面的工具列上有一个小位图,它可使控件在窗口内水平居中对齐,请按下此钮。

    如果您要让程序的图标出现在对话框中,可以这样做:先在浮动的Controls工具列中按下「Pictures」按钮。将鼠标移动到对话框的表面,按下左键,然后拉出一个矩形。这就是图标将出现的位置。然后在次矩形上按下鼠标右键,从菜单中选择Properties。保持ID为IDC_STATIC。此标识符在RESOURCE.H中定义为-1,用于程序中不使用的所有ID。将Type改为Icon。您可以在Image字段输入程序图标的名称,或者,如果您已经建立了一个图示,那么您也可以从下拉式清单方块中选择一个名称(About1)。

    对于对话框中的三个静态字符串,可以从Controls工具列中选择Static Text,然后确定文字在对话框中的位置。右键单击控件,然后从菜单中选择Properties。在Properties框的Caption字段中输入要显示的文字。选择Styles页面标签,从Align Text字段选择Center。

    在添加这些字符串的时候,若希望对话框可以更大一些,请先选中对话框,然后拖曳边框。您也可以选择并缩放控件。通常用键盘上的光标移动键完成此操作会更容易些。箭头键本身移动控件,按下Shift键后按箭头键,可以改变控件的大小。所选控件的坐标和大小显示在Developer Studio窗口的右下角。

    如果您建立了一个应用程序,那么以后在查看资源描述档ABOUT1.RC时,您将发现Developer Studio建立的模板。我所设计的对话框模板如下:

    ABOUTBOX DIALOG DISCARDABLE 32, 32, 180, 100

    STYLE DS_MODALFRAME | WS_POPUP

    FONT 8, "MS Sans Serif"

    BEGIN

    DEFPUSHBUTTON "OK",IDOK,66,80,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

    第一行给出了对话框的名称(这里为ABOUTBOX)。如同其它资源,您也可以使用数字作为对话框的名称。名称后面是关键词DIALOG和DISCARDABLE以及四个数字。前两个数字是对话框左上角的x、y坐标,该坐标在程序呼叫对话框时,是相对于父窗口显示区域的。后两个数字是对话框的宽度和高度。

    这些坐标和大小的单位都不是图素。它们实际上依据一种特殊的坐标系统,该系统只用于对话框模板。数字依据对话框使用字体的大小而定(这里是8点的MS Sans Serif字体):x坐标和宽度的单位是字符平均宽度的1/4;y坐标和高度的单位是字符高度的1/8。因此,对这个对话框来说,对话框左上角距离主窗口显示区域的左边是5个字符,距离顶边是2-1/2个字符。对话框本身宽40个字符,高10个字符。

    这样的坐标系使得程序写作者可以使用坐标和大小来大致勾勒对话框的尺寸和外观,而不管视讯显示器的分辨率是多少。由于系统字体字符的高度大致为其宽度的两倍,所以,x轴和y轴的量度差不多相等。

    模板中的STYLE叙述类似于CreateWindow呼叫中的style字段。对于模态对话框,通常使用WS_POPUP和DS_MODALFRAME,我们将在稍后介绍其它的选项。

    在BEGIN和END叙述(或者是左右大括号,手工设计对话框模板时,您可能会使用)之间,定义出现在对话框中的子窗口控件。这个对话框使用了三种型态的子窗口控件,它们分别是DEFPUSHBUTTON(内定按键)、ICON(图标)和CTEXT(文字居中)。这些叙述的格式为:

    control-type "text" id, xPos, yPos, xWidth, yHeight, iStyle

    其中,后面的iStyle项是可选的,它使用Windows表头文件中定义的标识符来指定其它窗口样式。

    DEFPUSHBUTTON、ICON和CTEXT等标识符只可以在对话框中使用,它们是某种特定窗口类别和窗口样式的缩写。例如,CTEXT指示这个子窗口控件类别是「静态的」,其样式为:

    WS_CHILD | SS_CENTER | WS_VISIBLE | WS_GROUP

    虽然前面没有出现过WS_GROUP标识符,但是在第九章的COLORS1程序中已经出现过WS_CHILD、SS_CENTER和WS_VISIBLE窗口样式,我们在建立静态子窗口文字控件时已经用到了它们。

    对于图标,文字字段是程序的图标资源名称,它也在ABOUT1资源描述档中定义。对于按键,文字字段是出现在按键里的文字,这个文字相同于在程序中建立子窗口控件时呼叫CreateWindow所指定的第二个参数。

    id字段是子窗口在向其父窗口发送消息(通常为WM_COMMMAND消息)时用来标示它自身的值。这些子窗口控件的父窗口就是对话框本身,它将这些消息发送给Windows的一个窗口消息处理程序。不过,这个窗口消息处理程序也将这些消息发送给您在程序中给出的对话框程序。ID值相同于我们在第九章建立子窗口时,在CreateWindow函数中使用的子窗口ID。由于文字和图标控件不向父窗口回送消息,所以这些值被设定为IDC_STATIC,它在RESOURCE.H中定义为-1。按键的ID值为IDOK,它在WINUSER.H中定义为1。

    接下来的四个数字设定子窗口的位置(相对于对话框显示区域的左上角)和大小,它们是以系统字体平均宽度的1/4和平均高度的1/8为单位来表示的。对于ICON叙述,宽度和高度将被忽略。

    对话框模板中的DEFPUSHBUTTON叙述,除了包含DEFPUSHBUTTON关键词所隐含的窗口样式,还包含窗口样式WS_GROUP。稍后讨论该程序的第二个版本ABOUT2时,还会详细说明WS_GROUP(以及相关的WS_TABSTOP样式)。

    展开全文
    weixin_39897267 2021-05-20 19:34:29
  • 称为 “对话框管理器” 和标准的Windows窗口消息处理略有不同。稍后能看到具体区别 许多消息不仅被对话框窗口过程处理,还会传递给你自己的程序中的某些函数。 称为对话框过程 对话框过程一般处理初始化自创控件...

    第十一章  对话框


    基于模板的对话框,包含了弹出窗口,和子窗口控件,而且有一个窗口过程来处理对话框消息。 包括键盘和鼠标的输入。

    称为 “对话框管理器”  和标准的Windows窗口消息处理略有不同。稍后能看到具体区别


    许多消息不仅被对话框窗口过程处理,还会传递给你自己的程序中的某些函数。  称为对话框过程

    对话框过程一般处理初始化自创控件以及子窗口传来的消息。不处理WM_PAINT 也不直接处理键盘和鼠标的输入


    子窗口控件由windows对话框管理器来负责。对话框管理器来负责处理在多个控件中转义输入焦点的相关逻辑


    11.1  模态对话框

    用户不能在该对话框和该程序的其他对话框之间切换。但是可以切换到其他的程序。有些系统模态不允许切换程序。必须结束系统模态才可以进行其他操作。

    11.1.1 创建一个about对话框


    About.cpp

    #include <windows.h>  
    #include "resource.h"   
    
    LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); //window procedure.   
    BOOL	CALLBACK AboutDlgProc(HWND, UINT, WPARAM, LPARAM);
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    	PSTR szCmdLine, int iCmdShow)
    {
    	static      TCHAR szAppName[] = TEXT("About1");    
    	HACCEL      hAccel;
    	HWND        hwnd;
    	MSG         msg;
    	WNDCLASS    wndClass;       //The window Class        
    
    	wndClass.style = CS_HREDRAW | CS_VREDRAW;
    	wndClass.lpfnWndProc = WndProc;// assign the window procedure to windows class.        
    	wndClass.cbClsExtra = 0;
    	wndClass.cbWndExtra = 0;
    	wndClass.hInstance = hInstance;
    	wndClass.hIcon = LoadIcon(hInstance, szAppName);// LoadIcon(NULL, IDI_APPLICATION);  
    	wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
    	wndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);    
    	wndClass.lpszMenuName = szAppName;
    	wndClass.lpszClassName = szAppName;
    
    	//Register the Window Class to the Windows System.         
    	if (!RegisterClass(&wndClass))
    	{
    		MessageBox(NULL, TEXT("This program require Windows NT!"),
    			szAppName, MB_ICONERROR);
    		return 0;
    	}
    
    	//This function will generate an WM_CREATE message.        
    	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); //This function will generate a WM_PAINT message.        
    
    	/* The message loop for this program.
    	if received the WM_QUIT message, the function will return 0.*/
    	while (GetMessage(&msg, NULL, 0, 0))
    	{
    		TranslateMessage(&msg);
    		DispatchMessage(&msg);	
    	}
    	return msg.wParam;
    
    }
    
    //define the Window Procedure WndProc        
    LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
    	static HINSTANCE hInstance;
    
    	switch (message) //get the 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;
    }

    About1.rc

    // Microsoft Visual C++ generated resource script.
    //
    #include "resource.h"
    
    #define APSTUDIO_READONLY_SYMBOLS
    /
    //
    // Generated from the TEXTINCLUDE 2 resource.
    //
    #include "afxres.h"
    
    /
    #undef APSTUDIO_READONLY_SYMBOLS
    
    /
    // English (United States) resources
    
    #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
    LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
    #pragma code_page(1252)
    
    #ifdef APSTUDIO_INVOKED
    /
    //
    // TEXTINCLUDE
    //
    
    1 TEXTINCLUDE 
    BEGIN
        "resource.h\0"
    END
    
    2 TEXTINCLUDE 
    BEGIN
        "#include ""afxres.h""\r\n"
        "\0"
    END
    
    3 TEXTINCLUDE 
    BEGIN
        "\r\n"
        "\0"
    END
    
    #endif    // APSTUDIO_INVOKED
    
    
    /
    //
    // Dialog
    //
    
    ABOUTBOX DIALOGEX 32, 32, 180, 102
    STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP
    FONT 8, "MS Sans Serif", 0, 0, 0x0
    BEGIN
        DEFPUSHBUTTON   "OK",IDOK,66,81,50,14
        ICON            "ABOUT1",IDC_STATIC,7,7,20,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
    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                    "About1.ico"
    
    
    /
    //
    // DESIGNINFO
    //
    
    #ifdef APSTUDIO_INVOKED
    GUIDELINES DESIGNINFO
    BEGIN
        "ABOUTBOX", DIALOG
        BEGIN
            LEFTMARGIN, 7
            RIGHTMARGIN, 173
            TOPMARGIN, 7
            BOTTOMMARGIN, 95
        END
    END
    #endif    // APSTUDIO_INVOKED
    
    
    /
    //
    // AFX_DIALOG_LAYOUT
    //
    
    ABOUTBOX AFX_DIALOG_LAYOUT
    BEGIN
        0
    END
    
    #endif    // English (United States) resources
    /
    
    
    
    #ifndef APSTUDIO_INVOKED
    /
    //
    // Generated from the TEXTINCLUDE 3 resource.
    //
    
    
    /
    #endif    // not APSTUDIO_INVOKED
    
    
    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
    


    11.1.2 对话框及其模板


    DEFPUSHBUTTON, ICON 和CTEXT只被用于对话框。他们是一些特殊类和窗口样式的缩写。  CTEXT指定窗口控件的类型是静态的,同时其样式是

    WS_CHILD | SS_CENTER | WS_VISIBLE | WS_GROUP

    文本设定等价于Caption参数

    当子窗口像父窗口发送WM_COMMAND时,id字段是子窗口用来表示自己的标识符。 子窗口控件的父窗口是对话框本身。它会把这些消息发送给某个windows的窗口过程。

    这里的ID和CreateWindow中 (HMENU)id  参数相同。 由于文本和图标并不需要向父窗口发送消息。所以ID被设定为ID_STATIC 按钮的ID为IDOK   在winuser.h中定义为1

    接下来设定子窗口控件的位置和大小。   单位是 字符评均宽度的1/4 和  平均高度的1/8


    11.1.3 对话框过程

    发送给对话框的消息是用户程序中的对话框过程来处理的。和窗口过程很像,但是其实是不一样的。  对话框的窗口过程属于windows。 而对话框过程是独立的。

    对话框的窗口过程会调用这个对话框的过程来处理许多消息。

    对话框过程

    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;
    }
    对话框过程  和 对话框的窗口过程的区别

    1)窗口过程返回值是  LRESULT  而对话框过程的返回值是BOOL

    2)窗口过程不处理一条消息时,会调用DefWindowProc。  对话框过程处理一条消息会返回TRUE,不处理则返回FALSE

    3)  对话框过程不需要处理WM_PAINT和WM_DESTROY消息。他也不会收到WM_CREATE消息。 然后他会在一条处理WM_INITDIALOG消息时进行初始化,这是对话框过程接收到的第一条消息。当其返回TRUE时,windows会把输入焦点放在第对话框第一个含有WS_TABSTOP样式的窗口子空间。本例中是按钮。

    另外在WM_INITDIALOG也可以调用SetFocus来设置焦点,并返回FALSE

    除此之外,对话框过程只处理WM_COMMAND,当鼠标单击按钮或者当焦点在按钮控件时按下空格键,按钮控件会像父窗口发送WM_COMMAND消息。wParam低位时控件ID

    其他任何消息,对话框过程会返回FALSE来通知对话框的窗口过程该消息未处理。

    模态对话框的消息并不通过程序的消息循环。


    11.1.4 激活对话框

    Dialog(hInstance, TEXT("AboutBox"), hwnd, AboutDlgProc);

    实例句柄, 对话框名称在资源该脚本中定义, 父窗口句柄   和对话框过程的地址。

    也可以使用MAKEINTRESOURCE宏来将其转换为字符。


    当回车或空格被按下,windows会向对话框发送WM_COMMAND消息。 wParam的低位时默认按钮ID。 也可以按ESC来结束对话框。

    直到对话框结束以后,用来显示对话框的DialogBox才将控制返回给WndProc。 DialogBox的返回值等于EndDialog函数的第二个参数。并将控制权返回给Windows.


    对话框在显示使,WndProc依旧可以处理消息。比如SendMessage(GetParent(Dlg), ...);


    11.1.5 主题变换

    对话框资源脚本

    对话框常用样式

    STYLE WS_POPUP | DS_MODALFRAME

    带标题栏 WS_CAPTION


    CAPTION "Dialog Box Caption"  标题栏文本

    或者当对话框过程处理WM_INITDIALOG消息时,你可以使用

    SetWindowText(hDlg, TEXT("Dialog Box Caption"));


    使用WS_CAPTION样式 还运行使用WS_SYSMENU 增加系统菜单框。这一样式允许用户通过系统菜单来选择Move或Close


    WS_THICKFRAME   (Resizing) 允许用户改变对话框的大小。甚至还可以给对话框添加菜单

    MENU 菜单名


    FONT 语句用来设置对话框文本为系统字体以外的字体。 早起VS创建对话框默认的字体是 8pt的 MS Scans Serif。  现在VS2015使用的是  8pt的 MS Shell Dlg 字体


    可以指定某个窗口过程来处理对话框消息。

    CLASS “类名”


    调用DialogBox函数, windows会从对话框资源模板中获取信息来CreateWindow ,windows从DialogBox函数的参数获取hInstance 和 父窗口hwnd

    windows所需的唯一其他信息是一个窗口类,假设对话框模板没有指定。  window设为对话框注册一个特殊的窗口类。窗口类用于对话框过程的访问地址。

    因此弹出式窗口可以向程序传递其收到的消息。 也可以自己使用CreateWindow并注册窗口类来创建自己的对话框,DialogBox函数只是一种简便的方法。


    也可以动态创建对话框,不需要写资源脚本。DialogBoxIndirect函数   使用数据结构来定义对话框模板。

    常用控件类型的相应窗口类和窗口样式



    除了表中的样式,每个控件默认还有以下样式

    WS_CHILD | WS_VISIBLE

      EDITTEXT, SCROLLBAR, LISTBOX 和COMBOBOX以下格式

    控件类型 id, xPos, yPos, xWidth, yHeight, iStyle

    除此之外所有控件的定义都有以下格式

    控件类型 "文本" , id, xpos, ypos, xwidth, yHeight, iStyle

    对话框模板中的单位是平均字符宽度的1/4 和  高度的 1/8 。


    例如复选框

    CHECKBOX "TEXT", id, xPos, yPos, xWidth, yHeight, BS_LEFTTEXT      checkbox上的说明文本左对齐


    EDITTEXT id, xPos, yPos, xWidth, yHeight, NOT WS_BORDER        不带边框的EDITTEXT


    资源编辑器还承认这样的一般化语句

    CONTROL  "文本" , id, "类", IStyle, xPos, yPos, xWidth, yHeight

    创建任何类型的子窗口控件

    比如 

    PUSHBUTTON "OK", IDOK, 10, 20, 32, 14

    可以使用下面语句

    CONTROL "OK" , IDOK, "button", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | WS_TABSTOP,

            10, 20, 32, 14

    可使用VS中自定义控件选项来生成以上语句


    在模板资源中,则无需WS_CHILD | WS_VISIBLE 样式

    上面的CONTROL语句转换成如下调用

    hCtrl1 = CreateWindow( TEXT("button"), TEXT("OK"),

                      WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_PUSHBUTTON,

                      10 * cxChar / 4,     20 * cyChar / 8,

                      32 * cxChar / 4,     14 * cyChar / 8,

                      hDlg, IDOK, hInstance, NULL);


    11.1.6 更复杂的对话框

    about2.cpp

    #include <windows.h>  
    #include "resource.h"   
    
    LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); //window procedure.   
    BOOL	CALLBACK AboutDlgProc(HWND, UINT, WPARAM, LPARAM);
    
    int iCurrentColor = IDC_BLACK,
    iCurrentFigure = IDC_RECT;
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    	PSTR szCmdLine, int iCmdShow)
    {
    	static      TCHAR szAppName[] = TEXT("About2");
    	HWND        hwnd;
    	MSG         msg;
    	WNDCLASS    wndClass;       //The window Class        
    
    	wndClass.style = CS_HREDRAW | CS_VREDRAW;
    	wndClass.lpfnWndProc = WndProc;// assign the window procedure to windows class.        
    	wndClass.cbClsExtra = 0;
    	wndClass.cbWndExtra = 0;
    	wndClass.hInstance = hInstance;
    	wndClass.hIcon = LoadIcon(hInstance, szAppName);// LoadIcon(NULL, IDI_APPLICATION);  
    	wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
    	wndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    	wndClass.lpszMenuName = szAppName;
    	wndClass.lpszClassName = szAppName;
    
    	//Register the Window Class to the Windows System.         
    	if (!RegisterClass(&wndClass))
    	{
    		MessageBox(NULL, TEXT("This program require Windows NT!"),
    			szAppName, MB_ICONERROR);
    		return 0;
    	}
    
    	//This function will generate an WM_CREATE message.        
    	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); //This function will generate a WM_PAINT message.        
    
    						/* The message loop for this program.
    						if received the WM_QUIT message, the function will return 0.*/
    	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), RGB(0,   0, 255),
    		RGB(0, 255, 0), RGB(0, 255, 255),
    		RGB(255, 0,   0), RGB(255,   0, 255),
    		RGB(255, 255, 0), RGB(255, 255, 255) };
    	HBRUSH	hBrush;
    	HDC		hdc;
    	RECT	rect;
    
    	hdc = GetDC(hwnd);
    	GetClientRect(hwnd, &rect);
    	hBrush = CreateSolidBrush(crColor[iColor - IDC_BLACK]);
    	hBrush = (HBRUSH)SelectObject(hdc, hBrush);
    
    	if (iFigure == IDC_RECT)
    		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(hCtrl);
    	PaintWindow(hCtrl, iColor, iFigure);
    }
    
    //define the Window Procedure WndProc        
    LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
    	static HINSTANCE hInstance;
    	PAINTSTRUCT		 ps;
    
    	switch (message) //get the message        
    	{
    	case WM_CREATE:
    		hInstance = ((LPCREATESTRUCT)lParam)->hInstance;
    		return 0;
    
    	case WM_COMMAND:
    		switch (LOWORD(wParam))
    		{
    		case IDM_APP_ABOUT:
    			if (DialogBox(hInstance, TEXT("AboutBox"), hwnd, AboutDlgProc))
    				InvalidateRect(hwnd, NULL, TRUE);
    			break;
    		}
    		break;
    
    	case WM_PAINT:
    		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 HWND	hCtrlBlock;
    	static int	iColor, iFigure;
    	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);
    			return TRUE;
    
    		case IDCANCEL:
    			EndDialog(hDlg, FALSE);
    			return TRUE;
    
    		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, LOWORD(wParam)); //The LOWORD(wParam) is the current ID of the command.
    			PaintTheBlock(hCtrlBlock, iColor, iFigure);
    			return TRUE;
    
    		case IDC_RECT:
    		case IDC_ELLIPSE:
    			iFigure = LOWORD(wParam);
    			CheckRadioButton(hDlg, IDC_RECT, IDC_ELLIPSE, LOWORD(wParam));
    			PaintTheBlock(hCtrlBlock, iColor, iFigure);
    			return TRUE;
    		}
    		break;
    
    	case WM_PAINT:
    		PaintTheBlock(hCtrlBlock, iColor, iFigure);
    		break;
    	}
    
    	return FALSE;
    }

    About2.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, 200, 234
    STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION
    FONT 8, "MS Sans Serif"
    BEGIN
        ICON            "ABOUT2",IDC_STATIC,7,7,20,20
        CTEXT           "About2",IDC_STATIC,57,12,86,8
        CTEXT           "About Box Demo Program",IDC_STATIC,7,40,186,8
        LTEXT           "",IDC_PAINT,114,67,72,72
        GROUPBOX        "&Color",IDC_STATIC,7,60,84,143
        RADIOBUTTON     "&Black",IDC_BLACK,16,76,64,8,WS_GROUP | WS_TABSTOP
        RADIOBUTTON     "B&lue",IDC_BLUE,16,92,64,8
        RADIOBUTTON     "&Green",IDC_GREEN,16,108,64,8
        RADIOBUTTON     "Cya&n",IDC_CYAN,16,124,64,8
        RADIOBUTTON     "&Red",IDC_RED,16,140,64,8
        RADIOBUTTON     "&Magenta",IDC_MAGENTA,16,156,64,8
        RADIOBUTTON     "&Yellow",IDC_YELLOW,16,172,64,8
        RADIOBUTTON     "&White",IDC_WHITE,16,188,64,8
        GROUPBOX        "&Figure",IDC_STATIC,109,156,84,46,WS_GROUP
        RADIOBUTTON     "Rec&tangle",IDC_RECT,116,172,65,8,WS_GROUP | WS_TABSTOP
        RADIOBUTTON     "&Ellipse",IDC_ELLIPSE,116,188,64,8
        DEFPUSHBUTTON   "OK",IDOK,35,212,50,14,WS_GROUP
        PUSHBUTTON      "Cancel",IDCANCEL,113,212,50,14,WS_GROUP
    END
    
    
    /
    //
    // Icon
    //
    
    // Icon with lowest ID value placed first to ensure application icon
    // remains consistent on all systems.
    ABOUT2                  ICON    DISCARDABLE     "About2.ico"
    
    /
    //
    // Menu
    //
    
    ABOUT2 MENU DISCARDABLE 
    BEGIN
        POPUP "&Help"
        BEGIN
            MENUITEM "&About",                      IDM_APP_ABOUT
        END
    END
    
    
    /
    //
    // DESIGNINFO
    //
    
    #ifdef APSTUDIO_INVOKED
    GUIDELINES DESIGNINFO DISCARDABLE 
    BEGIN
        "ABOUTBOX", DIALOG
        BEGIN
            LEFTMARGIN, 7
            RIGHTMARGIN, 193
            TOPMARGIN, 7
            BOTTOMMARGIN, 227
        END
    END
    #endif    // APSTUDIO_INVOKED
    
    #endif    // English (U.S.) resources
    /
    
    
    
    #ifndef APSTUDIO_INVOKED
    /
    //
    // Generated from the TEXTINCLUDE 3 resource.
    //
    
    
    /
    #endif    // not APSTUDIO_INVOKED
    
    

    Resource.h

    //{{NO_DEPENDENCIES}}
    // Microsoft Developer Studio generated include file.
    // Used by About2.rc
    //
    #define IDC_BLACK                       1000
    #define IDC_BLUE                        1001
    #define IDC_GREEN                       1002
    #define IDC_CYAN                        1003
    #define IDC_RED                         1004
    #define IDC_MAGENTA                     1005
    #define IDC_YELLOW                      1006
    #define IDC_WHITE                       1007
    #define IDC_RECT                        1008
    #define IDC_ELLIPSE                     1009
    #define IDC_PAINT                       1010
    #define IDM_APP_ABOUT                   40001
    
    // Next default values for new objects
    // 
    #ifdef APSTUDIO_INVOKED
    #ifndef APSTUDIO_READONLY_SYMBOLS
    #define _APS_NEXT_RESOURCE_VALUE        105
    #define _APS_NEXT_COMMAND_VALUE         40002
    #define _APS_NEXT_CONTROL_VALUE         1011
    #define _APS_NEXT_SYMED_VALUE           101
    #endif
    #endif
    

    运行结果



    11.1.7 对话框控件的应用

    当一个单选按钮被鼠标按下或有焦点时按下空格,  子窗口像父窗口发送WM_COMMAND消息 LOWPRD(wParam) 是控件ID,高位是通知码

     lParam是控件的窗口句柄

    对于单选按钮通知码是 BN_CLICKED ,他等于0.  然后windows的对话框窗口过程把该消息发送给About2.c中的对话框过程。

    当对话框过程收到单选按钮的WM_COMMAND消息以后表明他被选中,斌给取消选中同组所有其他按钮


    CP9中  取消或选中单选需要发送一条BM_SETCHECK消息

    SendMessage(hwndCtrl, BM_SETCHECK, 1, 0);  选中

    SendMessage(hwndCtrl, BM_SETCHECK, 0, 0); 取消选中


    hwndCtrl = GetDlgItem(hDlg, id);

    id = GetWindowLong(hwndCtrl, GWL_ID);


    可以使用下面代码来选择和取消单选框。

    		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);
    			for (i = IDC_BLACK; i <= IDC_WHITE; i++)
    			{
    				SendMessage(GetDlgItem(hDlg, i),
    					BM_SETCHECK, i == LOWORD(wParam), 0);
    			}

    另一种方法是 

    SendDlgItemMessage(hDlg, id, iMsg, wParam, lParam);

    等价于  SendMessage(GetDlgItem(hDlg, id), BM_SETCHECK, wParam, lParam);

    for (i = IDC_BLACK; i <= IDC_WHITE; i++)

    SendDlgMessage(hDlg, i,  BM_SETCHECK, i == LOWORD (wParam), lParam);


    或者使用

    CheckRadioButton(hDlg, idFirst, idLast, idCheck);


    对复选框也可以这样使用

    CheckDlgButton(hDlg, idCheckbox, iCheck);   1选择   0 取消

    iCheck = IsDlgButtonChecked(hDlg, idCheckbox);

    或者  SendMessage(hwndCtrl, BM_GETCHECK, 0, 0);


    在WM_COMMAND消息中切换状态

    CheckDlgButton(hDlg, idCheckbox, !IsDlgButtonChecked(hDlg, idCheckbox));


    如果是一个BS_AUTOCHECKBOX控件,则程序不需要处理WM_COMMAND消息  ,在对话框终止前使用IsDlgButtonChecked来获得按钮的选取状态。


    11.1.8  OK和Cancel按钮

    当用户按回车时,对话框窗口过程会产生一个WM_COMMAND消息,该消息的wParam参数的LOWORD会被设为默认的按钮的ID值,除非另一个按键有输入焦点。如果对话框没有按键是默认按钮。windows会像对话框过程发送一条LOWORD(wParam) 为IDOK的WM_COMMAND消息。   如果用户按下ESC或者Ctrl-Break, Windows会发送一条wParam参数为  LOWORD等于IDCANCEL的WM_COMMAND消息。

    EndDialog 第二个参数成为DialogBox函数的返回值


    11.1.9  避免全局变量


    定义一个数据结构和About对话框关联

    typedef struct

    {

        int iColor;

        int iFigure;

    }

    ABOUTBOX_DATA;


    在WndProc中   定义  static ABOUTBOX_DATA ad = { IDC_BLACK,  IDC_RECT}; 

    然后将iCurrentColor和iCurrentFigure替换为 ad.iColor  和  ad.iFigure

    当调用对话框使用DialogBoxParam


    if(DialogBoxParam(hInstance, TEXT("AboutBox"),

        hwnd, AboutDlgProc, &ad))


    最后一个参数将作为WM_INITDIALOG消息的lParam参数传递给对话框过程。

    对话框过程有两个基于ABOUTBOX_DATA结构的静态变量

    static ABOUTBOX_DATA ad, * pad;


    pad = (ABOUTBOX_DATA *) lParam;

    ad = * pad;

    在   Case IDOK

    * pad = ad;

    EndDialog(hDlg, TRUE);

    return TRUE;


    修改成非全局变量的版本

    #include <windows.h>  
    #include "resource.h"   
    
    LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); //window procedure.   
    BOOL	CALLBACK AboutDlgProc(HWND, UINT, WPARAM, LPARAM);
    
    
    typedef struct
    {
    	int iColor;
    	int iFigure;
    }
    ABOUTBOX_DATA;
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    	PSTR szCmdLine, int iCmdShow)
    {
    	static      TCHAR szAppName[] = TEXT("About2");
    	HWND        hwnd;
    	MSG         msg;
    	WNDCLASS    wndClass;       //The window Class        
    
    	wndClass.style = CS_HREDRAW | CS_VREDRAW;
    	wndClass.lpfnWndProc = WndProc;// assign the window procedure to windows class.        
    	wndClass.cbClsExtra = 0;
    	wndClass.cbWndExtra = 0;
    	wndClass.hInstance = hInstance;
    	wndClass.hIcon = LoadIcon(hInstance, szAppName);// LoadIcon(NULL, IDI_APPLICATION);  
    	wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
    	wndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    	wndClass.lpszMenuName = szAppName;
    	wndClass.lpszClassName = szAppName;
    
    	//Register the Window Class to the Windows System.         
    	if (!RegisterClass(&wndClass))
    	{
    		MessageBox(NULL, TEXT("This program require Windows NT!"),
    			szAppName, MB_ICONERROR);
    		return 0;
    	}
    
    	//This function will generate an WM_CREATE message.        
    	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); //This function will generate a WM_PAINT message.        
    
    						/* The message loop for this program.
    						if received the WM_QUIT message, the function will return 0.*/
    	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), RGB(0,   0, 255),
    		RGB(0, 255, 0), RGB(0, 255, 255),
    		RGB(255, 0,   0), RGB(255,   0, 255),
    		RGB(255, 255, 0), RGB(255, 255, 255) };
    	HBRUSH	hBrush;
    	HDC		hdc;
    	RECT	rect;
    
    	hdc = GetDC(hwnd);
    	GetClientRect(hwnd, &rect);
    	hBrush = CreateSolidBrush(crColor[iColor - IDC_BLACK]);
    	hBrush = (HBRUSH)SelectObject(hdc, hBrush);
    
    	if (iFigure == IDC_RECT)
    		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(hCtrl);
    	PaintWindow(hCtrl, iColor, iFigure);
    }
    
    //define the Window Procedure WndProc        
    LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
    	static HINSTANCE hInstance;
    	static ABOUTBOX_DATA ad = { IDC_BLACK,  IDC_RECT };
    	PAINTSTRUCT		 ps;
    
    	switch (message) //get the message        
    	{
    	case WM_CREATE:
    		hInstance = ((LPCREATESTRUCT)lParam)->hInstance;
    		return 0;
    
    	case WM_COMMAND:
    		switch (LOWORD(wParam))
    		{
    		case IDM_APP_ABOUT:
    			if (DialogBoxParam(hInstance, TEXT("AboutBox"), hwnd, AboutDlgProc, (LPARAM)(&ad)))
    				InvalidateRect(hwnd, NULL, TRUE);
    			break;
    		}
    		break;
    
    	case WM_PAINT:
    		BeginPaint(hwnd, &ps);
    		EndPaint(hwnd, &ps);
    
    		PaintWindow(hwnd, ad.iColor, ad.iFigure);
    		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 HWND	hCtrlBlock;
    	static ABOUTBOX_DATA ad, *pad;
    	switch (message)
    	{
    	case WM_INITDIALOG:
    		pad = (ABOUTBOX_DATA *)lParam;
    		ad = *pad;
    
    		CheckRadioButton(hDlg, IDC_BLACK, IDC_WHITE, ad.iColor);
    		CheckRadioButton(hDlg, IDC_RECT, IDC_ELLIPSE, ad.iFigure);
    
    		hCtrlBlock = GetDlgItem(hDlg, IDC_PAINT);
    
    		SetFocus(GetDlgItem(hDlg, ad.iColor));
    		return FALSE;
    
    	case WM_COMMAND:
    		switch (LOWORD(wParam))
    		{
    		case IDOK:
    			*pad = ad;
    			EndDialog(hDlg, TRUE);
    			return TRUE;
    
    		case IDCANCEL:
    			EndDialog(hDlg, FALSE);
    			return TRUE;
    
    		case IDC_BLACK:
    		case IDC_RED:
    		case IDC_GREEN:
    		case IDC_YELLOW:
    		case IDC_BLUE:
    		case IDC_MAGENTA:
    		case IDC_CYAN:
    		case IDC_WHITE:
    			ad.iColor = LOWORD(wParam);
    			CheckRadioButton(hDlg, IDC_BLACK, IDC_WHITE, LOWORD(wParam)); //The LOWORD(wParam) is the current ID of the command.
    			PaintTheBlock(hCtrlBlock, ad.iColor, ad.iFigure);
    			return TRUE;
    
    		case IDC_RECT:
    		case IDC_ELLIPSE:
    			ad.iFigure = LOWORD(wParam);
    			CheckRadioButton(hDlg, IDC_RECT, IDC_ELLIPSE, LOWORD(wParam));
    			PaintTheBlock(hCtrlBlock, ad.iColor, ad.iFigure);
    			return TRUE;
    		}
    		break;
    
    	case WM_PAINT:
    		PaintTheBlock(hCtrlBlock, ad.iColor, ad.iFigure);
    		break;
    	}
    
    	return FALSE;
    }


    11.1.10 TAB停靠和选项组

    需要TAB访问的控件  加入 WS_TABSTOP

    不含TABSTOP样式的控件不应该获取输入焦点。 除非在WM_INITDIALOG 中强制设置焦点并返回FALSE, 否则windows会把输入焦点设置为对话框中第一个含有WS_TABSTOP格式的控件


    当焦点在单选按钮上时,添加WS_GROUP样式使得可以使用方向键来切换选择同一个GROUP中的其他单选。再下一个WS_GROUP之前的控件为一组


    &使得其后面的字母带下划线,同时增加了一个键盘接口。用户可以通过按下带有下划线的字母来将输入焦点移动到任何单选按钮。



    windows提供下列函数来查找下一个或前一个tab停靠位或者选项组

    hwndCtrl = GetNextDlgTabItem(hDlg, hwndCtrl, bPrevious);

    hwndCtrl= GetNextDlgGroupItem(hDlg, hwndCtrl, bPrevious);


    bPrevious是TRUE, 函数返回掐你个TAB停靠位或选项组;  如果是FALSE 返回下一个


    11.1.11 在对话框上绘图

    在对话框过程的WM_PAINT消息 或者切换图形时候调用

    PaintTheBlock(hCtrlBlock, iColor, iFigure);

    在WM_INITDIALOG消息时 

    hCtrlBlock = GetDlgItem(hDlg, IDC_PAINT);


    MapDialogRect 函数把对话框中的以字符为单位的坐标转换为客户区中以像素为单位的坐标。

    实际上是在子窗口控件上绘图。


    11.1.12 关于对话框的其他函数

    MoveWindow

    EnableWindow(hwndCtrl, bEnable);

    不要禁用含有输入焦点的控件


    11.1.13 定义程序自己的控件

    About3.cpp

    #include <windows.h>  
    #include "resource.h"   
    
    LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); //window procedure.   
    BOOL	CALLBACK AboutDlgProc(HWND, UINT, WPARAM, LPARAM);
    LRESULT CALLBACK EllipPushWndProc(HWND, UINT, WPARAM, LPARAM);
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    	PSTR szCmdLine, int iCmdShow)
    {
    	static      TCHAR szAppName[] = TEXT("About3");
    	HWND        hwnd;
    	MSG         msg;
    	WNDCLASS    wndClass;       //The window Class        
    
    	wndClass.style = CS_HREDRAW | CS_VREDRAW;
    	wndClass.lpfnWndProc = WndProc;// assign the window procedure to windows class.        
    	wndClass.cbClsExtra = 0;
    	wndClass.cbWndExtra = 0;
    	wndClass.hInstance = hInstance;
    	wndClass.hIcon = LoadIcon(hInstance, szAppName);// LoadIcon(NULL, IDI_APPLICATION);  
    	wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
    	wndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    	wndClass.lpszMenuName = szAppName;
    	wndClass.lpszClassName = szAppName;
    
    	//Register the Window Class to the Windows System.         
    	if (!RegisterClass(&wndClass))
    	{
    		MessageBox(NULL, TEXT("This program require Windows NT!"),
    			szAppName, MB_ICONERROR);
    		return 0;
    	}
    
    
    	wndClass.style = CS_HREDRAW | CS_VREDRAW;
    	wndClass.lpfnWndProc = EllipPushWndProc;// assign the window procedure to windows class.        
    	wndClass.cbClsExtra = 0;
    	wndClass.cbWndExtra = 0;
    	wndClass.hInstance = hInstance;
    	wndClass.hIcon = NULL;// LoadIcon(NULL, IDI_APPLICATION);  
    	wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
    	wndClass.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
    	wndClass.lpszMenuName = NULL;
    	wndClass.lpszClassName = TEXT("EllipPush");
    
    	RegisterClass(&wndClass);
    
    	//This function will generate an WM_CREATE message.        
    	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); //This function will generate a WM_PAINT message.        
    
    						/* The message loop for this program.
    						if received the WM_QUIT message, the function will return 0.*/
    	while (GetMessage(&msg, NULL, 0, 0))
    	{
    		TranslateMessage(&msg);
    		DispatchMessage(&msg);
    	}
    	return msg.wParam;
    
    }
    
    
    //define the Window Procedure WndProc        
    LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
    	static HINSTANCE hInstance;
    
    	switch (message) //get the 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);
    			return 0;
    		}
    		break;
    
    	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, TRUE);
    			return TRUE;
    		}
    		break;
    	}
    
    	return FALSE;
    }
    
    LRESULT CALLBACK EllipPushWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
    	TCHAR		szText[40];
    	HBRUSH		hBrush;
    	HDC			hdc;
    	PAINTSTRUCT	ps;
    	RECT		rect;
    
    	switch (message)
    	{
    	case WM_PAINT:
    		GetClientRect(hwnd, &rect);
    		GetWindowText(hwnd, szText, sizeof(szText));
    
    		hdc = BeginPaint(hwnd, &ps);
    
    		hBrush = CreateSolidBrush(GetSysColor(COLOR_WINDOW));
    		hBrush = (HBRUSH)SelectObject(hdc, hBrush);
    		SetBkColor(hdc, GetSysColor(COLOR_WINDOW));
    		SetTextColor(hdc, GetSysColor(COLOR_WINDOWTEXT));
    
    		Ellipse(hdc, rect.left, rect.top, rect.right, rect.bottom);
    		DrawText(hdc, szText, -1, &rect,
    			DT_SINGLELINE | DT_CENTER | DT_VCENTER);
    
    		DeleteObject(SelectObject(hdc, 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);
    }


    about3.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, 100
    STYLE DS_MODALFRAME | WS_POPUP
    FONT 8, "MS Sans Serif"
    BEGIN
        CONTROL         "OK",IDOK,"EllipPush",WS_GROUP | WS_TABSTOP,73,79,32,14
        ICON            "ABOUT3",IDC_STATIC,7,7,20,20
        CTEXT           "About3",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
    //
    
    ABOUT3 MENU DISCARDABLE 
    BEGIN
        POPUP "&Help"
        BEGIN
            MENUITEM "&About About3...",            IDM_APP_ABOUT
        END
    END
    
    
    /
    //
    // DESIGNINFO
    //
    
    #ifdef APSTUDIO_INVOKED
    GUIDELINES DESIGNINFO DISCARDABLE 
    BEGIN
        "ABOUTBOX", DIALOG
        BEGIN
            LEFTMARGIN, 7
            RIGHTMARGIN, 173
            TOPMARGIN, 7
            BOTTOMMARGIN, 93
        END
    END
    #endif    // APSTUDIO_INVOKED
    
    
    /
    //
    // Icon
    //
    
    // Icon with lowest ID value placed first to ensure application icon
    // remains consistent on all systems.
    ABOUT3                  ICON    DISCARDABLE     "icon1.ico"
    #endif    // English (U.S.) resources
    /
    
    
    
    #ifndef APSTUDIO_INVOKED
    /
    //
    // Generated from the TEXTINCLUDE 3 resource.
    //
    
    
    /
    #endif    // not APSTUDIO_INVOKED
    
    

    resource.h

    //{{NO_DEPENDENCIES}}
    // Microsoft Developer Studio generated include file.
    // Used by About3.rc
    //
    #define IDM_APP_ABOUT                   40001
    #define IDC_STATIC                      -1
    
    // Next default values for new objects
    // 
    #ifdef APSTUDIO_INVOKED
    #ifndef APSTUDIO_READONLY_SYMBOLS
    #define _APS_NEXT_RESOURCE_VALUE        105
    #define _APS_NEXT_COMMAND_VALUE         40002
    #define _APS_NEXT_CONTROL_VALUE         1001
    #define _APS_NEXT_SYMED_VALUE           101
    #endif
    #endif
    


    运行结果


    11.2 非模态对话框

    hDlgModeless = CreateDialog(hInstance, szTemplate, hwndParent, DialogProc); //创建非模态对话框


    11.2.1 模态与非模态对话框的区别

    1.非模态对话框通常包含 标题栏和系统菜单栏

    STYLE  WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE

    而模态通常不需要。

    2. 通常非模态对话框包含WS_VISIBLE样式 ,否则需要在CreateDialog以后调用ShowWindow显示

    hDlgModeless = CraeteDialog(...);

    ShowWindow (hDlgModeless, SW_SHOW);


    3. 非模态对话框的消息要进入你程序的消息队列。而消息队列必须经过改动才能把这些消息传递给对话框窗口过程。

    hDlgModeless = CreateDialog(...);


    修改消息循环

    while (GetMessage(&msg, NULL, 0, 0))
    {
    	if (hDlgModeless == 0 || !IsDialogMessage(hDlgModeless, &msg))
    	{
    		TranslateMessage(&msg);
    		DispatchMessage(&msg);
    	}
    }
    如果消息是针对对话框的,IsDialogMessage就会把消息发送给对话框的窗口过程并返回TRUE,否则返回FALSE

    如果应用程序使用了键盘加速键,修改以后的消息循环如下

    while (GetMessage(&msg, NULL, 0, 0))
    {
    	if (hDlgModeless == 0 || !IsDialogMessage(hDlgModeless, &msg))
    	{
    		if (!TranslateAccelerator(HWND, hAccel, &msg))
    		{
    			TranslateMessage(&msg);
    			DispatchMessage(&msg);
    		}	
    	}
    }
    在创建非模态对话框之前hDlgModeless保持为0 ,在销毁以后也至于0


    4. 使用Destroywindow 来结束非模态对话框。当调用DestroyWindow时,还要把hDlgModeless全局变量设置为NULL.

    在非模态对话框的对话框过程中处理WM_CLOSE消息

    case WM_CLOSE:

         DestroyWindow(hDlg);

          hDlgModeless = NULL;

          break;

    避免使用全局变量可以使用CreateDialogParam来创建费莫泰对话框,并给他传递一个指向结构的指针。


    11.2.2 新的COLORS程序

    color2.cpp

    #include <windows.h>      
    
    LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); //window procedure.    
    BOOL CALLBACK ColorScrDlg(HWND, UINT, WPARAM, LPARAM);
    
    HWND hDlgModeless;
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    	PSTR szCmdLine, int iCmdShow)
    {
    	static      TCHAR szAppName[] = TEXT("Colors2");
    	HWND        hwnd;
    	MSG         msg;
    	WNDCLASS    wndClass;       //The window Class      
    
    	wndClass.style = CS_HREDRAW | CS_VREDRAW;
    	wndClass.lpfnWndProc = WndProc;// assign the window procedure to windows class.      
    	wndClass.cbClsExtra = 0;
    	wndClass.cbWndExtra = 0;
    	wndClass.hInstance = hInstance;
    	wndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    	wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
    	wndClass.hbrBackground = CreateSolidBrush(0L);//(HBRUSH)GetStockObject(WHITE_BRUSH);  
    	wndClass.lpszMenuName = NULL;
    	wndClass.lpszClassName = szAppName;
    
    	//Register the Window Class to the Windows System.       
    	if (!RegisterClass(&wndClass))
    	{
    		MessageBox(NULL, TEXT("This program require Windows NT!"),
    			szAppName, MB_ICONERROR);
    		return 0;
    	}
    
    	//This function will generate an WM_CREATE message.      
    	hwnd = CreateWindow(szAppName,      //Window class name      
    		TEXT("Color Scroll"),      //Window caption      
    		WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,            //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); //This function will generate a WM_PAINT message.   
    
    	hDlgModeless = CreateDialog(hInstance, TEXT("ColorScrDlg"),
    								hwnd, ColorScrDlg);
    
    						/* The message loop for this program.
    						if received the WM_QUIT message, the function will return 0.*/
    	while (GetMessage(&msg, NULL, 0, 0))
    	{
    		if (hDlgModeless == 0 || !IsDialogMessage(hDlgModeless, &msg))
    		{
    			TranslateMessage(&msg);
    			DispatchMessage(&msg);
    		}
    	}
    	return msg.wParam;
    
    }
    
    //define the Window Procedure WndProc      
    LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
    	switch (message) //get the message      
    	{
    	case WM_DESTROY:
    		DeleteObject((HGDIOBJ)SetClassLong(hwnd, GCL_HBRBACKGROUND,
    			(LONG)GetStockObject(WHITE_BRUSH)));
    		PostQuitMessage(0);
    		return 0;
    	}
    	return  DefWindowProc(hwnd, message, wParam, lParam);
    }
    
    BOOL CALLBACK ColorScrDlg(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
    {
    	static int		iColor[3];
    	HWND			hwndParent, hCtrl;
    	int				iCtrlID, iIndex;
    
    	switch (message)
    	{
    	case WM_INITDIALOG:
    		for (iCtrlID = 10; iCtrlID < 13; iCtrlID++)
    		{
    			hCtrl = GetDlgItem(hDlg, iCtrlID);
    			SetScrollRange(hCtrl, SB_CTL, 0, 255, FALSE);
    			SetScrollPos(hCtrl, SB_CTL, 0, FALSE);
    		}
    		return TRUE;
    
    	case WM_VSCROLL:
    		hCtrl = (HWND)lParam;
    		iCtrlID = GetWindowLong(hCtrl, GWL_ID);
    		iIndex = iCtrlID - 10;
    		hwndParent = GetParent(hDlg);
    
    		switch (LOWORD(wParam))
    		{
    		case SB_PAGEDOWN:
    			iColor[iIndex] += 15;	//fall through
    		case SB_LINEDOWN:
    			iColor[iIndex] = min(255, iColor[iIndex] + 1);
    			break;
    		case SB_PAGEUP:
    			iColor[iIndex] -= 15;	//fall through
    		case SB_LINEUP:
    			iColor[iIndex] = max(0, iColor[iIndex] - 1);
    			break;
    		case SB_TOP:
    			iColor[iIndex] = 0;
    			break;
    		case SB_BOTTOM:
    			iColor[iIndex] = 255;
    			break;
    		case SB_THUMBPOSITION:
    		case SB_THUMBTRACK:
    			iColor[iIndex] = HIWORD(wParam);
    			break;
    		default:
    			return FALSE;
    		}
    		SetScrollPos(hCtrl, SB_CTL, iColor[iIndex], TRUE);
    		SetDlgItemInt(hDlg, iCtrlID + 3, iColor[iIndex], FALSE);
    
    		DeleteObject((HGDIOBJ)SetClassLong(hwndParent, GCL_HBRBACKGROUND,
    			(LONG)CreateSolidBrush(
    				RGB(iColor[0], iColor[1], iColor[2]))));
    
    		InvalidateRect(hwndParent, NULL, TRUE);
    		return TRUE;
    	case WM_CLOSE:
    		DestroyWindow(hDlg);
    		hDlgModeless = NULL;
    		break;
    	}
    	return FALSE;
    }

    colors2.rc

    // Microsoft Visual C++ generated resource script.
    //
    #include "resource.h"
    
    #define APSTUDIO_READONLY_SYMBOLS
    /
    //
    // Generated from the TEXTINCLUDE 2 resource.
    //
    #include "afxres.h"
    
    /
    #undef APSTUDIO_READONLY_SYMBOLS
    
    /
    // English (United States) resources
    
    #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
    LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
    #pragma code_page(1252)
    
    #ifdef APSTUDIO_INVOKED
    /
    //
    // TEXTINCLUDE
    //
    
    1 TEXTINCLUDE 
    BEGIN
        "resource.h\0"
    END
    
    2 TEXTINCLUDE 
    BEGIN
        "#include ""afxres.h""\r\n"
        "\0"
    END
    
    3 TEXTINCLUDE 
    BEGIN
        "\r\n"
        "\0"
    END
    
    #endif    // APSTUDIO_INVOKED
    
    
    /
    //
    // Dialog
    //
    
    COLORSCRDLG DIALOGEX 16, 16, 120, 141
    STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
    CAPTION "Color Scroll Scrollbars"
    FONT 8, "MS Sans Serif", 0, 0, 0x0
    BEGIN
        CTEXT           "&Red",IDC_STATIC,8,8,24,8,NOT WS_GROUP
        SCROLLBAR       10,8,20,24,100,SBS_VERT | WS_TABSTOP
        CTEXT           "0",13,8,124,24,8,NOT WS_GROUP
        CTEXT           "&Green",IDC_STATIC,48,8,24,8,NOT WS_GROUP
        SCROLLBAR       11,48,20,24,100,SBS_VERT | WS_TABSTOP
        CTEXT           "0",14,48,124,24,8,NOT WS_GROUP
        CTEXT           "&Blue",IDC_STATIC,89,8,24,8,NOT WS_GROUP
        SCROLLBAR       12,89,20,24,100,SBS_VERT | WS_TABSTOP
        CTEXT           "0",15,89,124,24,8,NOT WS_GROUP
    END
    
    
    /
    //
    // DESIGNINFO
    //
    
    #ifdef APSTUDIO_INVOKED
    GUIDELINES DESIGNINFO
    BEGIN
        "COLORSCRDLG", DIALOG
        BEGIN
            LEFTMARGIN, 7
            RIGHTMARGIN, 113
            TOPMARGIN, 7
            BOTTOMMARGIN, 134
        END
    END
    #endif    // APSTUDIO_INVOKED
    
    
    /
    //
    // AFX_DIALOG_LAYOUT
    //
    
    COLORSCRDLG AFX_DIALOG_LAYOUT
    BEGIN
        0
    END
    
    #endif    // English (United States) resources
    /
    
    
    
    #ifndef APSTUDIO_INVOKED
    /
    //
    // Generated from the TEXTINCLUDE 3 resource.
    //
    
    
    /
    #endif    // not APSTUDIO_INVOKED
    
    

    resource.h

    //{{NO_DEPENDENCIES}}
    // Microsoft Developer Studio generated include file.
    // Used by Colors2.rc
    //
    #define IDC_STATIC                      -1
    
    // Next default values for new objects
    // 
    #ifdef APSTUDIO_INVOKED
    #ifndef APSTUDIO_READONLY_SYMBOLS
    #define _APS_NEXT_RESOURCE_VALUE        102
    #define _APS_NEXT_COMMAND_VALUE         40001
    #define _APS_NEXT_CONTROL_VALUE         1003
    #define _APS_NEXT_SYMED_VALUE           101
    #endif
    #endif
    

    运行结果



    11.2.3 HEXCALC:窗口还是对话框?

    hexcalc.cpp

    #include <windows.h>      
    
    LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); //window procedure.    
    
    HWND hDlgModeless;
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    	PSTR szCmdLine, int iCmdShow)
    {
    	static      TCHAR szAppName[] = TEXT("HexCalc");
    	HWND        hwnd;
    	MSG         msg;
    	WNDCLASS    wndClass;       //The window Class      
    
    	wndClass.style = CS_HREDRAW | CS_VREDRAW;
    	wndClass.lpfnWndProc = WndProc;// assign the window procedure to windows class.      
    	wndClass.cbClsExtra = 0;
    	wndClass.cbWndExtra = DLGWINDOWEXTRA;		// Note!
    	wndClass.hInstance = hInstance;
    	wndClass.hIcon = LoadIcon(NULL, szAppName);
    	wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
    	wndClass.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);//(HBRUSH)GetStockObject(WHITE_BRUSH);  
    	wndClass.lpszMenuName = NULL;
    	wndClass.lpszClassName = szAppName;
    
    	//Register the Window Class to the Windows System.       
    	if (!RegisterClass(&wndClass))
    	{
    		MessageBox(NULL, TEXT("This program require Windows NT!"),
    			szAppName, MB_ICONERROR);
    		return 0;
    	}
    
    	hwnd = CreateDialog(hInstance, szAppName, 0, NULL);
    
    	ShowWindow(hwnd, iCmdShow);
    
    	/* The message loop for this program.
    	if received the WM_QUIT message, the function will return 0.*/
    	while (GetMessage(&msg, NULL, 0, 0))
    	{
    		TranslateMessage(&msg);
    		DispatchMessage(&msg);
    	}
    	return msg.wParam;
    
    }
    
    void ShowNumber(HWND hwnd, UINT iNumber)
    {
    	TCHAR szBuffer[20];
    
    	wsprintf(szBuffer, TEXT("%X"), iNumber);
    	SetDlgItemText(hwnd, VK_ESCAPE, szBuffer);
    }
    
    DWORD CalcIt(UINT iFirstNum, int iOperation, UINT iNum)
    {
    	switch (iOperation)
    	{
    	case '=': return iNum;
    	case '+': return iFirstNum + iNum;
    	case '-': return iFirstNum - iNum;
    	case '*': return iFirstNum * iNum;
    	case '&': return iFirstNum & iNum;
    	case '|': return iFirstNum | iNum;
    	case '^': return iFirstNum ^ iNum;
    	case '<': return iFirstNum << iNum;
    	case '>': return iFirstNum >> iNum;
    	case '/': return iNum ? iFirstNum / iNum : MAXDWORD;
    	case '%': return iNum ? iFirstNum % iNum : MAXDWORD;
    	default:  return 0;
    	}
    }
    
    //define the Window Procedure WndProc      
    LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
    	static BOOL		bNewNumber = TRUE;
    	static int		iOperation = '=';
    	static UINT		iNumber, iFirstNum;
    	HWND			hButton;
    
    	switch (message) //get the message      
    	{
    	case WM_KEYDOWN:
    		if (wParam != VK_LEFT)			//left arrow --> backspace
    			break;
    		wParam = VK_BACK;
    
    		// fall through
    
    	case WM_CHAR:
    		if ((wParam = (WPARAM)CharUpper((TCHAR *)wParam)) == VK_RETURN)
    			wParam = '=';
    
    		if (hButton = GetDlgItem(hwnd, wParam))
    		{
    			SendMessage(hButton, BM_SETSTATE, 1, 0);
    			Sleep(100);
    			SendMessage(hButton, BM_SETSTATE, 0, 0);
    		}
    		else
    		{
    			MessageBeep(0);
    			break;
    		}
    
    		// fall through
    
    	case WM_COMMAND:
    		SetFocus(hwnd);
    
    		if (LOWORD(wParam) == VK_BACK)			// backspace
    			ShowNumber(hwnd, iNumber /= 16);
    
    		else if (LOWORD(wParam) == VK_ESCAPE)	// escape
    			ShowNumber(hwnd, iNumber = 0);
    
    		else if (isxdigit(LOWORD(wParam)))		// hex digit
    		{
    			if (bNewNumber)
    			{
    				iFirstNum = iNumber;
    				iNumber = 0;
    			}
    			bNewNumber = FALSE;
    
    			if (iNumber <= MAXDWORD >> 4)
    				ShowNumber(hwnd, iNumber = 16 * iNumber + wParam -
    				(isdigit(wParam) ? '0' : 'A' - 10));
    			else
    				MessageBeep(0);
    		}
    		else      //Operation
    		{
    			if (!bNewNumber)
    				ShowNumber(hwnd, iNumber =
    					CalcIt(iFirstNum, iOperation, iNumber));
    			bNewNumber = TRUE;
    			iOperation = LOWORD(wParam);
    		}
    
    		return 0;
    
    	case WM_DESTROY:
    		PostQuitMessage(0);
    		return 0;
    	}
    	return  DefWindowProc(hwnd, message, wParam, lParam);
    }

    hexcalc.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
        "#include ""hexcalc.dlg""\r\n"
        "\0"
    END
    
    #endif    // APSTUDIO_INVOKED
    
    
    /
    //
    // Icon
    //
    
    // Icon with lowest ID value placed first to ensure application icon
    // remains consistent on all systems.
    HEXCALC                 ICON    DISCARDABLE     "HexCalc.ico"
    #endif    // English (U.S.) resources
    /
    
    
    
    #ifndef APSTUDIO_INVOKED
    /
    //
    // Generated from the TEXTINCLUDE 3 resource.
    //
    #include "hexcalc.dlg"
    
    /
    #endif    // not APSTUDIO_INVOKED
    
    

    hexcalc.dlg

    /*---------------------------
       HEXCALC.DLG dialog script
      ---------------------------*/
    
    HexCalc DIALOG -1, -1, 102, 122
    STYLE WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX
    CLASS "HexCalc"
    CAPTION "Hex Calculator"
    {
         PUSHBUTTON "D",       68,  8,  24, 14, 14
         PUSHBUTTON "A",       65,  8,  40, 14, 14
         PUSHBUTTON "7",       55,  8,  56, 14, 14
         PUSHBUTTON "4",       52,  8,  72, 14, 14
         PUSHBUTTON "1",       49,  8,  88, 14, 14
         PUSHBUTTON "0",       48,  8, 104, 14, 14
         PUSHBUTTON "0",       27, 26,   4, 50, 14
         PUSHBUTTON "E",       69, 26,  24, 14, 14
         PUSHBUTTON "B",       66, 26,  40, 14, 14
         PUSHBUTTON "8",       56, 26,  56, 14, 14
         PUSHBUTTON "5",       53, 26,  72, 14, 14
         PUSHBUTTON "2",       50, 26,  88, 14, 14
         PUSHBUTTON "Back",     8, 26, 104, 32, 14
         PUSHBUTTON "C",       67, 44,  40, 14, 14
         PUSHBUTTON "F",       70, 44,  24, 14, 14
         PUSHBUTTON "9",       57, 44,  56, 14, 14
         PUSHBUTTON "6",       54, 44,  72, 14, 14
         PUSHBUTTON "3",       51, 44,  88, 14, 14
         PUSHBUTTON "+",       43, 62,  24, 14, 14
         PUSHBUTTON "-",       45, 62,  40, 14, 14
         PUSHBUTTON "*",       42, 62,  56, 14, 14
         PUSHBUTTON "/",       47, 62,  72, 14, 14
         PUSHBUTTON "%",       37, 62,  88, 14, 14
         PUSHBUTTON "Equals",  61, 62, 104, 32, 14
         PUSHBUTTON "&&",      38, 80,  24, 14, 14
         PUSHBUTTON "|",      124, 80,  40, 14, 14
         PUSHBUTTON "^",       94, 80,  56, 14, 14
         PUSHBUTTON "<",       60, 80,  72, 14, 14
         PUSHBUTTON ">",       62, 80,  88, 14, 14
    }
    

    resource.h

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


    运行结果


    11.3 公用对话框

    打开,存储文件,查找和替换,选择颜色字体的对话框。

    创建某一结构并传递给公用对话框的某一函数,就能够显示公用对话框。


    11.3.1 完善POPPAD


    该项目的加入内存泄漏检测 ,加入设置zi

    poppad3.cpp


    popfile.cpp


    #include <windows.h>
    #include <commdlg.h>
    #include "resource.h"
    #include "DetectMemoryLeak.h"
    
    #define EDITID 1 
    #define UNTITLED TEXT("(untitled)")
    
    LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); //window procedure. 
    BOOL	CALLBACK AboutDlgProc(HWND, UINT, WPARAM, LPARAM);
    
    // Functions in POPFILE.cpp
    void PopFileInitialize(HWND);
    BOOL PopFileOpenDlg(HWND, PTSTR, PTSTR);
    BOOL PopFileSaveDlg(HWND, PTSTR, PTSTR);
    BOOL PopFileRead(HWND, PTSTR);
    BOOL PopFileWrite(HWND, PTSTR);
    
    // Function in POPFIND.cpp
    
    HWND PopFindFindDlg(HWND);
    HWND PopFindReplaceDlg(HWND);
    BOOL PopFindFindText(HWND, int *, LPFINDREPLACE);
    BOOL PopFindReplaceText(HWND, int *, LPFINDREPLACE);
    BOOL PopFindNextText(HWND, int *);
    BOOL PopFindValidFind(void);
    
    // Functions in POPFONT.c
    
    void PopFontInitialize(HWND);
    BOOL PopFontChooseFont(HWND);
    void PopFontSetFont(HWND);
    void PopFontDeinitialize(void);
    BOOL PopFontChooseFontColor(HWND);
    void PopFontSetFontColor(HWND, COLORREF *);
    
    
    // Functions in POPPRINT.c
    
    BOOL PopPrntPrintFile(HINSTANCE, HWND, HWND, PTSTR);
    
    // Global variables
    // These variable could only be accessed in poppad3.cpp
    static HWND hDlgModeless;
    static TCHAR szAppName[] = TEXT("PopPad");
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    	PSTR szCmdLine, int iCmdShow)
    {
    	_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
    	HACCEL		hAccel;
    	HWND        hwnd;
    	MSG         msg;
    	WNDCLASS    wndClass;       //The window Class      
    
    	wndClass.style = CS_HREDRAW | CS_VREDRAW;
    	wndClass.lpfnWndProc = WndProc;// assign the window procedure to windows class.      
    	wndClass.cbClsExtra = 0;
    	wndClass.cbWndExtra = 0;
    	wndClass.hInstance = hInstance;
    	wndClass.hIcon = LoadIcon(hInstance, szAppName);// LoadIcon(NULL, IDI_APPLICATION);
    	wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
    	wndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    	wndClass.lpszMenuName = szAppName;
    	wndClass.lpszClassName = szAppName;
    
    	//Register the Window Class to the Windows System.       
    	if (!RegisterClass(&wndClass))
    	{
    		MessageBox(NULL, TEXT("This program require Windows NT!"),
    			szAppName, MB_ICONERROR);
    		return 0;
    	}
    
    	//This function will generate an WM_CREATE message.      
    	hwnd = CreateWindow(szAppName,      //Window class name      
    		NULL,      //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); //This function will generate a WM_PAINT message.      
    
    	hAccel = LoadAccelerators(hInstance, szAppName);
    
    	/* The message loop for this program.
    	if received the WM_QUIT message, the function will return 0.*/
    	while (GetMessage(&msg, NULL, 0, 0))
    	{
    		if (hDlgModeless == NULL || !IsDialogMessage(hDlgModeless, &msg))
    		{
    			if (!TranslateAccelerator(hwnd, hAccel, &msg))
    			{
    				TranslateMessage(&msg);
    				DispatchMessage(&msg);
    			}
    		}
    	}
    	return msg.wParam;
    }
    
    void DoCaption(HWND hwnd, TCHAR * szTitleName)
    {
    	TCHAR szCaption[64 + MAX_PATH];
    
    	wsprintf(szCaption, TEXT("%s - %s"), szAppName,
    		szTitleName[0] ? szTitleName : UNTITLED);
    
    	SetWindowText(hwnd, szCaption);
    }
    
    void OkMessage(HWND hwnd, TCHAR * szMessage, TCHAR * szTitleName)
    {
    	TCHAR szBuffer[64 + MAX_PATH];
    
    	wsprintf(szBuffer, szMessage, szTitleName[0] ? szTitleName : UNTITLED);
    
    	MessageBox(hwnd, szBuffer, szAppName, MB_OK | MB_ICONEXCLAMATION);
    }
    
    short AskAboutSave(HWND hwnd, TCHAR * szTitleName)
    {
    	TCHAR szBuffer[64 + MAX_PATH];
    	int iReturn;
    
    	wsprintf(szBuffer, TEXT("Save current changes in %s?"),
    		szTitleName[0] ? szTitleName : UNTITLED);
    
    	iReturn = MessageBox(hwnd, szBuffer, szAppName,
    		MB_YESNOCANCEL | MB_ICONQUESTION);
    
    	if (iReturn == IDYES)
    		if (!SendMessage(hwnd, WM_COMMAND, IDM_FILE_SAVE, 0))
    			iReturn = IDCANCEL;
    
    	return iReturn;
    }
    
    //define the Window Procedure WndProc      
    LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
    	static BOOL bNeedSave = FALSE;
    	static HINSTANCE hInst;
    	static HWND hwndEdit;
    	static int iOffset;
    	static TCHAR szFileName[MAX_PATH], szTitleName[MAX_PATH];
    	static UINT messageFindReplace;
    	int iSelBeg, iSelEnd, iEnable;
    	static COLORREF iColor;
    	static HBRUSH hBrushEdit;
    	LPFINDREPLACE pfr;
    
    	switch (message) //get the message      
    	{
    	case WM_CREATE:
    		hInst = ((LPCREATESTRUCT)lParam)->hInstance;
    
    		hwndEdit = CreateWindow(TEXT("edit"), NULL,
    			WS_CHILD | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL |
    			WS_BORDER | ES_LEFT | ES_MULTILINE |
    			ES_NOHIDESEL | ES_AUTOHSCROLL | ES_AUTOVSCROLL,
    			0, 0, 0, 0,
    			hwnd, (HMENU)EDITID,
    			hInst, NULL);
    
    		SendMessage(hwndEdit, EM_LIMITTEXT, 3200, 0L);
    
    		// Initialize common dialog box stuff
    
    		PopFileInitialize(hwnd);
    		PopFontInitialize(hwndEdit);
    
    		messageFindReplace = RegisterWindowMessage(FINDMSGSTRING);
    
    		DoCaption(hwnd, szTitleName);
    
    		hBrushEdit = CreateSolidBrush(GetSysColor(COLOR_BTNHILIGHT));
    
    		return 0;
    
    	case WM_SETFOCUS:
    		SetFocus(hwndEdit);
    		return 0;
    
    	case WM_SIZE:
    		MoveWindow(hwndEdit, 0, 0, LOWORD(lParam), HIWORD(lParam), TRUE);
    		return 0;
    
    	case WM_INITMENUPOPUP:
    		switch (lParam)
    		{
    		case 1:			// The index of edit menu
    						// Enable Undo if edit control can do it.
    
    			EnableMenuItem((HMENU)wParam, IDM_EDIT_UNDO,
    				SendMessage(hwndEdit, EM_CANUNDO, 0, 0) ?
    				MF_ENABLED : MF_GRAYED);
    
    			// Enable Paste if text is in the clipboard
    
    			EnableMenuItem((HMENU)wParam, IDM_EDIT_PASTE,
    				IsClipboardFormatAvailable(CF_TEXT) ?
    				MF_ENABLED : MF_GRAYED);
    
    			// Enable Cut, Copy, and Del if text is selected.
    
    			SendMessage(hwndEdit, EM_GETSEL, (WPARAM)&iSelBeg, (LPARAM)&iSelEnd);
    
    			iEnable = iSelBeg != iSelEnd ? MF_ENABLED : MF_GRAYED;
    
    			EnableMenuItem((HMENU)wParam, IDM_EDIT_CUT, iEnable);
    			EnableMenuItem((HMENU)wParam, IDM_EDIT_COPY, iEnable);
    			EnableMenuItem((HMENU)wParam, IDM_EDIT_CLEAR, iEnable);
    			break;
    
    		case 2:				// Search menu
    
    							// Enable Find, Next, and Replace if modeless
    							// dialogs are not already active
    
    			iEnable = hDlgModeless == NULL ?
    				MF_ENABLED : MF_GRAYED;
    
    			EnableMenuItem((HMENU)wParam, IDM_SEARCH_FIND, iEnable);
    			EnableMenuItem((HMENU)wParam, IDM_SEARCH_NEXT, iEnable);
    			EnableMenuItem((HMENU)wParam, IDM_SEARCH_REPLACE, iEnable);
    			break;
    		}
    		return 0;
    	case WM_CTLCOLOREDIT:
    		if (EDITID == GetWindowLong((HWND)lParam, GWL_ID))
    		{
    			SetTextColor((HDC)wParam, iColor);
    			SetBkColor((HDC)wParam, GetSysColor(COLOR_BTNHIGHLIGHT));
    			return (LRESULT)hBrushEdit;
    		}
    		break;
    	case WM_COMMAND:
    		if (lParam && LOWORD(wParam) == EDITID) //edit control command.
    		{
    			switch (HIWORD(wParam))
    			{
    			case EN_UPDATE:
    				bNeedSave = TRUE;
    				return 0;
    
    			case EN_ERRSPACE:
    			case EN_MAXTEXT:
    				MessageBox(hwnd, TEXT("Edit control out of space."),
    					szAppName, MB_OK | MB_ICONSTOP);
    				return 0;
    
    			case EM_SETSEL:
    				return 0;
    			}
    			break;
    		}
    
    		switch (LOWORD(wParam))
    		{
    			// Messages from File menu
    		case IDM_FILE_NEW:
    			if (bNeedSave && IDCANCEL == AskAboutSave(hwnd, szTitleName))
    				return 0;
    
    			SetWindowText(hwndEdit, TEXT("\0"));
    			szFileName[0] = TEXT('\0');
    			szTitleName[0] = TEXT('\0');
    			DoCaption(hwnd, szTitleName);
    			bNeedSave = FALSE;
    			return 0;
    
    		case IDM_FILE_OPEN:
    			if (bNeedSave && IDCANCEL == AskAboutSave(hwnd, szTitleName))
    				return 0;
    
    			if (PopFileOpenDlg(hwnd, szFileName, szTitleName))
    			{
    				if (!PopFileRead(hwndEdit, szFileName))
    				{
    					OkMessage(hwnd, TEXT("Could not read file %s!"),
    						szTitleName);
    					szFileName[0] = TEXT('\0');
    					szTitleName[0] = TEXT('\0');
    				}
    			}
    
    			DoCaption(hwnd, szTitleName);
    			bNeedSave = FALSE;
    			return 0;
    
    		case IDM_FILE_SAVE:
    			if (szFileName[0])
    			{
    				if (PopFileWrite(hwndEdit, szFileName))
    				{
    					bNeedSave = FALSE;
    					return 1;
    				}
    				else
    				{
    					OkMessage(hwnd, TEXT("Could not write file %s"),
    						szTitleName);
    
    					return 0;
    				}
    			}
    
    			// fall through
    
    		case IDM_FILE_SAVE_AS:
    			if (PopFileSaveDlg(hwnd, szFileName, szTitleName))
    			{
    				DoCaption(hwnd, szTitleName);
    
    				if (PopFileWrite(hwndEdit, szFileName))
    				{
    					bNeedSave = FALSE;
    					return 1;
    				}
    				else
    				{
    					OkMessage(hwnd, TEXT("Could not write file %s"),
    						szTitleName);
    					return 0;
    				}
    			}
    			return 0;
    
    		case IDM_FILE_PRINT:
    			if (!PopPrntPrintFile(hInst, hwnd, hwndEdit, szTitleName))
    				OkMessage(hwnd, TEXT("Could not print file %s"), szTitleName);
    			return 0;
    
    		case IDM_APP_EXIT:
    			SendMessage(hwnd, WM_CLOSE, 0, 0);
    			return 0;
    
    			// Messages from Edit menu
    		case IDM_EDIT_UNDO:
    			SendMessage(hwndEdit, WM_UNDO, 0, 0);
    			return 0;
    
    		case IDM_EDIT_CUT:
    			SendMessage(hwndEdit, WM_CUT, 0, 0);
    			return 0;
    
    		case IDM_EDIT_COPY:
    			SendMessage(hwndEdit, WM_COPY, 0, 0);
    			return 0;
    
    		case IDM_EDIT_PASTE:
    			SendMessage(hwndEdit, WM_PASTE, 0, 0);
    			return 0;
    
    		case IDM_EDIT_CLEAR:
    			SendMessage(hwndEdit, WM_CLEAR, 0, 0);
    			return 0;
    
    		case IDM_EDIT_SELECT_ALL:
    			SendMessage(hwndEdit, EM_SETSEL, 0, -1);
    			return 0;
    
    			// Messages from Search menu
    
    		case IDM_SEARCH_FIND:
    			SendMessage(hwndEdit, EM_GETSEL, 0, (LPARAM)&iOffset);
    			hDlgModeless = PopFindFindDlg(hwnd);
    			return 0;
    
    		case IDM_SEARCH_NEXT:
    			SendMessage(hwndEdit, EM_GETSEL, 0, (LPARAM)&iOffset);
    
    			if (PopFindValidFind())
    				PopFindNextText(hwndEdit, &iOffset);
    			else
    				hDlgModeless = PopFindFindDlg(hwnd);
    
    			return 0;
    
    		case IDM_SEARCH_REPLACE:
    			SendMessage(hwndEdit, EM_GETSEL, 0, (LPARAM)&iOffset);
    			hDlgModeless = PopFindReplaceDlg(hwnd);
    			return 0;
    
    		case IDM_FORMAT_FONT:
    			if (PopFontChooseFont(hwnd))
    				PopFontSetFont(hwndEdit);
    
    			return 0;
    
    		case IDM_FORMAT_COLOR:
    			if (PopFontChooseFontColor((hwnd)))
    				PopFontSetFontColor(hwndEdit, &iColor);
    			return 0;
    
    			// Messages from Help menu
    		case IDM_HELP:
    			OkMessage(hwnd, TEXT("Help not yet implemented!"),
    				TEXT("\0"));
    			return 0;
    
    		case IDM_APP_ABOUT:
    			DialogBox(hInst, TEXT("AboutBox"), hwnd, AboutDlgProc);
    			return 0;
    
    		}
    		break;
    
    	case WM_CLOSE:
    		if (!bNeedSave || IDCANCEL != AskAboutSave(hwnd, szTitleName))
    			DestroyWindow(hwnd);
    		return 0;
    
    	case WM_QUERYENDSESSION:
    		if (!bNeedSave || IDCANCEL != AskAboutSave(hwnd, szTitleName))
    			return 1;
    
    		return 0;
    
    	case WM_DESTROY:
    		DeleteObject(hBrushEdit);
    		PopFontDeinitialize();
    		PostQuitMessage(0);
    		return 0;
    
    	default:
    		// Process "Find-Replace" messages
    
    		if (message == messageFindReplace)
    		{
    			pfr = (LPFINDREPLACE)lParam;
    
    			if (pfr->Flags & FR_DIALOGTERM)
    				hDlgModeless = NULL;
    
    			if (pfr->Flags & FR_FINDNEXT)
    				if (!PopFindFindText(hwndEdit, &iOffset, pfr))
    					OkMessage(hwnd, TEXT("Text not found!"),
    						TEXT("\0"));
    
    			if (pfr->Flags & FR_REPLACE || pfr->Flags & FR_REPLACEALL)
    				if (!PopFindReplaceText(hwndEdit, &iOffset, pfr))
    					OkMessage(hwnd, TEXT("Text not found!"),
    						TEXT("\0"));
    
    			if (pfr->Flags & FR_REPLACEALL)
    				while (PopFindReplaceText(hwndEdit, &iOffset, pfr))
    					;
    			return 0;
    		}
    		break;
    	 }
    	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;
    }


    popfind.cpp

    #include <windows.h>
    #include <commdlg.h>
    #include <tchar.h>			// for _tcsstr (strstr for Unicode & non-unicode)
    #include "DetectMemoryLeak.h"
    
    #define MAX_STRING_LEN	256
    
    static TCHAR szFindText[MAX_STRING_LEN];
    static TCHAR szReplText[MAX_STRING_LEN];
    
    HWND PopFindFindDlg(HWND hwnd)
    {
    	static FINDREPLACE fr;		// must be static for modeless dialog!!!
    
    	fr.lStructSize = sizeof(FINDREPLACE);
    	fr.hwndOwner = hwnd;
    	fr.hInstance = NULL;
    	fr.Flags = FR_HIDEUPDOWN | FR_HIDEMATCHCASE | FR_HIDEWHOLEWORD;
    	fr.lpstrFindWhat = szFindText;
    	fr.lpstrReplaceWith = NULL;
    	fr.wFindWhatLen = MAX_STRING_LEN;
    	fr.wReplaceWithLen = 0;
    	fr.lCustData = 0;
    	fr.lpfnHook = NULL;
    	fr.lpTemplateName = NULL;
    
    	return FindText(&fr);
    }
    
    HWND PopFindReplaceDlg(HWND hwnd)
    {
    	static FINDREPLACE fr;		// must be static for modeless dialog!!!
    
    	fr.lStructSize = sizeof(FINDREPLACE);
    	fr.hwndOwner = hwnd;
    	fr.hInstance = NULL;
    	fr.Flags = FR_HIDEUPDOWN | FR_HIDEMATCHCASE | FR_HIDEWHOLEWORD;
    	fr.lpstrFindWhat = szFindText;
    	fr.lpstrReplaceWith = szReplText;
    	fr.wFindWhatLen = MAX_STRING_LEN;
    	fr.wReplaceWithLen = MAX_STRING_LEN;
    	fr.lCustData = 0;
    	fr.lpfnHook = NULL;
    	fr.lpTemplateName = NULL;
    
    	return ReplaceText(&fr);
    }
    
    BOOL PopFindFindText(HWND hwndEdit, int * piSearchOffset, LPFINDREPLACE pfr)
    {
    	int iLength, iPos;
    	PTSTR pstrDoc, pstrPos;
    
    	// Read in the edit document
    
    	iLength = GetWindowTextLength(hwndEdit);
    
    	if (NULL == (pstrDoc = (PTSTR)malloc((iLength + 1) * sizeof(TCHAR))))
    		return FALSE;
    
    	GetWindowText(hwndEdit, pstrDoc, iLength + 1);
    
    	// Search the document for the find string
    
    	pstrPos = _tcsstr(pstrDoc + *piSearchOffset, pfr->lpstrFindWhat);
    	free(pstrDoc);
    
    	// Return an error code if the string cannot be found
    
    	if (pstrPos == NULL)
    		return FALSE;
    
    	// Find the position in the document and the new start offset
    
    	iPos = pstrPos - pstrDoc;
    	*piSearchOffset = iPos + lstrlen(pfr->lpstrFindWhat);
    
    	// Select the found text
    	SendMessage(hwndEdit, EM_SETSEL, iPos, *piSearchOffset);
    	SendMessage(hwndEdit, EM_SCROLLCARET, 0, 0);
    
    	return TRUE;
    }
    
    BOOL PopFindNextText(HWND hwndEdit, int * piSearchOffset)
    {
    	FINDREPLACE fr;
    
    	fr.lpstrFindWhat = szFindText;
    
    	return PopFindFindText(hwndEdit, piSearchOffset, &fr);
    }
    
    BOOL PopFindReplaceText(HWND hwndEdit, int * piSearchOffset, LPFINDREPLACE pfr)
    {
    	// Find the text
    
    	if (!PopFindFindText(hwndEdit, piSearchOffset, pfr))
    		return FALSE;
    
    	// Replace it
    
    	SendMessage(hwndEdit, EM_REPLACESEL, 0, (LPARAM)pfr->lpstrReplaceWith);
    
    	return TRUE;
    }
    
    BOOL PopFindValidFind(void)
    {
    	return *szFindText != '\0';
    }

    popfont.cpp


    #include <windows.h>
    #include <commdlg.h>
    #include "DetectMemoryLeak.h"
    
    static LOGFONT	logfont;
    static HFONT	hFont;
    static CHOOSECOLOR cc;
    static COLORREF crCustColors[16];
    
    
    BOOL PopFontChooseFont(HWND hwnd)
    {
    	CHOOSEFONT cf;
    
    	cf.lStructSize = sizeof(CHOOSEFONT);
    	cf.hwndOwner = hwnd;
    	cf.hDC = NULL;
    	cf.lpLogFont = &logfont;
    	cf.iPointSize = 0;
    	cf.Flags = CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS | CF_EFFECTS;
    	cf.rgbColors = 0;
    	cf.lCustData = 0;
    	cf.lpfnHook = NULL;
    	cf.lpTemplateName = NULL;
    	cf.hInstance = NULL;
    	cf.lpszStyle = NULL;
    	cf.nFontType = 0;				// Returned from ChooseFont
    	cf.nSizeMin = 0;
    	cf.nSizeMax = 0;
    
    	return ChooseFont(&cf);
    }
    
    void PopFontInitialize(HWND hwndEdit)
    {
    	GetObject(GetStockObject(SYSTEM_FONT), sizeof(LOGFONT),
    		(PTSTR)&logfont);
    
    	hFont = CreateFontIndirect(&logfont);
    	SendMessage(hwndEdit, WM_SETFONT, (WPARAM)hFont, 0);
    }
    
    void PopFontSetFont(HWND hwndEdit)
    {
    	HFONT hFontNew;
    	RECT rect;
    
    	hFontNew = CreateFontIndirect(&logfont);
    	SendMessage(hwndEdit, WM_SETFONT, (WPARAM)hFontNew, 0);
    	DeleteObject(hFont);
    	hFont = hFontNew;
    	GetClientRect(hwndEdit, &rect);
    	InvalidateRect(hwndEdit, &rect, TRUE);
    }
    
    void PopFontDeinitialize(void)
    {
    	DeleteObject(hFont);
    }
    
    BOOL PopFontChooseFontColor(HWND hwnd)
    {
    	cc.lStructSize = sizeof(CHOOSECOLOR);
    	cc.hwndOwner = hwnd;
    	cc.hInstance = NULL;
    	cc.lpCustColors = crCustColors;
    	cc.Flags = CC_RGBINIT | CC_FULLOPEN;
    	cc.lCustData = 0;
    	cc.lpfnHook = NULL;
    	cc.lpTemplateName = NULL;
    	return ChooseColor(&cc);
    }
    
    void PopFontSetFontColor(HWND hwndEdit, COLORREF * iColor)
    {
    	*iColor = cc.rgbResult;
    	InvalidateRect(hwndEdit, NULL, TRUE);	// Redraw the edit control . It will cause the WM_CTLCOLOREDIT message
    }



    popprint0.cpp

    #include <windows.h>
    #include "DetectMemoryLeak.h"
    
    BOOL PopPrntPrintFile(HINSTANCE hInst, HWND hwnd, HWND hwndEdit,
    	PTSTR pstrTitleName)
    {
    	return FALSE;
    }

    Detectmemoryleak.h

    #pragma once
    
    #ifndef _UT_DETECT_MEMLEAK_H  
    #define _UT_DETECT_MEMLEAK_H  
    
    #ifdef _DEBUG  
    #define new DEBUG_CLIENTBLOCK  
    #define DebugCodeCRT(m) {m;}  
    #endif  
    #ifdef _DEBUG  
    #define DEBUG_CLIENTBLOCK   new( _CLIENT_BLOCK, __FILE__, __LINE__)  
    #else  
    #define DEBUG_CLIENTBLOCK  
    #endif  
    #define _CRTDBG_MAP_ALLOC  
    #include <crtdbg.h>  
    #ifdef _DEBUG  
    #define new DEBUG_CLIENTBLOCK  
    #endif  
    
    #endif _UT_DETECT_MEMLEAK_H  

    poppad.rc

    // Microsoft Visual C++ generated resource script.
    //
    #include "resource.h"
    
    #define APSTUDIO_READONLY_SYMBOLS
    /
    //
    // Generated from the TEXTINCLUDE 2 resource.
    //
    #include "afxres.h"
    
    /
    #undef APSTUDIO_READONLY_SYMBOLS
    
    /
    // English (United States) resources
    
    #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
    LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
    #pragma code_page(1252)
    
    #ifdef APSTUDIO_INVOKED
    /
    //
    // TEXTINCLUDE
    //
    
    1 TEXTINCLUDE 
    BEGIN
        "resource.h\0"
    END
    
    2 TEXTINCLUDE 
    BEGIN
        "#include ""afxres.h""\r\n"
        "\0"
    END
    
    3 TEXTINCLUDE 
    BEGIN
        "\r\n"
        "\0"
    END
    
    #endif    // APSTUDIO_INVOKED
    
    
    /
    //
    // Dialog
    //
    
    ABOUTBOX DIALOG 32, 32, 180, 100
    STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP
    FONT 8, "MS Sans Serif"
    BEGIN
        DEFPUSHBUTTON   "OK",IDOK,66,80,50,14
        ICON            "POPPAD",IDC_STATIC,7,7,20,20
        CTEXT           "PopPad",IDC_STATIC,40,12,100,8
        CTEXT           "Popup Editor for Windows",IDC_STATIC,7,40,166,8
        CTEXT           "(c) Charles Petzold, 1998",IDC_STATIC,7,52,166,8
    END
    
    PRINTDLGBOX DIALOG 32, 32, 186, 95
    STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
    CAPTION "PopPad"
    FONT 8, "MS Sans Serif"
    BEGIN
        PUSHBUTTON      "Cancel",IDCANCEL,67,74,50,14
        CTEXT           "Sending",IDC_STATIC,8,8,172,8
        CTEXT           "",IDC_FILENAME,8,28,172,8
        CTEXT           "to print spooler.",IDC_STATIC,8,48,172,8
    END
    
    
    /
    //
    // Menu
    //
    
    POPPAD MENU
    BEGIN
        POPUP "&File"
        BEGIN
            MENUITEM "&New\tCtrl+N",                IDM_FILE_NEW
            MENUITEM "&Open...\tCtrl+O",            IDM_FILE_OPEN
            MENUITEM "&Save\tCtrl+S",               IDM_FILE_SAVE
            MENUITEM "Save &As...",                 IDM_FILE_SAVE_AS
            MENUITEM SEPARATOR
            MENUITEM "&Print\tCtrl+P",              IDM_FILE_PRINT
            MENUITEM SEPARATOR
            MENUITEM "E&xit",                       IDM_APP_EXIT
        END
        POPUP "&Edit"
        BEGIN
            MENUITEM "&Undo\tCtrl+Z",               IDM_EDIT_UNDO
            MENUITEM SEPARATOR
            MENUITEM "Cu&t\tCtrl+X",                IDM_EDIT_CUT
            MENUITEM "&Copy\tCtrl+C",               IDM_EDIT_COPY
            MENUITEM "&Paste\tCtrl+V",              IDM_EDIT_PASTE
            MENUITEM "De&lete\tDel",                IDM_EDIT_CLEAR
            MENUITEM SEPARATOR
            MENUITEM "&Select All",                 IDM_EDIT_SELECT_ALL
        END
        POPUP "&Search"
        BEGIN
            MENUITEM "&Find...\tCtrl+F",            IDM_SEARCH_FIND
            MENUITEM "Find &Next\tF3",              IDM_SEARCH_NEXT
            MENUITEM "&Replace...\tCtrl+R",         IDM_SEARCH_REPLACE
        END
        POPUP "F&ormat"
        BEGIN
            MENUITEM "&Font...",                    IDM_FORMAT_FONT
            MENUITEM "Color...",                    IDM_FORMAT_COLOR
        END
        POPUP "&Help"
        BEGIN
            MENUITEM "&Help",                       IDM_HELP
            MENUITEM "&About PopPad...",            IDM_APP_ABOUT
        END
    END
    
    
    /
    //
    // Accelerator
    //
    
    POPPAD ACCELERATORS
    BEGIN
        VK_BACK,        IDM_EDIT_UNDO,          VIRTKEY, ALT, NOINVERT
        VK_DELETE,      IDM_EDIT_CLEAR,         VIRTKEY, NOINVERT
        VK_DELETE,      IDM_EDIT_CUT,           VIRTKEY, SHIFT, NOINVERT
        VK_F1,          IDM_HELP,               VIRTKEY, NOINVERT
        VK_F3,          IDM_SEARCH_NEXT,        VIRTKEY, NOINVERT
        VK_INSERT,      IDM_EDIT_COPY,          VIRTKEY, CONTROL, NOINVERT
        VK_INSERT,      IDM_EDIT_PASTE,         VIRTKEY, SHIFT, NOINVERT
        "^C",           IDM_EDIT_COPY,          ASCII,  NOINVERT
        "^F",           IDM_SEARCH_FIND,        ASCII,  NOINVERT
        "^N",           IDM_FILE_NEW,           ASCII,  NOINVERT
        "^O",           IDM_FILE_OPEN,          ASCII,  NOINVERT
        "^P",           IDM_FILE_PRINT,         ASCII,  NOINVERT
        "^R",           IDM_SEARCH_REPLACE,     ASCII,  NOINVERT
        "^S",           IDM_FILE_SAVE,          ASCII,  NOINVERT
        "^V",           IDM_EDIT_PASTE,         ASCII,  NOINVERT
        "^X",           IDM_EDIT_CUT,           ASCII,  NOINVERT
        "^Z",           IDM_EDIT_UNDO,          ASCII,  NOINVERT
    END
    
    
    /
    //
    // Icon
    //
    
    // Icon with lowest ID value placed first to ensure application icon
    // remains consistent on all systems.
    POPPAD                  ICON                    "poppad.ico"
    
    
    /
    //
    // DESIGNINFO
    //
    
    #ifdef APSTUDIO_INVOKED
    GUIDELINES DESIGNINFO
    BEGIN
        "ABOUTBOX", DIALOG
        BEGIN
            LEFTMARGIN, 7
            RIGHTMARGIN, 179
            TOPMARGIN, 7
            BOTTOMMARGIN, 88
        END
    
        "PRINTDLGBOX", DIALOG
        BEGIN
            LEFTMARGIN, 7
            RIGHTMARGIN, 179
            TOPMARGIN, 7
            BOTTOMMARGIN, 88
        END
    END
    #endif    // APSTUDIO_INVOKED
    
    #endif    // English (United States) resources
    /
    
    
    
    #ifndef APSTUDIO_INVOKED
    /
    //
    // Generated from the TEXTINCLUDE 3 resource.
    //
    
    
    /
    #endif    // not APSTUDIO_INVOKED
    
    


    resource.h

    //{{NO_DEPENDENCIES}}
    // Microsoft Visual C++ generated include file.
    // Used by POPPAD.RC
    //
    #define IDC_FILENAME                    1000
    #define IDM_FILE_NEW                    40001
    #define IDM_FILE_OPEN                   40002
    #define IDM_FILE_SAVE                   40003
    #define IDM_FILE_SAVE_AS                40004
    #define IDM_FILE_PRINT                  40005
    #define IDM_APP_EXIT                    40006
    #define IDM_EDIT_UNDO                   40007
    #define IDM_EDIT_CUT                    40008
    #define IDM_EDIT_COPY                   40009
    #define IDM_EDIT_PASTE                  40010
    #define IDM_EDIT_CLEAR                  40011
    #define IDM_EDIT_SELECT_ALL             40012
    #define IDM_SEARCH_FIND                 40013
    #define IDM_SEARCH_NEXT                 40014
    #define IDM_SEARCH_REPLACE              40015
    #define IDM_FORMAT_FONT                 40016
    #define IDM_HELP                        40017
    #define IDM_APP_ABOUT                   40018
    #define IDM_FORMAT_COLOR                40019
    
    // Next default values for new objects
    // 
    #ifdef APSTUDIO_INVOKED
    #ifndef APSTUDIO_READONLY_SYMBOLS
    #define _APS_NEXT_RESOURCE_VALUE        110
    #define _APS_NEXT_COMMAND_VALUE         40021
    #define _APS_NEXT_CONTROL_VALUE         1001
    #define _APS_NEXT_SYMED_VALUE           101
    #endif
    #endif
    



    运行结果


    可以改变和设置字体颜色




    11.3.2 Unicode 文件的读写操作

    在写入Unicode文件时先写入文件头  0xFEFF  表示此文本文件含有Unicode

    在读取时,使用IsTextUnicode函数来判断是否含有字节顺序标志,还会检测字节顺序标志是否反序的。 这意味此Unicode文本文件是在Macintosh或其他与Intel

    处理器字节顺序相反的机器上生成的。

    Unicode 转  ANSI

    WideCharToMultiChar

    WideCharToMultiByte(CP_ACP, 0, (PWSTR)pText, -1, pConv, iFileLength + 2, NULL, NULL);


    ANSI 转Unicode

    MultiByteToWideChar(CP_ACP, 0, (LPCCH)pText, -1, (PTSTR)pConv,iFileLength + 1);


    11.3.3 改变字体

    在处理WM_CREATE的时候,调用PopFontInitialize函数

    获取基于系统字体的LOGFONT结构,并由他创建一个字体,然后向编辑控件发送WM_SETFONT消息来设定新字体。

    GetObject(GetStockObject(SYSTEM_FONT), sizeof(LOGFONT),
    (PTSTR)&logfont);


    hFont = CreateFontIndirect(&logfont);
    SendMessage(hwndEdit, WM_SETFONT, (WPARAM)hFont, 0);

    当用户选择字体时

    会初始化CHOOSEFONT结构,然后调用ChooseFont来显示字体选择对话框,用户按下OK此函数会返回TRUE

    然后POPPAD调用PopFontSetFont函数为编辑控件设置新字体,旧字体会被删除。


    最后在WM_DESTROY时,POPPAD会调用PopFontDeinitialize函数来删除PopFontSetFont最后创建的字体


    11.3.4 查找和替换

    FindText 和ReplaceText  使用FINDREPLACE的结构

    在查找和替换函数时由一些需要注意的事项。

    1, 他们使用的对话框是非模态对话框,这意味着当对话框在使用时消息循环应该调用IsDialogMessage函数。

    2,传递给FindText和ReplaceText的FINDREPLACE结构必须是静态变量。

    3,在FindText和ReplaceText时,他们与拥有他们的对窗口通过一种特殊的消息进行通信。这个消息对应值可以通过messageFindReplace = RegisterWindowMessage(FINDMSGSTRING); 来获取。

    在处理默认消息时,WndProc比较messageFindReplace, 消息参数lParam是一个指向FINDREPLACE结构的指针,该结构的Flags表示用户是否已经在用对话框来查找或替换文本,或正在关闭该对话框。

    通过调用PopFindFindText和PopFindReplaceText函数来实现查找和替换文本的功能。


    11.3.5 只调用一个函数的Windows程序

    Color3

    #include <windows.h>
    #include <commdlg.h>
    
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    	PSTR szCmdLine, int iCmdShow)
    {
    	static CHOOSECOLOR cc;
    	static COLORREF crCustColors[16];
    
    	cc.lStructSize = sizeof(CHOOSECOLOR);
    	cc.hwndOwner = NULL;
    	cc.hInstance = NULL;
    	cc.rgbResult = RGB(0x80, 0x80, 0x80);
    	cc.lpCustColors = crCustColors;
    	cc.Flags = CC_RGBINIT | CC_FULLOPEN;
    	cc.lCustData = 0;
    	cc.lCustData = 0;
    	cc.lpfnHook = NULL;
    	cc.lpTemplateName = NULL;
    
    	return ChooseColor(&cc);
    }
    运行结果

    ChooseColor使用一个类型为 CHOOSECOLOR的结构和一个用来存储用户通过对话框选择的颜色含有16个DWORD值的数组。如果Flags字段
    设定CC_RGBINIT,那么rgbResult字段可以被初始化为锁要显示的颜色。一般情况下,rgbResult字段会被设置为用户选择的颜色。


    hwndOwnver 为NULL, 这是完全合法的。表示该对话框不属于任何窗口所有,会出现在windows任务列表中,并且对话框看上去和一般窗口狠相似。

    也可以在自己的程序对话框中使用这种技巧。Windows程序完全可以只创建一个对话框,并在该对话框过程中完成所有操作。

    展开全文
    sesiria 2016-07-31 16:40:26
  • 427KB weixin_38601103 2021-03-17 11:22:14
  • 要在Property中设置 Resizer属性才可以调整其大小 
    要在Property中设置 Resizer属性才可以调整其大小 
    展开全文
    lyzhm 2007-06-05 11:31:00
  • 很多时候,为了界面的美观,我们会隐藏标题栏,而在客户区通过自绘模拟标题栏。但是这样处理,会导致窗体无法移动。...因此可以大大减少我们的代码量。具体方法如下:响应鼠标左键按下消息WM_LBUTTONDOWN,相应函数中,

        很多时候,为了界面的美观,我们会隐藏标题栏,而在客户区通过自绘模拟标题栏。但是这样处理,会导致窗体无法移动。下面提供几种移动方法:

        1、采用欺骗的方式。即当鼠标点击客户区的时候,我们欺骗windows,让windows认为我们点击在了标题栏,这样,拖动过程就通过windows进行处理了。因此可以大大减少我们的代码量。具体方法如下:

    响应鼠标左键按下消息WM_LBUTTONDOWN,相应函数中,直接发送欺骗消息:

    PostMessage(WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(point.x, point.y));

        WM_NCLBUTTONDOWN即左键在非客户区按下,HTCAPTION即标题栏,所以采用这种方式,就可以实现无标题栏对话框的移动问题了。

        那么问题来了。。。

        采用这种操作后,会导致我们的对话框无法响应WM_LBUTTONUP消息,同时在我编写程序过程中发现WM_NCLBUTTONUP也一般不能响应。当然,可以通过注册WM_MOUSEHOVER以及WM_MOUSELEAVE消息,响应这两个消息去处理相应的代码,或者采用下钩子的方法,在钩子中正确发送消息,不过不推荐这种方法,实现也比较麻烦。

        所以下面提供第二种方法。

        2、在WM_MOUSEMOVE消息中,自己处理窗口移动。具体就是先判断鼠标左键是否处于按下,如果是的话,就获取鼠标移动到的位置,然后将窗口进行移动就可以了。具体实现如下:

    void CMyDlg::OnMouseMove(UINT nFlags, CPoint point)  
    {  
        static CPoint PrePoint = CPoint(0, 0);  
        if(MK_LBUTTON == nFlags)  
        {  
             if(point != PrePoint)  
             {  
                  CPoint ptTemp = point - PrePoint;  
                  CRect rcWindow;  
                  GetWindowRect(&rcWindow);  
                  rcWindow.OffsetRect(ptTemp.x, ptTemp.y);  
                  MoveWindow(&rcWindow);  
                  return ;  
             }  
         }  
        PrePoint = point;  
        CDialog::OnMouseMove(nFlags, point); 
    }

        通过上面的消息,就能够进行窗口移动了。然而,如果仅仅响应上面的消息发现两个问题:第一,当鼠标按住左键快速移动的时候,鼠标会移出窗口,窗口不动了,拖动效果不好;第二,左键释放消息在上面这种情况下没有响应。解决方法如下:

        首先左键按下消息中设置鼠标捕获

    SetCapture();

        在左键释放消息中释放鼠标捕获

    RealeseCapture();

        通过上面的处理,就可以完美拖动,同时,左键抬起的消息也不会受影响。


        因此,第一种方法较为简洁,适合不需要响应鼠标其它消息的情况;第二种方法相对麻烦一些,不过实现效果也很好,并且不影响其他消息。

    展开全文
    zjccsg 2016-07-16 20:01:04
  • weixin_33798152 2019-03-22 14:26:00
  • m372897500 2012-04-11 15:44:22
  • superxgl 2010-01-09 01:05:00
  • gnail_oug 2017-08-18 16:11:09
  • BjarneCpp 2019-08-22 16:17:13
  • qq_33176844 2020-08-05 15:18:05
  • Murphy_CoolCoder 2019-04-07 22:48:43
  • qq_18297675 2015-12-28 22:21:26
  • qq_26676945 2017-09-09 11:51:12
  • yue7603835 2011-08-03 23:19:46
  • u014139753 2020-12-24 09:36:12
  • zzh19811015 2012-08-28 11:34:34
  • l59565455 2020-03-12 01:15:35
  • lijunabc 2010-05-12 00:13:50
  • qq_42603841 2020-05-05 16:41:48
  • weixin_42438750 2021-01-30 15:06:09
  • qq_22642239 2016-03-25 20:09:36
  • qq_41786318 2018-06-01 17:10:12
  • qq_30901541 2021-05-17 21:06:08
  • 1.64MB m0_52957036 2020-03-24 02:01:02
  • dell17951 2018-09-28 14:56:47
  • qiuchangyong 2011-12-03 10:02:47
  • 33KB weixin_38662089 2021-03-17 12:58:23
  • u013678930 2015-11-16 17:04:53

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 71,116
精华内容 28,446
关键字:

windows7对话框可以移动吗