繁体   English   中英

如何将接口实现为约束的抽象类?

[英]How to implement Interface to an abstract class which is constraint?

几天前,我尝试在 ms access vba 中使用(参考)一个没有接口的 QRCode 库 .net,但未成功。 所以我做了一些研究,这里的人指导了我。 所以我决定按照这个步骤制作界面https://whoisburiedhere.wordpress.com/2011/07/12/creating-a-com-object-from-scratch-with-c/

我已经能够看到智能感知并创建其他类的一些对象和变量,但是我在看到 Dispose() 的类时遇到了麻烦,但我无法在 ms 访问中使用 New:

[Dim QRCD as New QRCode]

我收到一个错误,使用 New 无效,但我可以用以下行声明:

Dim QRCD as QRCode

[我认为这不是一个对象{如果我试图使它等于 QRData“这是不允许的”错误开始}]该类实现了一个抽象类,该类具有我试图将接口放在抽象类中的约束如果我将它放在 Child 类中,我会收到错误“不实现该方法”,我无法创建对象,也无法看到任何具有后期绑定的方法。 可以在此处找到 QRCoder 库。 https://github.com/codebude/QRCoder这是提供的抽象类。

{
using System;

public abstract class AbstractQRCode<T>
{
    protected QRCodeData qrCodeData;

    protected AbstractQRCode(QRCodeData data)
    {
        qrCodeData = data;
    }
    public abstract T GetGraphic(int pixelsPerModule);
}

}

这是实现它的子类; 它已经用界面修改了。 不是所有的代码,而是有几种方法都称为 GetGraphic(something as something),它们彼此不同。

    [ComVisible(true)]
[Guid("It's filled in the program"), InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface neker
{

    Bitmap GetGraphic(int pixelsPerModule);
}
[ComVisible(true)]
[Guid(""), ClassInterface(ClassInterfaceType.AutoDual)]

public class QRCode :AbstractQRCode<Bitmap>, IDisposable, neker
{
    public QRCode(QRCodeData data) : base(data) {}

    public override Bitmap GetGraphic(int pixelsPerModule)
    {
        return GetGraphic(pixelsPerModule, Color.Black, Color.White, true);
    }

    public Bitmap GetGraphic(int pixelsPerModule, string darkColorHtmlHex, string lightColorHtmlHex, bool drawQuietZones = true)
    {
        return GetGraphic(pixelsPerModule, ColorTranslator.FromHtml(darkColorHtmlHex), ColorTranslator.FromHtml(lightColorHtmlHex), true);
    }

这是示例代码(也提供)

QRCodeGenerator qrGenerator = new QRCodeGenerator();
QRCodeData qrCodeData = qrGenerator.CreateQrCode("The text which should be encoded.", QRCodeGenerator.ECCLevel.Q);
QRCode qrCode = new QRCode(qrCodeData);
Bitmap qrCodeImage = qrCode.GetGraphic(20);

这是我在 VBA 中的代码 [This is in a Module]

Public Sub QRCreator(QRtext As String)
Dim QRCG As QRCoder.QRCodeGenerator
Set QRCG = New QRCoder.QRCodeGenerator
Dim QRCD As QRCodeData
Set QRCD = QRCG.CreateQRCode(QRtext, ECCLevel_Q, False)
Dim QRCO As QRCode
Set QRCO = Factory.CreateQRCode(QRCD)
Forms!Formulario1.[Oleobject].Picture = QRCO.GetGraphic(5)
End Sub

Public Sub InitiateProperties(Data As QRCodeData)
//I declared it as Variant since QRCode is not avaliable
Dim m_data As Variant
m_data = Data
End Sub

这是在另一个模块中[我使用这个模块来创建带参数的对象] 在 VBA 中将参数传递给构造函数

Public Function CreateQRCode(Data As QRCodeData) As QRCode
//you see the word new is missing If I run it it says "An object is required"

Set CreateQRCode = QRCode
CreateQRCode.InitiateProperties Data:=Data

End Function

我如何修改它以使其可从 microsoft access 2013 中使用? 是另一种没有接口的方法吗? access 是否支持 vba 中的位图? 我对所有这些东西都很陌生,所以非常感谢。

编辑:我无法使其工作的原因是可见的不支持带有参数的构造函数和带有覆盖的方法。 答案是我无论如何都能创建图像。

无法创建您的 COM 对象,因为该类没有默认构造函数。 与其尝试公开原始 API,不如创建一个具有符合您需要的方法的类:

VBA 用法:

Public Sub QRCreator(text As String)
  Dim qrc As New QRCoder.QRCodeGenerator
  Forms!Formulario1.[Oleobject].Picture = qrc.Create(text, CCLevel_Q, 5)
End Sub

。网 :

[Guid("C7CC4CA0-813A-431E-B92C-842A07735E72")]
[ComVisible(true), InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface _QRCodeGenerator {

    public IStdPicture Create(string text, int cclevel, int pixelsPerModule);

}


[ProgId("QRCoder.QRCodeGenerator")]
[Guid("4DC2C1F8-2727-4120-80E1-8475650D8547")]
[ComVisible(true), ClassInterface(ClassInterfaceType.None)]
[Description("...")]
public class QRCodeGenerator : _QRCodeGenerator, IDisposable {

    private QRCoder.QRCodeGenerator instance;

    public QRCodeGenerator() {
        instance = new QRCoder.QRCodeGenerator();
    }

    public IStdPicture Create(string text, int cclevel, int pixelsPerModule){
        var qrCodeData = instance.CreateQrCode(text, cclevel);
        var qrCode = new QRCoder.QRCode(qrCodeData);
        var bitmap = qrCode.GetGraphic(pixelsPerModule);
        return ImageToPicture(bitmap);
    }

    public void Dispose() {
        instance.Dispose();
    }

    private static IStdPicture ImageToPicture(Bitmap bitmap) {
        ...
    }
}

经过检查、尝试和失败后,我决定改变我的观点。 所以我做了这个

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using Interop;
using System.Runtime.InteropServices;
using stdole;
namespace QRCoder
{
[Guid("52724C82-F18C-460B-B48D-1F19E016F86E")]
[ComVisible (true) , InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface IQRCodeGene
{
    string Create(string text, QRCodeGenerator.ECCLevel value, int pixelsPerModule);
}
[Guid("4F445AA5-D642-438B-A69A-429D621A3CB0")]
[ComVisible (true), ClassInterface(ClassInterfaceType.None)]
   public class QRCodeGene: IQRCodeGene, IDisposable
{
    private QRCodeGenerator Instance;
    public QRCodeGene()
    {
        Instance = new QRCodeGenerator();
    }
    public string Create(string text, QRCodeGenerator.ECCLevel value, int pixelsPerModule)
    {
        var qrCodeData = Instance.CreateQrCode(text, value);
        var qrCode = new QRCode(qrCodeData);
        var bitmap = qrCode.GetGraphic(pixelsPerModule);
// This line is the only modified by the provided in the code above.
        bitmap.Save("C:\\"+text+".bmp", System.Drawing.Imaging.ImageFormat.Bmp);
//I return this string for testing. I guess If removed the text wouldn't work.
        return ("Hello");
    }
    public void Dispose()
    {
        Instance.Dispose();
    }

}
}

上面的代码生成了我将在访问 VBA 中通过此函数发送的任何内容的 QRCode:

Public Sub QR(Text As String)
Dim QRC As New QRCodeGene
Dim x As String
x = QRC.Create(Text, ECCLevel_Q, 5)

End Sub

之后我只加载生成的图片和 access.image 控件源。 感谢 Florent B. 提供此代码。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM