Студопедия

Главная страница Случайная страница

Разделы сайта

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника






Спеціальні типи меню та їх використання






Загальні відомості про спеціальні типи меню

До спеціальних типів меню, власне, належать два типи: динамічні та спливаючі (floating). Використання таких типів меню додає більшої гнучкості у проектуванні інтерфейсу користувача. Але, розглядаючи, спеціальні типи меню, слід вказати на певні їх відмінності від стандартних меню, що вже розглянуті. На відміну від стандартних видів меню, для спеціальних типів визначаються обробники змін, за допомогою яких можна керувати станом елементів меню.

Обробники змін визначають режим відображення елемента меню. Інколи згадують [6] про спеціальний рівень обробки, що виконується, коли меню активовано, але ще не відображено на екрані. Саме у цей момент викликаються обробники змін, що визначають чи має бути доступним даний елемент чи ні або чи матиме він спеціальну позначку вибору поряд зі своєю назвою.

Під час активації меню програмі надсилається повідомлення Windows MENUPOPUP. Це повідомлення автоматично перехоплюється MFC та перетворюється у виклик відповідного обробника змін. Для стандартних обробників схема є дуже простою: кожен елемент меню, якому у карті повідомлень відповідає макрокоманда ON_COMMAND() є доступним, інші ж, що не мають відповідних макрокоманд і не поставлені у відповідність стандартним обробникам є недоступними.

Механізм автоматичного внесення змін у меню можна відмінити. Для цього необхідно встановити значення змінної m_pAutoMenuEnable класу СFrameWnd рівним FALSE.

Процедура визначення власного обробника змін є доволі легкою. Для цього необхідно виконати дві дії. Спочатку слід для кожного елемента меню, що має оброблятися, включити у чергу повідомлень макрокоманду ON_UPDATE_COMMAND_UI(), після чого визначити функцію-обробник.

Макрокоманда ON_UPDATE_COMMAND_UI() має такий вигляд:

 

ON_UPDATE_COMMAND_UI(ID, Handler)

 

де ID – ідентифікатор оброблюваного елемента меню, handler – містить ім’я відповідного обробника змін. Кожен обробник змін має відповідати такому вигляду:

 

void Handler(CCmdUI *UIOb);

 

де UIOb – покажчик на об’єкт типу CCmdUI. CCmdUI є спеціальним класом, що існує виключно для підтримки механізму внесення змін до меню. Він не є частиною ієрархії класів MFC і тому не породжується від CObject. Цей клас використовується лише для позначення типу параметрів у обробниках змін. Клас CCmdUI містить ряд функцій, призначених для керування елементами меню. Однією з них є функція Enable(), що має такий прототип:

 

void CCmdUI:: Enable(BOOL bOn = TRUE);

Функція Enable() встановлює стан елемента меню. Якщо параметр bOn дорівнює TRUE, елемент стає доступним і, якщо рівний FALSE – недоступним. Також у класі CСmdUI містяться функції, що дозволяють встановлювати позначку вибору поряд з назвою елемента або змінювати текст самої назви.

Коли усі дії стосовно визначення обробника змін виконані, він викликатиметься замість стандартного обробника. Слід, однак, не плутати обробники змін з обробниками ON_COMMAND(). Обробники змін виконують дії, пов’язані з відображенням меню, обробники повідомлень реагують на вибір елементів меню.

 

7.2 Основні функції визначення динамічних меню

 

В той час як більшість простих Windows-програм використовує статичне визначення меню, складніші програми потребують динамічного внесення або вилучення елементів меню безпосередньо під час виконання програми. Меню, вміст якого може змінюватися під час роботи програми, називаються динамічними. Їх перевагою такого меню є те, що воно надає користувачу саме той набір опцій, який відповідає поточному стану програми.

Windows має декілька API-функцій, призначених для керування вмісту меню під час виконання програми. Ці функції включаються у MFC за допомогою класу CMenu.

Для додавання елемента у меню під час роботи програми використовується функція InsertMenu() із такими прототипами:

 

BOOL CMenu:: InsertMenu(UINT nPosition, UINT nFlags, UINT nIDNewItem = 0, LPCTSTR lpszNewItem = NULL);

BOOL CMenu:: InsertMenu(UINT nPosition, UINT nFlags, UINT nIDNewItem, const CBitmap* pBmp);

 

