lekcjaB GBJLRGDS5HI2WKCMDFNIW3NRUU3YJZJKSM2P7AY


LEKCJA 42

KOMPILATORY "SPECJALNIE DLA Windows".

Z tej lekcji dowiesz się, czym różnią się kompilatory przeznaczone dla pracy w środowisku Windows.

W IDE i w sposobie zachowania zaszły istotne zmiany. Posługując się Turbo C++ z pakietu BORLAND C++ 3.0 lub BCW z pakietu 3.1 możemy korzystać z uroków i usług Windows szerzej niż do tej pory. Możemy otwierać wiele okien i uruchamiać bezpośrednio z poziomu IDE okienkowe aplikacje. W głównym menu kompilatora zaszły pewne zmiany (sygnalizujące obiektowo- i okienkowo - zorientowaną ewolucję pakietów Borlanda), na które warto zwrócić uwagę. Zniknęło menu Debug (co wcale nie oznacza, że nie możemy korzystać z Debuggera), pojawiło się natomiast nowe menu Browse (przeglądanie). Rozkazy, których tradycyjnie szukaliśmy w menu Debug zostały rozrzucone do innych menu. I tak:

Menu Compile zawiera:

Compile (kompilacja do *.OBJ),

Make (kompilacja i konsolidacja do *.EXE),

Link (konsolidacja bez powtórnej kompilacji),

Build all (konsolidacja wszystkich modułów),

Information... (informacja o przebiegu kompilacji),

Remove messages (usuwanie komunikatów z pliku wynikowego)

Menu Run zawiera:

Run (uruchomienie i ewentualna rekompilcja),

Arguments... (argumenty uruchomieniowe z wiersza rozkazu),

Debugger (zamiast w Debug - TU!)

Debugger arguments... (argumenty dla Debuggera)

Menu Project zawiera:

Open project - otwórz (nowy lub istniejący) plik projektu,

Close project - zamknij projekt,

Add item... - dodaj element (plik) do projektu,

Delete item - usuń element (plik) z projektu,

Include ˙˙files... ˙˙- ˙˙podaj ˙katalog ˙zawierający ˙dodatkowe

dołączane do programu pliki nagłówkowe *.H

W menu Options (zestaw znany już z Borland C++) warto zwrócić uwagę na pewną dodatkową możliwość. Jak wiemy z doświadczenia, uruchamiając program często dokonujemy zmian i korekt w pliku żródłowym *.C, czy *.CPP. Znacznie rzadziej jednak zmieniamy zestaw dołączanych do programu plików nagłówkowych *.H. Wiemy również, że kompilacja tych właśnie plików nagłówkowych zajmuje często lwią część czasu całej kompilacji i konsolidacji programu. Borland zauważył to i w okienku dialogowym:

Options | Compiler | Code generation --> Code Generation Options

umieścił opcję Pre-compiled headers (pliki nagłówkowe wstępnie skompilowane wcześniej - i tylko jeden raz). Szczególnie w przypadku aplikacji okienkowych może to znacznie przyspieszyć proces uruchamiania i "szlifowania" naszych programów. Nie ma jednak nic za darmo. Borland/Turbo C++ po skompilowaniu plików nagłówkowych tworzy na dysku roboczy plik *.SYM nadając mu nazwę zgodną z nazwą bieżącego projektu (jest to zwykle nazwa głównego modułu *.CPP) i do poprawnego działania wymaga kilkadziesiąt lub nawet kilkaset kilobajtów dodatkowej przestrzeni na dysku.

[!!!]UWAGA

Jeśli przenosisz projekt na dyskietkę i tam kontynuujesz pracę nad projektem, pamiętaj, że może zabraknąć miejsca na prekompilowany plik .SYM.

Czytelnik zechce sam sprawdzić w jakim stopniu przyspieszy to kompilację naszego własnego programu proceduralno - zdarzeniowego WINPZ1.CPP:

WINZ1.CPP. Jednomodułowa aplikacja proceduralno - zdarzeniowa dla Windows.

#include <windows.h>

