LEKCJA45.TXT

(13 KB) Pobierz
LEKCJA 45: Do��czanie zasob�w - menu i okienka dialogowe. 
________________________________________________________________ 
 
Jak doda� menu i okienka dialogowe do aplikacji.  
________________________________________________________________ 
 
Aby doda� do aplikacji menu nale�y utworzy� plik (ASCII) zasob�w 
*.RC, kt�ry zostanie u�yty w projekcie. Pierwsz� instrukcj� jest 
MENU, "NazwaMenu",  
MENU i para s��w kluczowych (znanych z Pascala) BEGIN oraz END,  
mi�dzy kt�rymi znajdzie si� kombinacja instrukcji MENUITEM oraz  
POPUP.  
 
MENUITEM definiuje pozycj� na g��wnym pasku menu - okre�la - jak 
b�dzie wygl�da� i jaki identyfikator b�dzie j� reprezentowa�.  
Instrukcja POPUP pozwala, rozwin�� list� pozycji wchodz�cych w  
sk�ad danego menu. Nazwa menu mo�e by� u�yta podczas rejestracji 
klasy danego okna jako wpisana w odpowiednie pole struktury na  
kt�rej oparte jest okno. W ten spos�b uzyskamy menu dla  
wszystkich okien danej klasy.  
 
BEGIN  
  POPUP "Rozkaz"  
    BEGIN  
       MENUITEM "Rozkaz 1", IDM_R1  
       MENUITEM "Rozkaz 2", IDM_R2  
       MENUITEM "Rozkaz 3", IDM_R3  
    END  
  POPUP "Kolor"  
    BEGIN  
       MENUITEM "Czarny", IDM_BLACK  
       MENUITEM "Niebieski", IDM_BLUE  
       MENUITEM "Zielony", IDM_GREEN  
  END  
  MENUITEM "Koniec", IDM_EXIT  
END  
 
Ka�da pozycja ma w�asny identyfikator, np. IDM_EXIT, IDM_BLUE,  
kt�ry Windows przekazuj� do aplikacji, gdy zostaje ona wybrana  
przez u�ytkownika z systemu menu. Poniewa� ka�dy identyfikator  
powinien by� unikalny, najlepiej jest go zdefiniowa� w pliku  
zasob�w .RC lub w�asnym pliku nag��wkowym .H:  
 
#define IDM_EXIT 100  
#define IDM_BLUE 101  
#define IDM_R1   102  
 ... 
 
Mamy ju� zdefiniowane menu w pliku zasob�w, nale�y je teraz  
do��czy� do aplikacji na jeden z dw�ch sposob�w:  
 
 - Mo�na okre�li� menu jako menu danej klasy okien, gdy klasa ta 
 
   jest rejestrowana. W ten spos�b do��czymy menu do ka�dego  
   okna opartego na tej klasie. Aby to wykona�, wystarczy  
   przypisa� odpowiedniemu polu struktury nazw� naszego menu.  
   Je�eli obiekt klasy WNDCLASS nazwiemy Window1, to:  
 
Window1.lpszMenuName = "NazwaMenu";  
 
Gdy klasa zostanie zarejestrowana, ka�de okno tej klasy b�dzie  
mia�o to samo menu, chyba �e dostarczymy odpowiedni  
identyfikator menu w momencie tworzenia okna funkcj�  
CreateWindow().  
 
 - Drugim sposobem jest do��czenie menu w momencie tworzenia  
   okna, wtedy tylko tworzone okno b�dzie mia�o dane menu.  
 
Nale�y najpierw za�adowa� menu przy u�yciu funkcji LoadMenu(),  
kt�ra zwraca jego identyfikator:  
 
HMENU  hMenu = LoadMenu(hInstance, "NazwaMenu");  
 
hWnd = CreateWindow(szAppName,  
                    "Nazwa Aplikacji",  
                    WS_OVERLAPPEDWINDOW,  
                    CW_USEDEFAULT,  
                    CW_USEDEFAULT,  
                    CW_USEDEFAULT,  
                    CW_USEDEFAULT,  
                    NULL,  
                    hMenu,                 <-- tu 
                    hIstance,  
                    NULL );  
 
Typow� praktyk� jest do��czenie pozycji menu do instrukcji  
switch w funkcji okienkowej. Poniewa� Windows wysy�a komunikat  
WM_COMMAND do odpowiedniej funkcji okienkowej w odpowiedzi na  
wyb�r pozycji przez u�ytkownika, a parametr wParam zawiera  
identyfikator tej�e pozycji - mo�na napisa� tak:  
 
case WM_COMMAND:  
switch (wParam)  
{  
case IDM_R1:     
            ... obs�uga ...; break; 
case IDM_R2:    
            ... obs�uga ...; break 
case IDM_QUIT:     
            ...DestroyWindow(...);  
}  
 
