精华内容
下载资源
问答
  • 3.VB中可以建立 菜单和 菜单...为了把通用对话框控件加到工具箱中应工程菜单中选择部件命令弹出部件对话框部件对话框的控件选项卡中选择 2.建立打开文件保存文件颜色字体和打印对话框所使用的方法分别为 Showopen
  • Delphi 下自定义通用对话框--------------自定义打开文件对话框 几次碰到有人论坛里问如何 Delphi 下自定义通用对话框,本人对此问题也比较感兴趣,所以抽点时间搞了下,现在把“成果”与大家分享。...
     

    在 Delphi 下自定义通用对话框
    --------------自定义打开文件对话框

        几次碰到有人在论坛里问如何在 Delphi 下自定义通用对话框,本人对此问题也比较感兴趣,所以抽点时间搞了下,现在把“成果”与大家分享。本文的题目大了点,通用对话框有好多,但这里只以打开文件对话框为例。其实自定义所有通用对话框的原理是一样的。

    第一步:建立对话框模版

        先来说个概念:对话框模版。对话框模版是一种资源,在 .rc 文件中定义,编译后生成 .res 文件,最终一般存在于资源动态链接库(DLL)中或可执行程序中。在专业的共享软件中一般都大量使用模版来创建对话框。通过模版生成的对话框一般用来采集用户输入,上面可以放标准的 Windows 控件,比如 Button, Label, TextBox, ListBox, ListView, TreeView 等。

        通用对话框也是由对话框模版生成的窗体,只不过这些对话框模版由操作系统定义,自定义通用对话框就是通过更改这些模版来实现的(打开和保存文件对话框例外,它们是通过添加新的模版来自定义的)。所以第一步要知道怎样定义对话框模版,可以在 Notpad 里直接敲 .rc 文件(这种方法这里就不使用了),还可以使用现有的工具,我机器上最好的工具是 Visual Studio .Net IDE,只需要点几下鼠标即可。(用它也可以查看、修改可执行文件中的资源,直接点打开->文件,打开可执行文件即可)。现在就先在 VS.Net 中定义一个对话框模版(过程略),该模版就是我们在打开文件对话框上自定义的部分,需要注意的是该模版必须具有 DS_3DLOOK 、DS_CONTROL 、WS_CHILD 、WS_CLIPSIBLINGS 风格且不能有 Border,因为通用对话框是将我们的整个模版当作子窗体SubClass 到原有对话框的(类似 Button 等标准控件与其拥有者的关系)。我将对话框模版的外观和 .rc 文件的内容贴出来:

    // .rc 文件内容 
    131 DIALOGEX 0, 0, 282, 36
    STYLE DS_SETFONT | DS_3DLOOK | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_CLIPSIBLINGS
    FONT 8, "MS Shell Dlg", 400, 0, 0x1
    BEGIN
       LTEXT "文件名称:",-1,7,8,40,8
       LTEXT "此静态控件用来显示文件名称",1004,51,8,224,8, SS_PATHELLIPSIS
       CONTROL "如果选中文件是图片文件则进行预览",1005,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,7,18,268,10
    END


        上面对话框模版中的 CheckBox 没有任何实际意义,只用来说明功能。将此 .rc 文件编译成 .res 文件(可以用 VS.Net 直接编译,也可以用 Delphi 带的 brcc32 工具)以备后面例子使用。

    第二步:继承 TOpenDialog 类

        调用打开文件对话框只需一个 API:GetOpenFileName,这个 API 需要一个 OPENFILENAME 结构的参数,自定义对话框时将该结构的 lpTemplateName 成员指定为对话框模版的标识(Identifier)并在 flags 成员中包含 OFN_ENABLETEMPLATE 常数即可。

        对话框模版及其包含的每个控件都应该有自己唯一的标识,而且这些标识不能与通用对话框上原有控件的标识重复。标识有2种:字符串标识和数字标识,在本例中使用数字标识:对话框模版的标识为 131,第一个静态控件的标识为 -1,第二个静态控件的标识为 1004,CheckBox 的标识为 1005。(标识为 -1 的控件一般为内容固定不变的静态控件。) OPENFILENAME 结构的 lpTemplateName 成员的类型是 null-terminated 字符串指针,如果对话框模版的标识为字符串,则可直接赋值,比如某模版的标识为 IDD_MYDIALOG,那么赋值语句为:lpTemplateName := PChar('IDD_MYDIALOG'),如果为数字,比如本例中的模版的标识为 131,赋值语句则为:lpTemplateName := Windows.MakeIntResource(131)。

        Delphi 中所有通用对话框类都继承自 TCommonDialg 抽象类,在这个抽象类中定义了个受保护的(Protected)属性:Template,类型为 PChar。这个属性就是用来存放模版标识的,但遗憾的是我们不能在除它的继承类以外的地方访问到它(因为受保护)。所以我们需要在它的孙子类中重新定义一公有(Public)属性来间接访问它。

        在 Delphi 里新建一个 VCL 类 TMyOpenDialog 继承自 TOpenDialog 类,定义一公有属性 TemplateRes ,通过其写入方法为受保护的 Template 属性赋值,下面列出代码:

    //********************************************
    // MyOpenDialog.pas
    // TMyOpenDialog 类实现自定义打开文件对话框
    // by: Joe Huang date: 2004-01-05
    //********************************************
    unit MyOpenDialog;

    interface

    uses
    SysUtils, Classes, Dialogs, Windows, Messages, CommDlg;

    type 
       TCommandEvent = procedure (ControlID: Word) of object; 
       TMyOpenDialog = class(TOpenDialog) 
       private 
          { Private declarations } 
          FTemplateRes: PChar; 
          FOnCommand: TCommandEvent; 

          procedure SetTemplateRes(const Value: PChar); 
       protected 
          { Protected declarations } 
          procedure WndProc(var Message: TMessage); override; 
       public 
          { Public declarations } 
          //该属性用来指定自定义模版的标识 
          property TemplateRes: PChar read FTemplateRes write SetTemplateRes; 
       published 
          { Published declarations } 
          property OnCommand: TCommandEvent read FOnCommand write FOnCommand; 
       end;

    procedure Register;

    implementation

    procedure Register;
    begin 
       RegisterComponents('Samples', [TMyOpenDialog]);
    end;

    { TMyOpenDialog }

    procedure TMyOpenDialog.SetTemplateRes(const Value: PChar);
    begin 
       FTemplateRes := Value; 
       Self.Template := Value;
    end;

    procedure TMyOpenDialog.WndProc(var Message: TMessage);
    begin 
       Message.Result := 0; 
       if (Message.Msg = WM_COMMAND) then 
       begin 
          if Assigned(FOnCommand) then 
             FOnCommand(Message.WParamLo); 
       end; 
       inherited WndProc(Message);
    end;

    end.

        TMyOpenDialog 类还定义了一个事件用来捕获对话框模版上控件状态发生的改变(后面说明此事件的用法)。将该类注册到组件面板的 Samples 页中。

    第三步:建立工程实现自定义对话框

        新建一工程保存至目录,将第一步中的 .res 文件放至该目录中并加入到工程文件中。从 Samples 页中把我们的新控件拖入 Form1 中,名字为 MyOpenDialog1,再在 Form1 上放入 Button1,Button1 的 On_Click 事件代码如下:

    procedure TForm1.Button1Click(Sender: TObject);
    begin 
       MyOpenDialog1.TemplateRes := Windows.MakeIntResource(131); 
       MyOpenDialog1.Execute;
    end;

    MyOpenDialog1 的 On_Show 事件代码如下:

    procedure TForm1.MyOpenDialog1Show(Sender: TObject);
    begin 
       //标识为 1004 的控件为第二个静态控件,用来显示选择的文件全名 
       //此事件一般用来初始化模版上的控件内容和状态 
       SetDlgItemText(MyOpenDialog1.Handle, 1004, '初始化...');
    end;

    MyOpenDialog1 的 On_SelectionChange 事件代码如下:

    procedure TForm1.MyOpenDialog1SelectionChange(Sender: TObject);
    begin 
       //在第二个静态控件上显示选择的文件全名 
       SetDlgItemText(MyOpenDialog1.Handle, 1004, PChar(MyOpenDialog1.FileName));
    end;

    MyOpenDialog1 的 On_Command 事件代码如下:

    procedure TForm1.MyOpenDialog1Command(ControlID: Word);
    var 
       hCtrl: HWND;
    begin 
       if ControlID = 1005 then //模版上的 CheckBox 控件,当状态发生改变时触发此事件 
       begin 
          hCtrl := GetDlgItem(MyOpenDialog1.Handle, ControlID); 
          if hCtrl <= 0 then Exit; 
          if SendMessage(hCtrl, BM_GETCHECK, 0, 0) = BST_CHECKED then 
             ShowMessage('You checked me.') 
          else 
             ShowMessage('You unchecked me.'); 
       end;
    end;

    运行后效果见下图:

    小结

        本例中的自定义部分默认的放在了对话框原有部分的下面,那么如何把对话框中自定义部分放在其它位置呢?其实这个工作不是在代码里做的,而是在第一步创建模版的时候。方法是在模版上放置一个不显示的静态控件(从 MSDN 带的例子来看可以放多个这样的控件),并且这个静态控件的标识必须为 stc32 ,即 0x045F 。通用对话框通过模版上其他控件相对于这个静态控件的位置来定位自定义部分相对于原有部分的位置,模版中位于 stc32 静态控件上方和左边的控件将被安放在通用对话框原有部分的上方和左边,同理,位于 stc32 静态控件下方和右边的控件将被安放在通用对话框原有部分的下方和右边。( All new controls above and to the left of the stc32 control are positioned the same amount above and to the left of the controls in the default dialog box. New controls below and to the right of the stc32 control are positioned below and to the right of the default controls. In general, each new control is positioned so that it has the same position relative to the default controls as it had to the stc32 control. )

        再说说我个人认为 Delphi 封装通用对话框不够完美的地方,一般来说通用对话框都有一个父窗体(Parent Window)或拥有者(Owner),拿打开文件对话框来说:OPENFILENAME 结构的 hwndOwner 成员指定其父窗体或拥有者的句柄,但 Delphi 并没有让我们来指定,而是将它指定为 Application.Handle,其他通用对话框也都是这样。

    MSDN 中有个 C++ 的完整例子,也是自定义打开文件对话框,很短也很容易看懂,它的对话框模版涉及到定位,可在下面位置找到该例子:
    User Interface Design and Development
      └User Interface Design & Usability
          └Technicle Articles
              └Using the Common Dialogs Under Windows 95

    本文参考了 MSDN 以下部分:
    User Interface Design and Development
      └Windows Management
          └User Input
              └Common Dialog Box Library

    User Interface Design and Development
      └Windows Management
          └Windowing
              └Dialog Box

    The end. 作者:Joe Huang 欢迎来 Email 讨论:happyjoe@21cn.com 时间:2004年1月5日 6:01 PM

    展开全文
  • 打开”文件和“保存”文件对话框 显示 “打开对话框的函数是 GetOpenFileName,显示“保存”文件对话的函数是 GetSaveFileName ,这两个对话框可以让用户选择 驱动器、目录、以及一个文件名(打开对话框还允许...
    1. “打开”文件和“保存”文件对话框

      1. 显示 “打开” 对话框的函数是 GetOpenFileName,显示“保存”文件对话的函数是 GetSaveFileName ,这两个对话框可以让用户选择 驱动器、目录、以及一个文件名(打开对话框还允许选择多个文件),但这两个对话框并不对文件进行任何操作,也就是说,它们进给用户提供一个同一界面来“选择”文件名,获取文件名以后,对程序的打开、读写等操作还需要程序员自己解决。

      2. 这两个函数的用法:
        在这里插入图片描述
        lpofn 参数是一个指针,指向一个 OPENFILENMAE 结构,程序在调用函数前需要在结构中填写初始化数据,两个函数使用的结构是一样的,只是实用的初始化数据有些不同而已。

      3. lpofn 结构:

        在windows.inc 中结构定义如下:
        在这里插入图片描述
        结构中一些重要的字段说明:

        1. ipstrFile – 指向一个包含文件名的缓冲区。如果这个缓冲区中已经包含了一个文件名,那么对话框初始的时候将显示这个文件名。当用户选择了一个文件的时候,函数在这里返回新的文件名。
        2. nMaxfile – 指定 lpstrFIle 参数指向的缓冲区长度。
        3. lpstrFileTitle – 指向一个缓冲区,用来接收用户选择的不含路径的文件名。这个字段可以为NULL。
        4. nMaxFileTitle – 指明 lpstrFileTitle 参数指向的缓冲区长度。
        5. lpstrInitialDir – 对话框的初始化目录,这个字段可以为 NULL。
        6. lpstrTitle – 指向自定义的对话框标题,如果这个字段为NULL,那么“打开”对话框和“保存”对话框的默认标题是“打开”和“另存为”。
        7. nFileOffset – 返回文件名字符串中文件名的起始位置,如果用户选择了文件"c:\dir1\file.ext’,这里将返回8(因为 file.ext 中 f 在第8个位置)
        8. nFilExtension – 返回文件名字符串中扩展名的起始位置,同样的上面的字符串,这里返回13.如果文件名的最后一个字符串是“.”,这里返回0,表示文件没有拓展名,这个字段和 nFileOffset 字段为分析文件名提供了方便。
        9. lpstrDefExt – 指定默认拓展名,如果用户输入了一个没有拓展名的文件名,那么函数会自动加上这个默认拓展名。
        10. Flags字段 – 该标志字段决定了对话框的不同行为,它可以是一些取值的组合。下面是一些重要的标志:
          1. OFN_ALLOWMULTISELECT – 允许同时选择多个文件名。
          2. OFN_CREATEPROMPT – 如果用户输入了一个不存在的文件名,对话框向用户提问“是否建立文件”
          3. OFN_FILEMUSTEXIST – 用户只能选择一个已经存在的文件名,使用这个文件名的同时必须使用 OFN_PATHMUSTEXIST 标志。
          4. OFN_HIDEREADONLY – 对话框不显示“以只读方式打开”复选框。
          5. OFN_OVERWRITEPROMPT – 在“保存”文件对话框中使用过的时候,当选择一个已存在的文件时,对话框会提问“是否覆盖文件”。
          6. OFN_PATHMUSTEXIST – 用户输入文件名时,路径必须存在。
          7. OFN_READONLY – 对话框中的“以只读方式打开”复选框初始化的时候处于选中状态。
      4. 说明:

        调用显示 “打开” 或 “保存” 文件对话框函数时,函数会停留直到对话框关闭位置,当用户点击了对话框中的“确定”按钮时,函数返回 TRUE,用户单击“取消”按钮退出时,函数返回 FALSE,程序可以由此判断是否需要继续进行打开或保存文件的操作。

      5. 代码解读:
        在这里插入图片描述

    2. 字体选择对话框

      1. 介绍:

        “字体”通用对话框如图措施,对话框列出了系统中安装的字体,用户可以在上面选择字体名称,同时可以选择字体大小、颜色、以及一些效果如斜体,粗体,删除线或下划线等。
        在这里插入图片描述

      2. 函数,显示选择“字体”对话框的函数是 ChooseFont:
        在这里插入图片描述

      3. 结构体 CHOOSEFONT 介绍:

        lpcf 是一个 CHOOSEFONT结构体:
        在这里插入图片描述
        重要字段介绍:

        1. hDC – 当Flags字段中制定 CF_PRINTERFONTS 标志时,它是打印机的DC句柄。
        2. lpLogFont – 指向一个包含 LOGFONT 结构的缓冲区。 LOGFONT 结构可以用来指定字体的名称和属性。如果 Flags 字段中制定 CF_INITTOLOGFONTSTRUCT 标志的话,对话框将根据这个结构初始化对话框,函数也在这里返回用户选择的字体和名称。
        3. iPointSize – 返回用户选择的字号大小,单位是 1/10 磅。
        4. rfbColors – 如果 FLags 字段的 CF_EFFECTS 标志被设置,对话框将根据这个数值初始化“颜色”下拉式列表框。另外,函数返回时这里返回用户选择的字体颜色。
        5. nFontType – 返回用户选择的字体属于哪一类,可能的返回值有 BOLD_FONTTYPE, ITALIC_FONTTYPE, PRINTER_FONTTYPE, REGULAR_FONNTYPE, SCREEN_FONTTYPE 等。
        6. Flags 标志,其初始值决定了对话框的不同行为,函数返回的时候也会在这里返回一些用户选择:
          1. CF_BOTH – 对话框同时列出打印机字体和屏幕字体。
          2. CF_TTONLY – 对话框只列出 TrueType 字体。
          3. CF_EFFECTS – 对话框中显示 “效果” 复选框。
          4. CF_FIXEDPITCHONLY – 对话框的字体列表中只显示等宽字体。
          5. CF_LIMITSIZE – 对话框显示的字体尺寸限于 nSizeMin 和 nSizeMax 字段指定的数值之间。
          6. CF_NOSTYLESEL – 对话框不显示“字形”组合列表框。
          7. CF_NOSIZESEL – 对话框不显示“大小”组合列表框。
          8. CF_SCREENFONTS – 字体列表中只显示屏幕字体。
      4. 使用介绍:

        1. 调用 ChooseFont 函数实,函数会停留直到对话框关闭为止,当用户单击了对话框中的“确定”按钮时,函数返回 TRUE,用户单击“取消”按钮退出时,返回返回 FALSE。
        2. 在调用 ChooseFont 之前,lpLogFont 字段被指向一个 LOGFONT结构,对话框关闭的时候,函数在 LOGFONT 结构的 lfFaceName 字段中返回字体的名称,字体的效果和字形也在LOGFONT结构中返回。
        3. 用户选择的颜色在rgbColors 字段中返回,字体大号在 iPointSize 字段中返回,由于单位是 1/10 磅,所以返回的值等于对话框中选择的字号大小乘以10.
      5. 代码解读:
        在这里插入图片描述

    3. “颜色”选择对话框

      1. 颜色对话框如图所示,左边是基本的选择系统预定义的颜色,右边是拓展的区域,可以由用户自己选择或输入颜色值。
        在这里插入图片描述
      2. 打开“颜色”选择对话框使用函数 ChooseColor:
        在这里插入图片描述
      3. lpcc 指向一个 CHOOSECOLOR结构:
        在这里插入图片描述
        结构中几个重要的参数介绍:
        1. rgbResult – 如果 Flags字段指定了 CC_RGBINIT标志,那么窗框对话框的时候使用这个字段来初始化选择框中的颜色;函数返回时在这里返回用户的选择。
        2. lpCustColors – 指向一个 16个双字长度的缓冲区,定义16中颜色。
        3. Flags – 标志,可以使下面取值的组合:
          1. CC_FULLOPEN – 对话框显示右边的拓展部分,如果不指定这个标志,初始化时候拓展部分不显示,但用户可以通过单击“规定自定义颜色”按钮将对话框展开。
          2. CC_PREVENTFULLOPEN – 禁止“规定自定义颜色”按钮,也就时说不允许用户展开对话框的扩展部分。
          3. CC_RGBINT – 对话框显示的时候用 rgbResult 字段的值初始化选择框中的颜色。
      4. 说明:
        1. 如果用户单击“确定”按钮,函数返回 TRUE,否则函数返回 FALSE。
        2. 使用 ChosseColor 函数要注意的是: lpCustColors 指针不能为 NULL,所以必须分配一个 16个双字长度缓冲区,如果指针是 NULL 会导致函数违规访问 00000000h 处的内存,你就等着看“非法操作吧”!
      5. 代码解读:
        在这里插入图片描述
    4. “查找”和“替换”文本对话框:

      1. “查找”和“替换”对话框如图所示
        在这里插入图片描述
      2. 要显示这两种 通用对话框可分别使用 FindText 和 ReplaceText 函数:
        在这里插入图片描述
      3. 这两个函数同样适用 FINREPLACE 结构:
        在这里插入图片描述
        结构中关键字段说明:
        1. flags – 标志,创建对话框的时候,函数根据标志中的数值初始化对话框中各控件的状态,返回的时候根据用户的选择来设置标志字段的内容,标志字段可以是以下取值的组合:
          1. FR_FINDNEXT,FR_REPLACE,FR_REPLACEALL,FR_DIALOGTERM – 分别表示用户单击了“查找下一个”、“替换”、“全部替换”和“取消”按钮。
          2. FR_HIDEUPDOWN、FR_HIDEMATCHCASE、FR_HIDEWHOLEWORD – 初始化的时候,表示对话框不显示“方向”、“区分大小写”、“全字匹配”按钮。
          3. FR_NOMATCHCASE,FR_NOUPDOWN,FR_NOWHOLEWORD – 初始化时将 “区分大小写”、“相仿”、“全字匹配”按钮灰化。
          4. FR_MATCHCASE, FR_WHOLEWORD – 表示用户选中了“区分大小写”或“全字匹配”复选框。
          5. FR_DOWN – 把 “方向” 单选钮设置为 “向下”。
        2. lpstrFindWhat – 指向包含查找字符串的指针,缓冲区的长度必须至少为80字节,这个字符串在初始化的时候在“查找内容”编辑框中,函数也在这里返回用户输入的内容。
        3. ipstrReplaceWith – 指向包含替换字符串的指针,这个字符串在初始化的时候出现在“编辑为”编辑框中,函数也在这里返回用户输入的内容。这个字段在使用 FindText 函数的时候可以为 NULL,但在使用 ReplaceText 函数的时候必须设置,否则对话框不会显示。
        4. wFindWhatLen 和 wReplaceWithLen – 相应的长度。
      4. 使用说明:
        1. “查找”和“替换”对话框的使用有些特殊,因为这两种对话框是非模态对话框,也就是说,当调用后,系统显示对话框后马上返回,对话框保持显示状态,直到用户按下了“取消”按钮后对话框才关闭。如果用户按下了对话框中的某些按钮,对话框设置FINDREPLACE 结构的相关字段并通过自定义的消息通知父窗口的窗口过程,程序中处理 哈找和替换的功能集中在这个自定义消息中完成。另外,由于对话框必须向父窗口发送消息,所以 hwndOwner 字段中必须指定父窗口的句柄,而不能像其他函数一样设置为NULL。

        2. 为了当对话框能够使用自定义消息,程序必须首先使用 RegisterWindowMessage 函数注册自定义消息,这个函数注册消息并返回消息ID,输入的参数是消息名称字符串,Microsoft 的编程手册中说明查找和替换对话框注册 FINDMSGSTRING 消息,其 FINDMSGSTRING 代表字符串,其看代码就能理解:

          1. FINDMSGSTRING
            在这里插入图片描述

          2. 注册消息,返回消息ID
            在这里插入图片描述

          3. 窗口过程处理消息:

            在这里插入图片描述

        3. 注意事项:

          因为查找和替换对话框是非模态对话框,所以使用时要把 FINDREPLACE 结构和字符串全部放在全局变量中,过放在窗口过程的局部变量中,对话框还没有关闭的情况下,这些全局变量就已经被释放了,以后对话框存取的就会是无效地址。

    5. “页面设置”对话框

      1. 介绍
        “页面设置”对话框用来设置打印机参数,用户在对话框中选择打印机,打印纸张大小、也边距和纸张方向,还可以引用一个打机属性的设置对话框。用户可以在这里完成与打印有关的所有设备的工作。
        在这里插入图片描述
        1. 显示“页面设置”对话框使用 PageSetupDlg 函数:
          在这里插入图片描述
        2. lppsd 参数指向一个 PAGESETUPDLG 结构:
          在这里插入图片描述
          由于这个暂时还用不到,在这里参数先不说了吧,之后用再继续查阅。
        3. 代码:
          在这里插入图片描述
    展开全文
  • WIN32汇编语言之通用对话框的使用

    千次阅读 2016-04-22 11:54:27
    以前学习过自定义的对话框,属性需要自己定义,包括边框,标题,模态与非模态等等,如果创建模态对话框(windows为它内建...因此当你用到相关的通用对话框的时候,需要程序的开头写上相关的声明:include comdlg32.in

    以前学习过自定义的对话框,属性需要自己定义,包括边框,标题,模态与非模态等等,如果创建模态对话框(windows为它内建的消息循环),你不用再去自己写消息循环与注册窗口和显示窗口这几个部分,可以很好的偷懒,这次要介绍的是WINDOWS已经建立好的对话框(已经写好在Comdlg32.dll中),因此当你用到相关的通用对话框的时候,需要在程序的开头写上相关的声明:include comdlg32.inc  与includelib  comdlg32.lib

    每当我们使用windows操作系统的时候,当你使用画图工具的时候,你选择“选择颜色”属性的时候,就会跳出一个标题为颜色的对话框ChooseColor(刚开始对于这个对话框我有一个疑问就是能不能把这个对话框的标题改为自己定义的字符串,仔细查看每个通用对话框相应的结构才发现只有“打开”和“另存为”  两个通用对话框的相关的结构中包含对话框的标题lpstrtitle  这个元素,而其他的几个通用对话框相应的结构中并没有哪一项涉及到修改对话框的标题的元素,对于这个问题现在还是很疑惑希望了解的人给与评论),这个对话框就是系统的通用对话框;当你使用QQ截图的时候你选择另存为这个选项的时候,就会弹出一个标题为"另存为"的通用对话框GetSaveFileName(这个标题是可以自己定义的),当你新建一个文本文档需要打开一个以前写好的文本的时候,就会弹出一个标题为“打开”的通用对话框GetOpenFileName(这个通用对话框的标题也是可以修改的),当你在一个文本文档里面选择“格式”--“字体”选项的时候会弹出一个标题为“字体”的通用对话框ChooseFont,用来选择需要选择的字体和字体的大小。同样还有“页面设置”这个通用对话框PageSetupDlg,“查找字符串”的通用对话框FindText      “替换字
    符串”的通用对话框ReplaceText。其中每一个通用对话框都对应一个相关的数据结构,用来对对话框的一些属性值进行设置,每个对话框的名字和相应的函数以及相应的结构如下表:

    通用对话框
    通用对话框使用的函数使用的数据结构
    选择颜色ChooseColor()CHOOSECOLOR
    打开文件GetOpenFileName()OPENFILENAME
    保存文件GetSaveFileName()OPENFILENAME
    页面设置PageSetupDlg()PAGESETUPDLG
    选择字体ChooseFont()CHOOSEFONT
    查找字符串FindText()FINDREPLACE
    替换字符串ReplaceText()FINDREPLACE


    介绍完了通用对画框的基本内容,下面来看一下资源文件的建立:资源文件需要三个部分

    首先是最简单的程序图标文件,为了简单,我建立的是一个加粗了的“2”(IDI_ICON1),关于图标,有一个问题:因为创建的是模态对话框(DialogboxParam),不需要再去注册窗口类,写消息循环,显示窗口这几步操作,所以加载图标不需要写出来,windows自己会加载资源图标,对于这个问题当时也是很纠结,图标文件在资源文件定义的时候并没有被选择加入到对话框资源中,菜单是被选择加入到对话框的,它可以附带着对话框的的过程被载入到程序中,但是这个图标并没有相关的操作,我自己理解为是windows自己加载的,(还请了解的指点)

    下面看一下资源脚本代码:

    // Generated by ResEdit 1.6.6
    // Copyright (C) 2006-2015
    // http://www.resedit.net
    #include <windows.h>
    #include <commctrl.h>
    #include <richedit.h>
    #include "resource.h"
    //
    // Menu resources
    //
    LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
    IDR_MENU1 MENU
    {
        POPUP "文件(&F)"
        {
            MENUITEM "打开文件(&O)", IDM_OPEN
            MENUITEM "文件另存为(&C)", IDM_SAVEAS
            MENUITEM SEPARATOR
            MENUITEM "页面设置(&P)", IDM_PAGESETUP
            MENUITEM SEPARATOR
            MENUITEM "退出(&X)", IDM_EXIT
        }
        POPUP "查看"
        {
            MENUITEM "查找字符串(&S)", IDM_FIND
            MENUITEM "替换字符串(&R)", IDM_REPLACE
            MENUITEM SEPARATOR
            MENUITEM "选择字体(&F)", IDM_SELFONT
            MENUITEM "选择颜色(&B)", IDM_SELCOLOR
        }
    }
    //
    // Dialog resources
    //
    LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
    IDD_DIALOG1 DIALOG 0, 0, 186, 95
    STYLE DS_3DLOOK | DS_CENTER | DS_MODALFRAME | DS_SETFONT | WS_CAPTION | WS_VISIBLE | WS_POPUP | WS_SYSMENU
    EXSTYLE WS_EX_STATICEDGE
    CAPTION "通用对话框示例"
    MENU IDR_MENU1
    FONT 8, "Ms Shell Dlg"
    {
    }
    //
    // Icon resources
    //
    LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
    IDI_ICON1          ICON           "icon2.ico"


    这次资源文件代码也挺短的,参数都占了一大堆,编译就不说了,都很熟悉了。


    下面来看一下实现程序的功能代码的一些疑问

    首先第一个问题:看下程序中这几句代码,用意就是利用wsprintf()函数将数值或者字符按指定的格式翻译成字符串,具体查看该函数的详细用法,太长了,没有出现什么问题就不详细介绍用法了。看代码:这是数据段的一个变量的定义。

    szFormatFont       db'您的选择:',0dh,0ah,'字体名称:%s',0dh,0ah
    db '字体颜色值:%08x,字体大小:%d ',0

    要注意的是“字体大小:%d ',0”这句,意思就是输出整数在这个位置,就是选中字体的大小,但是运行程序后可以发现其实对话框中输出的数值(即选择字体的大小)后面多一个“0”,刚开始很不理解,来看一下选择字体这个通用对话框所对应的数据结构CHOOSEFONT中的iPointSize字段的含义:返回用户选择的字号大小,单位是1/10磅,因此返回的数值等于对话框中选择的字号大小乘以10,刚开始因为不知道字体的大小使用的是什么单位,认为返回的数值和弹出的字体通用对话框中选择的字体大小相等,纠结了许久。关于字体单位大小可以参考一下下面这个表:(这个表我也是在网上看到别人写的写得很好就采用了)



    每一个通用对话框都有相对应的数据结构,每个数据结构中的字段比较多,在书写的时候,很容易出现错误,不仅仅是书写,就像上面这个疑问,就是对某个字段没有理解造成的。其他就没什么错误了,下面来看一下源代码:

                   

     .386
    .model flat, stdcall
    option casemap :none
    ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    ; Include 文件定义
    ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    include windows.inc
    include user32.inc
    includelib user32.lib
    include kernel32.inc
    includelib kernel32.lib
    include Comdlg32.inc
    includelib Comdlg32.lib
    ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    ; Equ 等值定义
    ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    IDI_ICON1 equ 110
    IDD_DIALOG1 equ108
    IDR_MENU1 equ 111
    IDM_OPEN equ 100
    IDM_SAVEAS equ101
    IDM_PAGESETUP equ102
    IDM_EXIT equ 103
    IDM_FIND equ 104
    IDM_REPLACE equ105
    IDM_SELFONT equ106
    IDM_SELCOLOR equ107
    ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    ; 数据段
    ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    .data?
    
    
    hInstance dd ?
    hWinMain dd ?
    dwFontColor dd?
    dwBackColor dd?
    dwCustColors dd16 dup (?)
    stLogFont LOGFONT<?>
    szFileName db MAX_PATH dup (?)
    szBuffer db 1024 dup (?)
    ;********************************************************************
    ; 查找替换对话框使用
    ;********************************************************************
    idFindMessage dd?
    stFind FINDREPLACE<?>
    szFindText db 100 dup (?)
    szReplaceText db100 dup (?)
    
    
    .const
    FINDMSGSTRING db'commdlg_FindReplace',0
    szSaveCaption db'请输入保存的文件名',0
    szFormatColor db'您选择的颜色值:%08x',0
    szFormatFont db'您的选择:',0dh,0ah,'字体名称:%s',0dh,0ah
    db '字体颜色值:%08x,字体大小:%d ',0
    szFormatFind db'您按下了“%s”按钮',0dh,0ah,'查找字符串:%s',0dh,0ah
    db '替换字符串:%s',0
    szFormatPrt db'您选择的打印机:%s',0
    szCaption db '执行结果',0
    szFindNext db '查找下一个',0
    szReplace db '替换',0
    szReplaceAll db'全部替换',0
    szFilter db 'Text Files(*.txt)',0,'*.txt',0,'All Files(*.*)',0,'*.*',0,0
    szDefExt db 'txt',0
    ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    ; 代码段
    ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    .code
    ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    ; 页面设置对话框
    ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    _PageSetup proc
    local @stPS:PAGESETUPDLG
    
    
    invoke RtlZeroMemory,addr @stPS,sizeof @stPS
    mov @stPS.lStructSize,sizeof @stPS
    push hWinMain
    pop @stPS.hwndOwner
    invoke PageSetupDlg,addr @stPS
    .if eax && @stPS.hDevMode
    mov eax,@stPS.hDevMode
    mov eax,[eax]
    invoke wsprintf,addr szBuffer,addr szFormatPrt,eax
    invoke MessageBox,hWinMain,addr szBuffer,addr szCaption,MB_OK
    .endif
    ret
    
    
    _PageSetup endp
    ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    ; 显示“保存文件”对话框
    ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    _SaveAs proc
    local @stOF:OPENFILENAME
    
    
    invoke RtlZeroMemory,addr @stOF,sizeof @stOF
    mov @stOF.lStructSize,sizeof @stOF
    push hWinMain
    pop @stOF.hwndOwner
    mov @stOF.lpstrFilter,offset szFilter
    mov @stOF.lpstrFile,offset szFileName
    mov @stOF.nMaxFile,MAX_PATH
    mov @stOF.Flags,OFN_PATHMUSTEXIST
    mov @stOF.lpstrDefExt,offset szDefExt
    mov @stOF.lpstrTitle,offset szSaveCaption
    invoke GetSaveFileName,addr @stOF
    .if eax
    invoke MessageBox,hWinMain,addr szFileName,addr szCaption,MB_OK
    .endif
    ret
    
    
    _SaveAs endp
    ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    ; 显示“打开文件”对话框
    ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    _OpenFile proc
    local @stOF:OPENFILENAME
    
    
    invoke RtlZeroMemory,addr @stOF,sizeof @stOF
    mov @stOF.lStructSize,sizeof @stOF
    push hWinMain
    pop @stOF.hwndOwner
    mov @stOF.lpstrFilter,offset szFilter
    mov @stOF.lpstrFile,offset szFileName
    mov @stOF.nMaxFile,MAX_PATH
    mov @stOF.Flags,OFN_FILEMUSTEXIST or OFN_PATHMUSTEXIST
    invoke GetOpenFileName,addr @stOF
    .if eax
    invoke MessageBox,hWinMain,addr szFileName,addr szCaption,MB_OK
    .endif
    ret
    
    
    _OpenFile endp
    ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    ; 选择颜色
    ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    _ChooseColor proc
    local @stCC:CHOOSECOLOR
    
    
    invoke RtlZeroMemory,addr @stCC,sizeof @stCC
    mov @stCC.lStructSize,sizeof @stCC
    push hWinMain
    pop @stCC.hwndOwner
    push dwBackColor
    pop @stCC.rgbResult
    mov @stCC.Flags,CC_RGBINIT or CC_FULLOPEN
    mov @stCC.lpCustColors,offset dwCustColors
    invoke ChooseColor,addr @stCC
    .if eax
    push @stCC.rgbResult
    pop dwBackColor
    invoke wsprintf,addr szBuffer,addr szFormatColor,dwBackColor
    invoke MessageBox,hWinMain,addr szBuffer,addr szCaption,MB_OK
    .endif
    ret
    
    
    _ChooseColor endp
    ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    ; 选择字体
    ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    _ChooseFont proc
    local @stCF:CHOOSEFONT
    
    
    invoke RtlZeroMemory,addr @stCF,sizeof @stCF
    mov @stCF.lStructSize,sizeof @stCF
    push hWinMain
    pop @stCF.hwndOwner
    mov @stCF.lpLogFont,offset stLogFont
    push dwFontColor
    pop @stCF.rgbColors
    mov @stCF.Flags,CF_SCREENFONTS or CF_INITTOLOGFONTSTRUCT or CF_EFFECTS
    invoke ChooseFont,addr @stCF
    .if eax
    push @stCF.rgbColors
    pop dwFontColor
    invoke wsprintf,addr szBuffer,addr szFormatFont,addr stLogFont.lfFaceName,\
    dwFontColor,@stCF.iPointSize
    invoke MessageBox,hWinMain,addr szBuffer,addr szCaption,MB_OK
    .endif
    ret
    
    
    _ChooseFont endp
    ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    _ProcDlgMain procuses ebx edi esi hWnd,wMsg,wParam,lParam
    local @szBuffer[128]:byte
    
    mov eax,wMsg
    .if eax ==WM_CLOSE
    invoke EndDialog,hWnd,NULL
    .elseif eax == WM_INITDIALOG
    ;********************************************************************
    ; 注册“查找”对话框消息,初始化“查找”对话框的结构
    ;********************************************************************
    mov eax,hWnd
    mov hWinMain,eax
    mov stFind.hwndOwner,eax
    mov stFind.lStructSize,sizeof stFind
    mov stFind.Flags,FR_DOWN
    mov stFind.lpstrFindWhat,offset szFindText
    mov stFind.wFindWhatLen,sizeof szFindText
    mov stFind.lpstrReplaceWith,offset szReplaceText
    mov stFind.wReplaceWithLen,sizeof szReplaceText
    invoke RegisterWindowMessage,addr FINDMSGSTRING
    mov idFindMessage,eax
    .elseif eax == WM_COMMAND
    mov eax,wParam
    .if ax ==IDM_EXIT
    invoke EndDialog,hWnd,NULL
    .elseif ax == IDM_OPEN
    invoke _OpenFile
    .elseif ax == IDM_SAVEAS
    invoke _SaveAs
    .elseif ax == IDM_PAGESETUP
    invoke _PageSetup
    .elseif ax == IDM_FIND
    and stFind.Flags,not FR_DIALOGTERM
    invoke FindText,addr stFind
    .elseif ax == IDM_REPLACE
    and stFind.Flags,not FR_DIALOGTERM
    invoke ReplaceText,addr stFind
    .elseif ax == IDM_SELFONT
    invoke _ChooseFont
    .elseif ax == IDM_SELCOLOR
    invoke _ChooseColor
    .endif
    ;********************************************************************
    .elseif eax == idFindMessage
    xor ecx,ecx
    .if stFind.Flags & FR_FINDNEXT
    mov ecx,offset szFindNext
    .elseif stFind.Flags & FR_REPLACE
    mov ecx,offset szReplace
    .elseif stFind.Flags & FR_REPLACEALL
    mov ecx,offset szReplaceAll
    .endif
    .if ecx
    invoke wsprintf,addr szBuffer,addr szFormatFind,\
    ecx,addr szFindText,addr szReplaceText
    invoke MessageBox,hWinMain,addr szBuffer,addr szCaption,MB_OK
    .endif
    ;********************************************************************
    .else
    mov eax,FALSE
    ret
    .endif
    mov eax,TRUE
    ret
    
    
    _ProcDlgMain endp
    ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    start:
    invoke GetModuleHandle,NULL
    mov hInstance,eax
    invoke DialogBoxParam,hInstance,IDD_DIALOG1,NULL,offset _ProcDlgMain,NULL
    invoke ExitProcess,NULL
    ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    end start



    win32汇编程序总会有许多相似的东西,就就像是一些固定的模板代码总是大同小异。关于源代码不再多赘述,也没什么问题了,下面来介绍一下本次遇到的一些新的API函数,以及新的结构类型:

    结构体:

    FINDREPLACEA           STRUCT
      lStructSize         DWORD   ?     ;结构长度
      hwndOwner           DWORD   ?     ;所属窗口
      hInstance           DWORD   ?     
      Flags               DWORD   ?     ;标志
      LpstrFindWhat       DWORD   ?     ;查找字符串
      lpstrReplaceWith    DWORD   ?     ;替换字符串
      wFindWhatLen        WORD    ?     ;查找字符串长度
      wReplaceWithLen     WORD    ?     ;替换字符串长度
      lCustData           DWORD   ?     
      lpfnHook            DWORD   ?     
      lpTemplateName      DWORD   ?     
    FINDREPLACEA          ENDS
    FINDREPLACE           EQU   <FINDREPLACEA>    
    
    
    
    OPENFILENAMEA         STRUCT
      lStructSize         DWORD  ?       ;结构的长度
      hwndOwner           DWORD  ?       ;所属窗口,可以为NULL
      hInstance           DWORD  ?       ;
      lpstrFilter         DWORD  ?       ;文件筛选字符串
      lpstrCustomFilter   DWORD  ?       
      nMaxCustFilter      DWORD  ?       
      nFilterIndex        DWORD  ?
      lpstrFile           DWORD  ?       ;全路径的文件名缓冲区
      nMaxFile            DWORD  ?       ;文件名缓冲区长度
      lpstrFileTitle      DWORD  ?       ;不包含路径的文件名缓冲区
      nMaxFileTitle       DWORD  ?       ;文件名缓冲区长度
      lpstrInitialDir     DWORD  ?       ;初始目录
      lpstrTitle          DWORD  ?       ;对话框标题
      Flags               DWORD  ?       ;标志
      nFileOffset         WORD   ?       ;文件名在字符串中的起始位置
      nFileExtension      WORD   ?       ;扩展名在字符串中的起始位置
      lpstrDefExt         DWORD  ?       ;默认扩展名
      lCustData           DWORD  ?       ;
      lpfnHook            DWORD  ?       
      lpTemplateName      DWORD  ?     
    OPENFILENAMEA         ENDS
    OPENFILENAME          equ   <OPENFILENAMEA>
    参数介绍:
    折叠lStructSize
    
    
    指定这个结构的大小,以字节为单位。
    
    
    Windows 95/98和Windows NT 4.0:特意为Windows 95/98或Windows NT 4.0,及带有WINVER和_WIN32_WINNT >= 0x0500编译时,为这个成员使用OPENFILENAME_SIZE_VERSION_400。
    
    
    Windows 2000及更高版本:这个参数使用sizeof (OPENFILENAME) 。
    
    
    折叠hwndOwner
    
    
    指向所有者对话框窗口的句柄。这个成员可以是任意有效窗口句柄,或如果对话框没有所有者它可以为NULL。
    
    
    折叠hInstance
    
    
    如果在Flags成员中设置了OFN_ENABLETEMPLATEHANDLE标记,hInstance成员指向包含一个对话框模板的内存对象。如果OFN_ENABLETEMPLATE标记被设置,hInstance是一个指向通过lpTemplateName成员命名的对话框模板的模块。如果两者都没有被设置,这个成员被忽略。
    
    
    如果OFN_EXPLORER标记被设置,系统使用Explorer风格的默认对话框的子窗口作为指定模板来建立一个对话框。如果OFN_EXPLORER标记没有被设置,系统使用模板建立一个旧风格的对话框。
    
    
    折叠lpstrFilter
    
    
    指向一对以空字符结束的过滤字符串的一个缓冲。缓冲中的最后一个字符串必须以两个NULL字符结束。
    
    
    第一个字符串是过滤器描述的显示字符串(例如,"文本文件"),第二个字符指定过滤样式(例如,"*.TXT")。要为一个显示字符串指定多个过滤样式,使用分号(";")分隔样式(例如,"*.TXT;*.DOC;*.BAK")。一个样式字符串中可以包含有效的文件名字字符及星号(*)通配符。不能在样式字符串中包含空格。
    
    
    系统不能改变过滤器的次序。它按lpstrFilter指定的次序显示在文件类型组合框中。
    
    
    如果lpstrFilter是NULL,对话框不能显示任何过滤器。
    
    
    折叠lpstrCustomFilter
    
    
    指向一个静态缓冲,它包含了一对以空字符结束的过滤器字符串,这个字符串是为了保留用户选择的过滤样式。第一个字符串是描述定制过滤器的显示字符串,第二个字符串是被用户选择的过滤器样式。第一次你的应用程序建立对话框,你指定的第一个字符串可以是任何非空的字符串。当用户选择了一个文件时,对话框复制当前过滤样式到第二个字符串。保留过滤样式可以是在lpstrFilter缓冲中指定的样式之一,或是用户输入的过滤器样式。在下一次对话框被建立时系统使用这个字符串去初始化用户自定义的文件过滤器。如果nFilterIndex成员是0,对话框使用定制过滤器。
    
    
    如果这个成员是NULL,对话框不能保留用户自定义过滤器样式。
    
    
    如果这个成员不是NULL,nMaxCustFilter成员的值必须指定以TCHARs为单位的lpstrCustomFilter缓冲的大小。对于ANSI版本,是字节的个数;对于Unicode版本,是字符的个数。
    
    
    折叠nMaxCustFilter
    
    
    指定特意为lpstrCustomFilter准备的以TCHARs为单位的缓冲大小。对于ANSI版本,是字节的个数;对于Unicode版本,是字符的个数。这缓冲应该最小在40个字符长。如果lpstrCustomFilter成员是NULL或是指向NULL的字符串,这个成员被忽略。
    
    
    折叠nFilterIndex
    
    
    指定在文件类型控件中当前选择的过滤器的索引。缓冲指向被lpstrFilter包含的一对定义了的过滤器的字符串。过滤器的第一对字符串的索引值为1,第二对为2,等等。0索引指出是通过lpstrCustomFilter指定的定制过滤器。你可以为对话框指定一个索引作为最初的过滤器描述及过滤器样式。当用户选择了一个文件时,nFilterIndex返回当前显示的过滤器的索引。
    
    
    如果nFilterIndex是0及lpstrCustomFilter是NULL,系统使用在lpstrFilter缓冲中的第一个过滤器。如果所有的三个成员都是0或NULL,系统不使用任何过滤器,在对话框的列表文件中不显示任何文件。
    
    
    折叠lpstrFile
    
    
    指向包含初始化文件名编辑控件使用的文件名的缓冲。如果不需要初始值,这个缓冲的第一个字符必须是NULL。当GetOpenFileName或GetSaveFileName函数返回成功时,这个缓冲包含驱动器,路径,文件名,及所选择的文件的扩展名。
    
    
    如果OFN_ALLOWMULTISELECT标记被设置并且用户选择了多个文件,缓冲包含了当前目录下被选择文件的文件名。对于Explorer风格对话框,目录和文件名字符串是被NULL分开的,在文件名之后有一个额外的NULL。对于旧风格对话框,字符串是被空格分开的并且函数为带有空格的文件名使用短文件名。你可以使用FindFirstFile函数在长短文件名之间转换。如果用户只选择了一个文件,lpstrFile字符串在路径和文件名之间没有分隔。
    
    
    如果缓冲太小,函数返回FALSE并且CommDlgExtendedError函数返回FNERR_BUFFERTOOSMALL.。既然这样,lpstrFile缓冲的首先两个字节包含必需的大小(字节或字符)。
    
    
    折叠nMaxFile
    
    
    指定lpstrFile缓冲的大小,以TCHARs为单位。对于ANSI版本,是字节的个数;对于Unicode版本,是字符的个数。这个缓冲必须足够存储路径和文件名字符串,包含结尾的null字符。如果缓冲太小,GetOpenFileName和GetSaveFileName函数返回假(FALSE)缓冲最小应该在256个字符长。
    
    
    折叠lpstrFileTitle
    
    
    指向接收选择的文件的文件名和扩展名的缓冲(不带路径信息)。这个成员可以是NULL。
    
    
    折叠nMaxFileTitle
    
    
    指定lpstrFileTitle缓冲的大小,以TCHARs为单位。对于ANSI版本,是字节的个数;对于Unicode版本,是字符的个数。如果lpstrFileTitle是NULL,这个成员被忽略。
    
    
    折叠lpstrInitialDir
    
    
    指向以空字符结束的字符串,可以在这个字符串中指定初始目录。Pointer to a null terminated string that can specify the initial directory. 在不同的平台上,为选择初始目录有不同的运算法则。
    
    
    Windows 7:
    
    
    如果lpstrInitialDir与应用程序第一次使用打开或另存为对话框的值相同,路径由用户选择作为初始目录。
    
    
    否则,如果lpstrFile包含路径,路径是初始目录。
    
    
    否则,如果lpstrInitialDir不是NULL,它指定初始目录。
    
    
    如果lpstrInitialDir为NULL,并且当前目录包含有一些指定过滤器类型的文件,初始目录是当前目录。
    
    
    否则,初始目录是当前用户的个人目录(即我的文档)。
    
    
    否则,初始目录是桌面文件夹。
    
    
    Windows 2000:
    
    
    如果lpstrFile包含了一个路径,这个路径就是初始目录。
    
    
    否则,lpstrInitialDir指定的为初始目录。
    
    
    如果lpstrInitialDir为NULL,并且当前目录下包含有一些指定过滤器类型的文件,初始目录就是当前目录。
    
    
    否则,如果应用程序在过去使用过打开哐另存为对话框,使用最近选择的路径作为初始目录。然而,如果一个应用程序长时间没有运行过,它保存的选择的路径将被丢弃。
    
    
    否则,初始目录是当前用户的私人文件目录(即我的文档)。
    
    
    否则,初始目录是桌面文件夹。
    
    
    Windows 98:
    
    
    lpstrInitialDir指定初始目录。
    
    
    如果lpstrInitialDir是NULL并且lpstrFile包含了一个路径,那么这个路径就是初始目录。
    
    
    否则,如果当前目录包含了一些指定的过滤类型的文件,那么初始化目录是当前目录。
    
    
    否则,初始目录是当前用户的私人文件目录(即我的文档)。
    
    
    Windows和Windows NT/ 2000的早期版本:
    
    
    lpstrInitialDir指定初始目录。
    
    
    如果lpstrInitialDir是NULL并且lpstrFile包含了一个路径,那么这个路径就是初始目录。
    
    
    否则,初始目录是当前目录。
    
    
    折叠lpstrTitle
    
    
    指向在对话框的标题栏中放置的字符串。如果这个成员是NULL,系统使用默认标题(另存为或打开)
    
    
    折叠Flags
    
    
    位标记的设置,你可以使用来初始化对话框。当对话框返回时,它设置的这些标记指出用户的输入。这个成员可以是下列标记的组合。 标记 含意
    
    
    OFN_ALLOWMULTISELECT 指定文件名列表框允许多选。如果同时你设置了OFN_EXPLORER标记,对话框使用Explorer风格用户界面;否则它使用旧风格用户界面。
    
    
    如果用户选择了一个以上的文件,lpstrFile缓冲返回当前目录下所有被选择的文件的文件名。nFileOffset成员是到第一个文件名的偏移量(字节或字符),并且nFileExtension成员不被使用。对于Explorer风格对话框,目录和文件名是被NULL分隔的,在最后的文件名后带有额外的NULL。这个格式使Explorer风格的对话框能返回包含空格的长文件名。对于旧风格对话框,目录和文件字符串是被空格分隔的,函数为带有空格的文件名使用短文件名。你可以使用FindFirstFile函数在短文件名和长文件名之间转换。
    
    
    如果你为一个旧风格对话框指定了一个定制的模板,文件名列表框的定义必须包含LBS_EXTENDEDSEL值。
    
    
    OFN_CREATEPROMPT 如果用户指定了一个不存在的文件,这个标记使用对话框能提示用户是否新建这个文件。如果用户选择了新建这个文件,对话框关闭并且函数返回指定的名字;否则,对话框继续停留。如果你使用带有OFN_ALLOWMULTISELECT标记的这个标记,对话框允许用户去指定一个不存在的文件。
    
    
    OFN_DONTADDTORECENT Windows 2000:防止系统为选择的文件增加快捷链接到最近使用文档中。要找回目录的位置,调用还有CSIDL_RECENT标记的SHGetSpecialFolderLocation函数。
    
    
    OFN_ENABLEHOOK 激活在lpfnHook成员中指定的钩子函数。
    
    
    OFN_ENABLEINCLUDENOTIFY Windows 2000:当用户打开一个文件夹时,引起对话框发送CDN_INCLUDEITEM通知消息到你的OFNHookProc程序。对话框为在最近打开的文件夹中的每一个项目发送一个通知。这些消息使你能够控制那些在对话框中显示的文件夹项目的列表。
    
    
    OFN_ENABLESIZING Windows 2000,Windows 98:使Explorer风格的对话框可以使用鼠标或键盘调整大小。缺省时,Explorer风格的打开和另存为对话框允许被调整大小,不顾这个标记是否被设置。这标记仅在你提供了一个钩子程序或定制模板时是必需的。旧风格的对话框不允许调整大小。
    
    
    OFN_ENABLETEMPLATE 指出lpTemplateName成员是指向对话框模板资源的名字,这个模板资源在能被hInstance成员识别的模块中。
    
    
    如果OFN_EXPLORER标记被设置,系统使用指定的模板去建立一个对话框,是默认Explorer风格对话框的子窗口。如果OFN_EXPLORER标记没有被设置,系统使用旧风格的对话框替代默认的对话框。
    
    
    OFN_ENABLETEMPLATEHANDLE 指出hInstance成员能识别的包含预载对话框模板的数据块。如果这个标记被指定的,系统忽略lpTemplateName。
    
    
    如果OFN_EXPLORER标记被设置,系统使用指定的模板去建立一个对话框,是默认Explorer风格对话框的子窗口。如果OFN_EXPLORER标记没有被设置,系统使用模板去建立一个旧风格对话框替代默认对话框。
    
    
    OFN_EXPLORER 指出任何打开或另存为对话框使用新的Explorer风格的用户化模块。关于更多的信息,参见Explorer-Style Hook Procedures和Explorer-Style Custom Templates。
    
    
    缺省下,打开和另存为对话框使用Explorer风格用户界面,不顾这个标记是否设置。这个标记仅在你提供了一个钩子程序或定制模板或设置了OFN_ALLOWMULTISELECT标记时是必需的。
    
    
    如果你想使用旧风格的界面,省略OFN_EXPLORER 标记,并且提供一个代替的旧风格模板或钩子程序。如果你想用旧风格但不需要一个定制模板或钩子程序,简单的提供一个钩子程序,让它返回FALSE。
    
    
    OFN_EXTENSIONDIFFERENT 指定用户输入的一个文件的扩展名与lpstrDefExt指定的扩展名不同。如果lpstrDefExt是NULL,函数不使用这个标记。
    
    
    OFN_FILEMUSTEXIST 指定用户仅可以在打开文件名输入字段中输入已存在的文件的名字。如果这个标记被指定的并且用户输入了一个无效的名字,对话框程序显示一个等待消息框。如果这个标记被指定,OFN_PATHMUSTEXIST标记也被使用。
    
    
    OFN_FORCESHOWHIDDEN Windows 2000:强制显示系统和隐藏属性的文件,从而压倒用户设置的显示或不显示隐藏文件。否则,带有系统和隐藏标记的文件不被显示。
    
    
    OFN_HIDEREADONLY 隐藏只读复选框。
    
    
    OFN_LONGNAMES 对于旧风格对话框,这个标记引起对话框使用长文件名。如果这个标记没有被指定,或如果OFN_ALLOWMULTISELECT标记也被设置,旧风格对话框为带有空格的文件名使用短文件名(8.3格式)。
    
    
    Explorer风格对话框忽略这个标记,通常显示长文件名。
    
    
    OFN_NOCHANGEDIR 如果当搜索文件时用户改变了目录的时候,恢复当前目录到它的初始值。
    
    
    OFN_NODEREFERENCELINKS 引导对话框为选择的快捷方式(.LNK)文件返回路径和文件名。如果这个值没有被指定,对话框返回这个快捷方式所引用文件的路径和文件名。
    
    
    OFN_NOLONGNAMES 对于旧风格对话框,这个标识引起对话框去使用短文件名(8.3格式)。
    
    
    Explorer风格对话框忽略这个标记,通常显示长文件名。
    
    
    OFN_NONETWORKBUTTON 隐藏和显示风格按钮。
    
    
    OFN_NOREADONLYRETURN 指定返回的文件不带有只读复选框,不是在写保护的目录中。
    
    
    OFN_NOTESTFILECREATE 指定文件不是在对话框关闭前建立的。如果应用程序保存文件到一个建立的非映象风格共享上,这个标记应该被指定的。当一个应用程序指定了这标记,库不能检查写保护,磁盘满,打开驱动器门或网络保护。应用程序使用这个标记必须小心执行文件操作,因为一旦文件被关闭,它不能重新打开。
    
    
    OFN_NOVALIDATE 指定公共对话框允许在返回的文件名中有无效的字符。典型的,正在调用的程序使用一个钩子程序通过FILEOKSTRING消息检查文件名。如果在编辑控件中的文本框是空的或只包含了空格,那么文件和目录列表框是被更新的。如果编辑控件中的文本框包含了别的东西,那么nFileOffset和nFileExtension的设置值是通过分析文本产生的。没有默认的扩展名被添加到文本,也没有文本被复制到lpstrFileTitle指定的缓冲。
    
    
    如果通过nFileOffset指定的值比0小,文件是无效的。否则,文件名是有效的。如果OFN_NOVALIDATE没有被指定,nFileExtension和nFileOffset可以被使用。
    
    
    OFN_OVERWRITEPROMPT 如果选择的文件已经存在,使用另存为对话框产生一个消息框。用户必须确认是否覆盖这个文件。
    
    
    OFN_PATHMUSTEXIST 指定用户仅能输入的路径和文件名。如果这个标记被使用并且用户在文件名输入字段中键入了一个用效的路径和文件名,对话框函数显示一个等待消息。
    
    
    OFN_READONLY 当对话框建立时,显示被选择的只读复选框。这个标记指出当对话框被关闭时只读复选框的状态。
    
    
    OFN_SHAREAWARE 指出如果调用OpenFile函数因为网络共享冲突而失败,这个错误被忽略并且对话框返回选择的文件名。
    
    
    如果这个标记没有被设置,当用户选择的文件名发生网络共享冲突时,对话框发送通知到你的钩子程序。如果你设置了OFN_EXPLORER标记,对话框发送CDN_SHAREVIOLATION消息到钩子程序。如果你没有设置OFN_EXPLORER,对话框发送SHAREVISTRING注册的消息到钩子程序。
    
    
    OFN_SHOWHELP 使对话框显示帮助按钮。hwndOwner成员必须指定一个窗口,这个窗口作为接收对话框发送的HELPMSGSTRING注册的消息,当用户单击帮助按钮时对话框发送这个消息。
    
    
    当用户单击帮助按钮时,一个Explorer风格的对话框发送CDN_HELP通知消息到你的钩子程序。
    
    
    折叠nFileOffset
    
    
    指定从路径开始到通过lpstrFile指定的文件名字符串基于0的偏移,以TCHARs为单位。对于ANSI版本,是字节的个数;对于Unicode版本,是字符的个数。例如,如果lpstrFile指向下列的字符串,"c:\dir1\dir2\file.ext",这个成员包含指出"file.ext"字符串偏移的位置值13。
    
    
    如果用户选择了多于一个的文件,nFileOffset是到第一个文件名的偏移。
    
    
    折叠nFileExtension
    
    
    指定从路径开始到通过lpstrFile指定的文件名字符串中扩展名基于0的偏移,以TCHARs为单位。对于ANSI版本,是字节的个数;对于Unicode版本,是字符的个数。例如,如果lpstrFile指向下列的字符串,"c:\dir1\dir2\file.ext",这个成员包含的值是18。如果用户没有输入一个扩展名并且lpstrDefExt是NULL,这个成员指定的偏移是结束字符NULL。如果用户在文件名中输入一个"."作为最后的字符,这个成员是0。
    
    
    折叠lpstrDefExt
    
    
    指向包含默认扩展名的缓冲。如果用户忘记输入扩展名,GetOpenFileName和GetSaveFileName附加这个扩展名到文件名中。这个字符串可以是任一长度,但但只有头三个字符被附加。字符串不应该包含一个句点(.)。如果这个成员是NULL并且用户忘记了输入一个扩展名,那么将没有扩展名被附加。
    
    
    折叠lCustData
    
    
    指定应用程序定义的数据,这数据是能被lpfnHook成员识别的系统传到的钩子程序。当系统发送WM_INITDIALOG消息到程序,消息的lParam参数指向当对话框建立时指定的OPENFILENAME结构。钩子程序可以使用这个指针获得lCustData的值。
    
    
    折叠lpfnHook
    
    
    指向一个钩子程序。除非Flags成员中包含OFN_ENABLEHOOK标记,要么这个成员将被忽略。
    
    
    如果在Flags成员中OFN_EXPLORER标记没有被设置,lpfnHook指向一个OFNHookProcOldStyle钩子程序,这个程序有意的从对话框接收消息。钩子程序返回FALSE传递一个消息到默认的对话框程序或返回TRUE丢弃消息。
    
    
    如果OFN_EXPLORER被设置,lpfnHook指向一个OFNHookProc钩子程序。这个钩子程序接收从对话框发出的通知消息。这个钩子程序也接收你通过一个子对话框模板定义的附加控件的消息。钩子程序不有意接收默认对话框的标准控件的消息。
    
    
    折叠lpTemplateName
    
    
    指向一个以空字符结束的字符串,字符串是对话框模板资源的名字,资源保存在能被hInstance成员识别的模块中。对于有限的对话框资源,这可以是通过MAKEINTRESOURCE返回的值。除非在Flags成员中设置了OFN_ENABLETEMPLATE标记,要么这个成员被忽略。
    
    
    如果OFN_EXPLORER标记被设置,系统使用指定的模板去建立一个对话框,是默认Explorer风格对话框的子窗口。如果OFN_EXPLORER标记没有被设置,系统使用模板去建立一个旧风格的对话框来替代默认对话框。
    
    
    pvReserved
    
    
    保留。
    
    
    dwReserved
    
    
    保留。
    
    
    FlagsEx
    
    
    Windows 2000:设置位标记,你可以使用来初始化对话框。这个成员可以是下列标记的组合。 标记 含意
    
    
    OFN_EX_NOPLACESBAR 如果这个标记被设置,则位置栏被不显示。如果这个标记没有设置,则Explorer风格的对话框包含一般使用文件图标的位置栏,例如像收藏夹和桌面。
    
    
    切记:#include <Commdlg.h>
    
    
    
    
    CHOOSEFONT            STRUCT
      lStructSize         DWORD  ?          ;结构长度  
      hwndOwner           DWORD  ?          ;所处窗口
      hdc                 DWORD  ?   
      lpLogFont           DWORD  ?          ;指向一个LOGFONT结构
      iPointSize          DWORD  ?          ;选择的字体大小
      Flags               DWORD  ?          ;标志
      rgbColors           DWORD  ?          ;选择的字体颜色
      lCustData           DWORD  ?          ;
      lpfnHook            DWORD  ? 
      lpTemplateName      DWORD  ?   
      hInstance           DWORD  ?
      lpszStyle           DWORD  ?
      nFontType           WORD   ?
      Alignment           WORD   ?
      nSizeMin            DWORD  ?
      nSizeMax            DWORD  ?
    CHOOSEFONT            ENDS
    
    
    
    
    CHOOSECOLOR           STRUCT ? 
      LStructSize         DWORD  ?           ;结构长度
      HwndOwner           DWORD  ?           ;所属窗口
      HInstance           DWORD  ?
      rgbResult           DWORD  ?           ;用户选择的颜色值
      lpCustColors        DWORD  ?           ;用户自定义颜色缓冲区
      Flags               DWORD  ?           ;标志
      lCustData           DWORD  ?           
      lpfnHook            DWORD  ?
      lpTemplataName      DWORD  ?
    CHOOSECOLOR           ENDS
    
    
    
    
    PAGESETUPDLG          STRUCT ?
      LStructSize         DWORD  ?            ;结构长度
      HwndOwner           DWORD  ?            ;所属窗口
      hDevMode            DWORD  ?            ;指向DEVMODE结构
      hDevNames           DWORD  ?            ;指向DEVNAMES结构
      Flags               DWORD  ?            ;标志
      PtPaperSize         POINT  ?            ;返回纸张尺寸
      RtMinMargin         RECT   ?            ;返回最小允许的页边距
      rtMargin            RECT   ?            ;返回用户选择的页边距
      hInstance           DWORD  ?            
      lCustData           DWORD  ?            
      lpfnPageSetupHook   DWORD  ? 
      lpfnPagePaintHook   DWORD  ?
      lpPageSetupTemplateName   DWORD  ?
      hPageSetupTemplate  DWORD   ?
    PAGESETUPDLG          ENDS
    
    API函数:
    
    PageSetupDlg()
    
    功能:
    该函数创建一个PageSetup对话框,此对话框能使用户指定打印页的属性。这些属性包括纸张大小和来源,送纸方向和页边距。
    
    原型:
    BOOL PageSetupDlg(LPPAGESETUPDLGI ppsd)
    参数:
    Ippsd:指向一个包含初始化对话框信息的PAGESETUPDLG结构。当函数返回时,该结构存放有关用户选择的信息
    
    返回值:
    返回如果用户点击OK钮,返回值为非零值,Ippsp参数指向的PAGESETUPDLG结构中的成员显示用户的选择。如果用户取消或关闭PageSetup对话框或错误出现,返回值为零
    
    
    GetSaveFileName()
    功能:
    该函数创建一个Save公共对话框,以便用户指定驱动器、目录和文件名
    原型:
    BOOL GetSaveFileName(LPOPENFILENAME Ipofn)
    参数:
    Ipofn:指向一个包含初始化对话框信息的OPENFILENAME结构。当GetsaveFileName函数返回时,此结构含有关于用户文件选择的信息。
    返回值:
    如果用户指定了一个文件名且点击OK按钮,返回值为非零值。由OPENFILENAME结构中的归IpstrFile成员指向的缓冲区含有全路径和用户指定的文件名。如果用户取消或关闭Save对话框或错误出现,返回值为零
    
    
    GetOpenFileName()
    
    功能:
    创建一个Open公共对话框,使用户指定驱动器、目录和文件名、或使用户打开文件
    原型:
    BOOL GetOpenFileName(LPOPENFILENAME Ipofn);
    参数;
    Ipofn:指向包含初始化对话框的信息的一个OPENFILENAME结构。当OpenfileName函数返回时,此结构包含有关用户文件选择的信息。
    返回值:
    如果用户指定了一个文件名,点击OK按钮,返回值为非零。由OPENFILENAME结构的IPstrFile成员指向的缓冲区含有全路径和用户指定的文件名。如果用户取消或关闭Open对话框或错误出现,返回值为零。
    
    
    ChooseColor()
    功能:
    该函数创建一个能使用户从中选择颜色的通用颜色对话框
    原型:
    BOOL ChooseColor(LPCHOOSECOLOR IpCC);
    参数;
    lpCC:指向一个包括初始化对话框信息的CHOOSECOLOR结构。当ChooseColor函数返回时,此结构含有有关用户颜色选择的信息。
    返回值:
    如果用户点击对话框中的OK按钮,返回值为非零值。CHOOSECOLOR结构中的rgbResult成员含有用户选择的颜色的RGB颜色值。如果用户取消或关闭Color对话框或错误出现,返回值为零。
    
    
    ChooseFont()
    
    功能:
    该函数创建一个使用户选择逻辑字体属性的对话框,这些属性包括字体名称、字体风格(如粗体、斜体或正常体)、字号、效果(如强调线,下划线或字体颜色)和手写体(或字符集)。
    原型:
    BOOL ChooseFont(LPCHOOSEFONT Ipcf)
    参数:
    Ipcf:指向一个含有初始化对话框信息的CHOOSEFONT结构。当返回ChooseFont函数时,此结构含有用户对字体选择的信息。
    
    返回值:
    
    如果用户点击对话框的OK按钮,返回值为非零值,CHOOSEFONT结构中的成员表明用户的选择。如果用户取消或关闭Font对话框或出现错误信息,返回值为零。
    





    展开全文
  • 上一篇我们学习了菜单的基本编程,本篇来了解一下通用对话框的使用。Windows系统之所以是目前最流行的桌面系统,也是因为Windows有一套标准化,统一友好的交互界面,比如菜单、工具栏、状态栏以及各个控件。当然除了...
    

    上一篇我们学习了菜单的基本编程,本篇来了解一下通用对话框的使用。Windows系统之所以是目前最流行的桌面系统,也是因为Windows有一套标准化,统一友好的交互界面,比如菜单、工具栏、状态栏以及各个控件。当然除了这些单独的控件之外,对于像文件打开、保存对话框,字体对话,颜色对话框等对于Windows本身会用到,在很多第三方的应用程序中也会用到。因此微软公司也早就清楚这种现实情况会存在,所以Windows把这种常见的公共对话就做了统一的接口函数,供Windows自己和第三方开发者使用。

    Windows提供的公用对话框在不同的版本有所不一样,但常见的公用对话框有:颜色选择对话框、打开文件对话框、保存文件对话框、字体选择对话框、查找对话框、替换对话框、打印对话框以及打印设置对话框等。

    本篇以最常见的文件打开/保存对话框、字体对话框、颜色对话框为例,来学习如何创建这些对话框,其他的对话框使用大同小异,且在MSDN上基本都有使用实例。

    要使用公用对话框函数,需要包含commdlg.h头文件,相关的数据结构和函数定义都在该头文件中定义。

    • 文件打开对话框

    文件打开对话框主要用于选择需要的文件,把选择的文件全路径名传给用户,至于取到文件全路径之后怎么操作完全是开发者自己决定。也就是说它提供了一个在电脑中选择任何文件的公共操作接口。API函数定义如下:

    BOOL GetOpenFileName(LPOPENFILENAME lpofn);

    参数lpofn的定义如下:

    typedef struct tagOFN { 
      DWORD         lStructSize; 
      HWND          hwndOwner; 
      HINSTANCE     hInstance; 
      LPCTSTR       lpstrFilter; 
      LPTSTR        lpstrCustomFilter; 
      DWORD         nMaxCustFilter; 
      DWORD         nFilterIndex; 
      LPTSTR        lpstrFile; 
      DWORD         nMaxFile; 
      LPTSTR        lpstrFileTitle; 
      DWORD         nMaxFileTitle; 
      LPCTSTR       lpstrInitialDir; 
      LPCTSTR       lpstrTitle; 
      DWORD         Flags; 
      WORD          nFileOffset; 
      WORD          nFileExtension; 
      LPCTSTR       lpstrDefExt; 
      LPARAM        lCustData; 
      LPOFNHOOKPROC lpfnHook; 
      LPCTSTR       lpTemplateName; 
    #if (_WIN32_WINNT >= 0x0500)
      void *        pvReserved;
      DWORD         dwReserved;
      DWORD         FlagsEx;
    #endif // (_WIN32_WINNT >= 0x0500)
    } OPENFILENAME, *LPOPENFILENAME;
    

     

    该接口定义的各个参数成员请参考MSDN的详细解释,这里我们最常用到的几项如下:

    lpstrFilter:该参数用于设置打开或保存对话的文件格式过滤,比如下图中的文件过滤情景,相信所有的读者朋友都见过:

    filter

    lpstrFile:该参数用于保存选择结束后的选择文件。

    nMaxFile:该参数指出上面用于保存结果文件的buffer字符长度。

    Flags:该参数最常见用于设置是否可以多选,其他请查看MSDN。

    • 文件保存对话框

    文件保存对话框跟文件打开对话几乎完全一样,参数相同。功能也是为用户保存文件时选择或新建文件名、保存路径进行选择的公共操作接口。API函数定义如下:

    BOOL GetSaveFileName(LPOPENFILENAME lpofn);

    该函数的参数与上面完全一样,只是有些不能在文件保存对话框函数中使用,保存文件时不能多选名字。

    • 颜色选择对话框

    该对话框函数提供统一接口用于选择颜色,API函数定义如下:

    BOOL ChooseColor(LPCHOOSECOLOR lpcc);

    参数lpcc最重要的参数:

    lpCustColors,它指向一个包含16个值的数组,该数组包含了对话框中自定义颜色的红、绿、蓝(RGB)值。如果用户修改这些颜色,系统将用新的颜色值更新这个数组。如果要在多个ChooseColor函数中保存这个新的数组,我们应该为该数组分配静态内存空间。

    rgbResult:该参数保存了选择的颜色值。

    • 字体选择对话框:

    该对话框函数用于浏览并选择字体,包括颜色。API函数定义如下:

    BOOL ChooseFont(LPCHOOSEFONT lpcf);

    对话框函数运行结束后的字体在rgbColors参数中,我们可以用它来创建选择的字体。

    以上各个结构的其他成员请参考MSDN。

    下面我们以一个demo程序演示以上几种公共对话框的基本用法。

    #include <windows.h>
    #include <tchar.h>
    
    #pragma comment(linker,"\"/manifestdependency:type='win32' "\
    			"name='Microsoft.Windows.Common-Controls' "\
    			"version='6.0.0.0' processorArchitecture='*' "\
    			"publicKeyToken='6595b64144ccf1df' language='*'\"")
    
    #define IDC_FILE_DIALOG  1001
    #define IDC_COLOR_DIALOG 1002
    #define IDC_FONT_DIALOG  1003
    
    static TCHAR szAppName[] = TEXT("CommonDialog");
    static LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
    {
         HWND     hWnd;
         MSG      msg;
         WNDCLASS wndclass;
    
         wndclass.style         = CS_HREDRAW | CS_VREDRAW;
         wndclass.lpfnWndProc   = WndProc;
         wndclass.cbClsExtra    = 0;
         wndclass.cbWndExtra    = 0;
         wndclass.hInstance     = hInstance;
         wndclass.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
         wndclass.hCursor       = LoadCursor(NULL, IDC_ARROW);
         wndclass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
         wndclass.lpszMenuName  = NULL;
         wndclass.lpszClassName = szAppName;
    
         if (!RegisterClass(&wndclass))
         {
              MessageBox (NULL, TEXT("This program requires Windows NT!"), szAppName, MB_ICONERROR);
              return 0;
         }
         
         hWnd = CreateWindow(szAppName,             // window class name
                              szAppName,            // window caption
                              WS_OVERLAPPEDWINDOW,  // window style
                              CW_USEDEFAULT,        // initial x position
                              CW_USEDEFAULT,        // initial y position
                              400,              // initial x size
                              300,              // initial y size
                              NULL,             // parent window handle
                              NULL,             // window menu handle
                              hInstance,        // program instance handle
                              NULL);            // creation parameters
         
         ShowWindow(hWnd, iCmdShow);
         UpdateWindow(hWnd);
         
         while (GetMessage(&msg, NULL, 0, 0))
         {
              TranslateMessage(&msg);
              DispatchMessage(&msg);
         }
    
         return msg.wParam;
    }
    
    static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
    	HDC hDC;
    
    	switch (message)
    	{
    	case WM_CREATE:
    		CreateWindow(TEXT("BUTTON"), TEXT("file dialog"), WS_CHILD|WS_VISIBLE, 20, 40, 160, 40, hWnd, (HMENU)IDC_FILE_DIALOG, NULL, NULL);
    		CreateWindow(TEXT("BUTTON"), TEXT("color dialog"),WS_CHILD|WS_VISIBLE, 20, 100, 160, 40, hWnd, (HMENU)IDC_COLOR_DIALOG, NULL, NULL);
    		CreateWindow(TEXT("BUTTON"), TEXT("font dialog"), WS_CHILD|WS_VISIBLE, 20, 160, 160, 40, hWnd, (HMENU)IDC_FONT_DIALOG, NULL, NULL);
    		return 0;
    
    	case WM_COMMAND:
    		{
    			int wmId = LOWORD(wParam);
    			switch (wmId)
    			{
    			case IDC_FILE_DIALOG:
    				{
    					OPENFILENAME ofn;
    					TCHAR ext[] = TEXT(".dat");
    					TCHAR szFile[MAX_PATH] = TEXT("default");
    					TCHAR szFilter[] = TEXT("文本文件 (*.txt)\0*.txt\0")
    						           TEXT("数据文件 (*.dat)\0*.dat\0")
    							   TEXT("All Files (*.*)\0*.*\0\0");
    					
    					ZeroMemory(&ofn, sizeof(ofn));
    					ofn.lStructSize  = sizeof(ofn);
    					ofn.hwndOwner	 = hWnd;
    					ofn.lpstrFilter  = szFilter;
    					ofn.nFilterIndex = 1;		  // 1 to default show *.txt type file; 2 to default show *.dat type file.
    					ofn.lpstrFile	 = szFile;
    					ofn.nMaxFile	 = MAX_PATH;
    					ofn.lpstrDefExt  = ext;
    					ofn.Flags	 = OFN_PATHMUSTEXIST|OFN_OVERWRITEPROMPT;
    					if (GetOpenFileName(&ofn))//GetOpenFileName, GetSaveFileName
    					{
                                                    //将选择的文件输出到窗口
    						LPTSTR file = ofn.lpstrFile; //file就是保存或者打开的文件名
    						hDC = GetDC(hWnd);
    						TextOut(hDC, 200, 50, ofn.lpstrFile, _tcslen(ofn.lpstrFile));
    						ReleaseDC(hWnd, hDC);
    					}
    				}
    				break;
    
    			case IDC_COLOR_DIALOG:
    				{
    					CHOOSECOLOR cc;
    					static COLORREF acrCustClr[16];
    
    					ZeroMemory(&cc, sizeof(cc));
    					cc.lStructSize  = sizeof(cc);
    					cc.hwndOwner	= hWnd;
    					cc.lpCustColors = (LPDWORD)acrCustClr;
    					if (ChooseColor(&cc))
    					{
                                                    //用选择的颜色画一个实心矩形
    						RECT rect = {240, 100, 340, 140};
    						hDC = GetDC(hWnd);
    						HBRUSH hBrush = CreateSolidBrush(cc.rgbResult);
    						SelectObject(hDC, hBrush);
    						FillRect(hDC, &rect, hBrush);
    						DeleteObject(hBrush);
    						ReleaseDC(hWnd, hDC);
    					}
    				}
    				break;
    
    			case IDC_FONT_DIALOG:
    				{
    					CHOOSEFONT cf;
    					LOGFONT lf;
    					ZeroMemory(&cf, sizeof(cf));
    					cf.lStructSize = sizeof(cf);
    					cf.hwndOwner   = hWnd;
    					cf.lpLogFont   = &lf;
    					cf.Flags       = CF_SCREENFONTS | CF_EFFECTS;
    					if (ChooseFont(&cf))
    					{
                                                    //用选择的字体输出一行测试文本
    						TCHAR str[] = TEXT("Font 测试!");
    						HFONT hFont = CreateFontIndirect(cf.lpLogFont);
    						DWORD rgbCurrent = cf.rgbColors;
    						hDC = GetDC(hWnd);
    						SelectObject(hDC, hFont);
    						SetTextColor(hDC, cf.rgbColors);
    						TextOut(hDC, 200, 170, str, _tcslen(str));
    						DeleteObject(hFont);
    						ReleaseDC(hWnd, hDC);
    					}
    				}
    				break;
    
    			default:
    				break;
    			}
    		}
    		return 0;
    
    	case WM_DESTROY:
    		PostQuitMessage(0);
    		return 0 ;
    	}
    
    	return DefWindowProc (hWnd, message, wParam, lParam);
    }
    

    以上demo运行后的文件选择对话框如下:

    fileopen

    选择颜色对话框如下:

    colordlg

    选择字体对话框如下:

    fontdlg

    在demo中选择三个对话框后,选择的文件、颜色和字体均画在窗口上:

    commdlg

    以上只是演示了文件打开/保存、颜色选择和字体选择对话框,虽然只演示了最简单的功能,但也是最基本、最常用的功能,能满足不少应用需求,更多的函数及用法请参考MSDN,学会查MSDN是Windows平台上开发的必备基础。

      更多经验交流可以加入Windows编程讨论QQ群454398517


    关注微信公众平台:程序员互动联盟(coder_online),你可以第一时间获取原创技术文章,和(java/C/C++/Android/Windows/Linux)技术大牛做朋友,在线交流编程经验,获取编程基础知识,解决编程问题。程序员互动联盟,开发人员自己的家。

    【Windows编程】系列第七篇:Menubar的创建和使用

    转载请注明出处http://www.coderonline.net/,谢谢合作!

    
    展开全文
  • 它不接受用户的任何输入,用户单击OK按钮后,对话框自动关闭,然后返回程序中继续执行。 >> msgbox('欢迎使用MATLAB')% 建立一个没有标题的消息对话框 >> msgbox('欢迎使用MATLAB','MATALB','warn')%% 建立一...
  • matlab GUI之通用对话框

    千次阅读 2012-07-19 01:06:34
    它不接受用户的任何输入,用户单击OK按钮后,对话框自动关闭,然后返回程序中继续执行。 >> msgbox('欢迎使用MATLAB')% 建立一个没有标题的消息对话框 >> msgbox('欢迎使用MATLAB','MATALB','warn')%%
  • 第九篇:模式对话框通用控件(上) 对话框是一个真正的窗口,它不但可以接受消息,而且可以被移动和关闭,还可以它的客户区中进行绘图操作。对话框可以分为模式对话框和无模式对话框两种,两者区别是在对话框被...
  • 对话框和常用控件

    千次阅读 2011-04-20 09:22:00
    对话框是一个特殊类型的窗口,任何对窗口进行的操作(如:移动、最大化、最小化等)都可在对话框中 实施,一般来说,在对话框中通过各种控件(如:按钮、编辑框、列表框、组合框等)来和用户进行交互。控件系统...
  • 对话框

    千次阅读 2011-05-03 15:51:00
    对话框控件是密不可分的,每个对话框内一般都有一些控件对话框依靠这些控件与用户进行交互.一个典型的对话框例子是选择了File-Open命令后弹出的文件对话框. 对话框是一种复杂的用户界面,本章的讨论将围绕...
  • 打开文件对话框使用实例

    千次阅读 2012-11-29 21:06:43
    1、打开文件对话框属于Windows通用对话框! 2、使用API函数GetOpenFileName可以显示打开文件对话框并返回所选文件。 3、MFC对GetOpenFileName的封装类为CFileDialog。 、、、、、、、、、、、、、、、、、、、、...
  • Win32通用控件

    千次阅读 2013-11-12 14:33:27
     核心提示:9.1.1 通用控件的分类 大部分的通用控件由Comctl32.dll模块提供,所以使用之前要源程序中包含相应的include和includelib语句: include Comctl32.inc includelib Comctl32.libComctl32.dll中提供的...
  • VC对话框

    千次阅读 2008-10-27 11:25:00
    关键字 VC 对话框 主要内容:1, 建立有模式对话框和无模式对话框2, 控件的对齐及焦点设置3, 实例4, 通用对话框5, 常用函数对话框可按其动作模式分为“有模式”和“无模式”两大类。对于有模式对话框,对话框...
  • 第12章 对话框

    2018-08-22 20:22:38
    对话框的一般形式是包含多种子窗口控件的弹出式窗口,这些控件的大小和位置程序资源描述文件的「对话框模板」中指定。虽然程序写作者能够「手工」定义对话框模板,但是现在通常是Visual C++ Developer Studio中...
  • WIN32中,模式对话框的创建一般是使用DialogBox来进行创建的。而非模式对话框则是利用CreateWindow来创建的。MFC或是WTL中,模式对话框一般是使用DoModal,而非模式对话框的创建则是使用Create。 模式对话框...
  • 对话框(api)

    2014-08-18 17:24:00
    对话框 ...壹佰软件开发小组整理编译 ...如果有很多输入超出了菜单可以处理的...对话框的一般形式是包含多种子窗口控件的弹出式窗口,这些控件的大小和位置程序资源描述文件的「对话框模板」中指定。虽然程序写...
  • 第九章 对话框

    2012-07-24 21:54:39
    Miscrosoft Windows中,对话框就是应用程序创建的用于获取用户输入的一个临时窗口。应用程序一般用对话框来提示用户输入命令的附加信息。对话框通常都含有一个或多个用户可以输入文本、选择可选择项或者指导命令...
  • 5-about interface

    2007-04-16 01:20:00
    界面设计对话框的分类:Visual Basic.NET中的...通用对话框控件Visual Basic.NET的通用对话框控件共有6种 : OpenFileDialog,SaveFileDialog,FolderBrowserDialog,FontDialog,ColorDialog,PrintDialog,PrintPreview
  • Delphi的对话框窗体

    2012-01-01 23:56:00
    “真正的对话框”意思是指用传统方法建立起来的对话框,它有资源编译器和资源脚本文件建立其他一些编程环境中其对话框就是用这种方式建立的,Delphi没有用传统的对话框)。 对话框有以下几种特征,这正是与正常...
  • Wince 对话框程序设计

    2015-01-17 22:10:00
    如何编程实现wince下“打开文件夹对话框”呢?这里就要涉及到下面要分析的知识了,对话框是一种特殊的窗口,它wince 作为应用程序和程序使用者之间的交流窗口,通过显示和获取信息使人们的交流更加方便,这里先...
  • MFC对话框学习笔记

    2015-03-15 08:26:06
    对话框上的各种控件,它们也是窗口,只不过是对话框窗口的子窗口,其对应类也是CWnd的派生类 CDialog类从CWnd类派生而来,所以它继承了CWnd类的成员函数,具有CWnd类的基本功能 CDialog类本身也有自己的成员函数...
  • MFC对话框摘要

    2011-11-06 22:31:08
    1.静态文本控件 ...CStatic类中,还有一些常用的函数,如:SetBitmap函数、SetIcon函数、SetCursor函数、SetEnhMetaFile函数等。 2.图片控件  同样是静态控件,由CStatic维护。 3.EditBox控件

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 8,562
精华内容 3,424
关键字:

在通用对话框控件建立打开