电子说
LabVIEW:2015
你可能碰到过这种需求:需要在自己开发的应用程序中嵌入某个第三方的可执行程序,那么该如何实现呢?其实是很简单的,借助Windows API,简单几步即可完成:
1. 找到待嵌入的窗体句柄,使用WinAPI:
HWND FindWindowA(
[in, optional] LPCSTR lpClassName,
[in, optional] LPCSTR lpWindowName
);
参数的详细描述如下图所示:
从描述中可以看到,通过窗口的标题来查找句柄是简单可行的方式(当有多个标题相同的窗体时,需要用窗体类名来区分),但是此时 lpClassName需要传入NULL值,但LabVIEW中并没有办法直接创建NULL值,参考官方给出的解决方案1是可行的(按照值传递的方式传入0,大多数时候DLL会视作指针类型参数传入的是NULL值),如下图所示:
于是封装 FindWindowA() 函数如下图所示:
另外如果你想获取任一窗体的类名和标题名,借用Spy++工具是很容易的,可以自行搜索下载,当然如果你按照了Visual Studio也是带的有的,如下图所示:
比如将查找程序工具拖拽到TEST.exe的窗体标题栏上,如下图所示:
2. 设置带嵌入窗体的父窗体,使用WinAPI:
HWND SetParent(
[in] HWND hWndChild,
[in, optional] HWND hWndNewParent
);
参数的详细描述如下图所示:
这两个参数比较简单,无需多解释,封装 SetParent() 函数如下图所示:
那么如何获取LabVIEW编写的VI窗体句柄呢?这里提供两种方式:
通过上面封装的 FindWinowA() 函数,传入窗体标题来获取;
通过VI的Front Panel Window.Native Window属性直接获取,但是该属性默认是隐藏的,需要在LabVIEW.ini配置文件中加上:SuperSecretPrivateSpecialStuff=True,重启LabVIEW即可;
有了上述两个API其实就已经可以把第三方exe嵌入到VI中了,但是窗体没有重绘,效果可能是窗体已经嵌入但是是空白的(如下图所示),需要自己拖动一下窗口或调整其大小才能恢复,另外嵌入时没有办法去控制嵌入的位置和窗体大小,显然这并不够完美,那么还需借助几个API来达到理想的效果。
3. 获取窗体的边界尺寸,使用WinAPI:
BOOL GetWindowRect(
[in] HWND hWnd,
[out] LPRECT lpRect
);
参数详细描述如下图所示:
参数也比较简单,只是第二个参数是一个结构体指针,这里需要用一个空类型指针来接收,传入适配类型簇(包含四个Int32数值元素),封装如下图所示:
4. 移到窗体位置并设置大小,使用WinAPI:
BOOL MoveWindow(
[in] HWND hWnd,
[in] int X,
[in] int Y,
[in] int nWidth,
[in] int nHeight,
[in] BOOL bRepaint
);
参数详细描述如下图所示:
封装如下图所示:
5.
5. 更改指定窗口的属性,使用WinAPI:
LONG SetWindowLongA(
[in] HWND hWnd,
[in] int nIndex,
[in] LONG dwNewLong
);
详细参数描述如下图所示:
关于窗口样式有很多种,这里不便展出,详细请参考官方描述,链接如下:
https://learn.microsoft.com/zh-cn/windows/win32/winmsg/window-styles
封装如下图所示:
6. 指定窗体的显示状态,使用WinAPI:
BOOL ShowWindow(
[in] HWND hWnd,
[in] int nCmdShow
);
详细参数描述如下图所示:
封装如下图所示:
7. 发送指定消息到窗口,使用WinAPI:
LRESULT SendMessageA(
[in] HWND hWnd,
[in] UINT Msg,
[in] WPARAM wParam,
[in] LPARAM lParam
);
详细参数如下图所示:
官方文档中提到更改窗口的父级时,应同步这两个窗口的 UISTATE。有关详细信息,请参阅 WM_CHANGEUISTATE 和 WM_UPDATEUISTATE。封装如下:
嵌入一个LabVIEW开发的可执行程序如下图所示:
嵌入Excel应用程序如下图所示:
全部0条评论
快来发表一下你的评论吧 !