首页
社区
课程
招聘
[原创]让任意窗口快速置顶
发表于: 2014-8-11 22:47 19390

[原创]让任意窗口快速置顶

2014-8-11 22:47
19390
近来心境不好, 什么东西都学不下, 每天偶尔点开论坛总没耐心看那些好的帖子, 自觉惭愧, 来发个帖聊以自慰罢.
   内容很基础, 都是几年前玩剩下的, 比较可笑的是, 自己和几年前想比, 也没什么进步, 大家见笑.

      要把窗口置顶, 稍有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期)

收藏
免费 0
支持
分享
最新回复 (10)
雪    币: 135
活跃值: (63)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
2
不错支持一下,窗口的一堆概念至今理解不清楚,焦点,活动,还有z序那些,感觉真难理解,看了老是忘记。
2014-8-11 23:49
0
雪    币: 118
活跃值: (72)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
3
深入浅出好文章
2014-8-12 07:57
0
雪    币: 16451
活跃值: (1715)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
支持夏啦
2014-8-12 09:01
0
雪    币: 102
活跃值: (31)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
5
浅出但不深入...
2014-8-12 10:19
0
雪    币: 102
活跃值: (31)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
6
感谢支持.
2014-8-12 10:21
0
雪    币: 174
活跃值: (620)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
7
循环GetParent不一定对,一般情况下是对的,但你看看如果是对话框程序,它也是有父窗口的,只不过是桌面而已,其它程序也有类似的现象
建议你检查窗口是不是子窗口,再GetParent,以保证正确
2014-8-14 09:55
0
雪    币: 102
活跃值: (31)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
8
感谢赐教.
2014-8-14 19:22
0
雪    币: 102
活跃值: (31)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
9
请问怎么判断他是否为子窗体呢?
2014-8-14 19:29
0
雪    币: 1037
活跃值: (117)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
一般说的子窗口是有WS_CHILD属性的,
给几个链接
http://blog.sina.com.cn/s/blog_48f93b530100eamd.html
http://www.cnblogs.com/cswuyg/archive/2012/07/09/2582186.html
2014-8-15 15:39
0
雪    币: 1
活跃值: (111)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
多谢楼主分享
2015-3-11 15:20
0
游客
登录 | 注册 方可回帖
返回
//