什么是/如何在C#中使用HFont

时间:2013-08-06 18:31:42

标签: c# printing pinvoke

我正在使用C#中的标签打印机的打印机SDK,详细信息可以在这里找到:

https://stackoverflow.com/questions/18083309/getting-a-printer-api-to-work-with-c-sharp

根据那里给出的建议,我使用PInvoke来使DLL中的函数正常工作,令我惊讶的是,它们已经开始聚集在一起......主要是。

函数SlpDrawTextXY()应该能够为Hfont类型的字体获取参数。这可以通过一个名为SlpCreateFont()的函数创建。 (文件第21页和第19页分别详述这些方法)。

现在,我发现Hfont实际上是什么的尝试很糟糕。 MSDN提到了一点,但并没有真正告诉我它究竟是什么。如果你是盲人,所提供的文章并不是真正有用的,并且肯定更适合那些已经在那里的人。关于它的其他文件非常渺茫,我还在猜测应该发生什么。

我有一段看起来像这样的代码:

public partial class Form1 : Form
{
    [DllImport("SlpApi7x32.dll")]
    static extern void SlpDebugMode(int nMode);

    [DllImport("SlpApi7x32.dll")]
    static extern int SlpOpenPrinter(String strPrinterName, int nID, bool fPortrait);

    [DllImport("SlpApi7x32.dll")]
    static extern void SlpClosePrinter();

    [DllImport("SlpApi7x32.dll")]
    static extern bool SlpStartLabel();

    [DllImport("SlpApi7x32.dll")]
    static extern void SlpDrawTextXY(int x, int y, Font iFont, String lpText);

    [DllImport("SlpApi7x32.dll")]
    static extern bool SlpEndLabel();

    [DllImport("SlpApi7x32.dll")]
    static extern Font SlpCreateFont(String lpName, int nPoints, int nAttributes);

    [DllImport("GDI32.dll")]
    public static extern bool DeleteObject(IntPtr objectHandle); 

    public Form1()
    {
        InitializeComponent();
    }

    private void print_Click(object sender, EventArgs e)
    {
        //Font myFont = new Font("Arial", 12);
        //IntPtr hFont = myFont.ToHfont();

        SlpDebugMode(2);

        SlpOpenPrinter("Smart Label Printer 440", 1, false);

        {
            SlpStartLabel();

            //Font font = SlpCreateFont("Courier", 12, 0);
            SlpDrawTextXY(30, 30, null, "Hello World!");

            SlpEndLabel();
        }

        SlpClosePrinter();
    }
}

我的玩具中有一些遗留物已经被注释掉了。如果它被注释掉了,它就不起作用。

这段代码实际上会打印到打印机并“打印”一个空白标签,所以看起来我真的很接近。 SlpDrawTextXY中的第三个参数是字体应该在哪里,我将它设置为'null'只是为了看看我是否可以成功通过它。此代码基于第12页的文档中的示例C代码。我希望能够将此代码转换为实际打印文本的代码。

2 个答案:

答案 0 :(得分:2)

[DllImport("SlpApi7x32.dll")]
static extern Font SlpCreateFont(...)

此处使用Font不正确。 SlpCreateFont()返回一个HFONT,一个“字体句柄”。当您在非托管代码中创建字体时,它是您操作字体的方式。并且是从Font.ToHfont()方法获得的完全相同的动物。因此,您必须以ToHfont()返回它的方式声明它,在声明中它必须是IntPtr。相应地更新其他声明。

请注意,您可以使用Font.ToHfont()而不是SlpCreateFont()获得一些不错的赔率。规则是相同的,但是,必须确保在使用完字体后调用DeleteObject(),否则您将泄漏最终会导致代码崩溃的GDI对象。

答案 1 :(得分:0)

汉斯绝对是对的。供将来参考,以下是工作代码:

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

namespace SSLP
{
public partial class Form1 : Form
{
    [DllImport("SlpApi7x32.dll")]
    static extern void SlpDebugMode(int nMode);

    [DllImport("SlpApi7x32.dll")]
    static extern int SlpOpenPrinter(String strPrinterName, int nID, bool fPortrait);

    [DllImport("SlpApi7x32.dll")]
    static extern void SlpClosePrinter();

    [DllImport("SlpApi7x32.dll")]
    static extern bool SlpStartLabel();

    [DllImport("SlpApi7x32.dll")]
    static extern void SlpDrawTextXY(int x, int y, IntPtr iFont, String lpText);

    [DllImport("SlpApi7x32.dll")]
    static extern bool SlpEndLabel();

    [DllImport("SlpApi7x32.dll")]
    static extern IntPtr SlpCreateFont(String lpName, int nPoints, int nAttributes);

    [DllImport("GDI32.dll")]
    public static extern bool DeleteObject(IntPtr objectHandle); 

    public Form1()
    {
        InitializeComponent();
    }
    private void Button1_Click(object sender, EventArgs e)
    {

        IntPtr font = SlpCreateFont("Arial", 10, 0);

        SlpDebugMode(2);

        //The second parameter defines the type of label per the documentation.
        SlpOpenPrinter("Smart Label Printer 440", 3, false);

        {
            SlpStartLabel();

            //Draw as much as you want with these!
            SlpDrawTextXY(0, 0, font, "Hello World");

            SlpEndLabel();
        }

        SlpClosePrinter();

        DeleteObject(font);
    }
}

}