www.gusucode.com > 精典源码Delphi130:顺某指纹考勤管理系统 > 精典源码Delphi130:顺某指纹考勤管理系统/11065顺某指纹考勤管理系统delphi/1.2newcxy/FPCtl.cpp
// FPCtl.cpp : Implementation of the CFPCtrl ActiveX Control class. #include "stdafx.h" #include "FP.h" #include "FPCtl.h" #include "FPPpg.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif int g_nWidth, g_nHeight; //width and height of drawing area FT_HANDLE g_FtContext; //dpFpFns context FT_HANDLE g_mcContext; //dpMatch context FT_UI_LINK g_FtUILink; //UI link information FT_DEVICE_INFO g_DevInfo; //device info FT_BYTE* g_Features=NULL; //features FT_BYTE* g_VerFeatures=NULL; //features int g_recommendedFtrLen, g_minFtrLen; //recommended features length and minimum features length int g_nFingerCount; //variable to count down fingers left while registering (4 - 0) BOOL g_bIsVerifying,g_bCanVerify; //verifying or register mode, in verifying mode do not show images or fingerprints CWinThread* g_pRegisterThread = NULL; //pointer to register thread CWinThread* g_pVerifyThread = NULL; //pointer to verify thread BYTE *g_FPBuffer; // Pointer to buffer which holds data portion of bitmap received from sensor. // This pointer is provided for toolkit in the callback function. // Toolkit loads image in the buffer and notifies GUI thread that image is ready. HWND g_hwnd = NULL; //HWND of dialog BOOL g_bIsTimeToDie = FALSE; //variable used to ensure clean exit from program CEvent g_event(FALSE, TRUE); //event used to make sure that program will not exit //while toolkit is doing something (like waiting for image) //second argument TRUE for manual CEvent //Callback functions set up by FT_setupUILink FT_ACTION getRegisterAction (FT_STATUS_PT pStatus) { if(g_bIsTimeToDie) //If program wants to exit, then indicate that to toolkit return FT_ID_CANCEL; switch(pStatus->code) { case FT_READY_TO_FILL_BUF: // SendMessage(g_hwnd, MESSAGE_READY_TO_FILL_BUF, 0, 0); TRACE("FT_READY_TO_FILL_BUF\n"); break; case FT_BUF_FILLED: // SendMessage(g_hwnd, MESSAGE_IMAGE_RECEIVED, 0, 0); TRACE("FT_BUF_FILLED\n"); break; case FT_IMAGE_INFO: // param1 = FT_IMGQUALITY. param2 = unused SendMessage(g_hwnd, MESSAGE_FT_IMAGE_INFO, 0, (LPARAM)pStatus->param1); TRACE("FT_IMAGE_INFO\n"); break; case FT_FEATURES_INFO: SendMessage(g_hwnd, MESSAGE_FT_FEATURES_INFO, 0, (LPARAM)pStatus->param1); TRACE("FT_FEATURES_INFO\n"); break; case FT_WAITING_FOR_IMAGE: SendMessage(g_hwnd, MESSAGE_FT_WAITING_FOR_IMAGE, 0, 0); TRACE("FT_WAITING_FOR_IMAGE\n"); break; default: break; } return FT_ID_CONTINUE; } FT_DISPLAY_BUF_PT getRegisterDisplayBuf (FT_FTR_TYPE) { TRACE("getRegisterDisplayBuf\n"); return g_FPBuffer; } FT_RETCODE releaseRegisterDisplayBuf (FT_DISPLAY_BUF_PT) { TRACE("releaseRegisterDisplayBuf\n"); return 0; } //Thread functions UINT DoRegister(LPVOID pParam) //register thread function { g_nFingerCount = 0; FT_RETCODE rc; FT_RESULT result; g_event.ResetEvent(); //we reset CEvent in nonsignaled state to make sure //program will wait until FT_register completes before exiting rc = FT_flushFpImages(g_FtContext); rc = FT_register(g_FtContext, FT_FALSE, //allowLearning has to be FT_TRUE here because we are planing to //use features with database g_recommendedFtrLen, g_Features, NULL, &result); g_event.SetEvent(); //now we can exit ::PostMessage((HWND)pParam, WM_REGISTERTHREADFINISHED, 0, (LPARAM)result); return 0; } //Thread functions UINT DoVerify(LPVOID pParam) //register thread function { FT_IMG_QUALITY qualityImg; FT_FTR_QUALITY qualityFtr; FT_RETCODE rc; FT_RESULT result; g_event.ResetEvent(); //we reset CEvent in nonsignaled state to make sure //program will wait until FT_register completes before exiting rc = FT_flushFpImages(g_FtContext); rc = FT_acquireFeatures(g_FtContext, FT_VER_FTR, g_recommendedFtrLen, g_VerFeatures, &qualityImg, &qualityFtr, &result); if(result == FT_SUCCESS) g_bCanVerify=TRUE; else g_bCanVerify=FALSE; g_event.SetEvent(); //now we can exit ::PostMessage((HWND)pParam, WM_VERIFYTHREADFINISHED, 0, (LPARAM)result); return 0; } IMPLEMENT_DYNCREATE(CFPCtrl, COleControl) ///////////////////////////////////////////////////////////////////////////// // Message map BEGIN_MESSAGE_MAP(CFPCtrl, COleControl) //{{AFX_MSG_MAP(CFPCtrl) // NOTE - ClassWizard will add and remove message map entries // DO NOT EDIT what you see in these blocks of generated code ! //}}AFX_MSG_MAP ON_MESSAGE(OCM_COMMAND, OnOcmCommand) ON_OLEVERB(AFX_IDS_VERB_PROPERTIES, OnProperties) ON_MESSAGE(MESSAGE_FT_IMAGE_INFO, OnImageInfo) ON_MESSAGE(MESSAGE_FT_FEATURES_INFO, OnFeaturesInfo) ON_MESSAGE(WM_REGISTERTHREADFINISHED, OnRegisterThreadFinished) ON_MESSAGE(WM_VERIFYTHREADFINISHED, OnVerifyThreadFinished) ON_MESSAGE(MESSAGE_FT_WAITING_FOR_IMAGE, OnWaitingForImage) END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // Dispatch map BEGIN_DISPATCH_MAP(CFPCtrl, COleControl) //{{AFX_DISPATCH_MAP(CFPCtrl) DISP_PROPERTY(CFPCtrl, "FeatureLength", m_FeatureLength, VT_I2) DISP_FUNCTION(CFPCtrl, "FlushImages", FlushImages, VT_BOOL, VTS_NONE) DISP_FUNCTION(CFPCtrl, "InitReg", InitReg, VT_BOOL, VTS_NONE) DISP_FUNCTION(CFPCtrl, "Regist", Regist, VT_EMPTY, VTS_NONE) DISP_FUNCTION(CFPCtrl, "InitVerify", InitVerify, VT_BOOL, VTS_NONE) DISP_FUNCTION(CFPCtrl, "GetRegFeatures", GetRegFeatures, VT_BOOL, VTS_I2 VTS_PI2) DISP_FUNCTION(CFPCtrl, "SetRegFeatures", SetRegFeatures, VT_BOOL, VTS_I2 VTS_I2) DISP_FUNCTION(CFPCtrl, "Verify", Verify, VT_BOOL, VTS_NONE) DISP_FUNCTION(CFPCtrl, "KillThread", KillThread, VT_BOOL, VTS_NONE) DISP_FUNCTION(CFPCtrl, "GetVerFeature", GetVerFeature, VT_EMPTY, VTS_NONE) //}}AFX_DISPATCH_MAP END_DISPATCH_MAP() ///////////////////////////////////////////////////////////////////////////// // Event map BEGIN_EVENT_MAP(CFPCtrl, COleControl) //{{AFX_EVENT_MAP(CFPCtrl) EVENT_CUSTOM("GetVerFeatures", FireGetVerFeatures, VTS_BOOL VTS_BSTR) EVENT_CUSTOM("GetRegFeatures", FireGetRegFeatures, VTS_BOOL VTS_BSTR) EVENT_CUSTOM("Status", FireStatus, VTS_I4 VTS_BSTR) //}}AFX_EVENT_MAP END_EVENT_MAP() ///////////////////////////////////////////////////////////////////////////// // Property pages // TODO: Add more property pages as needed. Remember to increase the count! BEGIN_PROPPAGEIDS(CFPCtrl, 1) PROPPAGEID(CFPPropPage::guid) END_PROPPAGEIDS(CFPCtrl) ///////////////////////////////////////////////////////////////////////////// // Initialize class factory and guid IMPLEMENT_OLECREATE_EX(CFPCtrl, "FP.FPCtrl.1", 0xb40bcde9, 0xb949, 0x11d3, 0x98, 0xf0, 0xbd, 0xa0, 0x34, 0x90, 0x69, 0x7a) ///////////////////////////////////////////////////////////////////////////// // Type library ID and version IMPLEMENT_OLETYPELIB(CFPCtrl, _tlid, _wVerMajor, _wVerMinor) ///////////////////////////////////////////////////////////////////////////// // Interface IDs const IID BASED_CODE IID_DFP = { 0xb40bcde7, 0xb949, 0x11d3, { 0x98, 0xf0, 0xbd, 0xa0, 0x34, 0x90, 0x69, 0x7a } }; const IID BASED_CODE IID_DFPEvents = { 0xb40bcde8, 0xb949, 0x11d3, { 0x98, 0xf0, 0xbd, 0xa0, 0x34, 0x90, 0x69, 0x7a } }; ///////////////////////////////////////////////////////////////////////////// // Control type information static const DWORD BASED_CODE _dwFPOleMisc = OLEMISC_ACTIVATEWHENVISIBLE | OLEMISC_SETCLIENTSITEFIRST | OLEMISC_INSIDEOUT | OLEMISC_CANTLINKINSIDE | OLEMISC_RECOMPOSEONRESIZE; IMPLEMENT_OLECTLTYPE(CFPCtrl, IDS_FP, _dwFPOleMisc) ///////////////////////////////////////////////////////////////////////////// // CFPCtrl::CFPCtrlFactory::UpdateRegistry - // Adds or removes system registry entries for CFPCtrl BOOL CFPCtrl::CFPCtrlFactory::UpdateRegistry(BOOL bRegister) { // TODO: Verify that your control follows apartment-model threading rules. // Refer to MFC TechNote 64 for more information. // If your control does not conform to the apartment-model rules, then // you must modify the code below, changing the 6th parameter from // afxRegApartmentThreading to 0. if (bRegister) return AfxOleRegisterControlClass( AfxGetInstanceHandle(), m_clsid, m_lpszProgID, IDS_FP, IDB_FP, afxRegApartmentThreading, _dwFPOleMisc, _tlid, _wVerMajor, _wVerMinor); else return AfxOleUnregisterClass(m_clsid, m_lpszProgID); } ///////////////////////////////////////////////////////////////////////////// // CFPCtrl::CFPCtrl - Constructor CFPCtrl::CFPCtrl() { InitializeIIDs(&IID_DFP, &IID_DFPEvents); // TODO: Initialize your control's instance data here. SetInitialSize(168,264); } ///////////////////////////////////////////////////////////////////////////// // CFPCtrl::~CFPCtrl - Destructor CFPCtrl::~CFPCtrl() { // TODO: Cleanup your control's instance data here. if (g_FPBuffer != NULL ) { g_bIsTimeToDie = TRUE; ::WaitForSingleObject(g_event, INFINITE); FT_disconnectDevice(g_FtContext); FT_closeContext(g_FtContext); FT_terminate(); if (g_VerFeatures !=NULL) { MC_closeContext(g_mcContext); MC_terminate(); delete [] g_VerFeatures; } delete [] g_FPBuffer; delete [] g_Features; delete m_pGray8Dib; }; } ///////////////////////////////////////////////////////////////////////////// // CFPCtrl::OnDraw - Drawing function void CFPCtrl::OnDraw( CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid) { DoSuperclassPaint(pdc, rcBounds); pdc->Rectangle(rcBounds); if (g_FPBuffer!=NULL) { m_pGray8Dib->UsePalette(pdc, true); m_pGray8Dib->Draw(pdc, 1, 1, g_FPBuffer); } } ///////////////////////////////////////////////////////////////////////////// // CFPCtrl::DoPropExchange - Persistence support void CFPCtrl::DoPropExchange(CPropExchange* pPX) { ExchangeVersion(pPX, MAKELONG(_wVerMinor, _wVerMajor)); COleControl::DoPropExchange(pPX); // TODO: Call PX_ functions for each persistent custom property. } ///////////////////////////////////////////////////////////////////////////// // CFPCtrl::OnResetState - Reset control to default state void CFPCtrl::OnResetState() { COleControl::OnResetState(); // Resets defaults found in DoPropExchange // TODO: Reset any other control state here. } ///////////////////////////////////////////////////////////////////////////// // CFPCtrl::PreCreateWindow - Modify parameters for CreateWindowEx BOOL CFPCtrl::PreCreateWindow(CREATESTRUCT& cs) { cs.lpszClass = _T("STATIC"); return COleControl::PreCreateWindow(cs); } ///////////////////////////////////////////////////////////////////////////// // CFPCtrl::IsSubclassedControl - This is a subclassed control BOOL CFPCtrl::IsSubclassedControl() { return TRUE; } ///////////////////////////////////////////////////////////////////////////// // CFPCtrl::OnOcmCommand - Handle command messages LRESULT CFPCtrl::OnOcmCommand(WPARAM wParam, LPARAM lParam) { #ifdef _WIN32 WORD wNotifyCode = HIWORD(wParam); #else WORD wNotifyCode = HIWORD(lParam); #endif // TODO: Switch on wNotifyCode here. return 0; } LRESULT CFPCtrl::OnImageInfo(WPARAM wParam, LPARAM lParam) { CString s; switch(lParam) { case FT_GOOD_IMG: s.LoadString(IDS_GoodIMG); TRACE("FT_GOOD_IMG\n"); break; case FT_IMG_TOO_LIGHT: s.LoadString(IDS_LightIMG); TRACE("FT_IMG_TOO_LIGHT\n"); break; case FT_IMG_TOO_DARK: s.LoadString(IDS_DarkIMG); TRACE("FT_IMG_TOO_DARK\n"); break; case FT_IMG_TOO_NOISY: s.LoadString(IDS_NoisyIMG); TRACE("FT_IMG_TOO_NOISY\n"); break; case FT_LOW_CONTRAST: s.LoadString(IDS_BadIMG); TRACE("FT_LOW_CONTRAST\n"); break; case FT_UNKNOWN_IMG_QUALITY: s.LoadString(IDS_BadIMG); TRACE("FT_LOW_CONTRAST\n"); break; default: break; } FireStatus(lParam,s); return 0L; } LRESULT CFPCtrl::OnFeaturesInfo(WPARAM wParam, LPARAM lParam) { CString s,s1; switch(lParam) { case FT_GOOD_FTR: s1.LoadString(IDS_GoodFTR); TRACE("FT_GOOD_FTR\n"); if(!g_bIsVerifying) { s.Format(s1, 3 - g_nFingerCount); g_nFingerCount++; } break; case FT_NOT_ENOUGH_FTR: s.LoadString(IDS_NOT_ENOUGH_FTR); TRACE("FT_NOT_ENOUGH_FTR\n"); break; case FT_NO_CENTRAL_REGION: s.LoadString(IDS_NOT_CENTRAL_FTR); TRACE("FT_NO_CENTRAL_REGION\n"); break; case FT_UNKNOWN_FTR_QUALITY: s.LoadString(IDS_BADFTR); TRACE("FT_UNKNOWN_FTR_QUALITY\n"); break; default: break; } InvalidateControl(NULL); FireStatus(lParam,s); return 0L; } LRESULT CFPCtrl::OnWaitingForImage(WPARAM wParam, LPARAM lParam) { CString s; s.LoadString(IDS_WaitIMG); FireStatus(FT_WAITING_FOR_IMAGE,s); TRACE("FT_WAITING_FOR_IMAGE\n"); return 0L; } LRESULT CFPCtrl::OnRegisterThreadFinished(WPARAM wParam, LPARAM lParam) { CString s; g_pRegisterThread = NULL; if((FT_RESULT)lParam == FT_SUCCESS) { s.LoadString(IDS_RegSuccess); FireGetRegFeatures(TRUE,s); } else if(!g_bIsTimeToDie) { s.LoadString(IDS_RegFail); FireGetRegFeatures(FALSE,s); } FireStatus(0,s); return 0L; } LRESULT CFPCtrl::OnVerifyThreadFinished(WPARAM wParam, LPARAM lParam) { CString s; g_pVerifyThread = NULL; if(g_bCanVerify) { s.LoadString(IDS_GetVerSuccess); } else if(!g_bIsTimeToDie) { s.LoadString(IDS_GetVerFail); } FireGetVerFeatures(g_bCanVerify,s); return 0L; } ///////////////////////////////////////////////////////////////////////////// // CFPCtrl message handlers BOOL CFPCtrl::FlushImages() { // TODO: Add your dispatch handler code here FT_RETCODE rc; rc=FT_flushFpImages(g_FtContext); if (rc==FT_OK) return TRUE; else return FALSE; } BOOL CFPCtrl::InitReg() { // TODO: Add your dispatch handler code here g_FPBuffer = NULL; GetControlSize(&g_nWidth,&g_nHeight); FT_RETCODE rc; rc = FT_init(); rc = FT_createContext(&g_FtContext); rc = FT_getDeviceList (1, &g_DevInfo); rc = FT_connectDevice (g_FtContext, g_DevInfo.devId, FT_REGULAR_PRIORITY); g_FtUILink.getAction = getRegisterAction; g_FtUILink.getDisplayBuf = getRegisterDisplayBuf; g_FtUILink.releaseDisplayBuf = releaseRegisterDisplayBuf; g_FtUILink.numIntensityLevels = 32; g_FtUILink.timeout = 2000; g_FtUILink.extension = NULL; g_FtUILink.displayOrientation = FT_PORTRAIT; g_FtUILink.displayBufSize.width = g_nWidth; g_FtUILink.displayBufSize.height = g_nHeight; rc = FT_setupUIlink(g_FtContext, &g_FtUILink); rc =FT_getFeaturesLen(FT_REG_FTR, FT_FALSE, &g_recommendedFtrLen, &g_minFtrLen); g_FPBuffer = new BYTE[g_FtUILink.displayBufSize.width * g_FtUILink.displayBufSize.height ]; g_Features = new FT_BYTE[g_recommendedFtrLen]; m_FeatureLength=g_recommendedFtrLen; ZeroMemory(g_FPBuffer, sizeof(BYTE) * g_nHeight * g_nWidth); // CGray8Dib is a class used to create a bitmap from an array of BYTE's and draw it in a specified rectangle m_pGray8Dib = new CGray8Dib(CRect(0, 0, g_nWidth, g_nHeight), g_nWidth, g_nHeight); g_hwnd = (HWND) GetHwnd(); g_bIsVerifying = FALSE; g_event.SetEvent(); g_event.SetEvent(); if (g_FPBuffer!=NULL) return TRUE; else return FALSE; } void CFPCtrl::Regist() { // TODO: Add your dispatch handler code here CString s; g_bIsTimeToDie = TRUE; ::WaitForSingleObject(g_event, INFINITE); g_bIsTimeToDie = FALSE; g_bIsVerifying = FALSE; ZeroMemory(g_FPBuffer, sizeof(BYTE) * g_nHeight * g_nWidth); s.LoadString(IDS_BegReg); FireStatus(0,s); InvalidateControl(NULL); g_pRegisterThread = AfxBeginThread(DoRegister, (HWND)GetHwnd(), THREAD_PRIORITY_NORMAL); } BOOL CFPCtrl::InitVerify() { // TODO: Add your dispatch handler code here if (g_FPBuffer==NULL) InitReg(); FT_RETCODE rc; rc = MC_init(); rc = MC_createContext(&g_mcContext); g_VerFeatures=new FT_BYTE[g_recommendedFtrLen]; if (rc==FT_OK) return TRUE; else return FALSE; } BOOL CFPCtrl::GetRegFeatures(short Index, short FAR* FeatureChar) { // TODO: Add your dispatch handler code here if (Index<0 || Index>=g_recommendedFtrLen) return FALSE; *FeatureChar=(short) g_Features[Index]; return TRUE; } BOOL CFPCtrl::SetRegFeatures(short Index, short FeatureChar) { // TODO: Add your dispatch handler code here if (Index<0 || Index>=g_recommendedFtrLen) return FALSE; g_Features[Index]=(unsigned char)FeatureChar; return TRUE; } BOOL CFPCtrl::Verify() { FT_RETCODE rc; FT_BOOL bFeatureChanged,isVerified; FT_VER_SCORE sc; FT_BYTE* fKey; CString s; BOOL bResult; if (!g_bCanVerify) return FALSE; fKey=new FT_BYTE[FT_KEY_LEN]; rc=MC_verifyFeatures(g_mcContext, g_recommendedFtrLen, g_Features, g_recommendedFtrLen, g_VerFeatures, FALSE, &bFeatureChanged, fKey, &sc, &isVerified); delete [] fKey; s.LoadString(IDS_EndVerify); FireStatus(rc,s); if (rc != FT_OK) bResult =FALSE; else bResult = isVerified; return bResult; } BOOL CFPCtrl::KillThread() { g_bIsTimeToDie=TRUE; ::WaitForSingleObject(g_event, INFINITE); return TRUE; } void CFPCtrl::GetVerFeature() { CString s; ZeroMemory(g_VerFeatures, sizeof(BYTE) * g_recommendedFtrLen); ZeroMemory(g_FPBuffer, sizeof(BYTE) * g_nHeight * g_nWidth); InvalidateControl(NULL); g_bIsVerifying = TRUE; s.LoadString(IDS_BegVerify); FireStatus(0,s); g_pVerifyThread = AfxBeginThread(DoVerify, (HWND)GetHwnd(), THREAD_PRIORITY_NORMAL); }