www.gusucode.com > VC++指定区域抓图、截屏小程序-源码程序 > VC++指定区域抓图、截屏小程序-源码程序/code/FBCtrlBar.cpp
//Download by http://www.NewXing.com /* @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 文件:FBCtrlBar.cpp 类CFBCtrlBar的执行文件 版权:Firebird Software Workroom 声明:本源程序的版权受《中华人民共和国著作权法》以及其 它相关法律和条约的保护。任何有机会得到本源程序的 个人和机构,未经作者明确授权,不得将本源程序用于 任何商业目的(直接的或间接的)。对于非商业目的的使 用 (包括复制、传播、编译和修改), 原则上没有特别 的限制条款,但请在相关文档中说明其来源,并尊重原 作者的署名权。 编写:秦传安(chings) 1999.12 - 2000.5 联络:Tel:(0792)6323086 E_mail:chings@163.net @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ #include "fclstd.h" #include "resource.h" #include "FBCtrlBar.h" //####################################################################### // // class CFBCtrlBar // //######################################################################### #define MOUSEMOVE_HOR 0x00000001 #define MOUSEMOVE_VER 0x00000002 #define MOUSEMOVE_ALL 0x00000003 ////////////////////////////////////////////////////////////////////// // 构造函数和析构函数 ////////////////////////////////////////////////////////////////////// CFBCtrlBar::CFBCtrlBar() { m_bDock = FALSE; m_bDown = FALSE; m_nSizeFlag = SIZEFLAG_NON; SetRectEmpty(&m_rcOver); } CFBCtrlBar::~CFBCtrlBar() { } /////////////////////////////////////////////////////////////////////// //窗口过程 LRESULT CFBCtrlBar::WindowProc(UINT msg,WPARAM wParam,LPARAM lParam) { LRESULT lResult = 0; switch(msg) { case WM_PAINT: { if(!GetUpdateRect(m_hWnd,NULL,FALSE)) return 0; PAINTSTRUCT ps; BeginPaint(m_hWnd,&ps); OnPaint(ps.hdc,&ps.rcPaint); EndPaint(m_hWnd,&ps); } break; case WM_SIZE: OnSize(); break; case FBWM_SETSIZE: OnSetSize((LPRECT)lParam); break; case WM_CLOSE: ShowWindow(m_hWnd,SW_HIDE); if(m_pOwner) lResult = SendMessage(m_pOwner->m_hWnd,FBWM_NOTIFY,MAKEWPARAM(GetWndID(),FB_CBN_CLOSE),0); break; case WM_COMMAND: if(m_pOwner) lResult = SendMessage(m_pOwner->m_hWnd,msg,wParam,lParam); break; case WM_NCLBUTTONDBLCLK://在标题栏双击时恢复上一次的停靠状态 if(wParam != HTCAPTION) return CFBWnd::WindowProc(msg,wParam,lParam); DockStateChange(m_nPreState); break; case WM_LBUTTONDBLCLK: if(m_nStyle & CBS_FLYBY) { POINT pos; pos.x = LOWORD(lParam); pos.y = HIWORD(lParam); if(HitTest(&pos) == HITTEST_GRIPPER) DockStateChange(m_nPreState); } break; case WM_NCLBUTTONDOWN: if(wParam != HTCAPTION) return CFBWnd::WindowProc(msg,wParam,lParam); else { POINT pos; pos.x = LOWORD(lParam); pos.y = HIWORD(lParam); ScreenToClient(m_hWnd,&pos); OnLButtonDown(&pos,wParam); } break; case WM_LBUTTONDOWN: { POINT pos; pos.x = LOWORD(lParam); pos.y = HIWORD(lParam); OnLButtonDown(&pos,wParam); } break; case WM_LBUTTONUP: { POINT pos; pos.x = LOWORD(lParam); pos.y = HIWORD(lParam); OnLButtonUp(&pos,wParam); } break; case WM_MOUSEMOVE: { POINT pos; pos.x = LOWORD(lParam); pos.y = HIWORD(lParam); OnMouseMove(&pos,wParam); } break; case WM_SETCURSOR: { POINT pos; GetCursorPos(&pos); ScreenToClient(m_hWnd,&pos); if((HitTest(&pos) == HITTEST_SIZER && m_nDockState) || (m_nSizeFlag != SIZEFLAG_NON && m_bDown)) { HCURSOR hcur; if(m_nDockState& (CB_DOCK_TOP|CB_DOCK_BOTTOM)) { hcur = LoadCursor(GetInstance(),MAKEINTRESOURCE(IDC_SIZINGNS)); m_nSizeFlag = SIZEFLAG_NS; } else { hcur = LoadCursor(GetInstance(),MAKEINTRESOURCE(IDC_SIZINGWE)); m_nSizeFlag = SIZEFLAG_WE; } SetCursor(hcur); } else { lResult = CFBWnd::WindowProc(msg,wParam,lParam); m_nSizeFlag = SIZEFLAG_NON; } } break; case WM_NOTIFY: OnNotify((LPNMHDR)lParam,lResult); break; default: lResult = CFBWnd::WindowProc(msg,wParam,lParam); break; } return lResult; } ///////////////////////////////////////////////////////////////////////////// BOOL CFBCtrlBar::Create(LPSTR lpszCaption, CFBWnd* pParent, UINT nStyle, int width, int height, UINT uID) { m_nWidth = width; m_nHeight = height; m_nStyle = nStyle; UINT style = WS_CHILD|WS_VISIBLE;//|WS_CLIPSIBLINGS | WS_CLIPCHILDREN; return CFBWnd::Create(CLS_FBSTDWNDCLASS, lpszCaption, pParent->GetInstance(), pParent, style, WS_EX_TOOLWINDOW, (HMENU)uID); } ////////////////////////////////////////////////////////////////////////// void CFBCtrlBar::OnSetSize(LPRECT pRect) { if(!m_bDock || !IsShow())return; RECT rc; CopyRect(&rc,pRect); switch(m_nDockState) { case CB_DOCK_TOP: rc.bottom = rc.top + m_nHeight; pRect->top += m_nHeight; break; case CB_DOCK_BOTTOM: rc.top = rc.bottom - m_nHeight; pRect->bottom -= m_nHeight; break; case CB_DOCK_LEFT: rc.right = rc.left + m_nWidth; pRect->left += m_nWidth; break; case CB_DOCK_RIGHT: rc.left = rc.right - m_nWidth; pRect->right -= m_nWidth; break; default: break; } if(m_nDockState != CB_DOCK_NON) SetWindowPos(m_hWnd,NULL,rc.left,rc.top, rc.right-rc.left,rc.bottom-rc.top, SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOCOPYBITS); } ////////////////////////////////////////////////////////////////////////// void CFBCtrlBar::OnSize() { if((m_nStyle&CBS_FLYBY) && (m_nDockState == CB_DOCK_NON)) { RECT rc; GetWindowRect(m_hWnd,&rc); CopyRect(&m_rcOver,&rc); } } /////////////////////////////////////////////////////////////////////////// void CFBCtrlBar::OnPaint(HDC hDC,LPRECT prcPaint) { if(!m_bDock)return; RECT rc; GetClientRect(m_hWnd,&rc); UINT style = m_nStyle & CBS_BORDER_RECT; if(style)//画边框 { if(style == CBS_BORDER_RECT) DrawEdge(GetDC(m_hWnd),&rc,EDGE_ETCHED,BF_RECT); else { if(style & CBS_BORDER_TOP) DrawEdge(GetDC(m_hWnd),&rc,EDGE_ETCHED,BF_TOP); if(style & CBS_BORDER_BOTTOM) DrawEdge(GetDC(m_hWnd),&rc,EDGE_ETCHED,BF_BOTTOM); if(style & CBS_BORDER_LEFT) DrawEdge(GetDC(m_hWnd),&rc,EDGE_ETCHED,BF_LEFT); if(style & CBS_BORDER_RIGHT) DrawEdge(GetDC(m_hWnd),&rc,EDGE_ETCHED,BF_RIGHT); } } if(m_nStyle & CBS_GRIPPER)//画把手 DrawGripper(hDC,&rc); } //////////////////////////////////////////////////////////////////////// void CFBCtrlBar::Docking(UINT nDockState) { m_bDock = TRUE; m_nDockState = nDockState; m_nPreState = nDockState; } //////////////////////////////////////////////////////////////////////////// //画把手 void CFBCtrlBar::DrawGripper(HDC hDC,LPRECT pRc) { switch(m_nDockState) { case CB_DOCK_TOP: case CB_DOCK_BOTTOM: m_rcGripper.top = pRc->top + 2; m_rcGripper.bottom = pRc->bottom - 2; m_rcGripper.left = pRc->left + 4; m_rcGripper.right = m_rcGripper.left +8; pRc->top += 2; pRc->bottom -= 2; pRc->left += 4; pRc->right = pRc->left + 3; DrawEdge(hDC,pRc,BDR_RAISEDINNER,BF_RECT); pRc->left += 4; pRc->right += 4; DrawEdge(hDC,pRc,BDR_RAISEDINNER,BF_RECT); break; case CB_DOCK_LEFT: case CB_DOCK_RIGHT: m_rcGripper.left = pRc->left + 2; m_rcGripper.right = pRc->right - 2; m_rcGripper.top = pRc->top + 4; m_rcGripper.bottom = m_rcGripper.top +8; pRc->left += 2; pRc->right -= 2; pRc->top += 5; pRc->bottom = pRc->top + 3; DrawEdge(hDC,pRc,BDR_RAISEDINNER,BF_RECT); pRc->top += 4; pRc->bottom += 4; DrawEdge(hDC,pRc,BDR_RAISEDINNER,BF_RECT); break; } } //////////////////////////////////////////////////////////////////////////// void CFBCtrlBar::OnNotify(LPNMHDR pNMHDR,LRESULT& lResult) { if(pNMHDR->hwndFrom != m_hWnd) SendMessage(pNMHDR->hwndFrom,WM_NOTIFY,(WPARAM)pNMHDR->idFrom,(LPARAM)pNMHDR); } //////////////////////////////////////////////////////////////////////////// void CFBCtrlBar::OnLButtonDown(LPPOINT pPos,UINT key) { m_bDown = TRUE; SetCapture(m_hWnd); m_BeginP.x = m_MoveP.x = pPos->x; m_BeginP.y = m_MoveP.y = pPos->y; if(m_nSizeFlag != SIZEFLAG_NON) { m_nSized = 0; DrawSizeFlag(); return; } if(!(m_nStyle&CBS_FLYBY) || HitTest(pPos)!=HITTEST_GRIPPER) { m_bDown = FALSE; ReleaseCapture(); return; } SetCapture(m_hWnd); m_nFlyState = m_nDockState; GetWindowRect(m_hWnd,&m_rcFlyby); if(m_nFlyState != CB_DOCK_NON) LineRect(GetDC(NULL),&m_rcFlyby); else DrawDragRect(GetDC(NULL),&m_rcFlyby); } //////////////////////////////////////////////////////////////////////////// void CFBCtrlBar::OnLButtonUp(LPPOINT pPos,UINT key) { if(!m_bDown)return; m_bDown = FALSE; ReleaseCapture(); if(m_nSizeFlag != SIZEFLAG_NON) { DrawSizeFlag(); if(m_nSized != 0) { if(m_nSizeFlag == SIZEFLAG_WE)//东西向拖动大小 { if(m_nDockState == CB_DOCK_LEFT) m_nWidth += m_nSized; else m_nWidth -= m_nSized; } else//南北向拖动大小 { if(m_nDockState == CB_DOCK_TOP) m_nHeight += m_nSized; else m_nHeight -= m_nSized; } SendMessage(m_pOwner->m_hWnd,FBWM_SETSIZE,0,0); } m_nSizeFlag = SIZEFLAG_NON; return; } if(!(m_nStyle&CBS_FLYBY))return; if(m_nFlyState != CB_DOCK_NON) LineRect(GetDC(NULL),&m_rcFlyby); else { DrawDragRect(GetDC(NULL),&m_rcFlyby); CopyRect(&m_rcOver,&m_rcFlyby); } DockStateChange(m_nFlyState); } //////////////////////////////////////////////////////////////////////////// void CFBCtrlBar::OnMouseMove(LPPOINT pPos,UINT key) { if(!m_bDown)return; if(m_nSizeFlag != SIZEFLAG_NON) { DrawSizeFlag(); m_MoveP.x = pPos->x; m_MoveP.y = pPos->y; if(m_nSizeFlag == SIZEFLAG_WE) m_nSized = m_MoveP.x - m_BeginP.x; else m_nSized = m_MoveP.y - m_BeginP.y; DrawSizeFlag(); return; } if(!(m_nStyle&CBS_FLYBY))return; if(m_nFlyState != CB_DOCK_NON) LineRect(GetDC(NULL),&m_rcFlyby); else DrawDragRect(GetDC(NULL),&m_rcFlyby); m_rcFlyby.left += pPos->x - m_MoveP.x; m_rcFlyby.top += pPos->y - m_MoveP.y; m_rcFlyby.right += pPos->x - m_MoveP.x; m_rcFlyby.bottom += pPos->y - m_MoveP.y; UINT flag = 0; if(pPos->x != m_BeginP.x) flag |= MOUSEMOVE_HOR; if(pPos->y != m_BeginP.y) flag |= MOUSEMOVE_VER; if(GetFlybySide(flag)) { RECT rc; GetClientRect(m_pOwner->m_hWnd,&rc); switch(m_nFlyState) { case CB_DOCK_TOP: case CB_DOCK_BOTTOM: { m_rcFlyby.right = m_rcFlyby.left+rc.right-rc.left; m_rcFlyby.bottom = m_rcFlyby.top + m_nHeight; } break; case CB_DOCK_LEFT: case CB_DOCK_RIGHT: { m_rcFlyby.bottom = m_rcFlyby.top + rc.bottom - rc.top; m_rcFlyby.right = m_rcFlyby.left + m_nWidth; } break; default: { if(IsRectEmpty(&m_rcOver)) { m_rcFlyby.right = m_rcFlyby.left + 300; m_rcFlyby.bottom = m_rcFlyby.top + 240; } else { m_rcFlyby.right = m_rcFlyby.left + m_rcOver.right - m_rcOver.left; m_rcFlyby.bottom = m_rcFlyby.top + m_rcOver.bottom - m_rcOver.top; } } break; } } if(m_nFlyState != CB_DOCK_NON) LineRect(GetDC(NULL),&m_rcFlyby); else DrawDragRect(GetDC(NULL),&m_rcFlyby); m_MoveP.x = pPos->x; m_MoveP.y = pPos->y; } //////////////////////////////////////////////////////////////////////////// void CFBCtrlBar::DrawSizeFlag() { RECT rc; if(m_nSizeFlag == SIZEFLAG_WE) { rc.left = m_rcSizer.left + m_nSized; rc.right = rc.left + 4; rc.top = m_rcSizer.top; rc.bottom = m_rcSizer.bottom; } else { rc.left = m_rcSizer.left; rc.right = m_rcSizer.right; rc.top = m_rcSizer.top + m_nSized; rc.bottom = rc.top + 4; } ClientToScreen(m_hWnd,&rc); DrawDragRect(GetDC(NULL),&rc,2); } //////////////////////////////////////////////////////////////////////////// BOOL CFBCtrlBar::GetFlybySide(UINT flag) { RECT rc; POINT pos; GetWindowRect(m_pOwner->m_hWnd,&rc); GetCursorPos(&pos); UINT FlyState = 0; if(PtInRect(&rc,pos)) { switch(flag) { case MOUSEMOVE_VER: { if((pos.y-rc.top)<m_nHeight) FlyState = CB_DOCK_TOP; if((rc.bottom-pos.y)<m_nHeight) FlyState = CB_DOCK_BOTTOM; } break; case MOUSEMOVE_HOR: { if((pos.x - rc.left)<m_nWidth) FlyState = CB_DOCK_LEFT; if((rc.right - pos.x)<m_nWidth) FlyState = CB_DOCK_RIGHT; } break; case MOUSEMOVE_ALL: { if((pos.y-rc.top)<m_nHeight) { if(((pos.x - rc.left)<m_nWidth) && ((pos.y-rc.top)>(pos.x - rc.left))) FlyState = CB_DOCK_LEFT; else if(((rc.right - pos.x)<m_nWidth) && ((pos.y-rc.top)>(rc.right - pos.x))) FlyState = CB_DOCK_RIGHT; else FlyState = CB_DOCK_TOP; } else if((rc.bottom-pos.y)<m_nHeight) { if(((pos.x - rc.left)<m_nWidth) && ((rc.bottom-pos.y)>(pos.x - rc.left))) FlyState = CB_DOCK_LEFT; else if(((rc.right - pos.x)<m_nWidth) && ((rc.bottom-pos.y)>(rc.right - pos.x))) FlyState = CB_DOCK_RIGHT; else FlyState = CB_DOCK_BOTTOM; } else { if((pos.x - rc.left)<m_nWidth) FlyState = CB_DOCK_LEFT; if((rc.right - pos.x)<m_nWidth) FlyState = CB_DOCK_RIGHT; } } break; default: FlyState = CB_DOCK_NON; break; } } if(m_nFlyState == FlyState) return FALSE; m_nFlyState = FlyState; return TRUE; } //////////////////////////////////////////////////////////////////////////// //停靠状态改变,必须重新安排窗口位置 void CFBCtrlBar::DockStateChange(UINT state) { if(m_nDockState != state) { m_nPreState = m_nDockState; if(m_nDockState == CB_DOCK_NON) { ModifyWndStyle(WS_OVERLAPPEDWINDOW,WS_CHILD); SetParent(m_hWnd,m_pOwner->m_hWnd); m_bDock = TRUE; } m_nDockState = state; if(state == CB_DOCK_NON) { ModifyWndStyle(WS_CHILD,WS_OVERLAPPEDWINDOW); SetParent(m_hWnd,NULL); m_bDock = FALSE; SetWindowPos(m_hWnd,HWND_TOPMOST,m_rcOver.left, m_rcOver.top, m_rcOver.right - m_rcOver.left, m_rcOver.bottom - m_rcOver.top, SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOCOPYBITS); } SendMessage(m_pOwner->m_hWnd,FBWM_SETSIZE,0,0); } else if(m_nDockState == CB_DOCK_NON) { RECT rc; GetWindowRect(m_hWnd,&rc); if(rc.left!=m_rcFlyby.left || rc.top!=m_rcFlyby.top) SetWindowPos(m_hWnd,HWND_TOPMOST,m_rcOver.left, m_rcOver.top, m_rcOver.right - m_rcOver.left, m_rcOver.bottom - m_rcOver.top, SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOCOPYBITS); } } //////////////////////////////////////////////////////////////////////////// LONG CFBCtrlBar::HitTest(LPPOINT pPos) { if(PtInRect(&m_rcGripper,*pPos)) return HITTEST_GRIPPER; if(PtInRect(&m_rcSizer,*pPos)) return HITTEST_SIZER; POINT p; p.x = pPos->x; p.y = pPos->y; ClientToScreen(m_hWnd,&p); if(SendMessage(m_hWnd,WM_NCHITTEST,0,MAKELPARAM(p.x,p.y)) == HTCAPTION) return HITTEST_GRIPPER; return 0; }