Rozdział 13
Praca z menu
Tworzenie i edycja zasobów menu Tworzenie funkcji
obsługi dla poleceń menu Nauka implementacji menu
skrótów_____ Dynamiczne tworzenie opcji menu
Tworzenie i edycja zasobów menu
Menu są kręgosłupem interakcji użytkownika z aplikacjami Windows, pozwalając mu na
szybkie wyszukiwanie poleceń w strukturze interfejsu. Menu posiadają nagłówki (widoczne na
pasku menu) oraz pozycje (opcje w rozwiniętym menu). Pozycje mogą posiadać menu
podrzędne, kierując użytkownika poprzez hierarchię kodu aplikacji. Można je dezaktywować,
zaznaczać lub traktować jako przełączniki alternatywne.
Menu skrótów umożliwiają dodawanie nowych, specyficznych opcji dla obiektów
aplikacji, udostępnianych na życzenie użytkownika wyrażone poprzez kliknięcie prawego
klawisza myszy. Zapewnia to użytkownikowi szybszą i bardziej przejrzystą formę kontroli
aplikacji.
Menu skrótów możemy w łatwy sposób tworzyć i obsługiwać przy użyciu edytora za-
sobów. Edytor ten pozwala tworzyć nowe nagłówki menu, jak też ich nowe pozycje, a
wszystko w trybie WYSIWYG, What You See Is What You Get (dostajesz to, co widzisz).
PATRZ TAKŻE
f Więcej informacji o edytorze zasobów znajdziesz w rozdziale 2.
300 Poznaj Visual C++ 6
Dynamiczne tworzenie menu
Jeśli nie używa się zasobów menu, można tworzyć menu dynamicznie i dodawać do nich
nowe opcje podczas pracy programu, co będzie opisane w dalszej części tego rozdziału.
,
Dodawanie nowych zasobów menu
Menu wyświetlane są zwykle z zasobów menu (takich jak szablony okien dialogowych),
które przechowują wszystkie nagłówki i pozycje menu. Nowe zasoby menu możemy dodawać
poprzez edytor zasobów. Tworząc nowy projekt typu SDI lub MDI, AppWizard dodaje
automatycznie do projektu domyślne menu, o identyfikatorze IDR_MAINFRAME. Umieszczanie
własnych menu wykonuje się według przedstawionej poniżej procedury.
Dodawanie nowych zasobów menu
1. Otwórz panel ResourceView wyświetlający zasoby projektu.
2. Kliknij prawym klawiszem pozycję najwyższego poziomu, a z otwartego menu wybierz
pozycję Insert, po czym wyświetlone zostanie okno dialogowe Insert Resource.
3. Wybierz pozycję Menu z listy typów zasobów.
4. Kliknij przycisk New, aby umieścić nowy zasób menu. Powinieneś ujrzeć szablon nowego
menu pod nagłówkiem Dialog Resource.
5. Kliknij prawym klawiszem okno dialogowe i wybierz pozycję Properties z otwartego menu
skrótów.
6. Możesz teraz zmienić identyfikator nowego zasobu na bardziej jednoznaczny, zastępując
domyślny IDD_.
7. Możesz dalej rozszerzyć zasoby projektu, klikając nagłówek Menu, co pozwoli ci wybrać
Insert Menu i dodać nowy zasób, a następnie ustalić jego identyfikator, powtarzając
kroki od 5 do 7.
Używanie klawisza skrótu Insert Menu
Naciskając kombinację klawiszy Ctrl+2 można pominąć kroki 1-4 powyższej procedury.
Skrót ten jest efektywny w każdym punkcie działania Visual Studio. Po naciśnięciu tej
kombinacji w panelu zasobów pojawi się pozycja nowego menu, a ono samo wyświetlone
zostanie w głównym oknie edytora.
fAIK& IAt\Z.t
Węcę/' informacji o tworzeniu aplikacji SD l znajdziesz w rozdziale 12.
Więcej informacji o tworzeniu aplikacji MDI znajdziesz w rozdziale 21.
Więcej informacji o edytorze zasobów znajdziesz w rozdziale 34.
Dodawanie do menu pozycji nagłówków
Po włączeniu do projektu nowego zasobu lub wybraniu istniejącego, możemy edyto-wać
ten zasób w oknie edytora zasobów. Menu wyświetlane jest w edytorze w postaci, w jakiej
pojawi się w gotowej aplikacji. Widoczne są zatem nagłówki paska menu. Tutaj możemy
dodawać nagłówki do nowego lub istniejącego zasobu menu.
Dodanie nagłówka nowego menu
1. Wybierz żądany zasób menu z panelu ResourceView, a w oknie edytora wyświetlony
zostanie pasek menu.
2. Kliknij pusty prostokąt widoczny po prawej stronie istniejących nagłówków. Wokół
prostokąta powinna pojawić się biała obwódka.
3. Wpisz nazwę nowego menu. Podczas jej wpisywania, tekst pojawiać się będzie jednocześnie
w oknie właściwości (Menu Item Properties) oraz wewnątrz oznaczonego prostokąta.
Pod nowym nagłówkiem pojawi się również pusta pozycja menu, jak widać na rysunku
13.1.
MFC AuuWizald - Ślep 4 ul E
Edi*rq Coktial: | Record
; P? Cfccck Boi (* Radio BWUOB |i| F
(bdio BMI< X
Wha> featmes would you like to include?
P (Docking tooiba;
1^ Iniliaistatu^baf 17 Printing and
print pieview r ConteKt-sensitive Hglp
17 30 conttols r MAPI(MessagingAR)
r ^/indows Sockete H ów do you want
your toolbars to look?
ff Noimal (~ Intetnet Euplorei
ReBars
Howmany files would you like on youtrecent
(ile list? ró^j Advanced... |
Einish Cancel
Rysunek 13.1. Dodawanie do paska nagłówka nowego menu
302 Poznaj Visual C++ 6
4. Oznacz według uznania inne, widoczne w oknie właściwości opcje (ich znaczenie
objaśnione zostanie w dalszej części tego rozdziału, możliwe będzie także dokonanie
poprawek).
5. Naciśnij Enter, by zakończyć proces dodawania nagłówka nowego menu.
6. Możesz teraz przemieszczać nowy nagłówek wewnątrz paska menu, ustalając własny
porządek.
Dodawanie pozycji menu
Wstawianie nowej pozycji menu
1. Kliknij nagłówek menu, które chcesz rozbudować o nową pozycję.
2. Kliknij pusty prostokąt widoczny pod wybranym nagłówkiem. Jeśli dodajesz pozycję
niższego poziomu, kliknij ją, by wyświetlić listę pozycji tego poziomu. Wokół oznaczonej
pozycji pojawi się biała obwódka.
3. Wpisz nazwę nowej pozycji. Pojawi się ona wewnątrz oznaczonego prostokąta oraz oknie
właściwości (rysunek 13.2).
4. Oznacz według uznania inne widoczne w oknie właściwości opcje (ich znaczenie
objaśnione zostanie w dalszej części tego rozdziału, możliwe będzie także dokonanie
poprawek).
5. Kliknij pole edycji Prompt. Możesz tu wprowadzić tekst, który pojawi się w pasku stanu,
gdy dana pozycja menu zostanie oznaczona. Możesz również dodać drugi łańcuch
znakowy, który pojawiać się będzie w formie "dymku", gdy wskaźnik myszy znajdzie się
ponad odpowiadającą pozycji menu ikoną w pasku narzędziowym. Ten łańcuch
oddzielasz od poprzedniego znakiem przejścia do nowej linii, czyli \n. Przykład pokazany
jest na rysunku 12.2.
Rysunek 13.2. Umieszczanie w menu nowej pozycji
Praca z menu 303
6. Kliknij pole ID. Powinieneś ujrzeć domyślny identyfikator menu, oparty o nazwy nagłówka
i pozycji menu. Jeśli chcesz, zmień ten identyfikator na bardziej sugestywny lub
odpowiedniejszy dla specyfiki danego menu.
7. Możesz zmienić porządek menu, przeciągając nową pozycję w nowe położenie (nawet pod
inny nagłówek).
Stosowanie identyfikatorów poleceń
Identyfikatory poleceń przypisane poszczególnym pozycjom menu są wykorzystywane do
powiadamiania o wydaniu polecenia przez użytkownika. Windows wysyła komunikat
WM_COMMAND do okna zawierającego menu. Identyfikator zostaje następnie odnaleziony na
mapie komunikatów przez makro ON_COMMAMD w celu ustalenia właściwej funkcji obsługi.
Przypisywanie identyfikatorów do poleceń
Identyfikator pozycji menu będzie używany do przydzielenia jej funkcji obsługi, co
opisane jest w punkcie "Dodawanie funkcji obsługi polecenia menu", w dalszej części
rozdziału. Jeśli chcemy przypisać pozycji menu istniejący już identyfikator (np. przycisku na
pasku narzędziowym), musimy go wybrać z listy kombinowanej ID, którą zobaczymy po
kliknięciu przycisku rozwijania. Listę tę znajdziemy w oknie właściwości. Możemy również
dzielić identyfikator pomiędzy różnymi zasobami menu. Przykładowo, gdybyśmy chcieli
utworzyć dwa różne widoki, oba wyświetlające menu File i wywołujące tę samą funkcję
obsługi, możemy w nowym widoku utworzyć duplikat interesującego nas menu. W obu
widokach pozycje menu będą miały te same identyfikatory, w związku z tym wywoływane
będą te same funkcje.
Do czasu utworzenia właściwych funkcji obsługi dla poszczególnych pozycji menu, będą
one nieaktywne.
Po wpisaniu łańcucha znakowego w polu Prompt (krok 5), łańcuch zostanie zapisany w
tablicy łańcuchów z odnoszącym się do niego identyfikatorem. Po skompilowaniu i wygene-
rowaniu pliku wykonywalnego w programie łańcuch ten będzie wyświetlany w pasku stanu.
Zmiany właściwości pozycji menu
Okno właściwości danej pozycji menu możemy wyświetlić klikając ją dwukrotnie w
oknie edytora lub oznaczając i naciskając Alt+Enter. W otwartym oknie możemy dokonywać
zmian wcześniej ustalonych właściwości.
Każda pozycja menu może zostać przesunięta poprzez przeciągnięcie jej w nowe poło-
żenie. Pojawiająca się podczas przeciągania linia pomocnicza wskazuje miejsce "zrzutu".
304_____________________________________Poznaj Visual C++ 6
Niepotrzebną pozycję menu możemy usunąć zaznaczając ją, a następnie naciskając klawisz Delete.
Jeśli potraktujemy w ten sposób pozycję nagłówkową, usuniemy również wszystkie pozycje menu, ale
zostaniemy o tym uprzedzeni i poproszeni o akceptację.
PATRZ TAKŻE
Wyjaśnień dotyczących tablic łańcuchów znakowych szukaj w rozdziale 2.
Umieszczanie separatorów
Separatory służą do dzielenia menu na mniejsze podgrupy. Są to poziome kreski usytuowane w
poprzek kolumny menu (jak w menu File programu Developer Studio). Aby umieścić separator,
musimy dwukrotnie kliknąć pustą pozycję menu, a następnie w oknie właściwości zaznaczyć opcję
Separator. Po zaznaczeniu tej opcji, wszelkie inne staną się niedostępne, z wyjątkiem pola edycji
Caption. W celu zamknięcia okna właściwości należy nacisnąć Enter. Ujrzymy wstawiony separator,
dzielący kolumnę menu. Separator ten możemy później przesunąć, gdybyśmy zmienili decyzję co do
jego położenia.
Zamiana separatorów na pozycje menu
Separatory mogą być przekształcane w pozycje menu poprzez wpisanie tekstu w polu Caption okna
właściwości.
Tworzenie pozycji menu podrzędnego
Pozycje menu mogą stanowić pozycje nagłówkowe dla menu podrzędnych, otwieranych po
najechaniu myszą na nagłówek (rysunek 13.3). Aby utworzyć takie menu, musimy dodać nową pozycję
menu nadrzędnego, a następnie w oknie właściwości zaznaczyć opcję Pop-up. Gdy to uczynimy, pole ID
zostanie zaciemnione, a obok pozycji menu, która ma otwierać menu podrzędne, pojawi się mała,
skierowana w prawo strzałka, wskazująca pustą pozycję podrzędną.
Pozycje menu podrzędnego możemy ustanawiać w taki sam sposób jak nadrzędnego. W razie
potrzeby z menu podrzędnego wyprowadzać możemy dalsze menu, jeszcze niższego poziomu. W ten
sposób możliwe jest tworzenie złożonych struktur hierarchicznych menu.
Praca z menu 305
a Et- y '/i ''iii
^ 3@
Eldiec' fimtó Irols Wndow Beto
.=,s===;=Bg;g3iiiaa
'Wii/St Bw ŁM) M>Ha
Sit My
9f r"---" ::!:!:^"" .:.:.
'-\ ~3 idintenu
lelouicef '
* UAcceletatoi
35 j Dialog L-fc-
LJ icon ) -a
Menu
Menu Irem | opup One
;--------|
| ^(iłDR MAlHFRAHEl :
B>-IStillTaUe : iB Cj
Toota :
-la ? Gwal
EitłendedSylss 1
: | j I;aHr |ailiflas r . p Pgp-uc r' }oacl!ve &ieak |rjune*| r
Chtked r SiW) r Hełp "t
-. l
:,:.'^',!1:'
Rysunek 13.3. Tworzenie menu podrzędnego
Umieszczanie znaczników
Pozycje menu mogą posiadać znaczniki - "ptaszki", umieszczone po ich lewej stronie.
Znaczniki możemy wprowadzać programowo lub ustalać ich domyślne wyświetlanie,
posługując się edytorem zasobów. Aby ustalić wyświetlanie domyślne, należy zaznaczyć
opcję Checked w oknie właściwości pozycji.
Umieszczanie skrótów klawiaturowych
Możemy ustanowić skróty klawiaturowe dla poszczególnych pozycji menu, które pozwolą
użytkownikowi wywoływać polecenia menu przy użyciu klawiatury. Skrót klawiaturowy
reprezentowany jest przez literę z podkreśleniem, stanowiącą skrót dla danej pozycji menu.
Aby przydzielić skrót do treści pozycji menu, musimy wstawić znak & (ang. amper-sand)
przed literą, którą na skrót wytypowaliśmy. W wyświetlanym menu litera ta będzie
podkreślona, a naciśnięcie odpowiadającego jej klawisza spowoduje wywołanie polecenia.
Przykładowo, jeśli chcemy uczynić literę S skrótem klawiaturowym dla pozycji My
Shortcut, w nagłówku tej pozycji (Caption w oknie właściwości) musimy dokonać wpisu:
My &Shortcut, w wyniku czego napis w menu będzie miał postać My Shortcut.
Gdybyśmy jednak chcieli wstawić do nazwy pozycji znak &, musimy wtedy umieścić w
nagłówku dwa takie znaki obok siebie, na przykład My && Am&persand Napis w menu
będzie wtedy wyglądał tak: My & Amfiersand.
306 Poznaj Visual C++ 6
Klawisze mnemonik
Klawisze skrótów bywają nazywane klawiszami mnemonik i mogą być ustalane dla kontrolek w
oknach dialogowych.
PATRZ TAKŻE
Więcej informacji na temat skrótów klawiaturowych znajdziesz w rozdziale 3.
Obsługa poleceń menu
Obsługa poleceń menu jest zorganizowana na podobnych zasadach, jak przyciski w oknach
dialogowych, czyli poprzez utworzenie funkcji obsługi. Możemy zatem użyć kreatora CIassWizard, by
utworzyć funkcje obsługi poleceń menu. Dodana zostanie również pozycja mapy dla komunikatu
Windows, WM_COMMAND, wysyłanego wraz z identyfikatorem przez pozycję menu. Gdy użytkownik
wybierze określoną pozycję menu, system wyśle komunikat WM_COMMAND do okna aplikacji będącego w
posiadaniu danego menu. Gdy odnaleziona zostanie odpowiednia pozycja mapy komunikatów, nastąpi
wywołanie właściwej funkcji obsługi.
Możemy także dodać funkcje obsługi poleceń interfejsu użytkownika w celu zapewnienia
możliwości aktywowania / dezaktywowania określonych menu, poprzez oddzielną, wygenerowaną przez
CIassWizard mapę komunikatów i funkcję obsługi.
PATRZ TAKŻE
Więcej o mapach komunikatów mówimy w rozdziale 4.
Dodawanie funkcji obsługujących polecenia menu
Po umieszczeniu nowego menu, możemy przystąpić do tworzenia funkcji obsługujących
poszczególne pozycje menu i wywołujących wykonanie związanych z nimi kodów. Owe funkcje mogą
być implementowane przez każdą klasę, której obiekt związany jest z wywoływanym poleceniem. W
normalnych warunkach będzie to klasa dokumentu lub określonego widoku implementującego menu.
Jednakże możemy również umieścić takie funkcje w klasach aplikacji bądź okna głównego. Najlepszym
sposobem na dokonanie właściwych ustaleń jest określenie miejsca najdogodniejszego dla dostępu do
danych i metod, z punktu widzenia różnych obiektów aplikacji. W celu dodania funkcji posłużymy się
kreatorem CIassWizard.
Dodanie za pomocą CIassWizard funkcji obsługi poleceń menu
l. Wybierz pozycję menu, dla którego chcesz dodać funkcję obsługi.
Praca z menu 307
2. Wywołaj CIassWizard, naciskając Ctri+W lub wybierając odpowiednią pozycję z menu
View. W oknie listy Object IDs powinieneś ujrzeć zaznaczony identyfikator wybranej
pozycji menu, jak na rysunku 13.4.
FC ClaWizaid
Messaga Maps
'roject:
MemberVafiab!es | Automation Act!Ve^
CIass name:
AddCtes...
sdimen
u
c\.\stSmigKiSe
Object ID
C?L::', I
d
WeaaMdimenu\Mar>
CMain
Ffd
Frm.cp
p
^lessas
es
UPDA
TE
me ^J
CO M MAŃ C'
Ul
AddFunction,..
ID FILE OPEN
ID FILE PRINT
J
PREVIEW SETUP |
S
iBiBHLil
y^MKi:/ -,.:::.
.:"i:^':':'::i:::;^-
'.:"
Edii Coda
ID FILE PRINT
ID FILE PRINT
10 FILE SAVE
ID FILE SAVE
A
lil'A!Ti1J:1
M embef
jun^ions
W OnCreate ONWMCREATE V
PieCieateWindow
Detcription: Handle a command (ftom menu. accel. cmd buttoni
| OK l Cancel j
Rysunek 13.4. Wskazany w CIassWizard identyfikator polecenia menu
3. Lista kombinowana Ciass Name wskazywać będzie klasę docelową dla nowej funkcji. Gdy
klikniesz przycisk rozwijania listy, będziesz mógł wybrać inną niż aktualnie wybrana, klasę
spośród zdolnych do zaimplementowania nowej funkcji. Możesz wybrać klasę widoku,
która implementuje menu lub klasę dokumentu. Wszystko zależy od tego, która z nich
będzie odpowiedniejsza.
4.
Kliknij dwukrotnie pozycję komunikatu COMMAND widoczną na liście Messages, po
czym wyświetlone zostanie okno dialogowe Add Member Function (rysunek 13.5). Jeśli
nie lubisz podwójnych kliknięć, zaznacz pozycję komunikatu, a następnie kliknij przycisk
Add Function.
Add Membel Function
Membet function
nanie:
l^^asgiaaEa
E
Message: COMMAND ObiectlD:
ID_MYHEADER_MYSUBONE
Rysunek 13.5. Okno dialogowe Add Member Function umożliwia zmianę nazwy funkcji
5. Domyślnie ustalona nazwa funkcji oparta jest o identyfikator nagłówka dla menu, w którym
znajduje się dana pozycja. Możesz zmienić tę nazwę, wpisując nową w polu Member
Function Name, zanim funkcja zostanie utworzona.
308_____________________________________Poznaj Visual C++ 6
6. Kliknij Ok, co spowoduje dodanie nowej funkcji.
7. W CIassWizard nowa funkcja powinna być widoczna w oknie Member Functions.
8. Możesz teraz edytować treść funkcji, zaznaczywszy jej pozycję i klikąwszy przycisk Edit
Code.
Po dodaniu nowej funkcji obsługi, możemy dodać również własny kod implementacyjny.
W bieżącym przykładzie będzie to funkcja (implementowana w klasie dokumentu) jedynie
wyświetlająca okno komunikatu informujące, iż użytkownik wybrał określoną pozycję menu:
void CSdimenuDoc::OnMyHeaderMysubone() ( AfxMessageBox("You picked
the l'" menu item") ;
}
PATRZ TAKŻE
Aby zrozumieć komunikaty przekazywane w aplikacjach SDI, zajrzyj do rozdziału 12. ^
Szczegółowe informacje na temat map komunikatów znajdziesz w rozdziale 4.
Dodawanie funkcji obsługi poleceń interfejsu użytkownika
Funkcja obsługi polecenia interfejsu użytkownika odpowiedzialna jest za wygląd, styl
oraz sposób zachowania danej pozycji menu. Przed wyświetleniem menu wywoływane są
odpowiednie funkcje obsługi, umożliwiające aplikacji aktywowanie lub dezaktywowanie
poszczególnych pozycji, dodawanie lub usuwanie znaczników lub zmianę treści opisu pozycji.
Wymienione atrybuty interfejsu użytkownika możemy zmienić poprzez wywołanie
funkcji dostępu do obiektu ccmdUl, związanego z pozycją menu. Gdy następuje wywołanie
funkcji obsługi interfejsu użytkownika, przekazany jej zostaje wskaźnik do obiektu CCmdui.
Na przykład, poniższa funkcja aktywuje pozycję menu, w związku z czym użytkownik
może ją wybrać. Czyni to wywołując funkcję Enable () wskazanego obiektu poprzez wskaźnik
pCmdUl:
void CSdimenuDoc::OnUpdateMyheaderMysubone(CCmdUl* pCmdUl) { pCmdUl -
>Enable(TRUE) ;
}
Kolejny punkt rozdziału opisze te aspekty interfejsu użytkownika szczegółowo.
Funkcje, jak powyższa możemy dodawać do aplikacji w taki sam sposób, jak miało to
miejsce w przypadku funkcji obsługujących pozycje menu, czyli za pomocą CIassWizard.
Trzeba jednak wybrać UPDATE_COMMAND_UI zamiast COMMAND, co miało miejsce w kroku 4.
Praca z menu 309
Kiedy wywoływane są funkcje obsługi poleceń interfejsu użytkownika?
Funkcje te wywoływane są pomiędzy kliknięciem nagłówka menu przez użytkownika a
wyświetleniem samego menu. System uaktualniania opcji menu na żądanie przyczynia się do
zwiększenia szybkości pracy aplikacji, jeśli atrybuty tych opcji wymagają uaktualniania wskutek
zmian stanu aplikacji.
Aktywowanie i dezaktywowanie pozycji menu
Poszczególne pozycje menu mogą być aktywowane lub dezaktywowane poprzez użycie funkcji
Enable ((obiektu CCmdUl. Jeśli przekazany jej zostanie parametr TRUE, pozycja jest aktywna, w
przeciwnym wypadku jest nieaktywna i przybiera szarą barwę.
Możemy regulować ten stan ustanawiając zmienną składową typu BOOL. Będzie ona osadzona w
klasie i przekazywana poprzez poniższą linię funkcji Enable () obiektu CCmdUl, gdy nastąpi wywołanie
funkcji obsługi interfejsu użytkownika:
pCmdUl ->Enable (in_bMySubItemEnableStatus) ;
Zależnie od stanu m_bMySubltemEnable3tatus, pozycja menu będzie aktywna lub nieaktywna.
Umieszczanie i usuwanie znaczników
Obok każdej pozycji menu, mogą być umieszczane znaczniki identyfikujące stan logiczny danej
pozycji w kontekście aplikacji. Umieszczanie tych znaczników odbywać się może poprzez wywołanie
funkcji SetCheck (), należącej do obiektu CCmdUl i przekazanie jej jako parametr liczby zero dla braku
znacznika lub jeden, gdy znacznik ma zostać umieszczony.
Aby zaimplementować możliwość przełączania przez użytkownika stanu pozycji menu, poprzez jej
kuknięcie, możemy posłużyć się kodem zawartym na listingu 13.1.
Listing 13.1. LST14_1.CPP - implementacja przełącznika znacznika dla pozycji menu
1 void CSdimenuDoc::OnMyheaderMysubone()
2 {
3 II** Przełączenie obecnego stanu
4 m_nToggleState = m_nToggleState==0 ? l : 0; O
5 }
6
7 void CSdimenuDoc::OnUpdateMyheaderMysubone (CCmdUl* pCmdUl)
8 (
9 // ** Uaktywnienie pozycji menu
10 pCmdUI->Enable(TRUE) ;
11
12 // ** Ustalenie bieżącego stanu
13 pCmdUI->SetCheck(m_nToggleState) ; @
14 }
O W odpowiedzi na dokonanie przez użytkownika wyboru pozycji menu, następuje zmiana wartości
m_nToggleState z O na l lub odwrotnie.
Wyświetlenie znacznika, jeśli wartość m_nToggleState wynosi l lub usunięcie znacznika w
przypadku wartości 0.
Na powyższym listingu w celu zaimplementowania przełącznika użyte zostały funkcje obsługi
poleceń menu oraz poleceń interfejsu użytkownika. Funkcja obsługi polecenia menu
OnMyheaderMysubone() zaimplementowana w liniach l do 5, ustanawia stan przełącznika poprzez
wartość zmiennej m_nToggleState. Zmienna ta może zostać zadeklarowana w definicji klasy, jako prosta
zmienna całkowitoliczbowa:
int m_nToggleState ;
W linii 4 użyty został operator warunkowy ? w celu sprawdzenia, czy obecna wartość zmiennej
m_nToggleState wynosi zero. Jeśli tak, wartość ta zostaje zmieniona na l, w przeciwnym wypadku zaś,
dzieje się odwrotnie.
Funkcja obsługi interfejsu użytkownika zaimplementowana jest w liniach 7-14 poprzez funkcję
OnUpdateMyheaderMysubone (). Linia 10 zapewnia stałą dostępność pozycji menu za pomocą
wywołania funkcji Enable () obiektu ccmdui.
Bieżący stan przełącznika zostaje uwidoczniony za pomocą ustawienia lub usunięcia znacznika obok
pozycji menu przez wywołaną w linii 13 funkcję SetCheckO obiektu CCmdUl. Funkcji SetCheckO
przekazana zostaje wartość zmiennej m_nToggleState, co decyduje o wyświetleniu lub usunięciu
znacznika.
Dynamiczna zmiana treści pozycji menu
Funkcję polecenia interfejsu użytkownika możemy wykorzystać również do zmiany treści pozycji
menu, przekazując funkcji SetText () obiektu ccmdui nowy łańcuch znakowy. Pozycja menu otrzyma
wówczas nowe określenie, wraz z przypisanymi jej skrótami klawiaturowymi.
Moglibyśmy w tym miejscu skorzystać z ostatniego przykładu, opisującego wstawianie znaczników
i zastąpić je tekstem On i Off, w zależności od stanu przełącznika, a na końcu treści funkcji obsługi
interfejsu użytkownika dodać następującą linię:
Praca z menu 311
pCmdUl ->SetText(m_nToggleState?"&On":"0&ff") ;
W powyższej linii operator warunkowy ? przekazuje jeden z dwóch łańcuchów, w zależności od
wartości zmiennej m_nToggleState.
Dodawanie menu skrótów
Menu skrótów jest to menu wyświetlane w dowolnym miejscu ekranu (zwykle), gdy
użytkownik kuknie prawym klawiszem myszy obiekt aplikacji. Pozwala to użytkownikowi
wybrać z menu pozycję specyficzną dla danego obiektu aplikacji.
Menu skrótów dodajemy do projektu jako nowy zasób. Powinniśmy to zrobić za po-
średnictwem edytora zasobów w sposób opisany wcześniej, w tym samym rozdziale, w
punkcie "Tworzenie i edycja zasobów menu".
Komunikat WM CONTEXTMENU
Komunikat ten generowany jest przez procedurę okna, gdy odebrany zostaje komunikat WM
RBUTTONUP. Jeśli nastąpi przechwycenie WM_RBUTTONUP bez wywołania funkcji obsługi
klasy bazowej, aplikacja nie będzie mogła odebrać komunikatu
WM CONTEXTMENU. , : :
Menu skrótów możemy zaimplementować w aplikacji dodając funkcję obsługi komu-
nikatu Windows WM_CONTEXTMENU, który przesyłany jest aplikacji, gdy użytkownik klik-nie
prawym klawiszem myszy gdziekolwiek w oknie aplikacji. Poprzez funkcję obsługi
załadowany zostanie odpowiedni zasób menu i nastąpi rozwinięcie menu poprzez wywołanie
funkcji TrackPopupMenu (). Funkcje obsługujące polecenia tego menu mogą być dodawane w
znany nam już sposób.
Uruchamianie menu skrótów
Poniżej przedstawiona jest procedura dodania funkcji obsługi komunikatu
WM_CONTEXTMENU.
Dodanie funkcji obsługi menu skrótów
1. Otwórz panel ClassView w oknie Project Workspace i w razie konieczności rozwiń listę
klas klikając znak plusa widoczny obok pozycji najwyższego poziomu.
2. Kliknij prawym klawiszem myszy pozycję klasy, do której chcesz dodać nową funkcję
obsługi i wybierz z rozwiniętego menu opcję Add Windows Message Handler. Otwarte
zostanie okno dialogowe New Windows Message and Event handlers.
3. Z listy New Windows Messages/Events wybierz WM_CONTEXTMENU, a następnie
kliknij przycisk Add and Edit, co spowoduje dodanie nowej funkcji.
312_____________________________________Poznaj Visual C++ 6
4. Powinna być widoczna nowa wygenerowana przez CIassWizard funkcja, nazwana domyślnie
OnContextMenu (). Teraz możesz dodać własny kod do implementacji domyślnej.
Tworzenie dynamicznych menu skrótów
Zamiast ładowania predefiniowanych menu z zasobów, można wyświetlić tekst związany z obiektem
kliniętym przez użytkownika (a nie typem obiektu). W tym przypadku korzystniejszym rozwiązaniem
może się okazać wywołanie funkcji Cre-atePopupMenu () klasy CMenu dla utworzenia menu, a
następnie użycie AppendMenu w celu dodania pozycji do nowego menu. W ten sam sposób można
użyć funkcji TrackPopupMenu () do wyświetlenia menu.
Po dodaniu funkcji obsługi możemy dodać kod powodujący wyświetlanie menu skrótów. Możemy
zadecydować, aby menu było otwierane tylko wtedy, gdy wskaźnik myszy znajdzie się nad określonym
obiektem lub aby wyświetlało różne polecenia, w zależności od specyfiki wybranego obiektu. Osiągnąć
to możemy dzięki parametrowi Cpoint point, określającemu, który z obiektów aplikacji lub jaki obszar
okna został kliknięty, od czego z kolei zależeć będzie wyświetlenie menu skrótów lub jego zawartość.
Techniki stosowane w takich sytuacjach opisane zostały w rozdziale 8.
Aby menu skrótów mogło zostać wyświetlone, musimy najpierw zadeklarować obiekt CMenu,
implementujący menu rozwijane (klasa CMenu jest klasą MFC, która może zawierać i posiadać dostęp
do obiektu HMENU). Nowy obiekt CMenu zainicjować możemy wywołując funkcję LoadMenu () i
przekazując jej identyfikator zasobu. W takiej sytuacji obiekt ten zostanie zainicjowany z nagłówkiem
nowego zasobu menu. Potrzebujemy jeszcze pozycji menu, które będą wyświetlane po jego otwarciu.
Pobranie zawartości menu (submenu) następuje poprzez wywołanie funkcji GetSubMenu () z
przekazanym parametrem zero, który określa pierwszą pozycję menu.
Z menu możemy wywoływać kolejną funkcję, TrackpopupMenu (), wyświetlającą menu i
określającą jego położenie. Funkcja ta wymaga czterech parametrów. Pierwszym z nich jest znacznik
służący do określania położenia menu w stosunku do zadanej pozycji. Jeśli wskaźnik myszy powinien
znajdować się po lewej stronie rozwiniętego menu, możemy przekazać TPM_LEFTALIGN jako pierwszy
parametr oraz pozycję wskaźnika myszy jako pozycję menu. Inne możliwe wartości znacznika
wymienione są w tabeli 13.1. Drugi i trzeci parametr to pozioma i pionowa współrzędne dla określenia
położenia menu. Jako te parametry mogą występować wartości point, x oraz point, y przekazywane
funkcji OnContextMenu (). Ostatnim parametrem jest wskaźnik do obiektu okna, który zwykle jest
operatorem this, wskazującym bieżący obiekt widoku.
Praca z menu 313
Tabela 13.1. Wartości znacznika położenia menu dla funkcji TrackPopupMenu ()
Wartość
TPM_LEFTALIGN
TPM_RIGHTALIGN
TPM_TOPALIGN
TPM_BOTTOMALIGN
TPM_CENTERALIGN
TPM_VCENTERALIGN
TPM_HORIZONTAL
TPM VERTICAL
Opis
Umieszcza menu po lewej stronie wskazanej pozycji
Umieszcza menu po prawej stronie wskazanej pozycji
Umieszcza menu poniżej wskazanej pozycji
Umieszcza menu powyżej wskazanej pozycji
Wyśrodkowuje menu w osi poziomej, w stosunku do wskazanej pozycji
Wyśrodkowuje menu w osi pionowej, w stosunku do wskazanej pozycji
Jeśli obszar wyświetlania jest ograniczony, istotniejsza jest oś pozioma
Jeśli obszar wyświetlania jest ograniczony, istotniejsza jest oś pozioma
Po wywołaniu funkcji menu zostaje wyświetlone, a użytkownik może dokonywać wyboru
poleceń. Gdy już wybór zostanie dokonany lub nastąpi kliknięcie poza obrębem menu, zostaje
ono usunięte.
Przykładowo, zaimplementujemy menu skrótów umożliwiające użytkownikowi dokonanie
wyboru spośród pozycji North, East, South i West (Północ, Wschód, Południe, Zachód) z
menu w aplikacji SDI, utworzonej za pomocą AppWizard. Pierwszą czynnością będzie
dodanie zasobu dla menu rozwijanego (rysunek 13.6).
MenuPioperties
-(l l? Resource
ID: jlil.KMiUiEii IP'eview
W, PW-D Waf-u l
1'W
SCT.
ff
Langysge: |English(U.S.) ^J
CtOndition; |
:-;^.::.::::::.:^;v:-
Rysunek 13.6. Umieszczanie nowego zasobu menu dla rozwijanego menu skrótów
Po dodaniu zasobu dla nowego menu dodać należy funkcję obsługi komunikatu
WM_CONTEXTMENU, wykonując procedurę opisaną wcześniej, w punkcie "Dodanie funkcji
obsługi menu skrótów". Funkcję tę powinniśmy umieścić w klasie widoku aplikacji SDI,
implementując kod służący załadowaniu i pozycjonowaniu menu. Kod ten znajduje się na
listingu 13.2.
314_____________________________________Poznaj Visual C++ 6
Listing 13.2. LST14_2.CPP - funkcja OnContextMenu () obsługująca komunikat
WM_CONTEXTMENU, ładująca i pozycjonująca rozwijane menu skrótów
1 void CSdimenuView::OnContextMenu(CWnd* pWnd, CPoint
point)
2 {
3 // ** Zadeklarowanie obiektu CMenu
4 CMenu menuPopup;
5
6 // ** Inicjalizacja zasobu menu skrótów
7 menuPopup.LoadMenu(IDR_MYCONTEXT) ;
8
9 // ** Wyświetlenie i pozycjonowanie menu
10 menuPopup.GetSubMenu(0)->TrackPopupMenu( O
11 TPM_LEFTALIGN,point.x,point.y,this) ;
12 }
O Linia wyświetla i rozpoczyna śledzenie wyboru menu przez użytkownika.
W linii 4 listingu 13.2 zadeklarowany zostaje obiekt CMenu jako zmienna menupopup.
Zmienna ta zainicjalizowana zostaje w linii 7 wraz z zawartością menu z zasobu IDR_MY-
CONTEXT.
W linii 10 następuje wywołanie funkcji TrackPopupMenu (), nakazującej wyświetlenie menu po
lewej stronie punktu wyrównania oraz przekazanie jej położenia wskaźnika myszy, które przekazane
zostało również funkcji obsługi menu skrótów. Przekazany zostaje także wskaźnik do bieżącego obiektu
widoku CSdimenuView, przy użyciu słowa kluczowego this.
Aby wyświetlone zostało właściwe menu, funkcja TrackPopupMenu () musi być wywołana z
głównego zasobu menu, zawierającego owo menu. Wskaźnik do tego menu zwrócony zostaje z menu
głównego przez funkcję menuPopup. GetSubMenu (0) wywołaną na początku linii 10.
Okno dialogowe dodawania klas w CIassWizard
Podczas dołączania nowego zasobu menu i następującego po tym wywołania CIassWizard, kreator
wyświetla okna dialogowe Adding a Ciass wskutek wykrycia nowego zasobu. Ponieważ nie trzeba
tworzyć ani wybierać klasy obsługującej, okno można zamknąć przyciskiem Cancel.
Więcej informacji o procedurze sprawdzającej kuknięcie w określonych obszarach znaj-
dziesz w rozdziale 8.
Obsługa poleceń menu skrótów
Po dodaniu do projektu menu skrótów powinniśmy dodać funkcje obsługi jego poleceń, w
taki sam sposób, jak robiliśmy to w przypadku normalnego menu (według opisu w punkcie
"Dodawanie funkcji obsługi poleceń interfejsu użytkownika").
Możemy posłużyć się w tym celu kreatorem CIassWizard, dodając funkcje obsługi
poleceń menu oraz interfejsu użytkownika, dla każdej pozycji menu. Oto przykład dla opcji
North:
void CSdimenuView::OnMypopupmenuNorth() {
AfxMessageBox("North") ;
)
Funkcja obsługi polecenia powodować będzie wyświetlanie słowa North w oknie
komunikatu, co nastąpi w wyniku wybrania tej pozycji przez użytkownika.
void CSdimenyView::OnUpdateMypopupmenuNorth(CCmdUl* pCmdUl)
( pCmdUl ->Enable(TRUE) ;
>
Funkcja obsługi interfejsu użytkownika powoduje aktywację pozycji menu poprzez
wywołanie funkcji Enable () dla obiektu CmdUl przekazanego funkcji obsługi.
Zmiany te możemy zastosować w standardowej aplikacji SDI, skompilować ją i
uruchomić. Kliknięcie prawym klawiszem myszy w obrębie głównego widoku spowoduje
wyświetlenie menu skrótów, jak widać na rysunku 13.7.
a? Uniltled - adimenu
File E dii View Hełp MyHeadet Radio Menu
D "'WH'. ' ', r igi "f
gH
South
West
Rysunek 13.7. Rozwijane menu skrótów, widoczne po kliknięciu prawym klawiszem myszy
fIMKt. IAIU.C
Więcej informacji na temat obsługi zdarzeń kuknięcia znajdziesz w rozdziale 8.
Tworzenie i dostęp do obiektów menu
Biblioteka MFC dostarcza nam klasę CMenu, opakowującą uchwyt menu Windows
(HMENU) i upraszczającą operacje wykonywane na menu. Możemy z niej korzystać podczas
konstruowania własnych menu (zamiast ich ładowania). Umożliwia ona również dynamiczne
dodawanie i usuwanie pozycji z istniejącego menu. Klasa CMenu zawiera szereg funkcji
składowych, zapewniając obsługę każdego aspektu wyświetlania i manipulacji. Kolejne
punkty rozdziału opisywać będą kilka najważniejszych spośród tych funkcji.
Uzyskiwanie dostępu do uchwytu menu
Dostęp do uchwytu obiektu menu CMenu można zdobyć poprzez jego zmienną składową m_hMenu.
Może to być użyteczne, gdy konieczne jest zastosowanie funkcji Win32 zamiast funkcji MFC.
.'.,', : ,,:
Inicjalizacja obiektu CMenu
Zanim będziemy mogli skorzystać z zadeklarowanego obiektu CMenu, musimy go za-
inicjalizować, ładując menu z zasobu menu, tworząc nowe menu lub dołączając obiekt menu
do innego już istniejącego.
Każda z funkcji inicjalizujących zwraca wartość TRUE, gdy operacja zakończona zostaje
pomyślnie zainicjalizowaniem menu lub FALSE w wypadku niepowodzenia.
Ładowanie menu z szablonu zasobu
Menu możemy załadować za pomocą funkcji LoadMenu (), z przekazanym jej identy-
fikatorem żądanego menu, co było zademonstrowane na listingu 13.2. Szablon menu
zostanie wówczas załadowany z zasobu i użyty do utworzenia pozycji menu.
Tworzenie nowych menu
Funkcja CreateMenu () dynamicznie tworzy pusty zasób menu Windows, bez żadnych
zawartych w nim pozycji. Do tego menu możemy dynamicznie dodawać nowe pozycje, co
opisane jest w następnym punkcie rozdziału.
Wywołanie funkcji CreatePopupMenu () pozwala zaś utworzyć menu rozwijane, które
może być otwierane z pozycji innego menu lub jako rozwijane menu skrótów.
Dołączanie do istniejącego menu
Za pomocą funkcji Attach () możemy dołączać istniejące menu Windows do obiektu
CMenu, przekazując funkcji uchwyt HMENU istniejącego menu. Uchwyt ten można po-
Praca z menu_________________________________________317
brać z CWnd (lub z wyprowadzonej CView) poprzez wywołanie funkcji obiektu okna GetMenu ().
Po zakończeniu tych operacji, możemy odłączyć menu od obiektu CMenu, wywołując funkcję
Detach ().
Po zainicjalizowaniu obiektu CMenu możemy dodawać, usuwać lub modyfikować pozycje menu,
by dostosować je do potrzeb aplikacji. Jest to opisane w następnych podrozdziałach.
Dynamiczne dodawanie pozycji menu
Nowe pozycje mogą być umieszczane w menu poprzez wywołanie funkcji AppendMe-nu () lub
insertMenu (), w zależności od tego, czy nowa pozycja ma się znaleźć na końcu, czy też w określonym
miejscu menu pomiędzy innymi jego pozycjami.
Funkcja AppendMenu () wymaga trzech parametrów. Pierwszym jest znacznik określający typ
nowej pozycji kombinacji znaczników stylu.
Normalnie powinniśmy wpisać znacznik MF_STRING, co oznaczałoby, iż nowa pozycja menu
przechowuje wskaźnik do zwykłego łańcucha znakowego (możemy użyć obiektów cstring). Możemy
jednak utworzyć separator przekazując MF_SEPARATOR. Można wówczas łączyć podstawowe znaczniki
typu z innymi znacznikami, wymienionymi w tabeli 13.2, korzystając z operatora dodawania (+) lub
logicznego OR (l).
Drugim parametrem, jaki możemy przekazać, jest identyfikator komunikatów poleceń lub uchwytu
menu rozwijanego HMENU, o ile został przekazany znacznik MF_POPUP.
Jako trzeci parametr występuje wskaźnik łańcucha znakowego, stanowiącego treść opisu pozycji
menu (pozostawiamy domyślne NULL dla pozycji separatorów).
Sprawdzanie odrębności identyfikatora menu
Zawsze należy sprawdzać, czy identyfikator menu jest niepowtarzalny i nie powoduje konfliktu z
innym identyfikatorem zasobu menu. Można to sprawdzić otwierając plik resource.h (na karcie
FileYiew) i odnajdując nowy identyfikator. Jeśli go tam nie ma i nie jest powtórzony w innym menu
dynamicznym, można go bezpiecznie zastosować.
Tabela 13.2. Znaczniki pozycji menu dla funkcji AppendMenu () oraz InsertMenu () Znacznik
Opis
MF_CHECKED Ustawia znacznik ("ptaszek") obok pozycji menu
MF_UNCHECKED Usuwa znacznik pozycji menu
MF_ENABLED Uaktywnia pozycj ę menu
318 Poznaj Visual C++6
MF_DISABLED Dezaktywuje pozycję menu MF_GRAYED Działa
identycznie jak MF_DISABLED
MF_POPUP Pozycja menu posiada własne podmenu rozwijane, określone identyfikatorem
MF_MENUBARBREAK Pozycja menu umieszczona zostaje w nowej linii (lub w nowej kolumnie menu
rozwijanego, oddzielonej pionową linią)
MF_MENUBREAK Działa podobnie do MF_MENUBARBREAK, lecz bez wstawiania pionowej linii
Funkcja insertMenuO pozwala na umieszczanie nowych pozycji menu w określonym
miejscu lub przed pozycją o wyznaczonym identyfikatorze. Jeśli chcemy określić pozycję
poprzez podanie indeksu, należy przekazać indeks, w porządku zaczynającym się od zera, jako
pierwszy parametr i dołączyć znacznik MF_BYPOSITION do znaczników umieszczonych
wcześniej.
Aby umieścić nową pozycję menu przed inną istniejącą o określonym identyfikatorze,
należy podać ten identyfikator jako pierwszy parametr i dołączyć znacznik MF_BYCOMMAND.
Pozostałe trzy parametry są identyczne z użytymi w funkcji AppendMenu (). Przykłado-
wo, zamiast ładować menu skrótów (jak na listingu 13.2 w poprzednim punkcie), możemy
utworzyć menu rozwijane i dołączyć do niego nowe pozycje, co pokazane jest na listingu 13.3.
Technika ta daje nam większą kontrolę nad dołączaną pozycją oraz umożliwia dynamiczne
dodawanie innych pozycji, specyficznych dla danej aplikacji. Listing 13.3 pokazuje również
inne sposoby dodawania pozycji menu, a także efekty łączenia znaczników.
Listing 13.3. LST14_3.CPP - dynamiczne tworzenie i wyświetlanie rozwijanego menu
skrótów
1 łdefine ID_MENU_RED 5001 O
2 łdefine ID_MENU_GREEN 5002 O
3 łdefine ID_MENU_BLUE 5003 O
4 łdefine ID_MENU_YELLOW 5004 O
5
6 void CSdimenuView::OnContextMenu(CWnd* pWnd, CPoint point)
7 {
8 // Deklaracja obiektu CMenu
9 CMenu menuPopup;
10
11 // Dodanie pozycji do menu
12 if (menuPopup.CreatePopupMenu() )@
13 {
14 // Dodanie prostych pozycji menu
15 menuPopup.AppendMenu(MF_STRING,ID_MENU_RED,"SRed");
16
17 // Dodanie pozycji na początku menu
18 menuPopup.InsertMenu(O, MF_BYPOSITION | MF_STRING,
19 ID_MENU_GREEN,"SGreen");
20
21
22 menuPopup.AppendMenu(MF_SEPARATOR) ;
23
24 // Dodanie pozycji oznaczonej
25 menuPopup.AppendMenu(MF_STRING | MF_CHECKED,
26 ID_MENU_BLUE,"SBlue") ;
27
28 // MF_MENUBARBREAK
29 menuPopup.AppendMenu(MF_STRING | MF_MENUBARBREAK, O
30 ID_MENU_YELLOW,"SYellow") ;
31 menuPopup.TrackPopupMenu(TPM_LEFTALIGN,
32 point.x,point.y,this);
33 }
34 }
O Zdefiniowane zostają odrębne identyfikatory.
@ Jeśli menu rozwijane może zostać utworzone, bezpiecznie można dodać do niego nowe pozycje.
Należy zauważyć, że pozycja ta umieszczona zostaje z indeksem O (ponad dotychczasową pierwszą
pozycją menu).
O Znacznik w tym miejscu powoduje umieszczenie pionowej linii, dzielącej menu rozwijane na dwie
kolumny.
Linie od l do 4 definiują wartości identyfikatorów dla czterech dodawanych do menu pozycji. W linii
9 następuje zadeklarowanie obiektu CMenu jako menuPopup, natomiast jego inicjalizacja jako menu ma
miejsce w linii 12, poprzez wywołanie funkcji CreatePo-pupMenu().
W liniil5 za pomocą funkcji AppendMenu () dodana zostaje nowa pozycja menu. Red. Kolejna
pozycja, Green, umieszczona zostaje przed pozycją Red, poprzez funkcję in-sertMenu () wywołaną w
linii 18. W linii 22 za pomocą dodania pozycji menu ze znacznikiem MF_SEPARATOR, do menu dodany
zostaje separator. Pozycja Blue dodana zostaje jako oznaczona, co ma miejsce w liniach 25 i 26,
natomiast w liniach 29 i 30 pozycja Yellow umieszczona zostaje po prawej stronie pionowego separatora.
Na koniec, wywołana w linii 31 funkcja TrackPopupMenu () wyświetla nowe menu.
320 Poznaj Visual C++ 6
Funkcje obsługi dla poszczególnych pozycji dynamicznego menu możemy uzyskać
dodając odpowiednie wpisy do mapy komunikatów na końcu mapy komunikatów widoku, dla
określonych identyfikatorów:
ON_COMMAND(ID_MENU_YELLOW,OnYellow)
Musimy mieć przy tym pewność, że linie łdefine dla tych identyfikatorów znajdują się w
kodzie powyżej mapy komunikatów, by kompilator mógł je odnaleźć.
Funkcja obsługi OnYeliowf) będzie wywoływana, gdy użytkownik dokona wyboru
pozycji menu o identyfikatorze ID_MENU_YELLOW. Implementacji tej funkcji obsługi doko-
nujemy w zwyczajny sposób:
void CSdimenuView::OnYellow()
{ AfxMessageBox("Yellow") ;
}
Po uruchomieniu skompilowanej aplikacji nasze rozwijane menu skrótów będzie wy-
glądało jak na rysunku 13.8.
rV Undtled - sdimenu
Fie Edit View Hełp MyHeader Radio Menu
rD^Hn^iij^'^''?7"""""'
Green | ^ellow
/ Blue
Rysunek 13.8. Dynamicznie utworzone menu rozwijane, z kilkoma włączonymi opcjami
Dynamiczne modyfikowanie pozycji menu
Możemy również modyfikować pozycje menu podczas ich wyświetlania poprzez wy-
wołanie funkcji ModifyMenu (). Funkcja ta wymaga czterech parametrów.
Pierwszy parametr funkcjonuje jak parametr funkcji insertMenu () określający pozycję.
Jeżeli chcemy określić pozycję poprzez jej indeks, powinniśmy podać indeks w relacji do
pierwszej pozycji oznaczonej jako zero oraz dołączyć znacznik MF_BYPOSITION do innych
przekazanych znaczników. Możemy także modyfikować określoną pozycję przekazując jej
identyfikator jako pierwszy parametr. Musi to być połączone z dodaniem znacznika MF
BYCOMMAND.
Praca z menu 321
Drugim parametrem jest zestaw nowych znaczników dla wybranej pozycji menu, zmieniających
dotychczasowe ustawienia. Użyć przy tym możemy znaczników omówionych w tabeli 13.2.
Opcjonalnie możemy jako trzeci parametr przekazać nowy identyfikator menu (lub obecny, co
pozostawi go niezmienionym), a jako czwarty parametr wskaźnik łańcucha znakowego, stanowiącego
nową treść opisu pozycji menu.
Przykładowo, aby oznaczyć pozycję menu połączoną z identyfikatorem ID_MENU_ YELLOW
(opisanym w poprzednim punkcie), umieścić należy poniższy wpis za linią dodającą nową pozycję menu:
menuPopup.ModifyMenu(ID_MENU_YELLOW,
MF_BYCOMMAND | MF_CHECKED | MF_STRING | MF_MENUBREAK ,
ID_MENU_YELLOW, "SYellow") ;
Bardzo prosto zmieniać możemy atrybuty pozycji, takie jak oznaczenie jej lub stan aktywności,
poprzez wywołanie funkcji CheckMenultem() lub EnableMenultemO. Funkcje te pobierają dwa
parametry. Pierwszy określa poprzez identyfikator lub indeks pozycję menu podlegającą zmianie. Drugi
parametr jest znacznikiem MF_BYCOMMAND lub MF_BYPOSITION, co determinuje sposób identyfikacji
pozycji. Funkcji CheckMenultem() przekazywać możemy znacznik MF_CHECKED lub MFJJNCHECKED, by
oznaczyć lub usunąć oznaczenie pozycji. Funkcja EnableMenultemO przyjmuje znaczniki MF_ENABLED
lub MF_DISABLED, które powodują uaktywnianie bądź dezaktywację pozycji menu.
Dla przykładu, możemy uprościć stosowanie ModifyMenuO dla oznaczenia pozycji menu,
korzystając z funkcji CheckMenultem ():
menuPopup.CheckMenuItem(ID_MENU_YELLOW,
MF_BYCOMMAND i MF_CHECKED) ;
Dynamiczne usuwanie pozycji menu
Usuwanie pozycji menu z obiektu CMenu odbywa się poprzez wywołanie funkcji Re-moveltem(),
pobierającej dwa parametry. Pierwszym jest identyfikator lub indeks pozycji mającej ulec usunięciu.
Drugim natomiast jest znacznik MF_BYCOMMAND lub MF_BYPOSITION, identyfikujący typ wartości
przekazanej jako parametr pierwszy.
Wyszukiwarka
Podobne podstrony:
13 Praca ze źródłami promieniotwórczymi
Rozwiązana praca domowa 13
MENU (13)
UAS 13 zao
er4p2 5 13
pu srvc menu nl
menu cwiczenia14
więcej podobnych podstron