Win32 - Appending text to an Edit Control

后端 未结 2 541
盖世英雄少女心
盖世英雄少女心 2021-01-02 10:55

Trying to append text to an edit control inside a dialog box. I can\'t get _tcscat_s to append correctly. It crashes and says something about the buffer being too small or s

相关标签:
2条回答
  • 2021-01-02 11:05

    http://support.microsoft.com/kb/109550

    Is your answer:

       string buffer = "append this!"
       HWND hEdit = GetDlgItem (hDlg, ID_EDIT);
       int index = GetWindowTextLength (hEdit);
       SetFocus (hEdit); // set focus
       SendMessageA(hEdit, EM_SETSEL, (WPARAM)index, (LPARAM)index); // set selection - end of text
       SendMessageA(hEdit, EM_REPLACESEL, 0, (LPARAM)buffer.c_str()); // append!
    
    0 讨论(0)
  • 2021-01-02 11:22

    GetWindowTextLength() returns the number of TCHAR elements in the text, but GlobalAlloc() expects a byte count instead. If you are compiling for Unicode, TCHAR is 2 bytes, not 1 byte, but you are not taking that into account. You are also not allocating the buffer large enough to hold both the existing text and the new text being appended. You are also leaking the memory that you allocate.

    Try this:

    void AppendText( const HWND &hwnd, TCHAR *newText )
    {
        // get edit control from dialog
        HWND hwndOutput = GetDlgItem( hwnd, IDC_OUTPUT );
    
        // get new length to determine buffer size
        int outLength = GetWindowTextLength( hwndOutput ) + lstrlen(newText) + 1;
    
        // create buffer to hold current and new text
        TCHAR * buf = ( TCHAR * ) GlobalAlloc( GPTR, outLength * sizeof(TCHAR) );
        if (!buf) return;
    
        // get existing text from edit control and put into buffer
        GetWindowText( hwndOutput, buf, outLength );
    
        // append the newText to the buffer
        _tcscat_s( buf, outLength, newText );
    
        // Set the text in the edit control
        SetWindowText( hwndOutput, buf );
    
        // free the buffer
        GlobalFree( buf );
    }
    

    Alternatively:

    #include <vector>
    
    void AppendText( const HWND &hwnd, TCHAR *newText )
    {
        // get edit control from dialog
        HWND hwndOutput = GetDlgItem( hwnd, IDC_OUTPUT );
    
        // get new length to determine buffer size
        int outLength = GetWindowTextLength( hwndOutput ) + lstrlen(newText) + 1;
    
        // create buffer to hold current and new text
        std::vector<TCHAR> buf( outLength );
        TCHAR *pbuf = &buf[0];
    
        // get existing text from edit control and put into buffer
        GetWindowText( hwndOutput, pbuf, outLength );
    
        // append the newText to the buffer
        _tcscat_s( pbuf, outLength, newText );
    
        // Set the text in the edit control
        SetWindowText( hwndOutput, pbuf );
    }
    

    With that said, getting the window's current text into memory, appending to it, and then replacing the window's text is a very inefficient way to append text to an edit control. Use the EM_REPLACESEL message instead:

    void AppendText( const HWND &hwnd, TCHAR *newText )
    {
        // get edit control from dialog
        HWND hwndOutput = GetDlgItem( hwnd, IDC_OUTPUT );
    
        // get the current selection
        DWORD StartPos, EndPos;
        SendMessage( hwndOutput, EM_GETSEL, reinterpret_cast<WPARAM>(&StartPos), reinterpret_cast<WPARAM>(&EndPos) );
    
        // move the caret to the end of the text
        int outLength = GetWindowTextLength( hwndOutput );
        SendMessage( hwndOutput, EM_SETSEL, outLength, outLength );
    
        // insert the text at the new caret position
        SendMessage( hwndOutput, EM_REPLACESEL, TRUE, reinterpret_cast<LPARAM>(newText) );
    
        // restore the previous selection
        SendMessage( hwndOutput, EM_SETSEL, StartPos, EndPos );
    }
    
    0 讨论(0)
提交回复
热议问题