#pragma argused

long FAR PASCAL WndProc (HWND, unsigned, WORD, LONG) ;

int PASCAL WinMain(HANDLE hInstance, HANDLE hPrevInstance,

LPSTR lpszCmdLine, int nCmdShow )

{

WNDCLASS Okno1;

MSG komunikaty;

HWND NrOkna;

LPSTR LongPtr1 = "Okno 1";

LPSTR lp2 = "AM: BC++ 3..4/Reczne sterowanie (1)";

if (hPrevInstance == 0)

{

Okno1.style= CS_HREDRAW | CS_VREDRAW ;

Okno1.lpfnWndProc= WndProc;

Okno1.cbClsExtra = 0;

Okno1.cbWndExtra= 0;

Okno1.hInstance = hInstance;

Okno1.hCursor = LoadCursor(0, IDC_CROSS );

Okno1.hbrBackground= GetStockObject(WHITE_BRUSH );

Okno1.lpszMenuName= 0;

Okno1.lpszClassName= LongPtr1;

if (!RegisterClass(&Okno1))

return 0;

}

NrOkna = CreateWindow(LongPtr1, lp2, WS_VISIBLE |

WS_SYSMENU |

WS_MINIMIZEBOX | WS_VSCROLL | WS_MAXIMIZEBOX,

CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,

0, 0, hInstance, 0);

ShowWindow(NrOkna, nCmdShow);

UpdateWindow(NrOkna);

while (GetMessage(&komunikaty, 0, 0, 0))

{

TranslateMessage(&komunikaty );

DispatchMessage(&komunikaty );

}

return 0;

}

long FAR PASCAL WndProc (HWND NrOkna, unsigned KomunikatWindows,

WORD wParam, LONG lParam)

{

HDC NrKontekstu;

PAINTSTRUCT struktura_graficzna;

RECT prostokat;

switch(KomunikatWindows)

{

case WM_PAINT:

{

NrKontekstu = BeginPaint(NrOkna, &struktura_graficzna);

GetClientRect(NrOkna, &prostokat);

TextOut(NrKontekstu,80,50, ": Reczne sterowanie:", 20 );

TextOut(NrKontekstu, 5,70, "Tu -->", 6);

TextOut(NrKontekstu, 5, 85, "Blad:", 5);

TextOut(NrKontekstu,75,70, "-----------------------------", 40);

TextOut(NrKontekstu,30,110, "Programowanie proceduralno - zdarzeniowe.", 41 );

TextOut(NrKontekstu,30,135, "Szablon moze zostac rozbudowany o inne funkcje.", 47 );

TextOut(NrKontekstu,30,180, "RECZNIE panujemy np. nad:", 25 );

TextOut(NrKontekstu,20,220, "paskiem tytulowym okna, tytulem ikonki...", 41);

TextOut(NrKontekstu, 100, 250, "!KONIEC - [Alt]+[F4]", 20);

EndPaint(NrOkna,&struktura_graficzna);

break;

}

case WM_DESTROY:

{

PostQuitMessage(0);

break;

}

default:

return DefWindowProc(NrOkna,KomunikatWindows,wParam,lParam);

}

return 0;

}

Program demonstruje opisane wyżej mechanizmy, może być uruchamiany wielokrotnie i sprowadzony do ikony. Z uwagi na brak zdefiniowanych dodatkowych zasobów (brak w projekcie plików:

.RC - resources - zasoby

.ICO - ikona

.DEF - definicji

.PRJ lub .IDE - projektu

.DSK - konfiguracyjnego

itp.)

podczas kompilacji programu wystąpią dwa komunikaty ostrzegawcze. Komunikaty te można zignorować. A oto druga przykładowa aplikacja w tym samym stylu. Tym razem funkcja okienkowa reaguje na naciśnięcie lewego klawisza myszki, co powoduje wygenerowanie komunikatu WM_LEFTBUTTONDOWN.

Program WINZ-2.CPP

#include <windows.h>

#include <string.h>

#pragma argused

char napis[10];

