Microsoft KB Archive/194294

= How To Add Toolbars and Tooltips to ActiveX Controls =

Article ID: 194294

Article Last Modified on 11/21/2006

-

APPLIES TO

 Microsoft Foundation Class Library 4.2, when used with:  Microsoft Visual C++ 4.0 Standard Edition

 Microsoft Visual C++ 4.1 Subscription

 Microsoft Visual C++ 4.2 Enterprise Edition

 Microsoft Visual C++ 4.2 Professional Edition</li></ul>

 Microsoft Visual C++ 5.0 Enterprise Edition</li></ul>

 Microsoft Visual C++ 5.0 Professional Edition</li></ul> </li></ul>

-

<div class="notice_section">

This article was previously published under Q194294

<div class="summary_section">

SUMMARY
An ActiveX control can have a toolbar (a CToolBar class) as its child window. This article shows a way to create such a toolbar and also how to implement tooltips for buttons on the toolbar window.

<div class="moreinformation_section">

MORE INFORMATION
Visual C++ provides two methods to create a toolbar. The article desribes how to create a toolbar resource using the Resource Editor. If you already have a bitmap resource, please refer to the online documentation "Converting Bitmaps to Toolbars" for converting your bitmap resource to a toolbar resource.

Steps are shown below:

<ol> Use the MFC ActiveX Control Wizard to generate an MFC ActiveX control.</li> Create a Toolbar resource in the control's project.</li> Add a tooltip string resource for each button in the toolbar. These tooltip string resources will be loaded in the TTN_NEEDTEXT notification code handler.</li>  Add a WH_GETMESSAGE hook callback function to the ActiveX control- derived class. The hook procedure is in charge of calling the application's PreTranslateMessage, and this results in the call to FilterToolTipMessage, which activates tooltips. A hook procedure is needed because the ActiveX control is just like an inproc server[ASCII 151]no message pump is found: HHOOK hHook = NULL;

// Hook procedure for WH_GETMESSAGE hook type. LRESULT CALLBACK GetMessageProc(int nCode, WPARAM wParam, LPARAM        lParam) {       // Switch the module state for the correct handle to be used. AFX_MANAGE_STATE(AfxGetStaticModuleState);

// If this is a keystrokes message, translate it in controls' // PreTranslateMessage. LPMSG lpMsg = (LPMSG) lParam;

if( (nCode >= 0) &&         PM_REMOVE == wParam &&          AfxGetApp->PreTranslateMessage(lpMsg)) {          lpMsg->message = WM_NULL; lpMsg->lParam = 0L; lpMsg->wParam = 0; }

// Passes the hook information to the next hook procedure in      // the current hook chain. return ::CallNextHookEx(hHook, nCode, wParam, lParam); }                   </li>  Create the toolbar window (a CToolBar class), which is a child window of the ActiveX control. This is done in response to WM_CREATE message. In addition, WM_CREATE message handler is also a good place to install the WH_GETMESSAGE hook procedure. int CCToolBarCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct) {        if (COleControl::OnCreate(lpCreateStruct) == -1) return -1;

// Create a CToolBar window which is a child of ActiveX control. if (!m_ToolBar.Create(this, WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_TOOLTIPS) ||             !m_ToolBar.LoadToolBar(IDR_TOOLBAR)) {              TRACE0("Failed to create toolbar\n"); return -1;     // fail to create }

// Toolbar has to have TBSTYLE_TOOLTIPS style. Otherwise, // notification handler for TTN_NEXTTEXT won't be called. m_ToolBar.ModifyStyle (0, TBSTYLE_TOOLTIPS);

// Move the toolbar so it is VISIBLE on the screen. CRect rc; GetClientRect(&rc); rc.bottom = rc.top + 34; m_ToolBar.MoveWindow(&rc);

// Because ActiveX control is an inproc server, it does not have a        // message pump. So, messages to child windows created by the // ActiveX control are not going to be received by the control. // Thus, we set up a message hook to call PreTranslateMessage. // This results in the call to FilterToolTipMessage, which // activates tooltips. hHook = ::SetWindowsHookEx(           WH_GETMESSAGE,            GetMessageProc,            AfxGetInstanceHandle,            GetCurrentThreadId); ASSERT (hHook);

return 0; }                   </li>  Uninstall the message hook function in response to WM_DESTROY message: void CCToolBarCtrl::OnDestroy {        // Remove the message hook function. VERIFY (::UnhookWindowsHookEx (hHook));

COleControl::OnDestroy; }                   </li>  Add a TTN_NEEDTEXTW (for Unicode notification code) or TTN_NEEDTEXTA (for ANSI notification code) notification handler to the ActiveX control-derived class. Load the tooltip string to be displayed in this notification code handler: BEGIN_MESSAGE_MAP(CCToolBarCtrl, COleControl) //AFX_MSG_MAP ON_OLEVERB(AFX_IDS_VERB_PROPERTIES, OnProperties)

// ANSI notification code (for Windows 95) ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTA, 0, 0xFFFF, OnToolTipNotify)

// Unicode notification code (for NT) ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTW, 0, 0xFFFF, OnToolTipNotify) END_MESSAGE_MAP

// Notification handler for tooltips - determine which tooltip // string resource to be displayed. BOOL CCToolBarCtrl::OnToolTipNotify(        UINT id, NMHDR * pNMHDR, LRESULT * pResult) {        TOOLTIPTEXTA* pTTTA = (TOOLTIPTEXTA*) pNMHDR; TOOLTIPTEXTW* pTTTW = (TOOLTIPTEXTW*) pNMHDR;

int strid = 0; switch (pNMHDR->idFrom) {        case ID_BUTTON1: strid = IDS_BUTTON1; break;

case ID_BUTTON2: strid = IDS_BUTTON2; break;

case ID_BUTTON3: strid = IDS_BUTTON3; break; }

if (strid) {         *pResult = 0; CString str; str.LoadString(strid); #define _countof(array) (sizeof(array)/sizeof(array[0])) #ifndef _UNICODE if (pNMHDR->code == TTN_NEEDTEXTA) lstrcpyn(pTTTA->szText, str, _countof(pTTTA->szText)); else _mbstowcsz(pTTTW->szText, str, _countof(pTTTW->szText)); #else if (pNMHDR->code == TTN_NEEDTEXTA) _wcstombsz(pTTTA->szText, str, _countof(pTTTA->szText)); else lstrcpyn(pTTTW->szText, str, _countof(pTTTW->szText)); #endif return TRUE; }

return FALSE; }                   </li></ol>

(c) Microsoft Corporation 1998, All Rights Reserved. Contributions by Yeong- Kah Tam, Microsoft Corporation.

Additional query words: ocx kbDSupport

Keywords: kbhowto kbmfcctrlbar kbtoolbar KB194294

-

[mailto:TECHNET@MICROSOFT.COM Send feedback to Microsoft]

© Microsoft Corporation. All rights reserved.