Professional UI Solutions
Site Map   /  Register
 
 

Forum

Please Log In to post a new message or reply to an existing one. If you are not registered, please register.

NOTE: Some forums may be read-only if you are not currently subscribed to our technical support services.

Forums » Prof-UIS Tech Support » Adding a button on CExtPropertyGridToolBar Collapse All
Subject Author Date
Nitesh Singh Oct 11, 2006 - 1:00 AM

Hi...

I want to add a button on the toolbar of my propertygrid. And when that button is clicked then I want to open a dialog box. Can you please show me that by an example.
Thank you.

ALso................ I have mentioned about the painting problem with my propertyGrid. I have sent you the sample project. Please rectify the problem.

Suhai Gyorgy Oct 11, 2006 - 2:12 AM

I can’t try the code just now, but I’d do the followings:

Create a CExtPropertyGridCtrl-derived class and override OnPgcCreateBars method. I can imagine it like this:

bool CMyPropertyGridCtrl::OnPgcCreateBars ()
{
	CExtPropertyGridCtrl::OnPgcCreateBars();
	CExtPropertyGridToolBar * pWnd =
		STATIC_DOWNCAST(
			CExtPropertyGridToolBar,
			GetChildByRTC(RUNTIME_CLASS(CExtPropertyGridToolBar))
		);
	if( pWnd == NULL )
		return;
	UINT nCmdID = ID_MY_BTN;
	LPCTSTR sToolBarBtnText = _T("Text of my button");
	CExtCmdItem * p_cmd = g_CmdManager->CmdGetPtr(g_CmdManager->ProfileNameFromWnd(AfxGetMainWnd()->GetSafeHwnd()), nCmdID);
	ASSERT( p_cmd != NULL );
	p_cmd->m_sToolbarText = sToolBarBtnText;
	HICON hIcon =(HICON)::LoadImage(AfxGetApp()->m_hInstance, MAKEINTRESOURCE( nCmdID ), IMAGE_ICON, 16, 16, 0);
	if( hIcon != NULL )
	{
		VERIFY(g_CmdManager->CmdSetIcon(g_CmdManager->ProfileNameFromWnd(AfxGetMainWnd()->GetSafeHwnd()), nCmdID, hIcon, false));
	} // if( hIcon != NULL )
	pWnd->InsertButton( -1, nCmdID, NULL );
}
Of course if your button is already in a menu or toolbar and you called g_CmdManager->UpdateFromMenu or g_CmdManager->UpdateFromToolBar for that, you dont need to initialize that CExtCmdItem, just call InsertButton.

Now the next thing you need to do is handle the button click. You can do this by overriding OnPgcProcessChildWindowCommand method in your CExtPropertyGridCtrl-derived class. This works much like OnCmdMsg:
void CMyPropertyGridCtrl::OnPgcProcessChildWindowCommand(
	CWnd * pWndChild,
	UINT nID, int nCode,
	void * pExtra,
	AFX_CMDHANDLERINFO * pHandlerInfo
)
{
	if( nID == ID_MY_BTN )
	{
		if ( nCode == CN_COMMAND )
		{
			CMyDialog dlg;
			dlg.DoModal();
		}
		else if ( nCode == CN_UPDATE_COMMAND_UI )
		{
			CCmdUI * pCmdUI = (CCmdUI *)pExtra;
			ASSERT( pCmdUI != NULL );
			pCmdUI->Enable( TRUE );
		}
		return TRUE;
	}
	return CExtPropertyGridCtrl::OnPgcProcessChildWindowCommand(pWndChild, nID, nCode, pExtra, pHandlerInfo);
}
I think that should work.

Suhai Gyorgy Oct 11, 2006 - 3:13 AM

Sorry there’s a little bug in my code. You have to register the command in the command manager by calling g_CmdManager->CmdSetup method instead of calling g_CmdManager->CmdGetPtr.

	if( pWnd == NULL )
		return;
	UINT nCmdID = ID_MY_BTN;
	CExtCmdItem cmd;
	cmd.m_nCmdId = nCmdID;
	cmd.m_sToolbarText = _T("Text of my button");
	VERIFY(g_CmdManager->CmdSetup(g_CmdManager->ProfileNameFromWnd(AfxGetMainWnd()->GetSafeHwnd()), nCmdID, true, NULL));
	HICON hIcon =(HICON)::LoadImage(AfxGetApp()->m_hInstance, MAKEINTRESOURCE( nCmdID ), IMAGE_ICON, 16, 16, 0);
	if( hIcon != NULL )
	{
		VERIFY(g_CmdManager->CmdSetIcon(g_CmdManager->ProfileNameFromWnd(AfxGetMainWnd()->GetSafeHwnd()), nCmdID, hIcon, false));
	} // if( hIcon != NULL )

