⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 balloonhelp.cpp

📁 实时监控
💻 CPP
📖 第 1 页 / 共 4 页
字号:
      sizeHdr.cx += nBtnWidth;      sizeHdr.cy = max(sizeHdr.cy, ::GetSystemMetrics(SM_CYSIZE));      if (bDraw)         pDC->DrawFrameControl(CRect(rectClient.right-nBtnWidth,0,rectClient.right,::GetSystemMetrics(SM_CYSIZE)), DFC_CAPTION, DFCS_CAPTIONCLOSE|DFCS_FLAT);      rectClient.right -= nBtnWidth;   }   // calc title size   CString strTitle;   GetWindowText(strTitle);   if ( !strTitle.IsEmpty() )   {      CFont* pOldFont = pDC->SelectObject(m_pTitleFont);      // if something is already in the header (icon or close button) leave space      if ( sizeHdr.cx > 0 )          sizeHdr.cx += nTIP_MARGIN;      CRect rectTitle(0,0,0,0);      pDC->DrawText(strTitle, &rectTitle, DT_CALCRECT | DT_NOPREFIX | DT_EXPANDTABS | DT_SINGLELINE);      sizeHdr.cx += rectTitle.Width();      sizeHdr.cy = max(sizeHdr.cy, rectTitle.Height());      // draw title      if ( bDraw )      {         pDC->SetBkMode(TRANSPARENT);         pDC->SetTextColor(m_crForeground);         pDC->DrawText(strTitle, &rectClient, DT_CENTER | DT_NOPREFIX  | DT_EXPANDTABS | DT_SINGLELINE);      }      // cleanup      pDC->SelectObject(pOldFont);   }   return sizeHdr;
}

