使用GetOpenFileName 笔记

来源:互联网 发布:哪些端口不是敏感端口 编辑:程序博客网 时间:2024/04/26 11:40

今天使用GetOpenFileName时在Release下没问题,在debug下莫名奇妙的失败,调用CommDlgExtendedError得到返回值为CDERR_INITIALIZATION,在网上找到原因如下:

摘自http://www.kbalertz.com/222003/Fails.lpstrFile.Buffer.Terminated.aspx

PRB: GetOpenFileName() Fails If lpstrFile Buffer Is Not NULL Terminated

View products that this article applies to.
Article ID:222003Last Review:May 14, 2004Revision:2.1
This article was previously published under Q222003

SYMPTOMS

The GetOpenFileName function fails with a CommDlgExtendedError of CDERR_INITIALIZATION(0x0002).

Back to the top

CAUSE

The lpstrFile buffer of the OPENFILENAME structure is not NULL terminated.

Back to the top

RESOLUTION

According to the Platform SDK documentation, the first character of the lpstrFile buffer must be NULL if the buffer is not being used for initialization of theFile Name edit box.

Back to the top

STATUS

This behavior is by design.

Back to the top

MORE INFORMATION

The following Win32 Application demonstrates the problem:
#include <Windows.h>// If the next line is commented out, GetOpenFileName fails.//#define NULL_TERMINATEint WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst,                             LPSTR szCmdLine, int nCmdShow){   longlErrMsg = 0;   OPENFILENAME ofn;   TCHAR sfile[MAX_PATH];   ZeroMemory(&ofn, sizeof(ofn));   ZeroMemory(sfile, sizeof(TCHAR)*MAX_PATH);   #ifndefNULL_TERMINATE   // Not NULL terminated.   {   int i;   for (i = 0; i < MAX_PATH; i++)   sfile[i] = ' ';   }   #else      // NULL terminated.   sfile[0] = '\0';   #endif    // Initialize OPENFILENAME structure.   ofn.lStructSize = sizeof(ofn);   ofn.hwndOwner = NULL;    ofn.lpstrFile = sfile;    ofn.nMaxFile = MAX_PATH;   ofn.lpstrFilter = NULL;   ofn.nFilterIndex = 1;   ofn.lpstrTitle = TEXT("Please Select a File");   ofn.lpstrInitialDir = NULL;   ofn.lpstrCustomFilter = NULL;   ofn.nMaxCustFilter = 0;   ofn.lpstrFileTitle = NULL;   ofn.nMaxFileTitle = 0;   ofn.nFileOffset = 0;   ofn.nFileExtension = 0;   ofn.lpstrDefExt = NULL;   ofn.lCustData = 0;   ofn.lpfnHook = 0;   ofn.lpTemplateName = 0;   ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;   // Call GetOpenFileName().   if (GetOpenFileName(&ofn))   {   MessageBox(NULL, TEXT("GetOpenFileName() Successful"), TEXT("OpenDialog"), MB_OK);   }   else   {      TCHARsErrMsg[256];      lErrMsg = CommDlgExtendedError();      wsprintf(sErrMsg,TEXT("Error %d returned from GetOpenFileName()"), lErrMsg);      MessageBox(NULL, sErrMsg, TEXT("OpenDialog"), MB_OK);   }   return lErrMsg;}
 
用VC编译时会报连接出错,需要手动加入LIB\COMDLG32.LIB才行,如果要默认过滤文件的话可以使用以下例子:

#include <Windows.h>

// If the next line is commented out, GetOpenFileName fails.//#define NULL_TERMINATE

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst,                             LPSTR szCmdLine, int nCmdShow){

   OPENFILENAME ofn;   TCHAR sfile[MAX_PATH];   long lErrMsg;      ZeroMemory(&ofn, sizeof(ofn));

   ZeroMemory(sfile, sizeof(TCHAR)*MAX_PATH);

   #ifndef NULL_TERMINATE   // Not NULL terminated.   {   int i;   for (i = 0; i < MAX_PATH; i++)    sfile[i] = ' ';   }   #else      // NULL terminated.   sfile[0] = '\0';   #endif 

   // Initialize OPENFILENAME structure.   ofn.lStructSize = sizeof(ofn);   ofn.lpstrFile = sfile;    ofn.nMaxFile = MAX_PATH;   ofn.lpstrFile[0] = TEXT('\0');   ofn.lpstrFilter = TEXT("ALL\0*.*\0Text\0*.TXT\0");   ofn.nFilterIndex = 1;   ofn.lpstrFileTitle = NULL;   ofn.nMaxFileTitle = 0;   ofn.lpstrInitialDir = NULL;   ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_EXPLORER;

   // Call GetOpenFileName().   if (GetOpenFileName(&ofn))   {    MessageBox(NULL, sfile, TEXT("OpenDialog"), MB_OK);   }   else   {      TCHAR  sErrMsg[256];      lErrMsg = CommDlgExtendedError();      wsprintf(sErrMsg,TEXT("Error %d returned from GetOpenFileName()"), lErrMsg);      MessageBox(NULL, sErrMsg, TEXT("OpenDialog"), MB_OK);   }

   return lErrMsg;}