SendMessageA and SendMessageW in Win7 migrated from WinXP
EDIT: Working code posted below, nonworking code commented out. You must use the same CHAR_T for retrieving data from windows as you used to create them in Win7.
I have a dialog written in C that works perfectly in WinXP but fails to collect user input from an edit control in unicode in Win7. The problem occurs on the first call to SendMessageW as shown below:
/* 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. */
}
}
It appears SendMessageA works multiple times with message = WM_GETTEXT or WM_SETTEXT, and suddenly, when a wide string is required, SendMessageW fails. Now, I know everyone is thinking that you should pick a CHAR_T and stick with it by always using SendMessage, but it's not so; Win32.hlp explicitly notes that it's possible to use both in the same program by calling the individual functions manually. I'm sure someone else is ready to say that the control itself is or becomes committed to one particular CHAR_T, but that's not the case in WinXP, where this worked perfectly. That particular edit control is also never set to an ASCII string explicitly.
The program interacts with WinHttp, which requires all WCHAR strings, a开发者_StackOverflow社区nd that's where the SendMessageW comes in. The rest of the inputs are only used internally and are primarily parsed integers with unit labels, which are more convenient and efficient in ASCII, if for no other reason than because the program was originally written that way.
So what do? Have they really changed something as integral as SendMessage to be incompatible? If so, is it a known bug with a work around, or is the ability to switch CHAR_T at will a deprecated feature? Is there some other easier way than expanding the input to WCHAR manually after getting it with SendMessageA?
My understanding is that if you step through your code with debugger - you will see the reason.
First of all, the two SendMessages you have one after another, they are using different window handles, so they are not of the kind to give you the same result. Let's talk about the one that gives you the problem:
cchResultLen = (int) SendMessageW(hDomainEdit, WM_GETTEXT, 256, (LPARAM) wszDomain);
// cchResultLen is ZERO! wszDomain[0] is null. Edit control is not empty
Standing with debugger on this line, check your hDomainEdit variable. Perhaps it's not valid, like NULL or damaged by some other code. This would explain invalid handle and zero result.
All window handles were fine. The folks at MSDN informed me that any window created with an 'A' function - in this case DialogBoxParamA() - must be accessed via the 'A' functions. As for the fact that it worked in XP, they said "Just because it works doesn't mean it's right". I suppose that functionality was deprecated - would have been nice to hear about that before it stopped working!
精彩评论