// Calculate the dimensions and draw the balloon contents
CSize CBalloonHelp::DrawContent(CDC* pDC, int nTop, bool bDraw)
{
   CRect rectContent;   GetAnchorScreenBounds(rectContent);   rectContent.OffsetRect(-rectContent.left, -rectContent.top);   rectContent.top = nTop;   // limit to half screen width   rectContent.right -= rectContent.Width()/2;   // calc size   CFont* pOldFont = pDC->SelectObject(m_pContentFont);   if ( !m_strContent.IsEmpty() )      pDC->DrawText(m_strContent, &rectContent, DT_CALCRECT | DT_LEFT | DT_NOPREFIX | DT_EXPANDTABS | DT_WORDBREAK);   else      rectContent.SetRectEmpty();   // don't want to leave half the screen for empty strings ;)      // draw   if (bDraw)   {      pDC->SetBkMode(TRANSPARENT);      pDC->SetTextColor(m_crForeground);      pDC->DrawText(m_strContent, &rectContent, DT_LEFT | DT_NOPREFIX | DT_WORDBREAK | DT_EXPANDTABS);   }
   // cleanup   pDC->SelectObject(pOldFont);   return rectContent.Size();
}
// calculates the client size necessary based on title and contentCSize CBalloonHelp::CalcClientSize(){   ASSERT(NULL != m_hWnd);   CWindowDC dc(this);   CSize sizeHeader = CalcHeaderSize(&dc);   CSize sizeContent = CalcContentSize(&dc);   return CSize(max(sizeHeader.cx,sizeContent.cx), sizeHeader.cy + nTIP_MARGIN + sizeContent.cy);}// calculates the size for the entire window based on content sizeCSize CBalloonHelp::CalcWindowSize(){   CSize size = CalcClientSize();   size.cx += nTIP_MARGIN*2;   size.cy += nTIP_TAIL+nTIP_MARGIN*2;   //size.cx = max(size.cx, nTIP_MARGIN*2+nTIP_TAIL*4);   return size;}// this routine calculates the size and position of the window relative// to it's anchor point, and moves the window accordingly.  The region is also// created and set here.void CBalloonHelp::PositionWindow(){
   CSize sizeWnd = CalcWindowSize();   CPoint ptTail[3];   CPoint ptTopLeft(0,0);   CPoint ptBottomRight(sizeWnd.cx, sizeWnd.cy);   // force recalculation of desktop
   m_screenRect.SetRectEmpty();

   switch (GetBalloonQuadrant())   {   case BQ_TOPLEFT:      ptTopLeft.y = nTIP_TAIL;      ptTail[0].x = (sizeWnd.cx-nTIP_TAIL)/4 + nTIP_TAIL;      ptTail[0].y = nTIP_TAIL+1;      ptTail[2].x = (sizeWnd.cx-nTIP_TAIL)/4;      ptTail[2].y = ptTail[0].y;      ptTail[1].x = ptTail[2].x;      ptTail[1].y = 1;      break;   case BQ_TOPRIGHT:      ptTopLeft.y = nTIP_TAIL;      ptTail[0].x = (sizeWnd.cx-nTIP_TAIL)/4*3;      ptTail[0].y = nTIP_TAIL+1;      ptTail[2].x = (sizeWnd.cx-nTIP_TAIL)/4*3 + nTIP_TAIL;      ptTail[2].y = ptTail[0].y;      ptTail[1].x = ptTail[2].x;      ptTail[1].y = 1;      break;   case BQ_BOTTOMLEFT:      ptBottomRight.y = sizeWnd.cy-nTIP_TAIL;      ptTail[0].x = (sizeWnd.cx-nTIP_TAIL)/4 + nTIP_TAIL;      ptTail[0].y = sizeWnd.cy-nTIP_TAIL-2;      ptTail[2].x = (sizeWnd.cx-nTIP_TAIL)/4;      ptTail[2].y = ptTail[0].y;      ptTail[1].x = ptTail[2].x;      ptTail[1].y = sizeWnd.cy-2;      break;   case BQ_BOTTOMRIGHT:      ptBottomRight.y = sizeWnd.cy-nTIP_TAIL;      ptTail[0].x = (sizeWnd.cx-nTIP_TAIL)/4*3;      ptTail[0].y = sizeWnd.cy-nTIP_TAIL-2;      ptTail[2].x = (sizeWnd.cx-nTIP_TAIL)/4*3 + nTIP_TAIL;      ptTail[2].y = ptTail[0].y;      ptTail[1].x = ptTail[2].x;      ptTail[1].y = sizeWnd.cy-2;      break;   }   // adjust for very narrow balloons   if ( ptTail[0].x < nTIP_MARGIN )      ptTail[0].x = nTIP_MARGIN;   if ( ptTail[0].x > sizeWnd.cx - nTIP_MARGIN )      ptTail[0].x = sizeWnd.cx - nTIP_MARGIN;   if ( ptTail[1].x < nTIP_MARGIN )      ptTail[1].x = nTIP_MARGIN;   if ( ptTail[1].x > sizeWnd.cx - nTIP_MARGIN )      ptTail[1].x = sizeWnd.cx - nTIP_MARGIN;   if ( ptTail[2].x < nTIP_MARGIN )      ptTail[2].x = nTIP_MARGIN;   if ( ptTail[2].x > sizeWnd.cx - nTIP_MARGIN )      ptTail[2].x = sizeWnd.cx - nTIP_MARGIN;   // get window position   CPoint ptAnchor = GetAnchorPoint();   CPoint ptOffs(ptAnchor.x - ptTail[1].x, ptAnchor.y - ptTail[1].y);   // adjust position so all is visible   CRect rectScreen;   GetAnchorScreenBounds(rectScreen);   int nAdjustX = 0;   int nAdjustY = 0;   if ( ptOffs.x < rectScreen.left )      nAdjustX = rectScreen.left-ptOffs.x;   else if ( ptOffs.x + sizeWnd.cx >= rectScreen.right )      nAdjustX = rectScreen.right - (ptOffs.x + sizeWnd.cx);   if ( ptOffs.y + nTIP_TAIL < rectScreen.top )      nAdjustY = rectScreen.top - (ptOffs.y + nTIP_TAIL);   else if ( ptOffs.y + sizeWnd.cy - nTIP_TAIL >= rectScreen.bottom )      nAdjustY = rectScreen.bottom - (ptOffs.y + sizeWnd.cy - nTIP_TAIL);   // reposition tail   // uncomment two commented lines below to move entire tail    // instead of just anchor point   //ptTail[0].x -= nAdjustX;   ptTail[1].x -= nAdjustX;   //ptTail[2].x -= nAdjustX;   ptOffs.x    += nAdjustX;   ptOffs.y    += nAdjustY;   // place window
   MoveWindow(ptOffs.x, ptOffs.y, sizeWnd.cx, sizeWnd.cy, TRUE);

   // apply region
   CRgn region;   CRgn regionRound;   CRgn regionComplete;   region.CreatePolygonRgn(&ptTail[0], 3, ALTERNATE);   regionRound.CreateRoundRectRgn(ptTopLeft.x,ptTopLeft.y,ptBottomRight.x,ptBottomRight.y,nTIP_MARGIN*3,nTIP_MARGIN*3);   regionComplete.CreateRectRgn(0,0,1,1);   regionComplete.CombineRgn(&region, &regionRound, RGN_OR);   if ( NULL == m_rgnComplete.m_hObject )      m_rgnComplete.CreateRectRgn(0,0,1,1);

   if ( !m_rgnComplete.EqualRgn(&regionComplete) )
   {
      m_rgnComplete.CopyRgn(&regionComplete);      SetWindowRgn((HRGN)regionComplete.Detach(), TRUE);

      // There is a bug with layered windows and NC changes in Win2k
      // As a workaround, redraw the entire window if the NC area changed.
      // Changing the anchor point is the ONLY thing that will change the
      // position of the client area relative to the window during normal
      // operation.
      RedrawWindow(NULL, NULL, RDW_UPDATENOW| RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN);
   }
}// Returns the class ATOM for a BalloonHelp control.  Registers the class first, if necessary.ATOM CBalloonHelp::GetClassAtom(BOOL bShadowed){   if ( NULL == s_ClassAtom )   {      WNDCLASSEX wcx;       // Fill in the window class structure with parameters       // that describe the main window.       wcx.cbSize = sizeof(wcx);                 // size of structure       wcx.style = CS_DBLCLKS|CS_SAVEBITS         |CS_DROPSHADOW;                        // notify of double clicks, save screen under, show dropshadow      wcx.lpfnWndProc = AfxWndProc;             // points to window procedure       wcx.cbClsExtra = 0;                       // no extra class memory       wcx.cbWndExtra = 0;                       // no extra window memory       wcx.hInstance = AfxGetInstanceHandle();   // handle to instance       wcx.hIcon = NULL;                         // no app. icon       wcx.hCursor = LoadCursor(NULL,IDC_ARROW); // predefined arrow       wcx.hbrBackground = ::GetSysColorBrush(COLOR_WINDOW);                 // no background brush       wcx.lpszMenuName =  NULL;                 // no menu resource       wcx.lpszClassName = _T("BalloonHelpClassDS"); // name of window class       wcx.hIconSm = NULL;                       // no small class icon      // Register the window class (this may not work if dropshadows are not supported)      s_ClassAtomShadowed = RegisterClassEx(&wcx);      // Register shadow-less class      wcx.style &= ~CS_DROPSHADOW;      wcx.lpszClassName = _T("BalloonHelpClass");      s_ClassAtom = RegisterClassEx(&wcx);   }   if ( bShadowed && NULL != s_ClassAtomShadowed )      return s_ClassAtomShadowed;   return s_ClassAtom;}

