user18175085
user18175085

Reputation:

Run-Time Check Failure #2 - Stack around the variable 'WidthC' was corrupted

This Code Throw Run-Time Check Failure #2 - Stack around the variable 'WidthC' was corrupted. This Code Draws Button.

After Adding This. INT WidthC; GetCharWidth(ControlStyles->hDC, 0, length, &WidthC);

But If I Ignore Error Program works and GetCharWidth() function returns character Width, but after program exit from DrawItem Function Error Occurs. Error Occurs after destroying WidthC variable.


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

Upvotes: 0

Views: 446

Answers (1)

Remy Lebeau
Remy Lebeau

Reputation: 597071

The 4th parameter of GetCharWidth() expects a pointer to a buffer that can hold as many INTs as are in the range of characters you specify in the 2nd and 3rd parameters. Since you are asking for a range of length number of characters, you need a buffer of length number of INTs. But, you are passing in the address of a single INT, so you will overwrite surrounding memory if length > 1 is true.

So, you would need something more like this instead:

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...
}

Or, perhaps you meant to do this instead for a single 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...
}

That being said, GetCharWidth() is long deprecated, you should be using GetCharWidth32() instead, as the documentation says:

Note This function is provided only for compatibility with 16-bit versions of Windows. Applications should call the GetCharWidth32 function, which provides more accurate results.

Upvotes: 1

Related Questions