一、工作中遇到一个问题:

1、需要让某个特定的窗口不被最小化、不被阻挡、不失去焦点(因为有输入);

2、由某个服务或进程来自动筛选和控制。

本来觉得用几个windows API就OK了,谁知道弄了好长好长的时间,崩溃了N次,直到现在..............依旧不敢100%确定,唉!

二、思路

1、FindWindow而后前置SetForegroundWindow

——总感觉似乎不妥,野蛮暴力,还得检索window句柄列表

2、插个全局钩子,自行判断是否前置

——感觉好一点,没那么暴力了,不过问题来了:用什么钩子?

三、实践

1、找啊找,找遍了整个屋子,终于找着了这本《阿里波特》——HCBT_CREATEWND,可以监视窗口创建——心花怒放!

——于是开始了一周的调试——注定要烧脑到死——跑偏了。

2、失败!失败!失败.........!

3、终于在崩溃前夕,不经意间发现了有个叫HCBT_ACTIVATE的家伙——她居然在灯火阑珊处好久了!小试一下,居然比那个桀骜不驯的HCBT_CREATEWND乖巧多了!不会分辨不清窗口和菜单、不会去分辨对话框窗口........,爱死你了!

好吧,就你了!

4、天真地认为花两小时调试一下就OK了..............图样图森破

5、要么找不到句柄1428,要么126、193.............

6、又一次在崩溃的边缘发现她还有一闺蜜——LoadLibraryEx,那个LoadLibrary已经被Win7封印了!(开发环境win10却好好的)好吧,有新欢就新欢吧,听你的!

噢,差点忘了#pragma data_seg,也如影随形,照顾不周,她就会捣乱,好吧,咱俩不熟,先学习研究下.......

7、啊?程序不能移植?这没有道理啊?肯定是目标机缺少运行库环境!我装——

8、VC++运行库合集——利刃呐!

——什么!还不行?!

9、...................................我还是程序员吗?

10、再去崩溃的边缘溜达溜达吧..............3、4天了,怎么跟人交差啊!

11、传说中有个叫“Release版本”的朋友,可我一直没有联系过!不经意间,他似乎.............

12、试试看吧,也许呢?...............朋友就是朋友啊,够意思!

13、哈哈,钩子跑起来了,貌似成功了!

14、..................怎么?钩子使性子?一会管用一会不管用?

15、家法伺候中.....................

16、我知道了不是你的错,你是32位的,还得有64位的,还得有32和64位的注入程序——好吧,给你俩克隆个双胞胎兄弟!——等等,我先研究下clone技术.................

17、什么?克隆了还不老实?...............................

——一会让我的VS窗口前置,一会让我的浏览器前置,当我的strstr函数不存在啊?

18、这下百度帮不了了,怎么回事?宣告是系统bug吗?

19、找bug,找bug,找bug,找bug,找bug,找bug,找bug,找bug,找bug,找......................

20、天道酬勤啊,原来是你——局部变量const,真不明白strstr函数就那么矫情,非要const参数干吗,可传个非const似乎也行........

21、于是经过很久很久的多次崩溃,钩子就成了下面这个样子——

