views:

23

answers:

0

How can you have CDockablePane have it own panel in the Taskbar, and that it is not always on top of the main window? In other words, have the pane works like normal windows.

I've tried to set the pane window's style but without success.

LONG windowExStyle = GetWindowLong( GetSafeHwnd(), GWL_EXSTYLE );
windowExStyle |= WS_EX_APPWINDOW;
windowExStyle &= ~WS_EX_TOPMOST;
SetWindowLong( GetSafeHwnd(), GWL_EXSTYLE, windowExStyle);

EDIT:

I have it partly working, but I can't get the "not always on top" working properly without getting asserts and crashing. Here's what I got:

#define HTBUTTON_MAXIMIZE HTHELP + 10

class MaximizeCaptionButton : public CMFCCaptionButton
{
public:

  MaximizeCaptionButton()
    : CMFCCaptionButton( HTBUTTON_MAXIMIZE )
  {
  }

  virtual CMenuImages::IMAGES_IDS GetIconID (BOOL bHorz, BOOL bMaximized) const
  {
    switch (m_nHit)
    {
    case HTBUTTON_MAXIMIZE:
      return CMenuImages::IdMaximize;
    }

    return CMFCCaptionButton::GetIconID (bHorz, bMaximized);
  }


  virtual void OnDraw (CDC* pDC, BOOL bActive, BOOL bHorz = TRUE, BOOL bMaximized = TRUE, BOOL bDisabled = FALSE)
  {
    CMFCVisualManager::GetInstance()->OnDrawCaptionButton(
      pDC, this, bActive, FALSE, FALSE, FALSE, CMenuImages::IdMaximize);
  }
};

class CMultiPaneFrameWndEx : public CMultiPaneFrameWnd
{
  DECLARE_SERIAL(CMultiPaneFrameWndEx)
  DECLARE_MESSAGE_MAP()

public:

  CMultiPaneFrameWndEx()
    : mWindowState(SW_NORMAL)
  {

  }

  HWND mRealParent;

  virtual BOOL PreCreateWindow(CREATESTRUCT& cs)
  {
    cs.style &= ~MFS_SYNCACTIVE;
    //cs.style &= ~WS_POPUP;
    cs.style |= WS_OVERLAPPED;
    //cs.style |= WS_CHILD;
    cs.dwExStyle |= WS_EX_APPWINDOW;
    cs.dwExStyle &= ~WS_EX_TOPMOST;
    mRealParent = cs.hwndParent;
    //cs.hwndParent = ::GetDesktopWindow();
    return CWnd::PreCreateWindow(cs);
  }

  LRESULT OnFloatStatus(WPARAM wParam, LPARAM)
  {
    return 0;
  }

  BOOL OnNcActivate(BOOL bActive)
  {
    if ((GetStyle() & MFS_SYNCACTIVE) == 0)
    {
      bActive = (GetFocus() == this);
      if (m_bActive != bActive)
      {
        m_bActive = bActive;
        if (m_pDockManager != NULL)
        {
          SendMessage(WM_NCPAINT);
        }
      }
    }
    else if (m_nFlags & WF_KEEPMINIACTIVE)
    {
      return FALSE;
    }

    return TRUE;
  }

  virtual void SetCaptionButtons(DWORD dwButtons)
  {
    ASSERT_VALID(this);
    RemoveAllCaptionButtons();

    if (dwButtons & AFX_CAPTION_BTN_CLOSE)
    {
      CBasePane* pBar = DYNAMIC_DOWNCAST(CBasePane, GetPane());
      if (pBar != NULL && pBar->CanBeClosed())
      {
        AddButton(HTCLOSE);
      }
    }

    if (dwButtons & AFX_CAPTION_BTN_PIN)
    {
      AddButton(HTMAXBUTTON);
    }

    if (dwButtons & AFX_CAPTION_BTN_MENU)
    {
      AddButton(HTMINBUTTON);
    }

    if (dwButtons & AFX_CAPTION_BTN_CUSTOMIZE)
    {
      AddButton(AFX_HTMENU);
    }

    if (dwButtons & AFX_CAPTION_BTN_MAXIMIZE)
    {
      m_lstCaptionButtons.AddHead( new MaximizeCaptionButton() );
    }

    m_dwCaptionButtons = dwButtons;
    SetCaptionButtonsToolTips();

    ArrangeCaptionButtons();
    SendMessage(WM_NCPAINT);
  }

