C++ Win32 - 将文本附加到编辑控件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16329007/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 20:16:07  来源:igfitidea点击:

Win32 - Appending text to an Edit Control

c++cwinapiwindows-controls

提问by ShrimpCrackers

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 something about a null terminated string.

尝试将文本附加到对话框内的编辑控件。我无法让 _tcscat_s 正确附加。它崩溃并说明缓冲区太小或空终止字符串。

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
    return DialogBox( hInstance, MAKEINTRESOURCE( IDD_MAIN ), NULL, DlgProc );
}

BOOL CALLBACK DlgProc( HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam ) 
{
    switch( Message )
    {
        case WM_INITDIALOG:
            OpenAndReadFile( hwnd );
            return TRUE;
        case WM_COMMAND:
            switch( LOWORD( wParam ) )
            {
                case IDSTART:
                    EndDialog( hwnd, IDSTART );
                    break;
                case IDQUIT:
                    EndDialog( hwnd, IDQUIT );
                    break;
            }
            break;
        case WM_CLOSE:
            EndDialog( hwnd, 0 );
            break;
        default:
            return FALSE;
    }
    return TRUE;
}

BOOL OpenAndReadFile( const HWND &hwnd ) 
{   
    // Open the file

    HANDLE hFile;
    hFile = CreateFile( TEXT( "sites.txt" ),    // file to open
                        GENERIC_READ,           // open for reading
                        FILE_SHARE_READ,        // share for reading
                        NULL,                   // default security
                        OPEN_EXISTING,          // existing file only
                        FILE_ATTRIBUTE_NORMAL,  // normal file
                        NULL );                 // no attr. template

    if ( hFile == INVALID_HANDLE_VALUE )
    {
        SetDlgItemText( hwnd, IDC_OUTPUT, TEXT( "Error: File could not be opened\r\n" ) );
        return FALSE;
    }
    else
        SetDlgItemText( hwnd, IDC_OUTPUT, TEXT( "sites.txt opened\r\n" ) );

    AppendText( hwnd, TEXT("TEXT") );

    // Read data from file

    const DWORD BUFFERSIZE = GetFileSize( hFile, NULL );
    char *ReadBuffer = new char [BUFFERSIZE]();
    DWORD dwBytesRead = 0;

    // read one character less than the buffer size to save room for the
    // terminate NULL character.
    //if ( FALSE == ReadFile( hFile, ReadBuffer, BUFFERSIZE - 1, &dwBytesRead, NULL ) )
    {

    }

    return TRUE;
}

void AppendText( const HWND &hwnd, TCHAR *newText )
{
    // get size to determine buffer size
    int outLength = GetWindowTextLength( GetDlgItem( hwnd, IDC_OUTPUT ) );

    // create buffer to hold current text in edit control
    TCHAR * buf = ( TCHAR * ) GlobalAlloc( GPTR, outLength + 1 );

    // get existing text from edit control and put into buffer
    GetDlgItemText( hwnd, IDC_OUTPUT, buf, outLength + 1 );

    // append the newText to the buffer
    _tcscat_s( buf, outLength + 1, newText );

    // Set the text in the dialog
    SetDlgItemText( hwnd, IDC_OUTPUT, buf );
}

回答by Remy Lebeau

GetWindowTextLength()returns the number of TCHARelements in the text, but GlobalAlloc()expects a byte count instead. If you are compiling for Unicode, TCHARis 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.

GetWindowTextLength()返回TCHAR文本中的元素数,但GlobalAlloc()需要字节数。如果您正在为 Unicode 编译,TCHAR则是 2 个字节,而不是 1 个字节,但您没有考虑到这一点。您也没有分配足够大的缓冲区来容纳现有文本和附加的新文本。您也正在泄漏您分配的内存。

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_REPLACESELmessage instead:

话虽如此,将窗口的当前文本放入内存,附加到它,然后替换窗口的文本是将文本附加到编辑控件的一种非常低效的方式。改用EM_REPLACESEL消息:

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

回答by fider

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

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!