TopWnd一键置顶窗口的实现,分享源码

TopWnd为一款精小实用的绿色软件,可以置顶大部分的窗口,一键置顶,一键取消!

贴上下载地址:

我一直都在实用这个小工具,今日好奇,决定一探其内部究竟如何实现。

网上搜索一番,没有找到这个小工具的源码。

无奈只好一步步的自己去实现它。



最终用MFC+全局钩子成功模仿了一个相差无几的程序。


  1. 准备工作

    • visual studio 2012
    • 建MFC工程
    • 拖几个控件
    • 参考文章:http://blog.csdn.net/friendan/article/details/12168273
  2. 全局钩子
    • 源码目录下有,MouseHook.dll
    • 在dll程序中,自定义一个消息,如下所示:
      • #define WM_MYMSG WM_USER + 305 //自定义消息,用于和主程序通信
    • 在钩子安装函数中,保存主程序的窗口句柄,代码如下:
      • BOOL WINAPI StartHookMouse(HWND hWnd)
        {
            g_hWnd=hWnd;
            hhkMouse=::SetWindowsHookEx(WH_MOUSE_LL,LowLevelMouseProc,g_hInstDll,0);
            if (hhkMouse==NULL)
            {
                return FALSE;
            }
            else
            {
                return TRUE;
            }
        }  
    • 在鼠标钩子响应函数中,我们将捕获到的消息,发送给主程序,代码如下:
      • LRESULT CALLBACK LowLevelMouseProc(
                                   int nCode,      // hook code
                                   WPARAM wParam,  // message identifier
                                   LPARAM lParam   // mouse coordinates
                                   )
        {  
        
            //有鼠标消息时,将其发给主程序
            if (g_hWnd!=NULL&&nCode==HC_ACTION)
            {
                ::SendMessage(g_hWnd,WM_MYMSG,wParam,lParam);
            }
            return CallNextHookEx(hhkMouse,nCode,wParam,lParam);
        }  
  3. 处理主程序与钩子DLL的通信
    • 在主程序头文件定义一个消息与dll定义的一样

      • #define WM_MYMSG WM_USER + 305
    • 在头文件中声明消息处理函数
      • afx_msg LRESULT OnMyMsg(WPARAM wParam,LPARAM lParam);
    • 在主文件中写消息映射
      • ON_MESSAGE(WM_MYMSG,OnMyMsg)
    • 实现消息处理函数,在函数内实现置顶与恢复功能
      • LRESULT CHookMouseTestDlg::OnMyMsg(WPARAM wParam,LPARAM lParam){}
  4. 主程序实现控制
    • 打开与dll的连接函数

      •  1     //加载钩子DLL
         2     g_hInstDll=LoadLibrary(_T("MouseHook.dll"));
         3     if(g_hInstDll==NULL)
         4     {
         5         AfxMessageBox(_T("no MouseHook.dll"));
         6         return;
         7     }
         8
         9     typedef BOOL (CALLBACK *StartHookMouse)(HWND hWnd);
        10     StartHookMouse StartHook;
        11
        12     StartHook=(StartHookMouse)::GetProcAddress(g_hInstDll,"StartHookMouse");
        13     if(StartHook==NULL)
        14     {
        15         AfxMessageBox(_T("func StartHookMouse not found!"));
        16         return;
        17     }
        18
        19     //将本程序的句柄传给 钩子DLL,用来通信
        20     if (StartHook(this->m_hWnd))
        21     {
        22         SetDlgItemText(IDC_STATE,STATE1);
        23     }
        24     else
        25     {
        26         SetDlgItemText(IDC_STATE,STATE2);
        27     }
    • 关闭与dll的连接函数
      • typedef VOID (CALLBACK *StopHookMouse)();
            StopHookMouse StopHook;
        
            g_hInstDll = LoadLibrary(_T("MouseHook.dll"));
            StopHook = (StopHookMouse)::GetProcAddress(g_hInstDll,"StopHookMouse");
            if( StopHook == NULL ){
                SetDlgItemText(IDC_STATE,STATE2);
            }
            StopHook();
            if(g_hInstDll != NULL){
                ::FreeLibrary(g_hInstDll);
            }
    • 置顶按钮,恢复按钮
      • 调用打开dll函数
      • 改变BOOL变量openORclose使OnMyMsg函数分别处理置顶还是恢复
      •  1 //启动置顶
         2 BOOL openORclose = FALSE;
         3 void CTopWndDlg::OnBnClickedOpen()
         4 {
         5     OpenHook();
         6     GetDlgItem(ID_OPEN)->EnableWindow(FALSE);
         7     openORclose = TRUE;
         8 }
         9
        10 //恢复置顶
        11 void CTopWndDlg::OnBnClickedClose()
        12 {
        13     OpenHook();
        14     GetDlgItem(ID_CLOSE)->EnableWindow(FALSE);
        15     openORclose = FALSE;
        16 }
    • 在消息处理函数中真正实现功能
      • 判断收到的鼠标事件是否是点击
      • 找到点击时鼠标所在的程序的句柄
      • 调用SetWindowPos函数使窗口置顶。参数1:目标程序窗口的句柄,参数2:(HWND_TOPMOST)置顶的参数,参数7:不改变窗口大小与位置
      • 处理结束,关闭与dll的连接
      •  1 //处理来钩子的信息,置顶与恢复的实现
         2 LRESULT CTopWndDlg::OnMyMsg(WPARAM wParam,LPARAM lParam){
         3     CString str;
         4     static PMSLLHOOKSTRUCT mouseHookStruct;
         5     mouseHookStruct = (PMSLLHOOKSTRUCT)lParam;
         6     if( wParam == WM_LBUTTONDOWN){
         7         HWND hWnd=::WindowFromPoint(mouseHookStruct->pt);
         8         TCHAR title[MAX_PATH];
         9         ::GetWindowText(hWnd,title,MAX_PATH);
        10         if(openORclose){
        11             // HWND_TOPMOST 窗口置顶  SWP_NOMOVE | SWP_NOSIZE 不改变窗口大小和位置
        12             ::SetWindowPos( hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE );
        13             GetDlgItem(ID_OPEN)->EnableWindow(TRUE);
        14             str.Format(_T("%s %s"),STATE3,title);
        15             SetDlgItemText(IDC_STATE, str);
        16         }
        17         else{
        18             ::SetWindowPos( hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE );
        19             GetDlgItem(ID_CLOSE)->EnableWindow(TRUE);
        20             str.Format(_T("%s %s"),STATE4,title);
        21             SetDlgItemText(IDC_STATE,str);
        22         }
        23         CloseHook();
        24     }
        25     return 1;
        26 }
  5. 源码下载地址:C++手工实现topwnd源码
  6. 谢谢观赏~
