如何将文本追加到TextBox?

时间:2012-09-21 20:03:57

标签: c++ c winapi textbox

我认为以下代码应该是不言自明的。

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

简而言之:该程序创建了两个文本框和一个按钮,用于启动将内容从第一个复制到第二个的过程。 SetWindowText功能导致清洁输出框,这显然是不希望的。

在Jerry Cofinn的回答后更新

SendMessage(textBoxOutput,EM_SETSEL,-1,-1); //no difference between passing 0 or -1
SendMessage(textBoxOutput,EM_REPLACESEL,TRUE,(LPARAM)buffer);

令人惊讶的是,预先文本。我已经阅读了关于EM_SETSEL的the documentation,我仍然想知道为什么不将原始输入放在最后。

2 个答案:

答案 0 :(得分:8)

对于文本框(编辑控件),插入符基本上是一个在同一个地方开始和结束的“选择”。

使用SetSel创建一个选择,该选择在控件中当前最后一个字符之后开始和结束,然后使用ReplaceSel将该空选项替换为新文本。

由于您使用的是原始Win32 API,SetSel将是

SendMessage(your_control, EM_SETSEL,-1, -1);

...而ReplaceSel将是:

SendMessage(your_control, EM_REPLACESEL, TRUE, string_to_add);

哎呀 - 正如问题的附言中所述,这不是原样的。您需要从WM_GETTEXTLENGTH(或GetWindowTextLength)开始获取文本的长度,然后将选择设置为结尾(即,开头和结尾都等于您刚刚获得的长度),然后替换选择。我道歉 - 我应该知道,在处理类似我之前没有做过的事情时,要记忆好。

答案 1 :(得分:3)

  1. 使用GetWindowTextLength查找其中的文字长度。
  2. 使用该长度创建一个动态数组字符(std::vector<TCHAR>),加上附加文本的长度加上null。
  3. 使用GetWindowText将当前文本存储在那里。
  4. 添加附加文字(类似_tcscat)。
  5. 使用SetWindowText将所有内容放入文本框中。
  6. 总结:

    int len = GetWindowTextLength(textbox);
    std::vector<TCHAR> temp(len + lengthOfAppendedText + 1);
    
    GetWindowText(textbox, temp.data(), temp.size());
    _tcscat(temp.data(), appendedText);
    SetWindowText(textbox, temp.data());
    

    如果您不使用C ++ 11,请将temp.data()替换为&temp[0]。如果它必须与C兼容,则会返回到mallocfree而不是std::vector,但考虑到没有进行大小调整,这项工作并不多。