Win32 — добавление текста в элемент управления редактирования

Попытка добавить текст в элемент управления редактирования в диалоговом окне. Я не могу заставить _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 );
}

8

Решение

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

Другие решения

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!
9

По вопросам рекламы [email protected]