#include <windows.h>
#include <iostream>
#include <Psapi.h>
#include <string>
//#define _WIN32_WINNT 0x500using namespace std;
#pragma data_seg("SharedDataName")
HHOOK hooker=NULL;
HWND ghwnd = NULL;
DWORD pid = -1;
//string TargetName = "AppFiles";
const char* target = "AppFiles";//TargetName.c_str();
#pragma data_seg()
#pragma comment(linker,"/section:SharedDataName,rws")HWND privateHwnd;extern "C" __declspec(dllexport) LRESULT CALLBACK HookProc(int nCode, WPARAM wParam, LPARAM lParam);
extern "C" __declspec(dllexport) HHOOK setHookDll();
extern "C" __declspec(dllexport) BOOL unHookDll();
extern "C" __declspec(dllexport) void getPid(DWORD id);
extern "C" __declspec(dllexport) void getPName(string name);BOOL APIENTRY DllMain(HMODULE hModule/* hModule */, DWORD ul_reason_for_call, LPVOID /* lpReserved */lpReserved)
{switch (ul_reason_for_call){case DLL_PROCESS_ATTACH:privateHwnd = NULL;break;case DLL_THREAD_ATTACH:case DLL_THREAD_DETACH:case DLL_PROCESS_DETACH:break;}return TRUE;
}void   CALLBACK   TimerProc(HWND   hWnd, UINT   nMsg, UINT   nTimerid, DWORD   dwTime);extern "C" __declspec(dllexport) LRESULT CALLBACK HookProc(int nCode, WPARAM wParam, LPARAM lParam) {if (nCode<0)return CallNextHookEx(hooker, nCode, wParam, lParam);tagMSG* msg;msg = (tagMSG*)lParam;switch (nCode){case HC_ACTION:break;case HCBT_CREATEWND:break;case HCBT_ACTIVATE:{HWND currentHwnd = (HWND)wParam;DWORD processID = NULL;GetWindowThreadProcessId(currentHwnd, &processID);HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processID);//LPSTR procName;TCHAR procName[MAX_PATH] = { 0 };GetProcessImageFileName(hProcess, procName, MAX_PATH);char* source = procName;if (strstr(source, target) != NULL){ghwnd = currentHwnd;privateHwnd = currentHwnd;KillTimer(currentHwnd, 1);//MessageBox(currentHwnd, source, target, MB_OK);SetTimer(currentHwnd, 1, 1000, (TIMERPROC)TimerProc);}break;}default:break;}return CallNextHookEx(hooker, nCode, wParam, lParam);
}extern "C" __declspec(dllexport) HHOOK setHookDll()
{hooker = SetWindowsHookEx(WH_CBT, HookProc, (HINSTANCE)GetModuleHandle("winhook.dll"), 0);//64位 用winhook64.dllreturn hooker;
}extern "C" __declspec(dllexport) BOOL unHookDll()
{KillTimer(privateHwnd, 1);bool unHk = UnhookWindowsHookEx(hooker);return unHk;
}extern "C" __declspec(dllexport) void getPid(DWORD id)
{pid = id;
}extern "C" __declspec(dllexport) void getPName(string name)
{//TargetName = name;
}void _stdcall  CALLBACK   TimerProc(HWND   hWnd, UINT   nMsg, UINT   nTimerid, DWORD   dwTime)
{SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_SHOWWINDOW | SWP_NOMOVE);//BringWindowToTop(currentHwnd);//SetFocus(currentHwnd);//SetActiveWindow(currentHwnd);PostMessage(hWnd, WM_SYSCOMMAND, SC_RESTORE,  NULL);HWND hForeWnd = ::GetForegroundWindow();DWORD dwForeID = ::GetWindowThreadProcessId(hForeWnd, NULL);DWORD dwCurID = ::GetCurrentThreadId();::AttachThreadInput(dwCurID, dwForeID, TRUE);SetForegroundWindow(hWnd);PostMessage(hWnd, WM_SETFOCUS, NULL, NULL);return;
}

22、不过在前置窗口并获取焦点的问题上倒数第三行的postmessage,以及前面的SetFocus似乎不怎么管用,在实际体验中感觉还是有小问题,我是没着了。

四、小记

1、微软前置个窗口怎么就那么累呢?

2、指定窗口获取个焦点怎么就那么费劲呢?死活就是不认。

3、非共享代码段似乎也会出问题,但不确认。

