此代码抛出Run-Time Check Failure #2 - Stack around the variable 'WidthC' was corrupted.
此代码绘制按钮。
添加此之后。INT WidthC; GetCharWidth(ControlStyles->hDC, 0, length, &WidthC);
但如果我忽略错误程序有效,并且GetCharWidth()
函数返回字符宽度,但在程序从DrawItem函数退出后发生错误。销毁WidthC变量后发生错误。
if (ControlStyles->CtlID == ID_PREVIEW_BUTTON || ControlStyles->CtlID == ID_PREVIEW_STATIC || ControlStyles->CtlID == ID_PREVIEW_EDIT) {
SetTextColor(ControlStyles->hDC, PreviewTextControlColor);
SetBkMode(ControlStyles->hDC, PreviewControlsBackgroundMode);
if (PreviewControlsBackgroundMode == OPAQUE) {
SetBkColor(ControlStyles->hDC, PreviewTextBackgroundControlColor);
}
FillRect(ControlStyles->hDC, &ControlStyles->rcItem, CreateSolidBrush(PreviewBackgroundControlColor));
WCHAR StaticText[MAX_NAME_STRING] = { 0 };
INT length = GetWindowText(ControlStyles->hwndItem, StaticText, ARRAYSIZE(StaticText));
INT WidthC;
GetCharWidth(ControlStyles->hDC, 0, length, &WidthC);
TextOut(ControlStyles->hDC, ControlStyles->rcItem.right / 2 - ((length - 1) * WidthC) / 2, ControlStyles->rcItem.bottom / 2 - FontSize / 2, StaticText, length);
}
GetCharWidth()
的第四个参数需要一个指向缓冲区的指针,该缓冲区可以容纳您在第二个和第三个参数中指定的字符范围内的任意数量的INT
。由于您要求的是length
个字符的范围,因此需要length
个INT
s的缓冲区。但是,您传递的是单个INT
的地址,因此如果length > 1
为true,您将覆盖周围的内存。
所以,你需要更像这样的东西:
WCHAR StaticText[MAX_NAME_STRING] = { 0 };
INT length = GetWindowText(ControlStyles->hwndItem, StaticText, ARRAYSIZE(StaticText));
if (length) {
INT WidthC[MAX_NAME_STRING] = { 0 };
GetCharWidth(ControlStyles->hDC, 0, length-1, WidthC);
// use WidthC[0]..WidthC[length-1] as needed...
}
或者,也许您打算为单个INT
:执行此操作
WCHAR StaticText[MAX_NAME_STRING] = { 0 };
INT length = GetWindowText(ControlStyles->hwndItem, StaticText, ARRAYSIZE(StaticText));
if (length) {
INT WidthC;
GetCharWidth(ControlStyles->hDC, 0, 0, WidthC);
// use WidthC as needed...
}
也就是说,GetCharWidth()
长期以来一直被弃用,您应该使用GetCharWidth32()
,正如文档所说:
注意此功能仅用于与16位版本的Windows兼容。应用程序应该调用
GetCharWidth32
函数,它可以提供更准确的结果。