2014-03-31 59 views
1

在我的SDI应用程序中,我使用this文章中的CWTLTabViewCtrl类。从子视图WTL更新状态栏

我想知道如何从子视图更新主框架的状态栏。

在为MainFrm.h代码:

CreateSimpleStatusBar(); 

// create tabctrl 
CTabViewCtrl m_MainTabCtrl; 
m_hWndClient = m_MainTabCtrl.Create(
      m_hWnd, rcDefault, NULL, 
      WS_CHILD | WS_VISIBLE, WS_EX_STATICEDGE); 
m_MainTabCtrl.AddPeopleTab(L"People); 

CTabViewCtrl类的代码:

class CTabViewCtrl : public CWTLTabViewCtrl 
{ 
public: 

    CTabViewCtrl() 
    { 
    } 

    virtual ~CTabViewCtrl() 
    { 
    } 
    void AddPeopleTab(LPCTSTR inTabName) 
    { 
     auto tabPeople = CTabPeople; 
     tabPeople->Create(*this, rcDefault, nullptr, WS_CHILD, WS_EX_STATICEDGE); 
     AddTab(inTabName, *tabPeople, FALSE, 0, (LPARAM)theProcessesView); 
    } 
public: 
    DECLARE_WND_SUPERCLASS(NULL, CWTLTabViewCtrl::GetWndClassName()) 

    BOOL PreTranslateMessage(MSG* pMsg) 
    { 
      pMsg; 
      return FALSE; 
    } 

    BEGIN_MSG_MAP_EX(CTabViewCtrl) 
     REFLECT_NOTIFICATIONS() 
     CHAIN_MSG_MAP(CWTLTabViewCtrl) 
    END_MSG_MAP() 
}; 

的代码在我的CTabPeople类(从这个观点我想更新状态栏在mainfrm.h):

class CTabPeople : public CWindowImpl<CTabPeople, CListViewCtrl>, 
          public CCustomDraw<CTabPeople> 
{ 
[snip] 

public: 
    DECLARE_WND_SUPERCLASS(NULL, CListViewCtrl::GetWndClassName()) 

    BOOL PreTranslateMessage(MSG* pMsg) 
    { 
     pMsg; 
     return FALSE; 
    } 

    BEGIN_MSG_MAP(CTabPeople) 
     MESSAGE_HANDLER(WM_CREATE, OnCreate) 
     MESSAGE_HANDLER(WM_CONTEXTMENU, OnContextMenu) 
     COMMAND_ID_HANDLER(IDM_PROCESSTAB_REFRESH, OnMenuRefresh) 
     REFLECTED_NOTIFY_CODE_HANDLER(LVN_COLUMNCLICK, OnColumnClick) 
     CHAIN_MSG_MAP_ALT(CCustomDraw, 1) 
    END_MSG_MAP() 

    LRESULT OnMenuRefresh(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL&bHandled) 
    { 
     // Here i would like to update the status bar created at the mainfrm.h 
     // something like UISetText(0, L"Updating.."); 
    } 

    [snip] 
} 

来自res目录操作搜索我这样做似乎有两种方法来更新状态栏:使用状态栏

  • 的手柄通过发送消息到mainfrm循环更新状态

      CTabPeople视图
    • 直接吧

    我的问题是如何在我的代码中实现上述选项之一。

    谢谢。

  • 回答

    4

    有许多的方式来实现这一目标:

    1. 使主帧的全局,并添加一个成员函数(比如SetStatusText):

      void CMainFrame::SetStatusText(CString strText) 
      { 
          CStatusBarCtrl sb(m_hWndStatusBar); 
          sb.SetText(SB_SIMPLEID, strText); 
      } 
      
      LRESULT CTabPeople::OnMenuRefresh(...) 
      { 
          g_pMainFrame->SetStatusText(_T("Status text")); 
      } 
      
    2. 使用静态成员函数与'这个指针':

      class CMainFrame;// Forward declaration 
      class CMainFrame : public ... 
      { 
      public: 
          CMainFrame() { this_ptr = this; } 
      
          static void SetStatusText(CString strText) 
          { 
           CStatusBarCtrl sb(this_ptr->m_hWndStatusBar); 
           sb.SetText(SB_SIMPLEID, strText); 
          } 
      
          static CMainFrame* this_ptr; 
      }; 
      
      // Initialization (in .cpp file) 
      CMainFrame* CMainFrame::this_ptr = NULL; 
      
      LRESULT CTabPeople::OnMenuRefresh(...) 
      { 
          CMainFrame::SetStatusText(_T("Status text")); 
      } 
      
    3. 使用SendMessage API与自定义消息标识符。可以将消息发送给父控制(CTabViewCtrl),后者又将消息传递给其父节点或主节点,或直接将其发送到主节点。最后一种情况要求您知道有多少个嵌套窗口,或者您可以像前面提到的那样使用主窗口句柄。

      LRESULT CTabPeople::OnMenuRefresh(...) 
      { 
          // Parent control processes the message 
          ::SendMessage(GetParent(), MY_STATUS_MSG, (WPARAM) _T("Status text"), 0); 
          // Main frame processes the message 
          ::SendMessage(::GetParent(GetParent()), MY_STATUS_MSG, (WPARAM) _T("Status text"), 0); 
          ::SendMessage(g_hWndMain, MY_STATUS_MSG, (WPARAM) _T("Status text"), 0); 
      } 
      

      在主框架和/或CTabViewCtrl添加消息处理程序:

      BEGIN_MSG_MAP(CMainFrame) 
          ... 
          MESSAGE_HANDLER(MY_STATUS_MSG, OnSetStatusMsg) 
      END_MSG_MAP() 
      
      LRESULT CMainFrame::OnSetStatusMsg(UINT, WPARAM wParam, LPARAM, BOOL&) 
      { 
          CStatusBarCtrl sb(m_hWndStatusBar); 
          sb.SetText(SB_SIMPLEID, (LPCTSTR) wParam); 
          return FALSE; 
      } 
      
    4. 或者,如果你有状态栏句柄作为一个全球性的,你可以简单地发送SB_SETTEXT消息:

      LRESULT CTabPeople::OnMenuRefresh(...) 
      { 
          ::SendMessage(g_hWndStatus, SB_SETTEXT, MAKEWPARAM(SB_SIMPLEID, 0), (LPARAM) _T("Status text")); 
      } 
      

    选项3和4显然消除了让c (不是面向对象的)。选项2可能是最适用的。

    我还没有测试过这件事,但你有想法。:)

    0

    我的工作只是版本:

    为MainFrm.h:

    class CMainFrame : 
        public CFrameWindowImpl<CMainFrame>, 
        public CUpdateUI<CMainFrame>, 
        public CMessageFilter, public CIdleHandler 
    { 
    public: 
        DECLARE_FRAME_WND_CLASS(NULL, IDR_MAINFRAME) 
        CMainFrame() { this_ptr = this; } 
        static CMainFrame* this_ptr; 
        void SetStatusText(std::wstring strText); 
        //... 
    } 
    

    MainFrm.cpp中

    CMainFrame* CMainFrame::this_ptr = nullptr; 
    
    // m_hWndStatusBar is from atlframe.h 
    void CMainFrame::SetStatusText(std::wstring strText) 
    { 
        ::SetWindowText(m_hWndStatusBar, strText.c_str()); 
    } 
    

    other.cpp

    CMainFrame::this_ptr->SetStatusText(L"program ready");