//我创建的statusBar是这样的,
BOOL CMainFrame::CreateStatusBar()
{
    static UINT nIndicators[] = {
        ID_SEPARATOR,
ID_INDICATOR_TIME,
ID_INDICATOR_POSITION,
        ID_INDICATOR_LINE,
        ID_INDICATOR_CAPS,
        ID_INDICATOR_NUM
    };    if (!m_wndStatusBar.Create (this))
        return FALSE;    m_wndStatusBar.SetIndicators (nIndicators, 6);
    return TRUE;
}
// Rc file
STRINGTABLE DISCARDABLE 
BEGIN
    AFX_IDS_SCRESTORE       "Restore the window to normal size"
    AFX_IDS_SCTASKLIST      "Activate Task List"
    ID_INDICATOR_LINE       "Line 00000"
END
//...
STRINGTABLE DISCARDABLE 
BEGIN
    ID_INDICATOR_EXT        "EXT"
    ID_INDICATOR_CAPS       "CAP"
    ID_INDICATOR_NUM        "NUM"
    ID_INDICATOR_SCRL       "SCRL"
    ID_INDICATOR_OVR        "OVR"
    ID_INDICATOR_REC        "REC"
    ID_INDICATOR_TIME       "HH:SS"         //这里的ID与上面的是分开了的。
    ID_INDICATOR_POSITION   "x=  ,y=  "
END
//上面这种情况下,没有添加任何消息,是可以运行的,但是显示的不是"HH:SS","x=  ,y=  ",面是上面的"Restore the window to normal size"
//如果改成这样就行了。
STRINGTABLE DISCARDABLE 
BEGIN
    ID_INDICATOR_TIME       "HH:SS"
ID_INDICATOR_POSITION   "x=  ,y=  "
    ID_INDICATOR_LINE       "Line 00000"
END
// 这到底是为什么呢?不是ID唯一就行了吗?
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////下面是我添加消息的情况://MainFrm.h
afx_msg void OnTimer(UINT nIDEvent);
//MainFrm.cpp  BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
//{{AFX_MSG_MAP(CMainFrame)
ON_WM_CREATE()
ON_WM_CLOSE()
ON_WM_TIMER()   /////////////////////////////////////
//}}AFX_MSG_MAP
    ON_COMMAND_EX (IDW_STYLE_BAR, OnBarCheck)
    ON_UPDATE_COMMAND_UI (IDW_STYLE_BAR, OnUpdateControlBarMenu)
END_MESSAGE_MAP()
//OnCreate()
  SetTimer(ID_TIMER,200,NULL);////
void CMainFrame::OnTimer(UINT nIDEvent) 
{
// TODO: Add your message handler code here and/or call default
CTime time=CTime::GetCurrentTime();
int nHour=time.GetHour()%12;
int nMinu=time.GetMinute(); CString str;
str.Format(_T("%0.2:%0.2"),nHour,nMinu);
m_wndStatusBar.SetPaneText(1,str); CFrameWnd::OnTimer(nIDEvent);
}//编译没有问题,但运行时会出错,到底为什么?  谢谢各位高手!!!!!!!!!!!!!!!!
//