int X, Y;

LONG FAR PASCAL WndProc (HWND, WORD, WORD, LONG);

int PASCAL WinMain(HANDLE hInstance, HANDLE hPrevInstance,

LPSTR lpszCmdLine, int nCmdShow )

{

WNDCLASSwndClass;

MSGmsg;

HWNDhWnd;

LPSTR Lp1 = "Mysza1";

LPSTR lp2 = "WINPZ2: Wykrywanie Lewego Klawisza Myszki";

if (!hPrevInstance)

{

wndClass.style= CS_HREDRAW | CS_VREDRAW ;

wndClass.lpfnWndProc= WndProc;

wndClass.cbClsExtra = 0;

wndClass.cbWndExtra= 0;

wndClass.hInstance = hInstance;

wndClass.hIcon = 0;

wndClass.hCursor= LoadCursor(0, IDC_ARROW );

wndClass.hbrBackground= GetStockObject(WHITE_BRUSH );

wndClass.lpszMenuName= 0;

wndClass.lpszClassName= Lp1;

if (!RegisterClass(&wndClass))

exit(1);

}

hWnd = CreateWindow(Lp1, lp2, WS_OVERLAPPEDWINDOW,

CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,

0, 0, hInstance, 0);

ShowWindow(hWnd, nCmdShow);

UpdateWindow(hWnd);

while (GetMessage(&msg, 0, 0, 0))

{

TranslateMessage(&msg );

DispatchMessage(&msg );

}

return 0;

}

LONG FAR PASCAL WndProc (HWND hWnd, WORD Message,

WORD wParam, LONG lParam)

{

HDC hDC;

PAINTSTRUCT ps;

RECT rect;

switch(Message)

{

case WM_SIZE:

hDC = GetDC( hWnd );

TextOut(hDC, 50, 100, "Wykrywanie nacisniecia", 22);

TextOut(hDC, 50, 120, "lewego klawisza myszki.", 23);

TextOut(hDC, 20, 140, "Komunikat o zdarzeniu: ", 22);

TextOut(hDC, 20, 156, "Left Button Down - LBUTTONDOWN", 31);

TextOut(hDC, 50, 170, "Po wcisnieciu klawisza,", 23);

TextOut(hDC, 50, 190,"w biezacej pozycji kursora, pojawi sie napis <-- Tu!.", 52);

ReleaseDC(hWnd, hDC);

break;

case WM_PAINT:

hDC = BeginPaint(hWnd, &ps);

TextOut(hDC, X,Y, napis, strlen(napis));

EndPaint(hWnd, &ps);

break;

case WM_LBUTTONDOWN:

strcpy(napis,"<-- Tu !");

X = LOWORD(lParam);

Y = HIWORD(lParam);

InvalidateRect(hWnd, 0, TRUE);

UpdateWindow(hWnd);

break;

case WM_DESTROY:

PostQuitMessage(0); break;

default:

return DefWindowProc(hWnd, Message, wParam, lParam);

}

return 0;

}

Plik nagłówkowy STRING.H pojawia się ze względu na obecność funkcji strlen() wyznaczającej długość napisu. Zmienne X i Y to bieżące (względne) współrzędne kursora myszki w momencie naciśnięcia klawisza. Program demonstruje następujące efekty:

X = LOWORD(lParam);

- przekazanie współrzędnej X przy pomocy parametru lParam (LOWORD to LOw WORD of the double word - młodsze słowo podójnego słowa).

Y = HIWORD(lParam);

Analogicznie - przekazanie współrzędnej Y (HIgh WORD of the double word). Funkcja InvalidateRect() powoduje uznanie prostokąnego pola za nieaktualne. Funkcja UpdateWindow() "odświeża" okno. Dzięki temu tandemowi napis znika i pojawia się w nowym miejscu.

PROJEKT.

Aby skompilować powyższe programy przykładowe należy:

1. Uruchomić kompilator C++.

2. Załadować do okienka edycyjnego (File | Open) plik z tekstem żródłowym programu.

