Click here to Skip to main content
15,881,803 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
The end desired result is a CMFCStatusBar with 3 panes, 0, 1, 2. Panes 0 & 2 are to contain programmatically set text; pane 1 is a bitmap. Panes 0 & 1 are of fixed length, pane 2 is “Stretch".

I have the following:
//-----------------------------------------------------------------CMainFrameEx.cpp
C++
ON_UPDATE_COMMAND_UI(IDCTL_SB_Pane_0, &CJBK_MF::OnUpdatePane)

p_SBCls = new CJBK_SB; //Pointer To Status Bar Class - Called by "OnCreate(…)"
ASSERT(p_SBCls->CreateEx(this, SB_CTRL_STYLE, SB_WND_STYLE, IDCls_SB));

sTemp.LoadStringW(ID_Text_SB_Init);                //Called after the above
p_SBCls->SetPaneText(0, sTemp, TRUE);

void CJBK_MF::OnUpdatePane(CCmdUI* p_CmdUI)    
 {
  p_CmdUI->Enable(TRUE);
 }
//--------------------------------------------------------------Status_Bar_Class.cpp
C++
IDArr[0] = IDCTL_SB_Pane_0;
  IDArr[1] = IDCTL_SB_Pane_1;
  IDArr[2] = IDCTL_SB_Pane_2;
  
  p_IDArr = &IDArr[0];
  ASSERT(this->;SetIndicators(p_IDArr, 3));   
//-------------------------------------------------------------------CMainFrameEx.h
C++
afx_msg void OnUpdatePane(CCmdUI* p_CmdUI);

Panes 0 & 1 work correctly.

When I modify CMainframeEx.cpp (see below), Pane 2 does not display the text.

C#
sTemp.LoadStringW(ID_Text_SB_Init);        //Was
p_SBCls->SetPaneText(0, sTemp, TRUE);

sTemp.LoadStringW(ID_Text_SB_Init);                       //Now
p_SBCls->SetPaneText(0, sTemp, TRUE);
sTemp.LoadStringW(ID_Text_SB_ABC);                       
p_SBCls->SetPaneText(2, sTemp, TRUE);


C++
ON_UPDATE_COMMAND_UI(IDCTL_SB_Pane_0, &CJBK_MF::OnUpdatePane) //Was

ON_UPDATE_COMMAND_UI(IDCTL_SB_Pane_0, &CJBK_MF::OnUpdatePane)             //Now
ON_UPDATE_COMMAND_UI(IDCTL_SB_Pane_2, &CJBK_MF::OnUpdatePane)


Can anyone please help me spot why Pane 2 does not display? The status bar contains a "gipper"; does that count in the pane count?

Thanks,
Barry
Posted
Updated 14-Aug-12 4:17am
v3
Comments
Argonia 14-Aug-12 7:45am    
Please paste the correct code. OnUpdatePane is pasted wrong . Please fix it. I suggest you try with LoadString instead of LoadStringW and put a breakpoint there and see if your program does this code and i dont understand where exactly you put the last 2 lines of code in which function ?
BarryPearlman 14-Aug-12 11:45am    
Done
Argonia 15-Aug-12 1:51am    
Did you debug it ? does it reach to the LoadStringW and SetPaneText for the second pane ?

1 solution

A trick is found :) :
C++
// Frame.h
class CMyStatusBar : public CMFCStatusBar
{
public:
    BOOL MySetIndicators(int nCount);
};

class CMainFrame : public CFrameWndEx
{
   CMyStatusBar m_wndStatusBar;
//.. 
public:
    virtual CWnd* GetMessageBar() { return NULL; } // no tracing of menu/toolbar commands in the first pane
//..
};

