|
Yes, this is possible. You need to use the
CStatusBarCtrl::SetIcon method which sets the icon for a pane in a status bar.
You can use the following code if you are using the Prof-UIS CExtStatusControlBar class:
<code>bool bRet = m_wndStatusBar.AddPane( IDS_PANE_TEXT, 1 );
if( !bRet )
return;
int nIndex = m_wndStatusBar.CommandToIndex( IDS_PANE_TEXT );
m_wndStatusBar.SetPaneWidth( nIndex, 100 );
HICON hPaneIcon = NULL;
HINSTANCE hInstResource =
AfxFindResourceHandle(
MAKEINTRESOURCE( IDR_PANE_ICON ),
RT_GROUP_ICON
);
ASSERT( hInstResource != NULL );
if( hInstResource != NULL )
{
hPaneIcon = (HICON)
::LoadImage(
hInstResource,
MAKEINTRESOURCE( IDR_PANE_ICON ),
IMAGE_ICON,
16,
16,
0
);
ASSERT( hPaneIcon != NULL );
}
m_wndStatusBar.GetStatusBarCtrl().SetIcon(
nIndex,
hPaneIcon
);
Best regards,
Dmitriy Yakovlev
|
|
|
|
|
Any suggestions?
|
|
|
|
|
You can use the following code:
class CExtStatusBarComboBox : public CComboBox{
virtual void PostNcDestroy(){
delete this;
}
};
CExtStatusBarComboBox* m_pWndComboBox
m_pWndComboBox = new CExtStatusBarComboBox;
if (!m_pWndComboBox->Create(
WS_CHILD|WS_VISIBLE|WS_TABSTOP|CBS_DROPDOWN,
CRect(0,0,0,200),
&m_pMainFrame->m_wndStatusBar,
IDC_STATUS_BAR_COMBO))
{
TRACE(_T("Failed to create combo box control.\n"));
return;
}
m_pWndComboBox->SetFont(
CFont::FromHandle(
(HFONT)::GetStockObject(DEFAULT_GUI_FONT)
)
);
m_pWndComboBox->AddString( _T("Item 1") );
m_pWndComboBox->AddString( _T("Item 2") );
m_pWndComboBox->AddString( _T("Item 3") );
m_pWndComboBox->AddString( _T("Item 4") );
bool bRet = m_pMainFrame->m_wndStatusBar.AddPane(IDS_PANE_COMBO,m_nPosition);
if(!bRet){
AfxMessageBox(_T("Pane index out of range\nor pane with same ID already exists in the status bar"), MB_ICONERROR);
return;
}
int nIndex = m_pMainFrame->m_wndStatusBar.CommandToIndex(IDS_PANE_COMBO);
if (nIndex == -1)
return;
m_pMainFrame->m_wndStatusBar.SetPaneWidth(nIndex, 100);
m_pMainFrame->m_wndStatusBar.SetPaneControl(m_pWndComboBox, IDS_PANE_COMBO, true);
Best regards,
Dmitriy Yakovlev
|
|
|
|
|
Is it possible to add two buttons in one pane?
I tried, but the buttons always fill the whole pane. So when I add the second button it is drawn over the first one. Then, the first button is hidden...
I looked for style flags and in the RepositionControls() method but I could not find any solution.
|
|
|
|
|
Yes, it is possible.
Currently you can insert only one window into a pane. But there is a workaround. Just create a kind of proxy window, create two buttons in it dynamically, and insert the proxy where you want it.
Best regards,
Dmitriy Yakovlev
|
|
|
|
|
Thanks.
I encountered another problem: I'd like to disable a button control but it seems that disabling is only possible for edit controls. How can I disable (gray) a button using your DisableControl() method?
Stevy
|
|
|
|
|
Hi,
When you use the status bar in dialogs it is enough to call the DisableControl method. As for frame-based applications, the status bar uses the OnUpdateCmdUI handler in which it controlled state of all the panes.
Use the ON_UPDATE_COMMAND_UI macro for creating an update handler for the IDC_STATUS_BAR_BUTTON command. Each status bar pane needs to know whether it is enabled or disabled to display itself properly. If the framework does not find an ON_UPDATE_COMMAND_UI entry during command routing, it automatically enables the user-interface object if there is an ON_COMMAND entry somewhere with the same command ID. Otherwise, it disables it. Therefore, to ensure that a button is enabled/disabled, provide an update handler for the IDC_STATUS_BAR_BUTTON command.
…
afx_msg void OnUpdateStatusBarButton(CCmdUI* pCmdUI);
…
BEGIN_MESSAGE_MAP(CChildFormView, CFormView)
…
ON_UPDATE_COMMAND_UI(IDC_STATUS_BAR_BUTTON, OnUpdateStatusBarButton)
…
END_MESSAGE_MAP()
void CChildFormView::OnUpdateStatusBarButton (CCmdUI* pCmdUI)
{
if( m_pWndButton && ::IsWindow(m_pWndButton->m_hWnd))
pCmdUI->Enable( m_pWndButton->IsWindowEnabled() );
}
Best regards,
Dmitriy Yakovlev
|
|
|
|
|
Prof-UIS seems free only for non-commercial use. May I use the code free in my commercial software?
|
|
|
|
|
Hi,
The CExtStatusControlBar class available in this article can be used in applications of ANY kind and distribured with them for absolutely FREE.
Best regards,
Dmitriy Yakovlev
|
|
|
|
|
Does anyone know how to make the entire status bar fatter? Like you see in Internet Explorer? I need to put some controls on it that need a little bit more room...
Thanks,
Swine
[b]yte your digital photos with [ae]phid [p]hotokeeper - www.aephid.com.
|
|
|
|
|
Hi Swine,
You can set the height of a status bar control's drawing area via the CStatusBarCtrl object.
<code>m_wndStatusBar.GetStatusBarCtrl().SetMinHeight(nMin); where nMin - the height of the status bar, in pixels.
Please see a description of the CStatusBarCtrl::SetMinHeight(int nMin) method in the MSDN library.
Best regards,
Dmitriy Yakovlev
|
|
|
|
|
Hello
I included the files ExtStatusControlBar.cpp and ExtStatusControlBar.h in my project(download statuspanes_demo.zip). After compilation Error:
error C2143: syntax error : missing ';' before '<'
g:\develop\visualc_project\keysacces\extstatuscontrolbar.h(131) : error C2501: 'CArray' : missing storage-class or type specifiers
g:\develop\visualc_project\keysacces\extstatuscontrolbar.h(131) : error C2059: syntax error : '<'
g:\develop\visualc_project\keysacces\extstatuscontrolbar.h(131) : error C2238: unexpected token(s) preceding ';'
G:\Develop\VisualC_Project\KeysAcces\ExtStatusControlBar.cpp(40) : error C2065: 'm_arrPaneControls' : undeclared identifier .... and more!!!!!
Where is the problem
Thanks
|
|
|
|
|
Hi,
The CArray class is declared in the afxtempl.h header file.
Please include this header into an appropriate file in your project (e.g.
into stdafx.h):
#include <afxtempl.h>
Best regards,
Dmitriy Yakovlev
|
|
|
|
|
We've just started using your source code as posted here, and a colleague has taken a look at your license agreement on the Prof-UIS website. The site here implies this status bar code, which is all we are using, is free of charge. The web site seems to disagree, so we want to make sure before we move too far forward.
The code in this listing, and this one alone, can be used free of charge for distribution correct?
|
|
|
|
|
Hi Eric,
The CExtStatusControlBar class available in this article can be used in applications of ANY kind and distribured with them for absolutely FREE.
Best regards,
Dmitriy Yakovlev
|
|
|
|
|
If panes are added which aren't controls, you still have to create string table entries in the resource and pass the identifier as the first parameter to addpane. You can't make up an arbitrary identifer and hope to use SetPaneText for setting the text in the pane. Strange will things happen.
It would be nice to be able to get away from having to define dummy strings in the string resource block.
|
|
|
|
|
It seems the answer to Bamaco2 ("Help - string ID") below is what you are trying to figure out. If not, please let me know.
Best regards,
Dmitriy Yakovlev
|
|
|
|
|
While this is a nice little class, it does seem to be missing quite a few things. For instance you can't add bitmaps or icons. This requires a new class derived from CStatic, which can correctly place the icons/bitmap and paint them on the status bar.
RLYON
|
|
|
|
|
I can't agree with you that it's impossible. The CExtStatusControlBar is just an enhanced version of the standard MFC status bar control, which allows you to put icons into status bar's panes.
This code demonstrates how to put an icon into the first pane:
HICON hIcon = AfxGetApp()->LoadIcon( IDI_ICON );
m_wndStatusBar.GetStatusBarCtrl().SetIcon(0,hIcon);
Best regards,
Dmitriy Yakovlev
|
|
|
|
|
Managed to get the icon displayed correctly. Create a static control with SS_ICON style and then use LoadImage to get the icon. The problem was that I used an arbitary identifier in AddPane instead of a entry from the resource string block. Also, LoadIcon will fail unless the icon is correctly dimensioned for the current system metrics.
The icon can go in any pane with AddPaneControl.
Thanks ....
|
|
|
|
|
A very nice control. Can you give me any idea how to use it in VB.net. I am relative new to Vb.net.
Thanks
|
|
|
|
|
To use this control in applications written in any language supporting COM (including VB.NET), you need to have its corresponding ActiveX component. I am pressed for time at the moment, but later I will try and write it.
Best regards,
Dmitriy Yakovlev
|
|
|
|
|
I know you did not write this whole class, but is there any way to 100% ignore the "string id" with the status bars ?
I know the "base class" and the Win32 control class is implemented with use of resource string identifiers, but I don't want to use them.
I would prefer to work with CString's
I would be so happy to find a "owner draw" status bar control that supports multiple panes and works with nothing more than a CString interface.
Before anyone attempts to convince me to use the resource editor, I have to point out that I have perfectly legitimate reasons to want a CString interface.
Help ?
|
|
|
|
|
Each status bar’s pane should have its own unique identifier. You can read about this in MSDN. But the pane index can be changed but after that we should get access to the pane . That can be done via its identifier, which is the pane's essential property. By the way, resource strings are not so important. You should just declare a unique identifier in your program. That is enough to use it in the status bar. The code below demonstrates this:
int nMyPaneID = 1000;<br />
int nIndex = 0;
m_wndStatusBar.AddPane(nMyPaneID, nIndex); <br />
m_wndStatusBar.SetPaneWidth(nIndex, 100);<br />
m_wndStatusBar.SetPaneText(nIndex, _T("A simple text") );<br />
m_wndStatusBar.RepositionControls();
Best regards,
Dmitriy Yakovlev
|
|
|
|
|
Very nice work, supporting WinXP visual themes. Can you implement Office XP visual style as well ?
|
|
|
|