I think the following code should be self-explanatory.
#include <Windows.h>
static HWND textBoxInput;
static HWND button;
static HWND textBoxOutput;
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
int CALLBACK WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR cmdLine,int nCmdShow)
{
HWND hMainWindow;
WNDCLASS wc = {};
wc.lpfnWndProc = WindowProc;
wc.lpszClassName = "Main's window class";
wc.hInstance = hInstance;
RegisterClass(&wc);
hMainWindow = CreateWindow(wc.lpszClassName,"Append text main window",WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,500,400,NULL,NULL,hInstance,NULL);
error=GetLastError();
if(hMainWindow == NULL) return 1;
textBoxInput = CreateWindowEx(WS_EX_CLIENTEDGE, "Edit", NULL,WS_CHILD | WS_VISIBLE | ES_AUTOHSCROLL, 10, 10, 300, 21, hMainWindow, NULL, NULL, NULL);
button = CreateWindowEx(WS_EX_CLIENTEDGE,"Button","Append",WS_CHILD | WS_VISIBLE | ES_CENTER, 10, 41,75,30,hMainWindow,NULL,NULL,NULL);
textBoxOutput = CreateWindowEx(WS_EX_CLIENTEDGE,"Edit",TEXT("->This content is untouchable and unreadable!<-"),WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_AUTOVSCROLL | ES_MULTILINE | ES_READONLY ,10,81,500,90,hMainWindow,NULL,NULL,NULL);
ShowWindow(hMainWindow,SW_SHOW);
MSG msg = { };
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
case WM_COMMAND:
if((HWND)lParam == button)
{
TCHAR* buffer = new TCHAR[150];
GetWindowText(textBoxInput,buffer,150);
SetWindowText(textBoxOutput,buffer);
//AppendWindowText(textBoxOutput,buffer,150) - I haven't found such function;
delete [] buffer;
}
break;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
HBRUSH pedzel;
pedzel = CreateSolidBrush(RGB(10,250,10));
FillRect(hdc, &ps.rcPaint, pedzel);
EndPaint(hwnd, &ps);
return 0;
}
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
In brief: this program creates two textBoxes and a button that launches a process of copying a content from the first to the second. The SetWindowText
function causes cleaning the output box , what obviously isn't desired.
Update after the Jerry Cofinn's answer
SendMessage(textBoxOutput,EM_SETSEL,-1,-1); //no difference between passing 0 or -1
SendMessage(textBoxOutput,EM_REPLACESEL,TRUE,(LPARAM)buffer);
Surprisingly, it prepends the text. I've read the documentation about EM_SETSEL and I'm still wondering why doesn't it place the raw input at the end.
For a text box (edit control) the caret is basically a "selection" that start and end at the same place.
Use SetSel to create a selection that starts and ends after the last character currently in the control, then use ReplaceSel to replace that empty selection with new text.
Since you're using the raw Win32 API,
SetSel
will be...and
ReplaceSel
will be:Oops -- as noted in the postscript to the question, this doesn't work as-is. You need to start with
WM_GETTEXTLENGTH
(orGetWindowTextLength
) to get the length of the text, then set the selection to the end (i.e., the beginning and end both equal to the length you just got), then replace the selection. My apologies -- I should probably know better than to go from memory when dealing with something like this that I haven't done in a while.GetWindowTextLength
to find the length of the text in there.std::vector<TCHAR>
) with that length, plus the length of the appended text, plus the null.GetWindowText
to store the current text in there._tcscat
).SetWindowText
to put everything into the textbox.In summary:
If you aren't using C++11, replace
temp.data()
with&temp[0]
. If it has to be compatible with C, it's back tomalloc
andfree
instead ofstd::vector
, but it's not much extra work considering there's no resizing going on.