以下是Unicode的示例:为了简洁起见,我避免使用win32应用程序:
在主要内容中,我创建了一个edit
控件,一个button
用于从中检索文本,并在按下时将其添加到listbox
。所以我使用了struct MSG
的对象,并在while循环peeking
中阻止了来自消息队列的消息。
int main(){
// An edit control where I can add any unicode text to.
HWND hEdit = CreateWindowExW(WS_EX_CLIENTEDGE,
L"Edit", L"你好! 你好吗?", WS_BORDER | WS_VISIBLE | WS_SYSMENU,
200, 100, 250, 70, 0, 0, GetModuleHandle(NULL), NULL);
// A listobx to receive the content of the edit control when pressing the button get text.
HWND hLstBx = CreateWindowExW(WS_EX_CLIENTEDGE,
L"Listbox", NULL, WS_BORDER | WS_VISIBLE | WS_OVERLAPPEDWINDOW,
500, 100, 170, 400, 0, 0, GetModuleHandle(NULL), NULL);
// A button when pressed adds the content of the edit to the listbox.
HWND hGetText = CreateWindowExW(WS_EX_CLIENTEDGE,
L"Button", L"中文", WS_BORDER | WS_VISIBLE,
450, 300, 100, 70, 0, 0, GetModuleHandle(NULL), NULL);
// msg struct to pass to GetMessage to receive the messages from the queue.
MSG msg;
// blocking and getting messages from the queue.
while (GetMessageW(&msg, 0, 0, 0)) {
// some virtual keys translation.
TranslateMessage(&msg);
// sending the message to the specified window.
DispatchMessageW(&msg);
// Now after the messages sent to the target Window I check which control the message has been passed to, So if it is the button then:
if (msg.message == WM_LBUTTONDOWN &&
msg.hwnd == hGetText) {
std::wstring wstrBuff;
int txtLen = SendMessageW(hEdit, WM_GETTEXTLENGTH, 0, 0);
// SendMessageW(hEdit, WM_GETTEXT, txtLen + 1, (LPARAM)wstrBuff.c_str());
// MessageBoxW(0, wstrBuff.c_str(), 0, 0);
wchar_t lpTxt[MAX_PATH];
SendMessageW(hEdit, WM_GETTEXT, MAX_PATH, (LPARAM)lpTxt);
SendMessageW(hLstBx, LB_ADDSTRING, 0, (LPARAM)lpTxt);
MessageBoxW(0, lpTxt, L"你好! 你好吗?", 0);
//delete[]lpTxt;
}
}
std::wcout << std::endl << std::endl;
std::wcin.get();
return 0;
}
除了以下内容之外,所有内容都可以正常工作:如果我取消注释上面的行,我会遇到断言消息的运行时错误,显示txtLen
和编辑控件文本的大小。这是因为有一些字符串重叠吗?
如果我输入一个小文本它可以正常工作,但是有一个大约14个字符的文本我得到了错误。
这也是将std::wstring.c_str()
传递给SendMessageW()
以获取文字的正确方法吗?
最后一个问题:如何正确有效地从控件中检索Unicode文本?如何将LPWSTR
与动态记忆结合使用:我不想耗尽筹码。
注意:我将源文件保存为utf8 /BOM
,否则我会收到不可读的字符。感谢为我提供帮助的成员。
答案 0 :(得分:4)
发送(LPARAM)wstrBuff.c_str()
将返回指向只读缓冲区的指针,该缓冲区具有单个空符号,而不是txtLen + 1
个符号的缓冲区。如果您使用的是最新的VS(使用C ++ 17标准支持),则可以修改代码以提供正确的指针:
std::wstring wstrBuff;
wstrBuff.resize(txtLen + 1);
const LRESULT copied_symbols_count = SendMessageW
(
hEdit
, WM_GETTEXT
, static_cast<WPARAM>(wstrBuff.size())
, reinterpret_cast<LPARAM>(wstrBuff.data())
);
if(copied_symbols_count == txtLen)
{
assert(L'\0' == wstrBuff.back());
wstrBuff.pop_back(); // get rid of terminating null
}
else
{
wstrBuff.clear(); // something went wrong...
}
请注意,C ++ 17标准添加了非const限定的wstring::data()
方法,可以安全地用于获取指向可写缓冲区的指针。