де параметрами функцій є:

nPosition – визначає позицію меню, до якої має додаватися новий пункт;

nFlags – визначає характер інтерпретації параметра nPosition у спосіб вказаний у таблиці 7.1:

 

Таблиця 7.1 – Стандартні значення параметра nPosition

Значення коду Коментар до інтерпретації nPosition
MF_BYCOMMAND параметр nPosition міститиме ідентифікатор існуючого пункту меню (значення за замовчуванням, якщо жоден з параметрів MF_BYCOMMAND або MF_BYPOSITION не встановлений)
MF_BYPOSITION параметр nPosition міститиме індекс позиції, у яку встановлюється новий елемент; індекси починаються з 0; під час додавання елемента в кінець меню у пара-метрі nPosition можна вказати -1

nIDNewItem – визначає або ідентифікатор нового пункту меню або (якщо nFlags встановлений у значення MF_POPUP) дескриптор меню (HMENU); ігнорується, якщо nFlags встановлений у значення MF_SEPARATOR;

lpszNewItem – визначає зміст текстової позначки нового пункту меню. Значення попереднього параметра nFlags можуть використовуватися для інтерпретації lpszNewItem у спосіб, зазначений у таблиці 7.2:

 

Таблиця 7.2 – Стандартні значення параметра lpszNewItem

Значення коду Коментар до інтерпретації параметра lpszNewItem
MF_OWNERDRAW містить 32-розрядне значення, яке показує, що програма може підтримувати додаткові дані, позв'язані з пунктом меню (доступно програма обробляє повідомлення WM_MEASUREITEM та WM_DRAWITEM)
MF_STRING містить покажчик на рядок з нульовим символом наприкінці (інтерпретація, задана за замовчуванням)
MF_SEPARATOR параметр lpszNewItem ігнорується

pBmp – покажчик на об’єкт типу CBitmap, що має використовуватися як пункт меню.

Для додавання нових елементів у кінець меню використовується функція AppendMenu():

 

BOOL CMenu:: AppendMenu(UINT nFlags, UINT nIDNewItem=0,

LPCTSTR lpszNewItem = NULL);

BOOL CMenu:: AppendMenu(UINT nFlags, UINT nIDNewItem, CBitmap* pBmp);

 

Функція повертає TRUE у разі успішного завершення та FALSE – в разі неуспішного. Параметри функції AppendMenu() мають характер, подібний до аналогічних параметрів попередньої функції InsertMenu():

nFlags - визначає інформацію про стан пункту меню, коли той додається і має значення, наведені у таблицях нижче;

nIDNewItem – визначає або ідентифікатор нового пункту меню або (якщо nFlags встановлений у значення MF_POPUP) дескриптор меню (HMENU); ігнорується, якщо nFlags встановлений у значення MF_SEPARATOR;

lpszNewItem – визначає зміст текстової позначки нового пункту меню; за допомогою зміни параметра nFlags можна контролювати lpszNewItem аналогічно одноіменному параметра функції InsertMenu() (таблиця 7.2);

pBmp – покажчик на об’єкт типу CBitmap, що використовується як пункт меню.

У таблиці 7.3 можна побачити основні значення параметра nFlags функції InsertMenu(), подані в об’єднаній формі.

 

Таблиця 7.3 – Значення параметра nFlags функції InsertMenu()

Значення коду Коментар до інтерпретації параметра
   
MF_CHECKED діє як перемикач і розміщує позначення вибору поруч з елементом (протилежний стан задається кодом MF_UNCHECKED)
MF_UNCHECKED діє як перемикач і вилучає позначення вибору поруч з елементом (протилежний стан задається кодом MF_CHECKED)
MF_DISABLED відключає пункт меню і унеможливлює вибір
MF_ENABLED підключає пункт меню і активує до повної функціональності
MF_GRAYED відключає пункт меню і унеможливлює вибір, пункт меню стає неактивним і має сірий колір
Продовження табл. 7.3
   
