Re: Dialog AND a custom Toolbar
On Aug 17, 10:08 pm, "Mark Salsbery [MVP]"
<MarkSalsbery[MVP]@newsgroup.nospam> wrote:
The command enabler functionality through the message map isn't implemented
in modal dialogs.
You can, however, use the undocumented WM_KICKIDLE message to force the same
functionality.
This article has some details:http://www.microsoft.com/msj/0797/c0797.aspx
(search/scroll for WM_KICKIDLE).
I'm not sure if you have to do the ON_UPDATE_COMMAND_UI processing in the
parent dialog class or if you can do it in the toolbar class (using
ON_UPDATE_COMMAND_UI_REFLECT). WM_KICKIDLE is sent to the dialog window.
Mark
--
Mark Salsbery
Microsoft MVP - Visual C++
"RAN" <nijenh...@wish.nl> wrote in message
news:1187379738.106649.72290@w3g2000hsg.googlegroups.com...
Hi,
I used some code from the book Visual C++ 4.0 HowTo, to add a toolbar
to my dialog.
The code is :
void CClientToolBar::OnNeedText (NMHDR* pNotifyStruct, LRESULT*
result)
{
LPTOOLTIPTEXT lpTipText = (LPTOOLTIPTEXT) pNotifyStruct;
UINT nStringID = lpTipText->hdr.idFrom;
TCHAR szFullText[256];
CString strTipText;
AfxLoadString(nStringID,szFullText);
AfxExtractSubString(strTipText,szFullText,1,'\n');
strcpy(lpTipText->lpszText,strTipText);
*result = TRUE;
}
struct CToolBarData
{
WORD wVersion;
WORD wWidth;
WORD wHeight;
WORD wItemCount;
WORD* items()
{ return (WORD*) (this+1); }
};
BOOL CClientToolBar::LoadToolBar (UINT nIDResource)
{
ASSERT_VALID(this);
ASSERT(nIDResource != 0);
HINSTANCE hInst = AfxGetInstanceHandle();
HRSRC hRsrc
= ::FindResource(hInst,MAKEINTRESOURCE(nIDResource),RT_TOOLBAR);
if(hRsrc == NULL)
return FALSE;
HGLOBAL hGlobal = LoadResource(hInst,hRsrc);
if (hGlobal == NULL)
return FALSE;
CToolBarData* pData = (CToolBarData*) LockResource(hGlobal);
if(pData == NULL)
return FALSE;
ASSERT(pData->wVersion == 1);
if(AddBitmap(pData->wItemCount , nIDResource) == -1)
{
UnlockResource(hGlobal);
FreeResource(hGlobal);
return FALSE;
}
UINT* pItems = new UINT[pData->wItemCount ];
for (int i = 0; i< pData ->wItemCount ; i++)
pItems[i] = pData->items ()[i];
BOOL bResult = SetButtons(pItems,pData->wItemCount );
delete[] pItems;
if(bResult)
{
CSize sizeImage(pData->wWidth , pData->wHeight);
CSize sizeButton(pData->wWidth +14, pData->wHeight + 7);
SetBitmapSize(sizeImage);
SetBitmapSize(sizeButton);
}
UnlockResource(hGlobal);
FreeResource(hGlobal);
return bResult;
}
BOOL CClientToolBar::SetButtons(const UINT* lpIDArray, int nIDCount)
{
ASSERT_VALID(this);
ASSERT(nIDCount >= 1);
ASSERT(lpIDArray == NULL || AfxIsValidAddress(lpIDArray, sizeof(UINT)
*nIDCount,FALSE));
int nCount = GetButtonCount();
while(nCount)
VERIFY(DeleteButton(0));
if(lpIDArray != NULL)
{
TBBUTTON button; memset(&button, 0, sizeof(TBBUTTON));
int iImage = 0;
for(int i = 0; i<nIDCount; i++)
{
button.fsState = TBSTATE_ENABLED;
if((button.idCommand = *lpIDArray++) == 0)
{
button.fsStyle = TBSTYLE_SEP;
button.iBitmap = 8;
}
else
{
button.fsStyle = TBSTYLE_BUTTON;
button.iBitmap = iImage++;
}
if(!AddButtons(1,&button))
return FALSE;
}
}
else
{
TBBUTTON button; memset(&button,0,sizeof(TBBUTTON));
button.fsState = TBSTATE_ENABLED;
for(int i = 0; i<nIDCount; i++)
{
ASSERT(button.fsStyle == TBSTYLE_BUTTON);
if(!AddButtons(1,&button))
return FALSE;
}
}
return TRUE;
}
void CClientToolBar::OnToolbarChat()
{
// TODO: Add your command handler code here
THIS GETS CALLED
}
void CClientToolBar::OnUpdateToolbarChat(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
THIS IS NEVER CALLED !!!!
}
In the dialog OnInitDialog():
CRect r(0,0,0,0);
o_ClientToolBar.Create (WS_VISIBLE|WS_CHILD|CCS_TOP|CCS_ADJUSTABLE |
TBSTYLE_TOOLTIPS,r,this,IDR_TOOLBAR1);
o_ClientToolBar.LoadToolBar (IDR_TOOLBAR1);
o_ClientToolBar.AutoSize ();
The Toolbar is added but the UPDATE_COMMAND_UI message is never
called.
What do i have to do to make this work ?
I want to SetCheck() the toolbar button when pressed.- Hide quoted text -
- Show quoted text -
I have read the document from MSJ:
Unfortunately, this wonderful UI update mechanism doesn't work for
dialogs-at least not automatically. You have to hook the pieces up
yourself. Fortunately, it's easy. All you have to do is handle
WM_KICKIDLE, a private MFC message that MFC sends whenever the dialog
is idle (analogous to the app's OnIdle handler) to call
UpdateDialogControls yourself.
LRESULT CTabDialog::OnKickIdle(WPARAM wp,
LPARAM lCount)
{
UpdateDialogControls(this, TRUE);
return 0;
}
CWnd::UpdateDialogControls sends the magic CN_ UPDATE_COMMAND_UI
message to all the dialog controls, the upshot being that now
ON_COMMAND_ UPDATE_UI handlers suddenly work for dialogs.
I have added the messagehandler for OnKickIdle but it is never called,
als the UPDATE_COMMAND_UI handler is never called, am i forgetting
something, do i have to extra stuff to make this work ?
The only thing i have added is this handler in my dialog:
LRESULT CClientDlg::OnKickIdle(WPARAM wParam, LPARAM lParam)
{
UpdateDialogControls(this, TRUE);
return 0;
}