1. 程式人生 > >基於Visual C 2010與windows SDK fo windows7開發windows7平臺的tabletp

基於Visual C 2010與windows SDK fo windows7開發windows7平臺的tabletp

               

基於Visual C++2010與windows SDK fo windows7開發windows7平臺的tabletpc應用(2)-漢字文件手寫軌跡輸入多語言識別

大家先看看流程與效果,然後我來講解程式碼,

1.VS2010帥氣的啟動畫面

2.VS2010的工程畫面

3。程式最終生成畫面

4.程式啟動畫面

5 程式執行畫面

6.程式列舉所有的語言識別手寫識別器

7 英文識別範例

8。韓文識別範例

9.中文識別範例

10.線條式文件

11.格子式樣文件

12.書寫嚮導模式

13.tablet pc的筆勢

核心程式碼講解如下

 核心標頭檔案程式碼講解

[cpp] view plain copy print?
  1. #pragma once
  2. class CAdvRecoApp :   
  3.     public CWindowImpl<CAdvRecoApp>,  
  4.     public IInkCollectorEventsImpl<CAdvRecoApp>,  
  5.     public IInkRecognitionEventsImpl<CAdvRecoApp>  
  6. {  
  7. public:  
  8.     // 常量
  9.     enum {   
  10.         // 子指數
  11.         mc_iSubmenuRecognizers = 1,   
  12.         mc_iSubmenuInputScopes = 2,   
  13.         mc_iSubmenuGuides = 3,  
  14.         mc_iSubmenuModes = 4,  
  15.         // child windows IDs
  16.         mc_iInputWndId = 1,   
  17.         mc_iOutputWndId = 2,   
  18.         mc_iStatusWndId = 3,  
  19.         mc_iSSGestLVId = 4,  
  20.         mc_iMSGestLVId = 5,  
  21.         // 識別指南框資料
  22.         mc_iNumRowsCols = 100,  
  23.         mc_iGuideColWidth = 100,   
  24.         mc_iGuideRowHeight = 100,  
  25.         mc_cxBoxMargin = 4,  
  26.         mc_cyBoxMargin = 4,  
  27.         // t寬度
  28.         mc_cxGestLVWidth = 160,   
  29.         // 格子數目
  30.         mc_cNumSSGestures = 36,     // single stroke gestures
  31.         mc_cNumMSGestures =  6,     // multi-stroke gestures
  32.         // 筆的筆記寬度
  33.         mc_iPenWidth = 5  
  34.     };  
  35.     // COM指標,手寫引擎的物件指標
  36.     CComPtr<IInkCollector>          m_spIInkCollector;  
  37.     CComPtr<IInkRenderer>           m_spIInkRenderer;  
  38.     CComPtr<IInkDisp>               m_spIInkDisp;  
  39.     CComPtr<IInkStrokes>            m_spIInkStrokes;  
  40.     CComPtr<IInkRecognizerContext>  m_spIInkRecoContext;  
  41.     CComPtr<IInkRecognizers>        m_spIInkRecognizers;  
  42.     CComPtr<IInkRecognizerGuide>    m_spIInkRecoGuide;  
  43.     // 子視窗
  44.     CInkInputWnd    m_wndInput;  
  45.     CRecoOutputWnd  m_wndResults;  
  46.     HWND            m_hwndStatusBar;  
  47.     HWND            m_hwndSSGestLV;     
  48.     HWND            m_hwndMSGestLV;      
  49.     // 定義資料變數
  50.     UINT            m_nCmdRecognizer;  
  51.     UINT            m_nCmdInputScope;  
  52.     UINT            m_nCmdGuide;  
  53.     UINT            m_nCmdMode;  
  54.     CComBSTR        m_bstrCurRecoName;  
  55.     bool            m_bCoerceInputScope;  
  56.     SIZE            m_szGuideBox;  
  57.     bool            m_bAllSSGestures;  
  58.     bool            m_bAllMSGestures;  
  59.     // 建立
  60.     staticint Run(int nCmdShow);  
  61.     //程式啟動
  62.     CAdvRecoApp() :  
  63.         m_hwndStatusBar(NULL), m_hwndSSGestLV(NULL), m_hwndMSGestLV(NULL),  
  64.         m_bCoerceInputScope(false),   
  65.         m_nCmdGuide(0), m_nCmdInputScope(0), m_nCmdRecognizer(0), m_nCmdMode(0),  
  66.         m_bAllSSGestures(true), m_bAllMSGestures(true)  
  67.     {  
  68.         m_szGuideBox.cx = m_szGuideBox.cy = 0;  
  69.     }  
  70.     // 所有程式方法
  71.     HMENU   LoadMenu();  
  72.     bool    CreateChildWindows();  
  73.     void    UpdateLayout();  
  74.     void    UpdateMenuRadioItems(UINT iSubMenu, UINT idCheck, UINT idUncheck);  
  75.     void    UpdateInputScopeMenu();  
  76.     void    UpdateStatusBar();  
  77.     bool    UseRecognizer(IInkRecognizer* pIInkRecognizer);  
  78.     bool    GetGestureName(InkApplicationGesture idGesture, UINT& idGestureName);  
  79.     void    PresetGestures();  
  80. DECLARE_WND_CLASS_EX(NULL, 0, -1)  
  81. BEGIN_MSG_MAP(CAdvRecoApp)  
  82.     MESSAGE_HANDLER(WM_CREATE, OnCreate)  
  83.     MESSAGE_HANDLER(WM_DESTROY, OnDestroy)  
  84.     MESSAGE_HANDLER(WM_SIZE, OnSize)  
  85.     COMMAND_ID_HANDLER(ID_RECOGNIZER_DEFAULT, OnRecognizer)  
  86.     COMMAND_RANGE_HANDLER(ID_RECOGNIZER_FIRST, ID_RECOGNIZER_LAST, OnRecognizer)  
  87.     COMMAND_ID_HANDLER(ID_INPUTSCOPE_COERCE, OnInputScopeCoerce)  
  88.     COMMAND_RANGE_HANDLER(ID_INPUTSCOPE_FIRST, ID_INPUTSCOPE_LAST, OnInputScope)  
  89.     COMMAND_ID_HANDLER(ID_GUIDE_NONE, OnGuide)  
  90.     COMMAND_ID_HANDLER(ID_GUIDE_LINES, OnGuide)  
  91.     COMMAND_ID_HANDLER(ID_GUIDE_BOXES, OnGuide)  
  92.     COMMAND_ID_HANDLER(ID_MODE_INK, OnMode)  
  93.     COMMAND_ID_HANDLER(ID_MODE_INK_AND_GESTURES, OnMode)  
  94.     COMMAND_ID_HANDLER(ID_MODE_GESTURES, OnMode)  
  95.     COMMAND_ID_HANDLER(ID_RECOGNIZE, OnRecognize)  
  96.     COMMAND_ID_HANDLER(ID_CLEAR, OnClear)  
  97.     COMMAND_ID_HANDLER(ID_EXIT, OnExit)  
  98.     NOTIFY_HANDLER(mc_iSSGestLVId, LVN_COLUMNCLICK, OnLVColumnClick)  
  99.     NOTIFY_HANDLER(mc_iMSGestLVId, LVN_COLUMNCLICK, OnLVColumnClick)  
  100.     NOTIFY_HANDLER(mc_iSSGestLVId, LVN_ITEMCHANGING, OnLVItemChanging)  
  101.     NOTIFY_HANDLER(mc_iMSGestLVId, LVN_ITEMCHANGING, OnLVItemChanging)  
  102. END_MSG_MAP()  
  103. public:  
  104.     // 訊息函式
  105.     LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);  
  106.     LRESULT OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);  
  107.     LRESULT OnSetFocus(UINTWPARAMLPARAMBOOL& bHandled);  
  108.     LRESULT OnSize(UINTWPARAMLPARAMBOOL& bHandled);  
  109.     LRESULT OnLVColumnClick(int idCtrl, LPNMHDR pnmh, BOOL& bHandled);  
  110.     LRESULT OnLVItemChanging(int idCtrl, LPNMHDR pnmh, BOOL& bHandled);  
  111.     // 命令控制代碼
  112.     LRESULT OnRecognizer(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);  
  113.     LRESULT OnInputScopeCoerce(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);  
  114.     LRESULT OnInputScope(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);  
  115.     LRESULT OnGuide(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);  
  116.     LRESULT OnMode(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);  
  117.     LRESULT OnRecognize(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);  
  118.     LRESULT OnClear(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);  
  119.     LRESULT OnExit(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);  
  120.     // 筆跡控制代碼
  121.     HRESULT OnStroke(IInkCursor* pIInkCursor, IInkStrokeDisp* pIInkStroke,   
  122.                      VARIANT_BOOL* pbCancel);  
  123.     HRESULT OnGesture(IInkCursor* pIInkCursor, IInkStrokes* pIInkStrokes,   
  124.                       VARIANT vGestures, VARIANT_BOOL* pbCancel);  
  125.     //識別器控制代碼
  126.     HRESULT OnRecognitionWithAlternates(IInkRecognitionResult* pIInkRecoResult,   
  127.                                         VARIANT vCustomParam,  
  128.                                         InkRecognitionStatus RecognitionStatus);  
  129. };  