C++
//Frame.cpp
BOOL CMyStatusBar::MySetIndicators(int nCount)
{
    ASSERT_VALID(this);
    ASSERT(nCount >= 1);  // must be at least one of them

    // free strings before freeing array of elements
    for (int i = 0; i < m_nCount; i++)
    {
        VERIFY(SetPaneText(i, NULL, FALSE));
        SetPaneIcon(i, NULL, FALSE);
    }

    // first allocate array for panes and copy initial data
    if (!AllocElements(nCount, sizeof(CMFCStatusBarPaneInfo)))
        return FALSE;

    ASSERT(nCount == m_nCount);
    RecalcLayout();
    return TRUE;
}

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
//..
	if (!m_wndStatusBar.Create(this))
	{
		TRACE0("Failed to create status bar\n");
		return -1;      // fail to create
	}

	m_wndStatusBar.MySetIndicators(3);
	
	m_wndStatusBar.SetPaneWidth(0, 100);
	m_wndStatusBar.SetPaneBackgroundColor(0, ::afxGlobalData.clrBarFace);
	m_wndStatusBar.SetPaneText(0, _T("Hello"));
	
	m_wndStatusBar.SetPaneWidth(1, 50);
	m_wndStatusBar.SetPaneBackgroundColor(1, ::afxGlobalData.clrBarFace);
	m_wndStatusBar.SetPaneText(1, _T("World")); // or set icon here :)
	
	m_wndStatusBar.SetPaneWidth(2, 1); // very important :)
	m_wndStatusBar.SetPaneBackgroundColor(2, ::afxGlobalData.clrBarFace);
	m_wndStatusBar.SetPaneStyle(2, SBPS_STRETCH);
	m_wndStatusBar.SetPaneText(2, _T("Test"));
//..
}
 
Share this answer
 
v3
Comments
BarryPearlman 15-Aug-12 10:46am    
Sorry, but it still doesn't work Eugen, and debugging shows that the text is placed in the pane information structure in the case of pane 0 and the last pane, Pane 2.

I am wondering if Microsoft decided that the last pane (right) is not intended for text, but rather would be used exclusively for the date and/or keyboard key status information and hence the internal pane coding will not support text. It is above my pay grade to be able to look at the source code and confirm or deny this.

I have tried both suggestions, but with negative results. I do have a few ideas which are unconventional, and will take some time to code and debug. If I am successfull, I will try to write it up and submit it as a seperate article.

Any other ideas are welcome, and thanks to those that have submitted input so far.
Eugen Podsypalnikov 15-Aug-12 11:34am    
Please try the update of the solution :)
BarryPearlman 15-Aug-12 16:07pm    
As usual, scope requirements have changed in the more elaborate direction; I do plan on using your revision and I will try to write it up and submit it to Code Project.

As an aside, I can't find a reference to _GetPanePtr(nIdx) and it appears that m_nCount is a member of something, but what is the something? Is it the number of physical panes?

Thanks,

Barry
Eugen Podsypalnikov 15-Aug-12 19:15pm    
Please try the last solution, ist this that you wanted ? :)
BarryPearlman 16-Aug-12 14:48pm    
Eugen -

The line of code marked "very important" solved the problem of displaying text in Pane 3; I believe that I understand the concept.

I did run into a couple of problems however. The first concerns the code paragraphs:

// free strings before freeing array of elements
for (int i = 0; i < m_nCount; i++)
{
VERIFY(SetPaneText(i, NULL, FALSE));
SetPaneIcon(i, NULL, FALSE);
}

// first allocate array for panes and copy initial data
if (!AllocElements(nCount, sizeof(CMFCStatusBarPaneInfo)))
return FALSE;

When the status bar is first created, there are no strings to cancel and the solution bombs out when it hits the "VERIFY" macro; it is looking to free a string that hasn't been created yet. Reversing the two blocks of code solves that problem.

The second problem concerns:

virtual CWnd* GetMessageBar() { return NULL; } // no tracing of menu/toolbar commands in the first pane

It appears that when you mark the application for context sensitive help, it automatically wants to display AFX_IDS_IDLEMESSAGE (supplied in string table) when the application enters the idle loop.

I let the wizard allow context sensitive help; I wish I had known then and I would have not done it. I need to find out how I can undo that.

Thanks for all of your help,

Barry

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900