3. Wybrać rozkaz Compile z menu Compile. Przed kompilacją i konsolidacją (jeśli był inny) ustawić sposób tworzenia kodu wynikowego [Windows EXE].

Kompilacja przebiegnie poprawnie (pamiętaj o Opcjach i Katalogach), mimo to pojawią się jednak dwa komunikaty ostrzegawcze. W okienku "Compile Status" (stan/przebieg kompilacji) pojawi się zawartość:

Lines 3832 (znakomita większość to WINDOWS.H, prekompilacja byłaby celowa)

Warnings: 1

Errors: 0

Jeśli wybierzesz klawisz [OK] w okienku "focus" (aktywność) zostanie przekazana do okienka komunikatów "Message" a tam pojawi się napis:

Warning: Parameter 'lspzCmdLine' is never used.

Wskaźnik do parametrów uruchomieniowych programu (Arguments) pobieranych z wiersza rozkazu nie został ani raz użyty w programie. Na to nic nie możemy poradzić. Po prostu argumenty uruchomieniowe nie są nam potrzebne. Wykonujemy więc "klik" (przekazanie "focusa") w okienku edycyjnym i możemy przejść do następnej czynności:

4. Konsolidacja: Compile | Link.

W okienku "Message" znów pojawi się ostrzeżenie: Linker Warning: No module definition file specified:

using defaults.

(brak wyspecyfikowanego pliku definicji .DEF; stosuję wartości domyślne) I tu już możemy coś zaradzić. Możemy zatem pokusić się o stworzenie naszego pierwszego pliku definicji (nazwa jest trochę myląca - chodzi o zdefiniowanie sposobu wykorzystania zasobów środowiska Windows). Aby utworzyć plik .DEF (jest to plik ASCII) należy:

1. Otworzyć nowe okienko edycyjne (nie wychodząc z IDE): File | New Otworzy się okienko NONAMExx.CPP. Ta nazwa nie jest oczywiście najodpowiedniejsza, więc umieszczamy plik we właściwym katalogu (tym samym, co główny program *.CPP) przy pomocy rozkazu File | Save as... i nadajemy plikowi stosowną nazwę i rozszerzenie *.DEF. Okieno pozostaje puste, ma jednak "focus" i nową nazwę, np. C:\..\PR.DEF.

3. Redagujemy nasz pierwszy plik definicji, np. tak:

NAME JAKAKOLWIEK // <-- nazwa aplikacji

DESCRIPTION 'Opis: A. MAJCZAK, BC C++ 3...4'

EXETYPE WINDOWS // <-- EXE dla Windows

CODE PRELOAD MOVEABLE DISCARDABLE

DATA PRELOAD MOVEABLE MULTIPLE

HEAPSIZE 4096 // <-- sterta 4 KB

STACKSIZE 5120 // <-- stos 5 KB

UWAGA: W przypadku tworzenia bibliotek .DLL dane muszą mieć status SINGLE (pojedyncze) zamiast MULTIPLE (wielokrotne). Użycie tu słowa MULTIPLE pozwoli nam na wielokrotne uruchamianie aplikacji.

Możnaby tu zapytać - po co to robić, skoro używamy standardowych wartości i obecność tego pliku nie wnosi nic nowego do sposobu działania naszego programu? Odpowiedź jest prosta. Mając taki plik będziemy mogli prześledzić stadia tworzenia tzw. projektu (w BC++ 4 bez tego ani rusz). Zapisujemy zatem plik na dysk:

4. File | Save. (plik .DEF zostaje zapisany na dysku). Ponieważ pracujemy w środowisku Windows, okno edycji pliku *.DEF możemy traktować podobnie jak każde inne okno. Najwygodniej zatem przejść do okna edycji głównego pliku żródłowego *.CPP przy pomocy własnego menu systemowego tegoż okna.

5. Menu Systemowe [-] | Zamknij. I możemy przystąpić do tworzenia projektu składającego się z dwu plików: *.CPP i *.DEF. Jeśli, dla przykładu, przyjmiemy w tym miejscu, że nasze dwa moduły nazywają się: WINZ2.CPP i WINZ2.DEF i są przechowywane w katalogu głównym dysku C:\ , kolejność czynności powinna być następująca:

