Programming Windows程式开发设计指南 第11章 对话方块

11. 对话方块 copyright dedecms

 

内容来自dedecms

如果有很多输入超出了功能表可以处理的程度,那么我们可以使用对话方块来取得输入资讯。程式写作者可以通过在某选项後面加上省略号()来表示该功能表项将启动一个对话方块。

织梦内容管理系统

对话方块的一般形式是包含多种子视窗控制项的弹出式视窗,这些控制项的大小和位置在程式资源描述档的「对话方块模板」中指定。虽然程式写作者能够「手工」定义对话方块模板,但是现在通常是在Visual C++ Developer Studio中以交谈式操作的方式设计的,然後由Developer Studio建立对话方块模板。 本文来自织梦

当程式呼叫依据模板建立的对话方块时,Microsoft Windows 98负责建立弹出式对话方块视窗和子视窗控制项,并提供处理对话方块讯息(包括所有键盘和滑鼠输入)的视窗讯息处理程式。有时候称呼完成这些功能的Windows内部程式码为「对话方块管理器」。 织梦好,好织梦

Windows的内部对话方块视窗讯息处理程式所处理的许多讯息也传递给您自己程式中的函式,这个函式即是所谓的「对话方块程序」或者「对话程序」。对话程序与普通的视窗讯息处理程式类似,但是也存在著一些重要区别。一般来说,除了在建立对话方块时初始化子视窗控制项,处理来自子视窗控制项的讯息以及结束对话方块之外,程式写作者不需要再给对话方块程序增加其他功能。对话程序通常不处理WM_PAINT讯息,也不直接处理键盘和滑鼠输入。

dedecms.com

对话方块这个主题的含义太广了,因为它还包含子视窗控制项的使用。不过,我们已经在第九章研究了子视窗控制项。当您在对话方块中使用子视窗控制项时,第九章所提到的许多工作都可以由Windows的对话方块管理器来完成。尤其是,在程式COLORS1中遇到在卷动列之间切换输入焦点的问题也不会在对话方块中出现。Windows会处理对话方块中的控制项之间切换输入焦点所必需完成的全部工作。 内容来自dedecms

不过,在程式中添加对话方块要比添加图示或者功能表更麻烦一些。我们将从一个简单的对话方块开始,让您对各部分之间的相互联系有所了解。 本文来自织梦

模态对话方块
 

copyright dedecms

对话方块分为两类:「模态的」和「非模态的」,其中模态对话方块最为普遍。当您的程式显示一个模态对话方块时,使用者不能在对话方块与同一个程式中的另一个视窗之间进行切换,使用者必须主动结束该对话方块,这藉由通过按一下「OK」或者「Cancel」键来完成。不过,在显示模态对话方块时,使用者通常可以从目前的程式切换到另一个程式。而有些对话方块(称为「系统模态」)甚至连这样的切换程式操作也不允许。在Windows中,显示了系统模态对话方块之後,要完成其他任何工作,都必须先结束该对话方块。

本文来自织梦

建立「About」对话方块
  本文来自织梦

Windows程式即使不需要接收使用者输入,也通常具有由功能表上的「About」选项启动的对话方块,该对话方块用来显示程式的名字、图示、版权旗标和标记为「OK」的按键,也许还会有其他资讯(例如技术支援的电话号码)。我们将要看到的第一个程式除了显示一个「About」对话方块外,别无它用。这个ABOUT1程式如程式11-1所示: copyright dedecms

 程式11-1  ABOUT1 

copyright dedecms

ABOUT1.C 

内容来自dedecms

/*------------------------------------------------------------------------ 内容来自dedecms 
        ABOUT1.C -- About Box Demo Program No. 1 

dedecms.com

                                              (c) Charles Petzold, 1998 
织梦内容管理系统
-------------------------------------------------------------------------*/ 内容来自dedecms 
  
织梦好,好织梦
#include <windows.h> 
织梦好,好织梦
#include "resource.h" 

织梦好,好织梦

  
织梦好,好织梦
LRESULT        CALLBACK WndProc                      (HWND, UINT, WPARAM, LPARAM) ; 内容来自dedecms 
BOOL                   CALLBACK AboutDlgProc          (HWND, UINT, WPARAM, LPARAM) ; 内容来自dedecms 
  织梦内容管理系统 
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, 

织梦好,好织梦

                                                             PSTR szCmdLine, int iCmdShow) 
织梦内容管理系统
{ 

本文来自织梦

        static TCHAR   szAppName[] = TEXT ("About1") ; 本文来自织梦 
        MSG                                   msg ; copyright dedecms 
        HWND                                  hwnd ; 织梦内容管理系统 
        WNDCLASS                              wndclass ; 
dedecms.com
         

dedecms.com

        wndclass.style                                = CS_HREDRAW | CS_VREDRAW ; 

织梦内容管理系统

        wndclass.lpfnWndProc                          = WndProc ; 

copyright dedecms

        wndclass.cbClsExtra                           = 0 ; copyright dedecms 
        wndclass.cbWndExtra                           = 0 ; 

dedecms.com

        wndclass.hInstance                            = hInstance ; 织梦内容管理系统 
        wndclass.hIcon                                = LoadIcon (hInstance, szAppName) ; copyright dedecms 
        wndclass.hCursor                              = LoadCursor (NULL, IDC_ARROW) ; dedecms.com 
        wndclass.hbrBackground                = (HBRUSH) GetStockObject (WHITE_BRUSH) ; 

织梦好,好织梦

        wndclass.lpszMenuName                 = szAppName ; 织梦好,好织梦 
        wndclass.lpszClassName                = szAppName ; 内容来自dedecms 
      dedecms.com 
        if (!RegisterClass (&wndclass)) 
织梦好,好织梦
        { 
织梦好,好织梦
                       MessageBox (NULL, TEXT ("This program requires Windows NT!"), 
dedecms.com
                szAppName, MB_ICONERROR) ; 内容来自dedecms 
                       return 0 ; 内容来自dedecms 
        } 织梦内容管理系统 
      

织梦好,好织梦

        hwnd = CreateWindow (  szAppName, TEXT ("About Box Demo Program"), 织梦内容管理系统 
                                      WS_OVERLAPPEDWINDOW, 织梦内容管理系统 
                                      CW_USEDEFAULT, CW_USEDEFAULT, 
copyright dedecms
                                       CW_USEDEFAULT, CW_USEDEFAULT, 织梦好,好织梦 
                                      NULL, NULL, hInstance, NULL) ; 
copyright dedecms
      copyright dedecms 
        ShowWindow (hwnd, iCmdShow) ; 
织梦好,好织梦
        UpdateWindow (hwnd) ;  织梦好,好织梦 
      
dedecms.com
        while (GetMessage (&msg, NULL, 0, 0)) 
织梦内容管理系统
        { 
织梦内容管理系统
                               TranslateMessage (&msg) ; 
织梦内容管理系统
                               DispatchMessage (&msg) ; 

织梦好,好织梦

        } dedecms.com 
        return msg.wParam ; dedecms.com 
} 

dedecms.com

  

织梦好,好织梦

LRESULT CALLBACK WndProc (     HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) 

织梦好,好织梦

{ 

copyright dedecms

        static HINSTANCE hInstance ; 
本文来自织梦
        switch (message) copyright dedecms 
        { 本文来自织梦 
        case    WM_CREATE : 
dedecms.com
                       hInstance = ((LPCREATESTRUCT) lParam)->hInstance ; 织梦好,好织梦 
                       return 0 ; 
织梦好,好织梦
           
织梦好,好织梦
        case    WM_COMMAND : copyright dedecms 
                       switch (LOWORD (wParam)) 

dedecms.com

                       { dedecms.com 
                       case IDM_APP_ABOUT : 
内容来自dedecms
                                      DialogBox (hInstance, TEXT ("AboutBox"), hwnd, AboutDlgProc) ; 
copyright dedecms
                                      break ; 
copyright dedecms
                       } 本文来自织梦 
                       return 0 ; dedecms.com 
           

本文来自织梦

        case    WM_DESTROY : 内容来自dedecms 
                       PostQuitMessage (0) ; dedecms.com 
                       return 0 ; 
内容来自dedecms
        } copyright dedecms 
        return DefWindowProc (hwnd, message, wParam, lParam) ; copyright dedecms 
} 

dedecms.com

  dedecms.com 
BOOL CALLBACK AboutDlgProc (HWND hDlg, UINT message,WPARAM wParam, LPARAM lParam) copyright dedecms 
{ dedecms.com 
        switch (message) 
织梦好,好织梦
        { 织梦好,好织梦 
        case    WM_INITDIALOG : 织梦好,好织梦 
                       return TRUE ; 内容来自dedecms 
           内容来自dedecms 
        case    WM_COMMAND : copyright dedecms 
                       switch (LOWORD (wParam)) 

织梦内容管理系统

                       { 

织梦好,好织梦

                       case    IDOK : 

内容来自dedecms

                       case    IDCANCEL : 
织梦内容管理系统
                                      EndDialog (hDlg, 0) ; 内容来自dedecms 
                                      return TRUE ; 本文来自织梦 
          } dedecms.com 
                       break ; 本文来自织梦 
     } 
copyright dedecms
        return FALSE ; 

织梦内容管理系统

} 织梦内容管理系统 
 ABOUT1.RC (摘录) 内容来自dedecms 
//Microsoft Developer Studio generated resource script. 本文来自织梦 
#include "resource.h" copyright dedecms 
#include "afxres.h" 

内容来自dedecms

  dedecms.com 
///////////////////////////////////////////////////////////////////////////// 织梦内容管理系统 
// Dialog dedecms.com 
ABOUTBOX DIALOG DISCARDABLE  32, 32, 180, 100 本文来自织梦 
STYLE DS_MODALFRAME | WS_POPUP 
织梦内容管理系统
FONT 8, "MS Sans Serif" copyright dedecms 
BEGIN 织梦好,好织梦 
        DEFPUSHBUTTON              "OK",IDOK,66,80,50,14 内容来自dedecms 
        ICON                                                          "ABOUT1",IDC_STATIC,7,7,21,20 
织梦好,好织梦
        CTEXT                                                         "About1",IDC_STATIC,40,12,100,8 内容来自dedecms 
        CTEXT                                 "About Box Demo Program",IDC_STATIC,7,40,166,8 
本文来自织梦
        CTEXT                                 "(c) Charles Petzold,  copyright dedecms 
1998",IDC_STATIC,7,52,166,8 

内容来自dedecms

END dedecms.com 
  
织梦好,好织梦
///////////////////////////////////////////////////////////////////////////// 织梦好,好织梦 
// Menu 

copyright dedecms

ABOUT1  MENU DISCARDABLE  
内容来自dedecms
BEGIN 

dedecms.com

        POPUP "&Help" 
内容来自dedecms
        BEGIN 
dedecms.com
                       MENUITEM "&About About1...",                                  IDM_APP_ABOUT 织梦内容管理系统 
        END 
织梦好,好织梦
END 织梦好,好织梦 
  dedecms.com 
///////////////////////////////////////////////////////////////////////////// 本文来自织梦 
// Icon 

copyright dedecms

ABOUT1         ICON    DISCARDABLE     "About1.ico" 

织梦好,好织梦

 RESOURCE.H (摘录) 
织梦内容管理系统
// Microsoft Developer Studio generated include file. 

dedecms.com

// Used by About1.rc 
内容来自dedecms
  
内容来自dedecms
#define IDM_APP_ABOUT        40001 
内容来自dedecms
#define IDC_STATIC              -1 
dedecms.com

 

织梦内容管理系统

ABOUT1.ICO 内容来自dedecms

 


 

内容来自dedecms

内容来自dedecms

藉由後面章节中介绍的方法,您还可以在程式中建立图示和功能表。图示和功能表的ID名均为「About1」。功能表有一个选项,它产生一条ID名为IDM_APP_ABOUTWM_COMMAND讯息。这使得程式显示的图11-1所示的对话方块。 copyright dedecms


 

copyright dedecms

copyright dedecms

  dedecms.com

11-1 程式ABOUT1的对话方块 织梦好,好织梦

 

对话方块及其模板
  织梦内容管理系统

要把一个对话方块添加到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。这表示对话方块相对於程式视窗显示区域左上角的显示位置待会会有关於对话方块座标的详细讨论)。 dedecms.com

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

dedecms.com

现在可以设计对话方块了。因为不需要 Cancel 按钮,所以先单击该按钮,然後按下键盘上的 Delete 键。接著单击 OK 按钮,将其移动到对话方块的底部。在Developer Studio视窗下面的工具列上有一个小点阵图,它可使控制项在视窗内水平居中对齐,请按下此钮。 织梦内容管理系统

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

内容来自dedecms

对於对话方块中的三个静态字串,可以从 Controls 工具列中选择 Static Text ,然後确定文字在对话方块中的位置。右键单击控制项,然後从功能表中选择 Properties 。在 Properties 框的 Caption 栏位中输入要显示的文字。选择 Styles 页面标签,从 Align Text 栏位选择 Center 织梦内容管理系统

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

内容来自dedecms

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

本文来自织梦

ABOUTBOX DIALOG DISCARDABLE  32, 32, 180, 100 
copyright dedecms
STYLE DS_MODALFRAME | WS_POPUP 

copyright dedecms

FONT 8, "MS Sans Serif" 织梦内容管理系统 
BEGIN 本文来自织梦 
        DEFPUSHBUTTON   "OK",IDOK,66,80,50,14 本文来自织梦 
        ICON                                                  "ABOUT1",IDC_STATIC,7,7,21,20 

dedecms.com

        CTEXT                                                 "About1",IDC_STATIC,40,12,100,8 copyright dedecms 
        CTEXT       "About Box Demo Program",IDC_STATIC,7,40,166,8 dedecms.com 
        CTEXT       "(c) Charles Petzold, 1998",IDC_STATIC,7,52,166,8 copyright dedecms 
END 织梦内容管理系统 

第一行给出了对话方块的名称(这里为ABOUTBOX)。如同其他资源,您也可以使用数字作为对话方块的名称。名称後面是关键字DIALOGDISCARDABLE以及四个数字。前两个数字是对话方块左上角的xy座标,该座标在程式呼叫对话方块时,是相对於父视窗显示区域的。後两个数字是对话方块的宽度和高度。 copyright dedecms

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

本文来自织梦

这样的座标系使得程式写作者可以使用座标和大小来大致勾勒对话方块的尺寸和外观,而不管视讯显示器的解析度是多少。由於系统字体字元的高度大致为其宽度的两倍,所以,x轴和y轴的量度差不多相等。

织梦内容管理系统

模板中的STYLE叙述类似於CreateWindow呼叫中的style栏位。对於模态对话方块,通常使用WS_POPUPDS_MODALFRAME,我们将在稍後介绍其他的选项。 内容来自dedecms

BEGINEND叙述(或者是左右大括弧,手工设计对话方块模板时,您可能会使用)之间,定义出现在对话方块中的子视窗控制项。这个对话方块使用了三种型态的子视窗控制项,它们分别是DEFPUSHBUTTON(内定按键)、ICON(图示)和CTEXT(文字居中)。这些叙述的格式为: 织梦内容管理系统

control-type "text" id, xPos, yPos, xWidth, yHeight, iStyle 
本文来自织梦

其中,後面的iStyle项是可选的,它使用Windows表头档案中定义的识别字来指定其他视窗样式。 织梦内容管理系统

DEFPUSHBUTTONICONCTEXT等识别字只可以在对话方块中使用,它们是某种特定视窗类别和视窗样式的缩写。例如,CTEXT指示这个子视窗控制项类别是「静态的」,其样式为:

copyright dedecms

WS_CHILD | SS_CENTER | WS_VISIBLE | WS_GROUP copyright dedecms 

虽然前面没有出现过WS_GROUP识别字,但是在第九章的COLORS1程式中已经出现过WS_CHILDSS_CENTERWS_VISIBLE视窗样式,我们在建立静态子视窗文字控制项时已经用到了它们。

织梦好,好织梦

对於图示,文字栏位是程式的图示资源名称,它也在ABOUT1资源描述档中定义。对於按键,文字栏位是出现在按键里的文字,这个文字相同於在程式中建立子视窗控制项时呼叫CreateWindow所指定的第二个参数。

本文来自织梦

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

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

织梦好,好织梦

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

内容来自dedecms

对话方块程序
 

dedecms.com

您程式内的对话方块程序处理传送给对话方块的讯息。尽管看起来很像是视窗讯息处理程式,但是它并不是真实的视窗讯息处理程式。对话方块的视窗讯息处理程式在Windows内部定义,这个视窗程序呼叫您编写的对话方块程序,把它所接收到的许多讯息作为参数。下面是ABOUT1的对话方块程序:

内容来自dedecms

BOOL    CALLBACK AboutDlgProc (HWND hDlg, UINT message,WPARAM wParam, LPARAM lParam) 织梦内容管理系统 
{ 

本文来自织梦

        switch (message) 

织梦好,好织梦

        { copyright dedecms 
        case    WM_INITDIALOG : 
本文来自织梦
                       return TRUE ; 
织梦好,好织梦
           

copyright dedecms

        case    WM_COMMAND : 

copyright dedecms

                       switch (LOWORD (wParam)) 
copyright dedecms
                       { 
内容来自dedecms
                       case    IDOK : 

织梦内容管理系统

                       case    IDCANCEL : 本文来自织梦 
                                      EndDialog (hDlg, 0) ; 
织梦好,好织梦
                                      return TRUE ; 
copyright dedecms
                       } 

dedecms.com

                       break ; 

copyright dedecms

        } 本文来自织梦 
        return FALSE ; 

dedecms.com

} 本文来自织梦 

该函式的参数与常规视窗讯息处理程式的参数相同,与视窗讯息处理程式类似,对话方块程序都必须定义为一个CALLBACKcallback)函式。尽管我使用了hDlg作为对话方块视窗的代号,但是您也可以按照您自己的意思使用hwnd。首先,让我们来看一下这个函式与视窗讯息处理程式的区别: 织梦内容管理系统

  • 视窗讯息处理程式传回一个LRESULT。对话方块传回一个BOOL,它在Windows表头档案中定义为int型态。
     
  • 如果视窗讯息处理程式不处理某个特定的讯息,那么它将呼叫DefWindowProc。如果对话方块程序处理一个讯息,那么它传回TRUE(非0),如果不处理,则传回FALSE0)。
     
  • 对话方块程序不需要处理WM_PAINTWM_DESTROY讯息。对话方块程序不接收WM_CREAT讯息,而是在特殊的WM_INITDIALOG讯息处理期间,对话方块程序执行初始化操作。
     

WM_INITDIALOG讯息是对话方块接收到的第一个讯息,这个讯息只发送给对话方块程序。如果对话方块程序传回TRUE,那么Windows将输入焦点设定给对话方块中第一个具有WS_TABSTOP样式(我们将在ABOUT2的讨论中加以解释)的子视窗控制项。在这个对话方块中,第一个具有WS_TABSTOP样式的子视窗控制项是按键。另外,对话方块程序也可以在处理WM_INITDIALOG时使用SetFocus来将输入焦点设定为对话方块中的某个子视窗控制项,然後传回FALSE

织梦好,好织梦

此外,对话方块程序只处理WM_COMMAND讯息。这是当按键被滑鼠点中,或者在按钮具有输入焦点的情况下按下空白键时,按键控制项发送给其父视窗的讯息。这个控制项的ID(我们在对话方块模板中将其设定为IDOK)在wParam的低字组中。对於这个讯息,对话方块程序呼叫EndDialog,它告诉Windows清除对话方块。对於所有其他讯息,对话方块程序传回FALSE,并告诉Windows内部的对话方块视窗讯息处理程式:我们的对话方块程序不处理这些讯息。 内容来自dedecms

模态对话方块的讯息不通过您程式的讯息伫列,所以不必担心对话方块中键盘加速键的影响。

织梦好,好织梦

启动对话方块
 

织梦内容管理系统

WndProc中处理WM_CREATE讯息时,ABOUT1取得程式的执行实体代号并将它放在静态变数中: dedecms.com

hInstance = ((LPCREATESTRUCT) lParam)->hInstance ; 

copyright dedecms

ABOUT1检查WM_COMMAND讯息,以确保讯息wParam的低位元字等於IDM_APP_ABOUT。当它获得这样一个讯息时,程式呼叫DialogBox

dedecms.com

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

织梦好,好织梦

该函式需要执行实体代号(在处理WM_CREATE时储存的)、对话方块名称(在资源描述档中定义的)、对话方块的父视窗(也是程式的主视窗)和对话方块程序的位址。如果您使用一个数字而不是对话方块模板名称,那么可以用MAKEINTRESOURCE巨集将它转换为一个字串。 织梦好,好织梦

从功能表中选择「About About1」,将显示图11-2所示的对话方块。您可以使用滑鼠单击「OK」按钮、按空白键或者按Enter键来结束这个对话方块。对任何包含内定按钮的对话方块,在按下Enter键或空白键之後,Windows发送一个WM_COMMAND讯息给对话方块,并令wParam的低字组等於内定按键的ID,此时的IDIDOK。按下Escape键也可以关闭对话方块,这时Windows将发送一个WM_COMMAND讯息,并令ID等於IDCANCEL

本文来自织梦

直到对话方块结束之後,用来显示对话方块的DialogBox才将控制权传回给WndProcDialogBox的传回值是对话方块程序内部呼叫的EndDialog函式的第二个参数(这个值未在ABOUT1中使用,但会在ABOUT2中使用)。然後,WndProc可以将控制权传回给Windows

dedecms.com

即使在显示对话方块时,WndProc也可以继续接收讯息。实际上,您可以从对话方块程序内部给WndProc发送讯息。ABOUT1的主视窗是弹出式对话方块视窗的父视窗,所以AboutDlgProc中的SendMessage呼叫可以使用如下叙述来开始:

dedecms.com

SendMessage (GetParent (hDlg),  . . . ) ; 织梦好,好织梦 

不同的主题
  织梦内容管理系统

虽然Visual C++ Developer Studio中的对话方块编辑器和其他资源编辑器,使我们几乎不用考虑资源描述的写作问题,但是学习一些资源描述的语法还是有用的。尤其对於对话方块模板来说,知道了语法,您就可以近一步了解对话方块的范围和限制。甚至当它不能满足您的需要时,您还可以自己建立一个对话方块模板(就像本章後面的HEXCALC程式)。资源编译器和资源描述语法的文件位於/Platform SDK/Windows Programming Guidelines/Platform SDK Tools/Compiling/Using the Resource Compilercopyright dedecms

Developer Studio的「Properties」对话方块中指定了对话方块的视窗样式,它翻译成对话方块模板中的STYLE叙述。对於ABOUT1,我们使用模态对话方块最常用的样式;

内容来自dedecms

STYLE WS_POPUP | DS_MODALFRAME 
内容来自dedecms

然而,您也可以尝试其他样式。有些对话方块有标题列,标题列用於指出对话方块的用途,并允许使用者通过滑鼠在显示幕上移动对话方块。此样式为WS_CAPTION。如果您使用WS_CAPTION,那么DIALOG叙述中所指定的x座标和y座标是对话方块显示区域的座标,并相对於父视窗显示区域的左上角。标题列将在y座标之上显示。

本文来自织梦

如果使用了标题列,那么您可以用CAPTION叙述将文字放入标题中。在对话方块模板中,CAPTION叙述在STYLE叙述的後面:

织梦内容管理系统

CAPTION "Dialog Box Caption" 
织梦内容管理系统

另外,在对话方块程序处理WM_INITDIALOG讯息处理期间,您还可以呼叫:

织梦内容管理系统

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

本文来自织梦

如果您使用WS_CAPTION样式,也可以添加一个WS_SYSMENU样式的系统功能表按钮。此样式允许使用者从系统功能表中选择 Move  Close 

dedecms.com

 Properties 对话方块的 Border 清单方块中选择 Resizing (相同於样式WS_THICKFRAME),允许使用者缩放对话方块,仅管此操作并不常用。如果您不介意更特殊一点的话,还可以著为此对话方块样式添加最大化方块。 织梦好,好织梦

您甚至可以给对话方块添加一个功能表。这时对话方块模板将包括下面的叙述: 本文来自织梦

MENU menu-name 织梦好,好织梦 

其参数不是功能表的名称,就是资源描述中的功能表号。模态对话方块很少使用功能表。如果使用了功能表,那么您必须确保功能表和对话方块控制项中的所有ID都是唯一的;或者不是唯一的,却表达了相同的命令。 内容来自dedecms

FONT叙述使您可以设定非系统字体,以供对话方块文字使用。这在过去的对话方块中不常用,但现在却非常普遍。事实上,在内定情况下,Developer Studio为您建立的每一个对话方块都选用8点的MS Sans Serif字体。一个Windows程式能把自己外观打点得非常与众不同,这只需为程式的对话方块及其他文字输出单独准备一种字体即可。

copyright dedecms

