正常的时候,打开并选择一个文件这样写代码:
char szFileName[MAX_PATH] = { 0 }; OPENFILENAME ofn; memset(szFileName, 0, MAX_PATH); memset(&ofn, 0, sizeof(ofn)); ofn.lStructSize = sizeof(ofn); ofn.hwndOwner = NULL; ofn.hInstance = GetModuleHandle(NULL); ofn.nMaxFile = MAX_PATH; ofn.lpstrTitle = _T("打开"); ofn.lpstrInitialDir = "."; ofn.lpstrFile = szFileName; ofn.lpstrDefExt = _T(".dat"); ofn.lpstrFilter = _T("参数文件(*.dat)\0*.dat\0\0"); if (GetOpenFileName(&ofn)) { // TODO }但是在涉及多语言软件的时候,怎么样才能把lpstrFilter内容放到资源文件里面去定义呢?显然直接输入参数文件(*.dat)\0*.dat\0\0是不被允许的,因为\0后面的字符串都将被自动截断了,只能输入参数文件(*.dat),但是如果缺少了后面一段,过滤器就失去了意义。于是我想到到字符串格式化,将内容拆分为2段,前面一段参数文件(*.dat)放到资源文件里面去,后面一段*.dat拼接起来不就可以了吗?于是乎就有了下面这段代码:
// 代码1 CString strFilter; strFilter.Format(_T("%s(*.dat)\0*.dat\0\0"), _T("参数文件")); ofn.lpstrFilter = strFilter; // 代码2 TCHAR szFilter[_MAX_PATH] = { 0 }; memset(&szFilter, 0, _MAX_PATH); strcpy(&szFilter[0], _T("参数文件")); strcpy(&szFilter[_tcslen(szFilter) + 1], _T("*.dat")); ofn.lpstrFilter = szFilter;代码1,很显然\0后面字符串将会被自动截断。
代码2,程序调用成功,但是函数退出会提示堆栈遭到破坏,显然也是行不通的。
既然是堆栈遭到破坏,那么我们能不能不破坏栈结构,将信息写入到szFilter里面去呢?既然问题明了,办法总是能想出来的:
TCHAR szFilter[_MAX_PATH] = { 0 }; memset(&szFilter, 0, _MAX_PATH); memmove(&szFilter[0], _T("参数文件"), _tcslen(_T("参数文件"))); memmove(&szFilter[_tcslen(szFilter) + 1], _T("*.dat"), _tcslen(_T("*.dat"))); ofn.lpstrFilter = szFilter;这里用memmove或者memcpy就无所谓了。