C++ - win32: how can i get the LOGFONT from HDC?

how can i get the LOGFONT from HDC?
sorry.. the GetObject() don't use the HDC. i belive it's a diferent thing.
i'm trying these(from window):
1
2
LOGFONT* lf = new LOGFONT;
    lf =(LOGFONT) SendMessage(hwnd,WM_GETFONT,0,0);

but i'm getting several errors:

"error: no matching function for call to 'tagLOGFONTA::tagLOGFONTA(LRESULT)'"
i never used SendMessage() for change\get window properties
The WM_GETFONT returns the HFONT which can be used as the parameter for GetObject(...).


To obtain the HFONT from HDC you need GetCurrentObject(...):

https://msdn.microsoft.com/en-us/library/dd144869%28v=vs.85%29.aspx
and now how can i convert from HFONT to LOGFONT?
and now how can i convert from HFONT to LOGFONT?

That's where GetObject comes in. (As Coder777 already mentioned!)

Andy

PS Strictly speaking, you're not converting from HFONT to LOGFONT -- you're saying fill in this LOGFONT structure with the info on the font this handle refers to...
Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
CHOOSEFONT ShowSelectFont()
{
    HWND hwnd=GetForegroundWindow();
    CHOOSEFONT cf = {sizeof(CHOOSEFONT)};
    LOGFONT* lf = new LOGFONT;
    HDC hdc=GetDC(hwnd);

    HFONT hlf =(HFONT) GetCurrentObject(hdc,OBJ_FONT);

    GetObject(hlf,sizeof(LOGFONT),lf);
    cf.Flags = CF_EFFECTS | CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS;
    cf.hwndOwner = hwnd;
    cf.lpLogFont = lf;
    cf.rgbColors =GetTextColor(hdc);
    ChooseFont(&cf);
    ReleaseDC(hwnd,hdc);
    cf.lpLogFont = lf;
    return cf;
}


now i'm doing another with a little diference:


1
2
3
4
5
6
7
8
9
10
11
CHOOSEFONT ShowSelectFont(const CHOOSEFONT cf1)
{
    CHOOSEFONT cf = {sizeof(CHOOSEFONT)};
    cf=cf1;
    HWND hwnd=GetForegroundWindow();

    cf.Flags = CF_EFFECTS | CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS;
    cf.hwndOwner = hwnd;
    ChooseFont(&cf);
    return cf;
}


on label class
1
2
3
4
5
6
7
8
9
10
11
12
13
14
CHOOSEFONT getFont()
    {
        return chFont;
    }

    void setFont(const CHOOSEFONT font)
    {
        chFont=font;
        clrTextColor=chFont.rgbColors;
        HFONT hFont=CreateFontIndirect(chFont.lpLogFont);
        SendMessage(hwnd, WM_SETFONT,(WPARAM) hFont, TRUE);//setting the control font for resize the control
        if(blnAutoSize==true)//the autosize is true
            setAutoSize(true);
    }


using a button
1
2
3
4
5
 btnFont.MouseClick=[]()//mouse click message
    {
        testw=ShowSelectFont(lbltest.getFont());
        lbltest.setFont(testw);
    };


i don't get any error message, but the font dialog isn't showed. what i'm doing wrong?
Last edited on
I assume ChooseFont() is being called...

1. what is it returning?
2. if it is returning FALSE, call CommDlgExtendedError for further info'

https://msdn.microsoft.com/en-us/library/windows/desktop/ms646914%28v=vs.85%29.aspx

The way you are setting the lStructSize member of your CHOOSEFONT instance 'cf' in ShowSelectFont() looks fragile (you set it and then overwrite it with the value passed in.)

Andy
Last edited on
i miss the variable data.. how can i get 1 data struture, if the struture was not inicializated :P
sorry about that
thanks to all
Last edited on
i continue confused with 1 thing: by rule, when we use the new, we must use the delete when isn't needed.
see these function:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
CHOOSEFONT ShowSelectFont()
{
    HWND hwnd=GetForegroundWindow();
    CHOOSEFONT cf = {sizeof(CHOOSEFONT)};
    LOGFONT* lf = new LOGFONT;
    HDC hdc=GetDC(hwnd);

    HFONT hlf =(HFONT) GetCurrentObject(hdc,OBJ_FONT);

    GetObject(hlf,sizeof(LOGFONT),lf);
    cf.Flags = CF_EFFECTS | CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS;
    cf.hwndOwner = hwnd;
    cf.lpLogFont = lf;
    cf.rgbColors =GetTextColor(hdc);
    ChooseFont(&cf);
    ReleaseDC(hwnd,hdc);
    cf.lpLogFont = lf;
    return cf;
}

if i delete the lf, i lose data... so can anyone explain to me?
(in these case i don't have errors... is just a question)
When you loose the data then you still need it and hence cannot delete it.

But there is an alternative to new: Pass by reference.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
CHOOSEFONT ShowSelectFont(LOGFONT &lf)
{
    HWND hwnd=GetForegroundWindow();
    CHOOSEFONT cf;
    memset(&cf, 0, sizeof(CHOOSEFONT)); // Note: setting all member to 0 prevents from uwanted data
    cf.lStructSize = sizeof(CHOOSEFONT);

    HDC hdc=GetDC(hwnd);

    HFONT hlf =(HFONT) GetCurrentObject(hdc,OBJ_FONT);

    GetObject(hlf,sizeof(LOGFONT),&lf);
    cf.Flags = CF_EFFECTS | CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS;
    cf.hwndOwner = hwnd;
    cf.lpLogFont = &lf;
    cf.rgbColors =GetTextColor(hdc);
    ChooseFont(&cf);
    ReleaseDC(hwnd,hdc);
    cf.lpLogFont = lf;
    return cf;
}
You still need to take care that the LOGFONT exist as long as the CHOOSEFONT exists, but you don't need to delete it.
Last edited on
thanks for all.
please try to explain to me 1 thing: depending on textcolor and the font name, why i see a white color arround the letters?
I don't know what you mean. Maybe the background mode is opaque? Change it with SetBkMode(...):

https://msdn.microsoft.com/en-us/library/windows/desktop/dd162965%28v=vs.85%29.aspx
like you see it's transparent:
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
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();
        

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

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

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

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

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

        SelectObject(HBitmap,oldPen);
        DeleteBrush(hBackPen);
    }
some fonts have holes on letters: see Algerian font arround the 'o', for exemple, i can see a white circule.. i want avoid that color.. be more 'clean'
isn't the best, but finally i fix it:
1
2
3
4
5
6
7
8
9
10
11
if(inst->blnTransparent==true)
                {
                    if(inst->clrTextColor!=RGB(0,0,0)) //if the text color is black?
                        imgLabel.Brush(RGB(0,0,0)); //if not black, the brush will be black
                    else
                        imgLabel.Brush(RGB(1,1,1));//if is black, give a diferent black
                }
                else
                {
                    imgLabel.Brush(inst->clrBackColor);
                }

is better seen a black color instead white :P
these problem don't make sence to me
Topic archived. No new replies allowed.