最近接到一个任务
开发POS系统打印机的OPOS driver,用ATL COM撰写 service object
搞得头都大了,查了很多资料,知道了大致的流程。
CO组件是通用的,有现成的可以下。SO就要自已写了。
于是用VC写了一个ATL 的DLL(第一次写,什么都不懂),编译完成注册,先在VB中试一下,工程引用新建的ATL COM 库,在代码中可以new出来并调用相应的方法。但是通过OCX就不行了,未提供所需的方法。资料介绍:  应用程序调用 CO 的 open(deviceName)方法
  CO 通过RegQueryValueEx 读注册表,得到SO的ProgID, 再用CLSIDFromProgID 得到SO的 CLSID, 再
CoCreateInstance 和 QueryInterface 得到SO的接口, 通过GetIDsOfNames,Invoke调用SO接口中的函数
OpenService(deviceClass,deviceName,pDispatch)打开设备。所有这些,都是现成的,不用做,我要做的只是一个SO
但问题来了,这个SO我是不是需要重写QueryInterface,GetIDsOfName和Invoke函数?要怎么写?还是根本不需要,IDE自动完成了?希望哪位大侠能拉小弟一把。资料上写OCX固定在注册表项[ HKEY_LOCAL_MACHINE\SOFTWARE\OLEforRetail\ServiceOPOS\POSPrinter ]
"Unit1"="MyPrinter"
[ HKEY_LOCAL_MACHINE\SOFTWARE\OLEforRetail\ServiceOPOS\POSPrinter\MyPrinter ]
@="XXXX.POSPrinter.1"找到unit1对应的SO
我手工建好这些项了,"XXXX.POSPrinter.1"是ATL DLL注册后的ProID
但那个OCX就是报找不到,肯定是SO写的不好,但不知道问题出在哪里,好郁闷哦。
// SoCitaqPtr.idl : IDL source for SoCitaqPtr.dll
//// This file will be processed by the MIDL tool to
// produce the type library (SoCitaqPtr.tlb) and marshalling code.import "oaidl.idl";
import "ocidl.idl";
        [
                object,
                uuid(2BF8F234-1C69-451B-B70F-83237FDE7E29),
                dual,
                helpstring("Iposprinter Interface"),
                pointer_default(unique)
        ]
        interface Iposprinter : IDispatch
        {
                [id(1), helpstring("method OpenService")] HRESULT OpenService([in] BSTR DeviceClass, [in] BSTR DeviceName, [in] IDispatch*  pDispatch,[out,retval] long* pRC);
[id(2), helpstring("method GetOpenResult")] HRESULT GetOpenResult([out,retval] long* pRC);
        };[
        uuid(641254CF-5ACA-4ECA-BCFF-327F69F3A13A),
        version(1.0),
        helpstring("SoCitaqPtr 1.0 Type Library")
]
library SOCITAQPTRLib
{
        importlib("stdole32.tlb");
        importlib("stdole2.tlb");        [
                uuid(D4CB9470-7E8C-442D-8465-72B377BA865F),
                helpstring("posprinter Class")
        ]
        coclass posprinter
        {
                [default] interface Iposprinter;
        };
};// posprinter.h : Declaration of the Cposprinter#ifndef __POSPRINTER_H_
#define __POSPRINTER_H_#include "resource.h"       // main symbols/////////////////////////////////////////////////////////////////////////////
// Cposprinter
class ATL_NO_VTABLE Cposprinter : 
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<Cposprinter, &CLSID_posprinter>,
public IDispatchImpl<Iposprinter, &IID_Iposprinter, &LIBID_SOCITAQPTRLib>
{
public:
Cposprinter()
{
}DECLARE_REGISTRY_RESOURCEID(IDR_POSPRINTER)DECLARE_PROTECT_FINAL_CONSTRUCT()BEGIN_COM_MAP(Cposprinter)
COM_INTERFACE_ENTRY(Iposprinter)
COM_INTERFACE_ENTRY(IDispatch)
END_COM_MAP()// Iposprinter
public:
STDMETHOD(OpenService)(/*[in]*/ BSTR DeviceClass, /*[in]*/ BSTR DeviceName, /*[in]*/ IDispatch*  pDispatch,/*[out,retval]*/ long* pRC);
STDMETHOD(GetOpenResult)(/*[out,retval]*/ long* pRC);};#endif //__POSPRINTER_H_

解决方案 »

  1.   

    QueryInterface,GetIDsOfName和Invoke这些都不用写。你可以按atl/com appwizard创建一个简单工程看看先,熟悉后再把已经有的代码加进来。
      

  2.   

    这只是一个普通的com组件,如果要实现ocx,还要实现其它的接口。
      

  3.   

    ATL不是简单易用的东西,它设计给懂COM的人用的,强调的是性能。
    如果想很快上手,建议用MFC。第一次写COM的话自己手动编写COM+nt service可能还要来得快些。
    而后再用ATL才会发现它的妙味。
      

  4.   

    打印的程序网上有现成的
    可以参考《atl开发指南》
    有电子版的 
    还可以到codeproject上 http://www.codeproject.com/KB/atl/SimpleATLCom.aspx
    照着做一遍就会了