尽管对话方块视窗讯息处理程式通常位於Windows内部,但是您也可以使用自己编写的视窗讯息处理程式来处理对话方块讯息。要这样做,您必须在对话方块模板中指定一个视窗类别名: 内容来自dedecms

CLASS "class-name" 内容来自dedecms 

这种用法很少见,但是在本章後面所示的HEXCALC程式中我们将用到它。

本文来自织梦

当您使用对话方块模板的名称来呼叫DialogBox时,Windows通过呼叫普通的CreateWindow函式来完成建立弹出式视窗所需要完成的一切操作。Windows从对话方块模板中取得视窗的座标、大小、视窗样式、标题和功能表,从DialogBox的参数中获得执行实体代号和父视窗代号。它所需要的唯一其他资讯是一个视窗类别(假设对话方块模板不指定视窗类别的话)。Windows为对话方块注册一个专用的视窗类别,这个视窗类别的视窗讯息处理程式可以存取对话方块程序位址(该位址是您在DialogBox呼叫中指定的),所以它可以使程式获得该弹出式视窗所接收的讯息。当然,您可以通过自己建立弹出式视窗来建立和维护自己的对话方块。不过,使用DialogBox则更简单。

dedecms.com

也许您希望受益於Windows对话方块管理器,但不希望(或者能够)在资源描述中定义对话方块模板,也可能您希望程式在执行时可以动态地建立对话方块。这时可以完成这种功能的函式是DialogBoxIndirect,此函式用资料结构来定义模板。

织梦内容管理系统

ABOUT1.RC的对话方块模板中,我们使用缩写CTEXTICONDEFPUSHBUTTON来定义对话方块所需要的三种型态的子视窗控制项。您还可以使用其他型态,每种型态都隐含一个特定的预先定义视窗类别和一种视窗样式。下表显示了与一些控制项型态相同的视窗类别和视窗样式:

copyright dedecms

 

dedecms.com

11-1 本文来自织梦

 

控制项型态

copyright dedecms

视窗类别

织梦内容管理系统

视窗样式 dedecms.com

PUSHBUTTON

织梦内容管理系统

按钮

copyright dedecms

BS_PUSHBUTTON | WS_TABSTOP 织梦内容管理系统

DEFPUSHBUTTON

内容来自dedecms

按钮 copyright dedecms

BS_DEFPUSHBUTTON | WS_TABSTOP 织梦好,好织梦

CHECKBOX

本文来自织梦

按钮 copyright dedecms

BS_CHECKBOX | WS_TABSTOP

dedecms.com

RADIOBUTTON 内容来自dedecms

按钮 内容来自dedecms

BS_RADIOBUTTON | WS_TABSTOP 织梦好,好织梦

GROUPBOX

本文来自织梦

按钮 织梦好,好织梦

BS_GROUPBOX | WS_TABSTOP

dedecms.com

LTEXT

内容来自dedecms

静态文字 copyright dedecms

SS_LEFT | WS_GROUP 织梦好,好织梦

CTEXT

本文来自织梦

静态文字

本文来自织梦

SS_CENTER | WS_GROUP 织梦好,好织梦

RTEXT copyright dedecms

静态文字

织梦好,好织梦

SS_RIGHT | WS_GROUP 内容来自dedecms

ICON 织梦内容管理系统

静态图示 本文来自织梦

SS_ICON 织梦好,好织梦

EDITTEXT

dedecms.com

编辑 copyright dedecms

ES_LEFT | WS_BORDER | WS_TABSTOP

copyright dedecms

SCROLLBAR 织梦内容管理系统

卷动列 织梦好,好织梦

SBS_HORZ 织梦好,好织梦

LISTBOX 内容来自dedecms

清单方块 织梦好,好织梦

LBS_NOTIFY | WS_BORDER | WS_VSCROLL

copyright dedecms

COMBOBOX copyright dedecms

下拉式清单方块

本文来自织梦

CBS_SIMPLE | WS_TABSTOP

织梦内容管理系统

 

资源编译器是唯一能够识别这些缩写的程式。除了表中所示的视窗样式外,每个控制项还具有下面的样式:

织梦好,好织梦

WS_CHILD | WS_VISIBLE 
织梦内容管理系统

对於这些控制项型态,除了EDITTEXTSCROLLBARLISTBOXCOMBOBOX之外,控制项叙述的格式为: 织梦好,好织梦

control-type "text", id, xPos, yPos, xWidth, yHeight, iStyle 内容来自dedecms 

对於EDITTEXTSCROLLBARLISTBOXCOMBOBOX,其格式为: 织梦好,好织梦

control-type id, xPos, yPos, xWidth, yHeight, iStyle 
内容来自dedecms

其中没有文字栏位。在这两种叙述中,iStyle参数都是选择性的。 织梦内容管理系统

在第九章,我讨论了确定预先定义子视窗的宽度和高度的规则。您可能需要回到第九章去参考这些规则,这时请记住:对话方块模板中指定大小的单位为平均字元宽度的1/4,及平均字元高度的1/8

织梦内容管理系统

控制项叙述的 style 栏位是可选的。它允许您包含其他视窗样式识别字。例如,如果您想建立在正方形框左边包含文字的核取方块,那么可以使用: 本文来自织梦

CHECKBOX "text", id, xPos, yPos, xWidth, yHeight, BS_LEFTTEXT 
dedecms.com

注意,控制项型态EDITTEXT会自动添加一个边框。如果您想建立一个没有边框的子视窗编辑控制项,您可以使用: dedecms.com

EDITTEXT id, xPos, yPos, xWidth, yHeight, NOT WS_BORDER 内容来自dedecms 

资源编译器也承认与下面叙述类似的专用控制项叙述: copyright dedecms

CONTROL "text", id, "class", iStyle, xPos, yPos, xWidth, yHeight 织梦好,好织梦 

此叙述允许您通过指定视窗类别和完整的视窗样式,来建立任意型态的子视窗控制项。例如,要取代:

copyright dedecms

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

织梦好,好织梦

您可以使用: dedecms.com

CONTROL  "OK", IDOK, "button", WS_CHILD | WS_VISIBLE | 织梦内容管理系统 
                       BS_PUSHBUTTON | WS_TABSTOP, 10, 20, 32, 14 织梦好,好织梦 

当编译资源描述档时,这两条叙述在.RES.EXE档案中的编码是相同的。在Developer Studio中,您可以使用 Controls 工具列中的 Custom Control 选项来建立此叙述。在ABOUT3程式中,我向您展示了如何用此选项建立一个控制项,且在您的程式中已定义了该控制项的视窗类别。 copyright dedecms

当您在对话方块模板中使用CONTROL叙述时,不必包含WS_CHILDWS_VISIBLE样式。在建立子视窗时,Windows已经包含了这些视窗样式。CONTROL叙述的格式也说明Windows对话方块管理器在建立对话方块时就完成了此项操作。首先,就像我前面所讨论的,它建立一个弹出式视窗,其父视窗代号在DialogBox函式中提供。然後,对话方块管理器为对话方块模板中的每个控制项建立一个子视窗。所有这些控制项的父视窗均是这个弹出式对话方块。上面给出的CONTROL叙述被转换成一个CreateWindow呼叫,形式如下所示: 织梦好,好织梦

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

内容来自dedecms

                                              WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_PUSHBUTTON, 

内容来自dedecms

                                                     10 * cxChar / 4, 20 * cyChar / 8, 
dedecms.com
                                                     32 * cxChar / 4, 14 * cyChar / 8, copyright dedecms 
                                                     hDlg, IDOK, hInstance, NULL) ; 本文来自织梦 

其中,cxCharcyChar是系统字体字元的宽度和高度,以图素为单位。hDlg参数是从建立该对话方块视窗的CreateWindow呼叫传回的值;hInstance参数是从DialogBox呼叫获得的。

dedecms.com

更复杂的对话方块
  织梦好,好织梦

ABOUT1中的简单对话方块展示了设计和执行一个对话方块的要点,现在让我们来看一个稍微复杂的例子。程式11-2给出的ABOUT2程式展示了如何在对话方块程序中管理控制项(这里用单选按钮)以及如何在对话方块的显示区域中绘图。 dedecms.com

 程式11-2  ABOUT2 织梦内容管理系统 
ABOUT2.C copyright dedecms 
/*-------------------------------------------------------------------------- 
织梦好,好织梦
   ABOUT2.C -- About Box Demo Program No. 2 dedecms.com 
                                              (c) Charles Petzold, 1998 
内容来自dedecms
---------------------------------------------------------------------------*/ copyright dedecms 
  内容来自dedecms 
#include <windows.h> 

织梦内容管理系统

#include "resource.h" dedecms.com 
  
dedecms.com
LRESULT        CALLBACK WndProc                      (HWND, UINT, WPARAM, LPARAM) ; 
织梦好,好织梦
BOOL                   CALLBACK AboutDlgProc          (HWND, UINT, WPARAM, LPARAM) ; 
dedecms.com
      dedecms.com 
int     iCurrentColor          = IDC_BLACK, 

本文来自织梦

        iCurrentFigure         = IDC_RECT ; 
dedecms.com
  织梦内容管理系统 
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, 内容来自dedecms 
                                                     PSTR szCmdLine, int iCmdShow) 织梦内容管理系统 
{ 织梦好,好织梦 
        static TCHAR           szAppName[] = TEXT ("About2") ; 
本文来自织梦
        MSG                                           msg ; 内容来自dedecms 
        HWND                                          hwnd ; 

织梦好,好织梦

        WNDCLASS                              wndclass ; 

dedecms.com

      织梦好,好织梦 
        wndclass.style                                        = CS_HREDRAW | CS_VREDRAW ; 
本文来自织梦
        wndclass.lpfnWndProc                                  = WndProc ; 内容来自dedecms 
       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 ; 
内容来自dedecms
      

本文来自织梦

        if (!RegisterClass (&wndclass)) 
内容来自dedecms
        { 
本文来自织梦
                       MessageBox (   NULL, TEXT ("This program requires Windows NT!"), 内容来自dedecms 
                                      szAppName, MB_ICONERROR) ; 
dedecms.com
               return 0 ; 

织梦好,好织梦

     } 内容来自dedecms 
      

dedecms.com

        hwnd = CreateWindow (  szAppName, TEXT ("About Box Demo Program"), copyright dedecms 
                                      WS_OVERLAPPEDWINDOW, 内容来自dedecms 
                                      CW_USEDEFAULT, CW_USEDEFAULT, 织梦内容管理系统 
                                      CW_USEDEFAULT, CW_USEDEFAULT, 
dedecms.com
                                      NULL, NULL, hInstance, NULL) ;      copyright dedecms 
  copyright dedecms 
        ShowWindow (hwnd, iCmdShow) ; 

织梦好,好织梦

        UpdateWindow (hwnd) ;  内容来自dedecms 
      
dedecms.com
        while (GetMessage (&msg, NULL, 0, 0)) 

本文来自织梦

        { copyright dedecms 
                               TranslateMessage (&msg) ; dedecms.com 
                               DispatchMessage (&msg) ; 
dedecms.com
     } 
dedecms.com
        return msg.wParam ; copyright dedecms 
} 
copyright dedecms
  织梦内容管理系统 
void PaintWindow (HWND hwnd, int iColor, int iFigure) 织梦好,好织梦 
{ 
copyright dedecms
        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), 
dedecms.com
                        RGB (255, 255, 0), RGB (255, 255, 255)} ; 织梦好,好织梦 
  
内容来自dedecms
        HBRUSH                                        hBrush ; 织梦好,好织梦 
        HDC                                           hdc ; 内容来自dedecms 
        RECT                                          rect ; 
dedecms.com
      本文来自织梦 
        hdc = GetDC (hwnd) ; 
织梦好,好织梦
        GetClientRect (hwnd, &rect) ; dedecms.com 
        hBrush = CreateSolidBrush (crColor[iColor - IDC_BLACK]) ; 
copyright dedecms
        hBrush = (HBRUSH) SelectObject (hdc, hBrush) ; 

dedecms.com

      织梦内容管理系统 
        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)) ; dedecms.com 
        ReleaseDC (hwnd, hdc) ; 织梦好,好织梦 
} 
本文来自织梦
  本文来自织梦 
void PaintTheBlock (HWND hCtrl, int iColor, int iFigure) 
copyright dedecms
{ 织梦好,好织梦 
        InvalidateRect (hCtrl, NULL, TRUE) ; 

织梦内容管理系统

        UpdateWindow (hCtrl) ; 内容来自dedecms 
        PaintWindow (hCtrl, iColor, iFigure) ; 
copyright dedecms
} 织梦内容管理系统 
LRESULT CALLBACK WndProc (     HWND hwnd, UINT message, WPARAM wParam,LPARAM lParam) 

dedecms.com

{ 

织梦内容管理系统

        static HINSTANCE               hInstance ; dedecms.com 
        PAINTSTRUCT                           ps ; 织梦好,好织梦 
      

织梦内容管理系统

        switch (message) 织梦内容管理系统 
     { 

copyright dedecms

        case    WM_CREATE: 织梦内容管理系统 
                       hInstance = ((LPCREATESTRUCT) lParam)->hInstance ; dedecms.com 
                       return 0 ; 织梦内容管理系统 
           织梦好,好织梦 
        case    WM_COMMAND: 织梦内容管理系统 
                      switch (LOWORD (wParam)) 织梦好,好织梦 
                       { 织梦好,好织梦 
                       case IDM_APP_ABOUT: copyright dedecms 
                                      if (DialogBox (hInstance, TEXT ("AboutBox"), hwnd, AboutDlgProc)) 
copyright dedecms
                                                     InvalidateRect (hwnd, NULL, TRUE) ; 本文来自织梦 
                                      return 0 ; 织梦内容管理系统 
                       } 内容来自dedecms 
                       break ; 

dedecms.com

           织梦好,好织梦 
        case    WM_PAINT: copyright dedecms 
                       BeginPaint (hwnd, &ps) ; 
内容来自dedecms
                       EndPaint (hwnd, &ps) ; 

copyright dedecms

                织梦好,好织梦 
                       PaintWindow (hwnd, iCurrentColor, iCurrentFigure) ; 内容来自dedecms 
                       return 0 ; 织梦内容管理系统 
                

织梦好,好织梦

        case    WM_DESTROY: 
dedecms.com
                       PostQuitMessage (0) ; 

copyright dedecms

                       return 0 ; 

内容来自dedecms

        } 

本文来自织梦

        return DefWindowProc (hwnd, message, wParam, lParam) ; copyright dedecms 
} copyright dedecms 
  

copyright dedecms

BOOL CALLBACK AboutDlgProc (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) 本文来自织梦 
{ copyright dedecms 
        static HWND    hCtrlBlock ; 内容来自dedecms 
        static int             iColor, iFigure ; 

dedecms.com

      

织梦内容管理系统

        switch (message) dedecms.com 
        { dedecms.com 
        case    WM_INITDIALOG: 
dedecms.com
                       iColor                 = iCurrentColor ; 织梦好,好织梦 
                       iFigure                = iCurrentFigure ; 

内容来自dedecms

  
copyright dedecms
                       CheckRadioButton (hDlg, IDC_BLACK, IDC_WHITE,   iColor) ; 

本文来自织梦

                       CheckRadioButton (hDlg, IDC_RECT,  IDC_ELLIPSE, iFigure) ; 内容来自dedecms 
           本文来自织梦 
                       hCtrlBlock = GetDlgItem (hDlg, IDC_PAINT) ; 织梦好,好织梦 
           
dedecms.com
                       SetFocus (GetDlgItem (hDlg, iColor)) ; 
copyright dedecms
                       return FALSE ; copyright dedecms 
           

本文来自织梦

        case    WM_COMMAND: copyright dedecms 
                       switch (LOWORD (wParam)) 

内容来自dedecms

                       { 
织梦好,好织梦
                       case    IDOK: 

本文来自织梦

                                      iCurrentColor          = iColor ; 
dedecms.com
                                      iCurrentFigure         = iFigure ; 
织梦内容管理系统
                                      EndDialog (hDlg, TRUE) ; 内容来自dedecms 
                                      return TRUE ; 本文来自织梦 
                

copyright dedecms

                       case    IDCANCEL: 

织梦内容管理系统

                                      EndDialog (hDlg, FALSE) ; dedecms.com 
                                      return TRUE ; 
dedecms.com
                本文来自织梦 
                       case    IDC_BLACK: dedecms.com 
                       case    IDC_RED: 

copyright dedecms

                       case    IDC_GREEN: 

织梦好,好织梦

                       case    IDC_YELLOW: 织梦内容管理系统 
                       case    IDC_BLUE: 
copyright dedecms
                       case    IDC_MAGENTA: 本文来自织梦 
                       case    IDC_CYAN: 内容来自dedecms 
                       case    IDC_WHITE: 
织梦内容管理系统
                                      iColor = LOWORD (wParam) ; copyright dedecms 
                                      CheckRadioButton (hDlg, IDC_BLACK, IDC_WHITE, LOWORD (wParam)) ; dedecms.com 
                                      PaintTheBlock (hCtrlBlock, iColor, iFigure) ; dedecms.com 
                                      return TRUE ; copyright dedecms 
                

织梦好,好织梦

                       case    IDC_RECT: 
dedecms.com
                       case    IDC_ELLIPSE: 
织梦内容管理系统
                                      iFigure = LOWORD (wParam) ; 内容来自dedecms 
                                      CheckRadioButton (hDlg, IDC_RECT, IDC_ELLIPSE, LOWORD (wParam)) ; 内容来自dedecms 
                                      PaintTheBlock (hCtrlBlock, iColor, iFigure) ; 
本文来自织梦
                                      return TRUE ; copyright dedecms 
                       } 
织梦内容管理系统
                       break ; 
内容来自dedecms
           
本文来自织梦
        case    WM_PAINT: 
copyright dedecms
                       PaintTheBlock (hCtrlBlock, iColor, iFigure) ; 
dedecms.com
                       break ; 

织梦好,好织梦

        } 织梦好,好织梦 
        return FALSE ; 内容来自dedecms 
} 
内容来自dedecms
 ABOUT2.RC (摘录) 

织梦内容管理系统

//Microsoft Developer Studio generated resource script. 
copyright dedecms
#include "resource.h" copyright dedecms 
#include "afxres.h" 内容来自dedecms 
  本文来自织梦 
///////////////////////////////////////////////////////////////////////////// 
本文来自织梦
// Dialog 

本文来自织梦

ABOUTBOX DIALOG DISCARDABLE  32, 32, 200, 234 织梦内容管理系统 
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION 本文来自织梦 
FONT 8, "MS Sans Serif" dedecms.com 
BEGIN 内容来自dedecms 
        ICON                                                          "ABOUT2",IDC_STATIC,7,7,20,20 
织梦内容管理系统
        CTEXT         "About2",IDC_STATIC,57,12,86,8 dedecms.com 
        CTEXT         "About Box Demo Program",IDC_STATIC,7,40,186,8 copyright dedecms 
        LTEXT         "",IDC_PAINT,114,67,74,72 内容来自dedecms 
        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 
内容来自dedecms
        RADIOBUTTON            "&Green",IDC_GREEN,16,108,64,8 织梦内容管理系统 
        RADIOBUTTON            "Cya&n",IDC_CYAN,16,124,64,8 copyright dedecms 
        RADIOBUTTON            "&Red",IDC_RED,16,140,64,8 
内容来自dedecms
        RADIOBUTTON            "&Magenta",IDC_MAGENTA,16,156,64,8 织梦好,好织梦 
        RADIOBUTTON            "&Yellow",IDC_YELLOW,16,172,64,8 织梦好,好织梦 
        RADIOBUTTON            "&White",IDC_WHITE,16,188,64,8 内容来自dedecms 
       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 
内容来自dedecms
        PUSHBUTTON                                    "Cancel",IDCANCEL,113,212,50,14,WS_GROUP 
内容来自dedecms
END dedecms.com 
  dedecms.com 
///////////////////////////////////////////////////////////////////////////// 
copyright dedecms
// Icon 

本文来自织梦

ABOUT2        ICON       DISCARDABLE         "About2.ico" 内容来自dedecms 
  
dedecms.com
///////////////////////////////////////////////////////////////////////////// 本文来自织梦 
// Menu 

织梦内容管理系统

ABOUT2 MENU DISCARDABLE  织梦内容管理系统 
BEGIN 

copyright dedecms

        POPUP "&Help" 
内容来自dedecms
        BEGIN 
织梦好,好织梦
                       MENUITEM "&About",                    IDM_APP_ABOUT dedecms.com 
        END 

dedecms.com

END 

织梦好,好织梦

 RESOURCE.H (摘录) 

织梦内容管理系统

// Microsoft Developer Studio generated include file. 
copyright dedecms
// Used by About2.rc dedecms.com 
  

dedecms.com

#define IDC_BLACK           1000 织梦好,好织梦 
#define IDC_BLUE            1001 
织梦内容管理系统
#define IDC_GREEN           1002 织梦好,好织梦 
#define IDC_CYAN            1003 

dedecms.com

#define IDC_RED             1004 copyright dedecms 
#define IDC_MAGENTA         1005 

copyright dedecms

#define IDC_YELLOW          1006 

织梦内容管理系统

#define IDC_WHITE           1007 本文来自织梦 
#define IDC_RECT            1008 

copyright dedecms

#define IDC_ELLIPSE         1009 

copyright dedecms

#define IDC_PAINT           1010 
copyright dedecms
#define IDM_APP_ABOUT       40001 dedecms.com 
#define IDC_STATIC          -1 织梦好,好织梦 

 

copyright dedecms

ABOUT2.ICO

dedecms.com


 

dedecms.com

ABOUT2中的About框有两组单选按钮。一组用来选择颜色,另一组用来选择是矩形还是椭圆形。所选的矩形或者椭圆显示在对话方块内,其内部以目前选择的颜色著色。使用者按下「OK」按钮後,对话方块会终止,程式的视窗讯息处理程式在它自己的显示区域内绘出所选图形。如果您按下「Cancel」,则主视窗的显示区域会保持原样。对话方块如图11-2所示。尽管ABOUT2使用预先定义的识别字IDOKIDCANCEL作为两个按键,但是每个单选按钮均有自己的识别字,它们以字首IDC开头(用於控制项的ID)。这些识别字在RESOURCE.H中定义。 copyright dedecms


 

内容来自dedecms

织梦内容管理系统

 

内容来自dedecms

11-2 ABOUT2程式的对话方块

织梦好,好织梦

 

当您在ABOUT2对话方块中建立单选按钮时,请按显示顺序建立。这能保证Developer Studio依照顺序定义识别字的值,程式将使用这些值。另外,每个单选按钮都不要选中「Auto」选项。「Auto Radio Button」需要的程式码较少,但基本上处理起来更深奥些。然後请依照ABOUT2.RC中的定义来设定它们的识别字。

织梦好,好织梦

选中「Properties」对话方块中下列物件的「Group」选项:「OK」和「Cancel」按钮、「Figure」分组方块、每个分组方块中的第一个单选按钮(「Black」和「Rectangle」)。选中这两个单选按钮的「Tab Stop」核取方块。 织梦好,好织梦

当您有全部控制项在对话方块中的近似位置和大小时,就可以从「Layout」功能表选择「Tab Order」选项。按ABOUT2.RC资源描述中显示的顺序单击每一个控制项。

内容来自dedecms

使用对话方块控制项
 

织梦内容管理系统

在第九章中,您会发现大多数子视窗控制项发送WM_COMMAND讯息给其父视窗(唯一例外的是卷动列控制项)。您还看到,经由发送讯息给子视窗控制项,父视窗可以改变子视窗控制项的状态(例如,选择或不选择单选按钮、核取方块)。您也可以用类似方法在对话方块程序中改变控制项。例如,如果您设计了一系列单选按钮,就可以发送讯息给它们,以选择或者不选择这些按钮。不过,Windows也提供了几种使用对话方块控制项的简单办法。我们来看一看对话方块程序与子视窗控制项相互通信的方式。

织梦好,好织梦

ABOUT2的对话方块模板显示在程式11-2ABOUT2.RC资源描述档中。GROUPBOX控制项只是一个带标题(标题为「Color」或者「Figure」)的分组方块,每组单选按钮都由这样的分组方块包围。前一组的八个单选按钮是互斥的,第二组的两个单选按钮也是如此。

内容来自dedecms

当用滑鼠单击其中一个单选按钮时(或者当单选按钮拥有输入焦点时按空白键),子视窗向其父视窗发送一个WM_COMMAND讯息,讯息的wParam的低字组被设为控制项的IDwParam的高字组是一个通知码,lParam值是控制项的视窗代号。对於单选按钮,这个通知码是BN_CLICKED或者0。然後Windows中的对话方块视窗讯息处理程式将这个WM_COMMAND讯息发送给ABOUT2.C内的对话方块程序。当对话方块程序收到一个单选按钮的WM_COMMAND讯息时,它为此按钮设定选中标记,并为组中其他按钮清除选中标记。

