Win7中的SendMessageA和SendMessageW从WinXP迁移

时间:2011-09-15 08:42:36

标签: c winapi windows-7 windows-xp sendmessage

编辑:下面发布的工作代码,非工作代码已注释掉。您必须使用相同的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后,还有其他更简单的方法吗?

2 个答案:

答案 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中运行的事实,他们说“只是因为它起作用并不意味着它是正确的”。我认为该功能已被弃用 - 在它停止工作之前听到这个功能会很高兴!