近来心境不好, 什么东西都学不下, 每天偶尔点开论坛总没耐心看那些好的帖子, 自觉惭愧, 来发个帖聊以自慰罢.
内容很基础, 都是几年前玩剩下的, 比较可笑的是, 自己和几年前想比, 也没什么进步, 大家见笑.
要把窗口置顶, 稍有Win32 编程基础的人就知道 可以 Get Handle 然后 SendMessage 或者是SetWindowLog, 这里不妨说得更详细点:
窗口: Windows是以窗口作为主要交互界面的系统, 我们把那个能拖来拖去, 一般带有最大化最小化关闭按钮的大方框叫做窗口, 但是其实窗口的定义可以更广泛一点, 一个按钮是窗口, 一个文本框也是窗口.
父窗口: 如果一个按钮(Button)被放在一个Panel(面板)上, 那按钮的父窗口就是Panel, 同样Panel的父窗口是Form, Form就是我们平时说的窗口了;
顶级窗口: Form的父窗口是什么? 有人说是桌面(Desktop), 也有人说没有父窗口, 但是通过实验得知, 它没有父窗口, 没有父窗口的窗口我们叫做顶级窗口, 我们平时说的窗口, 都是指的顶级窗口;
句柄: Handle, 这个"句柄"绝对是IT界的神翻译, 谁知道句柄是个什么意思?! 句柄是一种特殊的指针, 指向的是内存里的对象, 通俗得讲它就是一个窗口(事实上远不止窗口)的把手, 你有了这个句柄就能开窗关窗, 改变窗口的状态, 这样的形容虽然不贴切, 但足够生动了吧?
改变窗口的状态? 对了, 只要我们获得顶级窗口 的 句柄 ,改变它的状态, 把"不置顶"改为"置顶", 就达成目的了.
梳理逻辑:
自己做的工具不需要考虑太多, 而且要尽量简单易用, 实现上述的功能只需要几个API(Application Programmng Interface自行百度), 甚至连窗口都不需要, 所以决定用C语言.
流程如下: 1.获得顶级窗口的句柄 , 2.改变它的状态.
哪个窗口呢? 你需要指定一个窗口, 怎么指定?
能想到最好的方案是用鼠标指定, 你鼠标放在哪一个窗口, 就是哪一个窗口;
有函数GetCursorPos(), 能够取得鼠标所在的点;
又有函数WindowsFromPoint(),
取得在某点的窗口的句柄;
注意, 取得的是窗口的句柄, 要怎么的得到顶级窗口的句柄呢? 不停地找这个窗口的父窗口, 直到某个窗口的父窗口的句柄为0(不存在), 那就找到了,
有函数GetParent(), 能取得窗口的父窗口.
取得顶级窗口的句柄后, 有函数SetWindowPos, 指定参数HWND, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_DRAWFRAME | SWP_NOSIZE 就能置顶一个窗口.
废话了那么多, 其实核心代码只有6句,加了些修饰如下:
HWND GetHwnd()
{
POINT p;
HWND hwd;
GetCursorPos(&p);
hwd = WindowFromPoint(p);
while (GetParent(hwd))
hwd = GetParent(hwd);
return hwd;
}
SetWindowPos(GetHwnd(),HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_DRAWFRAME | SWP_NOSIZE);
另, 以上函数都包含在Windows.h中, 创建没有窗体的C语言工程, 可以新建Win32工程然后删去所有代码, 使用普通的Main函数即可.
如何使用:
这个程序执行的时候把当前鼠标所在的窗口置顶之后便退出, 因此我们可以把这个程序放在win + R 特地目录下, 给它一个简单的名字, 这样就能快速调用了.
完整代码:
#include <windows.h>
#include <string.h>
HWND GetHwnd()
{
POINT p;
HWND hwd;
GetCursorPos(&p);
hwd = WindowFromPoint(p);
while (GetParent(hwd))
hwd = GetParent(hwd);
return hwd;
}
int main(int argc, char* args[])
{
if (argc < 2)
{
SetWindowPos(GetHwnd(),HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_DRAWFRAME | SWP_NOSIZE);
return 0;
}
else
{
if (!strcmp("/?", args[1]))
{
MessageBox(0,
"Availableparameters:\n/?\n/no param: stay on top.\nother param: cancel\n\n 2014.2.21 LastAvenger",
"Help",
MB_OK
);
}
else
SetWindowPos(GetHwnd(),HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_DRAWFRAME | SWP_NOSIZE);
}
}
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)