📄 taskbarnotifier.cpp
字号:
m_nCurrentPosX=rcTaskbar.left;
m_nCurrentPosY=rcTaskbar.bottom-m_nBitmapHeight;
m_nCurrentWidth=0;
m_nCurrentHeight=m_nBitmapHeight;
}
else if (m_nTaskbarPlacement==ABE_LEFT)
{
m_nCurrentPosX=rcTaskbar.right;
m_nCurrentPosY=rcTaskbar.bottom-m_nBitmapHeight;
m_nCurrentWidth=0;
m_nCurrentHeight=m_nBitmapHeight;
}
else if (m_nTaskbarPlacement==ABE_TOP)
{
m_nCurrentPosX=rcTaskbar.right-m_nBitmapWidth;
m_nCurrentPosY=rcTaskbar.bottom;
m_nCurrentWidth=m_nBitmapWidth;
m_nCurrentHeight=0;
}
else //if (m_nTaskbarPlacement==ABE_BOTTOM)
{
// Taskbar is on the bottom or Invisible
m_nCurrentPosX=rcTaskbar.right-m_nBitmapWidth;
m_nCurrentPosY=rcTaskbar.top;
m_nCurrentWidth=m_nBitmapWidth;
m_nCurrentHeight=0;
}
ShowWindow(SW_SHOWNOACTIVATE);
SetTimer(IDT_APPEARING,m_dwShowEvents,NULL);
break;
case IDT_APPEARING:
RedrawWindow();
break;
case IDT_WAITING:
RedrawWindow();
KillTimer(IDT_WAITING);
SetTimer(IDT_WAITING,m_dwTimeToStay,NULL);
break;
case IDT_DISAPPEARING:
KillTimer(IDT_DISAPPEARING);
SetTimer(IDT_WAITING,m_dwTimeToStay,NULL);
if (m_nTaskbarPlacement==ABE_RIGHT)
{
m_nCurrentPosX=rcTaskbar.left-m_nBitmapWidth;
m_nCurrentWidth=m_nBitmapWidth;
}
else if (m_nTaskbarPlacement==ABE_LEFT)
{
m_nCurrentPosX=rcTaskbar.right;
m_nCurrentWidth=m_nBitmapWidth;
}
else if (m_nTaskbarPlacement==ABE_TOP)
{
m_nCurrentPosY=rcTaskbar.bottom;
m_nCurrentHeight=m_nBitmapHeight;
}
else //if (m_nTaskbarPlacement==ABE_BOTTOM)
{
m_nCurrentPosY=rcTaskbar.top-m_nBitmapHeight;
m_nCurrentHeight=m_nBitmapHeight;
}
SetWindowPos(&wndTopMost,m_nCurrentPosX,m_nCurrentPosY,m_nCurrentWidth,m_nCurrentHeight,SWP_NOACTIVATE);
RedrawWindow();
break;
}
}
void CTaskbarNotifier::Hide()
{
switch (m_nAnimStatus)
{
case IDT_APPEARING:
KillTimer(IDT_APPEARING);
break;
case IDT_WAITING:
KillTimer(IDT_WAITING);
break;
case IDT_DISAPPEARING:
KillTimer(IDT_DISAPPEARING);
break;
}
MoveWindow(0,0,0,0);
ShowWindow(SW_HIDE);
m_nAnimStatus=IDT_HIDDEN;
m_nActiveMessageType=TBN_NULL; //<<--enkeyDEV(kei-kun) -TaskbarNotifier-
}
HRGN CTaskbarNotifier::CreateRgnFromBitmap(HBITMAP hBmp, COLORREF color)
{
// this code is written by Davide Pizzolato
if (!hBmp)
return NULL;
CDC* pDC = GetDC();
if (!pDC)
return NULL;
BITMAP bm;
GetObject( hBmp, sizeof(BITMAP), &bm ); // get bitmap attributes
CDC dcBmp;
dcBmp.CreateCompatibleDC(pDC); //Creates a memory device context for the bitmap
HGDIOBJ hOldBmp = dcBmp.SelectObject(hBmp); //selects the bitmap in the device context
const DWORD RDHDR = sizeof(RGNDATAHEADER);
const DWORD MAXBUF = 40; // size of one block in RECTs
// (i.e. MAXBUF*sizeof(RECT) in bytes)
LPRECT pRects;
DWORD cBlocks = 0; // number of allocated blocks
INT i, j; // current position in mask image
INT first = 0; // left position of current scan line
// where mask was found
bool wasfirst = false; // set when if mask was found in current scan line
bool ismask; // set when current color is mask color
// allocate memory for region data
RGNDATAHEADER* pRgnData = (RGNDATAHEADER*)new BYTE[ RDHDR + ++cBlocks * MAXBUF * sizeof(RECT) ];
memset( pRgnData, 0, RDHDR + cBlocks * MAXBUF * sizeof(RECT) );
// fill it by default
pRgnData->dwSize = RDHDR;
pRgnData->iType = RDH_RECTANGLES;
pRgnData->nCount = 0;
for ( i = 0; i < bm.bmHeight; i++ )
for ( j = 0; j < bm.bmWidth; j++ ){
// get color
ismask=(dcBmp.GetPixel(j,bm.bmHeight-i-1)!=color);
// place part of scan line as RECT region if transparent color found after mask color or
// mask color found at the end of mask image
if (wasfirst && ((ismask && (j==(bm.bmWidth-1)))||(ismask ^ (j<bm.bmWidth)))){
// get offset to RECT array if RGNDATA buffer
pRects = (LPRECT)((LPBYTE)pRgnData + RDHDR);
// save current RECT
pRects[ pRgnData->nCount++ ] = CRect( first, bm.bmHeight - i - 1, j+(j==(bm.bmWidth-1)), bm.bmHeight - i );
// if buffer full reallocate it
if ( pRgnData->nCount >= cBlocks * MAXBUF ){
LPBYTE pRgnDataNew = new BYTE[ RDHDR + ++cBlocks * MAXBUF * sizeof(RECT) ];
memcpy( pRgnDataNew, pRgnData, RDHDR + (cBlocks - 1) * MAXBUF * sizeof(RECT) );
delete pRgnData;
pRgnData = (RGNDATAHEADER*)pRgnDataNew;
}
wasfirst = false;
} else if ( !wasfirst && ismask ){ // set wasfirst when mask is found
first = j;
wasfirst = true;
}
}
dcBmp.SelectObject(hOldBmp);
dcBmp.DeleteDC(); //release the bitmap
// create region
/* Under WinNT the ExtCreateRegion returns NULL (by Fable@aramszu.net) */
// HRGN hRgn = ExtCreateRegion( NULL, RDHDR + pRgnData->nCount * sizeof(RECT), (LPRGNDATA)pRgnData );
/* ExtCreateRegion replacement { */
HRGN hRgn=CreateRectRgn(0, 0, 0, 0);
ASSERT( hRgn!=NULL );
pRects = (LPRECT)((LPBYTE)pRgnData + RDHDR);
for(i=0;i<(int)pRgnData->nCount;i++)
{
HRGN hr=CreateRectRgn(pRects[i].left, pRects[i].top, pRects[i].right, pRects[i].bottom);
VERIFY(CombineRgn(hRgn, hRgn, hr, RGN_OR)!=ERROR);
if (hr) DeleteObject(hr);
}
ASSERT( hRgn!=NULL );
/* } ExtCreateRegion replacement */
delete pRgnData;
ReleaseDC(pDC);
return hRgn;
}
//START - enkeyDEV(kei-kun) -TaskbarNotifier-
int CTaskbarNotifier::GetMessageType() {
//return m_nMessageTypeClicked;
return m_nActiveMessageType;
}
BEGIN_MESSAGE_MAP(CTaskbarNotifier, CWnd)
ON_WM_MOUSEMOVE()
ON_WM_LBUTTONUP()
ON_MESSAGE(WM_MOUSEHOVER, OnMouseHover)
ON_MESSAGE(WM_MOUSELEAVE, OnMouseLeave)
ON_WM_ERASEBKGND()
ON_WM_PAINT()
ON_WM_SETCURSOR()
ON_WM_TIMER()
END_MESSAGE_MAP()
// CTaskbarNotifier message handlers
void CTaskbarNotifier::OnMouseMove(UINT nFlags, CPoint point)
{
TRACKMOUSEEVENT t_MouseEvent;
t_MouseEvent.cbSize = sizeof(TRACKMOUSEEVENT);
t_MouseEvent.dwFlags = TME_LEAVE | TME_HOVER;
t_MouseEvent.hwndTrack = m_hWnd;
t_MouseEvent.dwHoverTime = 1;
// We Tell Windows we want to receive WM_MOUSEHOVER and WM_MOUSELEAVE
::_TrackMouseEvent(&t_MouseEvent);
CWnd::OnMouseMove(nFlags, point);
}
void CTaskbarNotifier::OnLButtonUp(UINT nFlags, CPoint point)
{
CTaskbarNotifierHistory* messagePTR;
// close button clicked
if (m_rcCloseBtn.PtInRect(point)) {
m_bAutoClose=TRUE; // set true so next time arrive an autoclose event the popup will autoclose
// (when m_bAutoClose is false a "true" event will be ignored until the user
// manually close the windows)
switch (m_nAnimStatus)
{
case IDT_APPEARING:
KillTimer(IDT_APPEARING);
break;
case IDT_WAITING:
KillTimer(IDT_WAITING);
break;
case IDT_DISAPPEARING:
KillTimer(IDT_DISAPPEARING);
break;
}
m_nAnimStatus=IDT_DISAPPEARING;
SetTimer(IDT_DISAPPEARING,m_dwHideEvents,NULL);
//Hide();
}
// cycle history button clicked
if (m_rcHistoryBtn.PtInRect(point)) {
if (m_MessageHistory.GetCount() > 0) {
messagePTR = (CTaskbarNotifierHistory*) m_MessageHistory.RemoveHead();
Show(messagePTR->m_strMessage, messagePTR->m_nMessageType);
delete messagePTR;
}
}
// message clicked
if (m_rcText.PtInRect(point)) {
// Notify the parent window that the Notifier popup was clicked
m_pWndParent->PostMessage(WM_TASKBARNOTIFIERCLICKED,0,0);
}
CWnd::OnLButtonUp(nFlags, point);
}
LRESULT CTaskbarNotifier::OnMouseHover(WPARAM w, LPARAM l)
{
if (m_nAnimStatus == IDT_WAITING) //<<--enkeyDEV(kei-kun) -TaskbarNotifier-
KillTimer(IDT_WAITING);
POINTS mp;
mp = MAKEPOINTS(l);
m_ptMousePosition.x = mp.x;
m_ptMousePosition.y = mp.y;
if (m_bMouseIsOver==FALSE)
{
m_bMouseIsOver=TRUE;
RedrawWindow();
}
else
if ((m_ptMousePosition.x >= m_rcText.left) && (m_ptMousePosition.x <= m_rcText.right)
&& (m_ptMousePosition.y >= m_rcText.top) && (m_ptMousePosition.y <= m_rcText.bottom)) {
if (!m_bTextSelected)
RedrawWindow();
}
else {
if (m_bTextSelected)
RedrawWindow();
}
return 0;
}
LRESULT CTaskbarNotifier::OnMouseLeave(WPARAM w, LPARAM l)
{
if (m_bMouseIsOver==TRUE)
{
m_bMouseIsOver=FALSE;
RedrawWindow();
//START - enkeyDEV(kei-kun) -TaskbarNotifier-
if (m_nAnimStatus==IDT_WAITING)
SetTimer(IDT_WAITING,m_dwTimeToStay,NULL);
//END - enkeyDEV(kei-kun) -TaskbarNotifier-
}
return 0;
}
BOOL CTaskbarNotifier::OnEraseBkgnd(CDC* pDC)
{
CDC memDC;
CBitmap *pOldBitmap;
memDC.CreateCompatibleDC(pDC);
pOldBitmap=memDC.SelectObject(&m_bitmapBackground);
pDC->BitBlt(0,0,m_nCurrentWidth,m_nCurrentHeight,&memDC,0,0,SRCCOPY);
memDC.SelectObject(pOldBitmap);
return TRUE;
}
void CTaskbarNotifier::OnPaint()
{
CPaintDC dc(this);
CFont *pOldFont;
TCHAR *szBuffer;
if (m_bMouseIsOver)
{
if ((m_ptMousePosition.x >= m_rcText.left) && (m_ptMousePosition.x <= m_rcText.right)
&& (m_ptMousePosition.y >= m_rcText.top) && (m_ptMousePosition.y <= m_rcText.bottom)) {
m_bTextSelected = TRUE;
dc.SetTextColor(m_crSelectedTextColor);
pOldFont=dc.SelectObject(&m_mySelectedFont);
}
else {
m_bTextSelected = FALSE;
dc.SetTextColor(m_crNormalTextColor);
pOldFont=dc.SelectObject(&m_myNormalFont);
}
}
else
{
dc.SetTextColor(m_crNormalTextColor);
pOldFont=dc.SelectObject(&m_myNormalFont);
}
szBuffer=new TCHAR[m_strCaption.GetLength()+10];
_tcscpy(szBuffer,m_strCaption);
dc.SetBkMode(TRANSPARENT);
dc.DrawText(szBuffer,-1,m_rcText,m_uTextFormat);
delete[] szBuffer;
dc.SelectObject(pOldFont);
}
BOOL CTaskbarNotifier::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
if (nHitTest == HTCLIENT)
{
if (m_rcCloseBtn.PtInRect(m_ptMousePosition) ||
m_rcHistoryBtn.PtInRect(m_ptMousePosition) ||
m_rcText.PtInRect(m_ptMousePosition)) {
::SetCursor(m_hCursor);
return TRUE;
}
}
return CWnd::OnSetCursor(pWnd, nHitTest, message);
}
void CTaskbarNotifier::OnTimer(UINT nIDEvent)
{
switch (nIDEvent)
{
case IDT_APPEARING:
m_nAnimStatus=IDT_APPEARING;
switch(m_nTaskbarPlacement)
{
case ABE_BOTTOM:
if (m_nCurrentHeight<m_nBitmapHeight)
{
m_nCurrentPosY-=m_nIncrementShow;
m_nCurrentHeight+=m_nIncrementShow;
}
else
{
KillTimer(IDT_APPEARING);
SetTimer(IDT_WAITING,m_dwTimeToStay,NULL);
m_nAnimStatus=IDT_WAITING;
}
break;
case ABE_TOP:
if (m_nCurrentHeight<m_nBitmapHeight)
m_nCurrentHeight+=m_nIncrementShow;
else
{
KillTimer(IDT_APPEARING);
SetTimer(IDT_WAITING,m_dwTimeToStay,NULL);
m_nAnimStatus=IDT_WAITING;
}
break;
case ABE_LEFT:
if (m_nCurrentWidth<m_nBitmapWidth)
m_nCurrentWidth+=m_nIncrementShow;
else
{
KillTimer(IDT_APPEARING);
SetTimer(IDT_WAITING,m_dwTimeToStay,NULL);
m_nAnimStatus=IDT_WAITING;
}
break;
case ABE_RIGHT:
if (m_nCurrentWidth<m_nBitmapWidth)
{
m_nCurrentPosX-=m_nIncrementShow;
m_nCurrentWidth+=m_nIncrementShow;
}
else
{
KillTimer(IDT_APPEARING);
SetTimer(IDT_WAITING,m_dwTimeToStay,NULL);
m_nAnimStatus=IDT_WAITING;
}
break;
}
SetWindowPos(&wndTopMost,m_nCurrentPosX,m_nCurrentPosY,m_nCurrentWidth,m_nCurrentHeight,SWP_NOACTIVATE);
break;
case IDT_WAITING:
KillTimer(IDT_WAITING);
if (m_bAutoClose)
SetTimer(IDT_DISAPPEARING,m_dwHideEvents,NULL);
break;
case IDT_DISAPPEARING:
m_nAnimStatus=IDT_DISAPPEARING;
switch(m_nTaskbarPlacement)
{
case ABE_BOTTOM:
if (m_nCurrentHeight>0)
{
m_nCurrentPosY+=m_nIncrementHide;
m_nCurrentHeight-=m_nIncrementHide;
}
else
{
KillTimer(IDT_DISAPPEARING);
Hide();
}
break;
case ABE_TOP:
if (m_nCurrentHeight>0)
m_nCurrentHeight-=m_nIncrementHide;
else
{
KillTimer(IDT_DISAPPEARING);
Hide();
}
break;
case ABE_LEFT:
if (m_nCurrentWidth>0)
m_nCurrentWidth-=m_nIncrementHide;
else
{
KillTimer(IDT_DISAPPEARING);
Hide();
}
break;
case ABE_RIGHT:
if (m_nCurrentWidth>0)
{
m_nCurrentPosX+=m_nIncrementHide;
m_nCurrentWidth-=m_nIncrementHide;
}
else
{
KillTimer(IDT_DISAPPEARING);
Hide();
}
break;
}
SetWindowPos(&wndTopMost,m_nCurrentPosX,m_nCurrentPosY,m_nCurrentWidth,m_nCurrentHeight,SWP_NOACTIVATE);
break;
}
CWnd::OnTimer(nIDEvent);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -