《Windows核心编程》の“打开”和“保存”文件对话框

Windows操作系统为一些常用功能提供了一些通用对话框(Common Dialog Box),比如,在不同应用程序中运行打开文件、选择字体、选择颜色等操作时,不同程序显示的对话框的模样都是一样。这些对话框是操作系统提供的,实现对话框的代码封装在Comdlg32.dll库文件中,由于不同版本的Comdlg32.dll在设计上可能有所不同,所以不同版本的Windows下对话框会有所不同。

Windows提供多种通用对话框,每种通用对话框都使用一个专用的函数来创建和显示,另外,提供一个数据结构供初始化对话框使用,并在同一个数据结构中返回用户在对话框中输入的数据。

 

“打开”文件和“保存”文件对话框

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

函数原型如下:

BOOL WINAPI GetOpenFileName(

  __inout  LPOPENFILENAME lpofn

);

BOOL WINAPI GetSaveFileName(

  __inout  LPOPENFILENAME lpofn

);

 

其中lpofn参数是一个指针,指向一个OPENFILENAME结构,程序在调用函数前需要在结构中填写初始化数据,两个函数使用的结构是一样的,只是初始化数据不同而已:

typedef struct tagOFN {

  DWORD         lStructSize; //结构的长度

  HWND          hwndOwner; //所属窗口,可以为NULL

  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

} OPENFILENAME, *LPOPENFILENAME;

 

结构中重要字段说明:

lpStrFilter---指定文件名筛选字符串,该字段决定了对话框中“文件类型”下拉式列表框的内容,字符串可以由多组内容组成,每组包括一个说明字符串和一个筛选字符串,字符串最后用两个0结束。如下,字符串将在列表中显示两项内容,选择不同项目时分别列出“.txt”文件或者所有文件“*.*:

'Text Files(*.txt)', 0, '*.txt', 0, 'All Files(*.*)', 0, '*.*', 0, 0

 

lpstrFile---指向一个包含文件名的缓冲区。如果这个缓冲区中已经包含了一个文件名,那么对话框初始化时显示的是这个文件名。当用户选择一个新文件时,函数在这里返回新的文件名。

 

nFileOffset---返回文件名字符串中文件名的起始位置,如当用户选择了文件“C:/dir1/file.txt”是,将返回8

 

Flags---该字段决定对话框的不同行为,它可以是下列值的组合:

OFN_ALLOWMULTISELECT        //允许同时选择多个文件名

OFN_CREATEPROMPT //如果用户输入一个不存在的文件名,对话框向用户提示“是否建立文件”

OFN_FILEMUSTEXIST  //用户只能选择一个已经存在的文件名,

//使用这个标志时必须同时使用OFN_PATHMUSTEXIST

OFN_HIDEREADONLY         //对话框中不显示“以只读方式打开”复选框

OFN_OVERWRITEPROMPT       //在“保存”文件对话框使用时,当选择一个已经存在的文件时,

                            //对话框会提示“是否覆盖文件”

OFN_PATHMUSTEXIST        //用户输入用户名时,路径必须存在

OFN_READONLY //对话框中“以只读方式”复选框初始化时处于选中状态

 

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

 

打开对话框代码片段如下:

OPENFILENAME ofn;       // common dialog box structure

char szFile[260];       // buffer for file name

HWND hwnd;              // owner window

HANDLE hf;              // file handle

 

// Initialize OPENFILENAME

ZeroMemory(&ofn, sizeof(ofn));

ofn.lStructSize = sizeof(ofn);

ofn.hwndOwner = hwnd;

ofn.lpstrFile = szFile;

// Set lpstrFile[0] to '/0' so that GetOpenFileName does not

// use the contents of szFile to initialize itself.

ofn.lpstrFile[0] = '/0';

ofn.nMaxFile = sizeof(szFile);

ofn.lpstrFilter = "All/0*.*/0Text/0*.TXT/0";

ofn.nFilterIndex = 1;

ofn.lpstrFileTitle = NULL;

ofn.nMaxFileTitle = 0;

ofn.lpstrInitialDir = NULL;

ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;

 

// Display the Open dialog box.

 

if (GetOpenFileName(&ofn)==TRUE)

    hf = CreateFile(ofn.lpstrFile,

                    GENERIC_READ,

                    0,

                    (LPSECURITY_ATTRIBUTES) NULL,

                    OPEN_EXISTING,

                    FILE_ATTRIBUTE_NORMAL,

                    (HANDLE) NULL);

 

打开保存对话框的实例代码片段如下:

// Obtain a handle to a reference device context. 

 

hdcRef = GetDC(hWnd);

 

// Determine the picture frame dimensions. 

// iWidthMM is the display width in millimeters. 

// iHeightMM is the display height in millimeters. 

// iWidthPels is the display width in pixels. 

// iHeightPels is the display height in pixels 

 

iWidthMM = GetDeviceCaps(hdcRef, HORZSIZE);

iHeightMM = GetDeviceCaps(hdcRef, VERTSIZE);

iWidthPels = GetDeviceCaps(hdcRef, HORZRES);

iHeightPels = GetDeviceCaps(hdcRef, VERTRES);

 

// Retrieve the coordinates of the client 

// rectangle, in pixels. 

 

GetClientRect(hWnd, &rect);

 

// Convert client coordinates to .01-mm units. 

// Use iWidthMM, iWidthPels, iHeightMM, and 

// iHeightPels to determine the number of 

// .01-millimeter units per pixel in the x- 

//  and y-directions. 

 

rect.left = (rect.left * iWidthMM * 100)/iWidthPels;

rect.top = (rect.top * iHeightMM * 100)/iHeightPels;

rect.right = (rect.right * iWidthMM * 100)/iWidthPels;

rect.bottom = (rect.bottom * iHeightMM * 100)/iHeightPels;

 

// Load the filename filter from the string table. 

 

LoadString(hInst, IDS_FILTERSTRING,

     (LPSTR)szFilter, sizeof(szFilter));

 

// Replace the '%' separators that are embedded 

// between the strings in the string-table entry 

// with '/0'. 

 

for (i=0; szFilter[i]!='/0'; i++)

    if (szFilter[i] == '%')

            szFilter[i] = '/0';

 

// Load the dialog title string from the table. 

 

LoadString(hInst, IDS_TITLESTRING,

     (LPSTR)szTitle, sizeof(szTitle));

 

// Initialize the OPENFILENAME members. 

 

szFile[0] = '/0';

 

Ofn.lStructSize = sizeof(OPENFILENAME);

Ofn.hwndOwner = hWnd;

Ofn.lpstrFilter = szFilter;

Ofn.lpstrFile= szFile;

Ofn.nMaxFile = sizeof(szFile)/ sizeof(*szFile);

Ofn.lpstrFileTitle = szFileTitle;

Ofn.nMaxFileTitle = sizeof(szFileTitle);

Ofn.lpstrInitialDir = (LPSTR)NULL;

Ofn.Flags = OFN_SHOWHELP | OFN_OVERWRITEPROMPT;

Ofn.lpstrTitle = szTitle;

 

// Display the Filename common dialog box. The 

// filename specified by the user is passed 

// to the CreateEnhMetaFile function and used to 

// store the metafile on disk. 

 

GetSaveFileName(&Ofn);

 

// Load the description from the string table. 

 

LoadString(hInst, IDS_DESCRIPTIONSTRING,

     (LPSTR)szDescription, sizeof(szDescription));

 

// Replace the '%' string separators that are 

// embedded between strings in the string-table 

// entry with '/0'.  

 

for (i=0; szDescription[i]!='/0'; i++)

{

    if (szDescription[i] == '%')

            szDescription[i] = '/0';

}

 

// Create the metafile device context. 

 

hdcMeta = CreateEnhMetaFile(hdcRef,

          (LPTSTR) Ofn.lpstrFile,

          &rect, (LPSTR)szDescription);

 

if (!hdcMeta)

    errhandler("CreateEnhMetaFile", hWnd);

 

// Release the reference device context. 

 

ReleaseDC(hWnd, hdcRef);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值