Get text using SendMessage() C++ - c++

I am trying to get text from a textbox in a specific window. For this I'm using SendMessage Api function, I dont know if this is the corect way:
SendMessage(hwnd, WM_GETTEXT, 0, 0);
But I dont know how to print the text. For the argument 3 and 4 in msdn site it says: Additional message-specific information. So i dont know if I need to pass something else beside 0. I tried this also:
SendMessage(hwnd, WM_GETTEXT, sizeof(text), LPARAM(text));
But it prints the name of the textbox, I need to retrieve the text inside the box?
How can I do this? Is SendMessage() the correct API function to use ?
Thank you.
edit:
I omit to say, I am enumerating the child windows from a window, and for me it looks like a textbox, where you have to type a name. I am retrieving the username of a Instant messaging window so I cant compare it to a string, is that a textbox ?

You should use GetWindowText. More information here.

Read the MSDN documentation again. It does NOT say "Additional message-specific information" for those parameters:
wParam The maximum number of
characters to be copied, including the
terminating null character.
ANSI applications may have the string
in the buffer reduced in size (to a
minimum of half that of the wParam
value) due to conversion from ANSI to
Unicode.
lParam A pointer to the buffer that
is to receive the text.

This code works for local only:
char *szText;
szText = (char *)GlobalAlloc(GPTR, 255);
SendMessage(hEditControl, WM_GETTEXT, 255, (LPARAM)szText);
MessageBox(hWnd, szText, "It's your message", MB_OK | MB_TOPMOST);
GlobalFree((HGLOBAL)szText);

Related

Getting all text from Notepad++ document in c++ for Notepad++ plugin

I am writing a plugin for notepad++ with visual studio 2013 (C++).
How can I get all text from notepad++ documantation?
There is a SCI_GETTEXT function for this. I use sendMessage function.(e.g ::SendMessage(curScintilla, SCI_GETTEXT, end, null))
But this function returns long value. Can I convert this long value to char or how can I do this in other way?
SCI_GETTEXT doesn't work without sendMessage funtion.
If I understood correctly their documentation You will have to send the WM_GETTEXT message to the handle of the editor window, where wParam will be the length of text you can accomodate and lParam will be the address of the preallocated data. After SendMessage returns you are suppsoed to have the data populated.
(I am not familiar with the SCI_...stuff , this is the "oldschool" way of solving this problem :) )

SendMessage to TextBox Window Child in C++ not working

char arbc[60];
cout << "Message: ";
cin.getline(arbc+'\0',sizeof(arbc)+1);
system("pause");
PostMessage(hwndch,WM_SETTEXT,(WPARAM)*arbc,0);
So hwndch is a window child and the child is a textbox, it's parent is the main window form. The problem is that WM_SETTEXT isn't setting the text of the textbox to the string of characters. I know it's not a problem with the windowchild because WM_CHAR outputs at least 1 character in the textbox.
Note: I'm modifying the handles of another process.
You cannot use PostMessage with WM_SETTEXT. That's a synchronous message. Your problem is even greater when the window is in a different process. The system needs to marshal the text from your process into another process. It cannot do that with an asynchronous message.
Use SendMessage instead.
Your other problems include at least the following:
The wParam argument is wrong. That parameter is ignored. Pass (LPARAM)arbc to lParam instead. The documentation is quite clear.
You should not use C strings in any case. Use std::string, and then c_str().
Your use of sizeof is wrong. Your use of getline is all wrong too.
You seem confused over which function you are calling. The title says SendMessage, the code says PostMessage.
You probably want something along these lines:
std::cout << "Message: ";
std::string msg;
std::getline(std::cin, msg);
SendMessage(hwndch, WM_SETTEXT, 0, (LPARAM)msg.c_str());

Adding a string to a listbox results in weird characters

I have made a function that send strings to listbox using WIN32
char data[] = "abcd";
addToList(hWnd,data);
void addToList(HWND hWnd,char data[] ){
SendMessage(GetDlgItem(hWnd,IDC_LISTBOX),LB_ADDSTRING,0,(LPARAM)data);
}
when I execute this it's send data to list box but the problem they appeared in weird characters, I have tried wchar_t also but the problem still issued
First of all, you should be checking your API calls for errors. You need to check the return values of all your calls to API functions.
That said, given the code in the question,
SendMessage(GetDlgItem(hWnd,IDC_LISTBOX),LB_ADDSTRING,0,(LPARAM)data);
If that results in an item being added to the list box, then it means that GetDlgItem did indeed return a valid window handle, and data did indeed point to valid memory. In which case the only explanation for what you report is that the text encoded did not match.
So, we can assume that the SendMessage macro evaluates to SendMessageW. And since you are passing ANSI encoded text, that mismatch explains the symptoms. The function treats the text as UTF-16 encoded.
One obvious solution is to use SendMessageA instead. However, a better solution, in my view, would be to pass UTF-16 encoded data.
wchar_t data[] = L"abcd";
....
void addToList(HWND hWnd, const wchar_t *data)
{
SendMessage(GetDlgItem(hWnd,IDC_LISTBOX), LB_ADDSTRING, 0, (LPARAM)data);
}
Obviously your code would add in the error checking that I mentioned at the start.

