DrawText help - Follow-up Question

I'm trying to paint a star from the wingdings character set.
I get nothing on the screen.
SQUARE inherits from RECT.
I've stepped through the code.
I know my coordinates and square size are correct.
hfont gets set.
prev_font is set to zero.
temp has a character in it (in the debugger's character set).
Other aspects of the square paint correctly.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
void SQUARE::Draw_Star(HDC hdc)
{
    int		fmt = DT_CENTER | DT_VCENTER | DT_SINGLELINE;
    HFONT       hfont;
    wchar_t     star = 171;
    LPCSTR      facename = "Wingdings";
    CStringW    temp;           // Using wide characters
    HGDIOBJ     prev_font;
    int         rslt;

    hfont = CreateFontA (
        16,                     //  cHeigth
        16,                     //  cWidth
        0,                      //  cEscapement,
        0,                      //  cOrientation,
        FW_DONTCARE,            //  cWeight,
        0,                      //  bItalic,
        0,                      //  bUnderline,
        0,                      //  bStrikeOut,
        ANSI_CHARSET,           //  iCharSet,
        0,                      //  iOutPrecision,
        0,                      //  iClipPrecision,
        0,                      //  iQuality,
        0,                      //  iPitchAndFamily,
        facename                //  pszFaceName
    );    
    if (hfont == NULL)
        throw EXC_CREATEFONT;
    prev_font = SelectObject(hdc, &hfont);
    temp.AppendChar(star);
    rslt = DrawText(hdc, temp, 1, this, fmt);
    if (rslt == 0)
        throw EXC_DRAWTEXT;
    SelectObject(hdc, prev_font);
    DeleteObject(hfont);
}


Edit: I've also tried TextOutW. Made no difference.
Last edited on
The following should print a red star in the window...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
#include <windows.h>

template <class DERIVED_TYPE>
class BaseWindow
{
public:
    static LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
    {
        DERIVED_TYPE* pThis = NULL;

        if (uMsg == WM_NCCREATE)
        {
            CREATESTRUCT* pCreate = (CREATESTRUCT*)lParam;
            pThis = (DERIVED_TYPE*)pCreate->lpCreateParams;
            SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)pThis);

            pThis->m_hwnd = hwnd;
        }
        else
        {
            pThis = (DERIVED_TYPE*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
        }
        if (pThis)
        {
            return pThis->HandleMessage(uMsg, wParam, lParam);
        }
        else
        {
            return DefWindowProc(hwnd, uMsg, wParam, lParam);
        }
    }

    BaseWindow() : m_hwnd(NULL) { }

    BOOL Create(
        PCWSTR lpWindowName,
        DWORD dwStyle,
        DWORD dwExStyle = 0,
        int x = CW_USEDEFAULT,
        int y = CW_USEDEFAULT,
        int nWidth = CW_USEDEFAULT,
        int nHeight = CW_USEDEFAULT,
        HWND hWndParent = 0,
        HMENU hMenu = 0
    )
    {
        WNDCLASS wc = { 0 };

        wc.lpfnWndProc = DERIVED_TYPE::WindowProc;
        wc.hInstance = GetModuleHandle(NULL);
        wc.lpszClassName = ClassName();

        RegisterClass(&wc);

        m_hwnd = CreateWindowEx(
            dwExStyle, ClassName(), lpWindowName, dwStyle, x, y,
            nWidth, nHeight, hWndParent, hMenu, GetModuleHandle(NULL), this
        );

        return (m_hwnd ? TRUE : FALSE);
    }

    HWND Window() const { return m_hwnd; }

protected:

    virtual PCWSTR  ClassName() const = 0;
    virtual LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) = 0;

    HWND m_hwnd;
};


class MainWindow : public BaseWindow<MainWindow>
{
public:
    PCWSTR  ClassName() const { return L"Sample Window Class"; }
    LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam);
    void Draw_Star(HDC hdc);
};


int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, PWSTR pCmdLine, int nCmdShow)
{
    MainWindow win;

    if (!win.Create(L"Lone Star", WS_OVERLAPPEDWINDOW))
    {
        return 0;
    }

    ShowWindow(win.Window(), nCmdShow);

    // Run the message loop.

    MSG msg = { };
    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return 0;
}


LRESULT MainWindow::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;

    case WM_PAINT:
    {
        PAINTSTRUCT ps;
        HDC hdc = BeginPaint(m_hwnd, &ps);
        FillRect(hdc, &ps.rcPaint, (HBRUSH)(COLOR_WINDOW + 1));
        Draw_Star(hdc);
        EndPaint(m_hwnd, &ps);
    }
    return 0;

    default:
        return DefWindowProc(m_hwnd, uMsg, wParam, lParam);
    }
    return TRUE;
}

void MainWindow::Draw_Star(HDC hdc)
{
    HFONT hFont = CreateFont(48, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_OUTLINE_PRECIS,
        CLIP_DEFAULT_PRECIS, CLEARTYPE_QUALITY, VARIABLE_PITCH, TEXT("Wingdings"));
    HGDIOBJ old_font = SelectObject(hdc, hFont);

    RECT rect;
    SetRect(&rect, 100, 100, 700, 200);
    SetTextColor(hdc, RGB(255, 0, 0));

    wchar_t star = 171;
    DrawText(hdc, &star, 1, &rect, DT_NOCLIP);

    SelectObject(hdc, old_font);
    DeleteObject(hFont);
}
Thanks The Grey Wolf. You convinced me there was nothing wrong with my code. I pasted your code into my program and got the same symptoms. It was then I realized the problem.

I was painting the square to an intermediate buffer, but was writing the text (star) directly to the DC. The star never appeared because the DC with the star was overwritten by painting the square from the intermediate buffer (which did not have the star) to the DC which did have the star.
Follow-up question - After fixing the double buffering problem and using The Grey Wolf's code, I get the star to display in my square. However what is happening is the star is overwriting the background with white around the star. That's not what I was expecting. I was expecting the star to be written over the existing background.

I've checked the arguments to CreateFont and DrawText, but don't see anything that controls the background behind the star. Anyone know how to fix this?

Edit: Solved.
1
2
    SetBkColor(hdc, CR_LIGHT_RED);
    DrawText(hdc, &star, 1, this, DT_NOCLIP);

SetBkColor() fixed the problem. The last color I had used was white which is why the star was painted with a white background.
Last edited on
I think SetBkMode(hdc, TRANSPARENT); might be what you are looking for.

Edit: SetBkColor is also worth looking at.

Edit 2: Browser was slow to get the Solved update...
Last edited on
Registered users can post here. Sign in or register to post.