#pragma onceclass CAdvRecoApp :     public CWindowImpl<CAdvRecoApp>,    public IInkCollectorEventsImpl<CAdvRecoApp>,    public IInkRecognitionEventsImpl<CAdvRecoApp>{public:    // 常量    enum {         // 子指數        mc_iSubmenuRecognizers = 1,         mc_iSubmenuInputScopes = 2,         mc_iSubmenuGuides = 3,        mc_iSubmenuModes = 4,        // child windows IDs        mc_iInputWndId = 1,         mc_iOutputWndId = 2,         mc_iStatusWndId = 3,        mc_iSSGestLVId = 4,        mc_iMSGestLVId = 5,        // 識別指南框資料        mc_iNumRowsCols = 100,        mc_iGuideColWidth = 100,         mc_iGuideRowHeight = 100,        mc_cxBoxMargin = 4,        mc_cyBoxMargin = 4,        // t寬度        mc_cxGestLVWidth = 160,         // 格子數目        mc_cNumSSGestures = 36,     // single stroke gestures        mc_cNumMSGestures =  6,     // multi-stroke gestures        // 筆的筆記寬度        mc_iPenWidth = 5    };    // COM指標,手寫引擎的物件指標    CComPtr<IInkCollector>          m_spIInkCollector;    CComPtr<IInkRenderer>           m_spIInkRenderer;    CComPtr<IInkDisp>               m_spIInkDisp;    CComPtr<IInkStrokes>            m_spIInkStrokes;    CComPtr<IInkRecognizerContext>  m_spIInkRecoContext;    CComPtr<IInkRecognizers>        m_spIInkRecognizers;    CComPtr<IInkRecognizerGuide>    m_spIInkRecoGuide;    // 子視窗    CInkInputWnd    m_wndInput;    CRecoOutputWnd  m_wndResults;    HWND            m_hwndStatusBar;    HWND            m_hwndSSGestLV;       HWND            m_hwndMSGestLV;        // 定義資料變數    UINT            m_nCmdRecognizer;    UINT            m_nCmdInputScope;    UINT            m_nCmdGuide;    UINT            m_nCmdMode;    CComBSTR        m_bstrCurRecoName;    bool            m_bCoerceInputScope;    SIZE            m_szGuideBox;    bool            m_bAllSSGestures;    bool            m_bAllMSGestures;    // 建立    static int Run(int nCmdShow);    //程式啟動    CAdvRecoApp() :        m_hwndStatusBar(NULL), m_hwndSSGestLV(NULL), m_hwndMSGestLV(NULL),        m_bCoerceInputScope(false),         m_nCmdGuide(0), m_nCmdInputScope(0), m_nCmdRecognizer(0), m_nCmdMode(0),        m_bAllSSGestures(true), m_bAllMSGestures(true)    {        m_szGuideBox.cx = m_szGuideBox.cy = 0;    }    // 所有程式方法    HMENU   LoadMenu();    bool    CreateChildWindows();    void    UpdateLayout();    void    UpdateMenuRadioItems(UINT iSubMenu, UINT idCheck, UINT idUncheck);    void    UpdateInputScopeMenu();    void    UpdateStatusBar();    bool    UseRecognizer(IInkRecognizer* pIInkRecognizer);    bool    GetGestureName(InkApplicationGesture idGesture, UINT& idGestureName);    void    PresetGestures();    DECLARE_WND_CLASS_EX(NULL, 0, -1)    BEGIN_MSG_MAP(CAdvRecoApp)    MESSAGE_HANDLER(WM_CREATE, OnCreate)    MESSAGE_HANDLER(WM_DESTROY, OnDestroy)    MESSAGE_HANDLER(WM_SIZE, OnSize)    COMMAND_ID_HANDLER(ID_RECOGNIZER_DEFAULT, OnRecognizer)    COMMAND_RANGE_HANDLER(ID_RECOGNIZER_FIRST, ID_RECOGNIZER_LAST, OnRecognizer)    COMMAND_ID_HANDLER(ID_INPUTSCOPE_COERCE, OnInputScopeCoerce)    COMMAND_RANGE_HANDLER(ID_INPUTSCOPE_FIRST, ID_INPUTSCOPE_LAST, OnInputScope)    COMMAND_ID_HANDLER(ID_GUIDE_NONE, OnGuide)    COMMAND_ID_HANDLER(ID_GUIDE_LINES, OnGuide)    COMMAND_ID_HANDLER(ID_GUIDE_BOXES, OnGuide)    COMMAND_ID_HANDLER(ID_MODE_INK, OnMode)    COMMAND_ID_HANDLER(ID_MODE_INK_AND_GESTURES, OnMode)    COMMAND_ID_HANDLER(ID_MODE_GESTURES, OnMode)    COMMAND_ID_HANDLER(ID_RECOGNIZE, OnRecognize)    COMMAND_ID_HANDLER(ID_CLEAR, OnClear)    COMMAND_ID_HANDLER(ID_EXIT, OnExit)    NOTIFY_HANDLER(mc_iSSGestLVId, LVN_COLUMNCLICK, OnLVColumnClick)    NOTIFY_HANDLER(mc_iMSGestLVId, LVN_COLUMNCLICK, OnLVColumnClick)    NOTIFY_HANDLER(mc_iSSGestLVId, LVN_ITEMCHANGING, OnLVItemChanging)    NOTIFY_HANDLER(mc_iMSGestLVId, LVN_ITEMCHANGING, OnLVItemChanging)END_MSG_MAP()public:    // 訊息函式    LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);    LRESULT OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);    LRESULT OnSetFocus(UINT, WPARAM, LPARAM, BOOL& bHandled);    LRESULT OnSize(UINT, WPARAM, LPARAM, BOOL& bHandled);    LRESULT OnLVColumnClick(int idCtrl, LPNMHDR pnmh, BOOL& bHandled);    LRESULT OnLVItemChanging(int idCtrl, LPNMHDR pnmh, BOOL& bHandled);        // 命令控制代碼    LRESULT OnRecognizer(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);    LRESULT OnInputScopeCoerce(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);    LRESULT OnInputScope(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);    LRESULT OnGuide(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);    LRESULT OnMode(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);    LRESULT OnRecognize(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);    LRESULT OnClear(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);    LRESULT OnExit(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);    // 筆跡控制代碼    HRESULT OnStroke(IInkCursor* pIInkCursor, IInkStrokeDisp* pIInkStroke,                      VARIANT_BOOL* pbCancel);    HRESULT OnGesture(IInkCursor* pIInkCursor, IInkStrokes* pIInkStrokes,                       VARIANT vGestures, VARIANT_BOOL* pbCancel);    //識別器控制代碼    HRESULT OnRecognitionWithAlternates(IInkRecognitionResult* pIInkRecoResult,                                         VARIANT vCustomParam,                                        InkRecognitionStatus RecognitionStatus);};

 核心原始檔的程式碼講解