MF_MENUBARBREAK розміщує пункт меню у новий рядок у статичному меню або у новий стовпчик спливаючого меню, новий стовпчик спливаючого меню буде відділений від старого стовпчика верти-кальною розподільною лінією
MF_MENUBREAK розміщує пункт меню у новий рядок у статичних меню або у новий стовпчик спливаючого меню, розподільні лінії не розміщуються між стовпцями
MF_OWNERDRAW визначає, що пункт меню відображується у власний спосіб, під час першого відображення надсилає повідомлення WM_MEASUREITEM, що запитує висоту і ширину пункту меню, повідомлення WM_DRAWITEM надсилається під час онов-лення (опція не припустима для пунктів меню верхнього рівня)
MF_POPUP визначає, що пункт меню позв'язується з окремим новим підменю, ідентифікатор пункту визначає дескриптор підменю, що пов'язується з пунктом елементом; використовується для організації ієрархічних меню
MF_SEPARATOR визначає горизонтальну розподільну лінію між пунктами меню, формально є пунктом меню (додавання здійснюється у той самий спосіб), але не може обиратися
MF_STRING визначає, що пункт меню містить рядок символів

 

Окремі набори параметрів не можуть визначатися одночасно, бо мають протилежний за змістом характер. Зокрема, взаємовиключними є такі набори:

− MF_DISABLED, MF_ENABLED, та MF_GRAYED;

− MF_STRING, MF_OWNERDRAW, MF_SEPARATOR, і розміщення растрових зображень пунктів меню;

− MF_MENUBARBREAK та MF_MENUBREAK;

− MF_CHECKED та MF_UNCHECKED.

Після змін у меню, програма має викликати функцію CWnd:: DrawMenuBar(). Додатково зазначимо, що зміна стану пункту меню з активного на неактивний програмно здійснюється за допомогою функції EnableMenuItem().

Для вилучення пунктів меню використовується функція DeleteMenu():

 

BOOL CMenu:: DeleteMenu(UINT nPosition, UINT nFlags);

 

Функція повертає TRUE у випадку, коли вилучення пункту є успішним і FALSE – у протилежному випадку. Серед параметрів nPosition визначає пункт меню, що має вилучатися у спосіб визначений параметром nFlags. Стандартні значення nFlags визначаються у таблиці 7.4.

 

Таблиця 7.4 – Стандартні значення параметра nPosition

Значення коду Коментар до інтерпретації nPosition
MF_BYCOMMAND параметр nPosition містить ідентифікатор існуючого пункту меню (значення за замовчуванням, якщо жоден з параметрів MF_BYCOMMAND або MF_BYPOSITION не встановлений)
MF_BYPOSITION параметр nPosition міститиме індекс позиції, з якої вилучатиметься елемент; індекси починаються з 0

 

Визначення кількості пунктів меню забезпечує функція GetMenuItemCount():

 

UINT CMenu:: GetMenuItemCount();

 

Використання функцій класу CMenu, безперечно, має забезпечуватися відповідно до об’єктів цього класу або покажчиків на такі об’єкти. Найчастіше використовується покажчик на головне меню програми. Для отримання такого покажчика необхідно здійснити дві прості дії: оголосити покажчик на об’єкт класу CMenu та здійснити запит до головного меню програми. Запит головного меню програми здійснюється функцією GetMenu():

 

CMenu* CWnd:: GetMenu();

 

Функція повертає покажчик на меню вікна і повертає NULL якщо вікно CWnd не має ніякого меню. Повернуте значення є невизначеним, якщо CWnd є дочірнім вікном.

Таким чином для отримання доступу до меню програми можна здійснити таку послідовність операцій:

 

CMenu *m_MainMenu;

m_MainMenu = GetMenu();

 

Наявність покажчика на головне меню забезпечуватиме і подальший доступ до окремих підменю у головному меню за допомогою функції GetSubMenu():

 

CMenu* CMenu:: GetSubMenu (int nPos);

 

Функція повертає покажчик на об’єкт типу CMenu, якщо такий існує і NULL – у протилежному випадку. Єдиним параметром є nPos, що визначає позицію запитуваного підменю (початкове значення – 0).

Ще одним корисним засобом є функція визначення кількості елементів у складі меню (або підменю):

 

UINT CMenu:: GetMenuItemCount();

 

Функція повертає кількість елементів необхідного меню (підменю) або -1 – у разі, якщо такі не визначено. Наприклад:

CMenu *m_MainMenu; // оголошення покажчика на головне меню програми

CMenu *SubMenu; // оголошення покажчика на підменю

unsigned count; // оголошення лічильника

m_MainMenu = GetMenu(); // запит головного меню програми

SubMenu = m_MainMenu-> GetSubMenu(3); // запит третього підменю програми

