|
requires significant additions before it can be used as a generic control in real life projects
|
|
|
|
|
This was already acknowledged in the "Limitation" section. Thanks anyway.
|
|
|
|
|
Could you tell me how to create Status bar in VB.net? Thanks in advance.
|
|
|
|
|
First off, this is a great article!!!
I have a situation a little different from what is posted here. I would like to set the font color of the pane based on if I have an error or not. So if I try and write to my serial port and get an error I would like to display the error in RED and if it is successful, I would like to display a success message in GREEN.
How would I go about doing this, since they are both in the same pane and this only seems to change the color based on the pane.
Thanks in advance.
|
|
|
|
|
Check out DrawItem() function is CColoredStatusBarCtrl class. It uses SetTextColor to change the text color. Modify the function to your needs.
Thanks.
"Code till death"
|
|
|
|
|
Just what I needed. Thanks
|
|
|
|
|
Hello Onkar,
I am using this class in my project, however I am facing a problem on win 98 systems. Once the application is run continuously, system is losing its resources. If I change back to normal status bar(default color - black using SetPaneText()) the resource problem is not observed.
Please suggest.
Appreciate ur response at the earliest.
Thanks in advance
Shrinivas
shrinivas
|
|
|
|
|
How can you add this type of status bar to a dialog box
thanks,
mistroseth
|
|
|
|
|
Hi, I read your code and modified it, so anyone else can use your code more comfortable, I try to paste source file here because I don't know how to upload them.
anybody who care for this can email me
Best Regards
|
|
|
|
|
Yeh if u cnn send me the code you modiifed for
satus bar text.
Regarding updating the code use the
Fromatting :
code
its just 3 tabs from this textbox
Thankin you
Vikas Amin
Embin Technology
Bombay
vikas.amin@embin.com
|
|
|
|
|
Great Colors! But it doesn't seem to work when SetPaneText() is called. I have a timer that fires once a second to update the time on the status bar:
CTime TheTime = CTime::GetCurrentTime() ;
CString szMsg ;
szMsg.Format( "%02d:%02d:%02d", TheTime.GetHour(), TheTime.GetMinute(), TheTime.GetSecond() ) ;
m_wndStatusBar.SetPaneText( 3, szMsg ) ;
But it doesn't go through DrawItem() at all (unless I'm just completely clueless, which is quite possible). Or do I have to write my own handler of some kind?
Worse yet, when I open an MDI clild, the SetPaneText() stops working as well.
Any ideas?
Thanks and regards,
Spence
|
|
|
|
|
I would do it like this:
void CMainFrame::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
CTime TheTime = CTime::GetCurrentTime() ;
CString szMsg ;
szMsg.Format( "%02d:%02d:%02d", TheTime.GetHour(), TheTime.GetMinute(), TheTime.GetSecond() ) ;
m_wndStatusBar.m_szStatusString = szMsg;
m_wndStatusBar.RedrawWindow();
CFrameWnd::OnTimer(nIDEvent);
}
Don't use SetPaneText(). Directly modify associated text in the CColoredStatusBarCtrl class. Add member CString's in CColorStatusBar class for each pane text. Replace with them instead of "Red", Green" or "Blue" in DrawItem(). The above code modifies only Black text. For e.g. change following function in CColorStatusBar for your use.
void CColoredStatusBarCtrl::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
...
...
...
switch(lpDrawItemStruct->itemID) {
case 0:
dc.SetTextColor(RGB(0, 0, 255));
dc.TextOut(rect.left+2, rect.top, "Blue");
break;
....
....
}
to
void CColoredStatusBarCtrl::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
case 0:
dc.SetTextColor(RGB(0, 0, 255));
dc.TextOut(rect.left+2, rect.top, m_szStatusString);
break;
}
This will display time in Red text in first pane.
Let me know if it helps.
- Onkar
|
|
|
|
|
Thanks for the quick response!
I took your advice and added a CString array and a SetColoredPaneText() function that also takes a foreground and a background color, then calls RedrawWindow().
It works great until I open an MDI child window then the panes get automatically reset to what's in the string table (which I have as blank since I want to update them dynamically). At that point nothing seems to update them. In fact RedrawWindow() never calls DrawItem().
Is there someway to get the Child from resetting the status bar and controlling it's messages (or whatever the heck it's doing)?
I did find another way around it but it's ugly:
void CMainFrame::UpdateStatusBar( const CString &szMsg, UINT nItem, COLORREF ColorRef )
{
CWindowDC dc( &m_wndStatusBar ) ;
RECT rect ;
m_wndStatusBar.GetItemRect( nItem, &rect ) ;
CFont cf;
cf.CreatePointFont( 100, "Arial" ) ;
dc.SelectObject(&cf) ;
rect.top++ ; rect.bottom-- ;
rect.bottom++ ; rect.right-- ;
dc.FillSolidRect( &rect, ColorRef ) ;
dc.SetBkMode( OPAQUE ) ;
dc.SetTextColor( RGB(225,255,254) ) ;
dc.TextOut( rect.left+1, rect.top, szMsg ) ;
}
That makes it redraw everytime (even after the child is created), but there's lot of ugly flashing (plus I'm sure I've broken some Windows rules). And, when the window is moved or resized, it's redrawn blank and then this routine kicks in and redraws it again.
What should I do?
Thanks again!
Spence
|
|
|
|
|
I think doing all again for CChildView specifically as was done for CMainframe should solve the problem.
- Onkar
|
|
|
|
|
I do something like this:
add member variable to hold the statuspane text:
CString StatusText[4];
add member function to chage the statustext :
void SetTextTo(int index,CString &msg)<br />
{<br />
ASSERT(index<4);<br />
StatusText[index]=msg;<br />
ReDrawWindow();<br />
} do above you do need to change something for the DrawItem() function like bellow:
=======================================================================
switch(lpDrawItemStruct->itemID) {<br />
<br />
..................
CDC dc;<br />
dc.Attach(lpDrawItemStruct->hDC);<br />
<br />
dc.SetBkMode(TRANSPARENT);<br />
switch(lpDrawItemStruct->itemID) {<br />
case 0:<br />
dc.SetTextColor(RGB(0, 0, 255));<br />
dc.TextOut(rect.left+2, rect.top+2,StatusText[(int)lpDrawItemStruct->itemID]);<br />
break;<br />
<br />
case 1:<br />
dc.SetTextColor(RGB(255, 0, 0));<br />
dc.TextOut(rect.left+2, rect.top+2,StatusText[(int)lpDrawItemStruct->itemID]);<br />
break;<br />
<br />
case 2:<br />
dc.SetTextColor(RGB(204, 0, 204));<br />
dc.TextOut(rect.left+2, rect.top+2,StatusText[(int)lpDrawItemStruct->itemID]);<br />
break;<br />
<br />
case 3:<br />
dc.SetTextColor(RGB(192,192,0));<br />
dc.TextOut(rect.left+2, rect.top+2, StatusText[(int)lpDrawItemStruct->itemID]);<br />
break; ......................}
// as before
}
in your CMainFrame you just to do something like this:
for (int i=0; i<4; i++)<br />
{<br />
m_wndStatusBar.GetStatusBarCtrl().SetText("", i, SBT_OWNERDRAW); <br />
m_wndStatusBar.SetPaneInfo( i,m_wndStatusBar.GetItemID(i), SBPS_STRETCH, NULL );<br />
}<br />
m_wndStatusBar.SetTextTo(0,"some text of prompt");<br /> .... //etc
// best regards to all of you!
|
|
|
|
|
void CColoredStatusBarCtrl::SetTextTo(int index,CString &msg)
{
ASSERT(index<4);
m_szStatusText[index]=msg;
CRect rc;
GetItemRect(index, &rc);
rc.left += 2;
rc.top += 2;
rc.bottom -= 2;
rc.right -= 2;
GetStatusBarCtrl().InvalidateRect(rc, TRUE);
}
|
|
|
|
|
hi:lilyflower
when i set one pane of the statusbar to display coordinate of the cursor or current time with this codes,sometimes the statusbar will flash .
How can i fix it?
thanks
|
|
|
|
|
Try to use LockWindowUpdate function. You can see its documentation in MSDN, but in short it holds drawing the locked window until you call UnlockWindowUpdate(). Call these apis at around the code responsible for drawing.
|
|
|
|
|
This works quite well. I have added the variable:
COLORREF crPaneText[3] (I'm only using three status bar panes.) and then another function
SetPaneTextColour(int nPane, COLORREF crTextColour)
{
crPaneText[nPane] = crTextColour;
}
I then changed the
DrawItem code to look like:
CDC dc;
dc.Attach(lpDrawItemStruct->hDC);
dc.SetBkMode(TRANSPARENT);
CRect rect(&lpDrawItemStruct->rcItem);
switch(lpDrawItemStruct->itemID) {
case 0:
dc.SetTextColor(crPaneText[(int)lpDrawItemStruct->itemID]);
dc.TextOut(rect.left+2, rect.top, sStatusText[(int)lpDrawItemStruct->itemID]);
break;
case 1:
dc.SetTextColor(crPaneText[(int)lpDrawItemStruct->itemID]);
dc.TextOut(rect.left + 2, rect.top, sStatusText[(int)lpDrawItemStruct->itemID]);
break;
case 2:
dc.SetTextColor(crPaneText[(int)lpDrawItemStruct->itemID]);
dc.TextOut(rect.left + 2, rect.top, sStatusText[(int)lpDrawItemStruct->itemID]);
break;
case 3:
dc.SetTextColor(RGB(0, 0, 0));
dc.TextOut(rect.left+2, rect.top, m_szStatusString);
break;
}
dc.Detach();
This allows me to have a function in CMainFrame,
void CMainFrame::ShowStatusBarInfo(CString sInfo, int nPane, COLORREF crTextColour)
{
m_wndStatusBar.SetPaneTextColour(nPane, crTextColour);
m_wndStatusBar.SetPaneText(nPane, sInfo);
} to set the text and text colour in a pane on demand.
|
|
|
|
|
if(m_wndStatusBar)
m_wndStatusBar.Invalidate(TRUE);
Instead of RedrawWindow() , that will take you to DrawItem()
|
|
|
|
|
If you add ID_INDICATOR_PAGE to your string table and have this in your mainfrm.cpp:
ON_UPDATE_COMMAND_UI(ID_INDICATOR_PAGE, OnUpdatePage)
and add this to mainfrm.h:
afx_msg void OnUpdatePage(CCmdUI* pCmdUI);
and then you enter this to mainfrm.cpp:
void CMainFrame::OnUpdatePage(CCmdUI* pCmdUI)
{
m_wndStatusBar.GetStatusBarCtrl().SetBkColor(RGB(0,255,0));
}
It will redraw the colored text everytime without ever having to call
m_wndStatusBar.RedrawWindow();
It always calls On_Draw if the BkColor is constantly being set on every ON_COMMAND_UI it would appear.
|
|
|
|
|
Onkar Onkar, bravou bravou, !! Oink Oink !!!;)
Lol u got dun bladddd
|
|
|
|
|