首页 > 代码库 > TopWnd一键置顶窗口的实现,分享源码
TopWnd一键置顶窗口的实现,分享源码
TopWnd为一款精小实用的绿色软件,可以置顶大部分的窗口,一键置顶,一键取消!
贴上下载地址:
我一直都在实用这个小工具,今日好奇,决定一探其内部究竟如何实现。
网上搜索一番,没有找到这个小工具的源码。
无奈只好一步步的自己去实现它。
最终用MFC+全局钩子成功模仿了一个相差无几的程序。
- 准备工作
- visual studio 2012
- 建MFC工程
- 拖几个控件
- 参考文章:http://blog.csdn.net/friendan/article/details/12168273
- 全局钩子
- 源码目录下有,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); }
- 处理主程序与钩子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){}
- 在主程序头文件定义一个消息与dll定义的一样
- 主程序实现控制
- 打开与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 else25 {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 }
- 打开与dll的连接函数
- 源码下载地址:C++手工实现topwnd源码
- 谢谢观赏~
TopWnd一键置顶窗口的实现,分享源码
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。