所以在工作中,我已经为一些不同的事情开发了几个月的OPOS驱动程序。我没有创建这个项目,但我已经接管了它,并且是唯一一个开发它的人。所以今天我对它的完成方式感到好奇,我认为它可能一开始就错了。我不得不做一点挖掘,发现它使用了一家名为MCS(Monroe Consulting Services)的公司的OPOS驱动程序。我下载了1.13并安装了MSI版本。我启动VS创建了一个新的mfc dll。然后我去添加一个类。这就是我困惑的地方。
无论我选择Typelib还是ActiveX,它通常都会给我相同的接口列表,我可以从中添加/扩展(除了MSR的一个例外,它有一个我可以扩展的事件接口)。它们都制作了相同的头文件(在MSR的情况下,它是COPOSMSR.h),但一个扩展CCmdTarget,另一个扩展CWnd。这是我的第一个问题。我应该选择哪一个?什么是typelib/什么是ActiveX组件以及它们之间的区别。
我一直在做的那个扩展了CCmdTarget。就我而言,我不知道驱动程序是如何知道使用其中一个文件(USNMSRFID)的,但这就是所有开发的地方。(我把它分解了一点,所以它不仅仅是一个巨大的文件)但那个文件并没有扩展COPOSMSR。。它还扩展了CCmdTarget。我唯一一次看到有人提到USN文件是在MSRFID.idl中(这让我更加困惑)有人对此清楚吗?
我有一部分认为,在部署时,这可能会产生非常大的影响。一些使用该驱动程序编写的测试应用程序需要一个有点混乱的设置过程,包括注册不同的驱动程序、将文件复制到特定文件夹、设置注册表等等。我想,如果我能理解这一切意味着什么,以及如何制作一个好的应用程序,正确地扩展这些OPOS设备,我可以在未来为自己省去更多的悲伤。
有什么建议吗???很抱歉,如果这是一个新手问题。。但我对C++还是个新手。我从Java开始,然后转到C#,所以有些东西让我难以理解。。。。
好吧,我已经挖了很多洞,就像在寻找恐龙一样。不容易,也很难找到。我最后会写一篇关于这方面的好文章,但现在我会公布我的发现。虽然我还没有做到这一点,但我知道我已经很接近了。
事实证明,typelib和activeX并不是一个大问题,但在你开始之后就会发挥作用。ActiveX用于控件对象,Typelib用于服务对象。最重要的是正确地开始。我在一些中文网站上发现了一篇文章,在找出翻译错误后,提供了一些不错的建议。首先,您将希望使用Automation制作一个C++项目。它可以是ATL或MFC。我更喜欢MFC。在附录A第8节的UPOS 1.13 pdf(或更新版本)中,它描述了服务对象的责任。它有您需要实现的主要方法。有16种方法需要添加,至少有4种方法可以获取/设置OPOS设备的属性。
因此,要开始,您需要打开添加类向导(对于MFC类),然后单击添加MFC类。你会希望你的基类是CCmdTarget。想出一个经典的类名(我选择了PinpadSOCPP)然后在自动化单选按钮中选择按类型ID创建。它应该将您的类型ID填写为[项目名称]。[类名]所以我的是PinpadSO.PinpadSOCPP。完成。这就形成了一个很好的接口文件,您可以使用Class视图向其添加方法等等
关于添加方法,有两件事需要注意,其中一件我还没有100%弄清楚。首先,您必须使用正确的参数和返回值来实现该部分中的所有方法。大多数返回LONG(32位有符号数字)。并且两个最常见的参数是LONG和BSTR。(当你有"out"参数时,偶尔会有一些指针)这是我认为我目前失败的部分,因为我不知道我是否都正确地实现了它们,这就是为什么我会出现错误104/305(中文文章说我的方法中缺少了一些东西)我不确定它是否区分大小写,我不确定需要获取/设置的7个属性中的哪些需要实现,因为我正在工作的MSR SO并没有全部使用它们,而且SO正在工作。另一种是,在实现基本的OPOS方法后,还必须从特定的OPOS设备中实现额外的方法。由于我正在做PINPad,所以我必须实现另外6种方法。
现在这是一项非常耗时的工作,因为您必须打开类视图,导航到项目类的名称。展开它并转到"接口"部分。我的项目名称是PinpadSO,我在其中实现的文件是PinpadSOCPP(这意味着接口名称是IPinpadSOCPP),右键单击IPinpadSOCPP,然后单击添加>添加方法。这将使您进入一个分为两步的过程。您填写您的返回值、函数名称,并添加所有参数。点击next,填写一些帮助字符串信息(如果你愿意的话),然后点击finish。现在,在你做了20多次之后,它变得又老又慢。。。如果你和我一样,你可以键入Computer而不是Compute和flip-flop字母,或者忘记在所有参数上点击add。一个人可以制作一个很好的小程序来编辑每次添加方法时都会更改的3个文件,这将大大加快速度。如果您犯了一个错误,您将需要打开[project name].idl
、[class name].h
和[class name].cpp
,这三个文件将直接向其中添加方法。我建议不要犯错误。
所以现在,所有的艰苦工作都已经过去了。编译你的程序。如果你想保存你自己一个额外的步骤,你可以在链接器项目设置中打开"自动注册"(注意:如果你这样做,如果你在vista或更高版本中编程,你需要以管理员身份运行Visual Studio),这将使你不必打开一个命令窗口(管理员)导航到你的DLL并在该DLL上使用命令regsvr32。好的是,你不必一遍又一遍地这样做,只要一次就可以了。我没有确凿的事实表明它每次都是这样工作的,但我正在研究的MSR,我会对它进行更改,编译它,然后打开我的OPOS测试程序,这些更改已经生效。
之后,您需要添加注册表。导航到HKLM\software\OLEforRetail\ServiceOPOS(注意,如果你有x64机器,你会做两次。一次在那里,另一次在HKLM\software\Wow6432Node\OLEforRetail\ServiceOPOS)
您需要为正在使用的任何OPOS设备添加密钥。我正在制作一个密码板,所以我制作了一个名为pinpad的密钥(检查你的UPOS文档,看看你应该给它取什么名字)最后为你的设备选择一个名字。我从供应商那里选择了的型号作为我的设备名称(C100),并在PINPad中制作了一个子密钥。默认的REG_SZ值需要是您注册的SO设备类型ID。在我的情况下是PinpadSO.PinpadSOCPP
如果你没有OPOS测试程序(我刚刚把它作为控制台程序制作),那么你可以使用Microsoft OPOS测试应用程序(我无法让它在我的x64机器上运行……但也许你会更幸运)如果你决定制作自己的OPOS测试应用程序,请确保你为x86机器编译它(即使你有x64)OPOS出于某种原因不喜欢x64(可能是我假设的指针长度)。。无论如何。一旦你设置好了,运行你的测试应用程序(在我的情况下,我只是运行OPOSPinpadClass pin = new OPOSPinpadClass(); Console.WriteLine(pin.Open("C100"));
,希望0:)
我目前得到104(E_NOSERVICE)。。就像我之前说的,我认为这是因为我没有正确的方法。如果是这样的话,我会编辑这个回复,或者我会报告并说出它的真实情况。不管怎样,我希望这能帮助其他决定自己做SO的人。祝好运
更新
当您调用"打开"命令时,OPOS会检查几个属性。必须实现的属性之一是GetPropertyNumber中的,它是PIDX_ServiceObjectVersion
。您需要设置此数字才能返回(1000000 * majorVersion) + (1000 * minorVersion) + revision
,因为我正在制作一个兼容OPOS 1.13的版本,所以我返回的ServiceObjectVersion是1013000。您还需要在GetPropertyString:中实现3个属性
PIDX_DeviceDescription
PIDX_DeviceName
PIDX_ServiceObjectDescription
对于所有其他值,您可以返回一个空字符串或0,直到您开始连接所有这些值。
附带说明一下,如果你不想用C++制作它,你不必这样做。你可以用任何可以用它编写ActiveX对象的语言制作它(比如COM可见的.NET类库)