本文介绍了Win32的 - 追加文本的编辑控件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

试图将文本追加到一个对话框内的编辑控件。我不能让_tcscat_s正确追加。它崩溃并说一些关于缓冲区约为一个空结尾的字符串太小或什么的。

  INT WINAPI的WinMain(HINSTANCE的hInstance,HINSTANCE ^ h prevInstance,LPSTR lpCmdLine,诠释的nCmdShow)
{
    返回DialogBox的(的hInstance,MAKEINTRESOURCE(IDD_MAIN),NULL,DLGPROC);
}BOOL回调DLGPROC(HWND HWND,UINT的消息,WPARAM wParam参数,LPARAM lParam的)
{
    开关(消息)
    {
        案例WM_INITDIALOG:
            OpenAndReadFile(HWND);
            返回TRUE;
        案例WM_COMMAND:
            开关(LOWORD(wParam参数))
            {
                案例IDSTART:
                    的EndDialog(HWND,IDSTART);
                    打破;
                案例IDQUIT:
                    的EndDialog(HWND,IDQUIT);
                    打破;
            }
            打破;
        情况下WM_CLOSE:
            的EndDialog(HWND,0);
            打破;
        默认:
            返回FALSE;
    }
    返回TRUE;
}BOOL OpenAndReadFile(常量HWND&安培; HWND)
{
    //打开文件    HANDLE HFILE;
    HFILE =的CreateFile(TEXT(sites.txt)//文件打开
                        GENERIC_READ,//打开阅读
                        FILE_SHARE_READ,//份额阅读
                        NULL,//默认安全
                        只有OPEN_EXISTING,//现有的文件
                        FILE_ATTRIBUTE_NORMAL,//正常的文件
                        空值 ); //没有ATTR。模板    如果(HFILE == INVALID_HANDLE_VALUE)
    {
        SetDlgItemText(HWND,IDC_OUTPUT,TEXT(错误:文件无法打开\\ r \\ n));
        返回FALSE;
    }
    其他
        SetDlgItemText(HWND,IDC_OUTPUT,TEXT(sites.txt打开\\ r \\ n));    AppendText通过(HWND,TEXT(TEXT));    //从文件中读取数据    常量DWORD BUFFERSIZE = GetFileSize(HFILE,NULL);
    字符* ReadBuffer =新的char [BUFFERSIZE]();
    DWORD dwBytesRead = 0;    //读取一个字符比缓冲区大小要少节省空间的
    //终止NULL字符。
    //如果(FALSE == ReadFile的(HFILE,ReadBuffer,BUFFERSIZE - 1,&安培; dwBytesRead,NULL))
    {    }    返回TRUE;
}无效AppendText通过(常量HWND&放大器; HWND,TCHAR * newText)
{
    //取得大小来确定缓冲区大小
    INT outLength = GetWindowTextLength(函数GetDlgItem(HWND,IDC_OUTPUT));    //创建缓冲区持有编辑控件当前文本
    TCHAR * BUF =(TCHAR *)的GlobalAlloc(GPTR,outLength + 1);    //获得编辑控件现有的文本并投入缓冲
    GetDlgItemText(HWND,IDC_OUTPUT,BUF,outLength + 1);    //使用newText追加到缓冲区
    _tcscat_s(BUF,outLength + 1,newText);    //设置对话框中的文本
    SetDlgItemText(HWND,IDC_OUTPUT,BUF);
}


解决方案

GetWindowTextLength()返回 TCHAR数中的文本,但的GlobalAlloc()元素需要一个字节数来代替。如果要编译为统一code, TCHAR 为2个字节,而不是1个字节,但你没有考虑到这一点。您还没有分配缓冲区足够大,可以同时容纳现有的文本和新文本被追加。您还漏水,你分配内存。

试试这个:

 无效AppendText通过(常量HWND&放大器; HWND,TCHAR * newText)
{
    //从对话框编辑控件
    HWND hwndOutput =函数GetDlgItem(HWND,IDC_OUTPUT);    //获取新的长度来确定缓冲区大小
    INT outLength = GetWindowTextLength(hwndOutput)+ lstrlen(newText)+ 1;    //创建缓冲区来保存现有的和新的文本
    TCHAR * BUF =(TCHAR *)的GlobalAlloc(GPTR,outLength *的sizeof(TCHAR));
    如果回报(BUF!);    //获得编辑控件现有的文本并投入缓冲
    GetWindowText函数(hwndOutput,BUF,outLength);    //使用newText追加到缓冲区
    _tcscat_s(BUF,outLength,newText);    //设置编辑控件中的文本
    SetWindowText函数(hwndOutput,BUF);    //释放缓冲区
    GlobalFree(BUF);
}

或者

 的#include<矢量>无效AppendText通过(常量HWND&放大器; HWND,TCHAR * newText)
{
    //从对话框编辑控件
    HWND hwndOutput =函数GetDlgItem(HWND,IDC_OUTPUT);    //获取新的长度来确定缓冲区大小
    INT outLength = GetWindowTextLength(hwndOutput)+ lstrlen(newText)+ 1;    //创建缓冲区来保存现有的和新的文本
    的std ::矢量<&TCHAR GT; BUF(outLength);
    TCHAR * PBUF =安培; BUF [0];    //获得编辑控件现有的文本并投入缓冲
    GetWindowText函数(hwndOutput,PBUF,outLength);    //使用newText追加到缓冲区
    _tcscat_s(PBUF,outLength,newText);    //设置编辑控件中的文本
    SetWindowText函数(hwndOutput,PBUF);
}

随着中说,让窗口的当前文本到内存中,追加到它,然后替换窗口的文本是将文本追加到一个编辑控件非常低效的方式。使用 EM_REPLACESEL 消息,而不是:

 无效AppendText通过(常量HWND&放大器; HWND,TCHAR * newText)
{
    //从对话框编辑控件
    HWND hwndOutput =函数GetDlgItem(HWND,IDC_OUTPUT);    //获取当前的选择
    DWORD StartPos,EndPos;
    SendMessage函数(hwndOutput,EM_GETSEL,reinter pret_cast<&WPARAM GT;(安培; StartPos),reinter pret_cast<&WPARAM GT;(安培; EndPos));    //插入符移到文本的末尾
    INT outLength = GetWindowTextLength(hwndOutput);
    SendMessage函数(hwndOutput,EM_SETSEL,outLength,outLength);    //插入文本在新的插入位置
    SendMessage函数(hwndOutput,EM_REPLACESEL,TRUE,reinter pret_cast< LPARAM>(newText));    //恢复previous选择
    SendMessage函数(hwndOutput,EM_SETSEL,StartPos,EndPos);
}

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.

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 );
}
解决方案

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

这篇关于Win32的 - 追加文本的编辑控件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-05 00:16