count = SubMenu-> GetMenuItemCount(); // отримання кількості пунктів у підменю

 

Крім додавання окремих елементів до вже існуючого меню, можливо під час роботи програми динамічно створювати цілі підменю. Коли таке меню створено, його можна додати до існуючого меню. Для динамічного створення меню використовується функція CreatePopupMenu():

 

BOOL CMenu:: CreatePopupMenu();

 

Якщо меню створено успішно, функція повертає TRUE, і FALSE – в іншому випадку.

На самому початку створення меню є порожнім. Окремі пункти меню додаються за допомогою функцій AppendMenu() або InsertMenu(). Після закінчення формування саме меню додається (наприклад, до головного меню програми) за допомогою функції InsertMenu(). При цьому встановлюється параметр MF_POPUP та в третьому параметрі вказується дескриптор меню. Отримати дескриптор досить легко – він знаходиться у змінній m_hMenu класу CMenu.

Меню, створене за допомогою функції CreatePopupMenu() опісля свого використання має бути вилучено. Під час закриття вікна це робиться автома-тично, хоча видалення можна організувати і у явному вигляді – використавши функцію DestroyMenu().

 

7.3 Спливаючі меню

 

Спливаючі меню є необхідним елементом сучасних операційних систем із графічним інтерфейсом користувача. Зазвичай такі меню використовуються для забезпечення доступу до властивостей усієї програми або властовостей окремих її елементів. Наприклад, у самому Visual С++ використовується ряд спливаючих меню, зокрема у віконці робочого простору проекта (Workspace) натиснувши праву клавішу миші на назві будь-якого з класів проекту можна отримати спливаюче меню із списком можливих дій. Користувач, обираючи пункти меню, може здійснити певні дії із функціями та змінними проекту. Приклад такого меню наведений на рисунку 7.1.

Для активації спливаючих меню MFC використовує функцію TrackPopupMenu(), що має прототип такого вигляду:

 

BOOL CMenu:: TrackPopupMenu(UINT nFlags, int x, int y, CWnd * pWnd, LPCRECT lpRect =NULL);

 

Рисунок 7.1 – Приклад спливаючого меню із середовища Visual C++ 6.0

 

Функція TrackPopupMenu() повертає TRUE у разі успішного виконання та FALSE – в разі неуспішного. Параметрами функції є:

nFlags – визначає прапорець екранної позиції і прапорець кнопки миші.

Прапорець екранної позиції приймає одне із значень, наведених у таблиці 7.5:

 

Таблиця 7.5 – Стандартні значення прапорця екранної позиції

Значення коду Коментар
TPM_CENTERALIGN вирівнює спливаюче меню горизонтально за центром, відносно координати X
TPM_LEFTALIGN вирівнює лівий край спливаючого меню за координатою X
TPM_RIGHTALIGN вирівнює правий край спливаючого меню за координатою X
TPM_LEFTBUTTON спливаюче меню активується лівою клавішею миші
TPM_RIGHTBUTTON спливаюче меню активується правою клавішею миші

x – визначає горизонтальну позицію спливаючого меню у координатах дисплею, у залежності від значення параметра nFlags, меню може вирівнюватися відносно лівого, правого краю або відносно центру;

y – визначає вертикальну позицію спливаючого меню у координатах дисплею;

pWnd – покажчик на батьківське вікно, що містить спливаюче меню. Це вікно отримує усі повідомлення WM_COMMAND від меню (у Windows версій пізніше 3.1 повідомлення не надсилається до закінчення функції TrackPopupMenu());

lpRect – покажчик на структуру типу RECT або об’єкт класу CRect, що містить апаратні координати прямокутника в межах якого має відображатися спливаюче меню (меню не відображається, коли параметр має значання NULL).

Оскільки спливаюче меню – не обов’язково є частиною головного меню програми, воно може створюватися динамічно або завантажуватися з ресурсних файлів. У останньому випадку доречно використовувати функцію LoadMenu(), що має такі прототипи:

 

BOOL CMenu:: LoadMenu (LPCTSTR lpszResourceName);

BOOL CMenu:: LoadMenu (UINT nIDResource);

 

Функція повертає TRUE у разі успішного виконання та FALSE – в разі неуспішного. Параметрами функції є:

lpszResourceName – покажчик на рядок із ім’ям ресурсу меню;

