SendMessage to TextBox Window Child in C++ not working - c++

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());

Related

WM_GETTEXT returning only single character

I'm a chemist new to coding and am working on a script to help me automatically process some of my data. The code I'm working on right now involves using WM_GETTEXT to grab the title of a window handle. However, right now the char buffer is only grabbing a single character, rather than the whole title. It looks like someone several years ago had a similar problem (link: http://www.cplusplus.com/forum/beginner/58207/), which suggests the issue may be related to mixing data types. I tried switching to a TCHAR as suggested, but cannot compile on doing so (receive error that I cannot convert from "const char[1] to TCHAR[254]). Here's the code I'm using:
int textLen = (int)SendMessage(windowHandle, WM_GETTEXTLENGTH, 0, 0);
std::cout << "The handle length is: " << textLen << std::endl;
const int bufferSize = 254;
char textBuffer[bufferSize] = "";
SendMessage(windowHandle, WM_GETTEXT, (WPARAM)bufferSize, (LPARAM)textBuffer);
std::cout << "The handle title is: " << textBuffer << std::endl;
Does anyone have any suggestions? I'm working in Microsoft Visual Studio, which I think may be part of the problem, but I'm not sure how to fix it.
Try calling SendMessageA instead of SendMessage - that indicates you are using char not WCHAR (i.e. what TCHAR really might have been).
Alternatively, use wide-character versions of std::cout, which is std::wcout and use TCHAR/WCHAR throughout (including textBuffer declaration).
In essence, you're mixing wide strings with old-school strings.
The other answer is correct, but you might want to consider using GetWindowText instead of sending the message.
With GetWindowText, whether you use the -A or -W suffix, you'd get some type safety, which might have helped you avoid this problem in the first place.
In some cases, GetWindowText can return the title even if the process that owns the target window is hung or not responding to messages in a timely fashion.

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 :) )

Get text using SendMessage() 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);

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?.