My favorites | Sign in
Project Home Downloads Wiki Issues Source
Search
for
WindowsSubMenu  
win32 context menu.
Updated Oct 7, 2010 by Neill.So...@gmail.com

Introduction

Код для контекстного меню win32. Цепляются на кнопку и позволяют значительно расширить функционал кнопки без дополнительно вводимых визуальных элементов на канву. Полезный код для меня по той причине, что такого рода контекстными менюшками я пользуюсь довольно часто.

Details

Имеется два класса

MenuHandle - класс для заполнения менюшки пунктами и обработки их нажатия.

Имеет две виртуальные функции ItemCollect, ItemPress. Их следует переопределить чтобы заполнять меню пунктами и затем обрабатывать выбор пользователя.

ToolMenu - класс от FBComponent, который реализует кнопку и появляющееся по нажатию контекстное меню

Методы для работы с меню

GetControlполезен для установки кнопки на форму, для того чтобы присоединить к требуемому региону
SetHandleзадать обработкик пунктов меню (наполнение и нажатие). Обработчиков может быть сколько угодно, можно разными способами и с разным назначением выполнять заполнение пунктов меню
Showпоказать контекстное меню под курсором мыши
Titleсвойство для задания заголовка меню

Пример использования

Чтобы именовать пункты меню в полу-автоматическом режиме я сделал следующую уловку, используя вложение хедера

MainMenuItems.h

// edit menu
#ifdef	EDITCLASS
EDITCLASS(Undo, MF_STRING, "Undo")
EDITCLASS(Redo, MF_STRING, "Redo")
EDITCLASS(Sep1, MF_SEPARATOR, "")
EDITCLASS(ImpOpt, MF_STRING, "Import from FBOptical")
EDITCLASS(ExpOpt, MF_STRING, "Export to FBOptical")
EDITCLASS(Sep2, MF_SEPARATOR, "")
EDITCLASS(SelectAll, MF_STRING, "Select All")
EDITCLASS(SelectInvert, MF_STRING, "Select Invert")
EDITCLASS(SelectNone, MF_STRING, "Select None")
EDITCLASS(Sep3, MF_SEPARATOR, "")
EDITCLASS(FilterGaps, MF_STRING, "Filter Gaps")
EDITCLASS(FilterSegments, MF_STRING, "Filter Segments")
EDITCLASS(Sep4, MF_SEPARATOR, "")
EDITCLASS(DisplayDebug, MF_STRING, "Display debug drawings")
#endif
// menu segments
#ifdef	SEGCLASS
SEGCLASS(Pick, MF_STRING, "Pick")
SEGCLASS(Trackable, MF_STRING, "Trackable")
SEGCLASS(Paste, MF_STRING, "Assign data from FBOpticalMarker")
SEGCLASS(Merge, MF_STRING, "Merge")
SEGCLASS(CutLeft, MF_STRING, "Cut Left")
SEGCLASS(CutRight, MF_STRING, "Cut Right")
SEGCLASS(Remove, MF_STRING, "Remove")
#endif

Файл MainMenu.h

enum
{
#define	EDITCLASS(menuName, menuType, menuText)	MENU_##menuName,
	#include "MainMenuItems.h"
#undef	EDITCLASS

	MENU_SEG_START,
#define	SEGCLASS(menuName, menuType, menuText)	MENU_##menuName,
	#include "MainMenuItems.h"
#undef	SEGCLASS
};


class	EditHandle	: public MenuHandle
{
public:
	EditHandle()
	{
		MenuItem	item;

#define EDITCLASS(menuName, menuType, menuText) item.id = (int)MENU_##menuName; \
	item.type = menuType;	sprintf(item.text, ""##menuText); \
	mItems.Add(item);
#include "MainMenuItems.h"
#undef EDITCLASS

		mItems[MENU_FilterGaps].state = true;
		mItems[MENU_FilterSegments].state = true;
	}

	int		ItemPress(int item)
	{
		return 1;
	}

	MenuItem		*ItemCollect(int *count)
	{
		CEPointsCloudSettings		&settings = CESystem::instance().OpticalSettings;
		mItems[MENU_DisplayDebug].state = settings.DisplayDebug;

		*count	= mItems.GetCount();
		return mItems.GetArray();
	}

private:
	FBArrayTemplate	<MenuItem>	mItems;
};

Таким образом я определяю локальный массив mItems для класс управления и заполняю его данными из файла MainMenuItems в соотвествии с заполненными там пунктами. В ItemsCollect я обновляю положение переключателей (checkboxes) и возвращаю количество элементов и указатель на массив данных. В ItemPress можно обрабатывать нажатие того или иного пункта.

Example

Для примера возьмем меню для выбора некоторого типа.

mainmenuitem.h

//menu gap
#ifdef	GAPCLASS
GAPCLASS(Linear, MF_STRING, "Linear")
GAPCLASS(Smooth, MF_STRING, "Smooth")
#endif

MainMenu.h

class	GapHandle	: public MenuHandle
{
public:
	GapHandle()
	{
		MenuItem	item;

#define GAPCLASS(menuName, menuType, menuText) item.id = (int)MENU_##menuName; \
	item.type = menuType;	sprintf(item.text, ""##menuText); \
	mItems.Add(item);
#include "MainMenuItems.h"
#undef GAPCLASS

		mItems[MENU_Linear - MENU_GAP_START-1].state = true;
	}

	int		ItemPress(int item)
	{
          // do some action here
		return 1;
	}
	MenuItem		*ItemCollect(int *count)
	{
		*count	= mItems.GetCount();
		return mItems.GetArray();
	}

private:
	FBArrayTemplate	<MenuItem>	mItems;
};

tool.h

GapHandle		gaphandle;

tool.cpp

mGapMenu.SetTitle( ORTOOLTEMPLATE__LABEL );
mGapMenu.SetHandle( &gaphandle );
layout.SetControl( "ButtonGap", mGapMenu.GetControl() );
mGapMenu.GetControl().Caption = "Gap >";

Sign in to add a comment
Powered by Google Project Hosting