DELPHI中的自定义通用对话框处理和消息处理
一、自定义通用对话框 在Delphi的VCL的Dialog包中存在多个通用对话框, 比如TopenDialog(文件选择对话框)、 TsaveDialog(文件保存对话框) 、TopenPictureDialog(图片打开对话框)、TfontDialog(字体选 择对话框) 、TfindDialog(文件查找对话框)、TreplaceDialog(文件替换对话框)等13个
常用、 通用的标准对话框,这里的标准对话框采用的是Windows系统内置的标准对话框,对话框 的风格和样式和操作系统的风格和样式是一致的, 之所以能够保持一致, 是因为通用对话框 是由通过对话框模版生成的窗体,只不过这些对话框模版由操作系统定义。 建立自定义通用对话框有两种方式: 1、 修改通过对话框模版来实现的; 2、 通过代码在运行时添加控件; 这里首先介绍一下通过对话框模板方式的实现步骤: 1、对话框模板方式 Delphi的通用对话框位于Delphi系统库的VCL.Dialogs单元,Delphi 中所有通用对话框 类都继承自 TCommonDialg 抽象类, 以TfindDialog为例,可以看到创建查找兑换的结构信息如下: tagFINDREPLACEW = packed record lStructSize: DWORD; hWndOwner: HWND; hInstance: HINST; Flags: DWORD; lpstrFindWhat: PWideChar; lpstrReplaceWith: PWideChar; wFindWhatLen: Word; wReplaceWithLen: Word; lCustData: LPARAM; UINT stdcall; { ptr. to hook fn. or nil } lpTemplateName: PWideChar; { custom template name } 在这个抽象类中定义了PWideChar 类型的Template属性,这个属性就是用来存放模版 标识的,通过在IDE中对操作系统标准的对话框模板进行修改,因为lpTemplateName是保 护属性,所以需要对通用对话框进行继承,继承的类中定义好TemplateRes属性,将修改好 的模板赋给TemplatesRes属性,例如:TemplateRes := Windows.MakeIntResource(131);其中 131为资源ID。 该方法比较麻烦,需要修改模板文件,并引入资源,同时对于新加入的控件,需要捕捉 windows消息进行处理,所以推荐使用下面的方式。 { size of this struct $20 } { handle to owner's window } { instance handle of.EXE that contains cust. dlg. template } { one or more of the fr_?? } { ptr. to search UnicodeString { ptr. to replace UnicodeString { size of find buffer { size of replace buffer } } } }
{ data passed to hook fn. }
lpfnHook: function(Wnd: HWND; Message: UINT; wParam: WPARAM; lParam: LPARAM):
2、代码在运行时添加控件 在电子病历编辑器控件中,在标准打印的基础上增加了几个特殊选项,比如
“仅打印奇数页” 、 “仅打印偶数页” 、 “奇偶页边距互换”三个选项,对应于标准打印对 话框是没有的,这里需要在标准对话框的基础上,在空白区域加上我们需要的控件,这里只 要继承标准的打印对话框,在对话框的空白区域,算好控件需要放置的位置就可以了,过程 如下: 1、 首先创建TprintDialogEx类继承于标准对话框TprintDialog,并命名为TprintDialogEx; TPrintDialogEx = class(TPrintDialog) 2、 创建一个Tpanel,计算好位置到空白区域,这里打印窗口是Fixed窗口,空白区域 属于绝对位置; FExtendedPanel := TPanel.Create(self); with fExtendedPanel do begin Name := 'ExtendedPanel'; Caption := ''; SetBounds(0, 0, 169, 200); BevelOuter := bvNone; BorderWidth := 6; TabOrder := 1; End; 3、将3个CheckBox对应FextendedPanel的位置进行放置,并挂接事件就OK了; FCheckBoxOdd:=TCheckBox.Create(Self); with FCheckBoxOdd do begin Name:='CheckBoxOdd'; Checked:=False;
// (204, 5, 169, 200);
caption:='仅打印奇数页';
SetBounds( 2, 7, 90, 28 );
Parent := FExtendedPanel;
end;
….
这种方法最大的好处是方便,不需要再修改模板并且再去捕捉
系统Windows