谢谢

解决方案 »

  1.   

    在OnInitDialog() 加入
    static UINT indicators[] =
    {
    ID_SEPARATOR,           // status line indicator
    ID_INDICATOR_CAPS,
    ID_INDICATOR_NUM,
    ID_INDICATOR_SCRL,
    };if (!m_wndStatusBar.Create(this) ||
    !m_wndStatusBar.SetIndicators(indicators1,
     sizeof(indicators1)/sizeof(UINT)))
    {
    TRACE0("Failed to create status bar\n");
    return -1;      // fail to create
    }
    RepositionBars(AFX_IDW_CONTROLBAR_FIRST, AFX_IDW_CONTROLBAR_LAST, 0);
      

  2.   

    那又怎样使状态栏显示菜单或按钮的tooltip呢?
      

  3.   

    不行呀!
    error C2065: 'm_wndStatusBar' : undeclared identifier
    error C2228: left of '.Create' must have class/struct/union type
    error C2228: left of '.SetIndicators' must have class/struct/union type
    error C2065: 'indicators1' : undeclared identifier
    Generating Code...
    Error executing cl.exe.xxx.exe - 4 error(s), 0 warning(s)
      

  4.   

    //加入到OnInitDialog中
    HWND hDlg=GetSafeHwnd();
    HWND hStatusWindow=CreateStatusWindow(WS_CHILD|WS_VISIBLE|WS_BORDER,
    TEXT("状态栏"),hDlg, NULL); 
    int pint[4]={110,250,300,-1};
    ::SendMessage(hStatusWindow,SB_SETPARTS,4,(LPARAM)pint);
    ::SendMessage(hStatusWindow,SB_SETTEXT,1,(LPARAM)TEXT("信息一"));
    ::SendMessage(hStatusWindow,SB_SETTEXT,2,(LPARAM)TEXT("信息二"));
    ::SendMessage(hStatusWindow,SB_SETTEXT,3,(LPARAM)TEXT("信息三"));
      

  5.   

    谢谢xuejian1999(王凯) 
    请问那又怎样使状态栏动态显示菜单或按钮的tooltip呢?
      

  6.   

    在谈判youdlg.h 定义
    CStatusBar  m_wndStatusBar;
      

  7.   

    给你一个微软的例子,你只要从CModelessMain继承一个对话框类即可
    // MdlsMain.h : header file
    //// This is a part of the Microsoft Foundation Classes C++ library.
    // Copyright (C) 1992-1998 Microsoft Corporation
    // All rights reserved.
    //
    // This source code is only intended as a supplement to the
    // Microsoft Foundation Classes Reference and related
    // electronic documentation provided with the library.
    // See these sources for detailed information regarding the
    // Microsoft Foundation Classes product./*****************************************************************************
      Purpose:
    Interface for CModelessMain, a reusable class for creating modeless
    dialogs which act as main application windows.  The dialog contains
    a status bar and a tool bar.  It provides support for ID_VIEW_STATUS_BAR
    and ID_VIEW_TOOLBAR commands, as well as CAPS, NUM, and SCRL key
    indicators.  Functions:
    CModelessMain::CModelessMain()          -- constructor
    CModelessMain::~CModelessMain()         -- destructor
    CModelessMain::Create()                 -- Create dialog window
    CModelessMain::GetStatusBar()           -- access status bar
    CModelessMain::GetToolBar()             -- access toolbar
    CModelessMain::OnClose()                -- handle WM_CLOSE
    CModelessMain::OnEnterIdle()            -- handle WM_ENTERIDLE
    CModelessMain::OnEraseBkgnd()           -- handle WM_ERASEBKGND
    CModelessMain::OnInitDialog()           -- initialize dialog
    CModelessMain::OnInitMenuPopup()        -- handle WM_INITMENUPOPUP
    CModelessMain::OnMenuSelect()           -- handle WM_MENUSELECT
    CModelessMain::OnPaint()                -- handle WM_PAINT
    CModelessMain::OnQueryDragIcon()        -- handle WM_QUERYDRAGICON
    CModelessMain::OnSetMessageString()     -- handle WM_SETMESSAGESTRING
    CModelessMain::OnStatusBarCheck()       -- ID_VIEW_STATUS_BAR handler
    CModelessMain::OnToolBarCheck()         -- ID_VIEW_TOOLBAR handler
    CModelessMain::OnUpdateKeyIndicator()   -- update key indicator items
    CModelessMain::OnUpdateStatusBarMenu()  -- update ID_VIEW_STATUS_BAR items
    CModelessMain::OnUpdateToolBarMenu()    -- update ID_VIEW_TOOLBAR items  Development Team:
    Mary Kirtland
      Ported to 32-bit by:
    Mike Hedley
      Created by Microsoft Product Support Services, Premier ISV Support
      Copyright (c) 1998 Microsoft Corporation. All rights reserved.
    \****************************************************************************/#ifndef __MDLSMAIN_H__
    #define __MDLSMAIN_H__#include "modeless.h"
    #include "dlgbars.h"class CModelessMain : public CModelessDialog
    {
    DECLARE_DYNAMIC(CModelessMain)// Construction
    public:
    CModelessMain();
    BOOL Create(LPCSTR lpszTemplateName,
    const UINT FAR* lpaIDStatus, int cIDStatus,
    const UINT FAR* lpaIDToolbar, int cIDToolbar,
    UINT nIDBitmap);
    BOOL Create(UINT nIDTemplate,
    const UINT FAR* lpaIDStatus, int cIDStatus,
    const UINT FAR* lpaIDToolbar, int cIDToolbar,
    UINT nIDBitmap);// Attributes
    public:
    CStatusBar* GetStatusBar() { return &m_statusBar; }
    CToolBar*   GetToolBar()   { return &m_toolBar; }// Implementation
    public:
    virtual ~CModelessMain(); // Overrides
    virtual BOOL OnInitDialog();protected:
    HICON           m_hIcon; UINT            m_nIDTracking;
    UINT            m_nIDLastMessage; const UINT FAR* m_lpaIDStatusBar;
    int             m_cIDStatusBar;
    CDlgStatusBar   m_statusBar; const UINT FAR* m_lpaIDToolBar;
    int             m_cIDToolBar;
    UINT            m_nIDBitmap;
    CDlgToolBar     m_toolBar; // Generated message map functions
    //{{AFX_MSG(CModelessMain)
    afx_msg void OnClose();
    afx_msg void OnPaint();
    afx_msg BOOL OnEraseBkgnd(CDC* pDC);
    afx_msg HCURSOR OnQueryDragIcon();
    afx_msg void OnEnterIdle(UINT nWhy, CWnd* pWho);
    afx_msg void OnInitMenuPopup(CMenu* pPopupMenu, UINT nIndex, BOOL bSysMenu);
    afx_msg void OnMenuSelect(UINT nItemID, UINT nFlags, HMENU hSysMenu);
    afx_msg LRESULT OnSetMessageString(WPARAM wParam, LPARAM lParam = 0L);
    afx_msg void OnStatusBarCheck();
    afx_msg void OnToolBarCheck();
    afx_msg void OnUpdateStatusBarMenu(CCmdUI* pCmdUI);
    afx_msg void OnUpdateToolBarMenu(CCmdUI* pCmdUI);
    afx_msg void OnUpdateKeyIndicator(CCmdUI* pCmdUI);
    afx_msg LRESULT OnPopMessageString(WPARAM wParam, LPARAM lParam);
    afx_msg BOOL OnToolTipText(UINT, NMHDR* pNMHDR, LRESULT* pResult);
    //}}AFX_MSG
    DECLARE_MESSAGE_MAP()
    };#endif //__MDLSMAIN_H__
      

  8.   

    // Dlgcbr32.cpp : Defines the class behaviors for CModelessMain.
    //
    // This is a part of the Microsoft Foundation Classes C++ library.
    // Copyright (C) 1992-1998 Microsoft Corporation
    // All rights reserved.
    //
    // This source code is only intended as a supplement to the
    // Microsoft Foundation Classes Reference and related
    // electronic documentation provided with the library.
    // See these sources for detailed information regarding the
    // Microsoft Foundation Classes product.#include "stdafx.h"
    #include <afxpriv.h>
    #include "mdlsmain.h"#ifdef _DEBUG
    #define new DEBUG_NEW
    #undef THIS_FILE
    static char THIS_FILE[] = __FILE__;
    #endif/////////////////////////////////////////////////////////////////////////////
    // CModelessMainIMPLEMENT_DYNAMIC(CModelessMain, CModelessDialog)BEGIN_MESSAGE_MAP(CModelessMain, CModelessDialog)
    //{{AFX_MSG_MAP(CModelessMain)
    ON_WM_CLOSE()
    ON_WM_PAINT()
    ON_WM_ERASEBKGND()
    ON_WM_QUERYDRAGICON()
    ON_WM_ENTERIDLE()
    ON_WM_INITMENUPOPUP()
    ON_WM_MENUSELECT()
    ON_MESSAGE(WM_SETMESSAGESTRING, OnSetMessageString)
    ON_MESSAGE(WM_POPMESSAGESTRING, OnPopMessageString)
    //}}AFX_MSG_MAP
    ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTW, 0, 0xFFFF, OnToolTipText)
    ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTA, 0, 0xFFFF, OnToolTipText) // Standard View menu options
    ON_COMMAND(ID_VIEW_STATUS_BAR, OnStatusBarCheck)
    ON_COMMAND(ID_VIEW_TOOLBAR, OnToolBarCheck)
    ON_UPDATE_COMMAND_UI(ID_VIEW_STATUS_BAR, OnUpdateStatusBarMenu)
    ON_UPDATE_COMMAND_UI(ID_VIEW_TOOLBAR, OnUpdateToolBarMenu) // Standard status bar mode indicators
    ON_UPDATE_COMMAND_UI(ID_INDICATOR_CAPS, OnUpdateKeyIndicator)
    ON_UPDATE_COMMAND_UI(ID_INDICATOR_NUM, OnUpdateKeyIndicator)
    ON_UPDATE_COMMAND_UI(ID_INDICATOR_SCRL, OnUpdateKeyIndicator)END_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////
    // CModelessMain Construction/DestructionCModelessMain::CModelessMain()
    {
    m_hIcon = NULL; m_nIDTracking     = 0;
    m_nIDLastMessage  = 0; m_lpaIDStatusBar  = NULL;
    m_cIDStatusBar    = 0; m_lpaIDToolBar    = NULL;
    m_cIDToolBar      = 0;
    m_nIDBitmap       = 0;
    }CModelessMain::~CModelessMain()
    {
    }////////////////////////////////////////////////////////////////////////////
    // CModelessMain::Create
    //      Create saves away information about the status bar and toolbar,
    //      loads the dialog icon, and creates the dialog window.  It assumes
    //      the dialog icon has the same resource ID as the dialog template
    //      itself.BOOL CModelessMain::Create(UINT nIDTemplate,
       const UINT FAR* lpaIDStatus, int cIDStatus,
       const UINT FAR* lpaIDToolbar, int cIDToolbar,
       UINT nIDBitmap)
    {
    m_hIcon = AfxGetApp()->LoadIcon(nIDTemplate); m_lpaIDStatusBar = lpaIDStatus;
    m_cIDStatusBar   = cIDStatus; m_lpaIDToolBar   = lpaIDToolbar;
    m_cIDToolBar     = cIDToolbar;
    m_nIDBitmap      = nIDBitmap; return CModelessDialog::Create(nIDTemplate);
    }BOOL CModelessMain::Create(LPCSTR lpszTemplateName,
       const UINT FAR* lpaIDStatus, int cIDStatus,
       const UINT FAR* lpaIDToolbar, int cIDToolbar,
       UINT nIDBitmap)
    {
    ASSERT(lpszTemplateName != NULL); m_hIcon = AfxGetApp()->LoadIcon(lpszTemplateName); m_lpaIDStatusBar = lpaIDStatus;
    m_cIDStatusBar   = cIDStatus; m_lpaIDToolBar   = lpaIDToolbar;
    m_cIDToolBar     = cIDToolbar;
    m_nIDBitmap      = nIDBitmap; return CModelessDialog::Create(lpszTemplateName);
    }
    /////////////////////////////////////////////////////////////////////////////
    // CModelessMain::OnClose
    //      OnClose handles the WM_CLOSE message by posting a WM_QUIT message
    //      (so the app shuts down), after performing default processing to
    //      actually close the window.void CModelessMain::OnClose()
    {
    CModelessDialog::OnClose();
    // PostQuitMessage(1);
    }/////////////////////////////////////////////////////////////////////////////
    // CModelessMain::OnInitDialog
    //      OnInitDialog centers the dialog on the screen and creates the status
    //      and toolbars.  To make sure the control bars don't overlap any
    //      dialog controls, the dialog's client area is expanded by the amount
    //      of space required for the control bars.BOOL CModelessMain::OnInitDialog()
    {
    CModelessDialog::OnInitDialog(); // Create status bar at the bottom of the dialog window
    if (m_statusBar.Create(this))
    {
    m_statusBar.SetIndicators(m_lpaIDStatusBar, m_cIDStatusBar);
    OnSetMessageString(AFX_IDS_IDLEMESSAGE); // Make a sunken or recessed border around the first pane
    m_statusBar.SetPaneInfo(0, m_statusBar.GetItemID(0),
    SBPS_STRETCH, NULL );
    } // Create toolbar at the top of the dialog window
    if (m_toolBar.Create(this))
    {
    m_toolBar.LoadBitmap(m_nIDBitmap);
    m_toolBar.SetButtons(m_lpaIDToolBar, m_cIDToolBar);
    } m_toolBar.SetBarStyle(m_toolBar.GetBarStyle() |
    CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC); // We need to resize the dialog to make room for control bars.
    // First, figure out how big the control bars are.
    CRect rcClientStart;
    CRect rcClientNow;
    GetClientRect(rcClientStart);
    RepositionBars(AFX_IDW_CONTROLBAR_FIRST, AFX_IDW_CONTROLBAR_LAST,
       0, reposQuery, rcClientNow); // Now move all the controls so they are in the same relative
    // position within the remaining client area as they would be
    // with no control bars.
    CPoint ptOffset(rcClientNow.left - rcClientStart.left,
    rcClientNow.top - rcClientStart.top); CRect  rcChild;
    CWnd* pwndChild = GetWindow(GW_CHILD);
    while (pwndChild)
    {
    pwndChild->GetWindowRect(rcChild);
    ScreenToClient(rcChild);
    rcChild.OffsetRect(ptOffset);
    pwndChild->MoveWindow(rcChild, FALSE);
    pwndChild = pwndChild->GetNextWindow();
    } // Adjust the dialog window dimensions
    CRect rcWindow;
    GetWindowRect(rcWindow);
    rcWindow.right += rcClientStart.Width() - rcClientNow.Width();
    rcWindow.bottom += rcClientStart.Height() - rcClientNow.Height();
    MoveWindow(rcWindow, FALSE); // And position the control bars
    RepositionBars(AFX_IDW_CONTROLBAR_FIRST, AFX_IDW_CONTROLBAR_LAST, 0); // Set the icon for this dialog.  The framework does this automatically
    //  when the application's main window is not a dialog
    SetIcon(m_hIcon, TRUE);         // Set big icon
    SetIcon(m_hIcon, FALSE);        // Set small icon // Finally, center the dialog on the screen
    CenterWindow();
    return TRUE;
    }
      

  9.   

    /////////////////////////////////////////////////////////////////////////////
    // CModelessMain::OnPaint
    // CModelessMain::OnEraseBkgnd
    // CModelessMain::OnQueryDragIcon
    //      These functions are used to display a custom icon for the dialog.
    //
    //      These functions use a technique described in KB article Q87976
    //      to display a custom icon for our dialog window.  We assume that
    //      the icon has been loaded into m_hIcon.void CModelessMain::OnPaint()
    {
    CPaintDC dc(this);
    if (IsIconic() && m_hIcon)
    {
    // Erase the icon background when placed over other app window
    // DefWindowProc(WM_ICONERASEBKGND, (WORD)dc.m_hDC, 0L); // Center the icon
    CRect rc;
    GetClientRect(&rc);
    rc.left = (rc.right - ::GetSystemMetrics(SM_CXICON))/2;
    rc.top  = (rc.bottom - ::GetSystemMetrics(SM_CYICON))/2; // Draw the icon
    dc.DrawIcon(rc.left, rc.top, m_hIcon);
    }
    }BOOL CModelessMain::OnEraseBkgnd(CDC* pDC)
    {
    if (IsIconic() && m_hIcon)
    return TRUE;
    else
    return CModelessDialog::OnEraseBkgnd(pDC);
    }HCURSOR CModelessMain::OnQueryDragIcon()
    {
    return (HCURSOR)m_hIcon;
    }/////////////////////////////////////////////////////////////////////////////
    // CModelessMain::OnInitMenuPopup
    //      OnInitMenuPopup updates the state of items on a popup menu.
    //
    //      This code is based on CFrameWnd::OnInitMenuPopup.  We assume the
    //      application does not support context sensitive help.void CModelessMain::OnInitMenuPopup(CMenu* pPopupMenu, UINT nIndex, BOOL bSysMenu)
    {
    if (!bSysMenu)
    {
    ASSERT(pPopupMenu != NULL); // check the enabled state of various menu items
    CCmdUI state;
    state.m_pMenu = pPopupMenu;
    ASSERT(state.m_pOther == NULL); state.m_nIndexMax = pPopupMenu->GetMenuItemCount();
    for (state.m_nIndex = 0; state.m_nIndex < state.m_nIndexMax;
     state.m_nIndex++)
    {
    state.m_nID = pPopupMenu->GetMenuItemID(state.m_nIndex);
    if (state.m_nID == 0)
    continue; // menu separator or invalid cmd - ignore it ASSERT(state.m_pOther == NULL);
    ASSERT(state.m_pMenu != NULL);
    if (state.m_nID == (UINT)-1)
    {
    // possibly a popup menu, route to first item of that popup
    state.m_pSubMenu = pPopupMenu->GetSubMenu(state.m_nIndex);
    if (state.m_pSubMenu == NULL ||
    (state.m_nID = state.m_pSubMenu->GetMenuItemID(0)) == 0 ||
    state.m_nID == (UINT)-1)
    {
    continue; // first item of popup can't be routed to
    }
    state.DoUpdate(this, FALSE);  // popups are never auto disabled
    }
    else
    {
    // normal menu item
    // Auto enable/disable if command is _not_ a system command
    state.m_pSubMenu = NULL;
    state.DoUpdate(this, state.m_nID < 0xF000);
    }
    }
    }
    }/////////////////////////////////////////////////////////////////////////////
    // CModelessMain::OnEnterIdle
    //      OnEnterIdle updates the status bar when there's nothing better to do.
    //      This code is based on CFrameWnd::OnEnterIdle.void CModelessMain::OnEnterIdle(UINT nWhy, CWnd* pWho)
    {
    if (nWhy != MSGF_MENU || m_nIDTracking == m_nIDLastMessage)
    return; OnSetMessageString(m_nIDTracking);
    ASSERT(m_nIDTracking == m_nIDLastMessage);
    }/////////////////////////////////////////////////////////////////////////////
    // CModelessMain::OnMenuSelect
    //      OnMenuSelect updates the status bar message, based on the state
    //      of the dialog menu.
    //
    //      This code is based on CFrameWnd::OnMenuSelect.  We assume the
    //      application does not support context sensitive help.void CModelessMain::OnMenuSelect(UINT nItemID, UINT nFlags, HMENU hSysMenu)
    {
    // set the tracking state
    if (nFlags == 0xFFFF)
    {
    // cancel menu operation (go back to idle now)
    m_nIDTracking = AFX_IDS_IDLEMESSAGE;
    OnSetMessageString(m_nIDTracking);  // set string now
    ASSERT(m_nIDTracking == m_nIDLastMessage);
    }
    else if (nItemID == 0 ||
     nFlags & (MF_SEPARATOR|MF_POPUP|MF_MENUBREAK|MF_MENUBARBREAK))
    {
    // nothing should be displayed
    m_nIDTracking = 0;
    }
    else if (nItemID >= 0xF000 && nItemID < 0xF1F0)
    {
    // special string table entries for system commands
    m_nIDTracking = ID_COMMAND_FROM_SC(nItemID);
    ASSERT(m_nIDTracking >= AFX_IDS_SCFIRST &&
       m_nIDTracking < AFX_IDS_SCFIRST + 31);
    }
    else
    {
    // track on idle
    m_nIDTracking = nItemID;
    }
    }/////////////////////////////////////////////////////////////////////////////
    // CModelessMain::OnSetMessageString
    //      OnSetMessageString updates the status bar text.
    //
    //      This code is based on CFrameWnd::OnSetMessageString.  We assume
    //      a string ID is always passed in wParam.LRESULT CModelessMain::OnSetMessageString(WPARAM wParam, LPARAM lParam)
    {
    UINT    nIDMsg = (UINT)wParam;
    CString strMsg; if (nIDMsg)
    {
    if (strMsg.LoadString(nIDMsg) != 0)
    m_statusBar.SetWindowText(strMsg);
    else
    TRACE1("Warning: no message line prompt for ID %x%04X\n", nIDMsg);
    } UINT nIDLast     = m_nIDLastMessage;
    m_nIDLastMessage = nIDMsg;
    m_nIDTracking    = nIDMsg;
    return nIDLast;}