  virtual void OnPressButtons(UINT nHit)
  {
    switch (nHit)
    {
    case HTBUTTON_MAXIMIZE:
      {
        if ( mWindowState != SW_MAXIMIZE )
        {
          GetWindowRect( mWindowedRect );
          ShowWindow( SW_SHOWMAXIMIZED );
          LONG windowStyle = GetWindowLong( GetSafeHwnd(), GWL_STYLE );
          LONG windowExStyle = GetWindowLong( GetSafeHwnd(), GWL_EXSTYLE );

//           windowStyle &= ~WS_POPUP;
//           windowStyle |= WS_OVERLAPPEDWINDOW;
          SetWindowLong( GetSafeHwnd(), GWL_STYLE, windowStyle);

          windowExStyle |= WS_EX_APPWINDOW;
          windowExStyle &= ~WS_EX_TOPMOST;
          SetWindowLong( GetSafeHwnd(), GWL_EXSTYLE, windowExStyle);
          mWindowState = SW_MAXIMIZE;
        }
        else
        {
          // Restore window state
          MoveWindow( mWindowedRect );
          ShowWindow( SW_RESTORE );
          mWindowState = SW_NORMAL;
        }
        AdjustPaneFrames();
      }
      return;
    }

    CMultiPaneFrameWnd::OnPressButtons (nHit);
  }

protected:

  CRect mWindowedRect;
  int   mWindowState;
};

class DockablePaneEx : public CDockablePane
{
public:
  DockablePaneEx()
  {
    m_pMiniFrameRTC = RUNTIME_CLASS(CMultiPaneFrameWndEx);
  }

  virtual BOOL Create(LPCTSTR lpszCaption, CWnd* pParentWnd, const RECT& rect, BOOL bHasGripper, UINT nID, DWORD dwStyle, 
    DWORD dwTabbedStyle = AFX_CBRS_REGULAR_TABS, DWORD dwControlBarStyle = AFX_DEFAULT_DOCKING_PANE_STYLE, 
    CCreateContext* pContext = NULL)
  {
    ASSERT_VALID(this);
    return CreateEx(0, lpszCaption, pParentWnd, rect, bHasGripper, nID, dwStyle, dwTabbedStyle, dwControlBarStyle, pContext);
  }

  virtual BOOL CreateEx(DWORD dwStyleEx, LPCTSTR lpszCaption, CWnd* pParentWnd, const RECT& rect, BOOL bHasGripper, 
    UINT nID, DWORD dwStyle, DWORD dwTabbedStyle = AFX_CBRS_REGULAR_TABS, 
    DWORD dwControlBarStyle = AFX_DEFAULT_DOCKING_PANE_STYLE, CCreateContext* pContext = NULL)
  {
    CONST BOOL bRet = __super::CreateEx(dwStyleEx, lpszCaption, pParentWnd, rect, bHasGripper, nID, dwStyle, dwTabbedStyle, 
      dwControlBarStyle, pContext);
    m_pMiniFrameRTC = RUNTIME_CLASS(CMultiPaneFrameWndEx);
    return bRet;
  }

  virtual void OnDrawCaption() 
  {
    CDockablePane::OnDrawCaption();
  }

  virtual void SetCaptionButtons()
  {
    CDockablePane::SetCaptionButtons ();

    m_arrButtons.Add(new MaximizeCaptionButton());
  }

  void OnPressButtons (UINT nHit)
  {
    switch (nHit)
    {
    case HTBUTTON_MAXIMIZE:
      MessageBox (_T("HTBUTTON_MAXIMIZE"));

      return;
    }

    CDockablePane::OnPressButtons (nHit);
  }

  virtual void OnAfterFloat()
  {
    __super::OnAfterFloat();
    CPaneFrameWnd* parentMiniFrame = GetParentMiniFrame(FALSE);
    if ( parentMiniFrame )
    {
      parentMiniFrame->SetCaptionButtons( AFX_CAPTION_BTN_MAXIMIZE | AFX_CAPTION_BTN_CLOSE );
    }
  }
};