dcsimg
June 22, 2018
Hot Topics:

Yet another owner draw menu

  • August 27, 1998
  • By Jaroslav Pisk
  • Send Email »
  • More Articles »

This menu is another modification of owner draw menus (#2 if you want to know). I have corrected an error I found (use of uninitialized variable in DrawItem), change item measurement (now the height is the bigger from icon height or menu height) and changed the menu concept from using separate icons for each item to use of image list (CImageList) so all the icons are in one bitmap. For more information see original article by Ben Ashley

What's new

  • Icon size is not determined every time it's needed but is stored in member variables
  • Fixed few unnecesary lines of code

What to use them ?

To be able to use owner draw popup menu items it is neccesary to add following to the main window class:
In the message map:
ON_WM_MEASUREITEM()
In the declaration (header) file:
afx_msg void OnMeasureItem(int nIDCtl, LPMEASUREITEMSTRUCT lpMeasureItemStruct);
And in the definition (source) file:


static CMenu* FindPopupMenuFromID(CMenu* pMenu, UINT nID)

{

	ASSERT_VALID(pMenu);

	// walk through all items, looking for ID match

	UINT nItems = pMenu->GetMenuItemCount();

	for (int iItem = 0; iItem < (int)nItems; iItem++)

	{

		CMenu* pPopup = pMenu->GetSubMenu(iItem);

		if (pPopup != NULL)

		{

			// recurse to child popup

			pPopup = FindPopupMenuFromID(pPopup, nID);

			// check popups on this popup

			if (pPopup != NULL)

				return pPopup;

		}

		else if (pMenu->GetMenuItemID(iItem) == nID || (UINT)pMenu->GetSafeHmenu() == nID)

		{

			// it is a normal item inside our popup

			pMenu = CMenu::FromHandlePermanent(pMenu->m_hMenu);

			return pMenu;

		}

	}

	// not found

	return NULL;

}



void CMainWnd::OnMeasureItem(int nIDCtl, LPMEASUREITEMSTRUCT lpMeasureItemStruct)

{

	if (lpMeasureItemStruct->CtlType == ODT_MENU)

	{

		ASSERT(lpMeasureItemStruct->CtlID == 0);

		CMenu* pMenu;



		_AFX_THREAD_STATE* pThreadState = AfxGetThreadState();

		if (pThreadState->m_hTrackingWindow == m_hWnd)

		{

			// start from popup

			pMenu = CMenu::FromHandle(pThreadState->m_hTrackingMenu);

		}

		else

		{

			// start from menubar

			pMenu = GetMenu();

		}



		pMenu = FindPopupMenuFromID(pMenu, lpMeasureItemStruct->itemID);

		if (pMenu != NULL)

			pMenu->MeasureItem(lpMeasureItemStruct);

		else

			TRACE1("Warning: unknown WM_MEASUREITEM for menu item 0x%04X.\n", lpMeasureItemStruct->itemID);

	}

	else

	{

		CWnd* pChild = GetDescendantWindow(lpMeasureItemStruct->CtlID, TRUE);

		if (pChild != NULL && pChild->SendChildNotifyLastMsg())

			return;     // eaten by child

	}

	// not handled - do default

	Default();

}

Download code 5K

Last updated on: August 27, 1998.






Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.

By submitting your information, you agree that developer.com may send you developer offers via email, phone and text message, as well as email offers about other products and services that developer believes may be of interest to you. developer will process your information in accordance with the Quinstreet Privacy Policy.

Sitemap

×
We have made updates to our Privacy Policy to reflect the implementation of the General Data Protection Regulation.
Thanks for your registration, follow us on our social networks to keep up-to-date