VB.NET - Accessing Printer Font from NET - Asked By keith jones on 04-Aug-05 12:19 PM

My windows application is attempting to print a series of labels, within those labels is a Bar Code (Code 39) - this font is installed on the printer. I can use word to print it out (the printer font becoming visible in the fonts list whe the correct printer is selected) but I cannot find a way to get at this font from the Print Document object I am using for my label. Is it possible? 

If not is it possible to open the printer directly from VB.Net (There is no straight equivalent of VB6s Printer object, so how would I configure the printer to use the different fonts for the different lines.

Might it be possible to automate word to do this?

Any help or pointers gratefully received.

Printer Font - Asked By Ryan McFarren on 04-Aug-05 04:29 PM

I work on a printing product, where oftentimes we have to access printer resident fonts.  Unfortunately, in .NET, we are forced to continue using Win32 code to provide this functionality.  There isn't an equivalent in .NET.  You need to get a DeviceContext to the printer and use the EnumFontFamilesEx and so on.  It's ugly, but it works.

Re Printer Font - Asked By keith jones on 04-Aug-05 05:31 PM

Thanks Ryan - I was hoping for a different answer but at least now I know.

Problems Printing Labels using PrintDocument - Asked By keith jones on 17-Aug-05 12:46 PM

We have an application to print bar code labels to a Thermal Transfer Printer. Basically you pass the number of labels you require (since they are all identical apart from the label count 1 of 3, 2 of 3 etc) the Print Page routine prints each label and increments the label count. On the development machine (XP pro SP2  .net framework 1.1) it works. On site on an XP Pro , and on a Windows 2000 machine the application generates the correct number of labels on the printer however only the first label is printed and the others are blank.

The XP machine on site is SP1. The printer driver (for a Toshiba TEC B-452) is the same version pn each machine. 

Does anyone have any clue as to what could be causing this.
Using Win32 code to print in NET - Asked By Martin Harris on 18-Aug-05 09:55 AM
Do you have any sample code for this, or could you point me in the direction of the right API to use?

Thanks in advance

Martin Harris
Using Win32 code to print in NET - Asked By Martin Harris on 18-Aug-05 10:03 AM
PS. I'm familiar with the StartDocPrinter, StartPagePrinter, WritePrinter API, but don't know how to prepare the data to pass to the WritePrinter API

Thanks

M
Using Win32 code to print in NET - Asked By Ryan McFarren on 18-Aug-05 10:10 AM
Hi Martin,

As I mentioned previously, you will probably need the Win32 function EnumFontFamilesEx.  That will require duplicating a few Win32 structures in your code: NEWTEXTMETRIC, LOGFONT, ENUMLOGFONTEX, etc. and then set up delegates as the middle man between your .NET code and the Win32 code.  A basic example is below.

Ryan


      internal delegate int EnumFontFamiliesExProc(IntPtr lpelfe, IntPtr lpntme, 
         uint FontType, int lParam);
      
      [DllImport("gdi32.dll", EntryPoint="EnumFontFamiliesExW")]
      private static extern int EnumFontFamiliesExW(IntPtr hDC, IntPtr lpLogFont, 
         EnumFontFamiliesExProc lpEnumFontProc, int lParam, int dw);

      internal static int EnumFontFamiliesEx(IntPtr hDC, LOGFONT logFont,
         EnumFontFamiliesExProc fontProc)
      {         
         IntPtr logFontPtr = IntPtr.Zero;

         try
         {
            logFontPtr = Marshal.AllocCoTaskMem(LOGFONT.SizeOfLOGFONT);
            Marshal.StructureToPtr(logFont, logFontPtr, false);
            return Gdi32.EnumFontFamiliesExW(hDC, logFontPtr, fontProc, 0, 0);
         }
         catch (Exception ex)
         {
         }
         finally
         {
            Marshal.FreeCoTaskMem(logFontPtr);
         }

         return 0; 
      }
Setting the font - Asked By Martin Harris on 18-Aug-05 10:17 AM
Ryan

Thanks for you quick reply. If I used the EnumFontFamiliesExW API to enumerate the fonts, how do I then use that font for data that I pass to WritePrinter? Do I need to call another API to tell the device to use the font that I've returned from EnumFontFamiliesExW?

Thanks

M
Setting the font - Asked By Ryan McFarren on 18-Aug-05 10:24 AM
You just need to select the font into the device context that you are using.  Something like this:

Gdi32.SelectObject(hPrinterDC, Gdi32.GetStockObject(someLOGFONT));

Ryan
Thanks - Asked By Martin Harris on 18-Aug-05 10:32 AM
Thanks again for your quick response. It's starting to make sense now. I'll try to remember to post some full sample code when I'm done...
Sample Code - Asked By Martin Harris on 25-Aug-05 07:12 AM
' Print some text using a standard TTF font
e.Graphics.DrawString("Hello World", New Font("Arial", 10), Brushes.Black, 100, 100)

' As we're using a device font, we need to write directly on the device context
' as the System.Drawing.Font class which is used to write on a graphics object
' does not support device fonts
Dim hdcLabel As IntPtr
hdcLabel = e.Graphics.GetHdc

' Create the new device font
Dim hfEPC As IntPtr
hfEPC = WinAPI.GDI32.CreateFont(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "MyPrinterFont")

' Select the font on the device context, getting a handle on the font that is being replaced
Dim hReplacedFont As IntPtr
hReplacedFont = WinAPI.GDI32.SelectObject(hdcLabel, hfEPC)

' Draw the text on the label
Dim intDrawTextReturn As Integer
intDrawTextReturn = WinAPI.User32.DrawText(hdcLabel, "Hello World", ("Hello World").Length, New Rectangle(20, 20, 300, 300), 0)

' Re-Select the original font on the device context
WinAPI.GDI32.SelectObject(hdcLabel, hReplacedFont)

' Dispose of the EPC font
WinAPI.GDI32.DeleteObject(hfEPC)

' Release the device context
e.Graphics.ReleaseHdc(hdcLabel)
Possible answer - Asked By Martin Harris on 25-Aug-05 07:18 AM
I had something similar and it turned out to be the paper size. Make sure that the default paper size (i.e. label size) on your printer driver (usualy under the 'Stock' tab) is set correctly
WinAPI? - Gianni Carrero replied to Martin Harris on 09-Dec-08 07:26 AM
Looks like using this winAPI I'll also be able to use the Graphics.DrawString method which is what I need. I know it has been a long time since you posted this but is there any chance you can post the WinAPI class definition?

Thanks.
I am also having same problem. - Rup Rizal replied to Gianni Carrero on 03-Dec-09 12:25 PM
I am trying to write to Epson TM-T88III receipt printer using vb.net 2005.  I am using PrintDocument class. Using system fonts is too slow to print so I wanted to use printer native fonts. But my application replaces the printer fonts with system fonts when I try to print.
Here is the code:
'to create font
f_header = New Font("FontA42", 12) ', FontStyle.Bold)
'to print
 g.DrawString("A D M I T   O N E", f_header, Brushes.Black, 23, y)

Can any one tell me how to accomplish this printing with printer fonts -- "FontA42" is my printer font?
Looks like I need to use Win32API. Can I create the instance of printer font with Win32API and then use g.DrawString and use that font to print?
Please help.....

Rup