Jak rozbudowuje si� menu. 
 
API Windows zawiera funkcje, umo�liwiaj�ce rozbudow� menu nawet  
w ruchu aplikacji (run-time). Rozbudowa menu w konkretnym oknie  
nie poci�ga za sob� zmian w innych, opartych na tej samej klasie 
 
oknach. Jest to mo�liwe, poniewa� w chwili tworzenia okna  
otrzymuje ono swoj� kopi� menu (tradycyjne w C/C++ przekazywanie 
 
kopii zmiennej do funkcji).  
 
Nie wszystkie pozycje w menu s� w danym stadium pracy aplikacji  
sensowne (mo�liwe do wykonania). Zaraz przekonasz si�, jak to  
si� dzieje, �e niekt�re pozycje "robi si� na szaro". W API  
Windows s�u�y do tego funkcja: 
 
EnableMenuItem (hMenu, IDM_R1, MF_DISABLED);  
EnableMenuItem (hMenu, IDM_R1, MF_GRAYED);  
EnableMenuItem (hMenu, IDM_R1, MF_ENABLED);  
 
Rozkaz R1 skojarzony z identyfikatorem IDM_R1 i znajduj�cy si� w 
 
systemie menu o oznaczniku hMenu stanie si� kolejno zablokowany, 
 
widoczny-lecz-niedost�pny, dost�pny.  
 
Dodawanie i usuwanie pozycji w menu  
 
Dodawanie pozycji do menu mo�e by� wykonane dwoma sposobami:  
przez wstawienie pomi�dzy istniej�ce pozycje lub na ko�cu listy. 
 
W pierwszym przypadku nale�y u�y� funkcji InsertMenu(). Funkcja  
ta pozwala jednocze�nie okre�li� status pozycji, mi�dzy innymi  
czy b�dzie umieszczone nowe pole mo�na okre�li� dwoma sposobami: 
 
przez identyfikator pozycji maj�cej by� przed now� lub przez  
numeracj� poszczeg�lnych, licz�c id lewej skrajnej pozycji (C++  
tradycyjnie liczy od zera). Spos�b "odliczania" pozycji w  
systemie menu okre�la tryb (BYCOMMAND lub BYPOSITION - rozkaz,  
b�d� pozycja):  
 
InsertMenu(hMenu, IDM_R1, MF_BYCOMMAND |MF_DISABLED, IDM_R5,  
"Rozkaz 5");  
InsertMenu(hMenu, 1, MF_ENABLED, IDM_R5, "Rozkaz 5");  
 
Funkcja wstawi za pozycj� "Rozkaz 1" now� pozycj� "Rozkaz 5",  
jednocze�nie ustawia jej status. Drug� funkcj� dodaj�c� pozycj�  
do utworzonego systemu menu jest: 
 
AppendMenu(hMenu, MF_ENABLED, IDM_R4, "Rozkaz 4");  
 
Poni�ej przyk�ad zdefiniowania menu aplikacji w taki w�a�nie  
spos�b: 
 
case WM_CREATE:  
hMenu = CreateMenu();     //Utworzenie menu 
AppendMenu(hMenu, MF_ENABLED, IDM_R1, "Rozkaz 1");  
AppendMenu(hMenu, MF_ENABLED, IDM_R2, "Rozkaz 2");  
AppendMenu(hMenu, MF_ENABLED, IDM_R3, "Rozkaz 3");  
SetMenu(hWnd, hMenu);     //Wy�wietlenie menu  
 ...  
break;  
 
Usuwanie pozycji z menu mo�na przeprowadzi� dwoma sposobami:  
 
 - poprzez wskazanie numeru pozycji w systemie menu: 
 
DeleteMenu(hMenu, 1, MF_BYPOSITION); //usuni�ta zostanie druga  
                                     //pozycja z systemu menu 
 
 - przez wyszczeg�lnienie identyfikatorem pozycji  
 
DeleteMenu(hMenu, IDM_R3, MF_BYCOMMAND);  
 
Po usuni�ciu pozycji z menu Window usunie r�wnie� wszystkie  
zwi�zane z ni� submenu.  
 
Zaznaczanie pozycji w menu (mark). 
 
Obok pozycji w menu mo�na umie�ci� znak markuj�cy ("ptaszek").  
Znak markuj�cy mo�na zainicjowa� w pliku zasob�w .RC. Dzi�ki  
temu, u�ytkownik w momencie otwarcia okna dowie si� z wygl�du  
menu o pocz�tkowym ustawieniu opcji.  
 
MENUITEM "Rozkaz 2", IDM_R2, CHECKED  
 
