最近有网友来信询问于在LabVIEW 中如何使用” User32.dll ”中API EnumWindows ,由于它是使用callback 的方式传回资料因此需封装成dll 的形式给LabVIEW 使用,本篇将介绍此过程的程序撰写方式。
在LabVIEW 中若想要使用dll 来注册Event ,dll 必须加入extcode.h 这个头文件和使用Library 档labview.lib 或labviewv.lib 。
对于到底是使用labview.lib 或labviewv.lib ,根据这篇文章(labview.lib or labviewv.lib?[http://forums.ni.com/t5/LabVIEW/labview-lib-or-labviewv-lib/ td-p/2916894]) ,我的理解是为了对应不同版本的LabVIEW RunTime ,应该要使用labviewv.lib 。
首先由微软的MSDN 查看EnumWindows 的使用说明:
BOOL WINAPI EnumWindows(
_In_ WNDENUMPROC lpEnumFunc,
_In_ LPARAM lParam
);
Parameters
lpEnumFunc [in]
Type: WNDENUMPROC
A pointer to an application-defined callback function. For more information, see EnumWindowsProc .
lParam [in]
Type: LPARAM
An application-defined value to be passed to the callback function.
Return value
Type:
Type: BOOL
If the function succeeds, the return value is nonzero.
由此可看出EnumWindows 需要输入的参数,lpEnumFunc 就是callback函数的原型,要传入实作函数程序码的位址,lParam 则是输入的参数,要传入未定的资料型态位址。
接着再看看EnumWindowsProc的函数原型定义:
BOOL CALLBACK EnumWindowsProc(
_In_ HWND hwnd,
_In_ LPARAM lParam
);
Parameters
hwnd [in]
A handle to a top-level window.
lParam [in]
The application-defined value given in EnumWindows or EnumDesktopWindows .
Return value
To continue enumeration, the callback function must return TRUE ; to stop enumeration, it must return FALSE .
由此可知EnumWindowsProc 这个callback 函数的原型声明方式,当callback发生时系统会提供 hwnd 就是我们想要列举的程序handle值,而lParam 在这边并没有用到。
有了这些资讯就可以开始编写提供给LabVIEW 的dll 了,首先先定义回传给LabVIEW的资料型态,由于希望取得的是目标程序的类别字串和视窗名称自串,因此宣告一个结构包和两个字串:
typedef struct tagStrRec {
LStrHandle Str1;
LStrHandle Str2;
} StrRec, *StrRecPtr;
这样的话在LabVIEW 的部分就可以解成cluster 包含两个String 的结构。
LVUserEventRef EnumWindowsEvent;
// 预设最长字串长度为256 Bytes
#define STRING_LENGHT 256
然后再宣告dll 输出的函数:
// 用于注册LabVIEW事件
MgErr __declspec(dllexport) __cdecl RegisterEnumWindowsEvent(LVUserEventRef *value);
// 用于呼叫dll 内EnumerateWindows
void __declspec(dllexport) __cdecl EnumerateWindows(void);
{
// 用于纪录LabVIEW 程序内Event 的位址
EnumWindowsEvent = *value;
return 1;
}
void __declspec(dllexport) __cdecl EnumerateWindows(void)
{
}
BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
{
char class_name[STRING_LENGHT];
char title[STRING_LENGHT];
StrRec returnData;
// init labview string
returnData.Str1=(LStrHandle)DSNewHandle(sizeof(int32)+STRING_LENGHT*sizeof(uChar));
returnData.Str2=(LStrHandle)DSNewHandle(sizeof(int32)+STRING_LENGHT*sizeof(uChar));
// get windows class and title data
GetClassName(hwnd,class_name, sizeof(class_name));
GetWindowText(hwnd,title,sizeof(title));
// convert char arr to labview string
PopulateStringHandle(returnData.Str1,class_name);
PopulateStringHandle(returnData.Str2,title);
// use labview event to send back data
PostLVUserEvent(EnumWindowsEvent,(void *)&returnData);
return TRUE;
}
LabVIEW 程序的部分主要就是dll 的呼叫与User Event 的注册
在LabVIEW 中若想要使用dll 来注册Event ,dll 必须加入extcode.h 这个头文件和使用Library 档labview.lib 或labviewv.lib 。
对于到底是使用labview.lib 或labviewv.lib ,根据这篇文章(labview.lib or labviewv.lib?[http://forums.ni.com/t5/LabVIEW/labview-lib-or-labviewv-lib/ td-p/2916894]) ,我的理解是为了对应不同版本的LabVIEW RunTime ,应该要使用labviewv.lib 。
首先由微软的MSDN 查看EnumWindows 的使用说明:
BOOL WINAPI EnumWindows(
_In_ WNDENUMPROC lpEnumFunc,
_In_ LPARAM lParam
);
Parameters
lpEnumFunc [in]
Type: WNDENUMPROC
A pointer to an application-defined callback function. For more information, see EnumWindowsProc .
lParam [in]
Type: LPARAM
An application-defined value to be passed to the callback function.
Return value
Type:
Type: BOOL
If the function succeeds, the return value is nonzero.
由此可看出EnumWindows 需要输入的参数,lpEnumFunc 就是callback函数的原型,要传入实作函数程序码的位址,lParam 则是输入的参数,要传入未定的资料型态位址。
接着再看看EnumWindowsProc的函数原型定义:
BOOL CALLBACK EnumWindowsProc(
_In_ HWND hwnd,
_In_ LPARAM lParam
);
Parameters
hwnd [in]
A handle to a top-level window.
lParam [in]
The application-defined value given in EnumWindows or EnumDesktopWindows .
Return value
To continue enumeration, the callback function must return TRUE ; to stop enumeration, it must return FALSE .
由此可知EnumWindowsProc 这个callback 函数的原型声明方式,当callback发生时系统会提供 hwnd 就是我们想要列举的程序handle值,而lParam 在这边并没有用到。
有了这些资讯就可以开始编写提供给LabVIEW 的dll 了,首先先定义回传给LabVIEW的资料型态,由于希望取得的是目标程序的类别字串和视窗名称自串,因此宣告一个结构包和两个字串:
typedef struct tagStrRec {
LStrHandle Str1;
LStrHandle Str2;
} StrRec, *StrRecPtr;
这样的话在LabVIEW 的部分就可以解成cluster 包含两个String 的结构。
接着宣告全局变数用于储存LabVIEW UserEvent的位址和常数。
//labview 密码破解, Labview 忘记密码请找QQ:1425939287
// 纪录LabVIEW UserEvent的位址LVUserEventRef EnumWindowsEvent;
// 预设最长字串长度为256 Bytes
#define STRING_LENGHT 256
然后再宣告dll 输出的函数:
// 用于注册LabVIEW事件
MgErr __declspec(dllexport) __cdecl RegisterEnumWindowsEvent(LVUserEventRef *value);
// 用于呼叫dll 内EnumerateWindows
void __declspec(dllexport) __cdecl EnumerateWindows(void);
实作这两个函数与callback 函数就完成dll 的部分。
labview 密码破解, Labview 忘记密码请找QQ:1425939287
{
// 用于纪录LabVIEW 程序内Event 的位址
EnumWindowsEvent = *value;
return 1;
}
void __declspec(dllexport) __cdecl EnumerateWindows(void)
{
// 透过dll 呼叫EnumWindows ,并传入dll内宣告的callback函数位址。
//labview 密码破解, Labview 忘记密码 请找QQ:1425939287
EnumWindows(EnumWindowsProc, NULL);}
BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
{
char class_name[STRING_LENGHT];
char title[STRING_LENGHT];
StrRec returnData;
// init labview string
returnData.Str1=(LStrHandle)DSNewHandle(sizeof(int32)+STRING_LENGHT*sizeof(uChar));
returnData.Str2=(LStrHandle)DSNewHandle(sizeof(int32)+STRING_LENGHT*sizeof(uChar));
// get windows class and title data
GetClassName(hwnd,class_name, sizeof(class_name));
GetWindowText(hwnd,title,sizeof(title));
// convert char arr to labview string
PopulateStringHandle(returnData.Str1,class_name);
PopulateStringHandle(returnData.Str2,title);
// use labview event to send back data
PostLVUserEvent(EnumWindowsEvent,(void *)&returnData);
return TRUE;
}
LabVIEW 程序的部分主要就是dll 的呼叫与User Event 的注册