织梦内容管理系统

您可能还记得在第九章中已经提过,选中和不选中按钮均需要向子视窗控制项发送BM_CHECK讯息。要设定一个按钮选中标记,您可以使用: 织梦好,好织梦

SendMessage (hwndCtrl, BM_SETCHECK, 1, 0) ; 内容来自dedecms 

要消除选中标记,您可以使用:

dedecms.com

SendMessage (hwndCtrl, BM_SETCHECK, 0, 0) ; 内容来自dedecms 

其中hwndCtrl参数是子视窗按钮控制项的视窗代号。 内容来自dedecms

但是在对话方块程序中使用这种方法是时有点问题的,因为您不知道所有单选按钮的视窗代号,只是从您获得的讯息中知道其中一个代号。幸运的是,Windows为您提供了一个函式,可以用对话方块代号和控制项ID来取得一个对话方块控制项的视窗代号: copyright dedecms

hwndCtrl = GetDlgItem (hDlg, id) ; dedecms.com 

(您也可以使用如下函式,从视窗代号中取得控制项的ID值:

本文来自织梦

id = GetWindowLong (hwndCtrl, GWL_ID) ; 本文来自织梦 

但是在大多数情况下这是不必要的。) 织梦内容管理系统

您会注意到,在程式11-2所示的表头档案ABOUT2.H中,八种颜色的ID值是从IDC_BLACKIDC_WHITE连续变化的,这种安排在处理来自单选按钮的WM_COMMAND讯息时将会很有用。在第一次尝试选中或者不选中单选按钮时,您可能会在对话方块程序中编写如下的程式: 本文来自织梦

static int iColor ; copyright dedecms 
其他行程式 
内容来自dedecms
case    WM_COMMAND: 
dedecms.com
        switch (LOWORD (wParam)) 织梦好,好织梦 
        { 

copyright dedecms

        其他行程式 
织梦好,好织梦
        case    IDC_BLACK: 内容来自dedecms 
        case    IDC_RED: copyright dedecms 
        case    IDC_GREEN: 

内容来自dedecms

        case    IDC_YELLOW: 织梦好,好织梦 
        case    IDC_BLUE: 

dedecms.com

        case    IDC_MAGENTA: 

内容来自dedecms

        case    IDC_CYAN: 
dedecms.com
        case    IDC_WHITE: 
织梦好,好织梦
                       iColor = LOWORD (wParam) ; 
织梦好,好织梦
 

织梦好,好织梦

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

本文来自织梦

                                      SendMessage (GetDlgItem (hDlg, i), 

copyright dedecms

                            BM_SETCHECK, i == LOWORD (wParam), 0) ; 本文来自织梦 
                       return TRUE ; dedecms.com 
    其他行程式 本文来自织梦 

这种方法能让人满意地执行。您将新的颜色值储存在iColor中,并且还建立了一个回圈,轮流使用所有八种颜色的ID值。您取得每个单选按钮控制项的视窗代号,并用SendMessage给每个代号发送一条BM_SETCHECK讯息。只有对於向对话方块视窗讯息处理程式发送WM_COMMAND讯息的按钮,这个讯息的wParam值才被设定为1dedecms.com

第一种简化的方法是使用专门的对话方块程序SendDlgItemMessagecopyright dedecms

SendDlgItemMessage (hDlg, id, iMsg, wParam, lParam) ; 
织梦内容管理系统

它相同於:

copyright dedecms

SendMessage (GetDlgItem (hDlg, id), id, wParam, lParam) ; 

织梦内容管理系统

现在,回圈将变成这样: dedecms.com

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

织梦好,好织梦

     SendDlgItemMessage (hDlg, i, BM_SETCHECK, i == LWORD (wParam), 0) ; 织梦好,好织梦 

稍微有些改进。但是真正的重大突破要等到使用了CheckRadioButton函式时才会出现: dedecms.com

CheckRadioButton (hDlg, idFirst, idLast, idCheck) ; 
织梦内容管理系统

这个函式将IDidFirstidLast之间的所有单选按钮的选中标记都清除掉,除了IDidCheck的单选按钮,因为它是被选中的。这里,所有ID必须是连续的。从此我们可以完全摆脱回圈,并使用: copyright dedecms

CheckRadioButton (hDlg, IDC_BLACK, IDC_WHITE, LOWORD (wParam)) ; 内容来自dedecms 

这正是ABOUT2对话方块程序所采用的方法。

内容来自dedecms

在使用核取方块时,也提供了类似的简化函式。如果您建立了一个「CHECKBOX」对话方块视窗控制项,那么可以使用如下的函式来设定和清除选中标记: dedecms.com

CheckDlgButton (hDlg, idCheckbox, iCheck) ; copyright dedecms 

如果iCheck设定为1,那么按钮被选中;如果设定为0,那么按钮不被选中。您可以使用如下的方法来取得对话方块中某个核取方块的状态:

dedecms.com

iCheck = IsDlgButtonChecked (hDlg, idCheckbox) ; 

dedecms.com

在对话方块程序中,您既可以将选中标记的目前状态储存在一个静态变数中,又可以在收到一个WM_COMMAND讯息後,使用如下方法触发按钮: 织梦内容管理系统

CheckDlgButton (hDlg, idCheckbox, 
织梦好,好织梦
     !IsDlgButtonChecked (hDlg, idCheckbox)) ; 
dedecms.com

如果您定义了BS_AUTOCHECKBOX控制项,那么完全没有必要处理WM_COMMAND讯息。在终止对话方块之前,您只要使用IsDlgButtonChecked就可以取得按钮目前的状态。不过,如果您使用BS_AUTORADIOBUTTON样式,那么IsDlgButtonChecked就不能令人满意了,因为需要为每个单选按钮都呼叫它,直到函式传回TRUE。实际上,您还要拦截WM_COMMAND讯息来追踪按下的按钮。

织梦好,好织梦

OK」和「Cancel」按钮
 

织梦好,好织梦

ABOUT2有两个按键,分别标记为「OK」和「Cancel」。在ABOUT2.RC的对话方块模板中,「OK」按钮的ID值为IDOK(在WINUSER.H中被定义为1),「Cancel」按钮的ID值为IDCANCEL(定义为2),「OK」按钮是内定的:

织梦好,好织梦

DEFPUSHBUTTON          "OK",IDOK,35,212,50,14 织梦内容管理系统 
        PUSHBUTTON                     "Cancel",IDCANCEL,113,212,50,14 
copyright dedecms

在对话方块中,通常都这样安排「OK」和「Cancel」按钮:将「OK」按钮作为内定按钮有助於用键盘介面终止对话。一般情况下,您通过单击两个滑鼠按键之一,或者当所期望的按钮具有输入焦点时按下Spacebar来终止对话方块。不过,如果使用者按下Enter,对话方块视窗讯息处理程式也将产生一个WM_COMMAND讯息,而不管哪个控制项具有输入焦点。wParam的低字组被设定为对话方块中内定按键的ID值,除非另一个按键拥有输入焦点。在後一种情况下,wParam的低字组被设定为具有输入焦点之按键的ID值。如果对话方块中没有内定按键,那么Windows向对话方块程序发送一个WM_COMMAND讯息,讯息中wParam的低字组被设定为IDOK。如果使用者按下Esc键或者Ctrl-Break键,那么WindowswParam等於IDCANCEL,并给对话方块程序发送一个WM_COMMAND讯息。所以,您不用在对话方块程序中加入单独的处理键盘操作,因为通常终止对话方块的按键会由Windows将这两个按键动作转换为WM_COMMAND讯息。 织梦好,好织梦

AboutDlgProc函式通过呼叫EndDialog来处理这两种WM_COMMAND讯息: 内容来自dedecms

switch (LWORD (wParam)) 内容来自dedecms 
{ 织梦内容管理系统 
case IDOK: 织梦内容管理系统 
     iCurrentColor  = iColor ; dedecms.com 
     iCurrentFigure = iFigure ; 

copyright dedecms

     EndDialog (hDlg, TRUE) ; 织梦好,好织梦 
     return TRUE ; 
本文来自织梦
  
织梦内容管理系统
case IDCANCEL : 

内容来自dedecms

     EndDialog (hDlg, FALSE) ; 织梦内容管理系统 
     return TRUE ; copyright dedecms 

ABOUT2的视窗讯息处理程式在程式的显示区域中绘制矩形或椭圆时,使用了整体变数iCurrentColoriCurrentFigureAboutDlgProc在对话方块中画图时使用了静态区域变数iColoriFigure

copyright dedecms

注意EndDialog的第二个参数的值不同,这个值是在WndProc中作为原DialogBox函式的传回值传回的:

copyright dedecms

case    IDM_ABOUT: 本文来自织梦 
        if (DialogBox (hInstance, TEXT ("AboutBox"), hwnd, AboutDlgProc)) 

织梦内容管理系统

                       InvalidateRect (hwnd, NULL, TRUE) ; 
内容来自dedecms
        return 0 ; 
织梦好,好织梦

如果DialogBox传回TRUE(非0),则意味著按下了「OK」按钮,然後需要使用新的颜色来更新WndProc显示区域。当AboutDlgProc收到一个WM_COMMAND讯息并且讯息的wParam的低字组等於IDOK时,AboutDlgProc将图形和颜色储存在整体变数iCurrentColoriCurrentFigure中。如果DialogBox传回FALSE,则主视窗继续使用iCurrentColoriCurrentFigure的原始设定。 本文来自织梦

TRUEFALSE通常用於EndDialog呼叫中,以告知主视窗讯息处理程式使用者是用「OK」还是用「Cancel」来终止对话方块的。不过,EndDialog的参数实际上是一个int值,而DialogBox也传回一个int值。所以,用这种方法能比仅用TRUE或者FALSE传回更多的资讯。

dedecms.com

避免使用整体变数
  copyright dedecms

ABOUT2中使用整体变数可能会、也可能不会影响您。一些程式写作者(包括我自己)较喜欢少用整体变数。ABOUT2中的整体变数iCurrentColoriCurrentFigure看来使用得完全合法,因为它们必须同时在视窗讯息处理程式和对话方块程序中使用。不过,在一个有一大堆对话方块的程式中,每个对话方块都可能改变一堆变数的值,使整体变数的数量容易用得过多。 织梦内容管理系统

您可能更喜欢将程式中的对话方块与资料结构相联系,该资料结构含有对话方块可以改变的所有变数。您将在typedef叙述中定义这些结构。例如,在ABOUT2中,可以定义与「About」方块相联系的结构:

dedecms.com

typedef struct dedecms.com 
{ 织梦好,好织梦 
        int iColor, iFigure ; 

copyright dedecms

} 织梦内容管理系统 
ABOUTBOX_DATA ; 织梦好,好织梦 

WndProc中,您可以依据此结构来定义并初始化一个静态变数: copyright dedecms

static ABOUTBOX_DATA ad = { IDC_BLACK, IDC_RECT } ; 

织梦内容管理系统

WndProc中也是这样,用ad.iColorad.iFigure替换了所有的iCurrentColoriCurrentFigure。呼叫对话方块时,使用DialogBoxParam而不用DialogBox。此函式的第五个参数可以是任意的32位元值。一般来说,此值设定为指向一个结构的指标,在这里是WndProc中的ABOUTBOX_DATA结构。

本文来自织梦

case    IDM_ABOUT: 内容来自dedecms 
        if (DialogBoxParam (hInstance, TEXT ("AboutBox"),  内容来自dedecms 
                         hwnd, AboutDlgProc, &ad)) 本文来自织梦 
                       InvalidateRect (hwnd, NULL, TRUE) ; 

dedecms.com

        return 0 ; 织梦内容管理系统 

这是关键:DialogBoxParam的最後一个参数是作为WM_INITDIALOG讯息中的lParam传递给对话方块程序的。 内容来自dedecms

对话方块程序有两个ABOUTBOX_DATA结构型态的静态变数(一个结构和一个指向结构的指标): dedecms.com

static ABOUTBOX_DATA ad, * pad ; dedecms.com 

AboutDlgProc中,此定义代替了iColoriFigure的定义。在WM_INITDIALOG讯息的开始部分,对话方块程序根据lParam设定了这两个变数的值: 内容来自dedecms

pad = (ABOUTBOX_DATA *) lParam ; 本文来自织梦 
ad = * pad ; 
本文来自织梦

第一道叙述中,pad设定为lParam的指标。亦即,pad实际是指向在WndProc定义的ABOUTBOX_DATA结构。第二个参数完成了从WndProc中的结构,到DlgProc中的区域结构的栏位对栏位内容复制。

copyright dedecms

现在,除了使用者按下「OK」按钮时所用的程式码以之外,所有的AboutDlgProc都用ad.iColorad.iFigure替换了iFigureiColor。这时,将区域结构的内容复制回WndProc中的结构: copyright dedecms

case    IDOK: 

copyright dedecms

        * pad = ad ; dedecms.com 
        EndDialog (hDlg, TRUE) ; copyright dedecms 
        return TRUE ; 本文来自织梦 

Tab停留和分组
  织梦内容管理系统

在第九章,我们利用视窗子类别化为COLORS1增加功能,使我们能够按下Tab键从一个卷动列转移到另一个卷动列。在对话方块中,视窗子类别化是不必要的,因为Windows完成了将输入焦点从一个控制项移动到另一个控制项的所有工作。尽管如此,您必须在对话方块模板中使用WS_TABSTOPWS_GROUP视窗样式达到此目的。对於所有想要使用Tab键存取的控制项,都要在其视窗样式中指定WS_TABSTOP本文来自织梦

如果参阅表11-1,您就会注意到许多控制项将WS_TABSTOP定义为内定样式,其他一些则没有将它作为内定样式。一般而言,不包含WS_TABSTOP样式的控制项(特别是静态控制项)不应该取得输入焦点,因为即使有了输入焦点,它们也不能完成操作。除非在处理WM_INITDIALOG讯息时您将输入焦点设定给一个特定的控制项,并从讯息中传回FALSE。否则Windows将输入焦点设定为对话方块内第一个具有WS_TABSTOP样式的控制项。

织梦内容管理系统

Windows给对话方块增加的第二个键盘介面包括游标移动键,这种介面对於单选按钮有特殊的重要性。如果您使用Tab键移动到某一组内目前选中的单选按钮,那么,就需要使用游标移动键,将输入焦点从该单选按钮移动到组内其他单选按钮上。使用WS_GROUP视窗样式即可获得这个功能。对於对话方块模板中的特定控制项序列,Windows将使用游标移动键把输入焦点从第一个具有WS_GROUP样式的控制权切换到下一个具有WS_GROUP样式的控制项中。如果有必要,Windows将从对话方块的最後一个控制项回圈到第一个控制项,以便找到分组的结尾。 内容来自dedecms

在内定设定下,控制项LTEXTCTEXTRTEXTICON包含有WS_GROUP样式,这种样式方便地标记了分组的结尾。您必须经常将WS_GROUP样式加到其他型态的控制项中。 内容来自dedecms

让我们来看一看ABOUT2.RC中的对话方块模板。四个具有WS_TABSTOP样式的控制项是每个组的第一个单选按钮(明显地包含)和两个按键(内定设定)。在第一次启动对话方块时,您可以使用Tab键在这四个控制项之间移动。 织梦好,好织梦

在每组单选按钮中,您可以使用游标移动键切换输入焦点并改变选中标记。例如, Color 下拉式清单方块的第一个单选按钮( Black )和 Figure 下拉式清单方块都具有WS_GROUP样式。这意味著您可以用游标移动键将焦点从「Black」单选按钮移动到 Figure 分组方块中。类似的情形, Figure 分组方块的第一个单选按钮( Rectangle )和DEFPUSHBUTTON都具有WS_GROUP样式,所以您可以使用游标移动键在组内两个单选按钮- Rectangle  Ellipse 之间移动。两个按键都有WS_GROUP样式,以阻止游标移动键在按键具有输入焦点时起作用。 dedecms.com

使用ABOUT2时,Windows的对话方块管理器在两组单选按钮中完成一些相当复杂的处理。正如所预期的那样,处於单选按钮组内时,游标移动键切换输入焦点,并给对话方块程序发送WM_COMMAND讯息。但是,当您改变了组内选中的单选按钮时,Windows也给新选中的单选按钮设定了WS_TABSTOP样式。当您下一次使用Tab切换到这一组後,Windows将会把输入焦点设定为选中的单选按钮。

dedecms.com

文字栏位中的「&」将导致紧跟其後的字母以底线显示,这就增加了另一种键盘介面,您可以通过按底线字母来将输入焦点移动到任意单选按钮上。透过按下C(代表 Color 下拉式清单方块)或者F(代表 Figure 下拉式清单方块),您可以将输入焦点移动到相对应组内目前选中的单选按钮上。

织梦好,好织梦

尽管程式写作者通常让对话方块管理器来完成这些工作,但是Windows提供了两个函式,以便程式写作者找寻下一个或者前一个Tab键停留项或者组项。这些函式为: 内容来自dedecms

hwndCtrl = GetNextDlgTabItem (hDlg, hwndCtrl, bPrevious) ; 本文来自织梦 

copyright dedecms

hwndCtrl = GetNextDlgGroupItem (hDlg, hwndCtrl, bPrevious) ; 

织梦内容管理系统

如果bPreviousTRUE,那么函式传回前一个Tab键停留项或组项;如果为FALSE,则传回下一个Tab键停留项或者组项。

内容来自dedecms

在对话方块上画图
  copyright dedecms

ABOUT2还完成了一些相对说来很特别的事情,亦即在对话方块上画图。让我们来看一看它是怎样做的。在ABOUT2.RC的对话方块模板内,使用位置和大小为我们想要画图的区域定义了一块空白文字控制项:

织梦内容管理系统

LTEXT  ""  IDC_PAINT, 114, 67, 72, 72 dedecms.com 

这个区域为18个字元宽和9个字元高。由於这个控制项没有文字,所以视窗讯息处理程式为「静态」类别所做的工作,只是在必须重绘这个子视窗控制项时清除其背景。

本文来自织梦

在目前颜色或图形选择发生改变,或者对话方块自身获得一个WM_PAINT讯息时,对话方块程序呼叫PaintTheBlock,这个函式在ABOUT2.C中: 织梦好,好织梦

PaintTheBlock (hCtrlBlock, iColor, iFigure) ; 织梦好,好织梦 

AboutDlgProc中,视窗代号hCtrlBlock已经在处理WM_INITDIALOG讯息时被设定: dedecms.com

hCtrlBlock = GetDlgItem (hDlg, IDD_PAINT) ; 内容来自dedecms 

下面是PaintTheBlock函式: copyright dedecms

void PaintTheBlock (HWND hCtrl, int iColor, int iFigure) 
织梦好,好织梦
{ 本文来自织梦 
        InvalidateRect (hCtrl, NULL, TRUE) ; 内容来自dedecms 
        UpdateWindow (hCtrl) ; 内容来自dedecms 
        PaintWindow (hCtrl, iColor, iFigure) ; 
dedecms.com
} dedecms.com 

这个函式使得子视窗控制项无效,并为控制项视窗讯息处理程式产生一个WM_PAINT讯息,然後呼叫ABOUT2中的另一个函式PaintWindow 织梦好,好织梦

PaintWindow函式取得一个装置内容代号,并将其放到hCtrl中,画出所选图形,根据所选颜色用一个著色画刷填入图形。子视窗控制项的大小从GetClientRect获得。尽管对话方块模板以字元为单位定义了控制项的大小,但GetClientRect取得以图素为单位的尺寸。您也可以使用函式MapDialogRect将对话方块中的字元座标转换为显示区域中的图素座标。 内容来自dedecms

我们并非真的绘制了对话方块的显示区域,实际绘制的是子视窗控制项的显示区域。每当对话方块得到一个WM_PAINT讯息时,就令子视窗控制项的显示区域失效,并更新它,使它确信现在其显示区域又有效了,然後在其上画图。 copyright dedecms

将其他函式用於对话方块
 

copyright dedecms

大多数可以用在子视窗的函式也可以用於对话方块中的控制项。例如,如果您想捣乱的话,那么可以使用MoveWindow在对话方块内移动控制项,强迫使用者用滑鼠来追踪它们。 dedecms.com

有时,您需要根据其他控制项的设定,动态地启用或者禁用某些控制项,这需要呼叫:

织梦内容管理系统

EnableWindow (hwndCtrl, bEnable) ; dedecms.com 

bEnableTRUE(非0)时,它启用控制项;当bEnableFALSE0)时,它禁用控制项。在控制项被禁用时,它不再接收键盘或者滑鼠输入。您不能禁用一个拥有输入焦点的控制项。

本文来自织梦

定义自己的控制项
 

copyright dedecms

尽管Windows承揽了许多维护对话方块和子视窗控制项的工作,它同时也为您提供了各种加入程式码的方法。前面我们已经看到了在对话方块上绘图的方法。您也可以使用第九章中讨论的视窗子类别化来改变子视窗控制项的操作。 织梦内容管理系统

您还可以定义自己的子视窗控制项,并将它们用到对话方块中。例如,假定您特别不喜欢普通的矩形按键,而倾向於建立椭圆形按键,那么您可以通过注册一个视窗类别,并使用自己编写的视窗讯息处理程式处理来自您所建立视窗的讯息,从而建立椭圆形按键。在Developer Studio中,您可以在与自订控制项相联系的「Properties」对话方块中指定这个视窗类别,这将转换成对话方块模板中的CONTROL叙述。程式11-3所示的ABOUT3程式正是这样做的。 本文来自织梦

 程式11-3  ABOUT3 织梦好,好织梦 
ABOUT3.C 内容来自dedecms 
/*----------------------------------------------------------------------------- 本文来自织梦 
        ABOUT3.C -- About Box Demo Program No. 3 
dedecms.com
                                              (c) Charles Petzold, 1998 dedecms.com 
----------------------------------------------------------------------------*/ 内容来自dedecms 
  本文来自织梦 
#include       <windows.h> 内容来自dedecms 
#include       "resource.h" 本文来自织梦 
LRESULT        CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ; 

copyright dedecms

BOOL           CALLBACK AboutDlgProc (HWND, UINT, WPARAM, LPARAM) ; 本文来自织梦 
LRESULT        CALLBACK EllipPushWndProc (HWND, UINT, WPARAM, LPARAM) ; 织梦内容管理系统 
  织梦好,好织梦 
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, copyright dedecms 
                    PSTR szCmdLine, int iCmdShow) copyright dedecms 
{ 

本文来自织梦

        static TCHAR   szAppName[] = TEXT ("About3") ; copyright dedecms 
        MSG                                   msg ; 
dedecms.com
        HWND                                  hwnd ; 
内容来自dedecms
        WNDCLASS                       wndclass ; copyright dedecms 
  
织梦内容管理系统
        wndclass.style                                        = CS_HREDRAW | CS_VREDRAW ; 
织梦好,好织梦
        wndclass.lpfnWndProc                                  = WndProc ; dedecms.com 
        wndclass.cbClsExtra                                   = 0 ; 

织梦好,好织梦

        wndclass.cbWndExtra                                   = 0 ; 
织梦内容管理系统
        wndclass.hInstance                                    = hInstance ; 

本文来自织梦

        wndclass.hIcon                                        = LoadIcon (hInstance, szAppName) ; 

copyright dedecms

        wndclass.hCursor                                      = LoadCursor (NULL, IDC_ARROW) ; 

织梦好,好织梦

        wndclass.hbrBackground                        = (HBRUSH) GetStockObject (WHITE_BRUSH) ; 
dedecms.com
        wndclass.lpszMenuName                         = szAppName ; 
本文来自织梦
        wndclass.lpszClassName                        = szAppName ; 内容来自dedecms 
      织梦内容管理系统 
        if (!RegisterClass (&wndclass)) 
本文来自织梦
        { copyright dedecms 
                       MessageBox (   NULL, TEXT ("This program requires Windows NT!"), 本文来自织梦 
                                                                     szAppName, MB_ICONERROR) ; 本文来自织梦 
                       return 0 ; 内容来自dedecms 
        } copyright dedecms 
      

内容来自dedecms

        wndclass.style                                = CS_HREDRAW | CS_VREDRAW ; 

本文来自织梦

        wndclass.lpfnWndProc                          = EllipPushWndProc ; 内容来自dedecms 
        wndclass.cbClsExtra                           = 0 ; 织梦内容管理系统 
        wndclass.cbWndExtra                           = 0 ; 
织梦好,好织梦
        wndclass.hInstance                            = hInstance ; 
织梦内容管理系统
        wndclass.hIcon                                = NULL ; 
copyright dedecms
        wndclass.hCursor                              = LoadCursor (NULL, IDC_ARROW) ; 
dedecms.com
        wndclass.hbrBackground                = (HBRUSH) (COLOR_BTNFACE + 1) ; 织梦好,好织梦 
        wndclass.lpszMenuName                 = NULL ; copyright dedecms 
        wndclass.lpszClassName                = TEXT ("EllipPush") ; 

织梦好,好织梦

  内容来自dedecms 
        RegisterClass (&wndclass) ; 

copyright dedecms

        hwnd = CreateWindow (  szAppName, TEXT ("About Box Demo Program"), 
本文来自织梦
                          WS_OVERLAPPEDWINDOW, 本文来自织梦 
                          CW_USEDEFAULT, CW_USEDEFAULT, 

织梦好,好织梦

                          CW_USEDEFAULT, CW_USEDEFAULT, dedecms.com 
                          NULL, NULL, hInstance, NULL) ; 织梦内容管理系统 
      本文来自织梦 
        ShowWindow (hwnd, iCmdShow) ; 
dedecms.com
        UpdateWindow (hwnd) ;  copyright dedecms 
      内容来自dedecms 
        while (GetMessage (&msg, NULL, 0, 0)) 织梦内容管理系统 
        { 

内容来自dedecms

                       TranslateMessage (&msg) ; 内容来自dedecms 
                       DispatchMessage (&msg) ; 
内容来自dedecms
     } 织梦内容管理系统 
     return msg.wParam ; 

内容来自dedecms

} copyright dedecms 
  copyright dedecms 