// Displays the balloon on the screen, performing fade-in if enabled.
void CBalloonHelp::ShowBalloon(void)
{
   ShowWindow(SW_SHOWNOACTIVATE);
   if ( !(m_unOptions&unDELAY_CLOSE) )
      SetTimeout(m_unTimeout);     // start close timer}
// Removes the balloon from the screen, performing the fade-out if enabled
void CBalloonHelp::HideBalloon(void)
{
   if ( m_unOptions&unDELAY_CLOSE )
   {
      m_unOptions &= ~(unDELAY_CLOSE|unCLOSE_ON_ANYTHING);  // close only via timer or button
      SetTimeout(m_unTimeout);     // start close timer      return;   }
   ShowWindow( SW_HIDE );
   if ( GetCapture() == this ) 
      ReleaseCapture();
   DestroyWindow();
}

//
// Keyboard hook
//

void CBalloonHelp::SetKeyboardHook()
{
   if ( NULL==m_hKeyboardHook )
   {
      m_hKeyboardHook = ::SetWindowsHookEx(WH_KEYBOARD,
         (HOOKPROC)BHKeybHookThunk<CBalloonHelp>::GetThunk(),
         NULL, ::GetCurrentThreadId());
   }
}

void CBalloonHelp::RemoveKeyboardHook()
{
   if ( NULL!=m_hKeyboardHook )
   {
      ::UnhookWindowsHookEx(m_hKeyboardHook);
      m_hKeyboardHook=NULL;
   }
}


//
// Mouse hook
//

void CBalloonHelp::SetMouseHook()
{
   if ( NULL==m_hMouseHook )
   {
      m_hMouseHook = ::SetWindowsHookEx(WH_MOUSE,
         (HOOKPROC)BHMouseHookThunk<CBalloonHelp>::GetThunk(),
         NULL, ::GetCurrentThreadId());
   }
}

void CBalloonHelp::RemoveMouseHook()
{
   if ( NULL!=m_hMouseHook )
   {
      ::UnhookWindowsHookEx(m_hMouseHook);
      m_hMouseHook=NULL;
   }
}

//
// Call Window Return hook
//

void CBalloonHelp::SetCallWndRetHook()
{
   if ( NULL==m_hCallWndRetHook )
   {
      m_hCallWndRetHook = ::SetWindowsHookEx(WH_CALLWNDPROCRET,
         (HOOKPROC)BHCallWndRetHookThunk<CBalloonHelp>::GetThunk(),
         NULL, ::GetCurrentThreadId());
   }
}

void CBalloonHelp::RemoveCallWndRetHook()
{
   if ( NULL!=m_hCallWndRetHook )
   {
      ::UnhookWindowsHookEx(m_hCallWndRetHook);
      m_hCallWndRetHook=NULL;
   }
}

/////////////////////////////////////////////////////////////////////////////// CBalloonHelp message handlersBEGIN_MESSAGE_MAP(CBalloonHelp, CWnd)   ON_WM_ERASEBKGND()   ON_WM_PAINT()   ON_WM_NCPAINT()   ON_WM_LBUTTONDOWN()   ON_WM_LBUTTONUP()   ON_WM_NCCALCSIZE()

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -