VS Dialog font and dying my hair, maybe


Preparations

I’m in the mode where everything needs to get done before I can leave.  Don’t
you hate that mode?!  It’s like going on a long vacation.  You get extra
productive making sure everything is OK before you leave.  If only I could work
this way everyday!

Giving Campaign

Well, my Product Unit (Visual Studio Core) may just win for the Giving Campaign Challenge. 
Remember, if 80% participate in this year’s campaign, I said I’d dye my hair. 
The deadline was extended and it’s looking grim for my dark brown hair.  As of
today they’ve reached 59%.  At this pace, they’ll win for sure.  I’ll keep
you posted here.

VS dialog font from managed code

An internal MS integrator posted this question:

  • I
    have a managed package, where I’d like to reflect the font selected in the shell for
    Toolwindows and Dialogs into my package’s toolwindows. 
    Using
    the interop assemblies for the Shell, there is a QueryService to get an IUIHostLocale,
    which then has a GetDialogFont method.  My question is how do I transform the
    resulting UIDLGLOGFONT into a managed System::Drawing::Font object.  The static
    System::Drawing::Font::FromLogFont throws an invalid arg exception if I try to use
    it.  Anyone got any advice?

Here’s how to do this using the VSIP SDK from Everett Extras:

Use
the LOGFONT struct out of the NativeMethods namespace in the VSIP Helper classes, filling
in that struct with the info you get from the IUIHostLocale::GetDialogFont method. 
Then use the .NET Framework’s Font.FromLogFont method to create a Font object for your use.

Here’s
some code (I’ve not compiled, but it is close to what is expected to work):

                             
IUIHostLocale locale = (IUIHostLocale) GetService(typeof(IUIHostLocale));
                             
if (locale != null) {
                                  
UIDLGLOGFONT[] fArray = new UIDLGLOGFONT[1];
                                   
locale.GetDialogFont(fArray);
                                   
UIDLGLOGFONT font = fArray[0];



                                   
// Convert the face name from ushort[32] to string
                                   
StringBuilder sb = new StringBuilder();
                                   
int ch = 0;
                                   
while (ch < 32) {
                                       
ushort charVal = font.lfFaceName[ch];
                                       
if (charVal == 0) {
                                           
break;
                                       
}
                                       
sb.Append((char)charVal);
                                       
ch++;
                                   
}
                                   
if (sb.Length == 0) {
                                       
Debug.Fail(“Unable to get face name of VS dialog font.”);
                                   
}



                                   
// Copy one LOGFONT to the other…
                                   
NativeMethods.LOGFONT lfAuto = new NativeMethods.LOGFONT();
                                   
lfAuto.lfHeight = font.lfHeight;
                                   
lfAuto.lfWidth = font.lfWidth;
                                   
lfAuto.lfEscapement = font.lfEscapement;
                                   
lfAuto.lfOrientation = font.lfOrientation;
                                   
lfAuto.lfWeight = font.lfWeight;
                                   
lfAuto.lfItalic = font.lfItalic;
                                   
lfAuto.lfUnderline = font.lfUnderline;
                                   
lfAuto.lfStrikeOut = font.lfStrikeOut;
                                   
lfAuto.lfCharSet = font.lfCharSet;
                                   
lfAuto.lfOutPrecision = font.lfOutPrecision;
                                   
lfAuto.lfClipPrecision = font.lfClipPrecision;
                                   
lfAuto.lfQuality = font.lfQuality;
                                   
lfAuto.lfPitchAndFamily = font.lfPitchAndFamily;
                                   
lfAuto.lfFaceName = sb.ToString();



                                   
try {
                                        object
dialogFont = Font.FromLogFont(lfAuto);
                                   
}
                                   
catch (ArgumentException) {
                                   
}