关于如何知道有软件全屏的总结

方法一:通过检测屏幕四个角的HWND,看看他们是不是同一个窗口,但是对于一些播放器这种应用程序处于全屏的时候会出现问题,会带有一个进度条,导致四个角落所于不同的window。

BOOL IsFullModel()
{
HWND   pWnd1   =   NULL;
HWND   pWnd2   =   NULL;
HWND   pWnd3   =   NULL;
HWND   pWnd4   =   NULL;


int iCx=GetSystemMetrics(SM_CXSCREEN);
int iCy=GetSystemMetrics(SM_CYSCREEN);


POINT   pt1;
pt1.x   =   1;
pt1.y   =   1;
POINT   pt2;
pt2.x   =   1;
pt2.y   =   iCy-1;
POINT   pt3;
pt3.x   =   iCx-1;
pt3.y   =   1;
POINT   pt4;
pt4.x   =   iCx-1;
pt4.y   =   iCy-1;


pWnd1   =   WindowFromPoint(pt1);
pWnd2   =   WindowFromPoint(pt2);
pWnd3   =   WindowFromPoint(pt3);
pWnd4   =   WindowFromPoint(pt4);


if (pWnd1   ==   pWnd2   &&   pWnd2   ==   pWnd3   &&   pWnd3   ==   pWnd4)
{
return TRUE;
}
return FALSE;
}

同时这里也学习了一个函数:WindowFromPoint()通过屏幕上的点,来获取窗口的句柄。但是该方法好像很不好使用,好像只是在通过QQ的截屏功能、和IE的全屏模式才会触发,而使用QQ影音都不行。看来该方法只是一个思想,主要是的还是明白了原来还有WindowFromPoint这个函数。

方法二:获取屏幕的当前活动窗口GetActiveWindow(),但是要注意的是,当你点击的是桌面空白处的时候,我以为当前的窗口应该和GetDesktopWindow获得的句柄应该是一样的,因为当前的活动窗口就是Desktop,但是我发现他们居然是不一样的,然后使用方法GetWindowThreadProcessId来获取GetActiveWindow的进程ID,发现他居然是csrss的进程id,所以在后续的情况下,后来才知道,csrss.exe这个东西的窗口叫“Program Manager

CWnd *pWnd = GetActiveWindow();
CRect rect;
pWnd->GetWindowRect(&rect);
CString str;
str.Format("width = %d, height=%d", rect.Width(), rect.Height());
CRect fullRect;
CWnd *pFullWnd = ();
pFullWnd->GetWindowRect(fullRect);

DWORD foreProcessId;
DWORD deskProcessId;
::GetWindowThreadProcessId(pWnd->m_hWnd, &foreProcessId);
::GetWindowThreadProcessId(pFullWnd->m_hWnd, &deskProcessId);

char pName[100] ="";
pWnd->GetWindowText(pName , 100);

if (rect.Width() == fullRect.Width() && rect.Height() == fullRect.Height() && foreProcessId != deskProcessId && strcmp("Program Manager", pName) != 0)
{
MessageBox("有东西全屏了");
}”

从上面的代码可以看出,这个程序有个bug,也就是,如果由用户将自己的程序的窗口名字设置为:“Program Manager”,我们永远不知道这个窗口是不是全屏。

方法三:这个也是我最终采用的方法。

(1)在MFC的情况:

这里是一个简单的dlg窗口程序, 在

在头文件中定义

#define  UM_APPBARID WM_USER + 100

BEGIN_MESSAGE_MAP(CGetWindowFullDlg, CDialog)
ON_MESSAGE(UM_APPBARID, OnMyMessage)//添加的其中UM_APPBARID是自己定义的事件
END_MESSAGE_MAP()


下面是非常重要的:

APPBARDATA m_abd;
memset(&m_abd, 0, sizeof(APPBARDATA));  
m_abd.cbSize = sizeof(APPBARDATA);    
m_abd.hWnd = this->m_hWnd;  
m_abd.uCallbackMessage = UM_APPBARID;    
SHAppBarMessage(ABM_NEW, &m_abd); 

这个地方的作用就是安装全屏消息,这样,如果有窗口全屏的话,explorer.exe广播的消息就可以接受得到。

最后就是回调的相应函数:

ABN_FULLSCREENAPP这个东西是在这个头文件中#include "Shellapi.h"为2

LRESULT CGetWindowFullDlg::OnMyMessage(WPARAM wParam, LPARAM lParam)
{
switch (wParam)
{
case ABN_FULLSCREENAPP:
{
if (lParam == 1)
{
MessageBox("全屏");
}
if (lParam ==0)
{
// MessageBox("非全屏");
}
}
break;
}

return 0;
}

(2)Win32的情况:

使用的API: SHAppBarMessage (原型如下:)
WINSHELLAPI UINT APIENTRY SHAppBarMessage( DWORD dwMessage, PAPPBARDATA pData);
  这个API可以向系统发送一个appbar message(也就是dwMessage,有很多消息,可以查阅MSDN),然后系统通过pData返回你想知道的信息,这里我们主要用这个API来注册一个新的appbar。这里还需要关注的是APPBARDATA这个结构体。

检测全屏的具体实现代码如下:
APPBARDATA abd;
memset(&abd, 0, sizeof(abd));
// Specify the structure size and handle to the appbar.
abd.cbSize = sizeof(APPBARDATA);
abd.hWnd = hwnd; // 这里的hwnd 是你要进行消息处理的窗体wnd
abd.uCallbackMessage = MSG_APPBAR_MSGID;
!::SHAppBarMessage(ABM_NEW, &abd);

  注意MSG_APPBAR_MSGID这个,这是你自己定义的消息ID,当有全屏创建或者取消的时候,会给句柄为hwndAccessBar的窗口发送消息ID为MSG_APPBAR_MSGID的消息,具体到全屏消息,此时WPARAM为ABN_FULLSCREENAPP,而LPARAM则能够判断当前是有窗口全屏了还是有窗口取消全屏了,(BOOL) lParam为TRUE表示有窗口全屏了,而(BOOL) lParam为FALSE则表示有窗口取消全屏状态了。代码如下:

LRESULT WindowProc(UINT msg, WPARAM wp, LPARAM lp)
{
if (MSG_APPBAR_MSGID == msg)
{
switch((UINT)wp)
{
case ABN_FULLSCREENAPP:
{
if (TRUE == (BOOL)lp)
{
TRACE(TEXT("一个窗口全屏了\n"));

}
else
{
TRACE(TEXT("一个窗口取消全屏了\n"));

}
}
break;
default:
break;
}
}
return CSubclassWnd::WindowProc(msg, wp, lp);

}

上面给出的是怎么装载添加这样的shell监听,如何卸载呢?

下面是装载的:

APPBARDATA m_abd;
memset(&m_abd, 0, sizeof(APPBARDATA));
m_abd.cbSize = sizeof(APPBARDATA);
m_abd.hWnd = this->m_hWnd;
m_abd.uCallbackMessage = UM_APPBARID;
SHAppBarMessage(ABM_NEW, &m_abd);
卸载的是这样的:

APPBARDATA abd;
 memset(&abd, 0, sizeof(abd));
 // Specify the structure size and handle to the appbar.
 abd.cbSize = sizeof(APPBARDATA);
 abd.hWnd = GetHWND();
 abd.uCallbackMessage = MSG_APPBAR_MSGID;
 ::SHAppBarMessage(ABM_REMOVE, &abd);//其实就是第一个参数从ABM_NEW改为ABM_REMOVE而已,实现卸载的功能

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值