2012-09-21 61 views
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); 
} 

簡言之:這個程序創建兩個文本框和一個啓動複製從所述第一到所述第二內容的處理的按鈕。 SetWindowText功能導致清潔輸出盒,顯然不是所期望的。傑裏·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,我仍然想知道爲什麼不把原始輸入放在最後。

+0

有關設置和調整選擇的更多信息,則[.NET參考源用於'TextBoxBase.AppendText'](https://referencesource.microsoft.com/#System.Windows.Forms/winforms/Managed/System/的WinForms/TextBoxBase。cs,5194bb23bd26ed3e)可能會有所幫助 – Slai

回答

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

不錯的一個。我從來不知道這一點。 – chris

+0

使用'的wParam = -1'和'的lParam = -1'爲'EM_SETSEL'刪除當前的選擇,但插入符號不會移動到當前文本的結尾。如果脫字號位於文本的中間,那麼您將在中間插入新文本而不是結尾。在發送'EM_REPLACESEL'之前,您必須正確定位插入符號。 –

+1

'EM_REPLACESEL'是在EDIT控件中追加的正確方法。 「EM_SETSEL」的細節可能需要整理,但這是應該被接受的答案。獲取控件以執行附加操作。在應用程序中追加文本並將其全部發送回控件是很浪費的。 –

3
  1. 使用GetWindowTextLength找到那裏的文本的長度。
  2. 創建字符的與長度,再加上附加的文本的長度,加上上具有零點的動態陣列(std::vector<TCHAR>)。
  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[0]更換temp.data()。如果它必須是兼容C,又回到了mallocfree代替std::vector,但它不考慮有沒有調整大小事情很多額外的工作。

+1

因爲您知道兩種長度都是以開頭的方式來確定的,所以確實沒有重新調整它的意義。 – Marlon

+0

@Marlon,好點,我會改變這一點。 – chris

+0

不要使用'char',使用'TCHAR'(或'wchar_t',一旦你意識到你永遠不會再瞄準8位操作系統)。 –

相關問題