2014年6月9日 星期一

[原創] LabVIEW wrapper Callback from dll (2) Example:Keyboard,Mouse,USB event callback

本篇為延續前一篇的內容,進行Callback函數的實作

在LabVIEW中若想要使用dll來註冊Event,dll必須加入extcode.h這個檔頭hextcode.h位於..\National Instruments\(LabVIEW 版本)\cintools目錄下。它定義了CIN和外部程序所用到的基本數據類型和許多函數等。


首先先列出要完成的函數:


// dll 給 LabVIEW呼叫來安裝Mouse Hook的函數
MgErr __declspec(dllexport) InstallMouseHook(LVUserEventRef *value);
// dll 給 LabVIEW呼叫來解除Mouse Hook的函數
MgErr __declspec(dllexport) UnInstallMouseHook(void);

其中LVUserEventRef  * 就是LabVIEW中Event reference傳給dll的資料型態。
MgErr 是NI定義在extcode.h檔頭的錯誤訊息。
實作程式碼非常單純:


MgErr __declspec(dllexport) InstallMouseHook(LVUserEventRef *value)


{

 MgErr bSuccess = noErr;

 userRec.MSEevent = *value;

 if (!ghMouseHook)

 {

  gPreMouseProc = (HOOKPROC) MouseHookProc ;

  bSuccess = (NULL != (ghMouseHook = 

   SetWindowsHookEx (WH_MOUSE_LL, gPreMouseProc,

   g_hInst, NULL)));

 }



 if(bSuccess)

  return noErr;

 else

  return mgArgErr;



}



MgErr __declspec(dllexport) UnInstallMouseHook(void)

{

 if(ghMouseHook != NULL)

 {

  if(UnhookWindowsHookEx(ghMouseHook))

  {

   ghMouseHook=NULL;

   return noErr;

  }else

   return mgArgErr;

 }

 else

  return fNotFound;



}



userRec是用來存放LVUserEventRef  的結構,除此之外都是標準掛載Hook的程式碼。 接下來就是主要提到的Callback函數:
typedef struct tagDataRec {

 LONG lParam;

 LONG wParam;

} DataRec, *DataRecPtr;



LRESULT CALLBACK MouseHookProc 

(int nCode, WPARAM  wParam, LPARAM lParam)

{

 DataRec returnData;

 PMSLLHOOKSTRUCT pmll = (PMSLLHOOKSTRUCT) lParam;

 returnData.lParam=(pmll->pt.x<<16 )+ pmll->pt.y;

 returnData.wParam=wParam;

 PostLVUserEvent(userRec.MSEevent,&returnData);

 return CallNextHookEx (ghMouseHook, nCode, wParam, lParam);



}



DataRec是用來存放當LabVIEW的Event Structure觸發到這個自訂的滑鼠事件時收到的資料型態。程式很單純,把滑鼠座標塞到lParam,把滑鼠按鍵狀態存到wParam,然後透過定義在extcode.h檔頭的函式PostLVUserEvent就將這個事件的消息傳到LabVIEW程式的Event Structure訊息回圈內,一旦程式執行到Event Structure,程式碼就得到這個事件的結果。 LabVIEW端程式碼如下:
範例程式碼內除了攔截滑鼠的資料外,還有鍵盤與USB裝置插拔的資料。


3 則留言:

  1. Hi
    Thanks for your article it is exactly what I was looking for. Nevertheless the vi works great (labview 2014) but after a short time it just stops working. When this happend UnInstallingHook gives return code 7.
    Could it be posible to post or include the full dll code in your post.
    Thanks in advanced.

    Juan Manuel

    回覆刪除
    回覆
    1. Hi Juan
      Can you post your labview version and running environment(win7,win8,win10,32/64 bit?)

      The example dll was built under visual studio 6.0 and it is very simple, c++ source code are almost in this post so I don't keep the original source code.

      刪除
    2. Thanks for your reply. I tried lv2014_32 and lv2017_32 W10_64 and win XP_32 all with similar results.

      刪除