How to print many format strings into window? - c++

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.

Related

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 insert text to rich edit control in Win32 while preserving any previous formatting

I'm developing chat application in win32. Currently i'm dynamically allocating memory for rich edit controls text, append new line and set the new text with SetWindowText.
When a message arrives with specific keywords the app colors the line and appends it to the chat window. Everything's fine. Problem arises when next message is received - any previous formatting is lost!
How to solve this issue?
Ok, I've solved it. Apearantly I was replacing the text with unformated version of it. Here's how to properly append text to rich edit control:
CHARRANGE cr;
cr.cpMin = -1;
cr.cpMax = -1;
// hwnd = rich edit hwnd
SendMessage(hwnd, EM_EXSETSEL, 0, (LPARAM)&cr);
SendMessage(hwnd, EM_REPLACESEL, 0, (LPARAM)stringtoappend);

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

CEdit control maximum length? (in characters it can display)

What is the maximum length for the text string contained in a CEdit control in MFC? I get a beep when trying to add a character after the character 30001 is this documented anywhere? Can I display longer texts in a CEdit? Should I use another control?
As "Windows programmer" says down below, the text length limit is not the same when the user types as when we programatically set the text using SetWindowText. The limit for setting a text programatically is not mentioned anywhere. The default text lentgth limit for the user typing is wrong. (see my own post below).
I'm guessing that after I call pEdit->SetLimitText(0) the limit for both programatically and user input text length is 7FFFFFFE bytes. Am I right?
In vista, when pasting text longer than 40000 characters into a CEdit, it becomes unresponsive. It does not matter if I called SetLimitText(100000) previously.
I found the documentation is wrong when mentioning the default size for a single line CEdit control in vista.
I ran this code:
CWnd* pWnd = dlg.GetDlgItem(nItemId);
CEdit *edit = static_cast<CEdit*>(pWnd); //dynamic_cast does not work
if(edit != 0)
{
UINT limit = edit->GetLimitText(); //The current text limit, in bytes, for this CEdit object.
//value returned: 30000 (0x7530)
edit->SetLimitText(0);
limit = edit->GetLimitText();
//value returned: 2147483646 (0x7FFFFFFE)
}
the documentation states:
Before EM_SETLIMITTEXT is called, the
default limit for the amount of text a
user can enter in an edit control is
32,767 characters.
which is apparently wrong.
You can find out what the maximum is for your control by calling CEdit::GetLimitText() on your control. This returns the maximum size for character data in bytes. You can change the maximum size using the CEdit::SetLimitText() function.
The SetLimitText() function is equivalent to sending an EM_SETLIMITTEXT message. The documentation for that message gives the maximum sizes that can be used, but since these are MSDN links that will probably be broken by tomorrow, I'll copy the relevant information :)
The UINT parameter is interpreted as:
The maximum number of TCHARs the user
can enter. For ANSI text, this is the
number of bytes; for Unicode text,
this is the number of characters. This
number does not include the
terminating null character. Rich edit
controls: If this parameter is zero,
the text length is set to 64,000
characters.
Edit controls on Windows NT/2000/XP:
If this parameter is zero, the text
length is set to 0x7FFFFFFE characters
for single-line edit controls or –1
for multiline edit controls.
Edit controls on Windows 95/98/Me: If
this parameter is zero, the text
length is set to 0x7FFE characters for
single-line edit controls or 0xFFFF
for multiline edit controls.
Also, from the Remarks section:
Before EM_SETLIMITTEXT is called, the
default limit for the amount of text a
user can enter in an edit control is
32,767 characters.
Edit controls on Windows NT/2000/XP:
For single-line edit controls, the
text limit is either 0x7FFFFFFE bytes
or the value of the wParam parameter,
whichever is smaller. For multiline
edit controls, this value is either –1
bytes or the value of the wParam
parameter, whichever is smaller.
Edit controls on Windows 95/98/Me: For
single-line edit controls, the text
limit is either 0x7FFE bytes or the
value of the wParam parameter,
whichever is smaller. For multiline
edit controls, this value is either
0xFFFF bytes or the value of the
wParam parameter, whichever is
smaller.
I assume they meant 0xFFFFFFFF instead of -1 in the second paragraph there...
"(in characters it can display)" != "when trying to add a character".
"when trying to add a character" == "The maximum number of TCHARs the user can enter"
unless you mean programmatically trying to add a character.
"0x7FFFFFFE characters" != "0x7FFFFFFE bytes"
except sometimes, a fact which the quoted MSDN text understands sometimes.
I'll bet no one knows the answer to the original question. But "0x7FFFFFFE bytes" is likely one of many limits.