2

次のコードは一目瞭然だと思います。

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

簡単に説明すると、このプログラムは 2 つの textBox と、最初のテキスト ボックスから 2 番目のテキスト ボックスにコンテンツをコピーするプロセスを起動するボタンを作成します。この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に関するドキュメントを読みましたが、生の入力を最後に配置しないのはなぜなのか、まだ疑問に思っています。

4

2 に答える 2

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申し訳ありませんが、しばらくやっていないこのようなことを扱うときは、記憶から頼るよりもよく知っているはずです。

于 2012-09-21T20:56:35.773 に答える
3
  1. GetWindowTextLengthそこにあるテキストの長さを見つけるために 使用します。
  2. std::vector<TCHAR>その長さに、追加されたテキストの長さと null を加えた 文字の動的配列 ( ) を作成します。
  3. GetWindowTextそこに現在のテキストを保存 するために使用します。
  4. 追加されたテキストを追加します(のようなもので_tcscat)。
  5. SetWindowTextすべてをテキストボックスに入れるために使用します。

要約すれば:

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 との互換性が必要な場合は、 の代わりにmallocandに戻りますが、サイズ変更が行われないことを考えると、それほど余分な作業はありません。freestd::vector

于 2012-09-21T20:13:41.387 に答える