Vydělávej až 160.000 Kč měsíčně! Akreditované rekvalifikační kurzy s garancí práce od 0 Kč. Více informací.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.
Avatar
Michaal.K
Člen
Avatar
Michaal.K:23.5.2017 14:58

Ahoj,

snažím se do mé aplikace přidat vlastní font. Font mám přidán ve stromu projektu a v aplikaci se ho snažím načíst viz. kód níže.
Bohužel řádek: System.IntPtr data = Marshal.Alloc­CoTaskMem((in­t)fontStream.Len­gth); mi skončí s chybou: Odkaz na objekt není nastaven na instanci objektu.
A nějak se nemohu dopátrat proč. Prosím o pomoc. Díky

PrivateFontCollection private_fonts = new PrivateFontCollection();
        private void LoadFont()
        {
            // specify embedded resource name
            string resource = "App.windows_command_prompt.ttf";
            // receive resource stream
            Stream fontStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resource);
            // create an unsafe memory block for the font data
            System.IntPtr data = Marshal.AllocCoTaskMem((int)fontStream.Length);
            // create a buffer to read in to
            byte[] fontdata = new byte[fontStream.Length];
            // read the font data from the resource
            fontStream.Read(fontdata, 0, (int)fontStream.Length);
            // copy the bytes to the unsafe memory block
            Marshal.Copy(fontdata, 0, data, (int)fontStream.Length);
            // pass the font to the font collection
            private_fonts.AddMemoryFont(data, (int)fontStream.Length);
            // close the resource stream
            fontStream.Close();
            // free the unsafe memory
            Marshal.FreeCoTaskMem(data);
        }

        private void UTorrentWebUIForm_Load(object sender, EventArgs e)
        {
            LoadFont();
            richTextBoxInfoLog.Font = new Font(private_fonts.Families[0], 12);
        }
 
Odpovědět
23.5.2017 14:58
Avatar
HONZ4
Člen
Avatar
Odpovídá na Michaal.K
HONZ4:23.5.2017 20:24

Font přidej přes vlastnosti projektu v záložce Resources (Prostředky).

PrivateFontCollection private_fonts = new PrivateFontCollection();

private void UTorrentWebUIForm_Load(object sender, EventArgs e)
{
    GetFont(Properties.Resources.MySpecialFont); // tady zvol svůj zdroj
    richTextBoxInfoLog.Font = new Font(private_fonts.Families[0], 12);
}

