编辑:下面发布的工作代码,非工作代码已注释掉。您必须使用相同的CHAR_T来从Windows中检索数据,就像在Win7中创建它们一样。
我有一个用C语言编写的对话框在WinXP中完美运行,但无法从Win7中unicode的编辑控件收集用户输入。第一次调用SendMessageW时会出现问题,如下所示:
/* handles to controls */
HWND hDomainEdit;
HWND hOtherEdit;
HWND hTextOut;
HWND hButton;
/* buffers to receive input */
WCHAR wszDomain[256];
CHAR szOtherInput[512];
CHAR szBuffer[512]; //added to hold temporary value of wszDomain
/* a test string */
const CHAR szTest[] = "This is a test of SendMessageA."
BOOL dialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) {
if (message == WM_INIT) {
/* get all the handles shown above, then... */
SendMessageA(hTextOut, WM_SETTEXT, 0, (LPARAM) szTest);
/* worked fine */
/* do a few other things */
} else if (message == WM_COMMAND) {
/* are some other conditions are true? they sure are */
/* time to collect a bunch of input from controls */
int cchResultLen = (int) SendMessageA(hOtherEdit, WM_GETTEXT, 512, (LPARAM) szOtherInput);
/* cchResultLen is correctly the length of the user input */
/* cchResultLen = (int) SendMessageW(hDomainEdit, WM_GETTEXT, 256, (LPARAM) wszDomain); */
/* begin new code */
cchResultLen = (int) SendMessageA(hDomainEdit, WM_GETTEXT, 512, (LPARAM) szBuffer);
cchResultLen = MultiByteToWideChar(CP_UTF8, 0, szBuffer, cchResultLen, wszDomain, 256);
wszDomain[cchResultLen] = 0; /* above doesn't terminate string */
/* after SendMessageW(), cchResultLen was 0, no string transferred, no error
message. using SendMessageA, all is well. */
}
}
SendMessageA看起来多次使用message = WM_GETTEXT或WM_SETTEXT,突然,当需要一个宽字符串时,SendMessageW失败。现在,我知道每个人都在想你应该选择一个CHAR_T并坚持使用SendMessage,但事实并非如此; Win32.hlp明确指出,通过手动调用各个函数,可以在同一程序中使用它们。我敢肯定其他人已经准备好说控件本身已经或者变成了一个特定的CHAR_T,但在WinXP中并非如此,这种情况完美无缺。该特定编辑控件也永远不会显式设置为ASCII字符串。
程序与WinHttp交互,WinHttp需要所有WCHAR字符串,这就是SendMessageW所在的位置。其余输入仅在内部使用,主要是使用单位标签解析整数,这在ASCII中更方便有效,如果没有其他原因,因为该程序最初是以这种方式编写的。
那又怎么样?他们真的改变了与SendMessage不相容的东西吗?如果是这样,它是一个已知的错误解决方法,还是能够随意切换CHAR_T一个不推荐的功能?在使用SendMessageA获取WCHAR后,还有其他更简单的方法吗?
答案 0 :(得分:0)
我的理解是,如果您使用调试器逐步执行代码 - 您将看到原因。
首先,两个SendMessages是一个接一个,它们使用不同的窗口句柄,所以它们不是那种给你相同的结果。让我们谈谈给你解决问题的那个:
cchResultLen = (int) SendMessageW(hDomainEdit, WM_GETTEXT, 256, (LPARAM) wszDomain);
// cchResultLen is ZERO! wszDomain[0] is null. Edit control is not empty
在此行上使用调试器,检查 hDomainEdit 变量。也许它无效,如NULL或被其他一些代码损坏。这将解释无效句柄和零结果。
答案 1 :(得分:0)
所有窗口手柄都很好。 MSDN的人告诉我,任何使用'A'函数创建的窗口 - 在本例中为DialogBoxParamA() - 必须通过'A'函数访问。至于它在XP中运行的事实,他们说“只是因为它起作用并不意味着它是正确的”。我认为该功能已被弃用 - 在它停止工作之前听到这个功能会很高兴!