РЕДАКТИРОВАТЬ: рабочий код размещен ниже, нерабочий код закомментирован. Вы должны использовать тот же CHAR_T для получения данных из окон, который вы использовали для их создания в Win7.
У меня есть диалоговое окно, написанное на C, которое отлично работает в WinXP, но не может собирать данные, вводимые пользователем из элемента управления редактированием в Юникоде в Win7. Проблема возникает при первом вызове 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, для которого требуются все строки WCHAR, и именно здесь на помощь приходит SendMessageW. Остальные входные данные используются только для внутреннего использования и в основном представляют собой анализируемые целые числа с метками единиц измерения, которые более удобны и эффективны в ASCII, если нет по другой причине, кроме того, что программа изначально была написана именно так.
Так что же делать? Неужели они действительно изменили что-то столь же неотъемлемое, как SendMessage, на несовместимое? Если да, то это известная ошибка, которую можно обойти, или возможность переключать CHAR_T по желанию является устаревшей функцией? Есть ли другой более простой способ, чем расширение ввода в WCHAR вручную после его получения с помощью SendMessageA?
SendMessageW()
; по крайней мере, в качестве отправной точки. Вы уверены, чтоhDomainEdit
действительно? Что происходит, когда вы используете на немSendMessageA
? Кроме того, почему бы не использоватьGetWindowText[AW]
? - person atzz   schedule 15.09.2011