LRESULT CALLBACK WndProc (     HWND hwnd, UINT message, WPARAM wParam,LPARAM lParam) dedecms.com 
{ 内容来自dedecms 
        static HINSTANCE hInstance ; dedecms.com 
        switch (message) dedecms.com 
        { 
copyright dedecms
        case    WM_CREATE : copyright dedecms 
                       hInstance = ((LPCREATESTRUCT) lParam)->hInstance ; dedecms.com 
                       return 0 ; 本文来自织梦 
           copyright dedecms 
        case WM_COMMAND : 织梦好,好织梦 
                       switch (LOWORD (wParam)) 

织梦好,好织梦

          { 织梦内容管理系统 
                       case    IDM_APP_ABOUT : 织梦内容管理系统 
                                      DialogBox (hInstance, TEXT ("AboutBox"), hwnd, AboutDlgProc) ; 织梦好,好织梦 
                                      return 0 ; 内容来自dedecms 
                       } 本文来自织梦 
                       break ; 织梦内容管理系统 
           
本文来自织梦
        case    WM_DESTROY : 
copyright dedecms
                       PostQuitMessage (0) ; copyright dedecms 
                       return 0 ; 织梦好,好织梦 
        } 
本文来自织梦
        return DefWindowProc (hwnd, message, wParam, lParam) ; 
本文来自织梦
} 内容来自dedecms 
  内容来自dedecms 
BOOL CALLBACK AboutDlgProc (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) 织梦好,好织梦 
{ copyright dedecms 
        switch (message) 
内容来自dedecms
        { 内容来自dedecms 
        case    WM_INITDIALOG : 
copyright dedecms
                       return TRUE ; 本文来自织梦 
           dedecms.com 
        case    WM_COMMAND : 

内容来自dedecms

                       switch (LOWORD (wParam)) copyright dedecms 
                       { 本文来自织梦 
                       case    IDOK : 
织梦好,好织梦
                                      EndDialog (hDlg, 0) ; 织梦好,好织梦 
                                      return TRUE ; 

内容来自dedecms

                       } 
本文来自织梦
                       break ; copyright dedecms 
     } copyright dedecms 
       return FALSE ; 

dedecms.com

} 

dedecms.com

  copyright dedecms 
LRESULT CALLBACK EllipPushWndProc (   HWND hwnd, UINT message,WPARAM wParam, LPARAM lParam) 本文来自织梦 
{ 

内容来自dedecms

        TCHAR                          szText[40] ; 
内容来自dedecms
        HBRUSH                         hBrush ; 
copyright dedecms
        HDC                            hdc ; 织梦内容管理系统 
        PAINTSTRUCT                    ps ; 
本文来自织梦
        RECT                                          rect ; 
本文来自织梦
      本文来自织梦 
        switch (message) 

本文来自织梦

        { 

内容来自dedecms

        case    WM_PAINT : copyright dedecms 
                       GetClientRect (hwnd, &rect) ; 织梦好,好织梦 
                       GetWindowText (hwnd, szText, sizeof (szText)) ; 

内容来自dedecms

           dedecms.com 
                       hdc = BeginPaint (hwnd, &ps) ; 
织梦内容管理系统
           织梦内容管理系统 
                       hBrush = CreateSolidBrush (GetSysColor (COLOR_WINDOW)) ; 

copyright dedecms

                       hBrush = (HBRUSH) SelectObject (hdc, hBrush) ; 

copyright dedecms

                       SetBkColor (hdc, GetSysColor (COLOR_WINDOW)) ; 
内容来自dedecms
                       SetTextColor (hdc, GetSysColor (COLOR_WINDOWTEXT)) ; copyright dedecms 
           
copyright dedecms
                       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 ; 
copyright dedecms
  copyright dedecms 
        case    WM_KEYUP : copyright dedecms 
                       if (wParam != VK_SPACE) 

本文来自织梦

                                      break ;// fall through 
内容来自dedecms
        case    WM_LBUTTONUP : 

织梦内容管理系统

                       SendMessage (GetParent (hwnd), WM_COMMAND, 

织梦内容管理系统

                               GetWindowLong (hwnd, GWL_ID), (LPARAM) hwnd) ; 

织梦内容管理系统

                       return 0 ; 
本文来自织梦
     } copyright dedecms 
        return DefWindowProc (hwnd, message, wParam, lParam) ; 
copyright dedecms
} dedecms.com 
 ABOUT3.RC (摘录) 

dedecms.com

//Microsoft Developer Studio generated resource script. 本文来自织梦 
#include "resource.h" dedecms.com 
#include "afxres.h" dedecms.com 
  

织梦内容管理系统

///////////////////////////////////////////////////////////////////////////// 织梦好,好织梦 
// 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 dedecms.com 
        ICON       "ABOUT3",IDC_STATIC,7,7,20,20 
dedecms.com
        CTEXT      "About3",IDC_STATIC,40,12,100,8 
内容来自dedecms
        CTEXT      "About Box Demo Program",IDC_STATIC,7,40,166,8 
dedecms.com
        CTEXT                                  "(c) Charles Petzold, 1998",IDC_STATIC,7,52,166,8 

dedecms.com

END 
织梦好,好织梦
  织梦内容管理系统 
///////////////////////////////////////////////////////////////////////////// 

内容来自dedecms

// Menu 

织梦好,好织梦

ABOUT3 MENU DISCARDABLE  本文来自织梦 
BEGIN 织梦好,好织梦 
        POPUP "&Help" 
dedecms.com
        BEGIN 
内容来自dedecms
                       MENUITEM "&About About3...",                                         IDM_APP_ABOUT copyright dedecms 
        END 

织梦内容管理系统

END 织梦好,好织梦 
  本文来自织梦 
///////////////////////////////////////////////////////////////////////////// 本文来自织梦 
// Icon dedecms.com 
ABOUT3         ICON    DISCARDABLE    "icon1.ico" 

dedecms.com

 RESOURCE.H (摘录) 本文来自织梦 
// Microsoft Developer Studio generated include file. 
本文来自织梦
// Used by About3.rc 织梦内容管理系统 
  
织梦好,好织梦
#define IDM_APP_ABOUT           40001 

copyright dedecms

#define IDC_STATIC              -1 

织梦好,好织梦

  内容来自dedecms

ABOUT3.ICO

织梦内容管理系统

 


 

织梦好,好织梦

内容来自dedecms

我们所注册的视窗类别叫做「EllipPush」(椭圆形按键)。在Developer Studio的对话方块编辑器中,删除「Cancel」和「OK」按钮。要添加依据此视窗类别的控制项,请从「 Controls 」工具列选择「 Custom Control 」。在此控制项的「 Properties 」对话方块的「 Class 」栏位输入「 EllipPush 」。在对话方块模板中我们没有使用DEFPUSHBUTTON叙述,而是用CONTROL叙述来指定此视窗类别: copyright dedecms

CONTROL "OK" IDOK, "EllipPush", TABGRP, 64, 60, 32, 14 

dedecms.com

当在对话方块中建立子视窗控制项时,对话方块管理器把这个视窗类别用於CreateWindow呼叫中。

本文来自织梦

ABOUT3.C程式在WinMain中注册了EllipPush视窗类别:

织梦好,好织梦

wndclass.style                        = CS_HREDRAW | CS_VREDRAW ; 
dedecms.com
wndclass.lpfnWndProc           = EllipPushWndProc ; 
织梦内容管理系统
wndclass.cbClsExtra            = 0 ; 
copyright dedecms
wndclass.cbWndExtra            = 0 ; 

内容来自dedecms

wndclass.hInstance                    = hInstance ; 
内容来自dedecms
wndclass.hIcon                        = NULL ; copyright dedecms 
wndclass.hCursor                      = LoadCursor (NULL, IDC_ARROW) ; dedecms.com 
wndclass.hbrBackground                = (HBRUSH) (COLOR_WINDOW + 1) ; 

织梦好,好织梦

wndclass.lpszMenuName                 = NULL ; 

本文来自织梦

wndclass.lpszClassName                = TEXT ("EllipPush") ; 织梦好,好织梦 
  
织梦内容管理系统
RegisterClass (&wndclass) ; 

内容来自dedecms

该视窗类别指定视窗讯息处理程式为EllipPushWndProc,在ABOUT3.C中正是这样。 内容来自dedecms

EllipPushWndProc视窗讯息处理程式只处理三种讯息:WM_PAINTWM_KEYUPWM_LBUTTONUP。在处理WM_PAINT讯息时,它从GetClientRect中取得视窗的大小,从GetWindowText中取得显示在按键上的文字,用Windows函式EllipseDrawText来输出椭圆和文字。

织梦好,好织梦

WM_KEYUPWM_LBUTTONUP讯息的处理非常简单: 本文来自织梦

case    WM_KEYUP : 
copyright dedecms
        if (wParam != VK_SPACE) 
织梦好,好织梦
                       break ;     // fall through 

织梦内容管理系统

case WM_LBUTTONUP : 本文来自织梦 
        SendMessage (GetParent (hwnd), WM_COMMAND, dedecms.com 
                       GetWindowLong (hwnd, GWL_ID), (LPARAM) hwnd) ; 

本文来自织梦

        return 0 ; dedecms.com 

视窗讯息处理程式使用GetParent来取得其父视窗(即对话方块)的代号,并发送一个WM_COMMAND讯息,讯息的wParam等於控制项的ID,这个ID是用GetWindowLong取得的。然後,对话方块视窗讯息处理程式将这个讯息传给ABOUT3内的对话方块程序,结果得到一个使用者自订的按键,如图11-3所示。您可以用同样的方法来建立其他自订对话方块控制项。

本文来自织梦


 

内容来自dedecms

copyright dedecms

 

织梦内容管理系统

11-3 ABOUT3建立的自订按键 织梦好,好织梦

 

这就是全部要做的吗?其实不然。通常,对於维护子视窗控制项所需要的处理而言,EllipPushWndProc只是一个空架子。例如,按钮不会像普通的按键那样闪烁。要翻转按键内的颜色,视窗讯息处理程式必须处理WM_KEYDOWN(来自空白键)和WM_LBUTTONDOWN讯息。视窗讯息处理程式还必须在收到WM_LBUTTONDOWN讯息时拦截滑鼠,并且,如果当按钮还处於按下状态,而滑鼠移到了子视窗的显示区域之外,那么得要释放滑鼠拦截(并将按钮的内部颜色回复为正常状态)。只有在滑鼠被拦截时松开该按钮,子视窗才会给其父视窗送回一个WM_COMMAND讯息。

织梦好,好织梦

EllipPushWndProc也不处理WM_ENABLE讯息。如上所述,对话方块程序可以使用EnableWindow函式来禁用某视窗。於是,子视窗将显示灰色文字,而不再是黑色文字,以表示它已经被禁用,并且不能再接收任何讯息了。

本文来自织梦

如果子视窗控制项的视窗讯息处理程式需要为所建立的每个视窗存放各自不同的资料,那么它可以通过使用视窗类别结构中的cbWndExtra值来做到。这样就在内部视窗结构中保留了空间,并可以用SetWindowLongGetWindowLong来存取该资料。 本文来自织梦

非模态对话方块
  内容来自dedecms

在本章的开始,我曾经说过对话方块分为「模态的」和「非模态的」两种。现在我们已经研究过这两种对话方块中最常见的一种-模态对话方块。模态对话方块(不包括系统模态对话方块)。允许使用者在对话方块与其他程式之间进行切换。但是,使用者不能切换到同一程式的另一个视窗,直到模态对话方块被清除为止。非模态对话方块允许使用者在对话方块与其他程式之间进行切换,又可以在对话方块与建立对话方块的视窗之间进行切换。因此,非模态对话方块与使用者程式常见的普通弹出式视窗可能更为相似。

本文来自织梦

当使用者觉得让对话方块保留片刻会更加方便时,使用非模态对话方块是合适的。例如,文书处理程式经常使用非模态对话方块来进行「Find」和「Change」操作。如果「Find」对话方块是模态的,那么使用者必须从功能表中选择「Find」,然後输入要寻找的字串,结束对话方块,传回到档案中,接著再重复整个程序来寻找同一字串的另一次出现。允许使用者在档案与对话方块之间进行切换则会方便得多。 dedecms.com

您已经看到,模态对话方块是用DialogBox来建立的。只有在清除对话方块之後,函式才会传回值。在对话方块程序内使用EndDialog呼叫来终止对话方块,DialogBox传回的是该呼叫的第二个参数的值。非模态对话方块是使用CreateDialog来建立的,该函式所使用的参数与DialogBox相同。 本文来自织梦

hDlgModeless = CreateDialog (  hInstance, szTemplate,  织梦内容管理系统 
                               hwndParent, DialogProc) ; 本文来自织梦 

区别是CreateDialog函式立即传回对话方块的视窗代号,并通常将这个视窗代号存放到整体变数中。

dedecms.com

尽管将DialogBox这一名字用於模态对话方块而CreateDialog用於非模态对话方块是随意的,但是您可以通过非模态对话方块与普通视窗类似这一点来记住这两个函式的区别。CreateDialog可以令人想起CreateWindow函式来,而後者建立的是普通视窗。 织梦好,好织梦

模态对话方块与非模态对话方块的区别
  织梦好,好织梦

使用非模态对话方块与使用模态对话方块相似,但是也有一些重要的区别:

织梦好,好织梦

首先,非模态对话方块通常包含一个标题列和一个系统功能表按钮。当您在Developer Studio中建立对话方块时,这些是内定选项。用於非模态对话方块的对话方块模板中的STYLE叙述形如: 内容来自dedecms

STYLE WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE 织梦内容管理系统 

标题列和系统功能表允许使用者,使用滑鼠或者键盘将非模态对话方块移动到另一个显示区域。对於模态对话方块,您通常无须提供标题列和系统功能表,因为使用者不能在其下面的视窗中做任何其他的事情。

内容来自dedecms

第二项重要的区别是:注意,在我们的范例STYLE叙述中包含有WS_VISIBLE样式。在 Developer Studio 中,从「 Dialog Properties 」对话方块的「 More Styles 」页面标签中选择此选项。如果省略了WS_VISIBLE,那么您必须在CreateDialog呼叫之後呼叫ShowWindow

本文来自织梦

hDlgModeless = CreateDialog (  . . .  ) ; 织梦内容管理系统 
     ShowWindow (hDlgModeless, SW_SHOW) ; dedecms.com 

如果您既没有包含WS_VISIBLE样式,又没有呼叫ShowWindow,那么非模态对话方块将不会被显示。如果忽略这个事实,那么习惯於模态对话方块的程式写作者在第一次试图建立非模态对话方块时,经常会出现问题。

copyright dedecms

第三项区别:与模态对话方块和讯息方块的讯息不同,非模态对话方块的讯息要经过程序式的讯息伫列。要将这些讯息传送给对话方块视窗讯息处理程式,则必须改变讯息伫列。方法如下:当您使用CreateDialog建立非模态对话方块时,应该将从呼叫中传回的对话方块代号储存在一个整体变数(如hDlgModeless)中,并将讯息回圈改变为: 内容来自dedecms

while (GetMessage (&msg, NULL, 0, 0)) dedecms.com 
{ 
内容来自dedecms
        if (hDlgModeless == 0 || !IsDialogMessage (hDlgModeless, &msg)) 本文来自织梦 
     { 

本文来自织梦

                       TranslateMessage (&msg) ; 本文来自织梦 
                       DispatchMessage  (&msg) ; 

织梦内容管理系统

     } 
copyright dedecms
} copyright dedecms 

如果讯息是发送给非模态对话方块的,那么IsDialogMessage将它发送给对话方块中视窗讯息处理程式,并传回TRUE(非0);否则,它将传回FALSE0)。只有hDlgModeless0或者讯息不是该对话方块的讯息时,才必须呼叫TranslateMessageDispatchMessage函式。如果您将键盘加速键用於您的程式视窗,那么讯息回圈将如下所示:

dedecms.com

while (GetMessage (&msg, NULL, 0, 0)) 
copyright dedecms
{ 

织梦好,好织梦

        if (hDlgModeless == 0 || !IsDialogMessage (hDlgModeless, &msg)) 织梦内容管理系统 
        { 
织梦内容管理系统
                       if (!TranslateAccelerator (hwnd, hAccel, &msg)) 本文来自织梦 
                       { dedecms.com 
                                      TranslateMessage (&msg) ; 
织梦好,好织梦
                                      DispatchMessage  (&msg) ; 
本文来自织梦
                       } 织梦好,好织梦 
        } 

织梦好,好织梦

} 内容来自dedecms 

由於整体变数被初始化为0,所以hDlgModeless将为0,直到建立对话方块为止,从而保证不会使用无效的视窗代号来呼叫IsDialogMessage。在清除非模态对话方块时,您也必须注意这一点,正如最後一点所说明的。 copyright dedecms

hDlgModeless变数也可以由程式的其他部分使用,以便对非模态对话方块是否存在加以验证。例如,程式中的其他视窗可以在hDlgModeless不等於0时给对话方块发送讯息。

内容来自dedecms

最後一项重要的区别:使用DestroyWindow而不是EndDialog来结束非模态对话方块。当您呼叫DestroyWindow後,将hDlgModeless整体变数设定为0织梦好,好织梦

使用者习惯於从系统功能表中选择「Close」来结束非模态对话方块。尽管启用了「Close」选项,Windows内的对话方块视窗讯息处理程式并不处理WM_CLOSE讯息。您必须自己在对话方块程序中处理它:

copyright dedecms

case    WM_CLOSE : 

织梦内容管理系统

        DestroyWindow (hDlg) ; 织梦内容管理系统 
        hDlgModeless = NULL ; 内容来自dedecms 
        break ; 
本文来自织梦

注意这两个视窗代号之间的区别:DestroyWindowhDlg参数是传递给对话方块程序的参数;hDlgModeless是从CreateDialog传回的整体变数,程式在讯息回圈内检验它。 织梦内容管理系统

您也可以允许使用者使用按键来关闭非模态对话方块,处理方式与处理WM_CLOSE讯息一样。对话方块必须传回给建立它的视窗之任何资料都可以储存在整体变数中。如果不喜欢使用整体变数,那么您也可以用CreateDialogParam来建立非模态对话方块,并按前面介绍的方法让它储存一个结构指标。

内容来自dedecms

新的COLORS程式
 

dedecms.com

第九章中所描述的COLORS1程式建立了九个子视窗,以便显示三个卷动列和六个文字项。那时候,这个程式还是我们所写过的程式中相当复杂的一个。如果将COLORS1转换为使用非模态对话方块则会使程式-特别是WndProc函式-变得令人难以置信的简单,修正後的COLORS2程式如程式11-4所示。

织梦好,好织梦

 程式11-4  COLORS2 copyright dedecms 
COLORS2.C 

内容来自dedecms

/*---------------------------------------------------------------------------- 

dedecms.com

        COLORS2.C -- Version using Modeless Dialog Box 织梦内容管理系统 
                                                     (c) Charles Petzold, 1998 内容来自dedecms 
----------------------------------------------------------------------------*/ 
内容来自dedecms
#include <windows.h> 本文来自织梦 
LRESULT        CALLBACK WndProc               (HWND, UINT, WPARAM, LPARAM) ; 本文来自织梦 
BOOL           CALLBACK ColorScrDlg           (HWND, UINT, WPARAM, LPARAM) ; 本文来自织梦 
  

本文来自织梦

HWND hDlgModeless ; copyright dedecms 
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, dedecms.com 
                                                     PSTR szCmdLine, int iCmdShow) 
织梦内容管理系统
{ 
copyright dedecms
        static TCHAR           szAppName[] = TEXT ("Colors2") ; 织梦好,好织梦 
        HWND                                          hwnd ; copyright dedecms 
        MSG                                           msg ; 
copyright dedecms
        WNDCLASS                              wndclass ; 

copyright dedecms

      

本文来自织梦

        wndclass.style                                = CS_HREDRAW | CS_VREDRAW ; 
dedecms.com
        wndclass.lpfnWndProc                          = WndProc ; 

织梦好,好织梦

        wndclass.cbClsExtra                           = 0 ; 内容来自dedecms 
        wndclass.cbWndExtra                           = 0 ; 织梦好,好织梦 
        wndclass.hInstance                            = hInstance ; dedecms.com 
        wndclass.hIcon                                = LoadIcon (NULL, IDI_APPLICATION) ; 本文来自织梦 
        wndclass.hCursor                              = LoadCursor (NULL, IDC_ARROW) ; 
内容来自dedecms
        wndclass.hbrBackground                = CreateSolidBrush (0L) ; 本文来自织梦 
        wndclass.lpszMenuName                 = NULL ; 内容来自dedecms 
        wndclass.lpszClassName                = szAppName ; copyright dedecms 
      织梦好,好织梦 
        if (!RegisterClass (&wndclass)) 
dedecms.com
        { dedecms.com 
                       MessageBox (   NULL, TEXT ("This program requires Windows NT!"), 织梦内容管理系统 
                                                                     szAppName, MB_ICONERROR) ; 

织梦好,好织梦

                       return 0 ; 

织梦内容管理系统

        } 
织梦内容管理系统
      copyright dedecms 
        hwnd = CreateWindow (  szAppName, TEXT ("Color Scroll"), 
内容来自dedecms
                               WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN, 

copyright dedecms

                               CW_USEDEFAULT, CW_USEDEFAULT, 

织梦好,好织梦

                               CW_USEDEFAULT, CW_USEDEFAULT, 织梦好,好织梦 
                               NULL, NULL, hInstance, NULL) ; 织梦内容管理系统 
      
copyright dedecms
        ShowWindow (hwnd, iCmdShow) ; 
内容来自dedecms
        UpdateWindow (hwnd) ; 

织梦内容管理系统

      copyright dedecms 
        hDlgModeless = CreateDialog (  hInstance, TEXT ("ColorScrDlg"),  
织梦好,好织梦
               hwnd, ColorScrDlg) ; 本文来自织梦 
        while (GetMessage (&msg, NULL, 0, 0)) 
织梦内容管理系统
        { copyright dedecms 
                       if (hDlgModeless == 0 || !IsDialogMessage (hDlgModeless, &msg)) 织梦内容管理系统 
                       { 内容来自dedecms 
                               TranslateMessage (&msg) ; 

内容来自dedecms

                               DispatchMessage  (&msg) ; 织梦好,好织梦 
                       } 织梦好,好织梦 
        } 

本文来自织梦

        return msg.wParam ; 织梦好,好织梦 
} 织梦好,好织梦 
  本文来自织梦 
LRESULT CALLBACK WndProc (     HWND hwnd, UINT message, WPARAM wParam,LPARAM lParam) dedecms.com 
{ 本文来自织梦 
        switch (message) 内容来自dedecms 
        { copyright dedecms 
        case    WM_DESTROY : 本文来自织梦 
                       DeleteObject ((HGDIOBJ) SetClassLong (hwnd, GCL_HBRBACKGROUND, 本文来自织梦 
                (LONG) GetStockObject (WHITE_BRUSH))) ; 本文来自织梦 
                       PostQuitMessage (0) ; dedecms.com 
                       return 0 ; 织梦内容管理系统 
        } 
内容来自dedecms
        return DefWindowProc (hwnd, message, wParam, lParam) ; 本文来自织梦 
} 

本文来自织梦

  本文来自织梦 
