使用Windows API OPENFILENAME对话框实现文本文件读写问题咨询
问题修复与功能实现方案
现有代码的核心问题
你当前的代码存在3个关键缺失导致功能无法正常工作:
- 未定义存储选中文件路径的
szFile缓冲区,也未给ofn.lpstrFile赋值,GetOpenFileName无法返回用户选中的文件路径 - 调用
CreateFile拿到文件句柄后没有执行读取文件内容的逻辑 - 读取到的内容没有同步到
hWndEdit编辑框控件
打开文件功能完整实现
修正后的OpenFile函数代码
// 确保hWndEdit是全局可访问的编辑框句柄,或者作为参数传入函数 void OpenFile(HWND hWndEdit) { OPENFILENAME ofn; WCHAR szFile[MAX_PATH] = {0}; // 存储选中的文件路径,必须提前定义 HANDLE hFile; ZeroMemory(&ofn, sizeof(ofn)); ofn.lStructSize = sizeof(ofn); ofn.hwndOwner = hWndEdit; // 所有者窗口设为当前主窗口/编辑框父窗口即可 ofn.lpstrFile = szFile; // 绑定路径存储缓冲区 ofn.nMaxFile = MAX_PATH; ofn.lpstrFilter = L"NoteRecorder Notes\0*.recnote\0Text File\0*.txt\0All Files\0*.*\0\0"; // 过滤器末尾必须加两个\0结束 ofn.nFilterIndex = 1; ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST; if (GetOpenFileName(&ofn) == TRUE) { // 打开文件 hFile = CreateFile(szFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) { CloseHandle(hFile); return; } // 获取文件大小 DWORD fileSize = GetFileSize(hFile, NULL); if (fileSize == INVALID_FILE_SIZE || fileSize == 0) { CloseHandle(hFile); SendMessage(hWndEdit, WM_SETTEXT, 0, (LPARAM)L""); return; } // 分配缓冲区存储文件内容,+2是为了末尾加字符串结束符 WCHAR* fileContent = (WCHAR*)HeapAlloc(GetProcessHeap(), 0, fileSize + 2); if (fileContent == NULL) { CloseHandle(hFile); return; } // 读取文件内容 DWORD readBytes; ReadFile(hFile, fileContent, fileSize, &readBytes, NULL); fileContent[readBytes / sizeof(WCHAR)] = L'\0'; // 补字符串结束符 CloseHandle(hFile); // 设置内容到编辑框 SendMessage(hWndEdit, WM_SETTEXT, 0, (LPARAM)fileContent); HeapFree(GetProcessHeap(), 0, fileContent); } }
调用方式修改
case WM_COMMAND: switch (LOWORD(wParam)) // 注意WM_COMMAND的低字节是控件ID { case 12: // 打开按钮ID OpenFile(hWndEdit); // 传入编辑框句柄 break; } break;
注:如果你的文本文件是ANSI编码,读取后需要用
MultiByteToWideChar函数转成宽字符再设置到编辑框,避免乱码。
保存文件功能实现
保存函数代码
void SaveFile(HWND hWndEdit) { OPENFILENAME ofn; WCHAR szFile[MAX_PATH] = {0}; HANDLE hFile; ZeroMemory(&ofn, sizeof(ofn)); ofn.lStructSize = sizeof(ofn); ofn.hwndOwner = hWndEdit; ofn.lpstrFile = szFile; ofn.nMaxFile = MAX_PATH; ofn.lpstrFilter = L"NoteRecorder Notes\0*.recnote\0Text File\0*.txt\0All Files\0*.*\0\0"; ofn.nFilterIndex = 1; // OFN_OVERWRITEPROMPT会在覆盖已有文件时弹出提示 ofn.Flags = OFN_PATHMUSTEXIST | OFN_OVERWRITEPROMPT; if (GetSaveFileName(&ofn) == TRUE) { // 获取编辑框内的文本长度 int textLen = GetWindowTextLength(hWndEdit); if (textLen == 0) { // 空内容直接创建空文件即可 hFile = CreateFile(szFile, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); CloseHandle(hFile); return; } // 分配缓冲区存储编辑框内容 WCHAR* editContent = (WCHAR*)HeapAlloc(GetProcessHeap(), 0, (textLen + 1) * sizeof(WCHAR)); GetWindowText(hWndEdit, editContent, textLen + 1); // 创建/覆盖文件 hFile = CreateFile(szFile, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) { HeapFree(GetProcessHeap(), 0, editContent); CloseHandle(hFile); return; } // 写入内容到文件 DWORD writeBytes; WriteFile(hFile, editContent, textLen * sizeof(WCHAR), &writeBytes, NULL); CloseHandle(hFile); HeapFree(GetProcessHeap(), 0, editContent); } }
调用方式
你只需要在WM_COMMAND中新增保存按钮的响应逻辑即可:
case 13: // 假设保存按钮的ID是13 SaveFile(hWndEdit); break;
内容的提问来源于stack exchange,提问作者user16709023
相关产品推荐
相关产品推荐

