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

📄 atldock.h

📁 BCAM 1394 Driver
💻 H
📖 第 1 页 / 共 4 页
字号:
      ctx->bKeepSize = false;

      // Create docking child
      TDockWindow *wndDock;
      ATLTRY(wndDock = new TDockWindow(ctx));
      if( wndDock==NULL ) return;
      wndDock->Create(m_hWnd, rcDefault, NULL);
      ATLASSERT(::IsWindow(wndDock->m_hWnd));
      ctx->hwndDocked = *wndDock;

      // Create floating child
      TFloatWindow *wndFloat;
      TCHAR szCaption[128];    // max text length is 127 for floating caption
      ::GetWindowText(hWnd, szCaption, sizeof(szCaption)/sizeof(TCHAR));
      ATLTRY(wndFloat = new TFloatWindow(ctx));
      if( wndFloat==NULL ) return;
      wndFloat->Create(m_hWnd, rcDefault, szCaption);
      ATLASSERT(::IsWindow(wndFloat->m_hWnd));
      ctx->hwndFloated = *wndFloat;

      ::SetParent(ctx->hwndChild, ctx->hwndDocked);

      // Add Context to master list
      m_map.Add(ctx);
   }

   BOOL DockWindow(HWND hWnd, short Side, int iRequestedSize=0)
   {
      T* pT = static_cast<T*>(this);
      DOCKCONTEXT *ctx = _GetContext(hWnd);
      ATLASSERT(ctx);
      if( ctx==NULL ) return FALSE;
      if( Side==DOCK_LASTKNOWN ) Side = ctx->LastSide;
      if( !IsDocked(Side) ) return FALSE;
      return pT->_DockWindow(ctx, Side, iRequestedSize);
   }

   BOOL FloatWindow(HWND hWnd, RECT &rc)
   {
      T* pT = static_cast<T*>(this);
      DOCKCONTEXT *ctx = _GetContext(hWnd);
      ATLASSERT(ctx);
      if( ctx==NULL ) return FALSE;
      ctx->rcWindow = rc;
      return pT->_FloatWindow(ctx);
   }

   BOOL HideWindow(HWND hWnd)
   {
      T* pT = static_cast<T*>(this);
      DOCKCONTEXT *ctx = _GetContext(hWnd);
      ATLASSERT(ctx);
      if( ctx==NULL ) return FALSE;
      if( ctx->Side==DOCK_FLOAT ) return pT->_UnFloatWindow(ctx);
      else if( IsDocked(ctx->Side) ) return pT->_UnDockWindow(ctx);
      return FALSE;
   }

   void GetWindowState(HWND hWnd, int &DockState, RECT &rect)
   {
      DOCKCONTEXT *ctx = _GetContext(hWnd);
      ATLASSERT(ctx);
      if( ctx==NULL ) return;
      DockState = ctx->Side;
      ::GetWindowRect(::GetParent(hWnd), &rect);
   }

   int GetPaneSize(short Side)
   {
      ATLASSERT(IsDocked(Side));
      int cy = m_panes[Side].m_cy;
      if( cy==0 ) cy = m_panes[Side].m_cyOld;
      return cy;
   }

   void SetPaneSize(short Side, int Size)
   {
      ATLASSERT(IsDocked(Side));
      m_panes[Side].m_cy = ( m_panes[Side].m_map.GetSize()==0 ? 0 : Size );
      m_panes[Side].m_cyOld = Size;
      T* pT = static_cast<T*>(this);
      pT->UpdateLayout();
   }

   // Message handlers

   LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
   {
      for( short i=0; i<4; i++ ) {
         m_panes[i].m_Side = i;
         m_panes[i].Create(m_hWnd, rcDefault, NULL, WS_CHILD|WS_VISIBLE);
      }
      m_sizeBorder.cx = ::GetSystemMetrics(SM_CXEDGE);
      m_sizeBorder.cy = ::GetSystemMetrics(SM_CYEDGE);
      return 0;
   }

   LRESULT OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
   {
      for( int i=0; i<m_map.GetSize(); i++ ) {
         if( ::IsWindow(m_map[i]->hwndDocked) ) ::DestroyWindow(m_map[i]->hwndDocked);
         if( ::IsWindow(m_map[i]->hwndFloated) ) ::DestroyWindow(m_map[i]->hwndFloated);
         delete m_map[i];
      }
      return 0;
   }

   LRESULT OnEraseBackground(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
   {
      return 1; // handled, no background painting needed
   }

   LRESULT OnSize(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
   {
      T* pT = static_cast<T*>(this);
      pT->UpdateLayout();
      return 0;
   }

   // Custom defined messages

   LRESULT OnQueryRect(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
   {
      // wParam: Side
      // lParam: LPRECT
      LPRECT prc = (LPRECT)lParam;
      ATLASSERT(prc);
      switch( (short)wParam ) {
      case DOCK_LEFT:
      case DOCK_TOP:
      case DOCK_RIGHT:
      case DOCK_BOTTOM:
         ::GetWindowRect(m_panes[wParam], prc);
         break;
      case DOCK_INFO_CHILD:
         ::GetWindowRect(m_hwndClient, prc);
         break;
      default:
         ATLASSERT(false);
      }
      return 0;
   }

   LRESULT OnQueryTrack(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/)
   {
      // lParam: TRACKINFO *
      TRACKINFO *pTI = (TRACKINFO *)lParam;
      ATLASSERT(pTI);
      POINT &pt = pTI->ptPos;
      RECT rc;

      if( pTI->ctx->dwFlags & DCK_NOFLOAT ) {
         // If we're not allowed to float, we're still docked to where we came from
         ::GetWindowRect(pTI->hWnd, &rc);
         pTI->rc = rc;
         ::OffsetRect(&pTI->rc, pt.x-pTI->ptStart.x, pt.y-pTI->ptStart.y);
         pTI->Side = pTI->ctx->Side;
      }
      else {
         // But by default, we're floating in the skies
         ::GetWindowRect(pTI->hWnd, &rc);
         ::SetRect(&pTI->rc, rc.left, rc.top, rc.left+pTI->ctx->sizeFloat.cx, rc.top+pTI->ctx->sizeFloat.cy);
         ::OffsetRect(&pTI->rc, pt.x-pTI->ptStart.x, pt.y-pTI->ptStart.y);
         pTI->Side = DOCK_FLOAT;
      }
      // Pressing CTRL key gives default floating
      if( ::GetKeyState(VK_CONTROL)<0 ) return 0;
      // Are we perhaps hovering over the tracked window?
      ::GetWindowRect(pTI->hWnd, &rc);
      if( ::PtInRect(&rc, pt) ) {
         pTI->rc = rc;
         ::OffsetRect(&pTI->rc, pt.x-pTI->ptStart.x, pt.y-pTI->ptStart.y);
         pTI->Side = pTI->ctx->Side;
         return 0;
      }
      // Or is the point inside one of the other docking areas?
      for( short i=0; i<4; i++ ) {
         if( pTI->ctx->dwFlags & (1<<i) ) continue; // DCK_NOxxx flag?
         if( m_panes[i].m_cy==0 ) {
            // Simulate docking areas that are currently invisible
            ::GetWindowRect(m_hWnd, &rc);
            switch( m_panes[i].m_Side ) {
            case DOCK_LEFT: rc.right = rc.left + DEFAULT_DOCKPANE_SIZE; break;
            case DOCK_RIGHT: rc.left = rc.right - DEFAULT_DOCKPANE_SIZE; break;
            case DOCK_TOP: rc.bottom = rc.top + DEFAULT_DOCKPANE_SIZE; break;
            case DOCK_BOTTOM: rc.top = rc.bottom - DEFAULT_DOCKPANE_SIZE; break;
            }
         }
         else {
            ::GetWindowRect(m_panes[i], &rc);
         }
         if( ::PtInRect(&rc, pt) ) {
            pTI->Side = i;
            pTI->rc = rc;
            return 0;
         }
      }
      return 0;
   }

   LRESULT OnDock(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
   {
      T* pT = static_cast<T*>(this);
      pT->_DockWindow((DOCKCONTEXT *)lParam,(short)wParam,0);
      return 0;
   }

   LRESULT OnUnDock(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/)
   {
      T* pT = static_cast<T*>(this);
      pT->_UnDockWindow((DOCKCONTEXT *)lParam);
      return 0;
   }

   LRESULT OnFloat(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/)
   {
      T* pT = static_cast<T*>(this);
      pT->_FloatWindow((DOCKCONTEXT *)lParam);
      return 0;
   }

   LRESULT OnUnFloat(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/)
   {
      T* pT = static_cast<T*>(this);
      pT->_UnFloatWindow((DOCKCONTEXT *)lParam);
      return 0;
   }

   LRESULT OnRepositionWindow(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
   {
      T* pT = static_cast<T*>(this);
      pT->_RepositionWindow((DOCKCONTEXT *)lParam, (int)wParam);
      return 0;
   }

   // Overridables

   void UpdateLayout()
   {
      RECT rect;   
      GetClientRect(&rect);
      RECT rcClient = rect;

      if( m_panes[DOCK_TOP].m_cy>0 ) {
         ::SetWindowPos(m_panes[DOCK_TOP], NULL, rect.left, rect.top, rect.right-rect.left, m_panes[DOCK_TOP].m_cy, SWP_NOZORDER | SWP_NOACTIVATE);
         rcClient.top += m_panes[DOCK_TOP].m_cy;
      }
      if( m_panes[DOCK_LEFT].m_cy>0 ) {
         ::SetWindowPos(m_panes[DOCK_LEFT], NULL, rect.left, rcClient.top, m_panes[DOCK_LEFT].m_cy, rect.bottom - rcClient.top, SWP_NOZORDER | SWP_NOACTIVATE);
         rcClient.left += m_panes[DOCK_LEFT].m_cy;
      }
      if( m_panes[DOCK_RIGHT].m_cy>0 ) {
         int left = max( rect.right-m_panes[DOCK_RIGHT].m_cy, rcClient.left );
         ::SetWindowPos(m_panes[DOCK_RIGHT], NULL, left, rcClient.top, m_panes[DOCK_RIGHT].m_cy, rect.bottom-rcClient.top, SWP_NOZORDER | SWP_NOACTIVATE);
         rcClient.right -= m_panes[DOCK_RIGHT].m_cy;
      }
      if( m_panes[DOCK_BOTTOM].m_cy>0 ) {
         int top = max( rcClient.bottom-m_panes[DOCK_BOTTOM].m_cy, rcClient.top );
         ::SetWindowPos(m_panes[DOCK_BOTTOM], NULL, rcClient.left, top, rcClient.right-rcClient.left, m_panes[DOCK_BOTTOM].m_cy, SWP_NOZORDER | SWP_NOACTIVATE);
         rcClient.bottom -= m_panes[DOCK_BOTTOM].m_cy;
      }

      if( ::IsWindow(m_hwndClient) ) {
         // Adjust borders around docking panes
         DWORD dwExtStyle = (DWORD)::GetWindowLong(m_hwndClient, GWL_EXSTYLE);
         bool bClientEdge = ((dwExtStyle & WS_EX_CLIENTEDGE)!=0);
         if( bClientEdge ) {
            if( m_panes[DOCK_TOP].m_cy>0 ) rcClient.top -= m_sizeBorder.cy;
            if( m_panes[DOCK_LEFT].m_cy>0 ) rcClient.left -= m_sizeBorder.cx;
            if( m_panes[DOCK_RIGHT].m_cy>0 ) rcClient.right += m_sizeBorder.cx;
            if( m_panes[DOCK_BOTTOM].m_cy>0 ) rcClient.bottom += m_sizeBorder.cy;
         }
         // Map client rectangle to windows's coord system
         ::MapWindowPoints(m_hWnd, ::GetParent(m_hwndClient), (LPPOINT)&rcClient, sizeof(rcClient)/sizeof(POINT));
         ::SetWindowPos(m_hwndClient, NULL, rcClient.left, rcClient.top, rcClient.right - rcClient.left, rcClient.bottom - rcClient.top, SWP_NOZORDER);
      }
   }

   BOOL _DockWindow(DOCKCONTEXT *ctx, short Side, int iRequestedSize)
   {
      ATLASSERT(ctx);
      ATLASSERT(IsDocked(Side));
      ATLASSERT(ctx->Side==DOCK_HIDDEN); // Undock before redock
      if( !IsDocked(Side) ) return FALSE;
      if( ctx->Side!=DOCK_HIDDEN ) return FALSE;
      bool bVertical = IsDockedVertically(Side);
      // Make up a new panel size
      if( iRequestedSize<=0 ) {
         RECT rc;
         ::GetClientRect(m_panes[Side], &rc);
         iRequestedSize = bVertical ? rc.bottom-rc.top : rc.right-rc.left;
         if( m_panes[Side].m_map.GetSize()>0 ) iRequestedSize /= m_panes[Side].m_map.GetSize();
      }
      // Set the new size of the pane (subject to readjustment)
      ::SetRectEmpty(&ctx->rcWindow);
      (bVertical ? ctx->rcWindow.bottom : ctx->rcWindow.right) = iRequestedSize;
      ctx->bKeepSize = true;
      // Dock
      m_panes[Side].DockWindow(ctx);
      SendMessage(WM_DOCK_UPDATELAYOUT);
      return TRUE;
   }

   BOOL _FloatWindow(DOCKCONTEXT *ctx)
   {
      ATLASSERT(ctx);
      ATLASSERT(ctx->Side==DOCK_HIDDEN); // Undock before float
      if( ctx->Side!=DOCK_HIDDEN ) return FALSE;
      ctx->Side = DOCK_FLOAT;
      ::SetParent(ctx->hwndChild, ctx->hwndFloated);
      ::SetWindowPos(ctx->hwndFloated, NULL, ctx->rcWindow.left, ctx->rcWindow.top, ctx->rcWindow.right-ctx->rcWindow.left, ctx->rcWindow.bottom-ctx->rcWindow.top, SWP_NOZORDER);
      ::SendMessage(ctx->hwndFloated, WM_DOCK_UPDATELAYOUT, 0,0);
      ::ShowWindow(ctx->hwndFloated, SW_SHOWNORMAL);
      return TRUE;
   }

   BOOL _UnDockWindow(DOCKCONTEXT *ctx)
   {
      ATLASSERT(ctx);
      ATLASSERT(IsDocked(ctx->Side));
      if( !IsDocked(ctx->Side) ) return FALSE;
      m_panes[ctx->Side].UnDockWindow(ctx);
      ctx->Side = DOCK_HIDDEN;
      SendMessage(WM_DOCK_UPDATELAYOUT);
      return TRUE;
   }

   BOOL _UnFloatWindow(DOCKCONTEXT *ctx)
   {
      ATLASSERT(ctx);
      ATLASSERT(ctx->Side==DOCK_FLOAT);
      if( ctx->Side!=DOCK_FLOAT ) return FALSE;
      ::ShowWindow(ctx->hwndFloated, SW_HIDE);
      ctx->Side = DOCK_HIDDEN;
      return TRUE;
   }

   BOOL _RepositionWindow(DOCKCONTEXT *ctx, int iPos)
   {
      ATLASSERT(ctx);
      ATLASSERT(IsDocked(ctx->Side));
      if( !IsDocked(ctx->Side) ) return FALSE;
      m_panes[ctx->Side].RepositionWindow(ctx,iPos);
      return TRUE;
   }

   DOCKCONTEXT *_GetContext(HWND hWnd)
   {
      ATLASSERT(::IsWindow(hWnd));
      for( int i=0; i<m_map.GetSize(); i++ ) if( m_map[i]->hwndChild==hWnd ) return m_map[i];
      ATLASSERT(!"Docking Window not found; use AddWindow() to add it");
      return NULL;
   }

};

class CDockingWindow : public CDockingWindowImpl<CDockingWindow>
{
public:
   DECLARE_WND_CLASS_EX(_T("WTL_DockingWindow"), CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS, NULL)
};


#endif // __ATL_DOCK_H__

⌨️ 快捷键说明

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