private void GetFont(byte[] resdata)
{
    try
    {
        IntPtr memdata = IntPtr.Zero;
        try
        {
            memdata = Marshal.AllocCoTaskMem(resdata.Length);
            Marshal.Copy(resdata, 0, memdata, resdata.Length);
            private_fonts.AddMemoryFont(memdata, resdata.Length);
        }
        catch (Exception)
        {
            throw;
        }
        finally
        {
            if (memdata != IntPtr.Zero)
                Marshal.FreeCoTaskMem(memdata);
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}

nezapomeň změnit:
Application.Set­CompatibleTex­tRenderingDefau­lt(true);

 
Nahoru Odpovědět
23.5.2017 20:24
Avatar
HONZ4
Člen
Avatar
HONZ4:23.5.2017 20:32

malá oprava:

private void GetFont(byte[] resdata)
        {
            IntPtr memdata = IntPtr.Zero;
            try
            {
                memdata = Marshal.AllocCoTaskMem(resdata.Length);
                Marshal.Copy(resdata, 0, memdata, resdata.Length);
                private_fonts.AddMemoryFont(memdata, resdata.Length);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            finally
            {
                if (memdata != IntPtr.Zero) Marshal.FreeCoTaskMem(memdata);
            }
        }

(měl jsem tam pozůstatek testu)

Akceptované řešení
+20 Zkušeností
+2,50 Kč
Řešení problému
 
Nahoru Odpovědět
23.5.2017 20:32
Avatar
Michaal.K
Člen
Avatar
Odpovídá na HONZ4
Michaal.K:24.5.2017 9:31

Ahoj,
díky za rady. Ale zatím mi to nějak nefunguje. Font jsem přidal tak jak si psal přes vlastnosti projektu do resources.
Písmo se mi ale nezmění a když pak program krokuji, tak v:
private_fonts­.Families[0]
kterou jsem si vložil do watch mi to píše: Name = The name 'name' does not exist in the current context
Takže to vypadá že to písmo vůbec nenašlo. Kód viz níže:

private void NactiFont(byte[] resdata)
        {
            IntPtr memdata = IntPtr.Zero;
            try
            {
                memdata = Marshal.AllocCoTaskMem(resdata.Length);
                Marshal.Copy(resdata, 0, memdata, resdata.Length);
                private_fonts.AddMemoryFont(memdata, resdata.Length);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            finally
            {
                if (memdata != IntPtr.Zero) Marshal.FreeCoTaskMem(memdata);
            }
        }

        private void UTorrentWebUIForm_Load(object sender, EventArgs e)
        {
            NactiFont(Properties.Resources.windows_command_prompt);
            richTextBoxInfoLog.Font = new Font(private_fonts.Families[0], 12);
        }

Na obrázku níže je vidět přidaný font v resources.
A ještě nevím kde změnit toto:
Application.Set­CompatibleTex­tRenderingDefau­lt(true);
Díky za pomoc a rady.

 
Nahoru Odpovědět
24.5.2017 9:31
Avatar
HONZ4
Člen
Avatar
HONZ4:24.5.2017 12:51

právě kvůli nastaveni
Application.Set­CompatibleTex­tRenderingDefau­lt(false);
to nefakčí.
Najdeš to v souboru Program.cs

 
Nahoru Odpovědět
24.5.2017 12:51
Avatar
Michaal.K
Člen
Avatar
Odpovídá na HONZ4
Michaal.K:24.5.2017 13:26

Ahoj,
tak jsem to v program.cs změnil, ale pořád to nejde :-( Písmo se nezměnilo a když krokuju tak v
private_fonts­.Families[0]
kterou jsem si vložil do watch mi to píše: Name = The name 'name' does not exist in the current context
Díky za pomoc

 
Nahoru Odpovědět
24.5.2017 13:26
Avatar
HONZ4
Člen
Avatar
Odpovídá na Michaal.K
HONZ4:24.5.2017 20:49

Mě to funguje normálně. (Pro jiné formáty než .ttf by mohl být problém).
Důkaz a postup v obrázcích:

 
Nahoru Odpovědět
24.5.2017 20:49
Avatar
HONZ4
Člen
Avatar
HONZ4:24.5.2017 21:06

a pokud ti to nebude pořád fungovat, zkus pro test použít jiný font. Třeba ten co se snažíš použít nemá podporovaný formát.

ps, ta hláška je divná "The name 'name' does not exist.." nemáš tam překlep name/Name

Editováno 24.5.2017 21:09
 
Nahoru Odpovědět
24.5.2017 21:06
Avatar
Michaal.K
Člen
Avatar
Odpovídá na HONZ4
Michaal.K:25.5.2017 7:33

Ahoj,

tak jsem se posunul o kousek dál :-) Zkusil jsem založit nový projekt a postupoval jsem přesně podle tvého foto návodu. Spustil jsem program a ono to fungovalo, normálně se mi v labelu změnil font po stisku na tlačítko. Zkusil jsem tedy přidat richTextBox a změnit font a to už mi nejde, viz. kód:

private void button1_Click(object sender, EventArgs e)
        {
            GetFont(Properties.Resources.windows_command_prompt);
            label1.Font = new Font(private_fonts.Families[0], 14);
            richTextBox1.AppendText("Testovaci Text!!");
            richTextBox1.AppendText("\nTestovaci text 2!!");
            richTextBox1.SelectAll();
            richTextBox1.SelectionFont = new Font(private_fonts.Families[0], 14);
        }

Ale je zajímavé že pokud dám:
richTextBox1.Se­lectionFont = new Font("Times New Roman", 14);
tak se text změní na font Times New Roman. Takže to vypadá, že richTextBox nepodporuje tento typ písma. Je to možné?
Díky...

 
Nahoru Odpovědět
25.5.2017 7:33
Avatar
Odpovídá na Michaal.K
Michal Štěpánek:25.5.2017 8:09

Je divné, že by Label písmo podporoval a RichTextBox ne. Zkusil sis tam ten font dosadit názvem a ne výběrem podle indexu z kolekce?

Nahoru Odpovědět
25.5.2017 8:09
Nikdy neříkej nahlas, že to nejde. Vždycky se totiž najde blbec, který to neví a udělá to...
Avatar
Radek Chalupa:25.5.2017 9:07

Zkusil bych (když ten label to má správně)
richtext.Selec­tionFont = label1.Font;
výsledek bez vyzkoušení netuším, ale každopádně nebudeš mít zytečně v paměti 2 (datově) stejné objekty.

 
Nahoru Odpovědět
25.5.2017 9:07
Avatar
Michaal.K
Člen
Avatar
Odpovídá na Radek Chalupa
Michaal.K:25.5.2017 9:15

Tak bohužel ani toto nepomohlo jen se mi změnila velikost fontu v richtextboxu, protože v labelu mám 14.
Díky...

 
Nahoru Odpovědět
25.5.2017 9:15
Avatar
HONZ4
Člen
Avatar
Odpovídá na Michaal.K
HONZ4:25.5.2017 20:38

pokud je ten font šiřitelný, bylo by zajímavé tu dát odkaz ke stažení.

 
Nahoru Odpovědět
25.5.2017 20:38
Avatar
Michaal.K
Člen
Avatar
Odpovídá na HONZ4
Michaal.K:26.5.2017 6:31

Jj font je volně šiřitelný, stáhl jsem ho odsud:
http://www.dafont.com/…-prompt.font
je to font z příkazového řádku.
Díky

 
Nahoru Odpovědět
26.5.2017 6:31
Avatar
HONZ4
Člen
Avatar
Odpovídá na Michaal.K
HONZ4:26.5.2017 20:07

tak jsem to testoval, (nevím jestli je to někde i popsáno), vypadá to tak, že v RichTextBox jdou použít pouze nainstalovaná písma.
Takže, jako nejjednodušší řešení, doporučuji šířit aplikaci pomocí instalátoru a fonty nainstalovat.
Omlouvám se, že jsem tohle hned nevěděl.

Editováno 26.5.2017 20:10
 
Nahoru Odpovědět
26.5.2017 20:07
Avatar
Michaal.K
Člen
Avatar
Odpovídá na HONZ4
Michaal.K:29.5.2017 9:06

Aha, tak to mě štve, že to nejde. A jinak ten font přidat nejde? Předpokládám, že textbox se bude chovat stejně jako richtextbox.
Díky za rady a pomoc.

 
Nahoru Odpovědět
29.5.2017 9:06
Avatar
Michaal.K
Člen
Avatar
Odpovídá na HONZ4
Michaal.K:29.5.2017 10:17

Tak jsem si stím ještě chvíli hrál a zjistil jsem zajímavou věc. Pokud načtu font přímo do aplikace tak mi to v richTextBox normálně funguje, viz kód níže:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Text;
using System.Runtime.InteropServices;
using System.IO;
using System.Reflection;


namespace Pridani_fontu
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        PrivateFontCollection pfc = new PrivateFontCollection();

        private void button2_Click(object sender, EventArgs e)
        {
            richTextBox1.AppendText("Testovaci Text 3!!");
            richTextBox1.AppendText("\nTestovaci text 4!!");

        }

        private void Form1_Load(object sender, EventArgs e)
        {
            pfc.AddFontFile(Application.StartupPath + "\\" + "windows_command_prompt.ttf");
            richTextBox1.Font = new Font(pfc.Families[0], 22);
        }

    }
}

Tak teď nevím proč nefunguje tvůj postup načtení fontu z resources....
Nenapadá tě něco?
Díky.

 
Nahoru Odpovědět
29.5.2017 10:17
Avatar
Michaal.K
Člen
Avatar
Odpovídá na HONZ4
Michaal.K:29.5.2017 13:03

Tak jsem se do toho ponořil a něco jsem vygoogloval a funguje to i pro richtextbox. Viz kód níže:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Text;
using System.Runtime.InteropServices;
using System.IO;
using System.Reflection;


namespace Pridani_fontu
{
    public partial class Form1 : Form
    {
        [DllImport("gdi32.dll")]
        private static extern IntPtr AddFontMemResourceEx(IntPtr pbfont, uint cbfont, IntPtr pdv, [In] ref uint pcFonts);

        FontFamily ff;
        Font font;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            loadFont();
            AllocFont(font, this.richTextBox2, 12);
        }

        private void loadFont()
        {
            byte[] fontArray = Pridani_fontu.Properties.Resources.windows_command_prompt;
            int dataLength = Pridani_fontu.Properties.Resources.windows_command_prompt.Length;

            IntPtr ptrData = Marshal.AllocCoTaskMem(dataLength);

            Marshal.Copy(fontArray, 0, ptrData, dataLength);

            uint cFonts = 0;
            AddFontMemResourceEx(ptrData, (uint)fontArray.Length, IntPtr.Zero, ref cFonts);

            PrivateFontCollection pfc = new PrivateFontCollection();

            pfc.AddMemoryFont(ptrData, dataLength);

            Marshal.FreeCoTaskMem(ptrData);

            ff = pfc.Families[0];
            font = new Font(ff, 14f, FontStyle.Bold);
        }

        private void AllocFont(Font f, Control c, float size)
        {
            FontStyle fontStyle = FontStyle.Regular;

            c.Font = new Font(ff, size, fontStyle);
        }

        private void button3_Click(object sender, EventArgs e)
        {
            richTextBox2.AppendText("Testovaci retezec!!\n");
            richTextBox2.AppendText("Testovaci retezec!!\n");
        }

    }
}

Tak kdyby někdo náhodou řešil podobný problém, tak je to možné řešení :-)

 
Nahoru Odpovědět
29.5.2017 13:03
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 18 zpráv z 18.