用户使用Window应用程序时,经常要打开文件,可有时用户打开文件时却打开了一个不是要求的文件,这显得非常麻烦。因此,许多应用程序便给OpenFile通用对话框增添了预展功能,使得用户在选择文件时,可以先预视其内容。在这里,笔者也向你介绍这种功能的编程方法。
WINDOW的通用对话框OpenFile,在使用,可以安装用户定义的勾子函数。这样,原OpenFile窗口的消息先通过用户的勾子函数过滤。若用户在通用对话框中增加一个Edit控制(此处,以预展文本文件内容为例),处理OpenFile通用对话框中的 CDN_SELCHANGE消息(文件名选择更改消息),即可完成这种功能。
用户定义的勾子函数,WINDOW要求其原形定义如下:
typedef UINT (APIENTRY *LPCCHOOKPROC) (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
对于OpenFile通用对话框中的一些常见消息,WINDOWS会向用户定义的勾子发送WM_NOTIFY消息,此时,lParam指向一数据结构如下的指针:
typedef struct _OFNOTIFYA { NMHDR hdr; LPOPENFILENAMEA lpOFN; LPSTR pszFile; // May be NULL } OFNOTIFYA, FAR *LPOFNOTIFYA; |
而NMHDR在WINDOWS定义如下:
typedef struct tagNMHDR { HWND hwndFrom; UINT idFrom; UINT code; } NMHDR; |
其中:hwndFrom 表示发送消息控件的句柄;idFrom表示控件的ID值,而且code表示通告的消息。
在WINDOWS95中通告的消息在commdlg.h中定义如下
#define CDN_SELCHANGE (CDN_FIRST-0x0001) //文件名列表中的文件名更改时发送的消息 #define CDN_FOLDERCHANGE (CDN_FIRST - 0x0002) //路径更改时发送的消息 #define CDN_SHAREVIOLATION (CDN_FIRST - 0x0003) //共享按钮改更时发送的消息 #define CDN_HELP (CDN_FIRST - 0x0004) //HELP按钮按下消息 #define CDN_FILEOK (CDN_FIRST - 0x0005) //OK按钮按下消息 |
因为此处,我们仅处理用户选择的文件名发生更改时,才预展,因此我们定义的勾子函数中,仅处理CDN_SELCHANGE消息。
另外,当什么文件都预展时,用户会发现WINDOWS的速度明显减慢,因此,我决定在OpenFile对话框中增加一个"是否预展"的CheckBox按钮。只有当用户选中了它时才预展。当然,此时,还需要我们自己处理这个CheckBox发送的消息。
以上问题解决后,我们只需要将一个Edit和一个CheckBox增加到一个无窗体的对话框中,并将WINDOWS本身的OpenFile对话框用一个TEXT控件代替,ID值设置为stc32(定义在dlgs.h中)。
此时还需要将OPENFILENAME结构中的lpfnHook成员,设置成用户定义的勾子函数,将lpTemplateName成员设置成用户定义对话框的ID值(需要用MAKEINTRESOURCE),此外,成员Flags需要设置成OFN_EXPLORER(WINDOW32中使用) | OFN_ENABLEHOOK(允许使用用户定义的勾子函数) | OFN_ENABLETEMPLATE(允许用户定义的对话框模板)。