C++ : win32 - how select a HFONT?

Jul 16, 2015 at 2:24pm
how can i select a HFONT to a HDC?
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
void Font(CHOOSEFONT chft)
    {
        chFont=chft;
    }

    void DrawText(string strText,int PosX=0, int PosY=0)
    {
        // geting the text rectangle
        RECT r = { 0, 0, 0, 0 };
        char *text=(char*)strText.c_str();
        //change the position of the text
        r.left=PosX;
        r.top=PosY;
        r.bottom=HBitmap.Width() + PosY;
        r.right=HBitmap.Height() + PosX;
        SetBkMode(HBitmap,TRANSPARENT);
        //draw the text

        HBRUSH hBackBrush=imgBrush;
        HBRUSH oldBrush=(HBRUSH)SelectObject(HBitmap,hBackBrush);
        HPEN hBackPen=(HPEN)imgPen;
        HPEN oldPen=(HPEN)SelectObject((HDC)HBitmap,hBackPen);

        HFONT *hFont=(HFONT*)chFont.lpLogFont;
        HFONT holdfont=(HFONT)SelectObject((HDC)HBitmap,*hFont);

        SetTextColor(HBitmap,chFont.rgbColors);

        ::DrawText(HBitmap, text, -1,&r,DT_LEFT);

        SelectObject(HBitmap,holdfont);
        DeleteBrush(*hFont);

        SelectObject(HBitmap,oldBrush);
        DeleteBrush(hBackBrush);
        SelectObject(HBitmap,oldPen);
        DeleteBrush(hBackPen);
    }