nIDResource – ідентифікатор завантажуваного ресурсу меню.

Функція LoadMenu() завантажує ресурс меню з відповідного ресурсного файла і приєднує цей файл до об’єкта типу CMenu. Перед виходом з програми необхідно вивільнити системні ресурси, позв'язані з меню застосувавши функцію CMenu:: DestroyMenu().

Хоча меню (звичайні, динамічні та спливаючі) є одними з найстаріших елементів програмного інтерфейсу, вони залишаються потужним засобом організації роботи користувача і до цього часу у той чи інший спосіб входять до складу переважної більшості програм Microsoft Windows.

 

7.4 Розробка програм із використанням спеціальних типів меню

 

Звичайно, що перед розробкою програми необхідно з’ясувати вимоги користувача, у даному випадку – до реалізації динамічного та спливаючого меню. Встановимо такі вимоги:

1) одне з підменю головного меню програми має містити пункти, що в процесі виконання програми додаються у підменю вибором одного з пунктів меню та вилучаються в аналогічний спосіб (зображено на рисунках 7.2-а та 7.2-б);

 

а) б)

Рисунок 7.2 – Вигляд вікна програми із динамічним меню

(а – можливим є додавання пункту меню, б – можливим є вилучення)

 

Як наведено на рисунках, при першому завантаженні програми активним є пункт “Add item” підменю “Options” та неактивним – “ Delete item” (рис. 7.2-а). Після вибору “Add item” активується пункт “Delete item” та додаються два рядки меню – сепаратор (розподільна лінія) та пункт “Circle”. Сам пункт “Add item” стає неактивним (рис. 7.2-б). Якщо тепер натиснути “Delete item” програма повертає меню у первинний стан. Таким чином реалізується динамічне меню.

2) одне з підменю програми має активуватися за натисканням правої клавіші миші і відображатися у вигляді спливаючого меню (зображено на рис. 7.3).

 

Рисунок 7.3 – Вигляд вікна програми із спливаючим меню

 

У випадку, зображеному на рисунку 7.3 як спливаюче виступає підменю “Paint”, що і містить два пункти “Circle” та “Picture1”.

Відповідно до заявлених вимог визначимо порядок побудови програмного проекту:

1) створити проект типу “Win32 Application” (опція “Empty project”);

2) оголосити клас прикладки CApp з функцією ініціалізації InitInstance();

3) визначити ресурси основного меню програми із підменю “Paint” (містить пункти “Circle” та “Picture1”) та “Options” (із пунктами “Add Item” та “Delete Item”).

4) окремо визначити директиву для визначення ідентифікатора пункту меню, що додається:

#define ID_OPTIONS_CIRCLE 20001

5) оголосити прапорці стану пунктів меню “Add Item” та “Delete Item”:

int m_AddActive, m_DelActive;

6) оголосити обробники зміни стану пунктів меню:

void CMainWin:: OnUIAdd(CCmdUI *UI);

void CMainWin:: OnUIDel(CCmdUI *UI);

7) додати у карту повідомлень макрокоманди обробки пунктів меню, у тому числі для забезпечення динамічних змін та спливаючого меню:

 

BEGIN_MESSAGE_MAP(CMainWin, CFrameWnd)

ON_COMMAND(ID_PAINT_CIRCLE, OnCircle)

ON_UPDATE_COMMAND_UI(ID_OPTIONS_ADDITEM, OnUIAdd)

ON_UPDATE_COMMAND_UI(ID_OPTIONS_DELITEM, OnUIDel)

ON_COMMAND(ID_OPTIONS_ADDITEM, OnAdd)

ON_COMMAND(ID_OPTIONS_DELITEM, OnDelete)

ON_WM_RBUTTONDOWN()

ON_WM_PAINT()

END_MESSAGE_MAP()

 

8) у конструкторі головного вікна встановити прапорці стану пунктів динамічного меню:

m_AddActive=1;

m_DelActive=0;

9) реалізувати обробники OnAdd () та OnDelete(), що забезпечують додавання та вилучення елементів меню:

 

void CMainWin:: OnAdd()