How to print many format strings into window?

After successfully solve this problem how to print a format string into window, another problem comes to me.
If there are many format strings, how to print them into window? For example below:
sprintf(buf, formatString-1...);
SendMessage(hwnd, WM_SETTEXT, NULL, (LPARAM)buf);
...
sprintf(buf, formatString-2...);
SendMessage(hwnd, WM_SETTEXT, NULL, (LPARAM)buf);
...
sprintf(buf, formatString-3...);
SendMessage(hwnd, WM_SETTEXT, NULL, (LPARAM)buf);
...
Notice that only formatString-3 is printed into window, while i want to put them all into window. How to do this?(PS: Please Do not use buf concatenate) Thank you!~
Are you trying to produce a console-style or log-style window, with multiple lines of text, one after the other?
If so, simplest approach is to pick a control that will do this for you. Something like a static (usually used for labels) typically is only useful for one string at a time. If you want to display more than one line of output, your two main options are:
Listbox control: add items to the end using LB_ADDSTRING. (You may want to follow that with LB_SETCURSEL or similar to select the last item, so that as items are added to the end, it will scroll to show the last item.)
Read-only Multi-line Edit control: append text to the end using the technique outlined here on MSDN. Note that with this approach, you need to supply the "\r\n" yourself to create a new line.
Each WM_SETTEXT message overwrites the previous one. That's why you only observe the effects of the final message.
Although you state that you don't want to concatenate the buffer before sending the WM_SETTEXT message, that's the only option with WM_SETTEXT.
If you have an edit control then you can insert text using the EM_REPLACESEL message.

WinAPI: How to process keyboard input in custom edit control

So i'm creating my own edit control (multi-line textbox) in C++ using the windows API. It's going pretty well, but i'm a bit confused about one thing.
First off, the control is being built to be able to handle unicode and all input will be converted to unicode. In other words, all input will be stored as wchar_t.
What i'm confused about is which message to process for keyboard input. MSDN has the following window notifications:
WM_CHAR
WM_KEYDOWN
WM_UNICHAR
And others, but i believe it's one of these three that i need to process. My guess would be WM_UNICHAR, but the documentation is a bit unclear about it. Also, upon looking over the VKcodes, i saw this:
VK_PACKET
0xE7
Used to pass Unicode characters as if they were keystrokes. The VK_PACKET key is the low word of a 32-bit Virtual Key value used for non-keyboard input methods. For more information, see Remark in KEYBDINPUT, SendInput, WM_KEYDOWN, and WM_KEYUP.
Sorry if it's a silly question, but i just want to be sure about this.
If your control is created as a unicode window (using CreateWindowW) then
in WM_CHAR you will get wide char out of the box.
If you want to provide non-unicode version of your control then you need to handle
WM_INPUTLANGCHANGE, something like this:
case WM_INPUTLANGCHANGE:
{
HKL NewInputLocale = (HKL) lParam ;
g_InputCodePage = LangToCodePage( LOWORD(NewInputLocale) ) ;
}
And so your WM_CHAR handler should look like:
case WM_CHAR:
{
unsigned char c = (byte)wParam;
if(!::IsWindowUnicode(hwnd))
MultiByteToWideChar(g_InputCodePage , 0, (LPCSTR) &c, 1, (LPWSTR) &wParam, 1) ;
}
And don't forget about WM_IME_CHAR and friends.
And yet about RTL input.
WM_KEYDOWN is sent to the window with the focus when a non-system key has been pressed. When the message is translated by the TranslateMessage function, a WM_CHAR message is sent to the window. WM_CHAR uses UTF-16. WM_UNICHAR is similat to WM_CHAR, except that it uses UTF-32. It's purpose is to send/post Unicode characters to ANSI windows. If the window is ANSI (created with CreateWindowA), when WM_CHAR is generated. If it is Unicode (created with CreateWindowW) then WM_UNICHAR is generated. So your control should probably handle both.
Also see this discussion Why is my WM_UNICHAR handler never called?.