РЕДАКТИРОВАТЬ: рабочий код размещен ниже, нерабочий код закомментирован. Для извлечения данных из окон вы должны использовать тот же CHAR_T, который вы использовали для их создания в Win7.
У меня есть диалоговое окно, написанное на C, которое прекрасно работает в WinXP, но не может собрать пользовательский ввод из элемента управления редактирования в Unicode в 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 работает несколько раз с сообщением = WM_GETTEXT или WM_SETTEXT, и внезапно, когда требуется широкая строка, происходит сбой SendMessageW. Теперь я знаю, что все думают, что вы должны выбрать CHAR_T и придерживаться его, всегда используя SendMessage, но это не так; Win32.hlp явно отмечает, что можно использовать оба в одной и той же программе, вызывая отдельные функции вручную. Я уверен, что кто-то еще готов сказать, что сам элемент управления привязан или становится привязанным к одному конкретному CHAR_T, но это не относится к WinXP, где это работало идеально. Этот конкретный элемент управления для редактирования также никогда не устанавливается явно в строку ASCII.
Программа взаимодействует с WinHttp, для которого требуются все строки WCHAR, и именно здесь вступает SendMessageW. Остальные входные данные используются только для внутренних целей и представляют собой, в основном, анализируемые целые числа с метками модулей, которые более удобны и эффективны в ASCII, если только по той причине, что программа изначально была написана таким образом.
Так что же делать? Они действительно изменили что-то такое же неотъемлемое, как SendMessage, чтобы быть несовместимым? Если это так, то это известная ошибка с обходным решением или возможность переключать CHAR_T по желанию является устаревшей функцией? Есть ли какой-то другой более простой способ, чем расширение ввода вручную до WCHAR после получения его с помощью SendMessageA?