Nitesh Singh Oct 11, 2006 - 3:44 AM

Can’t it be done without the help of g_CmdManager ;

actually I am not using g_CmdManager in my application to store the commnads information. I have implemented prop UIS only for the perpose of implementing property grids.

Nitesh Singh Oct 11, 2006 - 4:46 AM

Hi Support...

Please give me a sample example. I am getting some problems and errors. thank you.

Suhai Gyorgy Oct 12, 2006 - 4:20 AM

Unfortunately I can’t think of a way how you could do this without the use of command manager. Actually property grid uses the command manager anyway, you just can’t see that from the outside.

I tested the code that I provided earlier and sadly it’s really not working as it is there. So here’s a fix. I tested it with SimpleProperties1(SingleObject) sample downloadable from the beginning of the article Prof-UIS Property Grid.

In resource.h I added line: #define ID_MY_BTN 1002
In .rc file I added line: ID_MY_BTN        ICON     "res\\Dial.ico"
and of course created a Dial.ico file in res folder of sample.

In SimplePropertiesDlg.h I added:

class CMyPropertyGridCtrl : public CExtPropertyGridCtrl
{
	virtual bool OnPgcCreateBars();
	virtual BOOL OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo);
};
and changed dialog’s CExtPropertyGridCtrl m_PGC; variable to CMyPropertyGridCtrl m_PGC;

In SimplePropertiesDlg.cpp file I added::
bool CMyPropertyGridCtrl::OnPgcCreateBars()
{
	CExtPropertyGridCtrl::OnPgcCreateBars();
	CExtPropertyGridToolBar * pWnd =
		STATIC_DOWNCAST(
		CExtPropertyGridToolBar,
		GetChildByRTC(RUNTIME_CLASS(CExtPropertyGridToolBar))
		);    
	if( pWnd == NULL )
		return false;
	UINT nCmdID = ID_MY_BTN;
	CExtCmdItem cmd;
	cmd.m_nCmdID = nCmdID;
	//cmd.m_sToolbarText = _T("Text of my button");
	VERIFY(g_CmdManager->CmdSetup(g_CmdManager->ProfileNameFromWnd(pWnd->GetSafeHwnd()), nCmdID, true, NULL));
	HICON hIcon =(HICON)::LoadImage(AfxGetApp()->m_hInstance, MAKEINTRESOURCE( nCmdID ), IMAGE_ICON, 16, 16, 0);
	if( hIcon != NULL )
	{
		VERIFY(g_CmdManager->CmdSetIcon(g_CmdManager->ProfileNameFromWnd(pWnd->GetSafeHwnd()), nCmdID, hIcon, false));
	}
	pWnd->InsertButton();
	pWnd->InsertButton( -1, nCmdID );
	return true;
}
 
BOOL CMyPropertyGridCtrl::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo)
{
	if( nID == ID_MY_BTN )
	{
		if ( nCode == CN_COMMAND )
		{
			AfxMessageBox(_T("Test"));
		}
		else if ( nCode == CN_UPDATE_COMMAND_UI )
		{
			CCmdUI * pCmdUI = (CCmdUI *)pExtra;
			ASSERT( pCmdUI != NULL );
			pCmdUI->Enable( TRUE );
		}
		return TRUE;
	}
	return CExtPropertyGridCtrl::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
}
So main differences from the first solution:
- button click event has to be handled in OnCmdMsg method
- ProfileNameFromWnd method has to have the toolbar’s HWND as parameter.

Nitesh Singh Oct 12, 2006 - 6:52 AM

thanks for the help... I am getting button now....

But I want to show TOOLTIPS. I tried like this...
.......
UINT nCmdID = ID_MY_BTN;
CExtCmdItem cmd;
cmd.m_nCmdID = nCmdID;

cmd.m_sTipTool = _T("tooltip for the button"); /// Line added

VERIFY(g_CmdManager->CmdSetup(g_CmdManager->ProfileNameFromWnd(pWnd->GetSafeHwnd()), nCmdID, true, NULL));
.....

But its not working...

.................... Can you please tell me the right term.. Thank you

Suhai Gyorgy Oct 12, 2006 - 7:37 AM

Again, mistake in my code. To set tip write this:

	cmd.m_sTipTool = _T("Tip of my button");
	VERIFY(g_CmdManager->CmdSetup(g_CmdManager->ProfileNameFromWnd(pWnd->GetSafeHwnd()), cmd, true, NULL));
Difference: second parameter of CmdSetup has to be cmd instead of nCmdID.

Nitesh Singh Oct 12, 2006 - 11:10 PM

thanks Suhai.... its working fine now...