时间: 2024-12-17 22:58:47

TopWnd一键置顶窗口的实现,分享源码的相关文章

WordPress 一键置顶文章(推荐用SM Sticky Clicky Star)

在 WordPress入门 之 发布新文章和管理文章 中,倡萌已经简单提到可以在文章编辑界面或者快速编辑界面设置置顶文章,但是如果你想在后台文章列表中添加一键置顶文章的功能,不妨试试 Quick Sticky 或 SM Sticky Clicky Star 插件. Quick Sticky 和 SM Sticky Clicky Star 都是用来给后台文章列表添加一键置顶文章功能的,一个较大的不同是,SM Sticky Clicky Star 支持 Ajax 无刷新设置,而 Quick Stic

Android应用Activity、Dialog、PopWindow窗口显示机制及源码分析

[工匠若水 http://blog.csdn.net/yanbober 转载烦请注明出处,尊重劳动成果] 1 背景 之所以写这一篇博客的原因是因为之前有写过一篇<Android应用setContentView与LayoutInflater加载解析机制源码分析>,然后有人在文章下面评论和微博私信中问我关于Android应用Dialog.PopWindow.Toast加载显示机制是咋回事,所以我就写一篇文章来分析分析吧(本文以Android5.1.1 (API 22)源码为基础分析),以便大家在应

Android SNS 分享 源码地址

最近学习开放平台,官方文档和Demo有点坑爹,经过几天的努力,写了一个DEMO,整合了新浪微博和腾讯微博,均能够SSO授权.网页授权和发微博,如果需要可以去看看源码,里面有注释说明: DEMO源码地址:https://github.com/cstdr/WeiboSDKDemo 说明一下:虽然已经有很多类似的开放平台DEMO,但这个是我根据最新的SDK所完善的,最新的新浪微博SDK是6天前更新的Github,所以我这个还是有一点点价值的啦- 代码使用自己感觉舒服的方式进行封装和整合,使用前需要修改

Android应用Activity、Dialog、PopWindow、Toast窗口添加机制及源码分析

1  背景 之所以写这一篇博客的原因是因为之前有写过一篇<Android应用setContentView与LayoutInflater加载解析机制源码分析>, 然后有人在文章下面评论和微博私信中问我关于Android应用Activity.Dialog.PopWindow加载显示机制是咋回事,所以我就写一 篇文章来分析分析吧(本文以Android5.1.1 (API 22)源码为基础分析),以便大家在应用层开发时不再迷糊. PS一句:不仅有人微博私信我这个问题,还有人问博客插图这些是用啥画的,这

Android自定义ScrollView实现一键置顶功能

效果图如下: (ps:动态图有太大了,上传不了,就给大家口述一下要实现的功能吧) 要实现的功能:当ScrollView向上滑动超过一定距离后,就渐变的出现一个置顶的按钮,当滑动距离小于我们指定的距离时,按钮又消失. 实现原理:就是监听View的onScrollChanged()方法(回调方法),获取到ScrolView滑动的距离,如果大于我们的距离,则出现置顶按钮,否则,直接隐藏,且当按钮出现点击事件,让整个ScrollView滑动到(0,0)位置即可,不废话,直接上代码 自定义的ScrollV

【重播工具箱】MTK全方案手机端APP,一键备份自动生成线刷包 源码思路解析

这个是本人MTK工具箱,在 5月份的时候,发布的..功能可能说是全球首发把,第一个手机MTK的一键备份工具,而且是兼容MTK全方案.MTK6589 MTK6592 6575 82等, 现在将源码以及思路,分享给大家,有兴趣的可以看看. 源码解析以及思路,待发布....... 分享地址:http://www.592zn.com/thread-311286-1-1.html 下载地址http://pan.baidu.com/s/1hqeethy重大更新: 1.手机端首发,备份MTK系列全自动,生成线

如何在Exe和BPL插件中实现公共变量共享及窗口溶入技术Demo源码

1.Delphi编译方式介绍: 当我们在开发一个常规应用程序时,Delphi可以让我们用两种方式使用VCL,一种是把VCL中的申明单元及实现单元全部以静态编译的方式编译并链接进Exe可执行文件中,这样做的好处就是发布程序时只需要发布独立的可执行文件,当我们使用了的第三方DLL.OCX等时,无需发布*.bpl等文件,但EXE程序文件的体积会较大. 另外一种是把VCL库以运行时状态(即把VCL库中的申请单元静态编译进EXE可执行文件,而单元的实行方法则通过LoadLiabary/LoadPackag

使用jquery实现简单的拖动效果,分享源码

因为想实现相框的拖到,找了半天的原因愣是没有找到错误,所以,只能翻看源码了 如何实现拖动效果? 浏览DEMO 首先分析下拖动效果原理: 1.当鼠标在被拖动对象上按下鼠标(触发onmousedown事件,且鼠标在对象上方) 2.开始移动鼠标(触发onmousemove事件) 3.移动时更显对象的top和left值 4.鼠标放开停止拖动(触发onmouseup事件) 注意:拖动的对象必须是定位对象(即设置了position:absolute或 relative). 也就是说拖动事件=onmoused

基于Cython和内置distutils库,实现python源码加密(非混淆模式)

起因 python本身只能做混淆,不能加密,多年的商业软件开发经验导致有某种"洁癖"欲望,将py编译打包 尝试 pyinstaller原理是freeze打包pyc文件,利用工具可完美逆行出源码 各种混淆脚本,版本兼容很差,配置繁琐 cython 常规使用只能编译单个特殊模块 解决 反复尝试摸索后,还是利用了cython和distutils库,自动化识别并转换py到c源码并编译,放出源码供大家参考 """ 利用cython和distutils编译py到pyd