📄 appbar.cpp
字号:
// AppBar.cpp: implementation of the CAppBar class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "AppBar.h"
#include <windowsx.h>
#include "utility.h"
#include "defines.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CAppBar::CAppBar(HWND hWnd)
{
m_hWnd = hWnd;
m_bAppRegistered = FALSE;
m_pOptions = new OPTIONS;
ASSERT (m_pOptions);
}
CAppBar::~CAppBar()
{
if (m_pOptions)
{
delete m_pOptions;
m_pOptions = NULL;
}
}
//
// AppBar_Size -- Handles updating the appbar's size and position.
//
void CAppBar::Size()
{
RECT rc;
APPBARDATA abd;
POPTIONS pOpt;
if (m_bAppRegistered)
{
pOpt = GetAppbarData ();
abd.cbSize = sizeof(APPBARDATA);
abd.hWnd = m_hWnd;
GetWindowRect (m_hWnd, &rc);
QuerySetPos (pOpt->uSide, &rc, &abd, TRUE);
}
}
//
// QueryPos -- Asks the system if the AppBar can occupy the rectangle specified
// -- in lprc. The system will change the lprc rectangle to make
// -- it a valid rectangle on the desktop.
//
void CAppBar::QueryPos(LPRECT lprc)
{
POPTIONS pOpt;
pOpt = GetAppbarData ();
APPBARDATA abd;
int iWidth = 0;
int iHeight = 0;
// Fill out the APPBARDATA struct and save the edge we're moving to
// in the appbar OPTIONS struct.
abd.hWnd = m_hWnd;
abd.cbSize = sizeof(APPBARDATA);
abd.rc = *lprc;
abd.uEdge = pOpt->uSide;
// Calculate the part we want to occupy. We only figure out the top
// and bottom coordinates if we're on the top or bottom of the screen.
// Likewise for the left and right. We will always try to occupy the
// full height or width of the screen edge.
if ((ABE_LEFT == abd.uEdge) || (ABE_RIGHT == abd.uEdge))
{
iWidth = pOpt->cxWidth;
abd.rc.top = 0;
abd.rc.bottom = GetSystemMetrics(SM_CYSCREEN);
}
else
{
iHeight = pOpt->cyHeight;
abd.rc.left = 0;
abd.rc.right = GetSystemMetrics(SM_CXSCREEN);
}
// Ask the system for the screen space
SHAppBarMessage(ABM_QUERYPOS, &abd);
// The system will return an approved position along the edge we're asking
// for. However, if we can't get the exact position requested, the system
// only updates the edge that's incorrect. For example, if we want to
// attach to the bottom of the screen and the taskbar is already there,
// we'll pass in a rect like 0, 964, 1280, 1024 and the system will return
// 0, 964, 1280, 996. Since the appbar has to be above the taskbar, the
// bottom of the rect was adjusted to 996. We need to adjust the opposite
// edge of the rectangle to preserve the height we want.
switch (abd.uEdge)
{
case ABE_LEFT:
abd.rc.right = abd.rc.left + iWidth;
break;
case ABE_RIGHT:
abd.rc.left = abd.rc.right - iWidth;
break;
case ABE_TOP:
abd.rc.bottom = abd.rc.top + iHeight;
break;
case ABE_BOTTOM:
abd.rc.top = abd.rc.bottom - iHeight;
break;
}
*lprc = abd.rc;
}
//
// QuerySetPos -- Asks the system if the appbar can move itself to a particular
// -- side of the screen and then does move the appbar.
//
void CAppBar::QuerySetPos(UINT uEdge, LPRECT lprc, PAPPBARDATA pabd, BOOL bMove)
{
int iHeight = 0;
int iWidth = 0;
POPTIONS pOpt = GetAppbarData();
// Fill out the APPBARDATA struct and save the edge we're moving to
// in the appbar OPTIONS struct.
pabd->rc = *lprc;
pabd->uEdge = uEdge;
pOpt->uSide = uEdge;
QueryPos(&(pabd->rc));
// Tell the system we're moving to this new approved position.
SHAppBarMessage(ABM_SETPOS, pabd);
if (bMove)
{
// Move the appbar window to the new position
MoveWindow(m_hWnd, pabd->rc.left, pabd->rc.top,
pabd->rc.right - pabd->rc.left,
pabd->rc.bottom - pabd->rc.top, TRUE);
}
// Save the appbar rect. We use this later when we autohide. If we're
// currently hidden, then don't mess with this.
if (!pOpt->fAutoHide)
{
m_rcAppBar = pabd->rc;
}
}
//
// PosChanged -- The system has changed our position for some reason. We need
// -- to recalculate the position on the screen we want to occupy
// -- by determining how wide or thick we are and the update the
// -- screen position.
//
void CAppBar::PosChanged (PAPPBARDATA pabd)
{
RECT rc;
RECT rcWindow;
int iHeight;
int iWidth;
POPTIONS pOpt = GetAppbarData ();
// Start by getting the size of the screen.
rc.top = 0;
rc.left = 0;
rc.right = GetSystemMetrics(SM_CXSCREEN);
rc.bottom = GetSystemMetrics(SM_CYSCREEN);
// Update the m_rcAppBar so when we slide (if hidden) we slide to the
// right place.
if (pOpt->fAutoHide)
{
m_rcAppBar = rc;
switch (pOpt->uSide)
{
case ABE_TOP:
m_rcAppBar.bottom = m_rcAppBar.top + m_dwHeight;
break;
case ABE_BOTTOM:
m_rcAppBar.top = m_rcAppBar.bottom - m_dwHeight;
break;
case ABE_LEFT:
m_rcAppBar.right = m_rcAppBar.left + m_dwWidth;
break;
case ABE_RIGHT:
m_rcAppBar.left = m_rcAppBar.right - m_dwWidth;
break;
}
}
// Now get the current window rectangle and find the height and width
GetWindowRect(pabd->hWnd, &rcWindow);
iHeight = rcWindow.bottom - rcWindow.top;
iWidth = rcWindow.right - rcWindow.left;
// Depending on which side we're on, try to preserve the thickness of
// the window
switch (pOpt->uSide)
{
case ABE_TOP:
rc.bottom = rc.top + iHeight;
break;
case ABE_BOTTOM:
rc.top = rc.bottom - iHeight;
break;
case ABE_LEFT:
rc.right = rc.left + iWidth;
break;
case ABE_RIGHT:
rc.left = rc.right - iWidth;
break;
}
// Move the appbar.
QuerySetPos (pOpt->uSide, &rc, pabd, TRUE);
}
void CAppBar::AppBarCallback (UINT uMsg, WPARAM wParam, LPARAM lParam)
{
APPBARDATA abd;
static HWND hwndZOrder = NULL;
POPTIONS pOpt = GetAppbarData ();
abd.cbSize = sizeof(abd);
abd.hWnd = m_hWnd;
switch (wParam)
{
// Notifies the appbar that the taskbar's autohide or always-on-top
// state has changed. The appbar can use this to conform to the settings
// of the system taskbar.
case ABN_STATECHANGE:
break;
// Notifies the appbar when a full screen application is opening or
// closing. When a full screen app is opening, the appbar must drop
// to the bottom of the Z-Order. When the app is closing, we should
// restore our Z-order position.
case ABN_FULLSCREENAPP:
if (lParam)
{
// A full screen app is opening. Move us to the bottom of the
// Z-Order.
// First get the window that we're underneath so we can correctly
// restore our position
hwndZOrder = GetWindow (m_hWnd, GW_HWNDPREV);
// Now move ourselves to the bottom of the Z-Order
SetWindowPos(m_hWnd, HWND_BOTTOM, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
}
else
{
// The app is closing. Restore the Z-order
SetWindowPos(m_hWnd, pOpt->fOnTop ? HWND_TOPMOST : hwndZOrder,
0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
hwndZOrder = NULL;
}
break;
// Notifies the appbar when an event has occured that may effect the
// appbar's size and position. These events include changes in the
// taskbar's size, position, and visiblity as well as adding, removing,
// or resizing another appbar on the same side of the screen.
case ABN_POSCHANGED:
// Update our position in response to the system change
PosChanged (&abd);
break;
}
}
//
// Register -- Registers the appbar with the system.
//
BOOL CAppBar::Register()
{
APPBARDATA abd;
abd.cbSize = sizeof(APPBARDATA);
abd.hWnd = m_hWnd;
abd.uCallbackMessage = APPBAR_CALLBACK;
m_bAppRegistered = SHAppBarMessage (ABM_NEW, &abd);
return m_bAppRegistered;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -