Wednesday, May 17, 2006

Adding your own Status Bar Button

Introduction

Hello,

Sometimes you need to have a quick access to your command mainly when this one is about enable/disable something in your software. Using ObjectARX you can easily add a new button to existing AutoCAD Status Bar.

To add this new button to AutoCAD Status Bar we need to derive a new class from AcPane and add our desired appearence and behavior. In this example I will show you how to create a simple ON/OFF button.

How to Begin

Create a new ARX project using ARXWizard. Add a new empty file called MyPane.h and use the follwoing code:

#pragma once
#include "AcStatusBar.h"
class MyPane : public AcPane
{
public:
// ----------------------
MyPane(void)
{
this->SetToolTipText(_T("This is MyPane Button"));
this->SetText(_T(" MyPane [OFF] "));
this->SetStyle(ACSB_POPOUT);
enabled = false;
}
// ----------------------
virtual ~MyPane(void) {;}
// ----------------------
virtual void OnLButtonDown(UINT nFlags, CPoint point)
{
AcPane::OnLButtonDown(nFlags,point);
enabled = !enabled;
CString strLabel;
strLabel.Format(_T(" MyPane [%s] "),enabled ? _T("ON") : _T("OFF"));
this->SetText(strLabel);
this->SetStyle(enabled ? ACSB_NORMAL : ACSB_POPOUT);
AcApStatusBar* pStatus = acedGetApplicationStatusBar();
if (pStatus) pStatus->Update();
}
// ----------------------
virtual void OnRButtonDown(UINT nFlags, CPoint point) {;}
// ----------------------
virtual void OnLButtonDblClk(UINT nFlags, CPoint point) {;}
// ----------------------

private:
bool enabled;
};


In this example we are supporting only the LEFT BUTTON CLICK event. Note that you may support other events too. We have added a bool member to handle the switching between ON / OFF states.

After that we need to add this button when our application starts. Open your acrxEntryPoint.cpp file and add the following include:

#include "MyPane.h"

Now, add a MyPane pointer variable as a member of your application class:

MyPane* pMyPane;

Next, add the following two functions to your application class:

// ----------------------
void AddMyPaneButton()
{
AcApStatusBar* pStatus = acedGetApplicationStatusBar();
if (pStatus) {
pMyPane = new MyPane();
pStatus->Add(pMyPane);
}
}
// ----------------------
void RemoveMyPaneButton()
{
AcApStatusBar* pStatus = acedGetApplicationStatusBar();
if (pStatus && pMyPane) pStatus->Remove(pMyPane);
}
// ----------------------


Finally, we need to call these two functions from inside the kInitAppMsg and kUnloadAppMsg events:

// ----------------------
virtual AcRx::AppRetCode On_kInitAppMsg (void *pkt) {
AcRx::AppRetCode retCode =AcRxArxApp::On_kInitAppMsg (pkt) ;
AddMyPaneButton();
return (retCode) ;
}
// ----------------------
virtual AcRx::AppRetCode On_kUnloadAppMsg (void *pkt) {
AcRx::AppRetCode retCode =AcRxArxApp::On_kUnloadAppMsg (pkt) ;
RemoveMyPaneButton();
return (retCode) ;
}
// ----------------------


That's it. Now if you load your ARX application you will see a new Status Bar Button. Try it to switch between ON/OFF. Cool?

Fernando.

7 comments :

Anonymous said...

Muito bom !

Thank you;

Luis.

Anonymous said...

Hi Fernando,
This is regarding adding button to Status bar. I did all the process you have mentioned. But when I compile the project I get error saying, include file "AcStatusBar.h" not found. I searched the include files but could'nt locate the file. Is the file name different for "AutoCAD 2000" or some other problem ?

Regards,
Jatin.

Fernando Malard said...

Hi Jatin,

AcPane class was introduced at AutoCAD 2004 and it is not available on previous versions.

Remember, this Blog is based on AutoCAD 2004 and much of its contents has been introduced on this version.

Sorry about the bad news.

Regards,
Fernando.

Anonymous said...

Hello,

Why isn't pMyPane deleted after it is removed? Is Autocad responsible for this?

Best regards,
Artur

Fernando Malard said...

Artur,

Actually this is not documented at ObjectARX API. You could give a try and delete it but before do a status bar update by calling the AcApStatusBar::Update() method.

Please let me know if it did work.

Regards,

Anonymous said...

Yes, it works to delete the pane before Update() is called. Also it works on application shut down when the main frame is already destroyed. If Autocad had been responsible for this, the unremoved panes would have been deleted with the status bar (as at this point acedGetApplicationStatusBar() returns NULL).

So, users should delete the status bar items after they remove them (in case dinamically allocated).

Fernando Malard said...

Thanks for the feedback Artur.