使用GetOpenFileName 笔记

今天使用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

Article ID:222003
Last Review:May 14, 2004
Revision: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 the File 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_TERMINATE

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, 
                            LPSTR szCmdLine, int nCmdShow)
{
   long	lErrMsg = 0;
   OPENFILENAME ofn;
   TCHAR sfile[MAX_PATH];

   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.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
   {
      TCHAR		sErrMsg[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; }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值