BOOL CALLBACK ColorScrDlg (    HWND hDlg, UINT message,WPARAM wParam, LPARAM lParam) 织梦内容管理系统 
{ 内容来自dedecms 
        static int             iColor[3] ; 
copyright dedecms
        HWND                                  hwndParent, hCtrl ; dedecms.com 
        int                                   iCtrlID, iIndex ; 织梦好,好织梦 
      本文来自织梦 
        switch (message) 
本文来自织梦
        { 

本文来自织梦

        case    WM_INITDIALOG : dedecms.com 
                       for (iCtrlID = 10 ; iCtrlID < 13 ; iCtrlID++) copyright dedecms 
                       { 
织梦好,好织梦
                                      hCtrl = GetDlgItem (hDlg, iCtrlID) ; 
织梦好,好织梦
                                      SetScrollRange (hCtrl, SB_CTL, 0, 255, FALSE) ; 

copyright dedecms

                                      SetScrollPos   (hCtrl, SB_CTL, 0, FALSE) ; copyright dedecms 
                       } 
本文来自织梦
                       return TRUE ; 内容来自dedecms 
           内容来自dedecms 
        case    WM_VSCROLL : 
dedecms.com
                       hCtrl                  = (HWND) lParam ; 

内容来自dedecms

                       iCtrlID                = GetWindowLong (hCtrl, GWL_ID) ; 

织梦内容管理系统

                       iIndex                 = iCtrlID - 10 ; 
copyright dedecms
                       hwndParent             = GetParent (hDlg) ; 

内容来自dedecms

           

内容来自dedecms

                       switch (LOWORD (wParam)) 织梦内容管理系统 
                               { 内容来自dedecms 
                       case    SB_PAGEDOWN : 

copyright dedecms

                                     iColor[iIndex] += 15 ;         // fall through 织梦好,好织梦 
                                      case SB_LINEDOWN : 本文来自织梦 
                                      iColor[iIndex] = min (255, iColor[iIndex] + 1) ; 
copyright dedecms
                                      break ; 织梦内容管理系统 
                       case    SB_PAGEUP : copyright dedecms 
                                      iColor[iIndex] -= 15 ;     // fall through dedecms.com 
                                      case SB_LINEUP : 

内容来自dedecms

                                      iColor[iIndex] = max (0, iColor[iIndex] - 1) ; dedecms.com 
                                      break ; 

本文来自织梦

                       case    SB_TOP : 织梦好,好织梦 
                                      iColor[iIndex] = 0 ; 内容来自dedecms 
                                      break ; 

dedecms.com

                       case    SB_BOTTOM : 织梦好,好织梦 
                                      iColor[iIndex] = 255 ; dedecms.com 
                                      break ; copyright dedecms 
                               case    SB_THUMBPOSITION : 

织梦内容管理系统

                               case    SB_THUMBTRACK : 
内容来自dedecms
                                              iColor[iIndex] = HIWORD (wParam) ; dedecms.com 
                                              break ; copyright dedecms 
                               default : 
本文来自织梦
                                      return FALSE ; 

dedecms.com

                       } 本文来自织梦 
                               SetScrollPos  (hCtrl, SB_CTL,        iColor[iIndex], TRUE) ; 
织梦内容管理系统
                       SetDlgItemInt (hDlg,  iCtrlID + 3, iColor[iIndex], FALSE) ; 

内容来自dedecms

           copyright dedecms 
                               DeleteObject ((HGDIOBJ) SetClassLong (hwndParent, GCL_HBRBACKGROUND, 本文来自织梦 
                               (LONG) CreateSolidBrush ( 织梦好,好织梦 
                                 RGB (iColor[0], iColor[1], iColor[2])))) ; 
copyright dedecms
           织梦好,好织梦 
                       InvalidateRect (hwndParent, NULL, TRUE) ; 
织梦好,好织梦
                       return TRUE ; 织梦好,好织梦 
        } 
copyright dedecms
        return FALSE ; 织梦好,好织梦 
} 
dedecms.com
 COLORS2.RC (摘录) 织梦内容管理系统 
//Microsoft Developer Studio generated resource script. 

本文来自织梦

#include "resource.h" dedecms.com 
#include "afxres.h" copyright dedecms 
  
织梦好,好织梦
///////////////////////////////////////////////////////////////////////////// copyright dedecms 
// Dialog 
本文来自织梦
COLORSCRDLG DIALOG DISCARDABLE  16, 16, 120, 141 

copyright dedecms

STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION 

本文来自织梦

CAPTION "Color Scroll Scrollbars" 内容来自dedecms 
FONT 8, "MS Sans Serif" 
织梦内容管理系统
BEGIN copyright dedecms 
        CTEXT                                                 "&Red",IDC_STATIC,8,8,24,8,NOT WS_GROUP 
内容来自dedecms
        SCROLLBAR                             10,8,20,24,100,SBS_VERT | WS_TABSTOP 

dedecms.com

        CTEXT                                 "0",13,8,124,24,8,NOT WS_GROUP copyright dedecms 
        CTEXT                                                 "&Green",IDC_STATIC,48,8,24,8,NOT WS_GROUP 
copyright dedecms
        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 

dedecms.com

        SCROLLBAR                             12,89,20,24,100,SBS_VERT | WS_TABSTOP 

内容来自dedecms

        CTEXT                                 "0",15,89,124,24,8,NOT WS_GROUP 

内容来自dedecms

END 
dedecms.com
 RESOURCE.H (摘录) 
内容来自dedecms
// Microsoft Developer Studio generated include file. 
本文来自织梦
// Used by Colors2.rc 织梦内容管理系统 
  

织梦内容管理系统

#define IDC_STATIC      -1 copyright dedecms 

原来的COLORS1程式所显示的卷动列大小是依据视窗大小决定的,而新程式在非模态对话方块内以固定的尺寸来显示它们,如图11-4所示。 dedecms.com

当您建立对话方块模板时,直接将三个卷动列的ID分别设为101112,将显示卷动列目前值的三个静态文字栏位的ID分别设为131415。将每个卷动列都设定为Tab Stop样式,而从所有的六个静态文字栏位中删除Group样式。

织梦好,好织梦


 

织梦好,好织梦

dedecms.com

 

本文来自织梦

11-4 COLORS2的萤幕显示

本文来自织梦

 

COLORS2中,非模态对话方块是在WinMain函式里建立的,紧跟在程式主视窗的ShowWindow呼叫之後。注意,主视窗的视窗样式包含WS_CLIPCHILDREN,这允许程式无须擦除对话方块就能够重画主视窗。

内容来自dedecms

如上所述,从CreateDialog传回的对话方块视窗代号存放在整体变数hDlgModeless中,并在讯息回圈中被测试。不过,在这个程式中,不需要将代号存放在整体变数中,也不需要在呼叫IsDialogMessage之前测试这个值。讯息回圈可以编写如下: 织梦好,好织梦

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

织梦好,好织梦

{ dedecms.com 
        if (!IsDialogMessage (hDlgModeless, &msg)) 

内容来自dedecms

     { 
织梦好,好织梦
                       TranslateMessage       (&msg) ; 内容来自dedecms 
                       DispatchMessage        (&msg) ; 

本文来自织梦

     } 
织梦好,好织梦
} 织梦好,好织梦 

由於对话方块是在程式进入讯息回圈前建立,并且直到程式结束时才会被清除,所以hDlgModeless的值将总是有效的。我加入了如下的处理方式,以便您可能会往对话方块的视窗讯息处理程式中加入一段清除对话方块的程式码: 织梦好,好织梦

case    WM_CLOSE : 织梦内容管理系统 
        DestroyWindow (hDlg) ; 

copyright dedecms

        hDlgModeless = NULL ; dedecms.com 
        break ; 
织梦好,好织梦

在原来的COLORS1程式中,SetWindowText在使用wsprintf将三个数值标签转换为文字之後才设定它们的值。叙述为:

织梦内容管理系统

wsprintf (szBuffer, TEXT ("%i"), color[i]) ; dedecms.com 
SetWindowText (hwndValue[i], szBuffer) ; 内容来自dedecms 

i的值为目前处理的卷动列的IDhwndValue是一个阵列,它包含颜色数值的三个静态文字子视窗的视窗代号。

织梦内容管理系统

新版本使用SetDlgItemInt为每个子视窗的每个文字栏位设定一个号码: 织梦好,好织梦

SetDlgItemInt (hDlg, iCtrlID + 3, color [iCtrlID], FALSE) ; 内容来自dedecms 

尽管SetDlgItemInt和与其对应的GetDlgItemInt在编辑控制项中用得最多,它们也可以用来设定其他控制项的文字栏位,如静态文字控制项等。iCtrlID变数是卷动列的ID,给ID加上3使之变成对应数字标签的ID。第三个参数是颜色值。通常,第四个参数表示第三个参数的值是解释为有正负号的(第四个参数为TRUE)还是无正负号的(第四个参数为FALSE)。但是,对於这个程式,值的范围是从0256,所以这个参数没有意义。

内容来自dedecms

在将COLORS1转换为COLORS2的程序中,我们把越来越多的工作交给了Windows。旧版本呼叫了CreateWindow 10次;而新版本只呼叫了CreateWindowCreateDialog各一次。但是,如果您认为我们已经把呼叫CreateWindow的次数降到最少,那么您就错了,请看下一个程式。 织梦内容管理系统

HEXCALC:视窗还是对话方块?
  本文来自织梦

HEXCALC程式可能是写程式偷懒的经典之作,如程式11-5所示。这个程式完全不呼叫CreateWindow,也不处理WM_PAINT讯息,不取得装置内容,也不处理滑鼠讯息。但是它只用了不到150行的原始码,就构成了一个具有完整键盘和滑鼠介面以及10种运算的十六进位计算机。计算机如图11-5所示。 copyright dedecms

 程式11-5  HEXCALC 织梦好,好织梦 
HEXCALC.C 
织梦好,好织梦
/*------------------------------------------------------------------------ 织梦内容管理系统 
        HEXCALC.C -- Hexadecimal Calculator 织梦内容管理系统 
                                     (c) Charles Petzold, 1998 织梦好,好织梦 
-------------------------------------------------------------------------*/ 

织梦内容管理系统

  织梦好,好织梦 
#include <windows.h> 

dedecms.com

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ; 

copyright dedecms

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, 

本文来自织梦

                                                             PSTR szCmdLine, int iCmdShow) 
本文来自织梦
{ 

本文来自织梦

        static TCHAR   szAppName[] = TEXT ("HexCalc") ; 

内容来自dedecms

        HWND                           hwnd ; 织梦好,好织梦 
        MSG                            msg ; 

copyright dedecms

        WNDCLASS                       wndclass ; 织梦好,好织梦 
      copyright dedecms 
        wndclass.style                                = CS_HREDRAW | CS_VREDRAW; 

本文来自织梦

        wndclass.lpfnWndProc                          = WndProc ; 织梦好,好织梦 
        wndclass.cbClsExtra                           = 0 ; 

织梦内容管理系统

        wndclass.cbWndExtra                           = DLGWINDOWEXTRA ;                     // Note! 本文来自织梦 
        wndclass.hInstance                            = hInstance ; 织梦好,好织梦 
        wndclass.hIcon                                = LoadIcon (hInstance, szAppName) ; 
dedecms.com
        wndclass.hCursor                              = LoadCursor (NULL, IDC_ARROW) ; 织梦内容管理系统 
        wndclass.hbrBackground                = (HBRUSH) (COLOR_BTNFACE + 1) ; 

织梦内容管理系统

        wndclass.lpszMenuName                 = NULL ; dedecms.com 
        wndclass.lpszClassName                = szAppName ; 
本文来自织梦
      

织梦好,好织梦

        if (!RegisterClass (&wndclass)) 

dedecms.com

     { 

本文来自织梦

                       MessageBox (   NULL, TEXT ("This program requires Windows NT!"), 
织梦好,好织梦
                                                                     szAppName, MB_ICONERROR) ; 

织梦好,好织梦

                       return 0 ; copyright dedecms 
        } 
内容来自dedecms
      dedecms.com 
        hwnd = CreateDialog (hInstance, szAppName, 0, NULL) ; 本文来自织梦 
        ShowWindow (hwnd, iCmdShow) ; 
内容来自dedecms
        while (GetMessage (&msg, NULL, 0, 0)) 
dedecms.com
        { 

织梦内容管理系统

                               TranslateMessage (&msg) ; 

copyright dedecms

                               DispatchMessage (&msg) ; 
copyright dedecms
     } 本文来自织梦 
        return msg.wParam ; 本文来自织梦 
} 内容来自dedecms 
  
内容来自dedecms
void ShowNumber (HWND hwnd, UINT iNumber) 本文来自织梦 
{ 

织梦好,好织梦

        TCHAR szBuffer[20] ; 织梦内容管理系统 
        wsprintf (szBuffer, TEXT ("%X"), iNumber) ; copyright dedecms 
        SetDlgItemText (hwnd, VK_ESCAPE, szBuffer) ; 

织梦好,好织梦

} 内容来自dedecms 
  内容来自dedecms 
DWORD CalcIt (UINT iFirstNum, int iOperation, UINT iNum) 织梦内容管理系统 
{ 织梦内容管理系统 
        switch (iOperation) 
copyright dedecms
        { 
本文来自织梦
        case '=': return iNum ; 本文来自织梦 
        case '+': return iFirstNum +  iNum ; 

copyright dedecms

        case '-': return iFirstNum -  iNum ; 织梦内容管理系统 
        case '*': return iFirstNum *  iNum ; 
copyright dedecms
        case '&': return iFirstNum &  iNum ; 织梦内容管理系统 
        case '|': return iFirstNum |  iNum ; 
copyright dedecms
        case '^': return iFirstNum ^  iNum ; dedecms.com 
        case '<': return iFirstNum << iNum ; 
织梦内容管理系统
        case '>': return iFirstNum >> iNum ; 

本文来自织梦

        case '/': return iNum ? iFirstNum / iNum: MAXDWORD ; 织梦好,好织梦 
        case '%': return iNum ? iFirstNum % iNum: MAXDWORD ; 织梦好,好织梦 
        default : return 0 ; copyright dedecms 
        } copyright dedecms 
} 
织梦内容管理系统
  copyright dedecms 
LRESULT CALLBACK WndProc (     HWND hwnd, UINT message, WPARAM wParam,LPARAM lParam) dedecms.com 
{ 内容来自dedecms 
        static BOOL    bNewNumber = TRUE ; copyright dedecms 
        static int     iOperation = '=' ; 
本文来自织梦
        static UINT    iNumber, iFirstNum ; 织梦好,好织梦 
        HWND                                  hButton ; 织梦好,好织梦 
      

copyright dedecms

        switch (message) 

copyright dedecms

        { 织梦内容管理系统 
        case WM_KEYDOWN:                   // left arrow --> backspace 
copyright dedecms
                       if (wParam != VK_LEFT) 

本文来自织梦

                                      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) ; 

dedecms.com

                       } 织梦好,好织梦 
                       else 内容来自dedecms 
                       { dedecms.com 
                               MessageBeep (0) ; 

内容来自dedecms

                               break ; 
内容来自dedecms
                       } 
织梦内容管理系统
                // fall through 
织梦内容管理系统
        case    WM_COMMAND: 内容来自dedecms 
                       SetFocus (hwnd) ; 织梦好,好织梦 
           

织梦内容管理系统

                       if (LOWORD (wParam) == VK_BACK)                 //backspace 

本文来自织梦

                                      ShowNumber (hwnd, iNumber /= 16) ; 本文来自织梦 
           dedecms.com 
                       else if (LOWORD (wParam) == VK_ESCAPE)                // escape copyright dedecms 
                                      ShowNumber (hwnd, iNumber = 0) ; 本文来自织梦 
           织梦好,好织梦 
                       else if (isxdigit (LOWORD (wParam)))                  // hex digit 织梦好,好织梦 
          { 
dedecms.com
                                      if (bNewNumber) 

dedecms.com

                                      { 内容来自dedecms 
                                                     iFirstNum = iNumber ; 
织梦好,好织梦
                                                     iNumber = 0 ; 

织梦内容管理系统

                               } 本文来自织梦 
                               bNewNumber = FALSE ; dedecms.com 
                       if      (iNumber <= MAXDWORD >> 4) 织梦好,好织梦 
                                              ShowNumber (hwnd, iNumber = 16 * iNumber + wParam - 内容来自dedecms 
                                              (isdigit (wParam) ? '0': 'A' - 10)) ; 
织梦好,好织梦
                       else 织梦内容管理系统 
                                              MessageBeep (0) ; dedecms.com 
                       } 织梦好,好织梦 
                       else    // operation 

织梦好,好织梦

          { 
织梦好,好织梦
                               if (!bNewNumber) dedecms.com 
                       ShowNumber (hwnd, iNumber = 内容来自dedecms 
                        CalcIt (iFirstNum, iOperation, iNumber)) ; 内容来自dedecms 
                               bNewNumber = TRUE ; copyright dedecms 
                               iOperation = LOWORD (wParam) ; 织梦好,好织梦 
                       } 

织梦好,好织梦

                       return 0 ; 织梦内容管理系统 
        case    WM_DESTROY: 织梦好,好织梦 
                       PostQuitMessage (0) ; 织梦好,好织梦 
                       return 0 ; 织梦好,好织梦 
        } 织梦内容管理系统 
        return DefWindowProc (hwnd, message, wParam, lParam) ; 

dedecms.com

} 

本文来自织梦

 HEXCALC.RC (摘录) 
dedecms.com
//Microsoft Developer Studio generated resource script. copyright dedecms 
#include "resource.h" 
copyright dedecms
#include "afxres.h" 织梦内容管理系统 
  织梦内容管理系统 
///////////////////////////////////////////////////////////////////////////// 

内容来自dedecms

// Icon 织梦好,好织梦 
HEXCALC                                       ICON    DISCARDABLE                           "HexCalc.ico" 织梦内容管理系统 
  织梦好,好织梦 
///////////////////////////////////////////////////////////////////////////// 织梦好,好织梦 
  织梦内容管理系统 
#include "hexcalc.dlg" copyright dedecms 
 HEXCALC.DLG 
织梦好,好织梦
/*-------------------------------- dedecms.com 
   HEXCALC.DLG dialog script 

dedecms.com

----------------------------------*/ 

dedecms.com

  内容来自dedecms 
HexCalc DIALOG -1, -1, 102, 122 
copyright dedecms
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 
内容来自dedecms
           PUSHBUTTON "7",         55,  8,  56, 14, 14 
内容来自dedecms
        PUSHBUTTON "4",          52,  8,  72, 14, 14 
织梦内容管理系统
        PUSHBUTTON "1",                  49,  8,  88, 14, 14 copyright dedecms 
        PUSHBUTTON "0",         48,  8,  104,14, 14 

内容来自dedecms

        PUSHBUTTON "0",          27,  26, 4,  50, 14   
copyright dedecms
        PUSHBUTTON "E",          69,  26, 24, 14, 14 
织梦内容管理系统
        PUSHBUTTON "B",          66,  26, 40, 14, 14 
内容来自dedecms
        PUSHBUTTON "8",                  56,  26, 56, 14, 14 
内容来自dedecms
        PUSHBUTTON "5",          53,  26, 72, 14, 14 copyright dedecms 
        PUSHBUTTON "2",          50,  26, 88, 14, 14 织梦好,好织梦 
        PUSHBUTTON "Back",       8,   26, 104,32, 14 copyright dedecms 
        PUSHBUTTON "C",          67,  44, 40, 14, 14 织梦内容管理系统 
        PUSHBUTTON "F",          70,  44, 24, 14, 14 

copyright dedecms

        PUSHBUTTON "9",         57,  44, 56, 14, 14 

内容来自dedecms

        PUSHBUTTON "6",         54,  44, 72, 14, 14 copyright dedecms 
        PUSHBUTTON "3",         51,  44, 88, 14, 14 织梦内容管理系统 
        PUSHBUTTON "+",         43,  62, 24, 14, 14 
本文来自织梦
        PUSHBUTTON "-",         45,  62, 40, 14, 14 dedecms.com 
        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 copyright dedecms 
        PUSHBUTTON "&&",38,  80, 24, 14, 14 

织梦内容管理系统

        PUSHBUTTON "|",          124, 80, 40, 14, 14 本文来自织梦 
        PUSHBUTTON "^",         94,  80, 56, 14, 14 
copyright dedecms
        PUSHBUTTON "<",      60,  80, 72, 14, 14 内容来自dedecms 
        PUSHBUTTON ">",      62,  80, 88, 14, 14 
dedecms.com
} copyright dedecms 

 

织梦好,好织梦

HEXCALC.ICO

织梦内容管理系统

 


  本文来自织梦

本文来自织梦


 

内容来自dedecms

dedecms.com

 


  织梦内容管理系统

copyright dedecms

  copyright dedecms

11-5 HEXCALC的萤幕显示

copyright dedecms

 

HEXCALC是一个普通的中序运算式计算机,使用C语言的符号表示方式进行计算。它对无正负号32位元整数作加、减、乘、除和取余数运算,位元AND, OR, exclusive-OR运算,还有左右位移运算。被0除将导致结果被设定为FFFFFFFF

织梦内容管理系统

HEXCALC中既可以使用滑鼠又可以使用键盘。您从按键点入」或者输入第一个数(最多8位元十六进位数位)开始,然後输入运算子,然後是第二个数。接著,您可以透过单击「Equals」按钮或者按下等号键或Enter键便可以显示运算结果。为了更正输入,您可以使用「Back」按钮、Backspace或者左箭头键。单击「display」方块或者按下Esc键即可清除目前的输入。 本文来自织梦

HEXCALC比较奇怪的一点是,萤幕上显示的视窗似乎是普通的重叠式视窗与非模态对话方块的混合体。一方面,HEXCALC的所有讯息都在函式的WndProc中处理,这个函式与通常的视窗讯息处理程式相似,该函式传回一个长整数,它处理WM_DESTROY讯息,呼叫DefWindowProc,就像普通的视窗讯息处理程式一样。另一方面,视窗是在WinMain中呼叫CreateDialog并使用HEXCALC.DLG中的对话方块模板建立的。那么,HEXCALC到底是一个普通的可重叠视窗,还是一个非模态对话方块呢? 织梦内容管理系统

简单的回答是,对话方块就是视窗。通常,Windows使用它自己内部的视窗讯息处理程式处理对话方块视窗的讯息,然後,Windows将这些讯息传送给建立对话方块的程式内的对话方块程序。在HEXCALC中,我们让Windows使用对话方块模板建立一个视窗,但是自己写程式处理这个视窗的讯息。

本文来自织梦

不幸的是,在Developer StudioDialog Editor中,对话方块模板需要一些我们不能添加的东西。因此,对话方块模板包含在HEXCALC.DLG档案中,而且需要手工输入。依照下面的方法,您可以将一个文字档案添加到任何专案中:从「 File 」功能表选择「 New 」,再选择「 Files 」页面标签,然後从档案型态列表中选择「 Text File 」。像这样的档案-包含附加资源定义-需要包含在资源描述中。从「 View 」功能表选择「 Resource Includes 」。这显示一个对话方块。在「Compile-time Directives」编辑栏输入 内容来自dedecms

#include "hexcalc.dlg" 织梦内容管理系统 

这一行将插入到HEXCALC.RC资源描述中,像上面所显示的一样。 织梦好,好织梦

仔细看一下HEXCALC.DLG档案中的对话方块模板,您将发现HEXCALC如何为对话方块使用它自己的视窗讯息处理程式。对话方块模板的上方如下:

copyright dedecms

HexCalc DIALOG -1, -1, 102, 122 copyright dedecms 
STYLE WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX copyright dedecms 
CLASS "HexCalc" 

copyright dedecms

CAPTION "Hex Calculator" copyright dedecms 

注意诸如WS_OVERLAPPEDWS_MINIMIZEBOX等识别字,我们可以将它们用在CreateWindow呼叫中以建立普通的视窗。CLASS叙述是这个对话方块与曾经建立过的对话方块之间最重要的区别(而且它也是Developer Studio中的Dialog Editor不允许我们指定的)。当对话方块模板省略了这个叙述时,Windows为对话方块注册一个视窗类别,并使用它自己的视窗讯息处理程式处理对话方块讯息。这里,包含CLASS叙述就告诉Windows将讯息发送到其他的地方-具体的说,就是发送到在HexCalc视窗类别中指定的视窗讯息处理程式。

本文来自织梦

HexCalc视窗类别是在HEXCALCWinMain函式中注册的,就像普通视窗的视窗类别一样。但是,请注意有个十分重要的区别:WNDCLASS结构的cbWndExtra栏位设定为DLGWINDOWEXTRA。对於您自己注册的对话方块程序,这是必需的。

织梦内容管理系统

在注册视窗类别之後,WinMain呼叫CreateDialog

织梦好,好织梦

hwnd = CreateDialog (hInstance, szAppName, 0, NULL) ; 
织梦好,好织梦

第二个参数(字串「HexCaEc」)是对话方块模板的名字。第三个参数通常是父视窗的视窗代号,这里设定为0,因为视窗没有父视窗。最後一个参数,通常是对话方块程序的位址,这里不需要。因为Windows不会处理这些讯息,因而也不会将讯息发送给对话方块程序。 dedecms.com

这个CreateDialog呼叫与对话方块模板一起,被Windows有效地转换为一个CreateWindow呼叫。该CreateWindow呼叫的功能与下面的呼叫相同:

