Win32 -附加文本到编辑控件

Win32 - Appending text to an Edit Control

本文关键字:编辑 控件 文本 Win32      更新时间:2023-10-16

尝试将文本追加到对话框中的编辑控件。我不能让_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 openedrn" ) );
        return FALSE;
    }
    else
        SetDlgItemText( hwnd, IDC_OUTPUT, TEXT( "sites.txt openedrn" ) );
    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 );
}

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

试试这个:

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

另外:

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

话虽如此,获取窗口的当前文本到内存中,附加到它,然后替换窗口的文本是一个非常低效的方式来附加文本到编辑控件。使用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 );
}

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

是你的答案吗?

   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!