{CMenu *m_MainMenu;

CMenu *SubMenu;

unsigned count;

m_MainMenu = GetMenu(); // запит до головного меню

SubMenu = m_MainMenu-> GetSubMenu(1); // запит до першого підменю

count = SubMenu-> GetMenuItemCount(); // обчислення кількості елементів першого підменю

SubMenu-> InsertMenu(count, MF_BYPOSITION | MF_SEPARATOR); // додавання сепаратора

// додавання пункту “Circle”

SubMenu-> InsertMenu(count+1, MF_BYPOSITION | MF_STRING, ID_OPTIONS_CIRCLE, " & Circle");

m_AddActive=0; // деактивація пункту “Add item”

m_DelActive=1; // активація пункту “Delete item”

}

 

void CMainWin:: OnDelete()

{CMenu *m_MainMenu;

CMenu *SubMenu;

unsigned count;

m_MainMenu = GetMenu();

SubMenu = m_MainMenu-> GetSubMenu(1);

count = SubMenu-> GetMenuItemCount();

SubMenu-> DeleteMenu(count-1, MF_BYPOSITION); // вилучення пункту “Circle”

SubMenu-> DeleteMenu(count-2, MF_BYPOSITION); // вилучення сепаратора

m_AddActive=1;

m_DelActive=0;

}

10) реалізувати обробники для забезпечення динамічних змін у меню:

 

void CMainWin:: OnUIAdd(CCmdUI * UI) {UI-> Enable(m_AddActive); }

void CMainWin:: OnUIDel(CCmdUI * UI) {UI-> Enable(m_DelActive); }

 

11) реалізувати обробник натискання правої клавіші миші для виклику спливаючого меню:

 

void CMainWin:: OnRButtonDown(UINT Flags, CPoint Loc)

{CMenu *SubMenu; // оголошення покажчика на підменю

CMenu m_FloatMenu; // оголошення покажчика на спливаюче меню

ClientToScreen(& Loc); // прив’язка до координат положення миші

m_FloatMenu.LoadMenu(IDR_MENU1); // завантаження головного меню програми (другий спосіб)

SubMenu = m_FloatMenu.GetSubMenu(0);

SubMenu-> TrackPopupMenu(0, Loc.x, Loc.y, this); // виведення спливаючого меню на екран

m_FloatMenu.DestroyMenu();

}

 

Повністю текст програми наводиться у прикладі 7.1. Як пункти меню у програмі реалізуються функції виведення зображення (IDB_BITMAP1) та кола. Для забезпечення ефективного виконання програми виведення графічної інформації реалізоване через віртуальне вікно.

 

Приклад 7.1 – Текст програми із використанням спеціальних меню

 

// файл im1.h

class CMainWin: public CFrameWnd

{public: void OnPicture1();

void OnUIDel(CCmdUI *UI);

void OnUIAdd(CCmdUI *UI);

void OnDelete();

void OnAdd();

void OnCircle();

void OnPaint();

void OnRButtonDown(UINT Flags, CPoint Loc);

CMainWin();

DECLARE_MESSAGE_MAP()

private: int m_DelActive, int m_AddActive;

CBrush mBrush;

CBitmap vbmp, bmp1;

CDC memDC;

};

 

class CApp: public CWinApp

{public: BOOL InitInstance(); };

 

// im1.cpp: implementation of the CMainWin class.

#include < afxwin.h>

#include < afxdlgs.h>

#include " im1.h"

#include " resource.h "

#define ID_OPTIONS_CIRCLE 20001

 

int maxX, maxY;

 

CMainWin:: CMainWin()

{Create(NULL, " Приклад із спеціальними меню", WS_OVERLAPPEDWINDOW, rectDefault, NULL, MAKEINTRESOURCE(IDR_MENU1));

LoadAccelTable(MAKEINTRESOURCE(IDR_ACCELERATOR1));

bmp1.LoadBitmap(IDB_BITMAP1);

maxX=GetSystemMetrics(SM_CXSCREEN);

maxY=GetSystemMetrics(SM_CYSCREEN);

CClientDC dc(this);

memDC.CreateCompatibleDC(& dc); // створення контексту віртуального вікна

vbmp.CreateCompatibleBitmap(& dc, maxX, maxY);

memDC.SelectObject(& vbmp);

mBrush.CreateStockObject(WHITE_BRUSH);

memDC.SelectObject(& mBrush);

memDC.PatBlt(0, 0, maxX, maxY, PATCOPY);

m_AddActive=1; m_DelActive=0;

}

 

BOOL CApp:: InitInstance()

