-1

I published a C# winforms GUI and everything looks as expected on my machine. I went to install on another machine and all my text gets italicized.

Both machines are running windows 10 and have the same screen resolution settings. I also installed my GUI on a third machine and everything works as expected on it.

Is there some setting in Visual Studio I have to set for the fonts to look the same on all machines? Or is there a specific code I need to add?

Here is a snippet of what the GUI should look like (no italics)

GUI on machine #2 (font gets italicized)

timmebee
  • 89
  • 1
  • 2
  • 12
  • Offtopic, but still. You are clearly trying to make some design moves, as far as I can see. So why not use WPF? The winforms is so outdated now, afaik. – AgentFire Jul 11 '19 at 22:35
  • Btw...I am using Century Gothic font. Nothing crazy..so I don't need to install new fonts on every machine. – timmebee Jul 11 '19 at 22:37
  • @AgentFire The GUI was built in WinForms, don't want to re-write the whole thing in WPF... – timmebee Jul 11 '19 at 22:38
  • What happens if you use a standard Font, as `Segoe UI`? – Jimi Jul 11 '19 at 22:41
  • open up the Font Settings and see if you can find the non italic version on that buggy computer – AgentFire Jul 11 '19 at 22:41
  • @Jimi Just tried that font and Times New Roman. They don't get italicized on machine #2. But I was kinda hoping to have my current font display correctly, if possible because those other fonts are too outdated. – timmebee Jul 11 '19 at 23:01
  • @AgentFire What do you mean open up the font settings? The gui is published and installed as a standalone .exe on the machines. – timmebee Jul 11 '19 at 23:02
  • CenturyGothic is more outdated (than Segoe UI) :) Take the Font with your application. You can embed a Font as a Resource: [PrivateFontCollection](https://learn.microsoft.com/en-us/dotnet/api/system.drawing.text.privatefontcollection), [How to: Create a Private Font Collection](https://learn.microsoft.com/en-us/dotnet/framework/winforms/advanced/how-to-create-a-private-font-collection) – Jimi Jul 11 '19 at 23:10
  • CenturyGothic can only work with Latin, Greek and Cyrillic. If the local culture doesn't use any of these scripts, you'll get a surrogate. A User may also have another mapping (sometimes, a software does that). – Jimi Jul 11 '19 at 23:15
  • @timmebee Font Settings, man. https://snag.gy/xLB02G.jpg – AgentFire Jul 12 '19 at 10:18
  • @AgentFire Ahh! Yes that was the issue...for some reason the CenturyGothic Regular was not installed on that machine. Installed it and now the text looks like it should. However, I'm going to try to use the PrivateFontCollection that jimi suggested because I don't want to be verifying every machine has the font...I'll update once I get the code figured out. Thanks all! – timmebee Jul 12 '19 at 15:52

2 Answers2

0

Ok so that you could close the question:

Check the Font Settings and ensure the font you want is installed.

There.

AgentFire
  • 8,944
  • 8
  • 43
  • 90
0

Ok so after a ton of SO and Google based on the comments received earlier, I was able to embed the font into my code. Now, on startup, my app checks if the font is installed on the machine. If font is not installed, my app installs it.

This way eliminates having to manually check if the font is installed on each machine that the app will be run on.

Note: need admin privileges for this to work.

First: Embed the font file as a resource

  1. Double-click Resources.resx, and in the toolbar for the designer click Add Resource/Add Existing File and select your .ttf file
  2. In the solution explorer, right-click your .ttf file and go to Properties. Set the 'Build Action' to "Content" and 'Copy To Output Directory' property set to "Copy Always"

Second: Add this code

using Microsoft.Win32;                  
using System;                           
using System.Drawing.Text;              
using System.IO;                        
using System.Runtime.InteropServices;   


namespace TestAutomation
{
    public partial class SplashScreen : Form
    {
        [DllImport("gdi32.dll", EntryPoint = "AddFontResource")]
        public static extern int AddFontResource(string lpFileName);
        [DllImport("gdi32.dll")]
        private static extern int CreateScalableFontResource(uint fdwHidden, string
        lpszFontRes, string lpszFontFile, string lpszCurrentPath);

        // <summary>
        // Installs font on the user's system and adds it to the registry so it's available on the next session
        // Your font must be embedded as a resource in your project with its 'Build Action' property set to 'Content' 
        // and its 'Copy To Output Directory' property set to 'Copy Always'
        // </summary>
        private void RegisterFont(string contentFontName)
        {
            DirectoryInfo dirWindowsFolder = Directory.GetParent(Environment.GetFolderPath(Environment.SpecialFolder.System));

            // Concatenate Fonts folder onto Windows folder.
            string strFontsFolder = Path.Combine(dirWindowsFolder.FullName, "Fonts");

            // Creates the full path where your font will be installed
            var fontDestination = Path.Combine(strFontsFolder, contentFontName);

            // Check if file exists in destination folder. If not, then copy the file from project directory to destination
            if (!File.Exists(fontDestination))
            {
                try
                {
                    // Copies font to destination
                    File.Copy(Path.Combine(Directory.GetCurrentDirectory(), contentFontName), fontDestination);

                    // Retrieves font name
                    PrivateFontCollection fontCol = new PrivateFontCollection();
                    fontCol.AddFontFile(fontDestination);
                    var actualFontName = fontCol.Families[0].Name;

                    // Add font
                    AddFontResource(fontDestination);
                    // Add registry entry   
                    Registry.SetValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts",
                        actualFontName, contentFontName, RegistryValueKind.String);
                }
                catch (Exception e)
                {
                    MessageBox.Show(e.Message + "\n\nThe required font(s) have not been installed."
                        + "\n\nPlease contact your systems administrator for help.");
                    Start();
                }

            }

            // If file exists in destination folder, then start program.
            else
            {
                Start();
            }

        }

        public SplashScreen()
        {
            RegisterFont("GOTHIC.TTF");
        }

        private void Start()
        {
            InitializeComponent();
        }
    }
}

I modified the code to fit my needs. Here are the links to where I found my info:

How to quickly and easily embed fonts in winforms app in C#

https://csharp.hotexamples.com/examples/System.Drawing.Text/PrivateFontCollection/AddFontFile/php-privatefontcollection-addfontfile-method-examples.html

timmebee
  • 89
  • 1
  • 2
  • 12