织梦好,好织梦

hwnd = CreateWindow (TEXT ("HexCalc"), TEXT ("Hex Calculator"), 

织梦内容管理系统

                       WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX, 

本文来自织梦

                       CW_USEDEFAULT, CW_USEDEFAULT, 织梦好,好织梦 
                       102 * 4 / cxChar, 122 * 8 / cyChar, 本文来自织梦 
                       NULL, NULL, hInstance, NULL) ; 
本文来自织梦

其中,cxCharcyChar变数分别是系统字体字元的宽度和高度。 本文来自织梦

我们通过让Windows来进行CreateWindow呼叫而收获甚丰:Windows不会在建立弹出式视窗1後就停止,它还会为对话方块模板中定义的其他29个子视窗按键控制项呼叫CreateWindow。所有这些控制项都给父视窗的视窗讯息处理程式发送WM_COMMAND讯息,该程序正是WndProc。对於建立一个包含许多子视窗的视窗来说,这是一个很好的技巧。

dedecms.com

下面是使HEXCALC的程式码量下降到最少的另一种方法:或许您会注意到HEXCALC没有表头档案,表头档案中通常包含对话方块模板中,需要为所有子视窗控制项定义的识别字。我们之所以可以不要这个档案,是因为每个按键控制项的ID设定为出现在控制项上的文字的ASCII码。这意味著,WndProc可以完全相同地对待WM_COMMAND讯息和WM_CHAR讯息。在每种情况下,wParam的低字组都是按钮的ASCII码。

织梦内容管理系统

当然,对键盘讯息进行一些处理是必要的。WndProc拦截WM_KEYDOWN讯息,将左箭头键转换为Backspace键。在处理WM_CHAR讯息时,WndProc将字元代码转换为大写,Enter键转换为等号键的ASCII码。

织梦好,好织梦

WM_CHAR讯息的有效性是通过呼叫GetDlgItem来检验的。如果GetDlgItem函式传回0,那么键盘字元不是对话方块模板中定义的ID之一。如果字元是ID之一,则通过给相应的按钮发送一对BM_SETSTATE讯息,来使之闪烁: 内容来自dedecms

if (hButton = GetDlgItem (hwnd, wParam)) 
织梦内容管理系统
{ dedecms.com 
       SendMessage (hButton, BM_SETSTATE, 1, 0) ; 

内容来自dedecms

        Sleep (100) ;   

织梦内容管理系统

        SendMessage (hButton, BM_SETSTATE, 0, 0) ; 
内容来自dedecms
} 
内容来自dedecms

这样做,用最小的代价,却为HEXCALC的键盘介面增色不少。Sleep函式将程式暂停100毫秒。这会防止按钮被按得太快而让人注意不到。

内容来自dedecms

WndProc处理WM_COMMAND讯息时,它总是将输入焦点设定给父视窗:

本文来自织梦

case    WM_COMMAND : 
织梦好,好织梦
        SetFocus (hwnd) ; 

织梦好,好织梦

否则,一旦使用滑鼠单击某按钮,输入焦点就会切换到该按钮上。 织梦好,好织梦

通用对话方块
 

dedecms.com

Windows的一个主要目的是推动标准的使用者介面。对许多常用的功能表项来说,这推行得很快,几乎所有软体厂商都采用Alt-File-Open选择来打开一个档案。然而,实际的档案开启对话方块却经常各不相同。 织梦内容管理系统

Windows 3.1开始,对这个问题有了一个可行的解决方案,这是一种叫做「通用对话方块程式库」的增强。这个程式库由几个函式组成,这些函式启动标准对话方块来进行打开和储存档案、搜索和替换、选择颜色、选择字体(我将在本章讨论以上的这些内容)以及列印(我将在第十三章讨论)。

织梦好,好织梦

为了使用这些函式,您基本上都要初始化某一结构的各个栏位,并将该结构的指标传送给通用对话方块程式库的某个函式,该函式会建立并显示对话方块。当使用者关闭对话方块时,被呼叫的函式将控制权传回给程式,您可以从传送给它的结构中获得资讯。

织梦内容管理系统

在使用通用对话方块程式库的任何C原始码档案时,您都需要含入COMMDLG.H表头档案。通用对话方块的文件在/Platform SDK/User Interface Services/User Input/Common Dialog Box Library中。 织梦好,好织梦

增强POPPAD
  本文来自织梦

当我们往第十章的POPPAD中增加功能表时,还有几个标准功能表项没有实作。现在我们已经准备好在POPPAD中加入打开档案、读入档案以及在磁片上储存编辑过档案的功能。在处理中,我们还将在POPPAD中加入字体选择和搜索替换功能。 织梦内容管理系统

实作POPPAD3程式的档案如程式11-6所示。 dedecms.com

 程式11-6  POPPAD3 copyright dedecms 
POPPAD.C 
织梦好,好织梦
/*------------------------------------------------------------------------ dedecms.com 
   POPPAD.C -- Popup Editor 

织梦好,好织梦

                                              (c) Charles Petzold, 1998 织梦好,好织梦 
-------------------------------------------------------------------------*/ 织梦好,好织梦 
  
dedecms.com
#include <windows.h> 

copyright dedecms

#include <commdlg.h> 织梦好,好织梦 
#include "resource.h" 

织梦好,好织梦

  内容来自dedecms 
#define        EDITID   1 本文来自织梦 
#define        UNTITLED TEXT ("(untitled)") dedecms.com 
  

内容来自dedecms

LRESULT        CALLBACK WndProc      (HWND, UINT, WPARAM, LPARAM) ; 

织梦内容管理系统

BOOL           CALLBACK AboutDlgProc (HWND, UINT, WPARAM, LPARAM) ; 织梦好,好织梦 
  copyright dedecms 
               // Functions in POPFILE.C 织梦内容管理系统 
  本文来自织梦 
void    PopFileInitialize                      (HWND) ; 织梦内容管理系统 
BOOL    PopFileOpenDlg                         (HWND, PTSTR, PTSTR) ; 
织梦内容管理系统
BOOL    PopFileSaveDlg                         (HWND, PTSTR, PTSTR) ; 
本文来自织梦
BOOL    PopFileRead                            (HWND, PTSTR) ; 

dedecms.com

BOOL    PopFileWrite                           (HWND, PTSTR) ; 本文来自织梦 
  织梦好,好织梦 
               // Functions in POPFIND.C 
内容来自dedecms
  
copyright dedecms
HWND    PopFindFindDlg                         (HWND) ; 本文来自织梦 
HWND    PopFindReplaceDlg                      (HWND) ; 

本文来自织梦

BOOL    PopFindFindText                        (HWND, int *, LPFINDREPLACE) ; dedecms.com 
BOOL    PopFindReplaceText                     (HWND, int *, LPFINDREPLACE) ; 内容来自dedecms 
BOOL    PopFindNextText                        (HWND, int *) ; dedecms.com 
BOOL    PopFindValidFind                       (void) ; 内容来自dedecms 
  
织梦内容管理系统
               // Functions in POPFONT.C 织梦好,好织梦 
  dedecms.com 
void    PopFontInitialize               (HWND) ; 
dedecms.com
BOOL    PopFontChooseFont               (HWND) ; 

dedecms.com

void    PopFontSetFont                  (HWND) ; 
copyright dedecms
void PopFontDeinitialize (void) ; 
织梦好,好织梦
                       // Functions in POPPRNT.C 本文来自织梦 
  copyright dedecms 
BOOL PopPrntPrintFile (HINSTANCE, HWND, HWND, PTSTR) ; 织梦内容管理系统 
  织梦好,好织梦 
                       // Global variables 内容来自dedecms 
  内容来自dedecms 
static HWND  hDlgModeless ; dedecms.com 
static TCHAR szAppName[] = TEXT ("PopPad") ; 

织梦好,好织梦

  
内容来自dedecms
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, 本文来自织梦 
                               PSTR szCmdLine, int iCmdShow) 织梦好,好织梦 
{ 

本文来自织梦

        MSG       msg ; 

dedecms.com

        HWND      hwnd ; 内容来自dedecms 
        HACCEL    hAccel ; 
织梦好,好织梦
        WNDCLASS  wndclass ; 织梦好,好织梦 
      织梦好,好织梦 
        wndclass.style                                        = CS_HREDRAW | CS_VREDRAW ; 
本文来自织梦
        wndclass.lpfnWndProc                                  = WndProc ; 内容来自dedecms 
        wndclass.cbClsExtra                                   = 0 ; 织梦好,好织梦 
        wndclass.cbWndExtra                                   = 0 ; 织梦内容管理系统 
        wndclass.hInstance                                    = hInstance ; 内容来自dedecms 
        wndclass.hIcon                                        = LoadIcon (hInstance, szAppName) ; copyright dedecms 
        wndclass.hCursor                                      = LoadCursor (NULL, IDC_ARROW) ; 
内容来自dedecms
        wndclass.hbrBackground                        = (HBRUSH) GetStockObject (WHITE_BRUSH) ; 
dedecms.com
        wndclass.lpszMenuName                         = szAppName ; 
本文来自织梦
        wndclass.lpszClassName                        = szAppName ; 内容来自dedecms 
      

本文来自织梦

        if (!RegisterClass (&wndclass)) 本文来自织梦 
        { copyright dedecms 
                       MessageBox (   NULL, TEXT ("This program requires Windows NT!"), 内容来自dedecms 
                                      szAppName, MB_ICONERROR) ; 
本文来自织梦
                       return 0 ; 

织梦内容管理系统

        } 本文来自织梦 
      

织梦好,好织梦

        hwnd = CreateWindow (  szAppName, NULL, 本文来自织梦 
                                      WS_OVERLAPPEDWINDOW, 内容来自dedecms 
                                      CW_USEDEFAULT, CW_USEDEFAULT, 

dedecms.com

                                      CW_USEDEFAULT, CW_USEDEFAULT, 

copyright dedecms

                                      NULL, NULL, hInstance, szCmdLine) ; 
dedecms.com
      

dedecms.com

        ShowWindow (hwnd, iCmdShow) ; 
dedecms.com
        UpdateWindow (hwnd) ; dedecms.com 
        hAccel = LoadAccelerators (hInstance, szAppName) ; 本文来自织梦 
  dedecms.com 
        while (GetMessage (&msg, NULL, 0, 0)) 内容来自dedecms 
        { 
内容来自dedecms
                       if (hDlgModeless == NULL || !IsDialogMessage (hDlgModeless, &msg)) 织梦内容管理系统 
                       { 

织梦内容管理系统

                               if (!TranslateAccelerator (hwnd, hAccel, &msg)) dedecms.com 
               { copyright dedecms 
                                              TranslateMessage (&msg) ; copyright dedecms 
                                              DispatchMessage (&msg) ; dedecms.com 
                               } 

织梦好,好织梦

                       } copyright dedecms 
        } 
内容来自dedecms
        return msg.wParam ; dedecms.com 
} 

织梦好,好织梦

  内容来自dedecms 
void DoCaption (HWND hwnd, TCHAR * szTitleName) 

dedecms.com

{ 
内容来自dedecms
        TCHAR szCaption[64 + MAX_PATH] ; 
织梦内容管理系统
        wsprintf (szCaption, TEXT ("%s - %s"), szAppName, 

dedecms.com

                                      szTitleName[0] ? szTitleName : UNTITLED) ; 织梦好,好织梦 
        SetWindowText (hwnd, szCaption) ; 

本文来自织梦

} copyright dedecms 
  织梦内容管理系统 
void OkMessage (HWND hwnd, TCHAR * szMessage, TCHAR * szTitleName) 织梦内容管理系统 
{ 

本文来自织梦

        TCHAR szBuffer[64 + MAX_PATH] ; 

copyright dedecms

        wsprintf (szBuffer, szMessage, szTitleName[0] ? szTitleName : UNTITLED) ; 
织梦内容管理系统
        MessageBox (hwnd, szBuffer, szAppName, MB_OK | MB_ICONEXCLAMATION) ; 织梦内容管理系统 
} copyright dedecms 
  

内容来自dedecms

short AskAboutSave (HWND hwnd, TCHAR * szTitleName) copyright dedecms 
{ 本文来自织梦 
        TCHAR          szBuffer[64 + MAX_PATH] ; 内容来自dedecms 
        int   iReturn ; 

dedecms.com

      织梦好,好织梦 
        wsprintf (szBuffer, TEXT ("Save current changes in %s?"), 

内容来自dedecms

                                      szTitleName[0] ? szTitleName : UNTITLED) ; 

织梦好,好织梦

      dedecms.com 
        iReturn = MessageBox (hwnd, szBuffer, szAppName, copyright dedecms 
                           MB_YESNOCANCEL | MB_ICONQUESTION) ; copyright dedecms 
        if (iReturn == IDYES) 
本文来自织梦
                       if (!SendMessage (hwnd, WM_COMMAND, IDM_FILE_SAVE, 0)) 内容来自dedecms 
                                      iReturn = IDCANCEL ; 内容来自dedecms 
           
dedecms.com
        return iReturn ; 织梦好,好织梦 
} 
本文来自织梦
  
dedecms.com
LRESULT CALLBACK WndProc (     HWND hwnd, UINT message, WPARAM wParam,LPARAM lParam) 织梦内容管理系统 
{ 

本文来自织梦

        static BOOL                           bNeedSave = FALSE ; 
dedecms.com
        static HINSTANCE hInst ; dedecms.com 
        static HWND                           hwndEdit ; 
内容来自dedecms
        static int                            iOffset ; 织梦内容管理系统 
        static TCHAR                          szFileName[MAX_PATH], szTitleName[MAX_PATH] ; 
内容来自dedecms
        static UINT                           messageFindReplace ; 

copyright dedecms

        int                                   iSelBeg, iSelEnd, iEnable ; 
dedecms.com
        LPFINDREPLACE                         pfr ; 内容来自dedecms 
      本文来自织梦 
        switch (message) 

织梦好,好织梦

        { 
织梦内容管理系统
        case WM_CREATE: copyright dedecms 
                       hInst = ((LPCREATESTRUCT) lParam) -> hInstance ; dedecms.com 
                                      // Create the edit control child window 
copyright dedecms
                       hwndEdit = CreateWindow (TEXT ("edit"), NULL, 内容来自dedecms 
                         WS_CHILD | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL | 

dedecms.com

                         WS_BORDER | ES_LEFT | ES_MULTILINE | dedecms.com 
                         ES_NOHIDESEL | ES_AUTOHSCROLL | ES_AUTOVSCROLL, copyright dedecms 
                         0, 0, 0, 0, 织梦好,好织梦 
                         hwnd, (HMENU) EDITID, hInst, NULL) ; dedecms.com 
           copyright dedecms 
                       SendMessage (hwndEdit, EM_LIMITTEXT, 32000, 0L) ; copyright dedecms 
                               // Initialize common dialog box stuff 本文来自织梦 
                       PopFileInitialize (hwnd) ; 
dedecms.com
                       PopFontInitialize (hwndEdit) ; 内容来自dedecms 
           

本文来自织梦

                       messageFindReplace = RegisterWindowMessage (FINDMSGSTRING) ; 
copyright dedecms
                       DoCaption (hwnd, szTitleName) ; 

dedecms.com

                       return 0 ; 

内容来自dedecms

        case    WM_SETFOCUS: 织梦内容管理系统 
                       SetFocus (hwndEdit) ; dedecms.com 
                       return 0 ; 
内容来自dedecms
           

内容来自dedecms

        case    WM_SIZE:  

内容来自dedecms

                       MoveWindow (hwndEdit, 0, 0, LOWORD (lParam), HIWORD (lParam), TRUE) ; 织梦好,好织梦 
                       return 0 ; 

dedecms.com

           

本文来自织梦

        case    WM_INITMENUPOPUP: 织梦好,好织梦 
                       switch (lParam) 织梦内容管理系统 
                       { dedecms.com 
                       case 1:                // Edit menu 本文来自织梦 
                

本文来自织梦

                                                     // Enable Undo if edit control can do it copyright dedecms 
                dedecms.com 
                                      EnableMenuItem ((HMENU) wParam, IDM_EDIT_UNDO, 
织梦好,好织梦
                               SendMessage (hwndEdit, EM_CANUNDO, 0, 0L) ? 织梦内容管理系统 
                                         MF_ENABLED : MF_GRAYED) ; 
织梦好,好织梦
                织梦好,好织梦 
                                                     // Enable Paste if text is in the clipboard 
copyright dedecms
                copyright dedecms 
                                      EnableMenuItem ((HMENU) wParam, IDM_EDIT_PASTE, 

织梦内容管理系统

                                      IsClipboardFormatAvailable (CF_TEXT) ? copyright dedecms 
                                             MF_ENABLED : MF_GRAYED) ; 

织梦好,好织梦

                内容来自dedecms 
                                              // Enable Cut, Copy, and Del if text is selected 
织梦内容管理系统
                
本文来自织梦
                       SendMessage (hwndEdit, EM_GETSEL,     (WPARAM) &iSelBeg, 织梦内容管理系统 
                                (LPARAM) &iSelEnd) ; copyright dedecms 
                

织梦好,好织梦

                       iEnable = iSelBeg != iSelEnd ? MF_ENABLED : MF_GRAYED ; copyright dedecms 
                织梦内容管理系统 
                       EnableMenuItem ((HMENU) wParam, IDM_EDIT_CUT,   iEnable) ; 本文来自织梦 
                       EnableMenuItem ((HMENU) wParam, IDM_EDIT_COPY,  iEnable) ; 
内容来自dedecms
                       EnableMenuItem ((HMENU) wParam, IDM_EDIT_CLEAR, iEnable) ; 织梦内容管理系统 
                                      break ; dedecms.com 
                dedecms.com 
                       case 2:                               // Search menu 织梦好,好织梦 
                dedecms.com 
                                      // Enable Find, Next, and Replace if modeless 
织梦内容管理系统
                                      //   dialogs are not already active 织梦好,好织梦 
                
织梦好,好织梦
                                      iEnable = hDlgModeless == NULL ? 本文来自织梦 
                            MF_ENABLED : MF_GRAYED ; 

内容来自dedecms

                            EnableMenuItem ((HMENU) wParam, IDM_SEARCH_FIND,                iEnable) ; 

织梦好,好织梦

                                      EnableMenuItem ((HMENU) wParam, IDM_SEARCH_NEXT,              iEnable) ; 

dedecms.com

                                      EnableMenuItem ((HMENU) wParam, IDM_SEARCH_REPLACE, iEnable) ; 
内容来自dedecms
                                      break ; 
dedecms.com
                       } 
内容来自dedecms
                       return 0 ; 
织梦内容管理系统
     

织梦内容管理系统

        case    WM_COMMAND: 
内容来自dedecms
                                                     // Messages from edit control 
织梦内容管理系统
           dedecms.com 
                       if (lParam && LOWORD (wParam) == EDITID) 
织梦好,好织梦
                       { 
内容来自dedecms
                                      switch (HIWORD (wParam)) 
dedecms.com
                       { dedecms.com 
                       case    EN_UPDATE : 织梦内容管理系统 
                                              bNeedSave = TRUE ; 本文来自织梦 
                                              return 0 ; 

copyright dedecms

               case    EN_ERRSPACE : 

本文来自织梦

                       case    EN_MAXTEXT : 织梦好,好织梦 
                               MessageBox (hwnd, TEXT ("Edit control out of space."), dedecms.com 
                            szAppName, MB_OK | MB_ICONSTOP) ; 
dedecms.com
                                              return 0 ; 
织梦内容管理系统
                               } dedecms.com 
                       break ; 本文来自织梦 
                       } 

copyright dedecms

           

copyright dedecms

        switch (LOWORD (wParam)) 

内容来自dedecms

                       { 本文来自织梦 
                               // Messages from File menu dedecms.com 
                       case    IDM_FILE_NEW: 

dedecms.com

                                      if (bNeedSave && IDCANCEL == AskAboutSave (hwnd, szTitleName)) 
本文来自织梦
                                                             return 0 ; 织梦好,好织梦 
                dedecms.com 
                                      SetWindowText (hwndEdit, TEXT ("\0")) ; 
本文来自织梦
                                      szFileName[0]  = '\0' ; 

dedecms.com

                                      szTitleName[0] = '\0' ; 
dedecms.com
                                      DoCaption (hwnd, szTitleName) ; 内容来自dedecms 
                                      bNeedSave = FALSE ; copyright dedecms 
                                      return 0 ; 内容来自dedecms 
                
copyright dedecms
                       case    IDM_FILE_OPEN: copyright dedecms 
             if (bNeedSave && IDCANCEL == AskAboutSave (hwnd, szTitleName)) 织梦好,好织梦 
                return 0 ; 织梦内容管理系统 
             if (PopFileOpenDlg (hwnd, szFileName, szTitleName)) 

dedecms.com

               { 

copyright dedecms

                if (!PopFileRead (hwndEdit, szFileName)) 
织梦好,好织梦
                                                             { 

织梦内容管理系统

                 OkMessage (hwnd, TEXT ("Could not read file %s!"), 

dedecms.com

                            szTitleName) ; 内容来自dedecms 
                               szFileName[0]  = '\0' ; 织梦好,好织梦 
                               szTitleName[0] = '\0' ; 内容来自dedecms 
                                                             } 

织梦好,好织梦

                                      } copyright dedecms 
                

织梦好,好织梦

                                      DoCaption (hwnd, szTitleName) ; 

本文来自织梦

               bNeedSave = FALSE ; 内容来自dedecms 
               return 0 ; 织梦内容管理系统 
                织梦好,好织梦 
        case    IDM_FILE_SAVE: 
dedecms.com
              if      (szFileName[0]) copyright dedecms 
               { 本文来自织梦 
                       if (PopFileWrite (hwndEdit, szFileName)) 织梦好,好织梦 
                       { 

内容来自dedecms

                                      bNeedSave = FALSE ; 内容来自dedecms 
                                      return 1 ; 
内容来自dedecms
                       } 
内容来自dedecms
                       else 

内容来自dedecms

                       { 

织梦内容管理系统

                                      OkMessage (hwnd, TEXT ("Could not write file %s"), copyright dedecms 
                                              szTitleName) ; 
内容来自dedecms
                                                             return 0 ; 内容来自dedecms 
                                      } 织梦内容管理系统 
                       } 

copyright dedecms

                    //fall through 
织梦内容管理系统
               case    IDM_FILE_SAVE_AS: 织梦内容管理系统 
                       if (PopFileSaveDlg (hwnd, szFileName, szTitleName)) dedecms.com 
               { 内容来自dedecms 
                                                     DoCaption (hwnd, szTitleName) ; 织梦内容管理系统 
                     

内容来自dedecms

                                                     if (PopFileWrite (hwndEdit, szFileName)) 本文来自织梦 
                                                     { 本文来自织梦 
                                                                                    bNeedSave = FALSE ; 
本文来自织梦
                                                                                    return 1 ; 
dedecms.com
                                                     } 织梦好,好织梦 
                                                             else 织梦内容管理系统 
                                                     { 本文来自织梦 
                       OkMessage (hwnd, TEXT ("Could not write file %s"), 

本文来自织梦

                                  szTitleName) ; dedecms.com 
                                                                            return 0 ; copyright dedecms 
                                                     } 

dedecms.com

                                              } copyright dedecms 
                                      return 0 ; 织梦好,好织梦 
  内容来自dedecms 
        case    IDM_FILE_PRINT: 

织梦好,好织梦

                       if (!PopPrntPrintFile (hInst, hwnd, hwndEdit, szTitleName)) 织梦好,好织梦 
                    OkMessage (       hwnd, TEXT ("Could not print file %s"), 
copyright dedecms
                                szTitleName) ; dedecms.com 
                       return 0 ; 

织梦内容管理系统

                

copyright dedecms

               case    IDM_APP_EXIT: 织梦内容管理系统 
                       SendMessage (hwnd, WM_CLOSE, 0, 0) ; 内容来自dedecms 
                       return 0 ; 

copyright dedecms

                

dedecms.com

                                                                     // Messages from Edit menu 织梦好,好织梦 
                织梦内容管理系统 
               case    IDM_EDIT_UNDO: 织梦好,好织梦 
                       SendMessage (hwndEdit, WM_UNDO, 0, 0) ; 
copyright dedecms
                       return 0 ; 内容来自dedecms 
                
dedecms.com
               case    IDM_EDIT_CUT: dedecms.com 
                       SendMessage (hwndEdit, WM_CUT, 0, 0) ; copyright dedecms 
                       return 0 ; copyright dedecms 
                
织梦内容管理系统
               case    IDM_EDIT_COPY: 内容来自dedecms 
                       SendMessage (hwndEdit, WM_COPY, 0, 0) ; 

织梦内容管理系统

                       return 0 ; dedecms.com 
                
织梦好,好织梦
               case    IDM_EDIT_PASTE: 

织梦内容管理系统

                       SendMessage (hwndEdit, WM_PASTE, 0, 0) ; 
织梦内容管理系统
                       return 0 ; 织梦内容管理系统 
                
copyright dedecms
               case    IDM_EDIT_CLEAR: 织梦好,好织梦 
                       SendMessage (hwndEdit, WM_CLEAR, 0, 0) ; dedecms.com 
                       return 0 ; 本文来自织梦 
                dedecms.com 
               case    IDM_EDIT_SELECT_ALL: 本文来自织梦 
                       SendMessage (hwndEdit, EM_SETSEL, 0, -1) ; copyright dedecms 
                       return 0 ; 

织梦好,好织梦

                

本文来自织梦

                                                             // Messages from Search menu 织梦好,好织梦 
        case    IDM_SEARCH_FIND: 本文来自织梦 
                       SendMessage (hwndEdit, EM_GETSEL, 0, (LPARAM) &iOffset) ; 织梦内容管理系统 
                       hDlgModeless = PopFindFindDlg (hwnd) ; 

copyright dedecms

                       return 0 ; 
copyright dedecms
                

dedecms.com

               case    IDM_SEARCH_NEXT: 

copyright dedecms

                       SendMessage (hwndEdit, EM_GETSEL, 0, (LPARAM) &iOffset) ; 本文来自织梦 
                织梦好,好织梦 
                       if (PopFindValidFind ()) 织梦好,好织梦 
                                              PopFindNextText (hwndEdit, &iOffset) ; 内容来自dedecms 
                       else 
内容来自dedecms
                                              hDlgModeless = PopFindFindDlg (hwnd) ; 

织梦好,好织梦

                
copyright dedecms
                       return 0 ; 
copyright dedecms
                织梦好,好织梦 
               case    IDM_SEARCH_REPLACE: 

copyright dedecms

                       SendMessage (hwndEdit, EM_GETSEL, 0, (LPARAM) &iOffset) ; 
copyright dedecms
                       hDlgModeless = PopFindReplaceDlg (hwnd) ; dedecms.com 
                       return 0 ; 
内容来自dedecms
                dedecms.com 
               case    IDM_FORMAT_FONT: copyright dedecms 
                       if (PopFontChooseFont (hwnd)) 

织梦好,好织梦

                                              PopFontSetFont (hwndEdit) ; 
dedecms.com
                copyright dedecms 
                       return 0 ; 

织梦好,好织梦

                

内容来自dedecms

                                                             // Messages from Help menu 本文来自织梦 
                

内容来自dedecms

        case    IDM_HELP: 

本文来自织梦

                       OkMessage (hwnd,       TEXT ("Help not yet implemented!"),  

内容来自dedecms

                    TEXT ("\0")) ; 
织梦好,好织梦
                       return 0 ; 

dedecms.com

                

本文来自织梦

               case    IDM_APP_ABOUT: copyright dedecms 
                       DialogBox (hInst, TEXT ("AboutBox"), hwnd, AboutDlgProc) ; copyright dedecms 
                       return 0 ; dedecms.com 
        } copyright dedecms 
               break ; 内容来自dedecms 
case    WM_CLOSE: 织梦好,好织梦 
               if (!bNeedSave || IDCANCEL != AskAboutSave (hwnd, szTitleName)) 织梦内容管理系统 
                       DestroyWindow (hwnd) ; 
织梦内容管理系统
           内容来自dedecms 
                       return 0 ; copyright dedecms 
        case    WM_QUERYENDSESSION : 织梦内容管理系统 
                       if (!bNeedSave || IDCANCEL != AskAboutSave (hwnd, szTitleName)) 织梦好,好织梦 
                              return 1 ; 
织梦好,好织梦
           
本文来自织梦
                       return 0 ; 内容来自dedecms 
           copyright dedecms 
        case    WM_DESTROY: 

织梦内容管理系统

                       PopFontDeinitialize () ; 本文来自织梦 
                       PostQuitMessage (0) ; 
织梦好,好织梦
                       return 0 ; 
本文来自织梦
           dedecms.com 
        default: 
织梦内容管理系统
                                      // Process "Find-Replace" messages dedecms.com 
                       if (message == messageFindReplace) 织梦好,好织梦 
                       { 织梦内容管理系统 
                               pfr = (LPFINDREPLACE) lParam ; 

本文来自织梦

                               if       (pfr->Flags & FR_DIALOGTERM) 本文来自织梦 
                                                     hDlgModeless = NULL ; 织梦内容管理系统 
                
copyright dedecms
                               if       (pfr->Flags & FR_FINDNEXT) copyright dedecms 
                               if (!PopFindFindText (hwndEdit, &iOffset, pfr)) 

织梦内容管理系统

                               OkMessage (hwnd,       TEXT ("Text not found!"),  

dedecms.com

                        TEXT ("\0")) ; 

copyright dedecms

                     织梦好,好织梦 
                               if (pfr->Flags & FR_REPLACE || pfr->Flags & FR_REPLACEALL) 织梦内容管理系统 
                                              if (!PopFindReplaceText (hwndEdit, &iOffset, pfr)) 内容来自dedecms 
                                              OkMessage (hwnd,       TEXT ("Text not found!"),  copyright dedecms 
                        TEXT ("\0")) ; 织梦好,好织梦 
                          织梦好,好织梦 
                               if (pfr->Flags & FR_REPLACEALL) 

本文来自织梦

                                                     while (PopFindReplaceText (hwndEdit, &iOffset, pfr)) ; 织梦内容管理系统 
                               织梦内容管理系统 
                               return 0 ; 
本文来自织梦
               } 
织梦内容管理系统
               break ; copyright dedecms 
        } 本文来自织梦 
        return DefWindowProc (hwnd, message, wParam, lParam) ; 

内容来自dedecms

} 织梦内容管理系统 
  织梦好,好织梦 
