C++实现的特定Window系统窗口操控

1 缘起

激光手势导航项目,控制常规办公软件和特定开发软件的窗口切换及其翻页展示,用于多媒体的会议、论坛、课堂教学、指挥调度等场景。

开发之初,设想用Python语言开发,拟用PyUSB、Kivy/Tkinter、python-pptx/word/excel/acrobat,PyKeyboard/PyMouse等库,深入之后发现这些库多是用C++开发打包的,而且不新、不全面,作为解释语言也没有编译语言C++运行效率高,与其特制一些把C++库弥补Python应用,倒不如运用顺手的C++更快捷,反正底层已经采用C++实现了WinUSB远程指令数据接收。特别是Window窗口的操控,WinAPI更为经典直接,Python也是在应用它的包装库。于是回到了C++开发实现。

主要是两类窗口:引导窗口和展示窗口。

引导窗口是核心,控制展示窗口切换和翻页,但只能小视野指示。

展示窗口,展示常规办公软件特定开发软件的窗口,切换及其翻自如,客户体验要好。

2 基础

开发环境:这里选用EnbarcaderoRadStudio,核心C++Builder。

操控技术:WinAPI窗口控制函数及其键盘操控模拟,WinUSB多线程操控指令接收。

3 引导窗口设计

3.1 窗口设计思想

桌面顶层透明小视窗动态图文指示。透明视窗通过设置窗口属性加以实现:

AlphaBlend=true;
AlphaBlendValue=100;

3.2 GIF动画实现

以可视化控件TTimer加载gif图片,自定义TGIFImage实现动画效果:

相关头文件:

#include <Vcl.Imaging.GIFImg.hpp>
class TfmShow : public TForm
{
__published:    // IDE-managed Components
         TImage *imgDrct;
private:              // User declarations
         TGIFImage *m_pGifImg;
}

相关CPP文件:

imgDrct->Picture->LoadFromFile("normal.gif");
m_pGifImg = dynamic_cast<TGIFImage*>(imgDrct->Picture->Graphic);
m_pGifImg->AnimationSpeed =100;
m_pGifImg->Transparent = true;
m_pGifImg->Animate = true;

3.3 窗口造型设计

自适图片大小、无边框、最前:

fmShow->AutoSize = true;
fmShow->BorderStyle = bsNone;
fmShow->FormStyle = fsStayOnTop;

靠右、居中、椭圆外形,以WinAPI窗口函数实现,固定窗口在一个相应形状的框内:

void_fastcall TfmShow::FormCreate(TObject *Sender) {
         HWND hWnd = FindWindow(NULL, L"便捷操控");  // 指示窗口及其定位
         int cx = GetSystemMetrics(SM_CXSCREEN);
         int cy = GetSystemMetrics(SM_CYSCREEN);
         RECT rect;

         GetWindowRect(hWnd,&rect);
         cx -= rect.right - rect.left + 10;
         cy = (cy - rect.bottom + rect.top) / 2;
         SetWindowPos(hWnd, HWND_TOP, cx, cy, 0, 0, SWP_NOSIZE);
         int x = rect.right - rect.left;
         int y = rect.bottom - rect.top;
         HRGN hRgn = CreateRoundRectRgn(0, 0, 2*x, y, x, y);   // 圆角矩形
         //HRGN hRgn = CreateEllipticRgn(0, 0, x, y);          // 椭圆形
         SetWindowRgn(hWnd, hRgn, TRUE);
}

AERO通明玻璃效果--GalssFrame:
 

fmShow->GlassFrame->Enabled = true;
fmShow->GlassFrame->SheetOfGlass = true;

3.4 水波涟漪特效

PS动画特定制作

4 展示窗口控制

4.1 窗口展示的类型划分

便于控制起见,按同类文档的窗口显示方式区分多窗口MDI和单窗口SDI两类,MDI视窗如:PPT、word、excel、myEclipse等,SDI视窗如acrobat、notepad++、rapidStudio、googleChrom、fireFox等。

4.2 窗口桌面顶层显示

相关线程可能存在阻塞,使用SetForegroundWindow并不一定能把相关视窗带到最前显示,可先操控其线程再调用SetForegroundWindow():

BOOL SetTopWindow(HWND hWnd) {              // 设置窗口到最顶层[参数:窗口句柄]
         HWND hForeWnd = GetForegroundWindow();
         DWORD dwForeID = GetWindowThreadProcessId(hForeWnd, NULL);
         DWORD dwCurID = GetCurrentThreadId();
         AttachThreadInput(dwCurID, dwForeID, TRUE);
         ShowWindow(hWnd, SW_MAXIMIZE);                   //SW_SHOWNORMAL
         SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
         SetWindowPos(hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
         SetForegroundWindow(hWnd);
         AttachThreadInput(dwCurID, dwForeID, FALSE);
         return TRUE;
}

4.3 不同类型的窗口展示控制

控制只显示同种类型视窗中最靠前的一个,每次操作最大化显示一个窗口。

使用FindWindow()函数,按窗口类如PPTFrameClass,寻找并得到相应窗口句柄,窗口类可用工具软件如PpsSpyUI得到。

4.4 相同类型的窗口间展示控制

模拟键盘操作,MDI类型视窗,采用ctrl+F6:

keybd_event(0x11, 0, 0, 0);
keybd_event(0x75, 0, 0, 0);
keybd_event(0x11, 0, 2, 0);
keybd_event(0x75, 0, 2, 0);

SDI类型视窗,采用ctrl+Tab:
 

keybd_event(0x11, 0, 0, 0);
keybd_event(0x09, 0, 0, 0);
keybd_event(0x11, 0, 2, 0);
keybd_event(0x09, 0, 2, 0);

4.5 相同类型的窗口内展示控制

模拟键盘操作,上下翻页采用gageUp/gageDown:

keybd_event(0x21, 0, 0, 0);
keybd_event(0x21, 0, 2, 0);
keybd_event(0x22, 0, 0, 0);
keybd_event(0x22, 0, 2, 0);

直达首末页,采用ctrl+home/ctrl+end:

keybd_event(0x11, 0, 0, 0);
keybd_event(0x24, 0, 0, 0);
keybd_event(0x11, 0, 2, 0);
keybd_event(0x24, 0, 2, 0);

keybd_event(0x11, 0, 0, 0);
keybd_event(0x23, 0, 0, 0);
keybd_event(0x11, 0, 2, 0);
keybd_event(0x23, 0, 2, 0);

4.6 PPT文档的播放操控

模拟键盘操作,进入shift+F5:

keybd_event(0x10, 0, 0, 0);
keybd_event(0x74, 0, 2, 0);
keybd_event(0x10, 0, 0, 0);
keybd_event(0x74, 0, 2, 0);

上下翻页采用gageUp/gageDown:

keybd_event(0x21, 0, 0, 0);
keybd_event(0x21, 0, 2, 0);
keybd_event(0x22, 0, 0, 0);
keybd_event(0x22, 0, 2, 0);

直达首末页,采用ctrl+home/ctrl+end:

keybd_event(0x24, 0, 0, 0);
keybd_event(0x24, 0, 2, 0);
keybd_event(0x23, 0, 0, 0);
keybd_event(0x23, 0, 2, 0);

退出,采用esc:

keybd_event(0x1b, 0, 0, 0);
keybd_event(0x1b, 0, 2, 0);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值