W trakcie pracy aplikacji nale�y pos�u�y� si� funkcj�  
CheckMenuItem(). Zwykle najpierw kasujemy "ptaszka" przy  
poprzedniej pozycji:  
 
CheckMenuItem( hMenu, IDM_R2, MF_UNCHECKED);  
CheckMenuItem(hMenu, IDM_R3, MF_CHECKED);  
 
Zmiany pozycji menu  
 
Funkcja ModyfyMenu() pozwala na zmian� nazwy pozycji i jej  
atrybut�w. Oto przyk�ady u�ycia tej funkcji:  
 
ModifyMenu(hMenu, IDM_R2, MF_BYCOMMAND, IDM_R2, "Polecenie 2");  
 
Identyfikator pozycji nie ulegnie zmianie, jedynie nazwa pola z  
"Rozkaz 2" na "Polecenie 2". Mo�emy zmieni� jednocze�nie i  
identyfikator, by nie pomyli� si� w programie:  
 
ModifyMenu(hMenu, IDM_R2, MF_BYCOMMAND, IDM_P2, "Polecenie 2");  
 
Dodatkowo mo�na ustawi� za jednym zamachem i atrybuty:  
 
ModifyMenu(hMenu, IDM_R2, MF_BYCOMMAND | MF_CHECKED | MF_GRAYED, 
 
           IDM_R2, "Polecenie 2");  
 
U�ycie grafiki w systemie menu.  
 
W systemie menu aplikacji mo�emy zamiast �a�cucha znak�w "Rozkaz 
 
2" umie�ci� element graficzny - np. w postaci mapy bitowej.  
Zamiast pola o nazwie "Pole", wprowadza map� bitow�:  
 
HMENU hMenu = GetMenu(hWnd);  
HBITMAP hBitmap = LoadBitmap (hIstance, "Pole");  
ModifyMenu(hMenu, IDM_R2, MF_BYCOMMAND | MF_BITMAP, IDM_R2,  
(LPSTR) MAKELONG (hBitmap, 0));  
 
GetMenu() zwraca oznacznik aktualnego menu, potrzebny jako  
pierwszy parametr funkcji ModifyMenu(). Drugim parametrem tej  
funkcji jest identyfikator pozycji, kt�r� chcemy zmieni�.  
Trzecia okre�la, �e zmiana ma by� wykonana przez wyszukanie  
pozycji za po�rednictwem jej identyfikatora oraz �e now� pozycj� 
 
ma reprezentowa� mapa bitowa. Czwarty parametr okre�la  
identyfikator nowej pozycji. Poniewa� ostatnim parametrem nie  
jest ju� wska�nik do �a�cucha znakowego, nale�y przes�a�  
oznacznik mapy bitowej jako mniej znacz�ce s�owo tego parametru. 
 
W tym celu 16-bitowy oznacznik jest ��czony z 16-bitow� sta��, a 
 
nast�pnie poddawany konwersji do typu Long Pointer to STRing.  
 
Zmiana menu aplikacji na kolejne.  
 
Aplikacja w r�nych stadiach pracy mo�e mie� na ekranie r�ne  
(kilka czasem kilkana�cie) menu. Wymiany menu w oknie aplikacji  
mo�na dokona�, za�adowuj�c nowe menu funkcj� LoadMenu() i  
ustawiaj�c je jako aktualne funkcj� SetMenu(): 
 
...  
hMenu2 = LoadMenu (hIstance, "Menu2");  
SetMenu (hWnd, hMenu2);  
DrawMenuBar(...); 
...  
 
Menu i Menu2 powinny by� zdefiniowane w pliku zasob�w *.RC.  
Po ka�dej zmianie menu nale�y u�y� funkcji DrawMenuBar(), aby  
wprowadzone zmiany pojawi�y si� na ekranie. Oto przyk�ad  
stosownego pliku zasob�w: 
 
Menu1 MENU  
BEGIN  
  POPUP "&File"  
  BEGIN  
    MENUITEM "&New" , IDM_NEW  
    MENUITEM "&Save", IDM_SAVE  
    MENUITEM "E&xit", IDM_EXIT  
  END  
  POPUP "&Options"  
  BEGIN  
    MENUITEM "Menu&1", IDM_M1,CHECKED  
    MENUITEM "Menu&2" , IDM_M2  
  END  
END  
 
Menu2 MENU  
BEGIN  
  POPUP "&File"  
  BEGIN 
    MENUITEM "&Open", IDM_OPEN  
    MENUITEM "&New" , IDM_NEW  
    MENUITEM "&Save", IDM_SAVE  
    MENUITEM "Save &As", IDM_SAVEAS  
    MENUITEM "&DOS shell", IDM_DOSSHELL...
Zgłoś jeśli naruszono regulamin