3,245
社区成员
发帖
与我相关
我的任务
分享
// Created by Microsoft (R) C/C++ Compiler Version 11.00.50727.1 (b1ad9319).
//
// c:\users\say\documents\visual studio 2012\projects\consoleapplication1\consoleapplication1\debug\biokey.tlh
//
// C++ source equivalent of Win32 type library biokey.ocx
// compiler-generated file created 05/27/14 at 00:25:23 - DO NOT EDIT!
#pragma once
#pragma pack(push, 8)
#include <comdef.h>
namespace ZKFPEngXControl {
//
// Forward references and typedefs
//
struct __declspec(uuid("d95cb779-00cb-4b49-97b9-9f0b61cab3c1"))
/* LIBID */ __ZKFPEngXControl;
struct __declspec(uuid("161a8d2d-3dde-4744-ba38-08f900d10d6d"))
/* dual interface */ IZKFPEngX;
struct __declspec(uuid("8aee2e53-7ebe-4b51-a964-009adc68d107"))
/* dispinterface */ IZKFPEngXEvents;
struct /* coclass */ ZKFPEngX;
//
// Smart pointer typedef declarations
//
_COM_SMARTPTR_TYPEDEF(IZKFPEngX, __uuidof(IZKFPEngX));
_COM_SMARTPTR_TYPEDEF(IZKFPEngXEvents, __uuidof(IZKFPEngXEvents));
//
// Type library items
//
struct __declspec(uuid("161a8d2d-3dde-4744-ba38-08f900d10d6d"))
IZKFPEngX : IDispatch
{
//
// Property data
//
__declspec(property(get=GetRegTplFileName,put=PutRegTplFileName))
_bstr_t RegTplFileName;
__declspec(property(get=GetEnrollIndex,put=PutEnrollIndex))
long EnrollIndex;
//太长帖子不允许,类似的代码段未贴出来
//
// Wrapper methods for error-handling
//
long GetEnrollCount ( );
void PutEnrollCount (
long Value );
VARIANT_BOOL VerFinger (
VARIANT * regTemplate,
const _variant_t & verTemplate,
VARIANT_BOOL ADoLearning,
VARIANT_BOOL * ARegFeatureChanged );
VARIANT_BOOL VerRegFingerFile (
_bstr_t regTemplateFile,
const _variant_t & verTemplate,
VARIANT_BOOL ADoLearning,
VARIANT_BOOL * ARegFeatureChanged );
//太长帖子不允许,类似的代码段未贴出来
//
// Raw methods provided by interface
//
virtual HRESULT __stdcall get_EnrollCount (
/*[out,retval]*/ long * Value ) = 0;
virtual HRESULT __stdcall put_EnrollCount (
/*[in]*/ long Value ) = 0;
virtual HRESULT __stdcall raw_VerFinger (
/*[in,out]*/ VARIANT * regTemplate,
/*[in]*/ VARIANT verTemplate,
/*[in]*/ VARIANT_BOOL ADoLearning,
/*[in,out]*/ VARIANT_BOOL * ARegFeatureChanged,
/*[out,retval]*/ VARIANT_BOOL * Value ) = 0;
//太长帖子不允许,类似的代码段未贴出来
};
struct __declspec(uuid("8aee2e53-7ebe-4b51-a964-009adc68d107"))
IZKFPEngXEvents : IDispatch
{
//
// Wrapper methods for error-handling
//
// Methods:
HRESULT OnFeatureInfo (
long AQuality );
HRESULT OnImageReceived (
VARIANT_BOOL * AImageValid );
HRESULT OnEnroll (
VARIANT_BOOL ActionResult,
const _variant_t & ATemplate );
HRESULT OnCapture (
VARIANT_BOOL ActionResult,
const _variant_t & ATemplate );
HRESULT OnCaptureToFile (
VARIANT_BOOL ActionResult );
HRESULT OnEnrollToFile (
VARIANT_BOOL ActionResult );
HRESULT OnFingerTouching ( );
HRESULT OnFingerLeaving ( );
};
struct __declspec(uuid("ca69969c-2f27-41d3-954d-a48b941c3ba7"))
ZKFPEngX;
// [ default ] interface IZKFPEngX
// [ default, source ] dispinterface IZKFPEngXEvents
//
// Wrapper method implementations
//
#include "c:\users\say\documents\visual studio 2012\projects\consoleapplication1\consoleapplication1\debug\biokey.tli"
} // namespace ZKFPEngXControl
#pragma pack(pop)
#include <stdio.h>
#import"biokey.ocx"
#include "Debug\biokey.tlh"
using namespace ZKFPEngXControl;
int main (void)
{
CoInitialize(NULL);
IZKFPEngXPtr fpeFuc;
fpeFuc.CreateInstance(__uuidof(IZKFPEngX));
if (0 == fpeFuc->InitEngine())
{
printf("指纹仪初始化成功\n");
}
CoUninitialize();
}
//--------------------------
CSink sink; // 接受器对象
IZKFPEngXPtr fpeEngX;
CComQIPtr< IConnectionPoint > m_spCP; // 连接点指针
DWORD m_dwCookie; // 连接的 cookie
初始化中的部分 CoInitialize(NULL);
m_dwCookie = 0;
HRESULT hr = fpeEngX.CreateInstance( __uuidof(ZKFPEngX) );
if( FAILED( hr ) )
{
MessageBox( _T("没有注册还是没有初始化?") );
OnCancel();
}
m_dwCookie = 0;
测试事件响应的部分//测试事件段
CComQIPtr<IConnectionPointContainer> spContainer( fpeEngX);
if( !spContainer )
{
MessageBox(_T("组件没有提供连接点功能\n"));
}
// 得到连接点接口
spContainer->FindConnectionPoint(__uuidof(IZKFPEngXEvents), &m_spCP);
if( !m_spCP )
{
MessageBox(_T("没有找到连接点接口\n"));
}
//注册接收器
HRESULT hr;
hr = m_spCP->Advise( &sink, &m_dwCookie);
if( FAILED( hr ) )
{
CString csErrorInfo;
csErrorInfo.Format(_T("%x"), hr);
MessageBox(csErrorInfo);
}
else
{
MessageBox(_T("已经连接成功\n"));
}
简直要疯了,我明明一开始就是这样做的,为何不行呢,折腾一圈回来竟然又可以响应com消息了,感谢前辈的耐心帮助,目前遇到的问题算是基本解决了,待我将这个控件用到windows7凭证提供程序里遇到问题在请教,先拜谢了,同时也谢谢回复帖子的每一个人,大家的回复不仅是技术上的帮助更是心里上的帮助啊,如果我一个人纠结这些问题那该是多么凄惨的事情
//fpeEngX为IZKFPEngXPtr类型
CComQIPtr<IConnectionPointContainer> spContainer( fpeEngX);
if( !spContainer )
{
MessageBox(_T("组件没有提供连接点功能\n"));
}
// 得到连接点接口
//查找连接点用了IZKFPEngXEvents的IID,
//这样的意思是不是IZKFPEngXEvents就是我们要找的连接点?
spContainer->FindConnectionPoint(__uuidof(IZKFPEngXEvents), &m_spCP);
if( !m_spCP )
{
MessageBox(_T("没有找到连接点接口\n"));
}
只有这样写才能正确得到连接点, 这样一来就有个我非常不理解的地方了:如果说连接点是IZKFPEngXEvents接口或者是连接点在IZKFPEngXEvents接口中,那连接点容器为什么在另一个接口中呢?,IZKFPEngXEvents接口和IZKFPEngX接口从上面贴的ith文件中的声明看应该是并列的关系啊。
在上面用GetControlUnknown得到组件指针后又用其QueryInterface方法得到了IZKFPEngX接口的指针,但有一点就是无论怎么弄都得不到IZKFPEngXEvents接口的指针,如下:
const RECT rect = {0, 0, 0, 0};
HRESULT hr = cwndForZKFPEngX.CreateControl(__uuidof(ZKFPEngX), NULL, 0, rect, this, IDC_ZKFPENGX, NULL, FALSE, NULL);
if (FAILED(hr))
{
MessageBox(_T("cwndForZKFPEngX.CreateControl) 失败!\n"));
}
IUnknown *pzkIunknown = cwndForZKFPEngX.GetControlUnknown();
if (pzkIunknown != NULL )
{
MessageBox(_T("获取pzkIunknown成功"));
}
hr = pzkIunknown->QueryInterface(__uuidof(IZKFPEngX), (void **)&fpeEngX);
if (FAILED(hr) )
{
MessageBox(_T("QueryInterface(__uuidof(IZKFPEngX), (void **)&fpeFuc)失败"));
}
// 下面注释掉的部分总是失败,即无法得到IZKFPEngXEvents接口的指针,
//我还常识先从IUnknown接口得到IDispatch接口再从IDispatch接口去查询
//IZKFPEngXEvents接口还是查不到,不过貌似我不必得到
//IZKFPEngXEvents接口的指针也可以,至少到连接连接点这一步还没有用
//到IZKFPEngXEvents的指针,仅仅在查询连接点时用到了__uuidof(IZKFPEngXEvents);
//
// hr = pzkIunknown->QueryInterface(__uuidof(IZKFPEngXEvents), (void **)&fpeEvents);
// if (FAILED(hr) )
// {
// MessageBox(_T("QueryInterface(__uuidof(IZKFPEngXEvents), (void **)&fpeEvents);"));
// }
最关键的问题在下面这点 //测试事件段
HRESULT hr;
CComQIPtr<IConnectionPointContainer> spContainer( fpeEngX);
if( !spContainer )
{
MessageBox(_T("组件没有提供连接点功能"));
}
// 得到连接点接口
spContainer->FindConnectionPoint(__uuidof(IZKFPEngXEvents), &m_spCP);
if( !m_spCP )
{
MessageBox(_T("没有找到连接点接口"));
}
//注册接收器
hr = m_spCP->Advise( &sink, &m_dwCookie);
if( FAILED( hr ) )
{
CString csErrorInfo;
csErrorInfo.Format(_T("%x"), hr);
MessageBox(csErrorInfo);
}
else
{
MessageBox(_T("已经连接成功\n"));
}
注册接收器竟然失败了,前面找连接点并没有失败,但注册的时候失败了,返回的错误码是0x80040202,百度竟然查不到这个错误是具体是啥,但我并没有修改csink类,连接点也找到了,为什么会注册接收器失败呢?
还有现在我对biokey中的接口声明也大部分能看懂了,但也越来越迷惑,他的那些声明注释该怎么理解
struct __declspec(uuid("d95cb779-00cb-4b49-97b9-9f0b61cab3c1"))
/* LIBID */ __ZKFPEngXControl; //这个libid似乎从来都没用到,是不是该在哪里用下?
struct __declspec(uuid("161a8d2d-3dde-4744-ba38-08f900d10d6d"))
/* dual interface */ IZKFPEngX; //杨老师讲解了这个意思是双接口,但IZKFPEngXEvents也是双接口啊,
//因为下面具体声明中IZKFPEngXEvents也实现了IDispatch接口
struct __declspec(uuid("8aee2e53-7ebe-4b51-a964-009adc68d107"))
/* dispinterface */ IZKFPEngXEvents; //这个注释想告诉使用者IZKFPEngXEvents实现了IDispatch接口吧,
//告诉我这个信息是要提示该如何使用这个接口吗?可我不知道啊,
//我只知道这个接口下都是的那几个函数实际上都是事件源,会被指
//纹仪主动触发,而不是要我们调用的,虽然他们写的很像函数,实际
//是带有参数的消息
struct /* coclass */ ZKFPEngX; //这个注释的意思是上面的两个接口都是包含在ZKFPEngX这个类中的吗?
#include <stdio.h>
#import"biokey.ocx"
#include "Debug\biokey.tlh"
using namespace ZKFPEngXControl;
#define REG_TPL_PATH L"C:\\Windows\\System32\\regtpl.tpl"
#define VER_TPL_PATH L"vertpl.tpl"
#define ENROLL_COUNT 3L
int main (void)
{
CoInitialize(NULL);
IZKFPEngXPtr fpeFuc(L"ZKFPEngXControl.ZKFPEngX");
//fpeFuc.CreateInstance(__uuidof(IZKFPEngX));
if (0 == fpeFuc->InitEngine())
{
printf("指纹仪初始化成功\n");
BSTR reg_tpl_path = SysAllocString(REG_TPL_PATH);
BSTR ver_tpl_path = SysAllocString(VER_TPL_PATH);
fpeFuc->put_RegTplFileName(reg_tpl_path); //设置模板存储路径
fpeFuc->put_VerTplFileName(ver_tpl_path);
fpeFuc->put_EnrollCount(ENROLL_COUNT);
BSTR regpath, verpath, sn;
long enrollcount;
fpeFuc->get_RegTplFileName(®path);
fpeFuc->get_VerTplFileName(&verpath);
fpeFuc->get_EnrollCount(&enrollcount);
fpeFuc->get_SensorSN(&sn);
printf("regpath:%ls\n verpath:%ls\n enrollcount:%ld\n sn:%ls\n",
regpath, verpath, enrollcount, sn);
SysFreeString(reg_tpl_path);
SysFreeString(ver_tpl_path);
SysFreeString(regpath);
SysFreeString(verpath);
SysFreeString(sn);
}
fpeFuc->EndEngine();
fpeFuc.Release();
CoUninitialize();
return 1;
}
现在的问题是我怎么响应这个组件里的消息,这个组件里有几个消息我需要捕捉到,比如手指放到指纹仪上了或者手指离开指纹仪了,这些事件都是组件内提供的,组件会发出响应的消息,在mfc中利用类向导很方便给这些事件添加响应函数,这样就算是捕捉到我想要的消息了,但现在是在非mfc程序中,我该如何捕捉想要的消息,也可以说是给感兴趣的消息添加响应函数?
还望大神们不吝赐教,实在是急死人了[/quote]
响应控件的消息,可以参考这个http://blog.csdn.net/worldy/article/details/12770709
struct __declspec(uuid("8aee2e53-7ebe-4b51-a964-009adc68d107"))
IZKFPEngXEvents : IDispatch
{
//
// Wrapper methods for error-handling
//这个接口中的所有函数都是事件,指纹仪会自动触发,可能因为消息较多所以所以把所有消息单独放在了一个接口中
// Methods:
HRESULT OnFeatureInfo (
long AQuality );
HRESULT OnImageReceived (
VARIANT_BOOL * AImageValid );
HRESULT OnEnroll (
VARIANT_BOOL ActionResult,
const _variant_t & ATemplate );
HRESULT OnCapture (
VARIANT_BOOL ActionResult,
const _variant_t & ATemplate );
HRESULT OnCaptureToFile (
VARIANT_BOOL ActionResult );
HRESULT OnEnrollToFile (
VARIANT_BOOL ActionResult );
HRESULT OnFingerTouching ( );
HRESULT OnFingerLeaving ( );
};
我仿照例子只能把响应对象和这个IZKFPEngXEvents 接口连接起来,但不知道如何区分里面的消息,实现的响应消息类(仿照杨老师例子)
//Sink.cpp
#include "Sink.h"
CSink::CSink()
{
}
CSink::~CSink()
{
}
// STDMETHODIMP 是宏,等价于 long __stdcall
STDMETHODIMP CSink::QueryInterface(const struct _GUID &iid,void ** ppv)
{
*ppv=this;
return S_OK;
}
ULONG __stdcall CSink::AddRef(void)
{ return 1; } // 做个假的就可以,因为反正这个对象在程序结束前是不会退出的
ULONG __stdcall CSink::Release(void)
{ return 0; } // 做个假的就可以,因为反正这个对象在程序结束前是不会退出的
STDMETHODIMP CSink::GetTypeInfoCount(unsigned int *)
{ return E_NOTIMPL; } // 不用实现,反正也不用
STDMETHODIMP CSink::GetTypeInfo(unsigned int,unsigned long,struct ITypeInfo ** )
{ return E_NOTIMPL; } // 不用实现,反正也不用
//STDMETHODIMP CSink::GetIDsOfNames(const struct _GUID &,unsigned short ** ,unsigned int,unsigned long,long *)
//{ return E_NOTIMPL; } // 此函数参数已变化为下面的类型了
STDMETHODIMP CSink::GetIDsOfNames(const IID &,LPOLESTR *,UINT,LCID,DISPID *)
{ return E_NOTIMPL; } //先不实现,看会不会用到
STDMETHODIMP CSink::Invoke(
long dispID,
const struct _GUID &,
unsigned long,
unsigned short,
struct tagDISPPARAMS * pParams,
struct tagVARIANT *,
struct tagEXCEPINFO *,
unsigned int *)
{ // 只需要实现这个就足够啦
//switch(dispID)
//{
//case FINGER_TOUCH: //根据不同的dispID,完成不同的回调函数
// printf("\n手指放上去了\n");
// break;
//default:
// printf("\n没有动静\n");
// break;
//}
printf("\n来消息了!\n"); //我即使改成这样,就是无论来什么消息,只要有消息来就输出点内容,可是没动静
return S_OK;
}
我绑定响应器的实现如下
#import"biokey.ocx"
#include <stdio.h>
#include "sink.h"
#include <atlcomcli.h>
using namespace ZKFPEngXControl;
#define REG_TPL_PATH L"C:\\Windows\\System32\\regtpl.tpl"
#define VER_TPL_PATH L"vertpl.tpl"
#define ENROLL_COUNT 3L
int main (void)
{
CoInitialize(NULL);
IZKFPEngXPtr fpeFuc(__uuidof(ZKFPEngX));
{ //初始化测试段
if (0 == fpeFuc->InitEngine())
{
printf("指纹仪初始化成功\n");
BSTR reg_tpl_path = SysAllocString(REG_TPL_PATH);
BSTR ver_tpl_path = SysAllocString(VER_TPL_PATH);
fpeFuc->put_RegTplFileName(reg_tpl_path); //设置模板存储路径
fpeFuc->put_VerTplFileName(ver_tpl_path);
fpeFuc->put_EnrollCount(ENROLL_COUNT);
BSTR regpath, verpath, sn;
long enrollcount;
fpeFuc->get_RegTplFileName(®path);
fpeFuc->get_VerTplFileName(&verpath);
fpeFuc->get_EnrollCount(&enrollcount);
fpeFuc->get_SensorSN(&sn);
printf("regpath:%ls\nverpath:%ls\nenrollcount:%ld\nsn:%ls\n",
regpath, verpath, enrollcount, sn);
SysFreeString(reg_tpl_path);
SysFreeString(ver_tpl_path);
SysFreeString(regpath);
SysFreeString(verpath);
SysFreeString(sn);
}
}
{//测试事件段
IZKFPEngXPtr fpeE(__uuidof(ZKFPEngX));// 组件接口指针
HRESULT hr = fpeE.CreateInstance(__uuidof(ZKFPEngX));
if (FAILED(hr))
{
printf("fpeEvents.CreateInstance(__uuidof(ZKFPEngX)) 失败!\n");
return 0;
}
CSink sink; // 接受器对象
DWORD m_dwCookie; // 连接的 cookie
IZKFPEngXEventsPtr fpeEvents = fpeE;
CComQIPtr< IConnectionPoint > m_spCP; // 连接点指针
CComQIPtr<IConnectionPointContainer> spContainer( fpeE);
if( !spContainer )
{
printf("组件没有提供连接点功能\n");
return 0;
}
// 得到连接点接口
spContainer->FindConnectionPoint(__uuidof(IZKFPEngXEvents), &m_spCP);
if( !m_spCP )
{
printf("没有找到连接点接口\n");
return 0;
}
//注册接收器
hr = m_spCP->Advise( &sink, &m_dwCookie);
if( FAILED( hr ) )
{
printf("连接失败");
}
else
{
printf("已经连接成功\n");
}
}
while('o' != getchar()) //为了让程序一直运行,好响应事件
{
}
//记得释放绑定
fpeFuc->EndEngine();
fpeFuc.Release();
CoUninitialize();
return 1;
}
程序开始运行,会显示“已经连接成功”,但是就是不会显示“来消息了!”就是sink对象没有接收到组件的消息,不知道是什么问题struct __declspec(uuid("d95cb779-00cb-4b49-97b9-9f0b61cab3c1"))
/* LIBID */ __ZKFPEngXControl; //这句前面是给__ZKFPEngXControl指定了GUID,但这个__ZKFPEngXControl是什么时候用,怎么用
struct __declspec(uuid("161a8d2d-3dde-4744-ba38-08f900d10d6d"))
/* dual interface */ IZKFPEngX; //这个接口中是一些操作属性以及可以主动调用的方法,我尝试成功初始化指纹仪以及设置属性读取属性就是用了这个接口里的方法,上面某楼层我贴的代码中有
struct __declspec(uuid("8aee2e53-7ebe-4b51-a964-009adc68d107"))
/* dispinterface */ IZKFPEngXEvents; //这个接口的函数是事件,指纹仪有相关动作会自动触发,我需要捕捉里面的事件消息,但在这种非mfc程序中我不知道该怎么做,这是现在最重要的问题
struct /* coclass */ ZKFPEngX; //这个又是什么,是类名?几个几口都在这个类中?
/*
省略中间的部分
*/
struct __declspec(uuid("ca69969c-2f27-41d3-954d-a48b941c3ba7"))
ZKFPEngX;
// [ default ] interface IZKFPEngX
// [ default, source ] dispinterface IZKFPEngXEvents
//上面的这两行注释是什么意思?好像很高深的样子,第一行是说这个GUID默认指向IZKFPEngX接口吗?那第二行呢
//求大神赐教
#include <stdio.h>
#import"biokey.ocx"
#include "Debug\biokey.tlh"
using namespace ZKFPEngXControl;
#define REG_TPL_PATH L"C:\\Windows\\System32\\regtpl.tpl"
#define VER_TPL_PATH L"vertpl.tpl"
#define ENROLL_COUNT 3L
int main (void)
{
CoInitialize(NULL);
IZKFPEngXPtr fpeFuc(L"ZKFPEngXControl.ZKFPEngX");
//fpeFuc.CreateInstance(__uuidof(IZKFPEngX));
if (0 == fpeFuc->InitEngine())
{
printf("指纹仪初始化成功\n");
BSTR reg_tpl_path = SysAllocString(REG_TPL_PATH);
BSTR ver_tpl_path = SysAllocString(VER_TPL_PATH);
fpeFuc->put_RegTplFileName(reg_tpl_path); //设置模板存储路径
fpeFuc->put_VerTplFileName(ver_tpl_path);
fpeFuc->put_EnrollCount(ENROLL_COUNT);
BSTR regpath, verpath, sn;
long enrollcount;
fpeFuc->get_RegTplFileName(®path);
fpeFuc->get_VerTplFileName(&verpath);
fpeFuc->get_EnrollCount(&enrollcount);
fpeFuc->get_SensorSN(&sn);
printf("regpath:%ls\n verpath:%ls\n enrollcount:%ld\n sn:%ls\n",
regpath, verpath, enrollcount, sn);
SysFreeString(reg_tpl_path);
SysFreeString(ver_tpl_path);
SysFreeString(regpath);
SysFreeString(verpath);
SysFreeString(sn);
}
fpeFuc->EndEngine();
fpeFuc.Release();
CoUninitialize();
return 1;
}
现在的问题是我怎么响应这个组件里的消息,这个组件里有几个消息我需要捕捉到,比如手指放到指纹仪上了或者手指离开指纹仪了,这些事件都是组件内提供的,组件会发出响应的消息,在mfc中利用类向导很方便给这些事件添加响应函数,这样就算是捕捉到我想要的消息了,但现在是在非mfc程序中,我该如何捕捉想要的消息,也可以说是给感兴趣的消息添加响应函数?
还望大神们不吝赐教,实在是急死人了