Thread: bold static text

  1. #1
    Madly in anger with you
    Join Date
    Nov 2005
    Posts
    211

    bold static text

    I'm just wondering how I would go about changing the font of a static text control on a dialog box at run time. my goal is to be able to make certain text bold while its related action is being performed, and set it back to normal after its action has finished (setting bold focus on the next line of text).

    the problem is is that I really don't have any experience modifying text appearance at all. I have absolutely no idea which API calls I could use for this. I cannot set the static text to bold by default, as that would deplete the purpose, the whole idea is emphasizing which actions are currently being performed by my program. I know it's possible, and probably not that hard, I just don't know where to start.

    any help here would be greatly appreciated. thank you in advance.

    Intel Core 2 Quad Q6600 @ 2.40 GHz
    3072 MB PC2-5300 DDR2
    2 x 320 GB SATA (640 GB)
    NVIDIA GeForce 8400GS 256 MB PCI-E

  2. #2
    Reverse Engineer maxorator's Avatar
    Join Date
    Aug 2005
    Location
    Estonia
    Posts
    2,318
    "The Internet treats censorship as damage and routes around it." - John Gilmore

  3. #3
    Madly in anger with you
    Join Date
    Nov 2005
    Posts
    211
    if possible, I don't want to have to create custom fonts. this will just make the whole process harder and the end result simply won't be the same (graphics aren't my thing). it's a rather simple thing I want to do here, simply bold and unbold text. CreateFont has about 10 parameters for things I've never even heard of before, and after reading its msdn description, it doesn't look like its as easy as passing a parameter to it to retrieve a specific default font set, rather it must be re-created manually. I believe Windows uses the MS Sans Serif font however that is all that I really know, which isn't sufficient for a call to CreateFont to re-create the font.

    Code:
    HFONT CreateFont(
      int nHeight,               // height of font
      int nWidth,                // average character width
      int nEscapement,           // angle of escapement
      int nOrientation,          // base-line orientation angle
      int fnWeight,              // font weight
      DWORD fdwItalic,           // italic attribute option
      DWORD fdwUnderline,        // underline attribute option
      DWORD fdwStrikeOut,        // strikeout attribute option
      DWORD fdwCharSet,          // character set identifier
      DWORD fdwOutputPrecision,  // output precision
      DWORD fdwClipPrecision,    // clipping precision
      DWORD fdwQuality,          // output quality
      DWORD fdwPitchAndFamily,   // pitch and family
      LPCTSTR lpszFace           // typeface name
    );
    specifically these parameters:

    nEscapement
    [in] Specifies the angle, in tenths of degrees, between the escapement vector and the x-axis of the device. The escapement vector is parallel to the base line of a row of text.
    Windows NT/2000/XP: When the graphics mode is set to GM_ADVANCED, you can specify the escapement angle of the string independently of the orientation angle of the string's characters.

    When the graphics mode is set to GM_COMPATIBLE, nEscapement specifies both the escapement and orientation. You should set nEscapement and nOrientation to the same value.

    Windows 95/98/Me: The nEscapement parameter specifies both the escapement and orientation. You should set nEscapement and nOrientation to the same value.


    nOrientation
    [in] Specifies the angle, in tenths of degrees, between each character's base line and the x-axis of the device.
    I have absolutely no idea what any of that means, and these both look like essential parameters (there is no default value I can pass, and it doesn't say anything about passing 0).

    Intel Core 2 Quad Q6600 @ 2.40 GHz
    3072 MB PC2-5300 DDR2
    2 x 320 GB SATA (640 GB)
    NVIDIA GeForce 8400GS 256 MB PCI-E

  4. #4
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    If we start by the "simple case" where you are in "compatible mode", the nEscapement is the angle you want the text to come out at - e.g. :
    Code:
    t e x t  (0)
    
    t
    x
    e
    t (90)
    
    t x e t (180)
    
    t
    e 
    x 
    t  (270)
    This would of coruse be with the actual letters rotated correctly - but I'm not about to draw fonts in ASCII art.

    Try some of it out, if you like...

    In the new variation, I beleive you can rotate the letters (nEscapement) independently from the actual "line the text is drawn on", so for example if you set nEscapement to 90 and nOrientation to zero, the letters will rotate 90 degrees, but they will still come out in a line just like the text here in this post.

    For "normal" text, just use zero for both - it means "don't lean anything".

    --
    Mats

  5. #5
    Madly in anger with you
    Join Date
    Nov 2005
    Posts
    211
    Thanks matsp, I gave it a try, but it didn't seem to do anything.

    Code:
    hFont = CreateFont(0, 0, 0, 0, FW_BOLD, 0, 0, 0, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, "MS Sans Serif");
    SendDlgItemMessage(hwndDlg, IDC_STATIC_PRG, WM_SETFONT, (WPARAM)hFont, (LPARAM)TRUE);
    there could be a number of things wrong, however I can't even be bothered to add error handling to try to see what's up, there's likely more than one problem that I just can't be bothered fixing. It's not that important, and I'm just not interested in learning about this GDI stuff.

    Thanks to all who helped anyways.

    Intel Core 2 Quad Q6600 @ 2.40 GHz
    3072 MB PC2-5300 DDR2
    2 x 320 GB SATA (640 GB)
    NVIDIA GeForce 8400GS 256 MB PCI-E

  6. #6
    Reverse Engineer maxorator's Avatar
    Join Date
    Aug 2005
    Location
    Estonia
    Posts
    2,318
    That's because you created a font with the size 0.

    For example if you want the size in pixels (10 here):
    Code:
    hFont = CreateFont(10, 0, 0, 0, FW_BOLD, 0, 0, 0, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
                       DEFAULT_QUALITY, DEFAULT_PITCH, "MS Sans Serif");
    SendDlgItemMessage(hwndDlg, IDC_STATIC_PRG, WM_SETFONT, (WPARAM)hFont, (LPARAM)TRUE);
    And in points:
    Code:
    hFont = CreateFont(-MulDiv(10, GetDeviceCaps(hDC, LOGPIXELSY), 72), 0, 0, 0, FW_BOLD, 0,
                       0, 0, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, "MS Sans Serif");
    SendDlgItemMessage(hwndDlg, IDC_STATIC_PRG, WM_SETFONT, (WPARAM)hFont, (LPARAM)TRUE);
    "The Internet treats censorship as damage and routes around it." - John Gilmore

  7. #7
    Madly in anger with you
    Join Date
    Nov 2005
    Posts
    211
    thanks again maxorator, but when I said it didn't seem to do anything, I didn't mean that nothing appeared, I mean that it did not seem to affect the original text (IDC_STATIC_PRG) at all.

    just found a nice post on msdn: http://forums.microsoft.com/MSDN/Sho...17970&SiteID=1

    can't believe I missed that before. gonna see what I can do from that now. thanks again all.

    Intel Core 2 Quad Q6600 @ 2.40 GHz
    3072 MB PC2-5300 DDR2
    2 x 320 GB SATA (640 GB)
    NVIDIA GeForce 8400GS 256 MB PCI-E

  8. #8
    Reverse Engineer maxorator's Avatar
    Join Date
    Aug 2005
    Location
    Estonia
    Posts
    2,318
    That does the same thing actually...
    "The Internet treats censorship as damage and routes around it." - John Gilmore

  9. #9
    Madly in anger with you
    Join Date
    Nov 2005
    Posts
    211
    yes, but note the type face name:

    my code:

    hFont = CreateFont(10, 0, 0, 0, FW_BOLD, 0, 0, 0, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
    DEFAULT_QUALITY, DEFAULT_PITCH, "MS Sans Serif");
    his code:

    memcpy(lfFont.lfFaceName, TEXT("Microsoft Sans Serif"), 24);
    the "MS Sans Serif" type face was just an assumption, I could not find any information on default Windows type faces other than something at msdn which mentioned using EnumFontFamilies to retrieve them. I now see that that assumption was incorrect.

    and my interest was mainly in this reply:

    Hi,

    Did you try using WM_GETFONT and then modifying its lfWeight field alone before using WM_SETFONT?

    Thanks
    if that was possible, it would be perfect. as the original poster says, he does not want to modify dimensions or quality, rather just set the font weight to bold. this would also make it easy for me to change the font back to normal, by simply resetting the lfWeight member to FW_DONTCARE and re-painting the control. this way I wouldn't have to worry about re-creating the font every time I need to change it. the problem is that if I send the message WM_GETFONT, I will retrieve an HFONT, which is not a LOGFONT. I don't see any functions capable of making the conversion, I don't even know if it would be possible (I believe HFONT is a void* and LOGFONT is a struct).

    whatever the case, I can't seem to change it, I don't know if it is even possible for text that is statically drawn on the dialog resource prior to run time (the dialog resource itself is probably setting the default font, which might be impossible to override). it might be if I dynamically created the controls with CreateWindowEx, which would be a lot more work to get them properly positioned on the dialog.

    here is the code I have tried, both aren't much different, just different ways of going about it.

    Code:
    hFont = CreateFont(10, 0, 0, 0, FW_BOLD, 0, 0, 0, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, "Microsoft Sans Serif");
    SendDlgItemMessage(hwndDlg, IDC_STATIC_PRG, WM_SETFONT, (WPARAM)hFont, (LPARAM)TRUE);
    Code:
    	ZeroMemory(&logFont, sizeof logFont);
    
    	memcpy(logFont.lfFaceName, TEXT("Microsoft Sans Serif"), 24);
    
    	logFont.lfHeight = 10;
    	logFont.lfWeight = FW_BOLD;
    	logFont.lfCharSet = DEFAULT_CHARSET;
    	logFont.lfOutPrecision = OUT_DEFAULT_PRECIS;
    	logFont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
    	logFont.lfQuality = DEFAULT_QUALITY;
    
    	hFont = CreateFontIndirect(&logFont);
    
    	hwnd = GetDlgItem(hwndDlg, IDC_STATIC_PRG);
    
    	SendMessage(hwnd, WM_SETFONT, (WPARAM)hFont, (LPARAM)TRUE);
    both seem to have the same effect, which is nothing. unfortunately I cannot check the return value of SendDlgItemMessage or SendMessage, as msdn states that nothing will be returned after sending the WM_SETFONT message. my only choice is to dynamically create the controls and try it then, but if it still doesn't work, I will definately give up on it altogether (it will take at least 2 days just to get everything right manually, all for nothing if it still doesn't work).
    Last edited by Bleech; 08-21-2007 at 04:22 PM.

    Intel Core 2 Quad Q6600 @ 2.40 GHz
    3072 MB PC2-5300 DDR2
    2 x 320 GB SATA (640 GB)
    NVIDIA GeForce 8400GS 256 MB PCI-E

  10. #10
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    A LOGFONT can be obtained from an HFONT using GetObject.

    The font should be set in WM_INITDIALOG.

  11. #11
    Madly in anger with you
    Join Date
    Nov 2005
    Posts
    211
    EDIT: thanks alot anonytmouse, I finally got it working.

    it took me a while to notice, but IDC_STATIC_PRG was defined in my resource.h as -1, which was likely causing attempts to retrieve the control's window handle to fail (I discovered GetDlgItem was returning a null value after inserting some debugging statements). after setting the value to a positive, unused number, it works.

    here is the working code.

    Code:
    hwnd = GetDlgItem(hwndDlg, IDC_STATIC_PRG);
    hFont = (HFONT)SendMessage(hwnd, WM_GETFONT, 0, 0);
    
    GetObject(hFont, sizeof logFont, &logFont);
    
    logFont.lfWeight = FW_BOLD;
    
    hFont = CreateFontIndirect(&logFont);
    
    SendMessage(hwnd, WM_SETFONT, (WPARAM)hFont, 0);
    Last edited by Bleech; 08-22-2007 at 06:21 PM.

    Intel Core 2 Quad Q6600 @ 2.40 GHz
    3072 MB PC2-5300 DDR2
    2 x 320 GB SATA (640 GB)
    NVIDIA GeForce 8400GS 256 MB PCI-E

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. uploading file to http server via multipart form data
    By Dynamo in forum C++ Programming
    Replies: 1
    Last Post: 09-03-2008, 04:36 AM
  2. LNK2001 ERROR!!! need help
    By lifeafterdeath in forum C++ Programming
    Replies: 7
    Last Post: 05-27-2008, 05:05 PM
  3. struct question
    By caduardo21 in forum Windows Programming
    Replies: 5
    Last Post: 01-31-2005, 04:49 PM
  4. MFC: Change the color of static text with button press?
    By BrianK in forum Windows Programming
    Replies: 2
    Last Post: 06-16-2004, 11:03 PM
  5. any way to modify static text? lol
    By jverkoey in forum Windows Programming
    Replies: 3
    Last Post: 04-27-2003, 06:34 AM