the text color is changed, but not font name and size :(
what i'm doing wrong?
(if i was losing data(because i'm not using the 'const'), i losed the color too... i think)
Last edited on Jul 16, 2015 at 2:27pm
Jul 16, 2015 at 2:45pm
The lpLogFont member of the CHOOSEFONT is not a pointer to HFONT. It's a pointer to LOGFONT

Use CreateFontIndirect(...) to get the HFONT. See:

https://msdn.microsoft.com/en-us/library/aa911457.aspx
Jul 16, 2015 at 3:02pm
thanks for that. true. now the font size is changed, but not the font name :(
it's because i use the DrawText() function?
Jul 16, 2015 at 4:33pm
Either CreateFont() or CreateFontIndirect() allow for the setting of all aspects of a font whether it be the name, i.e., L"Courier New", L"Ariel", etc., the font size, weight, or whatever. Any GDI object is selected into a DC through SelectObject().
Jul 16, 2015 at 5:16pm
see the function:

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
void Font(CHOOSEFONT chft)
    {
        chFont=chft;
    }

    void DrawText(string strText,int PosX=0, int PosY=0)
    {
        // geting the text rectangle
        RECT r = { 0, 0, 0, 0 };
        char *text=(char*)strText.c_str();
        //change the position of the text
        r.left=PosX;
        r.top=PosY;
        r.bottom=HBitmap.Width() + PosY;
        r.right=HBitmap.Height() + PosX;
        SetBkMode(HBitmap,TRANSPARENT);
        //draw the text

        HBRUSH hBackBrush=imgBrush;
        HBRUSH oldBrush=(HBRUSH)SelectObject(HBitmap,hBackBrush);
        HPEN hBackPen=(HPEN)imgPen;
        HPEN oldPen=(HPEN)SelectObject((HDC)HBitmap,hBackPen);

        HFONT hFont=CreateFontIndirect(chFont.lpLogFont);
        HFONT holdfont=(HFONT)SelectObject((HDC)HBitmap,hFont);

        SetTextColor(HBitmap,chFont.rgbColors);

        ::DrawText(HBitmap, text, -1,&r,DT_LEFT);

        SelectObject(HBitmap,holdfont);
        DeleteBrush(hFont);

        SelectObject(HBitmap,oldBrush);
        DeleteBrush(hBackBrush);
        SelectObject(HBitmap,oldPen);
        DeleteBrush(hBackPen);
    }

heres the result :(
https://onedrive.live.com/?id=C3EF456E15C8DEB6!1284&cid=C3EF456E15C8DEB6&group=0&parId=C3EF456E15C8DEB6!197&o=OneUp
i don't know why :(
Last edited on Jul 16, 2015 at 5:19pm
Jul 16, 2015 at 7:42pm
Well, HBitmap is not a HBITMAP and certainly not a HDC. It makes no sense to use SelectObject(...) or other DC functions with it.

I bet that imgPen isn't a HPEN either. DeleteBrush with HFONT and HPEN?

Stop using this invalid casts.
Jul 16, 2015 at 7:58pm
seems that i lose from here:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
CHOOSEFONT ShowSelectFont(HWND hwnd=GetForegroundWindow())
{
    CHOOSEFONT cf = {sizeof(CHOOSEFONT)};
    LOGFONT lf;

    cf.Flags = CF_EFFECTS | CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS;
    cf.hwndOwner = hwnd;
    cf.lpLogFont = &lf;
    cf.rgbColors = RGB(0,0,0);
    cf.lpLogFont->lfStrikeOut=FALSE;
    cf.lpLogFont->lfUnderline=FALSE;
    cf.lpLogFont->lfHeight=-MulDiv(12, GetDeviceCaps(GetDC(hwnd), LOGPIXELSY), 72);//change font size
    _tcscpy(cf.lpLogFont->lfFaceName, "Arial" );

    ChooseFont(&cf);
    cf.lpLogFont = &lf;
    return cf
}

the cf.lpLogFont is a pointer. so i lose
Jul 17, 2015 at 6:05am
lf is a local variable that is destroyed when ShowSelectFont(...) ends, hence lpLogFont points to something invalid.
Last edited on Jul 17, 2015 at 10:18am
Jul 17, 2015 at 8:46am
now works:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
CHOOSEFONT ShowSelectFont(HWND hwnd=GetForegroundWindow())
{
    CHOOSEFONT cf = {sizeof(CHOOSEFONT)};
    LOGFONT* lf = new LOGFONT;
    cf.Flags = CF_EFFECTS | CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS;
    cf.hwndOwner = hwnd;
    cf.lpLogFont = lf;
    cf.rgbColors = RGB(0,0,0);
    cf.lpLogFont->lfStrikeOut=FALSE;
    cf.lpLogFont->lfUnderline=FALSE;
    cf.lpLogFont->lfHeight=-MulDiv(12, GetDeviceCaps(GetDC(hwnd), LOGPIXELSY), 72);//change font size
    _tcscpy(cf.lpLogFont->lfFaceName, "Arial" ); //we must include tchar.h
    ChooseFont(&cf);

    HFONT hf = CreateFontIndirect(lf);
    cf.lpLogFont = lf;
    //delete lf; //i can't delete what i'm using it
    return cf;
    delete lf;

}

theres just 1 bad drawed color :(
see the image:
https://onedrive.live.com/?id=C3EF456E15C8DEB6!1285&cid=C3EF456E15C8DEB6&group=0&parId=C3EF456E15C8DEB6!197&o=OneUp
why i get that white color?
Last edited on Jul 17, 2015 at 8:49am
Jul 17, 2015 at 11:20am
You mean that your DrawText(...) wondrously works? What am I supposed to see on that wee image?
Jul 17, 2015 at 11:41am
a white color arrow the letters and isn't a backcolor(SetBKMode is transparent.

let me ask anotherthing out-off-topic: isn't the 1st time that happens and i hate that :(
why the WM_PAINT isn't updated or the control isn't redraw? i dn't understand what is happen on my code, maybe a diferente place, that don''t let the control been update :(
Jul 17, 2015 at 4:54pm
the WM_PAINT was fixed now. i have the old header file ;)
please see these function:
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
void DrawText(string strText,int PosX=0, int PosY=0)
    {
        // geting the text rectangle
        RECT r = { 0, 0, 0, 0 };
        char *text=(char*)strText.c_str();
        //change the position of the text
        ::DrawText(HBitmap, text, -1,&r,DT_LEFT | DT_EXPANDTABS | DT_CALCRECT);
        r.left+=PosX;
        r.top+=PosY;
        r.bottom+= PosX;
        r.right+= PosY;
        SetBkMode(HBitmap,TRANSPARENT);
        //draw the text

        HBRUSH hBackBrush=imgBrush;
        HBRUSH oldBrush=(HBRUSH)SelectObject(HBitmap,hBackBrush);
        HPEN hBackPen=(HPEN)imgPen;
        HPEN oldPen=(HPEN)SelectObject((HDC)HBitmap,hBackPen);

        HFONT hFont=CreateFontIndirect(chFont.lpLogFont);
        HFONT holdfont=(HFONT)SelectObject((HDC)HBitmap,hFont);
        SetTextColor(HBitmap,chFont.rgbColors);

        ::DrawText(HBitmap, text, -1,&r,DT_LEFT | DT_EXPANDTABS);

        SelectObject(HBitmap,holdfont);
        DeleteBrush(hFont);

        SelectObject(HBitmap,oldBrush);
        DeleteBrush(hBackBrush);

        SelectObject(HBitmap,oldPen);
        DeleteBrush(hBackPen);
    }

i belive the white color, from DrawText() is showed because of the 'r'. so maybe i'm wrong on size calculation or control size. please give me more information
Jul 17, 2015 at 8:52pm
the lpLogFont have a member for activate truefont or other for 'clean' the string?
Jul 17, 2015 at 9:27pm
heres the resize control function:
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
void setAutoSize(bool autosize)
    {
        blnAutoSize=autosize;
        if(blnAutoSize==true)
        {
            RECT textrect={0};
            HDC txthdc=GetDC(hwnd);
            
            // set the font to txthdc

            HFONT hFont=CreateFontIndirect(chFont.lpLogFont);
            HFONT holdfont=(HFONT)SelectObject(txthdc,hFont);
            
            //calculate the string size, using the new font
            DrawText (txthdc,strCaption.c_str(),strCaption.size(),&textrect,DT_CALCRECT | DT_LEFT | DT_EXPANDTABS);

            //deletint the objects
            SelectObject(txthdc,holdfont);
            DeleteBrush(hFont);
            ReleaseDC(hwnd,txthdc);
            
            //changing the size between the image size and string size
            if(imgtest.haveimage())
            {
                if((textrect.bottom)<=imgtest.height())
                    intHeight=imgtest.height();
                else
                    intHeight=textrect.bottom;
                if((textrect.right)<=imgtest.width())
                    intWidth=imgtest.width();
                else
                    intWidth=textrect.right;
            }
            else
            {
                intHeight=textrect.bottom;
                intWidth=textrect.right;
            }
            
            //now we can change the control size
            //advice: when change the font or text or image, is the best change the control size            
            SetWindowPos(hwnd, 0, 0, 0,intWidth+2,intHeight+2,
                SWP_NOZORDER|SWP_NOMOVE|SWP_NOACTIVATE);
        }
        
        //now lets redraw the control
        InvalidateRect(hwnd,NULL,FALSE);
    }


resolved: that bad effect have to do with back color or brush color ;)

thanks for all.. realy, thank you
Jul 17, 2015 at 10:01pm
Topic archived. No new replies allowed.