首页 > 代码库 > 简单易懂的小应用StayOnTop
简单易懂的小应用StayOnTop
应用场景:
当你需要边聊天边看网页的时候, 你就不能把浏览器最大化, 或者需要看一下网页再去任务栏把聊天窗口点出来, 超麻烦不是?很多网页两边都是空白的, 如果能让聊天窗口置顶的话, 这个空间就得以利用了.但其实这又是个伪需求, 腾讯哪能没想到? 每个窗口的右上角都有一个小按钮, 随时可以让窗口置顶.
但其他软件就没得玩了, 一边看网上的Step-by-step教程, 一边来回切换窗口真是麻烦死了, 当时就萌生了花一个晚上来写它的想法.(其实这样的工具应该一大把...另Linux下的话自带置顶功能)
所以目标确定了, 我要做一个能让任意窗口置顶的小工具.
知识点:
窗口: 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函数即可.
完整代码:
#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);
}
}