LEKCJA 43
Elementy sterujące i zarządzanie programem.
Jak sterować pracą aplikacji. Jak umieszczać elementy graficzne-sterujące w oknie aplikacji. Najczęściej stosowane funkcje API Windows.
Elementy sterujące pracą aplikacji w Windows (ang. controls) są również swoistymi okienkami (tyle, że potomnymi - Child Window wobec głównego okna aplikacji - Parent Window). Do utworzenia takiego specjalnego okna również można użyć funkcji CreateWindow(). Jeśli okno ma stać się nie głównym oknem aplikacji, lecz oknem sterującym przebiegiem programu, funkcja wymaga podania następujących argumentów:
- rodzaj klasy sterującej (ang. control class)
- rodzaj elementu sterującego (ang. control style)
Typowe rodzaje elementów (obiektów) starujących w środowisku Windows:
BUTTON
|
klawisz rozkazu, prostokątne okno typu Child, reprezentujące przycisk, który użytkownik może włączyć; przycisk może być opatrzony etykietą (text label).
|
COMBOBOX
|
okienko dialogowe kombinowane. Jest złożeniem klasy EDIT i LISTBOX;
|
LISTBOX
|
oknienko z listą (zwykle element składowy okienka dialogowego typu Combo Box.
|
STATIC
|
pole statyczne (bez prawa edycji). Niewielkie okno zawierające tekst lub grafikę; służy z reguły do oznaczania innych okien sterujących.
|
SCROLLBAR
|
pasek przewijania (pionowy - Vertical Scroll Bar; poziomy - Horizontal Scroll Bar). Style klawiszy sterujących (Button Styles):
|
BS_PUSHBUTTON
|
Klawisz. Okno sterujące wysyła, po każdym wyborze klawisza (kliknięcie), wiadomość do okna macieżystego (Parent Window).
|
BS_RADIOBUTTON
|
Okrągły przełącznik działający zwykle na zasadzie @tylko jeden z grupy".
|
BS_CHECKBOX -
|
prostokątny przełącznik [X] włączający (aktywna) lub wyłączający (nieaktywna) opcję. Działa niezależnie od pozostałych. |
Inne style określają np. sposób edycji tekstu (ES_LEFT, ES_MULTILINE, itp.) Szczegóły - patrz system Help - Windows API. Oto przykład utworzenia okna elementu sterującego typu "Klawisz"
(BUTTON to nazwa typu):
hControlWnd = CreateWindow ("BUTTON", " Napis_na_Klawiszu ",
BS_PUSHBUTTON |WS_CHILD | WS_VISIBLE,
10, 20, 30, 40,
hWnd, ID_Elem, hInstance, 0);
Identyfikator ID_Elem jest potrzebny, gdy w jednym oknie znajduje się kilka elementów sterujących - pozwala na ich rozpoznawanie w programie. Sposób przekazywania informacji o kliknięciu klawisza przypomnę na przykładzie okienka komunikatów:
if(IDOK==MessageBox(0, "", "", MB_OK)) ...
IDOK to predefiniowany w Windows identyfikator klawisza [OK]. Oto krótkie wyjaśnienie pozostałych elementów: 10, 10, 30, 20, - współrzędne. x, y, szerokość, wysokość hWnd, - oznacznik okna macieżystego Przesuwanie i zmiana wielkości elementu sterującego. Funkcja MoveWindow() przesuwa okno we wskazane miejsce:
MoveWindow(hKlawisz, 10, 10, 20, 30, TRUE);
Ponieważ okno elementu sterującego ma zadane względne współrzędne w oknie macieżystym, gdy okno macierzyste zostanie przesunięte - element sterujący będzie przesunięty automatycznie. Również po zmianie rozmiarów okna macieżystego okno elementu sterującego zmienia położenie, zawsze jednakowe względem lewego górnego rogu.
Usuwanie okna sterującego
Okienko elementu sterującego możemy usunąć (jak i każde inne okna) przy pomocy funkcji:
DestroyWindow(hKlawisz);
Przekazywanie informacji do- i z- okna elementu sterującego Zdarzenie w oknie elementu sterującego - np. kliknięcie klawisza
- powoduje wygenerowanie komunikatu WM_COMMAND. Towarzyszące komunikatowi parametry przenoszą istotne informacje:
wParam - identyfikator elementu sterującego,
lParam - dla wciśniętego klawisza będzie to BN_CLICKED.
Niektóre komunikaty Windows mogą być kierowane do okna elementu sterującego i wymuszać pewne operacje. Dla przykładu komunikat WM_GETTEXTLENGTH przesłany do okienka edycyjnego typu Text Edit Box (element sterujący klasy EDIT) jest żądaniem podania długości tekstu wpisanego właśnie do okienka. Aby Windows wygenerowały komunikat i przesłały go do naszego elementu sterującego - musimy "poprosić" przy pomocy funkcji SendMessage() (WyślijKomunikat):
DlugTekstu = SendMessage(hEditWnd, WM_GETTEXTLENGHT, 0, 0);
gdzie:
hEditWnd jest identyfikatorem elementu - okienka edycyjnego
[???]Robi na "szaro'? Podobnie jak opcje w menu - klawisze także mogą zostać udostępnione (ang. enable), bądź zablokowane (ang. disable). Jeśli hKlawisz będzie identyfikatorem elementu sterującego, można go udostępnić (1), bądź zablokować (0) przy pomocy funkcji:
EnableWindow(hKlawisz, 0);
EnableWindow(hKlawisz, 1);
Typowy projekt dla środowiska Windows składa się z kilku (czasem kilkunastu) plików: .H, .MNU, .DLG, .RC, .DEF, .PRJ, .ICO, .BMP, itp. Kompilator zasobów generuje na podstawie tego "składu" końcowy plik aplikacji.
------------------Plik MEDYT-01.H-------------------------------
#define szAppName "MEDYT-01"
#define ID_EDIT 200
------------------Plik główny: MEDYT-01.CPP---------------------
#include <windows.h>
#include "EDIT.H"
#pragma argused
HWND hEditWnd;
long FAR PASCAL WndProc (HWND, unsigned, WORD, LONG) ;
int PASCAL WinMain(HANDLE hInstance, HANDLE hPrevInstance,
LPSTR lpszCmdLine, int nCmdShow)
{
WNDCLASS wndClass;
MSG msg;
HWND hWnd;
RECT rect;
if ( !hPrevInstance )
{
wndClass.style= CS_HREDRAW | CS_VREDRAW ;
wndClass.lpfnWndProc= WndProc;
wndClass.cbClsExtra = 0;
wndClass.cbWndExtra= 0;
wndClass.hInstance = hInstance;
wndClass.hIcon = LoadIcon(NULL, szAppName);
wndClass.hCursor= LoadCursor(NULL, IDC_CROSS);
wndClass.hbrBackground= GetStockObject(WHITE_BRUSH );
wndClass.lpszMenuName= NULL;
wndClass.lpszClassName= szAppName;
if (!RegisterClass(&wndClass))
return 0;
}
hWnd = CreateWindow(szAppName,
"MEDYT-01", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,
0, 0, hInstance, 0);
GetClientRect(hWnd, (LPRECT) &rect);
hEditWnd = CreateWindow ("Edit",NULL, WS_CHILD | WS_VISIBLE |
ES_MULTILINE | WS_VSCROLL |
WS_HSCROLL | ES_AUTOHSCROLL |
ES_AUTOVSCROLL, 0, 0,(rect. right -
rect. left),
(rect. bottom - rect.
top),hWnd,IDC_EDIT, hIstance,NULL);
if( ! hEditWnd )
{
DestroyWindow(hWnd);
return 0;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg );
DispatchMessage(&msg );
}
return 0;
}
long FAR PASCAL WndProc (HWND hWnd, unsigned Message,
WORD wParam, LONG lParam)
{
switch(Message)
{
case ID_EDIT:
if(HIWORD(lParam)==EN_ERRSPACE)
/* starsze słowo lParam zawiera właściwe dla okna edycyjnego
wiadomości, jeżeli jest to EN_ERRSPACE - okno sterujące nie
może alokować dodatkowego obszaru pamięci */
{
MessageBox (GetFocus(), "Brak pamieci", "MEDYT-01",
MB_ICONSTOP | MB_OK);
}
break;
case WM_SETFOCUS:
SetFocus(hEditWnd);
break;
/* Pierwsze dwa parametry funkcji MoveWindow są ustawione na
zero, dzięki temu po zastosowaniu tej funkcji nie zmieni się
wzajemne położenie obu okien, a jedynie uaktualnianiu
ulegnie okno sterujące. */
case WM_SIZE:
MoveWindows(hEditWnd, 0, 0, LOWORD(lParam));
HIWORD(lParam), TRUE);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return (DefWindowProc(hWnd,Message,wParam,lParam));
}
return 0;
}
1