解决方案 »

  1.   

    你的SetTimer(ID_TIMER,200,NULL);和CreateStatusBar()函数调用先后的问题,应该是先CreateStatusBar()再SetTimer(ID_TIMER,200,NULL);
    否则你在定时器里调用m_wndStatusBar.SetPaneText(1,str);的时候wndStatusBar还没有创建,所以出错。
    可以将m_wndStatusBar.SetPaneText(1,str);改为:
    if(m_wndStatusBar.GetSafeHwnd() != NULL)
       m_wndStatusBar.SetPaneText(1,str);
      

  2.   

    你还没创建好状态栏就SetTimer了,这样不行。先查看下是否能取到状态栏的句柄,然后再SetPaneText(1,str); 
      

  3.   

    m_wndStatusBar.SetIndicators (nIndicators, 6);   你只创建了6个Indicator,但是你资源里有8个单项,所有后面两个没显示
     
      

  4.   


    int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
    {
    if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
    return -1;

    //
    // Tell the frame window to permit docking.
    //
        EnableDocking (CBRS_ALIGN_ANY); //
    // Create the toolbar, style bar, and status bar.
    //
        if (!CreateToolBar () ||
            !CreateStyleBar () ||
            !CreateStatusBar ())
            return -1; //
    // Load the saved bar state (if any).
    //
    LoadBarState (_T ("MainBarState"));
    SetTimer(ID_TIMER,500,NULL);      //在这里的,应该是先创建了的吧????
    return 0;
    }
      

  5.   

    to 3 楼:不是在 
    static UINT nIndicators[] = {
            ID_SEPARATOR,
            ID_INDICATOR_TIME,
            ID_INDICATOR_POSITION,
            ID_INDICATOR_LINE,
            ID_INDICATOR_CAPS,
            ID_INDICATOR_NUM
        };
    有ID唯一标记的才有效的吗?
      

  6.   

    CMainFrame的OnCreate里面是怎么写的?
      

  7.   

    是,有标记才有效,上面看错了。  你看看你的资源ID是不是有重复的你的问题好象是 str.Format(_T("%0.2:%0.2"), nHour, nMinu);,没有指明格式化的格式,应该是下面的格式
    str.Format(_T("%0.2d:%0.2d"), nHour, nMinu);
      

  8.   

       static UINT nIndicators[] = {
            ID_SEPARATOR,
            ID_INDICATOR_TIME,
            ID_INDICATOR_POSITION,
            ID_INDICATOR_LINE,
            ID_INDICATOR_CAPS,
            ID_INDICATOR_NUM
        };
    把这个声明成全局的试试
      

  9.   

    的确,是这个问题,谢谢!但现在我发现的问题,我在OnCreate里面SetTimeer了,用classwiarzd里加了void CMainFrame::OnTimer(UINT nIDEvent) 
    {
    // TODO: Add your message handler code here and/or call default
     CTime time=CTime::GetCurrentTime();
    int nHour=time.GetHour()%12;
      int nMinu=time.GetMinute();
     
      CString str;
      str.Format(_T("%0.2d:%0.2d"),nHour,nMinu);
      if(m_wndStatusBar.GetSafeHwnd() != NULL)
      {
        CClientDC dc(this);
           CSize sz=dc.GetTextExtent(str);
        m_wndStatusBar.SetPaneInfo(1,IDS_TIMER,SBPS_NORMAL,sz.cx);
           m_wndStatusBar.SetPaneText(1,str); 
      }
    CFrameWnd::OnTimer(nIDEvent);
    }
    这时在第一次运行时可以正确地显示时间,但是它不更新。永远是第一次的这个时间,为什么呢?但我在CView里面有一个更新行数的,可以正常运行:
    void CMyWordView::OnUpdateLineNumber(CCmdUI* pCmdUI)
    {
        int nLine = GetRichEditCtrl ().LineFromChar (-1) + 1;    CString string;
        string.Format (_T ("Line %d"), nLine);
        pCmdUI->Enable (TRUE);
        pCmdUI->SetText (string);
    }
      

  10.   

    谢谢
    是的,我试过了,是我的错,能正常工作,但还有的问题的是显示位置的真的不行。我写的代码是这样的:
    void CMainFrame::OnMouseMove(UINT nFlags, CPoint point) 
    {
    // TODO: Add your message handler code here and/or call default
    CString str;
    str.Format(_T("x=%d, y=%d"),point.x,point.y);
    m_wndStatusBar.SetPaneText(2,str);
    CFrameWnd::OnMouseMove(nFlags, point);
    }
    // class CMyWordView : public CRichEditView  View类是来自CRichEditView。我本以为是与时间那个的是同一道理的,所以没有问,但现在
    //才发现不是。   为什么呢?
      

  11.   

    你应该在view类中处理WM_MOUSEMOVE消息,框架类的OnMouseMove接收不到鼠标在VIEW上的移动消息比如自定义一个消息来更新状态栏void CXXXView::OnMouseMove(UINT nFlags, CPoint point)
    {
    // TODO: Add your message handler code here and/or call default GetParentFrame()->PostMessage(WM_UPDATE_STATUS, wParam, lParam);  //发送消息更新状态栏

    CView::OnMouseMove(nFlags, point);
    }
      

  12.   


    void CMyWordView::OnMouseMove(UINT nFlags, CPoint point) 
    {
    // TODO: Add your message handler code here and/or call default
    CString str;
        str.Format(_T("x=%d, y=%d"),point.x,point.y);
         ((CMainFrame *)AfxGetMainWnd())->m_wndStatusBar.SetPaneText(2,str);
    CRichEditView::OnMouseMove(nFlags, point);
    }
    //非常感谢Ryanwen