如何读取文本文件并将其显示在 win 32 unicode 字符集中的编辑控件上?
Posted
技术标签:
【中文标题】如何读取文本文件并将其显示在 win 32 unicode 字符集中的编辑控件上?【英文标题】:how to read text file and show it on edit control in win 32 unicode character set? 【发布时间】:2016-01-08 04:56:27 【问题描述】:我一直在制作一个程序,通过单击按钮从文本文件中读取文本并将其显示在编辑控件上。单击按钮时,将打开对话框以选择文本文件并单击确定,它应该显示在编辑控件上,但我没有以正确的格式获取文本。 这是输出:output image from visual studio
#include <windows.h>
const wchar_t g_szClassName[] = L"myWindowClass" ;
#define IDC_MAIN_EDIT 101
#define IDC_MAIN_BUTTON 102
#define IDC_MAIN_BUTTON1 103
BOOL LoadTextFileToEdit(HWND hEdit, LPTSTR pszFileName)
HANDLE hFile;
BOOL bSuccess = FALSE;
hFile = CreateFile(pszFileName, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, 0, NULL);
if (hFile != INVALID_HANDLE_VALUE)
DWORD dwFileSize;
dwFileSize = GetFileSize(hFile, NULL);
if (dwFileSize != 0xFFFFFFFF)
wchar_t* pszFileText;
pszFileText = (wchar_t*)GlobalAlloc(GPTR, dwFileSize + 1);
if (pszFileText != NULL)
DWORD dwRead;
if (ReadFile(hFile, (LPVOID)pszFileText, dwFileSize, &dwRead, NULL))
pszFileText[dwFileSize] = 0 ; // Add null terminator
if (SetWindowText(hEdit, (LPCWSTR)pszFileText))
bSuccess = TRUE; // It worked!
GlobalFree(pszFileText);
CloseHandle(hFile);
return bSuccess;
// Step 4: the Window Procedure
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
switch (msg)
case WM_CREATE:
HFONT hfont;
HWND hedit,button,btnsave;
hedit = CreateWindowEx(WS_EX_CLIENTEDGE, L"EDIT", L"My Own Window", WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_HSCROLL | ES_AUTOVSCROLL | ES_MULTILINE
, CW_USEDEFAULT, CW_USEDEFAULT, 100, 100, hwnd, (HMENU)IDC_MAIN_EDIT, GetModuleHandle(NULL), NULL);
button = CreateWindowEx(WS_EX_CLIENTEDGE, L"BUTTON", L"Open File", WS_CHILD | WS_VISIBLE|WS_BORDER|WS_TABSTOP
,CW_USEDEFAULT, CW_USEDEFAULT, 50, 20, hwnd, (HMENU)IDC_MAIN_BUTTON, GetModuleHandle(NULL), NULL);
btnsave = CreateWindowEx(WS_EX_CLIENTEDGE, L"BUTTON", L"Save File", WS_CHILD | WS_VISIBLE | WS_EX_STATICEDGE|WS_TABSTOP
, CW_USEDEFAULT, CW_USEDEFAULT, 50, 20, hwnd, (HMENU)IDC_MAIN_BUTTON1, GetModuleHandle(NULL), NULL);
if (hedit == NULL)
MessageBox(NULL, L"Could not create edit box", L"Error!", MB_ICONEXCLAMATION | MB_OK);
return 0;
hfont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
SendMessage(hedit, WM_SETFONT, (WPARAM)hfont, MAKELPARAM(FALSE, 0));
//SetWindowText(button, L"Open File");
//SetWindowText(btnsave, L"Save File");
break;
case WM_COMMAND:
switch (LOWORD(wParam))
case IDC_MAIN_BUTTON:
OPENFILENAME ofn;
wchar_t szFileName[MAX_PATH] = L"";
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(ofn); // SEE NOTE BELOW
ofn.hwndOwner = hwnd;
ofn.lpstrFilter = L"Text Files (*.txt)\0*.txt\0All Files (*.*)\0*.*\0";
ofn.lpstrFile = szFileName;
ofn.nMaxFile = MAX_PATH;
ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
ofn.lpstrDefExt = L"txt";
if (GetOpenFileName(&ofn))
// Do something usefull with the filename stored in szFileName
HWND hedit;
hedit = GetDlgItem(hwnd, IDC_MAIN_EDIT);
LoadTextFileToEdit(hedit, szFileName);
break;
case IDC_MAIN_BUTTON1:
OPENFILENAME ofn;
wchar_t szFileName[MAX_PATH] = L"";
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(ofn); // SEE NOTE BELOW
ofn.hwndOwner = hwnd;
ofn.lpstrFilter = L"Text Files (*.txt)\0*.txt\0All Files (*.*)\0*.*\0";
ofn.lpstrFile = szFileName;
ofn.nMaxFile = MAX_PATH;
ofn.Flags = OFN_EXPLORER | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT;
ofn.lpstrDefExt = L"txt";
if (GetOpenFileName(&ofn))
// Do something usefull with the filename stored in szFileName
HWND hedit;
hedit = GetDlgItem(hwnd, IDC_MAIN_EDIT);
break;
default:
break;
break;
case WM_SIZE:
HWND hEdit,button,btnsave;
RECT rcClient;
GetClientRect(hwnd, &rcClient);
hEdit = GetDlgItem(hwnd, IDC_MAIN_EDIT);
button = GetDlgItem(hwnd, IDC_MAIN_BUTTON);
btnsave = GetDlgItem(hwnd, IDC_MAIN_BUTTON1);
SetWindowPos(hEdit, NULL, 0, 0, rcClient.right, rcClient.bottom-120, SWP_NOZORDER);
SetWindowPos(button, NULL, rcClient.right-200, rcClient.bottom-30, 70, 30, SWP_NOZORDER);
SetWindowPos(btnsave, NULL, rcClient.right - 100, rcClient.bottom - 30, 70, 30, SWP_NOZORDER);
break;
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
return 0;
int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
WNDCLASSEX wc;
HWND hwnd;
MSG msg;
//step 1: registering the window class
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hinstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wc.lpszMenuName = NULL;
wc.lpszClassName = g_szClassName;
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if (!RegisterClassEx(&wc))
MessageBox(NULL, L"Window Registration failed", L"Error!", MB_ICONEXCLAMATION | MB_OK);
return 0;
//step 2: Creating the Window
hwnd = CreateWindowEx(WS_EX_CLIENTEDGE,
g_szClassName, L"The title of my window", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 500, 300,
NULL, NULL, hinstance, NULL);
if (hwnd == NULL)
MessageBox(NULL, L"Window Registration failed", L"Error!", MB_ICONEXCLAMATION | MB_OK);
return 0;
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
//Step-3: the message loop
while (GetMessage(&msg, NULL, 0, 0)>0)
TranslateMessage(&msg);
DispatchMessage(&msg);
return msg.wParam;
【问题讨论】:
文件实际上是否包含 Unicode 文本?您可能应该调用MultiByteToWideChar
并传递与文件内容匹配的代码页标识符。
另外,你不应该有那么多演员表。
它是一个普通的文本文件@BenVoigt,你能告诉我是什么问题并提供解决方案吗?
pszFileText[dwFileSize] = 0
行是缓冲区溢出。您正在破坏内存(并且未能正确终止字符串)。
我已经尝试过 pszFileText[dwFileSize] = '\0' 和 pszFileText[dwFileSize] = L'\0' 但同样的问题,但现在我得到了解决方案并发布了它
【参考方案1】:
我得到了我的问题的答案。实际上在 unicode 宽字符串中,一个字符是 2 个字节,所以我们需要分配两倍的内存。所以替换:
pszFileText = (wchar_t*)GlobalAlloc(GPTR, dwFileSize + 1);
与
pszFileText = (wchar_t*)GlobalAlloc(GPTR, 2*(dwFileSize + 1));
和
if (ReadFile(hFile, (LPVOID)pszFileText, dwFileSize, &dwRead, NULL))
与
if (ReadFile(hFile, (LPVOID)pszFileText, 2*(dwFileSize+1), &dwRead, NULL))
【讨论】:
以上是关于如何读取文本文件并将其显示在 win 32 unicode 字符集中的编辑控件上?的主要内容,如果未能解决你的问题,请参考以下文章