【发布时间】:2013-05-02 01:32:44
【问题描述】:
试图将文本附加到对话框内的编辑控件。我无法让 _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 );
}
【问题讨论】:
-
我一直假设 _tcscat_s 在进行连接时会添加必要的空间。这是错的吗?如果是这样,我是否需要在 GlobalAlloc 期间为 newText 腾出额外的空间?
-
为什么要使用它?要使用相同的算法,只需将文本加载到
std::string,附加到它,然后保存回来。至少在 C++11 中,数据保证是连续的。如果不使用 C++11,std::vector几乎同样可以加载文本。或者(可能更好),使用this technique。没有为它管理内存。不用担心追加。同样易于使用。 -
@ShrimpCrackers:
_tcscat_s()如果附加文本超出缓冲区的范围,则不会增加缓冲区。_tcscat_s()有一个参数来指定缓冲区大小,因此如果它变得太长,它将截断连接的文本。因此,您需要先将缓冲区分配到所需的最终大小,然后再开始将文本放入其中。
标签: c++ c winapi windows-controls