1. Rozwijamy menu Project ([Alt]+[P] lub myszką).

2. Wybieramy z menu rozkaz Open Project... (Utwórz projekt). Pojawia się okienko dialogowe Open Project File z domyślnym rozszerzeniem *.PRJ (w BC 4+ - *.IDE).

3. Do okienka File Name: wpisujemy nazwę pliku z opisem projektu: np. WINZ2.PRJ. W dolnej części ekranu otwiera się okienko Project: WINZ2

4. Wybieramy z menu Project rozkaz Add item... (dodaj element do projektu). Pojawia się okienko dialogowe "Add to Project List" (dodawanie do listy elementów projektu).

5. Do okienka File Name: wpisujemy nazwę głównego pliku projektu: WINZ2.CPP (*.cpp jest domyślnym rozszerzeniem). Plik możemy wybrać także z listy w okienku Files: .

6. Wybieramy w okienku dialogowym klawisz [+Add] (dodaj do projektu).

7. Wpisujemy nazwę kolejnego pliku wchodzącego w skład projektu (w tym przypadku WINZ2.DEF).

8. Wybieramy klawisz [+Add] w okienku. UWAGA: Czynności 7) i 8) w przypadku bardziej złożonych projektów będą powtarzane wielokrotnie.

9. Wybieramy klawisz [Done] w okienku (zrobione/gotowe). Konfigurowanie projektu zostało zakończone.

10. Przy pomocy rozkazów Compile, Link, Make, Build all, Run możemy teraz skompilować, skonsolidować i uruchomić nasz program w postaci projektu. Ostrzeżenie Linkera zniknie.

[!!!]UWAGA

W dolnej części ekranu w stadium tworzenia projektów ( i póżniej po załadowaniu pliku projektu [Open Project] pojawi się lista plików. Do trybu edycji pliku możesz przjść poprzez dwukrotne klinięcie pliku na tej liście. Zwróć uwagę, że pliki projektów .PRJ ( w Borland 4+ .IDE) przechowują również informacje o konfiguracji. Najważniejsza z nich to informacja o katalogach, z których korzysta kompilator:

Options | Directories... | Include

Options | Directories... | Library

Options | Directories... | Output

Najwygodniej przechowywać wszystkie pliki wchodzące w skład jednego projektu w odrębnym katalogu dyskowym. Dla wprawy załóż odrębny katalog i zapisz tam pliki:

*.CPP

*.DEF

*.PRJ (lub *.IDE)

dla swoich pierwszych dwóch projektów, które właśnie powstały.

[!!!] UWAGA

Ten sam plik definicji możesz wykorzystywać do tworzenia następnych przykładowych aplikacji typu Windows EXE.

6



Wyszukiwarka

Podobne podstrony:
Lekcja kliniczna 2 VI rok WL
Lekcja Przysposobienia Obronnego dla klasy pierwszej liceum ogólnokształcącego
Lekcja wychowania fizycznego jako organizacyjno metodyczna forma lekcji ruchu
Lekcja kliniczna nr 2 VI rok WL
04 Lekcja
PF7 Lekcja2
lekcja52
Printing bbjorgos lekcja41 uzupelnienie A
lekcja 18 id 265103 Nieznany
Hydrostatyka i hydrodynamika lekcja ze wspomaganiem komputerowym
Lekcja 6 Jak zapamietywac z notatki Tajemnica skutecznych notatek
lekcja 20
lekcja20
Lekcja 04 Szene 04
LINGO ROSYJSKI raz a dobrze Intensywny kurs w 30 lekcjach PDF nagrania audio audio kurs
Printing bbjorgos lekcja01 05 A
'Half Life', czyli pół życia przed monitorem zagrożenia medialne foliogramy gim modul 3 lekcja 5
Lekcja od mamy
lekcja 3 id 265134 Nieznany

więcej podobnych podstron