yasofiz yasofiz - 3 months ago 30
C Question

GetWindowTextW doesnt grab a wide string

I have the following code which gets the data from the textbox input ( pure winapi )

BOOL CALLBACK DlgProc(HWND hw, UINT msg, WPARAM wp, LPARAM lp) {
switch (msg)
{
case WM_INITDIALOG:
SendDlgItemMessage(hw, IDC_EDITMASK, EM_SETLIMITTEXT, 512, 0);
return true;

case WM_CLOSE:
DestroyWindow(hw);
return TRUE;


case WM_COMMAND:
HWND hCtrl;
int length;
wchar_t * text;
switch (LOWORD(wp))
{

case IDCPROCESS:

nElements = 1;
hCtrl = GetDlgItem(hw, IDC_EDITMASK);

length = GetWindowTextLengthW(hCtrl);
if (length == 0) {
MessageBox(hw, L"Неверная маска", L"Ошибка", 0);
return FALSE;
}

text = (wchar_t*)HeapAlloc(hProcessHeap, HEAP_ZERO_MEMORY, length * sizeof(wchar_t) + sizeof(wchar_t));

GetWindowTextW(hCtrl, text, length + sizeof(wchar_t));

char *test = (char*)text;

int pos = 0;
int startPos = 0;
char dbg[2] = { 0 };
while (pos <= length) {
dbg[0] = text[pos];
OutputDebugStringA(dbg); // here i output the text by characters
if (text[pos] == ',' || pos == length) {

if(!szMasks)
szMasks = (wchar_t**)HeapAlloc(hProcessHeap, HEAP_ZERO_MEMORY, sizeof(wchar_t*)*nElements);
else
szMasks = (wchar_t**)HeapReAlloc(hProcessHeap, HEAP_ZERO_MEMORY,szMasks, sizeof(wchar_t*)*nElements);

int bufferSize = pos - startPos;
szMasks[nElements - 1] = (wchar_t*)HeapAlloc(hProcessHeap, HEAP_ZERO_MEMORY, (bufferSize + 2) * sizeof(wchar_t));
if(bufferSize % sizeof(wchar_t) != 0)
bufferSize++;
int copyLength = bufferSize / sizeof(wchar_t);

wcsncpy(szMasks[nElements - 1], text + startPos, copyLength);
OutputDebugStringW(szMasks[nElements - 1]);
OutputDebugStringW(L"\r\n");

nElements++;
startPos = pos+1;

}

pos++;
}

searchMasks.count = nElements-1;
searchMasks.szMasks = szMasks;

HeapFree(hProcessHeap, 0, text);
DestroyWindow(hw);

return TRUE;


}
break;



case WM_DESTROY:
PostQuitMessage(0);
return TRUE;
}

return FALSE;
}


So if i enter russian text for example, i get the valid wide string, everything is ok. If i switch to english, and input let's say "word", i get the buffer in the text that it's not formed as a wide string, i expect it to be :
"w\0o\0r\0d"
but i get
"word"

But i get a regular
char*
string instead, which is really bad because i need to parse the text by some rule, searching for the character ',' and copying data to the other buffer according to it, using
wcsncpy
, so i must always have a proper formatted
wchar_t*
string. Is there any way to deal with this, and why does
GetWindowTextW
doesn't form a proper wide string? I'am compiling my project using
UNICODE
character set, and not multibyte.

UPDATED THE CODE

char * test = (char*) text
Give a valid ansi string, if input only latin chracters in the input box, not a proper formatted
wchar_t*

Answer

A C-style string is a sequence of characters, terminated by a NUL character. Anything from the first NUL character is not considered part of a C-style string.

When you call OutputDebugStringA with an argument of \0 it is interpreted as an empty string, i.e. a string with length zero. Writing a string of length zero and not writing a string have the same observable effect.

You are dealing with wide character strings. Your logic to deduce the string type is wrong.