[cpp] view plain copy print?
  1. #ifndef _WIN32_WINNT
  2. #define _WIN32_WINNT 0x0500
  3. #endif
  4. #include <windows.h>
  5. #include <commctrl.h>       //  com指標所需標頭檔案
  6. #ifndef ListView_SetCheckState
  7. #define ListView_SetCheckState(hwndLV, i, fCheck) /
  8. ListView_SetItemState(hwndLV, i, INDEXTOSTATEIMAGEMASK((fCheck ? 2 : 1)), LVIS_STATEIMAGEMASK)  
  9. #endif
  10. #ifndef ListView_GetCheckState
  11. #define ListView_GetCheckState(hwndLV, i) /
  12. ((((UINT)(SNDMSG((hwndLV), LVM_GETITEMSTATE, (WPARAM)(i), LVIS_STATEIMAGEMASK))) >> 12) -1)  
  13. #endif
  14. #ifndef MIIM_STRING
  15. #define MIIM_STRING      0x00000040
  16. #endif
  17. #ifndef MIIM_FTYPE
  18. #define MIIM_FTYPE       0x00000100
  19. #endif
  20. // 定義陣列容納筆勢
  21. #define countof(array)  (sizeof(array)/sizeof(array[0]))
  22. #include <atlbase.h>        /
  23. CComModule _Module;  
  24. #include <atlwin.h>         
  25. #include <atlcom.h>        
  26. // Tablet PC 標頭檔案
  27. #include <msinkaut.h>
  28. #include <msinkaut_i.c>
  29. #include <tpcerror.h>
  30. #include "resource.h"       
  31. #include "EventSinks.h"    
  32. #include "ChildWnds.h"      
  33. #include "AdvReco.h"        
  34. //定義初始化變數
  35. const LPOLESTR gc_pwsInputScopes[] = {  
  36.     L"(!IS_DEFAULT)",  
  37.     L"(!IS_URL)",  
  38.     L"(!IS_FILE_FULLFILEPATH)",  
  39.     L"(!IS_FILE_FILENAME)",  
  40.     L"(!IS_EMAIL_USERNAME)",  
  41.     L"(!IS_EMAIL_SMTPEMAILADDRESS)",  
  42.     L"(!IS_LOGINNAME)",  
  43.     L"(!IS_PERSONALNAME_FULLNAME)",  
  44.     L"(!IS_PERSONALNAME_PREFIX)",  
  45.     L"(!IS_PERSONALNAME_GIVENNAME)",  
  46.     L"(!IS_PERSONALNAME_MIDDLENAME)",  
  47.     L"(!IS_PERSONALNAME_SURNAME)",  
  48.     L"(!IS_PERSONALNAME_SUFFIX)",  
  49.     L"(!IS_ADDRESS_FULLPOSTALADDRESS)",  
  50.     L"(!IS_ADDRESS_POSTALCODE)",  
  51.     L"(!IS_ADDRESS_STREET)",  
  52.     L"(!IS_ADDRESS_STATEORPROVINCE)",  
  53.     L"(!IS_ADDRESS_CITY)",  
  54.     L"(!IS_ADDRESS_COUNTRYNAME)",  
  55.     L"(!IS_ADDRESS_COUNTRYSHORTNAME)",  
  56.     L"(!IS_CURRENCY_AMOUNTANDSYMBOL)",  
  57.     L"(!IS_CURRENCY_AMOUNT)",  
  58.     L"(!IS_DATE_FULLDATE)",  
  59.     L"(!IS_DATE_MONTH)",  
  60.     L"(!IS_DATE_DAY)",  
  61.     L"(!IS_DATE_YEAR)",  
  62.     L"(!IS_DATE_MONTHNAME)",  
  63.     L"(!IS_DATE_DAYNAME)",  
  64.     L"(!IS_DIGITS)",  
  65.     L"(!IS_NUMBER)",  
  66.     L"(!IS_ONECHAR)",  
  67.     L"(!IS_TELEPHONE_FULLTELEPHONENUMBER)",  
  68.     L"(!IS_TELEPHONE_COUNTRYCODE)",  
  69.     L"(!IS_TELEPHONE_AREACODE)",  
  70.     L"(!IS_TELEPHONE_LOCALNUMBER)",  
  71.     L"(!IS_TIME_FULLTIME)",  
  72.     L"(!IS_TIME_HOUR)",  
  73.     L"(!IS_TIME_MINORSEC)",  
  74.     L"((0|1|2|3|4|5|6|7|8|9) ?(0|1|2|3|4|5|6|7|8|9) ?(0|1|2|3|4|5|6|7|8|9) ?-? ?)?(0|1|2|3|4|5|6|7|8|9) ?(0|1|2|3|4|5|6|7|8|9) ?(0|1|2|3|4|5|6|7|8|9) ?-? ?(0|1|2|3|4|5|6|7|8|9) ?(0|1|2|3|4|5|6|7|8|9) ?(0|1|2|3|4|5|6|7|8|9) ?(0|1|2|3|4|5|6|7|8|9)",  
  75.     L"(!IS_PERSONALNAME_FULLNAME)|((!IS_PERSONALNAME_PREFIX)? +(!IS_PERSONALNAME_GIVENNAME)+ +(!IS_PERSONALNAME_MIDDLENAME)* +(!IS_PERSONALNAME_SURNAME)+)",  
  76.     L"MN(0|1|2|3|4|5|6|7|8|9)(0|1|2|3|4|5|6|7|8|9)(A|B)(!IS_DIGITS)(X|Y)((0|1)*)"
  77. };  
  78. constLONG gc_lMaxInputScopeMenuItemLength = 40;  
  79. // 定義筆勢常量
  80. const InkApplicationGesture gc_igtSingleStrokeGestures[] = {  
  81.     IAG_Scratchout, IAG_Triangle, IAG_Square, IAG_Star, IAG_Check,  
  82.     IAG_Circle, IAG_DoubleCircle, IAG_Curlicue, IAG_DoubleCurlicue,  
  83.     IAG_SemiCircleLeft, IAG_SemiCircleRight,  
  84.     IAG_ChevronUp, IAG_ChevronDown, IAG_ChevronLeft,  
  85.     IAG_ChevronRight, IAG_Up, IAG_Down, IAG_Left, IAG_Right, IAG_UpDown, IAG_DownUp,  
  86.     IAG_LeftRight, IAG_RightLeft, IAG_UpLeftLong, IAG_UpRightLong, IAG_DownLeftLong,  
  87.     IAG_DownRightLong, IAG_UpLeft, IAG_UpRight, IAG_DownLeft, IAG_DownRight, IAG_LeftUp,  
  88.     IAG_LeftDown, IAG_RightUp, IAG_RightDown, IAG_Tap  
  89. };  
  90. constUINT gc_nRecommendedForMixedMode[] = {  
  91.         0 /*Scratchout*/, 3/*Star*/, 6/*Double Circle*/,  
  92.         7 /*Curlicue*/, 8 /*Double Curlicue*/, 25 /*Down-Left Long*/ };  
  93. const InkApplicationGesture gc_igtMultiStrokeGestures[] = {  
  94.     IAG_ArrowUp, IAG_ArrowDown, IAG_ArrowLeft,  
  95.     IAG_ArrowRight, IAG_Exclamation, IAG_DoubleTap  
  96. };  
  97. const _ATL_FUNC_INFO IInkRecognitionEventsImpl<CAdvRecoApp>::mc_AtlFuncInfo =  
  98.         {CC_STDCALL, VT_EMPTY, 3, {VT_UNKNOWN, VT_VARIANT, VT_I4}};  
  99. const _ATL_FUNC_INFO IInkCollectorEventsImpl<CAdvRecoApp>::mc_AtlFuncInfo[2] = {  
  100.         {CC_STDCALL, VT_EMPTY, 3, {VT_UNKNOWN, VT_UNKNOWN, VT_BOOL|VT_BYREF}},  
  101.         {CC_STDCALL, VT_EMPTY, 4, {VT_UNKNOWN, VT_UNKNOWN, VT_VARIANT, VT_BOOL|VT_BYREF}}  
  102. };  
  103. constTCHAR gc_szAppName[] = TEXT("CSDN專家尹成的程式,http://blog.csdn.net/yincheng01");  
  104. //程式初始化視窗
  105. int APIENTRY WinMain(  
  106.         HINSTANCE hInstance,  
  107.         HINSTANCE/*hPrevInstance*/,   // not used here
  108.         LPSTR/*lpCmdLine*/,       // not used here
  109.         int       nCmdShow  
  110.         )  
  111. {  
  112.     int iRet = 0;  
  113.     // 初始化COM
  114.     if (S_OK == ::CoInitializeEx(NULL, COINIT_APARTMENTTHREADED))  
  115.     {  
  116.         _Module.Init(NULL, hInstance);  
  117.         // 註冊空間視窗
  118.         INITCOMMONCONTROLSEX icc;