BOOL CALLBACK AboutDlgProc (HWND hDlg, UINT message,WPARAM wParam, LPARAM lParam) 

内容来自dedecms

{ 

内容来自dedecms

        switch (message) 本文来自织梦 
        { 织梦好,好织梦 
        case    WM_INITDIALOG: 内容来自dedecms 
                       return TRUE ; copyright dedecms 
           
dedecms.com
        case    WM_COMMAND: 织梦内容管理系统 
                       switch (LOWORD (wParam)) dedecms.com 
                       { 
copyright dedecms
                       case IDOK: 内容来自dedecms 
                                      EndDialog (hDlg, 0) ; 

本文来自织梦

                                      return TRUE ; 本文来自织梦 
                       } 本文来自织梦 
                 break ; 本文来自织梦 
        } copyright dedecms 
        return FALSE ; 
织梦内容管理系统
} 织梦内容管理系统 
 POPFILE.C 内容来自dedecms 
/*-------------------------------------------------------------------------- 
织梦内容管理系统
        POPFILE.C -- Popup Editor File Functions 

织梦好,好织梦

  ------------------------------------------------------------------------*/ 

dedecms.com

  

copyright dedecms

#include <windows.h> 织梦内容管理系统 
#include <commdlg.h> 
内容来自dedecms
  内容来自dedecms 
static OPENFILENAME ofn ; 织梦好,好织梦 
void PopFileInitialize (HWND hwnd) 织梦内容管理系统 
{ 内容来自dedecms 
        static TCHAR szFilter[] =      TEXT ("Text Files (*.TXT)\0*.txt\0")  \ 
本文来自织梦
                                              TEXT ("ASCII Files (*.ASC)\0*.asc\0") \ 织梦好,好织梦 
                                              TEXT ("All Files (*.*)\0*.*\0\0") ; 织梦好,好织梦 
      copyright dedecms 
        ofn.lStructSize                       = sizeof (OPENFILENAME) ; 

织梦好,好织梦

        ofn.hwndOwner                         = hwnd ; 

织梦内容管理系统

        ofn.hInstance                         = NULL ; 

织梦好,好织梦

        ofn.lpstrFilter                       = szFilter ; dedecms.com 
        ofn.lpstrCustomFilter = NULL ; 
内容来自dedecms
        ofn.nMaxCustFilter    = 0 ; 织梦内容管理系统 
        ofn.nFilterIndex      = 0 ; copyright dedecms 
        ofn.lpstrFile         = NULL ;               // Set in Open and Close functions dedecms.com 
        ofn.nMaxFile                   = MAX_PATH ; 

织梦好,好织梦

        ofn.lpstrFileTitle             = NULL ;               // Set in Open and Close functions 织梦内容管理系统 
        ofn.nMaxFileTitle              = MAX_PATH ; 

dedecms.com

        ofn.lpstrInitialDir            = NULL ; 织梦内容管理系统 
        ofn.lpstrTitle                 = NULL ; dedecms.com 
        ofn.Flags                      = 0 ;                          // Set in Open and Close functions 

织梦内容管理系统

        ofn.nFileOffset                = 0 ; 
内容来自dedecms
        ofn.nFileExtension             = 0 ; 

内容来自dedecms

        ofn.lpstrDefExt                = TEXT ("txt") ; 
dedecms.com
        ofn.lCustData                  = 0L ; 织梦好,好织梦 
        ofn.lpfnHook                   = NULL ; 
本文来自织梦
        ofn.lpTemplateName             = NULL ; 
本文来自织梦
} 

本文来自织梦

  
本文来自织梦
BOOL PopFileOpenDlg (HWND hwnd, PTSTR pstrFileName, PTSTR pstrTitleName) 

本文来自织梦

{ 

内容来自dedecms

        ofn.hwndOwner                  = hwnd ; 
内容来自dedecms
        ofn.lpstrFile                  = pstrFileName ; 织梦内容管理系统 
        ofn.lpstrFileTitle             = pstrTitleName ; 
本文来自织梦
        ofn.Flags                      = OFN_HIDEREADONLY | OFN_CREATEPROMPT ; copyright dedecms 
      dedecms.com 
        return GetOpenFileName (&ofn) ; dedecms.com 
} 
织梦内容管理系统
  

织梦内容管理系统

BOOL PopFileSaveDlg (HWND hwnd, PTSTR pstrFileName, PTSTR pstrTitleName) 
织梦内容管理系统
{ 织梦内容管理系统 
        ofn.hwndOwner                  = hwnd ; 织梦好,好织梦 
        ofn.lpstrFile                  = pstrFileName ; 织梦内容管理系统 
        ofn.lpstrFileTitle             = pstrTitleName ; 

dedecms.com

        ofn.Flags                      = OFN_OVERWRITEPROMPT ; 织梦内容管理系统 
      dedecms.com 
        return GetSaveFileName (&ofn) ; 织梦好,好织梦 
} 

织梦好,好织梦

  copyright dedecms 
BOOL PopFileRead (HWND hwndEdit, PTSTR pstrFileName) 
copyright dedecms
{ 织梦好,好织梦 
        BYTE                   bySwap ; dedecms.com 
        DWORD                  dwBytesRead ; dedecms.com 
        HANDLE             hFile ; 织梦内容管理系统 
        int                    i, iFileLength, iUniTest ; 

本文来自织梦

        PBYTE                  pBuffer, pText, pConv ; 

织梦内容管理系统

  内容来自dedecms 
                                      // Open the file. copyright dedecms 
        if (INVALID_HANDLE_VALUE ==  内容来自dedecms 
                       (hFile = CreateFile (pstrFileName, GENERIC_READ, FILE_SHARE_READ, 织梦内容管理系统 
                         NULL, OPEN_EXISTING, 0, NULL))) 
copyright dedecms
               return FALSE ; 
织梦内容管理系统
                       // Get file size in bytes and allocate memory for read. 

本文来自织梦

                       // Add an extra two bytes for zero termination. 织梦内容管理系统 
                     织梦好,好织梦 
        iFileLength = GetFileSize (hFile, NULL) ;  

copyright dedecms

        pBuffer = malloc (iFileLength + 2) ; 

内容来自dedecms

  织梦好,好织梦 
                       // Read file and put terminating zeros at end. 
织梦内容管理系统
        ReadFile (hFile, pBuffer, iFileLength, &dwBytesRead, NULL) ; 内容来自dedecms 
        CloseHandle (hFile) ; 

copyright dedecms

        pBuffer[iFileLength] = '\0' ; 

织梦内容管理系统

        pBuffer[iFileLength + 1] = '\0' ; 

织梦好,好织梦

  

本文来自织梦

                       // Test to see if the text is Unicode 织梦好,好织梦 
        iUniTest = IS_TEXT_UNICODE_SIGNATURE | IS_TEXT_UNICODE_REVERSE_SIGNATURE ; dedecms.com 
        if (IsTextUnicode (pBuffer, iFileLength, &iUniTest)) dedecms.com 
{ copyright dedecms 
                       pText = pBuffer + 2 ; 本文来自织梦 
                       iFileLength -= 2 ; 

织梦好,好织梦

  

dedecms.com

               if (iUniTest & IS_TEXT_UNICODE_REVERSE_SIGNATURE) 内容来自dedecms 
          { 

copyright dedecms

                       for (i = 0 ; i < iFileLength / 2 ; i++) dedecms.com 
                       { 
copyright dedecms
                                      bySwap = ((BYTE *) pText) [2 * i] ; 

内容来自dedecms

                        ((BYTE *) pText) [2 * i] = ((BYTE *) pText) [2 * i + 1] ; 

内容来自dedecms

                       ((BYTE *) pText) [2 * i + 1] = bySwap ; 
内容来自dedecms
                       } dedecms.com 
          } 
copyright dedecms
  
内容来自dedecms
                               // Allocate memory for possibly converted string 
内容来自dedecms
                       pConv = malloc (iFileLength + 2) ; 
内容来自dedecms
                               // If the edit control is not Unicode, convert Unicode text to  dedecms.com 
                               // non-Unicode (i.e., in general, wide character). 
织梦内容管理系统
#ifndef UNICODE 织梦好,好织梦 
                       WideCharToMultiByte (CP_ACP, 0, (PWSTR) pText, -1, pConv,  
copyright dedecms
                       iFileLength + 2, NULL, NULL) ; 

dedecms.com

                               // If the edit control is Unicode, just copy the string 织梦内容管理系统 
#else 织梦内容管理系统 
               lstrcpy ((PTSTR) pConv, (PTSTR) pText) ; 内容来自dedecms 
#endif copyright dedecms 
  
copyright dedecms
     } 
织梦内容管理系统
        else                   // the file is not Unicode 
dedecms.com
      { 
内容来自dedecms
               pText = pBuffer ; copyright dedecms 
                               // Allocate memory for possibly converted string. 织梦内容管理系统 
                       pConv = malloc (2 * iFileLength + 2) ; 内容来自dedecms 
                               // If the edit control is Unicode, convert ASCII text. 
织梦内容管理系统
#ifdef UNICODE 

本文来自织梦

               MultiByteToWideChar (CP_ACP, 0, pText, -1, (PTSTR) pConv,  
dedecms.com
                                              iFileLength + 1) ; 

内容来自dedecms

                                              // If not, just copy buffer 

copyright dedecms

#else 

织梦好,好织梦

                       lstrcpy ((PTSTR) pConv, (PTSTR) pText) ; 本文来自织梦 
#endif 织梦好,好织梦 
        } 
内容来自dedecms
      
内容来自dedecms
        SetWindowText (hwndEdit, (PTSTR) pConv) ; 织梦内容管理系统 
        free (pBuffer) ; 
内容来自dedecms
        free (pConv) ; 
织梦好,好织梦
    
内容来自dedecms
        return TRUE ; 本文来自织梦 
} 

内容来自dedecms

  

本文来自织梦

BOOL PopFileWrite (HWND hwndEdit, PTSTR pstrFileName) 内容来自dedecms 
{ 
织梦内容管理系统
        DWORD          dwBytesWritten ; 织梦内容管理系统 
        HANDLE     hFile ; 内容来自dedecms 
        int            iLength ; 
dedecms.com
        PTSTR          pstrBuffer ; 

织梦内容管理系统

        WORD           wByteOrderMark = 0xFEFF ; 本文来自织梦 
                               // Open the file, creating it if necessary 
织梦好,好织梦
      
dedecms.com
        if (INVALID_HANDLE_VALUE ==  

dedecms.com

                       (hFile = CreateFile (pstrFileName, GENERIC_WRITE, 0,  copyright dedecms 
                NULL, CREATE_ALWAYS, 0, NULL))) 
本文来自织梦
                       return FALSE ; 

本文来自织梦

                       // Get the number of characters in the edit control and allocate 本文来自织梦 
                       // memory for them. 
本文来自织梦
      织梦好,好织梦 
        iLength = GetWindowTextLength (hwndEdit) ; 
织梦好,好织梦
        pstrBuffer = (PTSTR) malloc ((iLength + 1) * sizeof (TCHAR)) ; 
内容来自dedecms
      

内容来自dedecms

        if (!pstrBuffer) 内容来自dedecms 
        { 织梦好,好织梦 
                       CloseHandle (hFile) ; 本文来自织梦 
                       return FALSE ; 
copyright dedecms
        } 

copyright dedecms

  

copyright dedecms

                       // If the edit control will return Unicode text, write the 本文来自织梦 
                       // byte order mark to the file. copyright dedecms 
  

织梦好,好织梦

#ifdef UNICODE 
dedecms.com
        WriteFile (hFile, &wByteOrderMark, 2, &dwBytesWritten, NULL) ; dedecms.com 
#endif 
dedecms.com
                       // Get the edit buffer and write that out to the file. 
内容来自dedecms
        GetWindowText (hwndEdit, pstrBuffer, iLength + 1) ; 织梦好,好织梦 
        WriteFile (hFile, pstrBuffer, iLength * sizeof (TCHAR),  
织梦内容管理系统
                                              &dwBytesWritten, NULL) ; 

dedecms.com

        if ((iLength * sizeof (TCHAR)) != (int) dwBytesWritten) copyright dedecms 
     { 
织梦好,好织梦
                       CloseHandle (hFile) ; 内容来自dedecms 
                       free (pstrBuffer) ; 

织梦好,好织梦

                       return FALSE ; 
dedecms.com
        } 

织梦好,好织梦

      
织梦好,好织梦
        CloseHandle (hFile) ; 

内容来自dedecms

        free (pstrBuffer) ; 织梦内容管理系统 
      

本文来自织梦

        return TRUE ; 

织梦内容管理系统

} 
本文来自织梦
 POPFIND.C copyright dedecms 
/*-------------------------------------------------------------------------- dedecms.com 
   POPFIND.C -- Popup Editor Search and Replace Functions 
织梦好,好织梦
  ------------------------------------------------------------------------*/ dedecms.com 
  

内容来自dedecms

#include <windows.h> 本文来自织梦 
#include <commdlg.h> 
织梦好,好织梦
#include <tchar.h>                    // for _tcsstr (strstr for Unicode & non-Unicode) 本文来自织梦 
  

织梦好,好织梦

#define MAX_STRING_LEN   256 

织梦好,好织梦

  
copyright dedecms
static TCHAR szFindText [MAX_STRING_LEN] ; 织梦内容管理系统 
static TCHAR szReplText [MAX_STRING_LEN] ; 织梦好,好织梦 
  
dedecms.com
HWND PopFindFindDlg (HWND hwnd) 
织梦内容管理系统
{ 本文来自织梦 
        static FINDREPLACE fr ;        // must be static for modeless dialog!!! 

本文来自织梦

      
内容来自dedecms
        fr.lStructSize                 = sizeof (FINDREPLACE) ; 本文来自织梦 
        fr.hwndOwner                   = hwnd ; 本文来自织梦 
        fr.hInstance                   = NULL ; 织梦内容管理系统 
        fr.Flags                       = FR_HIDEUPDOWN | FR_HIDEMATCHCASE | FR_HIDEWHOLEWORD ; 

copyright dedecms

        fr.lpstrFindWhat               = szFindText ; 
copyright dedecms
        fr.lpstrReplaceWith            = NULL ; 
copyright dedecms
        fr.wFindWhatLen                = MAX_STRING_LEN ; 织梦好,好织梦 
        fr.wReplaceWithLen             = 0 ; 
内容来自dedecms
        fr.lCustData                   = 0 ; 织梦好,好织梦 
        fr.lpfnHook                    = NULL ; copyright dedecms 
        fr.lpTemplateName              = NULL ; 

内容来自dedecms

      
织梦好,好织梦
        return FindText (&fr) ; 织梦内容管理系统 
} 

copyright dedecms

  
copyright dedecms
HWND PopFindReplaceDlg (HWND hwnd) 本文来自织梦 
{ dedecms.com 
        static FINDREPLACE fr ;        // must be static for modeless dialog!!! 
织梦内容管理系统
      
dedecms.com
        fr.lStructSize                 = sizeof (FINDREPLACE) ; 本文来自织梦 
        fr.hwndOwner                   = hwnd ; 
织梦好,好织梦
        fr.hInstance                   = NULL ; 
本文来自织梦
        fr.Flags                       = FR_HIDEUPDOWN | FR_HIDEMATCHCASE | FR_HIDEWHOLEWORD ; 

copyright dedecms

        fr.lpstrFindWhat               = szFindText ; 
copyright dedecms
        fr.lpstrReplaceWith            = szReplText ; 内容来自dedecms 
        fr.wFindWhatLen                = MAX_STRING_LEN ; 内容来自dedecms 
        fr.wReplaceWithLen             = MAX_STRING_LEN ; 本文来自织梦 
        fr.lCustData                   = 0 ; 内容来自dedecms 
        fr.lpfnHook                    = NULL ; copyright dedecms 
        fr.lpTemplateName              = NULL ; 

copyright dedecms

      织梦内容管理系统 
        return ReplaceText (&fr) ; 
织梦好,好织梦
} 本文来自织梦 
  dedecms.com 
BOOL PopFindFindText (HWND hwndEdit, int * piSearchOffset, LPFINDREPLACE pfr) 
织梦内容管理系统
{ 内容来自dedecms 
        int    iLength, iPos ; 本文来自织梦 
        PTSTR  pstrDoc, pstrPos ; 
copyright dedecms
      

织梦内容管理系统

                               // Read in the edit document 

内容来自dedecms

      

copyright dedecms

        iLength = GetWindowTextLength (hwndEdit) ; copyright dedecms 
      织梦好,好织梦 
        if (NULL == (pstrDoc = (PTSTR) malloc ((iLength + 1) * sizeof (TCHAR)))) 
织梦好,好织梦
                       return FALSE ; 

dedecms.com

      dedecms.com 
        GetWindowText (hwndEdit, pstrDoc, iLength + 1) ; 
copyright dedecms
      织梦内容管理系统 
                               // Search the document for the find string 
dedecms.com
      
内容来自dedecms
        pstrPos = _tcsstr (pstrDoc + * piSearchOffset, pfr->lpstrFindWhat) ; 本文来自织梦 
        free (pstrDoc) ; 

copyright dedecms

      织梦内容管理系统 
                               // Return an error code if the string cannot be found dedecms.com 
      dedecms.com 
        if (pstrPos == NULL) 织梦好,好织梦 
                       return FALSE ; dedecms.com 
      

内容来自dedecms

                               // Find the position in the document and the new start offset 内容来自dedecms 
      copyright dedecms 
        iPos = pstrPos - pstrDoc ; 内容来自dedecms 
        * piSearchOffset = iPos + lstrlen (pfr->lpstrFindWhat) ; 
内容来自dedecms
      copyright dedecms 
                               // Select the found text 内容来自dedecms 
        SendMessage (hwndEdit, EM_SETSEL, iPos, * piSearchOffset) ; 
织梦好,好织梦
        SendMessage (hwndEdit, EM_SCROLLCARET, 0, 0) ; copyright dedecms 
      
织梦内容管理系统
        return TRUE ; 内容来自dedecms 
} copyright dedecms 
BOOL PopFindNextText (HWND hwndEdit, int * piSearchOffset) 
dedecms.com
{ 

dedecms.com

        FINDREPLACE fr ; copyright dedecms 
     fr.lpstrFindWhat = szFindText ; 
dedecms.com
     return PopFindFindText (hwndEdit, piSearchOffset, &fr) ; 织梦内容管理系统 
} 
织梦好,好织梦
  

内容来自dedecms

BOOL PopFindReplaceText (HWND hwndEdit, int * piSearchOffset, LPFIND,REPLACE pfr) 织梦好,好织梦 
{ 本文来自织梦 
          // Find the text 
内容来自dedecms
     if (!PopFindFindText (hwndEdit, piSearchOffset, pfr)) 

dedecms.com

          return FALSE ; 

织梦内容管理系统

      织梦好,好织梦 
          // Replace it 

织梦好,好织梦

     SendMessage (     hwndEdit, EM_REPLACESEL, 0, (LPARAM) pfr-> 织梦好,好织梦 
lpstrReplaceWith) ; 
copyright dedecms
     return TRUE ; 织梦好,好织梦 
} 织梦内容管理系统 
  copyright dedecms 
BOOL PopFindValidFind (void) 内容来自dedecms 
{ 
织梦好,好织梦
     return * szFindText != '\0' ; 

织梦内容管理系统

} 
dedecms.com
 POPFONT.C 