{m_pMainWnd = new CMainWin;

m_pMainWnd -> ShowWindow(m_nCmdShow);

m_pMainWnd -> UpdateWindow();

return TRUE; }

 

CApp App;

 

BEGIN_MESSAGE_MAP(CMainWin, CFrameWnd)

ON_COMMAND(ID_PAINT_CIRCLE, OnCircle)

ON_COMMAND(ID_PAINT_PICTURE1, OnPicture1)

ON_UPDATE_COMMAND_UI(ID_OPTIONS_ADDITEM, OnUIAdd)

ON_UPDATE_COMMAND_UI(ID_OPTIONS_DELITEM, OnUIDel)

ON_COMMAND(ID_OPTIONS_ADDITEM, OnAdd)

ON_COMMAND(ID_OPTIONS_DELITEM, OnDelete)

ON_COMMAND(ID_OPTIONS_CIRCLE, OnCircle)

ON_WM_RBUTTONDOWN()

ON_WM_PAINT()

END_MESSAGE_MAP()

 

void CMainWin:: OnRButtonDown(UINT Flags, CPoint Loc)

{CMenu *SubMenu;

CMenu m_FloatMenu;

ClientToScreen(& Loc);

m_FloatMenu.LoadMenu(IDR_MENU1);

SubMenu = m_FloatMenu.GetSubMenu(0);

SubMenu-> TrackPopupMenu(0, Loc.x, Loc.y, this);

m_FloatMenu.DestroyMenu();

}

 

void CMainWin:: OnPaint()

{CPaintDC dc(this); dc.BitBlt(0, 0, maxX, maxY, & memDC, 0, 0, SRCCOPY); }

 

void CMainWin:: OnCircle()

{CPen redPen(PS_SOLID, 10, RGB(255, 0, 0));

CBrush Br;

Br.CreateSolidBrush(RGB(0, 255, 255));

memDC.SelectObject(& Br);

memDC.SelectObject(& redPen);

memDC.Ellipse(0, 0, 200, 200);

InvalidateRect(NULL); }

 

void CMainWin:: OnAdd()

{CMenu *m_MainMenu;

CMenu *SubMenu;

unsigned count;

m_MainMenu = GetMenu();

SubMenu = m_MainMenu-> GetSubMenu(1);

count = SubMenu-> GetMenuItemCount();

SubMenu-> InsertMenu(count, MF_BYPOSITION | MF_SEPARATOR);

SubMenu-> InsertMenu(count+1, MF_BYPOSITION | MF_STRING, ID_OPTIONS_CIRCLE, " & Circle");

m_AddActive=0; m_DelActive=1;

}

 

void CMainWin:: OnDelete()

{CMenu *m_MainMenu;

CMenu *SubMenu;

unsigned count;

m_MainMenu = GetMenu();

SubMenu = m_MainMenu-> GetSubMenu(1);

count = SubMenu-> GetMenuItemCount();

SubMenu-> DeleteMenu(count-1, MF_BYPOSITION);

SubMenu-> DeleteMenu(count-2, MF_BYPOSITION);

m_AddActive=1; m_DelActive=0; }

 

void CMainWin:: OnUIAdd(CCmdUI * UI) {UI-> Enable(m_AddActive); }

void CMainWin:: OnUIDel(CCmdUI * UI) {UI-> Enable(m_DelActive); }

 

void CMainWin:: OnPicture1()

{CClientDC dc(this);

CDC mdc;

mdc.CreateCompatibleDC(& dc);

BITMAP map;

bmp1.GetBitmap(& map);

mdc.SelectObject(& bmp1);

memDC.BitBlt(0, 0, map.bmWidth, map.bmHeight, & mdc, 0, 0, SRCCOPY);

CRect a(0, 0, map.bmWidth, map.bmHeight);

InvalidateRect(a); }

 

Додатково зазначимо, що у методичних вказівках [14] наводиться порядок побудови аналогічної програми для проектів, що використовують MFC Application Wizard.

 

7.5 Контрольні завдання

 

1. Пояснити різницю між звичайними та спеціальними типами меню.

2. Пояснити порядок активації пунктів спеціальних меню.

3. Розробити програму із використанням динамічних та спливаючих меню.







© 2023 :: MyLektsii.ru :: Мои Лекции
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав.
Копирование текстов разрешено только с указанием индексируемой ссылки на источник.