令人头痛的WH_CBT钩子,使窗口前置——泪水+汗水的赞歌相关推荐

  1. python 使窗口前置

    文章出处:https://www.cnblogs.com/ibingshan/p/11176040.html 关键: win32gui.FindWindow(class_name, window_na ...

  2. 【原创】终结版 窗口前置 方案 最前面 Z 轴 窗体 最前面

    要真正的理解和解决这个问题,确实不容易.当我花了好几天时间才搞明白之后(每天都会纠结新的问题),我真想写一本书. 首先说明下让窗口前置的方法非常多,但现有(2011年1月26号)网上(公开中文论坛资料 ...

  3. window.open打开窗口时要使窗口去掉菜单栏、工具栏、标题栏,达到窗口最大化

    window.open打开窗口时要使窗口去掉菜单栏.工具栏.标题栏,达到窗口最大化,可以采用下面的方法:           js 代码 ///window.open(document.locatio ...

  4. 使窗口(和 MDI 子窗口)的关闭按钮变灰的方法 - 回复 梦想成真

    问题来源: http://www.cnblogs.com/del/archive/2008/06/14/1221980.html#1225922 //这样就可以使当前窗口的关闭按钮变灰, 但系统菜单中 ...

  5. C++ 使窗口最大化最小化

    使用ShowWindow函数可是设置窗体的形态 代码 #include<windows.h> #include<cstdio> #include<iostream> ...

  6. wxpython使窗口重新显示_wxPython 窗口

    创建窗口 wx.Frame.__init__(parent, id, title, pos, size, style, name) parent : 父窗口,顶级窗口值:None,多文档界面的情况下, ...

  7. PyQt5 技巧篇-窗口置顶设置,如何使窗口始终显示在最前面

    为一个工具做个悬浮窗口,这个窗口用来做工具栏,要始终在电脑的前面,好随时被我操控,进行工具"继续/暂停"的功能. 只需要一行代码就行了,说白了,就是一个参数. Dialog.set ...

  8. pyqt5 最小化 系统托盘_Qt中如何使窗口隐藏/最小化到托盘

    展开全部 功能62616964757a686964616fe78988e69d8331333361303733:窗口最小化后或者点击"hide"按钮将窗口隐藏到托盘. 通常最小化的 ...

  9. qt中使窗口的大小随窗口的内容大小进行调整

    提要 窗口用于显示文本信息,当窗口的文本信息变长,原有窗口的大小不足以显示文本信息.这时就需要一个能够根据窗口要显示的文本信息的长度来调整窗口大小的窗口. 示例 效果图: 窗口内容少的时候提示窗口大小 ...

最新文章

  1. wordpress rest api 登录_WordPress版微信小程序3.5版发布
  2. 使用NSCondition实现多线程同步
  3. 【安全漏洞】SRC另类思路分享:不受限制的资源调用
  4. 高等数理统计(part9)--C-R不等式
  5. 如何使用单例EJB和MBean构建和清除参考数据缓存
  6. wcf 返回图片_wcf http 返回图片
  7. SVG-不是图片的图片
  8. 【科普】半监督学习的概述与思考,及其在联邦学习场景下的应用
  9. OpenCV 2.4.8 or OpenCV 2.4.9组件结构全解析
  10. php连接mysql数据库输出_PHP连接并输出数据库数据实例代码
  11. Python的@property使用方法
  12. css3中的perspective与perspective-origin
  13. via浏览器原始css,简约却不简单—via浏览器
  14. 医学超声成像—合成孔径法(Synthetic Aperture Methods)[1]
  15. 【制作】基于金沙滩51单片机的电子跑表
  16. 机器学习总结(九):梯度消失(vanishing gradient)与梯度爆炸(exploding gradient)问题
  17. 2022京东618具体活动时间和优惠节点
  18. python获取图片像素点_Python 处理图片像素点的实例
  19. pyspark RDD详细教程
  20. Excel怎么样可以快速删除空白表

热门文章

  1. 2019成长复盘2020成长规划
  2. spaCy文本分类教程
  3. 使用wxjava实现发表内容、预览信息以及推送文章
  4. 公司/企业如何管理?管理技巧是什么?《宁向东管理学课》音频资料免费下载
  5. 【C#】操作局域网共享文件夹文件,将本地文件复制到共享文件夹
  6. 干货 | 敏捷培训必备小游戏,都在这里了!
  7. Fiddler基本使用
  8. 重学JavaWeb —— JSP,简单全面一发入魂
  9. 2018微信公开课:微信小游戏的精华内容要点分享!
  10. PostgreSQL 技术内幕(二) Greenplum-AO表