copyright dedecms
/*---------------------------------------------------- 

dedecms.com

   POPFONT.C -- Popup Editor Font Functions 内容来自dedecms 
------------------------------------------------------*/ 织梦内容管理系统 
  dedecms.com 
#include <windows.h> 
copyright dedecms
#include <commdlg.h> 
内容来自dedecms
  
dedecms.com
static LOGFONT logfont ; copyright dedecms 
static HFONT   hFont ; 内容来自dedecms 
  
织梦好,好织梦
BOOL PopFontChooseFont (HWND hwnd) 本文来自织梦 
{ dedecms.com 
     CHOOSEFONT cf ; 织梦好,好织梦 
        cf.lStructSize                 = sizeof (CHOOSEFONT) ; 内容来自dedecms 
        cf.hwndOwner                   = hwnd ; dedecms.com 
        cf.hDC                         = NULL ; 

本文来自织梦

        cf.lpLogFont                   = &logfont ; 
织梦内容管理系统
        cf.iPointSize                  = 0 ; 

织梦内容管理系统

        cf.Flags                              = CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS | CF_EFFECTS ; dedecms.com 
        cf.rgbColors                          = 0 ; 内容来自dedecms 
        cf.lCustData                          = 0 ; 本文来自织梦 
        cf.lpfnHook                           = NULL ; 
织梦内容管理系统
        cf.lpTemplateName                  = NULL ; 织梦内容管理系统 
        cf.hInstance                          = NULL ; 

内容来自dedecms

        cf.lpszStyle                          = NULL ; 织梦好,好织梦 
        cf.nFontType                          = 0 ;                          // Returned from ChooseFont 

织梦好,好织梦

        cf.nSizeMin                                   = 0 ; 

本文来自织梦

        cf.nSizeMax                                   = 0 ; 
织梦好,好织梦
      织梦内容管理系统 
        return ChooseFont (&cf) ; dedecms.com 
} 
内容来自dedecms
  
内容来自dedecms
void PopFontInitialize (HWND hwndEdit) 织梦内容管理系统 
{ 内容来自dedecms 
        GetObject (GetStockObject (SYSTEM_FONT), sizeof (LOGFONT),  

内容来自dedecms

                                              (PTSTR) &logfont) ; 

dedecms.com

        hFont = CreateFontIndirect (&logfont) ; 本文来自织梦 
        SendMessage (hwndEdit, WM_SETFONT, (WPARAM) hFont, 0) ; copyright dedecms 
} 
本文来自织梦
  织梦好,好织梦 
void PopFontSetFont (HWND hwndEdit) 
本文来自织梦
{ 

copyright dedecms

        HFONT hFontNew ; 

dedecms.com

       RECT  rect ; 本文来自织梦 
      

内容来自dedecms

        hFontNew = CreateFontIndirect (&logfont) ; 
本文来自织梦
        SendMessage (hwndEdit, WM_SETFONT, (WPARAM) hFontNew, 0) ; 

本文来自织梦

        DeleteObject (hFont) ; 
copyright dedecms
        hFont = hFontNew ; 
织梦内容管理系统
        GetClientRect (hwndEdit, &rect) ; 本文来自织梦 
        InvalidateRect (hwndEdit, &rect, TRUE) ; 
织梦内容管理系统
} dedecms.com 
  织梦内容管理系统 
void    PopFontDeinitialize (void) 
本文来自织梦
{ 织梦内容管理系统 
        DeleteObject (hFont) ; 织梦内容管理系统 
} 
copyright dedecms
 POPPRNT0.C copyright dedecms 
/*------------------------------------------------------------------------ 
dedecms.com
   POPPRNT0.C -- Popup Editor Printing Functions (dummy version) 

copyright dedecms

--------------------------------------------------------------------------*/ copyright dedecms 
  织梦内容管理系统 
#include <windows.h> 织梦内容管理系统 
BOOL PopPrntPrintFile (        HINSTANCE hInst, HWND hwnd, HWND hwndEdit, 

内容来自dedecms

                                                                            PTSTR pstrTitleName) 
dedecms.com
{ 织梦内容管理系统 
        return FALSE ; 

内容来自dedecms

} 

内容来自dedecms

 POPPAD.RC (摘录) 织梦内容管理系统 
//Microsoft Developer Studio generated resource script. copyright dedecms 
#include "resource.h" 
copyright dedecms
#include "afxres.h" 
dedecms.com
  copyright dedecms 
///////////////////////////////////////////////////////////////////////////// 
织梦好,好织梦
// Dialog 织梦内容管理系统 
ABOUTBOX DIALOG DISCARDABLE  32, 32, 180, 100 本文来自织梦 
STYLE DS_MODALFRAME | WS_POPUP 

内容来自dedecms

FONT 8, "MS Sans Serif" 
织梦好,好织梦
BEGIN 
dedecms.com
        DEFPUSHBUTTON "OK",IDOK,66,80,50,14 织梦内容管理系统 
        ICON                                                          "POPPAD",IDC_STATIC,7,7,20,20 

dedecms.com

        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 copyright dedecms 
PRINTDLGBOX DIALOG DISCARDABLE  32, 32, 186, 95 内容来自dedecms 
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU 内容来自dedecms 
CAPTION "PopPad" copyright dedecms 
FONT 8, "MS Sans Serif" 

内容来自dedecms

BEGIN 内容来自dedecms 
        PUSHBUTTON    "Cancel",IDCANCEL,67,74,50,14 内容来自dedecms 
        CTEXT                                                 "Sending",IDC_STATIC,8,8,172,8 
copyright dedecms
        CTEXT         "",IDC_FILENAME,8,28,172,8 
dedecms.com
        CTEXT         "to print spooler.",IDC_STATIC,8,48,172,8 
织梦内容管理系统
END 织梦好,好织梦 
  

织梦好,好织梦

///////////////////////////////////////////////////////////////////////////// 
本文来自织梦
// Menu 
织梦好,好织梦
POPPAD MENU DISCARDABLE  

内容来自dedecms

BEGIN 

织梦好,好织梦

        POPUP           "&File" 
dedecms.com
        BEGIN 

内容来自dedecms

        MENUITEM       "&New\tCtrl+N",    IDM_FILE_NEW 

copyright dedecms

    MENUITEM   "&Open...\tCtrl+O",IDM_FILE_OPEN 

本文来自织梦

        MENUITEM       "&Save\tCtrl+S",   IDM_FILE_SAVE 织梦内容管理系统 
        MENUITEM       "Save &As...",     IDM_FILE_SAVE_AS dedecms.com 
        MENUITEM       SEPARATOR dedecms.com 
        MENUITEM       "&Print\tCtrl+P",  IDM_FILE_PRINT 织梦内容管理系统 
        MENUITEM       SEPARATOR dedecms.com 
        MENUITEM       "E&xit",           IDM_APP_EXIT 

本文来自织梦

END 
内容来自dedecms
        POPUP "&Edit" 

本文来自织梦

BEGIN 内容来自dedecms 
        MENUITEM       "&Undo\tCtrl+Z",   IDM_EDIT_UNDO 
织梦好,好织梦
        MENUITEM       SEPARATOR dedecms.com 
        MENUITEM       "Cu&t\tCtrl+X",    IDM_EDIT_CUT dedecms.com 
        MENUITEM       "&Copy\tCtrl+C",   IDM_EDIT_COPY 

内容来自dedecms

        MENUITEM       "&Paste\tCtrl+V",  IDM_EDIT_PASTE dedecms.com 
        MENUITEM       "De&lete\tDel",    IDM_EDIT_CLEAR copyright dedecms 
        MENUITEM       SEPARATOR 
织梦好,好织梦
        MENUITEM       "&Select All",     IDM_EDIT_SELECT_ALL 

本文来自织梦

END 织梦好,好织梦 
        POPUP       "&Search" dedecms.com 
BEGIN    织梦好,好织梦 
       MENUITEM       "&Find...\tCtrl+F",IDM_SEARCH_FIND copyright dedecms 
        MENUITEM       "Find &Next\tF3",  IDM_SEARCH_NEXT 织梦好,好织梦 
        MENUITEM       "&Replace...\tCtrl+R", IDM_SEARCH_REPLACE 本文来自织梦 
END 

内容来自dedecms

        POPUP       "F&ormat" 织梦好,好织梦 
BEGIN 织梦内容管理系统 
        MENUITEM       "&Font...",              

织梦内容管理系统

END 本文来自织梦 
        POPUP   "&Help" 
copyright dedecms
       BEGIN 织梦好,好织梦 
       MENUITEM        "&Help",                  IDM_HELP 
织梦内容管理系统
        MENUITEM        "&About PopPad...",  IDM_APP_ABOUT 内容来自dedecms 
        END 内容来自dedecms 
END 本文来自织梦 
///////////////////////////////////////////////////////////////////////////// dedecms.com 
// Accelerator dedecms.com 
POPPAD ACCELERATORS DISCARDABLE  dedecms.com 
BEGIN dedecms.com 
        VK_BACK,       IDM_EDIT_UNDO,   VIRTKEY,      ALT,     NOINVERT 

织梦内容管理系统

        VK_DELETE,  IDM_EDIT_CLEAR,  VIRTKEY,         NOINVERT 织梦好,好织梦 
        VK_DELETE,  IDM_EDIT_CUT,    VIRTKEY,         SHIFT,   NOINVERT 
copyright dedecms
        VK_F1,      IDM_HELP,        VIRTKEY,         NOINVERT 本文来自织梦 
        VK_F3,      IDM_SEARCH_NEXT, VIRTKEY,         NOINVERT copyright dedecms 
        VK_INSERT,  IDM_EDIT_COPY,   VIRTKEY,         CONTROL,  NOINVERT 
copyright dedecms
        VK_INSERT,                     IDM_EDIT_PASTE,        VIRTKEY,       SHIFT, NOINVERT 织梦好,好织梦 
        "^C",         IDM_EDIT_COPY,         ASCII,  NOINVERT dedecms.com 
        "^F",          IDM_SEARCH_FIND,       ASCII,         NOINVERT 
copyright dedecms
       "^N",          IDM_FILE_NEW,          ASCII,         NOINVERT dedecms.com 
        "^O",          IDM_FILE_OPEN,         ASCII,         NOINVERT 
织梦内容管理系统
        "^P",         IDM_FILE_PRINT,        ASCII,  NOINVERT 
dedecms.com
        "^R",         IDM_SEARCH_REPLACE,    ASCII,  NOINVERT 

本文来自织梦

        "^S",         IDM_FILE_SAVE,         ASCII,  NOINVERT 织梦好,好织梦 
        "^V",         IDM_EDIT_PASTE,        ASCII,  NOINVERT 

织梦好,好织梦

        "^X",         IDM_EDIT_CUT,          ASCII,  NOINVERT 

内容来自dedecms

        "^Z",         IDM_EDIT_UNDO,         ASCII,  NOINVERT 

内容来自dedecms

END dedecms.com 
  内容来自dedecms 
///////////////////////////////////////////////////////////////////////////// copyright dedecms 
// Icon 织梦内容管理系统 
POPPAD                                                       ICON    DISCARDABLE     "poppad.ico" 本文来自织梦 
 RESOURCE.H (摘录) copyright dedecms 
// Microsoft Developer Studio generated include file. 

织梦内容管理系统

// Used by poppad.rc 

dedecms.com

  dedecms.com 
#define IDC_FILENAME          1000 

dedecms.com

#define IDM_FILE_NEW          40001 
织梦内容管理系统
#define IDM_FILE_OPEN         40002 

织梦好,好织梦

#define IDM_FILE_SAVE         40003 
内容来自dedecms
#define IDM_FILE_SAVE_AS      40004 dedecms.com 
#define IDM_FILE_PRINT        40005 
内容来自dedecms
#define IDM_APP_EXIT          40006 
内容来自dedecms
#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 内容来自dedecms 
#define IDM_SEARCH_FIND       40013 

织梦内容管理系统

#define IDM_SEARCH_NEXT       40014 
织梦好,好织梦
#define IDM_SEARCH_REPLACE    40015 
织梦好,好织梦
#define IDM_FORMAT_FONT       40016 dedecms.com 
#define IDM_HELP              40017 
织梦好,好织梦
#define IDM_APP_ABOUT         40018 
内容来自dedecms

 

织梦好,好织梦

POPPAD.ICO 内容来自dedecms

 


 

copyright dedecms

织梦好,好织梦


 

织梦好,好织梦

本文来自织梦

 

为了避免在第十三章中重复原始码,我在POPPAD.RC的功能表中加入了列印专案和一些其他的支援。

dedecms.com

POPPAD.C包含了程式中所有的基本原始码。POPFILE.C具有启动File OpenFile Save对话方块的程式码,它还包含档案I/O常式。POPFIND.C中包含了搜寻和替换文字功能。POPFONT.C包含了字体选择功能。POPPRNT0.C不完成什么工作:在第十三章中将使用POPPRNT.C替换POPPRNT0.C以建立最终的POPPAD程式。

本文来自织梦

让我们先来看一看POPPAD.CPOPPAD.C含有两个档案名字串:第一个,储存在WndProc,名称为szFileName,含有详细的驱动器名称、路径名称和档案名称;第二个,储存为szTitleName,是程式本身的档案名称。它用在POPPAD3DoCaption函式中,以便将档案名称显示在视窗的标题列上;也用在OKMessage函式和AskAboutSave函式中,以便向使用者显示讯息方块。 本文来自织梦

POPFILE.C包含了几个显示「File Open」和「File Save」对话方块以及实际执行档案I/O的函式。对话方块是使用函式GetOpenFileNameGetSaveFileName来显示的。这两个函式都使用一个型态为OPENFILENAME的结构,这个结构在COMMDLG.H中定义。在POPFILE.C中,使用了一个该结构型态的整体变数,取名为ofnofn的大多数栏位在PopFileInitialize函式中被初始化,POPPAD.CWndProc中处理WM_CREATE讯息时呼叫该函式。 内容来自dedecms

ofn作为静态整体结构变数会比较方便,因为GetOpenFileNameGetSaveFileName给该结构传回的一些资讯,并将在以後呼叫这些函式时用到。 dedecms.com

尽管通用对话方块具有许多选项-包括设定自己的对话方块模板,以及为对话方块程序增加「挂勾(hook)」-POPFILE.C中使用的「File Open」和「File Save」对话方块是最基本的。OPENFILENAME结构中被设定的栏位只有lStructSize(结构的长度)、hwndOwner(对话方块拥有者)、lpstrFilter(下面将简要讨论)、lpstrFilenMaxFile(指向接收完整档案名称的缓冲区指标和该缓冲区的大小)、lpstrFileTitlenMaxFileTitle(档案名称缓冲区及其大小)、Flags(设定对话方块的选项)和lpstrDefExt(如果使用者在对话方块中输入档案名时不指定档案副档名,那么它就是内定的档案副档名)。 copyright dedecms

当使用者在「File」功能表中选择「Open」时,POPPAD3呼叫POPFILEPopFileOpenDlg函式,将视窗代号、一个指向档案名称缓冲区的指标和一个指向档案标题缓冲区的指标传给它。PopFileOpenDlg恰当地设定OPENFILENAME结构的hwndOwnerlpstrFilelpstrFileTitle栏位,将Flags设定为OFN_ CREATEPROMPT,然後呼叫GetOpenFileName,显示如图11-6所示的普通对话方块。 织梦好,好织梦


  内容来自dedecms

织梦内容管理系统

  内容来自dedecms

11-6 File Open」对话方块

dedecms.com

 

当使用者结束这个对话方块时,GetOpenFileName函式传回。OFN_CREATEPROMPT旗标指示GetOpenFileName显示一个讯息方块,询问使用者如果所选档案不存在,是否要建立该档案。 dedecms.com

左下角的下拉式清单方块列出了将要显示在档案列表中的档案型态,此清单方块被称为「筛选清单」。使用者可以通过从下拉式清单方块列表中选择另一种档案型态,来改变筛选条件。在POPFILE.CPopFileInitialize函式中,我在变数szFilter(一个字串阵列)中为三种型态的档案定义了一个筛检清单:带有.TXT副档名的文字档案、带有.ASC副档名的ASCII档案和所有档案。OPENFILENAME结构的lpstrFilter栏位储存指向此阵列第一个字串的指标。 织梦好,好织梦

如果使用者在对话方块处於活动状态时改变了筛选条件,那么OPENFILENAMEnFilterIndex栏位反映出使用者的选择。由於该结构是静态变数,下次启动对话方块时,筛选条件将被设定为选中的档案型态。 copyright dedecms

POPFILE.C中的PopFileSaveDlg函式与此类似,它将Flags参数设定为OFN_OVERWRITEPROMPT,并呼叫GetSaveFileName启动「File Save」对话方块。OFN_OVERWRITEPROMPT旗标导致显示一个讯息方块,如果被选档案已经存在,那么将询问使用者是否覆盖该档案。 内容来自dedecms

Unicode档案I/O
  copyright dedecms

对於本书中的大多数程式,您都不必注意Unicode和非Unicode版的区别。例如,在POPPAD3Unicode中,编辑控制项将保留Unicode文字和使用Unicode字串的所有通用对话方块。例如,当程式需要搜索和替换时,所有的操作都会处理Unicode字串,而不需要转换。 dedecms.com

不过,POPPAD3得处理档案I/O,也就是说,程式不能闭门造车。如果Unicode版的POPPAD3获得了编辑缓冲区的内容并将其写入磁片,档案将是使用Unicode存放的。如果非Unicode版的POPPAD3读取了该档案,并将其写入编辑缓冲区,其结果将是一堆垃圾。Unicode版读取由非Unicode版储存的档案时也会这样。

copyright dedecms

解决的办法在於辨别和转换。首先,在POPFILE.CPopFileWrite函式中,您将看到Unicode版的程式将在档案的开始位置写入0xFEFF。这定义为位元组顺序标记,以表示文字档案含有Unicode文字。 织梦内容管理系统

其次,在PopFileRead函式中,程式用IsTextUnicode函式来决定档案是否含有位元组顺序标记。此函式甚至检测位元组顺序标记是否反向了,亦即Unicode文字档案在Macintosh或者其他使用与Intel处理器相反的位元组顺序的机器上建立的。这时,位元组的顺序都经过翻转。如果档案是Unicode版,但是被非Unicode版的POPPAD3读取,这时,文字将被WideCharToMultiChar转换。WideCharToMultiChar实际上是一个宽字元ANSI函式(除非您执行远东版的Windows)。只有这时文字才能放入编辑缓冲区。

内容来自dedecms

同样地,如果档案是非Unicode文字档案,而执行的是Unicode版的程式,那么文字必须用MultiCharToWideChar转换。 copyright dedecms

改变字体
 

内容来自dedecms

我们将在第十七章详细讨论字体,但那些都不能代替通用对话方块函式来选择字体。 copyright dedecms

WM_CREATE讯息处理期间,POPFONT.C中的POPPAD呼叫PopFontInitialize。这个函式取得一个依据系统字体建立的LOGFONT结构,由此建立一种字体,并向编辑控制项发送一个WM_SETFONT讯息来设定一种新的字体(内定编辑控制项字体是系统字体,而PopFontInitialize为编辑控制项建立一种新的字体,因为最终该字体将被删除,而删除现有系统字体是不明智的)。 本文来自织梦

POPPAD收到来自程式的字体选项的WM_COMMAND讯息时,它呼叫PopFontChooseFont。这个函式初始化一个CHOOSEFONT结构,然後呼叫ChooseFont显示字体选择对话方块。如果使用者按下「OK」按钮,那么ChooseFont将传回TRUE。随後,POPPAD呼叫PopFontSetFont来设定编辑控制项中的新字体,旧字体将被删除。

织梦好,好织梦

最後,在WM_DESTROY讯息处理期间,POPPAD呼叫PopFontDeinitialize来删除最近一次由PopFontSetFont建立的字体。

dedecms.com

搜寻与替换
 

内容来自dedecms

通用对话方块程式库也提供两个用於文字搜寻和替换函式的对话方块,这两个函式(FindTextReplaceText)使用一个型态为FINDREPLACE的结构。图10-11中所示的POPFIND.C档案有两个常式(PopFindFindDlgPopFindReplaceDlg)呼叫这些函式,还有两个函式在编辑控制项中搜寻和替换文字。

dedecms.com

使用搜寻和替换函式有一些考虑。首先,它们启动的对话方块是非模态对话方块,这意味著必须改写讯息回圈,以便在对话方块活动时呼叫IsDialogMessage。第二,传送给FindTextReplaceTextFINDREPLACE结构必须是一个静态变数,因为对话方块是模态的,函式在对话方块显示之後传回,而不是在对话方块结束之後传回;而对话方块程序必须仍然能够存取该结构。 copyright dedecms

第三,在显示FindTextReplaceText对话方块时,它们通过一条特殊讯息与拥有者视窗联络,讯息编号可以通过以FINDMSGSTRING为参数呼叫RegisterWindowMessage函式来获得。这是在WndProc中处理WM_CREATE讯息时完成的,讯息号存放在静态变数中。 dedecms.com

在处理内定讯息时,WndProc将讯息变数与RegisterWindowMessage传回的值相比较。lParam讯息参数是一个指向FINDREPLACE结构的指标,Flags栏位指示使用者使用对话方块是为了搜寻文字还是替换文字,以及是否要终止对话方块。POPPAD3是呼叫POPFIND.C中的PopFindFindTextPopFindReplaceText函式来执行搜寻和替换功能的。 本文来自织梦

只呼叫一个函式的Windows程式
 

copyright dedecms

到现在为止,我们已经说明了两个程式,让您浏览选择颜色,这两个程式分别是第九章中的COLORS1和本章中的COLORS2。现在是讲解COLORS3的时候了,这个程式只有一个Windows函式呼叫。COLORS3的原始码如程式11-7所示。 copyright dedecms

COLORS3所呼叫的唯一Windows函式是ChooseColor,这也是通用对话方块程式库中的函式,它显示如图11-7所示的对话方块。颜色选择类似於COLORS1COLORS2,但是它与使用者交谈互动能力更强。

本文来自织梦

 程式11-7  COLORS3 本文来自织梦 
COLORS3.C 

织梦内容管理系统

/*------------------------------------------------------------------------- 
织梦好,好织梦
        COLORS3.C -- Version using Common Dialog Box 

织梦内容管理系统

                                                     (c) Charles Petzold, 1998 织梦内容管理系统 
--------------------------------------------------------------------------*/ copyright dedecms 
  

织梦好,好织梦

#include <windows.h> 内容来自dedecms 
#include <commdlg.h> 

织梦内容管理系统

  

织梦内容管理系统

int WINAPI WinMain (   HINSTANCE hInstance, HINSTANCE hPrevInstance, 织梦内容管理系统 
                                                             PSTR szCmdLine, int iCmdShow) 织梦内容管理系统 
{ 织梦内容管理系统 
        static CHOOSECOLOR     cc ; 
本文来自织梦
        static COLORREF                       crCustColors[16] ; 
copyright dedecms
  

织梦好,好织梦

        cc.lStructSize                        = sizeof (CHOOSECOLOR) ; 

本文来自织梦

        cc.hwndOwner                          = NULL ; 

织梦好,好织梦

        cc.hInstance                          = NULL ; 
本文来自织梦
        cc.rgbResult                          = RGB (0x80, 0x80, 0x80) ; 内容来自dedecms 
        cc.lpCustColors                       = crCustColors ; 

dedecms.com

        cc.Flags                              = CC_RGBINIT | CC_FULLOPEN ; 织梦内容管理系统 
        cc.lCustData                          = 0 ; 
织梦好,好织梦
        cc.lpfnHook                           = NULL ; copyright dedecms 
        cc.lpTemplateName = NULL ; copyright dedecms 
  
本文来自织梦
        return ChooseColor (&cc) ; copyright dedecms 
} 

织梦内容管理系统


  本文来自织梦

copyright dedecms

  本文来自织梦

11-7 COLORS3的萤幕显示

织梦内容管理系统

 

ChooseColor函式使用一个CHOOSECOLOR型态的结构和含有16DWORD的阵列来存放常用颜色,使用者将从对话方块中选择这些颜色之一。rgbResult栏位可以初始化为一个颜色值,如果Flags栏位的CC_RGBINIT旗标被设立,则显示该颜色。通常在使用这个函式时,rgbResult将被设定为使用者选择的颜色。 织梦内容管理系统

请注意,Color对话方块的hwndOwner栏位被设定为NULL。在ChooseColor函式呼叫DialogBox以显示对话方块时,DialogBox的第三个参数也被设定为NULL。这是完全合法的,其含义是对话方块不为另一个视窗所拥有。对话方块的标题将显示在工作列中,而对话方块就像一个普通的视窗那样执行。

copyright dedecms

您也可以在自己程式的对话方块中使用这种技巧。使Windows程式只建立对话方块,其他事情都在对话方块程序中完成,这是可能的。

dedecms.com