我有以下代码,可以从指定父窗口的所有子窗口加载文本。它工作正常,但有时,有一些父窗口(如打开的记事本与一个很长的C ++源文件)那些有大量的文本,导致缓冲区溢出。
BOOL CALLBACK EnumChildProc(__in HWND hWnd, __in LPARAM lParam) {
LRESULT TEXT_LENGTH = NULL;
WCHAR szText[32767];
LPWSTR szWindowText;
UINT nBuffer = NULL, nText = NULL;
szWindowText = reinterpret_cast<LPWSTR>(lParam); szText[0] = L'\0';
nBuffer = (UINT)wcslen(szWindowText);
TEXT_LENGTH = SendMessage(hWnd, WM_GETTEXTLENGTH, NULL, NULL);
if (TEXT_LENGTH > NULL)
{
SendMessage(hWnd, WM_GETTEXT, (WPARAM)32767, reinterpret_cast<LPARAM>(&szText));
szText[TEXT_LENGTH] = L'\n'; szText[TEXT_LENGTH + 1] = L'\0';
while ((nBuffer < 32766) && (szText[nText] != L'\0'))
{ szWindowText[nBuffer++] = szText[nText++]; }
szWindowText[nBuffer] = L'\0';
}
return TRUE;
}
行SendMessage(hWnd, WM_GETTEXT, (WPARAM)32767, reinterpret_cast<LPARAM>(&szText));
有时会导致缓冲区溢出,我的应用程序崩溃。
我知道如何像if (TEXT_LENGTH > 32767)
那样检测此溢出,但我无法动态增加缓冲区szText
的大小。
正如问题标题所提到的,我不想增加它的大小,我只想截断并将null终止返回文本到最大缓冲区大小32767
(如果TEXT_LENGTH
超过{{ 1}})并将其分配给32767
以用于其他目的。
非常感谢任何帮助。
答案 0 :(得分:1)
基本上你需要为\n
腾出空间,为什么你要插入它,而这样做的方法是在sizeof szText-1
调用中使用WM_GETTEXT
而不是32767。
注意如果您必须使用Simonyi表示法,请不要在不适用的地方使用它。 szText
没有空格终止,您仅用于WM_GETTEXT
的结果。
答案 1 :(得分:0)
一些事情:
DWORD l = SendMessage(hWnd, WM_GETTEXTLENGTH, NULL, NULL);
if (l > 0){
TCHAR *szText = new TCHAR[l + 1];
SendMessage(hWnd, WM_GETTEXT, (WPARAM)l + 1, reinterpret_cast<LPARAM>(szText));
// use szText
delete[] szText;
}
答案 2 :(得分:0)
SendMessage(hWnd, WM_GETTEXT, (WPARAM)32767, reinterpret_cast<LPARAM>(&szText));
永远不会导致缓冲区溢出,因为提供了正确的缓冲区大小。实际上根本不需要这个临时缓冲区。
您真正的问题是您在不知道目标缓冲区大小的情况下将字符附加到以lParam
提供的指针中。您应该在供应目的地缓冲区大小。