Cyfroteka.pl

klikaj i czytaj online

Cyfro
Czytomierz
00514 008210 10498176 na godz. na dobę w sumie
C++. Elementarz hakera - książka
C++. Elementarz hakera - książka
Autor: Liczba stron: 296
Wydawca: Helion Język publikacji: polski
ISBN: 83-7361-801-5 Data wydania:
Lektor:
Kategoria: ebooki >> komputery i informatyka >> hacking >> inne
Porównaj ceny (książka, ebook, audiobook).

Poznaj techniki tworzenia programów,
które zadziwią użytkowników swoim działaniem

Haker, wbrew utartym poglądom, nie jest osobą, której głównym celem jest niszczenie -- haker to ktoś, kto podchodzi do standardowych problemów programistycznych w niestandardowy sposób, tworząc własne rozwiązania, często zaskakujące innych. Opracowywanie takich nietypowych rozwiązań wymaga wszechstronnej wiedzy z zakresu programowania, znajomości systemu operacyjnego i umiejętności wynajdowania i stosowania nieudokumentowanych funkcji języków programowania i platform systemowych.

'C++. Elementarz hakera' to książka przeznaczona dla wszystkich tych, którym 'zwykłe' programowanie już nie wystarcza i którzy chcą stworzyć coś wyjątkowego. Przedstawia techniki, dzięki którym programy będą działać szybciej, a efekty ich działania będą zachwycać i zaskakiwać. Czytając ją, nauczysz się pisać aplikacje, które rozbawią lub zirytują innych użytkowników, tworzyć narzędzia do skanowania portów oraz wykorzystywać wiedzę o systemach operacyjnych i językach programowania do optymalizacji i przyspieszania działania programów.

Wiedząc, jak działają hakerzy, będziesz mógł zabezpieczyć swoje aplikacje przed atakami tych, którzy swoją wiedzę wykorzystują w niewłaściwy sposób.

Znajdź podobne książki Ostatnio czytane w tej kategorii

Darmowy fragment publikacji:

IDZ DO IDZ DO PRZYK£ADOWY ROZDZIA£ PRZYK£ADOWY ROZDZIA£ SPIS TREĎCI SPIS TREĎCI KATALOG KSI¥¯EK KATALOG KSI¥¯EK KATALOG ONLINE KATALOG ONLINE ZAMÓW DRUKOWANY KATALOG ZAMÓW DRUKOWANY KATALOG TWÓJ KOSZYK TWÓJ KOSZYK DODAJ DO KOSZYKA DODAJ DO KOSZYKA CENNIK I INFORMACJE CENNIK I INFORMACJE ZAMÓW INFORMACJE ZAMÓW INFORMACJE O NOWOĎCIACH O NOWOĎCIACH ZAMÓW CENNIK ZAMÓW CENNIK CZYTELNIA CZYTELNIA FRAGMENTY KSI¥¯EK ONLINE FRAGMENTY KSI¥¯EK ONLINE Wydawnictwo Helion ul. Chopina 6 44-100 Gliwice tel. (32)230-98-63 e-mail: helion@helion.pl C++. Elementarz hakera Autor: Michael Flenov T³umaczenie: Przemys³aw Szeremiota ISBN: 83-7361-801-5 Tytu³ orygina³u: Hackish C++ Pranks Tricks Format: B5, stron: 296 Haker, wbrew utartym pogl¹dom, nie jest osob¹, której g³ównym celem jest niszczenie — haker to ktoġ, kto podchodzi do standardowych problemów programistycznych w niestandardowy sposób, tworz¹c w³asne rozwi¹zania, czêsto zaskakuj¹ce innych. Opracowywanie takich nietypowych rozwi¹zañ wymaga wszechstronnej wiedzy z zakresu programowania, znajomoġci systemu operacyjnego i umiejêtnoġci wynajdowania i stosowania nieudokumentowanych funkcji jêzyków programowania i platform systemowych. „C++. Elementarz hakera” to ksi¹¿ka przeznaczona dla wszystkich tych, którym „zwyk³e” programowanie ju¿ nie wystarcza i którzy chc¹ stworzyæ coġ wyj¹tkowego. Przedstawia techniki, dziêki którym programy bêd¹ dzia³aæ szybciej, a efekty ich dzia³ania bêd¹ zachwycaæ i zaskakiwaæ. Czytaj¹c j¹ nauczysz siê pisaæ aplikacje, które rozbawi¹ lub zirytuj¹ innych u¿ytkowników, jak tworzyæ narzêdzia do skanowania portów i jak wykorzystywaæ wiedzê o systemach operacyjnych i jêzykach programowania do optymalizacji i przyspieszania dzia³ania programów. • Optymalizacja kodu ĥród³owego i usuwanie w¹skich garde³ • Zasady prawid³owego projektowania aplikacji • Tworzenie programów-¿artów • Programowanie w systemie Windows • Sieci i protoko³y sieciowe • Implementacja obs³ugi sieci we w³asnych aplikacjach • Sztuczki ze sprzêtem • Techniki hakerskie Wiedz¹c, jak dzia³aj¹ hakerzy, bêdziesz w stanie zabezpieczyæ swoje aplikacje przed atakami tych, którzy swoj¹ wiedzê wykorzystuj¹ w niew³aġciwy sposób. Spis treści Wstęp ...................................................w............................................ 7 Wprowadzenie ...................................................w................................ 9 O książce ............................................................................................................................. 9 Kim jest haker? Jak zostać hakerem? ............................................................................... 11 Rozdział 1. Jak uczynić program zwartym, a najlepiej niewidzialnym? .................. 19 1.1. Kompresowanie plików wykonywalnych.................................................................. 19 1.2. Ani okna, ani drzwi… ............................................................................................... 24 1.3. Wnętrze programu..................................................................................................... 30 1.3.1. Zasoby projektu .............................................................................................. 31 1.3.2. Kod źródłowy programu ................................................................................. 33 1.4. Optymalizacja programu ........................................................................................... 43 Zasada 1. Optymalizować można wszystko.............................................................. 44 Zasada 2. Szukaj wąskich gardeł i słabych ogniw..................................................... 44 Zasada 3. W pierwszej kolejności optymalizuj operacje często powtarzane............ 45 Zasada 4. Pomyśl dwa razy, zanim zoptymalizujesz operacje jednorazowe ............ 47 Zasada 5. Poznaj wnętrze komputera i sposób jego działania.................................. 48 Zasada 6. Przygotuj tabele gotowych wyników obliczeń i korzystaj z nich w czasie działania programu................................................................................... 49 Zasada 7. Nie ma niepotrzebnych testów.................................................................. 50 Zasada 8. Nie bądź nadgorliwy................................................................................. 50 Podsumowanie ........................................................................................................... 51 1.5. Prawidłowe projektowanie okien .............................................................................. 51 1.5.1. Interfejs okna głównego.................................................................................. 54 1.5.2. Elementy sterujące .......................................................................................... 55 1.5.3. Okna dialogowe .............................................................................................. 55 Rozdział 2. Tworzenie prostych programów-żartów.............................................. 61 2.1. Latający przycisk Start .............................................................................................. 62 2.2. Zacznij pracę od przycisku Start................................................................................ 71 2.3. Zamieszanie z przyciskiem Start ............................................................................... 73 2.4. Więcej dowcipów z paskiem zadań ........................................................................... 76 2.5. Inne żarty.................................................................................................................... 83 Jak „zgasić” monitor? ............................................................................................... 83 Jak uruchamiać systemowe pliki CPL?..................................................................... 83 Jak wysunąć tackę napędu CD-ROM?...................................................................... 84 Jak usunąć zegar z paska zadań?............................................................................... 86 4 C++. Elementarz hakera Jak ukryć cudze okno? .............................................................................................. 86 Jak ustawić własną tapetę pulpitu? ........................................................................... 87 2.6. Berek z myszą ............................................................................................................ 88 Szalona mysz ............................................................................................................. 88 Latające obiekty......................................................................................................... 89 Mysz w klatce ............................................................................................................ 90 Jak zmienić kształt wskaźnika myszy? ..................................................................... 91 2.7. Znajdź i zniszcz .......................................................................................................... 92 2.8. Pulpit .......................................................................................................................... 93 2.9. Bomba sieciowa ......................................................................................................... 94 Rozdział 3. Programowanie w systemie Windows ............................................... 97 3.1. Manipulowanie cudzymi oknami............................................................................... 97 3.2. Gorączkowa drżączka.............................................................................................. 102 3.3. Przełączanie ekranów .............................................................................................. 103 3.4. Niestandardowe okna .............................................................................................. 107 3.5. Finezyjne kształty okien .......................................................................................... 113 3.6. Sposoby chwytania nietypowego okna.................................................................... 119 3.7. Ujawnianie haseł ..................................................................................................... 121 3.7.1. Biblioteka deszyfrowania haseł..................................................................... 122 3.7.2. Deszyfrowanie hasła ..................................................................................... 126 3.7.3. Obróćmy to w żart......................................................................................... 128 3.8. Monitorowanie plików wykonywalnych ................................................................. 130 3.9. Zarządzanie ikonami pulpitu ................................................................................... 132 3.9.1. Animowanie tekstu ....................................................................................... 133 3.9.2. Odświeżanie pulpitu...................................................................................... 134 3.10. Żarty z wykorzystaniem schowka ........................................................................... 134 Rozdział 4. Sieci komputerowe ...................................................w..................... 139 4.1. Teoria sieci i protokołów sieciowych ...................................................................... 139 4.1.1. Protokoły sieciowe........................................................................................ 141 Protokół IP .................................................................................................... 142 Protokół ARP a protokół RARP ................................................................... 143 4.1.2. Protokoły transportowe ................................................................................. 143 Protokół UDP — szybki ............................................................................... 143 Protokół TCP — wolniejszy, ale solidniejszy.............................................. 144 TCP — zagrożenia i słabości ........................................................................ 145 4.1.3. Protokoły warstwy aplikacji — tajemniczy NetBIOS.................................. 145 4.1.4. NetBEUI ........................................................................................................ 146 4.1.5. Gniazda w Windows ..................................................................................... 147 4.1.6. Protokoły IPX/SPX....................................................................................... 147 4.1.7. Porty............................................................................................................... 148 4.2. Korzystanie z zasobów otoczenia sieciowego ......................................................... 148 4.3. Struktura otoczenia sieciowego ............................................................................... 151 4.4. Obsługa sieci za pośrednictwem obiektów MFC..................................................... 158 4.5. Transmisja danych w sieci za pośrednictwem obiektu CSocket............................. 165 4.6. Bezpośrednie odwołania do biblioteki gniazd ......................................................... 174 4.6.1. Obsługa błędów ............................................................................................ 175 4.6.2. Wczytywanie biblioteki gniazd..................................................................... 175 4.6.3. Tworzenie gniazda ........................................................................................ 179 4.6.4. Funkcje strony serwera ................................................................................. 180 4.6.5. Funkcje strony klienta................................................................................... 184 4.6.6. Wymiana danych........................................................................................... 186 4.6.7. Zamykanie połączenia................................................................................... 191 4.6.8. Zasady stosowania protokołów bezpołączeniowych .................................... 192 Spis treści 5 4.7. Korzystanie z sieci za pośrednictwem protokołu TCP ........................................... 194 4.7.1. Przykładowy serwer TCP.............................................................................. 194 4.7.2. Przykładowy klient TCP ............................................................................... 199 4.7.3. Analiza przykładów ...................................................................................... 202 4.8. Przykłady wykorzystania protokołu UDP ............................................................... 204 4.8.1. Przykładowy serwer UDP ............................................................................. 204 4.8.2. Przykładowy klient UDP .............................................................................. 205 4.9. Przetwarzanie odebranych danych........................................................................... 207 4.10. Wysyłanie i odbieranie danych................................................................................ 209 4.10.1. Funkcja select ............................................................................................... 210 4.10.2. Prosty przykład stosowania funkcji select..................................................... 211 4.10.3. Korzystanie z gniazd za pośrednictwem komunikatów systemowych ......... 213 4.10.4. Asynchroniczna wymiana danych z wykorzystaniem obiektów zdarzeń..... 220 Rozdział 5. Obsługa sprzętu ...................................................w.......................... 223 5.1. Parametry podsystemu sieciowego.......................................................................... 223 5.2. Zmiana adresu IP komputera................................................................................... 229 5.3. Obsługa portu szeregowego..................................................................................... 234 5.4. Pliki zawieszające system........................................................................................ 239 Rozdział 6. Sztuczki, kruczki i ciekawostki ...................................................w... 241 6.1. Algorytm odbioru-wysyłania danych ...................................................................... 242 6.2. Szybki skaner portów .............................................................................................. 245 6.3. Stan portów komputera lokalnego ........................................................................... 252 6.4. Serwer DHCP........................................................................................................... 257 6.5. Protokół ICMP ......................................................................................................... 260 6.6. Śledzenie trasy wędrówki pakietu ........................................................................... 267 6.7. Protokół ARP ........................................................................................................... 273 Podsumowanie ...................................................w........................... 283 Skorowidz...................................................w................................... 285 Rozdział 3. Programowanie w systemie Windows W niniejszym rozdziale przyjrzymy się różnym narzędziom systemowym. Zobaczymy przykłady programów, które pomagają podglądać przebieg pracy komputera. Nie służą one tylko do zabawy. Będziemy w istocie pracować z systemem operacyjnym, choć w wielu przykładach będziemy się uciekać do żartów. Pisałem już, że każdy haker to profe- sjonalista — powinien więc znać tajniki systemu operacyjnego, z którego korzysta. Zakładam tutaj, że Czytelnik korzysta z systemu Windows i pisze bądź ma zamiar pisać programy przeznaczone do uruchamiania w tym właśnie systemie. Rozdział ten ma Czytelnikowi pomóc lepiej zrozumieć system. Jak zwykle, zamiast przeciążać pamięć teorią, będziemy się uczyć przez praktykę. Czytelnicy moich poprzednich książek z pew- nością pamiętają to podejście. Zawsze twierdziłem, że jedynie praktyka daje prawdziwą wiedzę. Dlatego wszystkie moje książki są wprost przeładowane przykładami. Nie in- aczej będzie tym razem. Zabierzemy się za chwilę za analizę kilku ciekawych przykładów. Będą one ilustrować techniki pracy w systemie operacyjnym Windows i uczyć praktycznego ich zastoso- wania. Mam nadzieję, że choć niektóre z nich przydadzą się Czytelnikowi w pracy. Będę starał się w tym rozdziale stopniować poziom zaawansowania przykładów, tak aby kolejne prezentacje wnosiły coś nowego i Czytelnik nie stracił zainteresowania tematem. 3.1. Manipulowanie cudzymi oknami W mojej skrzynce poczty elektronicznej często lądują pytania: „Jak zamknąć czyjeś okno albo coś w nim zmienić?”. Zasadniczo zadanie to można łatwo zrealizować funkcją (KPF9KPFQY, z którą zdążyliśmy się już zapoznać. Jeśli jednak zachodzi potrzeba 98 C++. Elementarz hakera ingerowania w kilka (albo wszystkie) okien, należałoby skorzystać z innej niż propo- nowana wcześniej metody wyszukiwania. Napiszmy na początek program, który wy- szuka wszystkie okna na pulpicie i zmieni ich tytuły. Rysunek 3.1 prezentuje wpływ naszego programu na okno innego programu. Jak widać, to ostatnie ma na belce tytułowej napis: „Widzę Cię!”. Rysunek 3.1. Efekt działania programu Utwórz w Visual C++ nowy projekt Win32 Project i wyposaż go w menu, za pomocą którego będziesz uruchamiał właściwą funkcję programu. Do funkcji 9PF2TQE dodaj następujący kod obsługi komunikatu wywołania menu: ECUG+ A/1, / 07A9+ +  YJKNG 647 ]  PWO9KPFQYU  PWO9KPFQYU9PF  _ + A/1, / 07A9+ + jest tu oczywiście identyfikatorem utworzonej pozycji menu. Obsługująca ją pętla YJKNG jest pętlą nieskończoną wywołującą wciąż funkcję PWO 9KPFQYU  PWO9KPFQYU9PF  . To funkcja WinAPI wykorzystywana do wyliczania wszystkich otwartych okien. Jej pierwszym parametrem jest adres innej funkcji (tzw. funkcji zwrotnej), która będzie wywoływana za każdym razem, kiedy wykryte zosta- nie działające okno. Drugi parametr to liczba przekazywana do owej funkcji zwrotnej. W roli funkcji zwrotnej występuje tu PWO9KPFQYU9PF. Dla każdego okna, które znaj- dzie funkcja PWO9KPFQYU, wywołana zostanie funkcja PWO9KPFQYU9PF. Oto jej kod: Rozdział 3. ♦ Programowanie w systemie Windows 99 $11. #..$# - PWO9KPFQYU9PF *90 JYPFuchwyt okna-rodzica .2#4#/N2CTCOparametr własny funkcji zwrotnej  ] 5GPF/GUUCIG JYPF9/A5 66 :6.2#4#/ .2 6564 9KFú Kú  TGVWTP647  _ Liczba i typy parametrów funkcji zwrotnej oraz typ wartości zwracanej powinny być następujące:  Pierwszy parametr — uchwyt znalezionego okna (typu *90 ).  Drugi parametr — wartość typu .2#4#/ wykorzystywana wedle uznania programisty funkcji zwrotnej.  Wartość zwracana — wartość logiczna (typu $11.). Jeśli zmienisz typy bądź kolejność parametrów albo typ wartości zwracanej, funkcja stanie się niezgodna z funkcją PWO9KPFQYU. Aby uniknąć pomyłek, skopiowałem na- zwę funkcji i jej parametry z plików pomocy opisujących interfejs WinAPI. Wolę to od późniejszego szukania literówek w kodzie źródłowym i zalecam wszystkim takie samo postępowanie. W tym celu należy odszukać w pomocy hasło PWO9KPFQY i zna- leźć w opisie odsyłacz do opisu formatu funkcji zwrotnej. W momencie wywołania funkcji zwrotnej mamy do dyspozycji uchwyt następnego znalezionego okna. Wykorzystywaliśmy już takie uchwyty do chowania okien. Teraz spróbujemy za pośrednictwem uchwytu zmienić tytuł okna. Posłuży do tego znana nam już funkcja 5GPF/GUUCIG służąca do wysyłania komunikatów systemu Windows. Oto jej parametry:  Uchwyt okna adresata komunikatu. Otrzymaliśmy go w postaci parametru wywołania funkcji zwrotnej.  Typ komunikatu — 9/A5 66 :6 to komunikat zmieniający tytuł okna.  Parametr komunikatu — tutaj 0.  Ciąg nowego tytułu okna. Aby program kontynuował wyszukiwanie kolejnych okien, funkcja zwrotna powinna zwrócić wartość 647 . Kod źródłowy tego przykładu oraz jego pliki wykonywalne znajdują się na dołączonej do książki płycie CD-ROM w podkatalogu PrzykładyRozdział3ISeeYou. Skomplikujmy nieco program, zmieniając na początek funkcję PWO9KPFQYU9PF w sposób następujący: $11. #..$# - PWO9KPFQYU9PF *90 JYPFuchwyt okna-rodzica .2#4#/N2CTCOparametr własny funkcji zwrotnej  100 C++. Elementarz hakera ] 5GPF/GUUCIG JYPF9/A5 66 :6.2#4#/ .2 6564 9KFú Kú   PWO JKNF9KPFQYU JYPF PWO JKNF9PF  TGVWTP647  _ Tym razem po wysłaniu do znalezionego okna komunikatu zmiany tytułu wywoły- wana jest funkcja PWO JKNF9KPFQYU, która wyszukuje wszystkie okna potomne dane- go okna. Przyjmuje ona trzy parametry:    Uchwyt okna rodzica, którego okna potomne mają być wyszukane. Podajemy tu właśnie odnalezione okno, którego uchwyt przekazany został w wywołaniu PWO9KPFQYU9PF. Adres funkcji zwrotnej wywoływanej dla kolejnych okien potomnych. Liczba przekazywana jako własny parametr funkcji zwrotnej. Łatwo zauważyć, że funkcja PWO JKNF9PF powinna działać podobnie jak PWO9KP FQYU9PF. Ta ostatnia zmienia tytuły wszystkich okien w systemie, pierwsza zaś będzie zmieniać nazwy okien potomnych. Przykładem efektu jej działania jest rysunek 3.2. Rysunek 3.2. Okno ze zmienionymi podpisami okien potomnych Wiemy już, że również PWO JKNF9PF ma zmieniać podpis czy tytuł okna. Aby po zmianie można było kontynuować wyszukiwanie okien potomnych, funkcja powinna zwrócić wartość 647 . Program można by uznać za kompletny, ale ma on jeszcze pewną słabość, którą trze- ba wyeliminować. Przypuśćmy, że program znajdzie okno i rozpocznie wyliczanie jego okien potomnych, ale użytkownik nagle zamknie okno-rodzica. Program będzie próbował wysłać komunikat do znalezionego okna potomnego, które nie będzie już istniało, co doprowadzi do błędu wykonania programu. Aby tego uniknąć, należałoby za każdym razem sprawdzać poprawność otrzymanego uchwytu okna: Rozdział 3. ♦ Programowanie w systemie Windows 101 KH JYPF TGVWTP647  Teraz program można uznać za gotowy. Pamiętaj, że nie ma czegoś takiego, jak nadmierna ostrożność w programowaniu. Jeśli program ma być niezawodny, należy wziąć pod uwagę wszystkie możliwe okoliczno- ści jego działania, które mogą doprowadzić do problemów. W niektórych przykładach ignoruję tę regułę, chcąc uniknąć komplikowania i gmatwania kodu przykładowego. Będę jednak wskazywał te miejsca w kodzie, które wymagają szczególnej rozwagi. Kod źródłowy tego przykładu oraz jego pliki wykonywalne znajdują się na dołączonej do książki płycie CD-ROM w podkatalogu PrzykładyRozdział3ISeeYou2. W przykładach z rozdziału 2. próbowałem zazwyczaj umieścić cały kod w głównej pętli komunikatów. Program wykonywał swoje zadanie, a potem przechodził do obsługi ko- munikatów systemowych. Aby zakończyć takie programy, wystarczyło zamknąć ich okna. W programie, który teraz omawiamy, występuje nieskończona pętla poza pętlą obsługi komunikatów. Oznacza to, że w czasie działania programu, kiedy wkroczy on już do naszej pętli nieskończonej, obsługa komunikatów zostanie zawieszona. Taki program bardzo trudno byłoby zamknąć. Użytkownik programu od razu zrozumie, w czym sęk, ponieważ okno programu po wybraniu pozycji menu uruchamiającej zmianę tytułów przestanie odpowiadać. Będzie można pozbyć się programu jedynie przez jego zatrzyma- nie z poziomu menedżera zadań. Taki efekt uboczny jest korzystny w przypadku okien niewidocznych. Jeśli kod wy- świetlający okno główne zostałby usunięty z programu, również główna pętla komuni- katów stałaby się zbędna i można by się jej pozbyć. Dodajmy do naszego programu jeszcze jeden prosty, acz interesujący efekt. Spróbujmy zminimalizować wszystkie okna. Funkcja zwrotna PWO9KPFQYU9PF (wywoływana dla każdego znalezionego okna) powinna wyglądać tak: $11. #..$# - PWO9KPFQYU9PF *90 JYPFuchwyt okna-rodzica .2#4#/N2CTCOparametr własny funkcji zwrotnej  ] 5JQY9KPFQY JYPF59A/+0+/+  TGVWTP647  _ W powyższym kodzie zastosowaliśmy nową wartość drugiego parametru funkcji 5JQY9KPFQY. Wymusza ona minimalizację okna. Uruchamiając ten program, należy zachować ostrożność. Funkcja (KPF9KPFQY wylicza bowiem wszystkie okna, również te, które są niewidoczne. Kod źródłowy tego przykładu oraz jego pliki wykonywalne znajdują się na dołączonej do książki płycie CD-ROM w podkatalogu PrzykładyRozdział3RandMinimize. 102 C++. Elementarz hakera 3.2. Gorączkowa drżączka Skomplikujmy przykład z poprzedniego podrozdziału, pisząc program, który będzie zmieniał pozycje i rozmiary wszystkich okien tak, aby system wyglądał jak w febrze. Stwórz nowy projekt typu Win32 Project w Visual C++. Dodaj do projektu pozycję menu, za pośrednictwem której będziesz wywoływać rzeczony efekt. W kodzie źródłowym projektu znajdź funkcję 9PF2TQE, obsługującą komunikaty kierowane do okna programu. Ruchy okien muszą być opóźniane tak, aby były dobrze widoczne. Do tego celu przy- da się zmienna typu *#0 . inicjalizowana wywołaniem funkcji TGCVG XGPV: *#0 . J J TGCVG XGPV 647 (#.5 GV  Kod obsługi komunikatu wywołania polecenia menu powinien wyglądać następująco: ECUG+ A/1, / 07A( $4# YJKNG 647 ]  PWO9KPFQYU  PWO9KPFQYU9PF  9CKV(QT5KPING1DLGEV J opóźnienie _ Jak w poprzednim przykładzie inicjujemy pętlę nieskończoną. Wewnątrz pętli wyliczamy wszystkie okna, opóźniając kolejny przebieg pętli za pomocą znanej już Czytelnikowi funkcji 9CKV(QT5KPING1DLGEV. Najciekawszy jest w tym przykładzie kod funkcji zwrotnej PWO9KPFQYU9PF prezento- wany na listingu 3.1. Listing 3.1. Funkcja zwrotna EnumWindowsWnd $11. #..$# - PWO9KPFQYU9PF *90 JYPFuchwyt okna-rodzica .2#4#/N2CTCOparametr własny funkcji zwrotnej  ] KH +U9KPFQY8KUKDNG JYPF (#.5 TGVWTP647  4 6TGEV )GV9KPFQY4GEV JYPFTGEV  KPVKPFGZTCPF  KH KPFGZ ] TGEVVQRTGEVVQR  TGEVNGHVTGEVNGHV  _ GNUG ] TGEVVQRTGEVVQR TGEVNGHVTGEVNGHV _ Rozdział 3. ♦ Programowanie w systemie Windows 103 /QXG9KPFQY JYPFTGEVNGHVTGEVVQRTGEVTKIJVTGEVNGHV TGEVDQVVQOTGEVVQR647  TGVWTP647  _ Spójrzmy, co takiego robi funkcja PWO9KPFQYU9PF wywoływana dla każdego znalezione- go w systemie okna. Po pierwsze, wywołuje ona funkcję +U9KPFQY8KUKDNG, która spraw- dza, czy znalezione okno jest w tej chwili widoczne. Jeśli nie jest, funkcja zwrotna zwraca wartość 647 , umożliwiając jej wywołanie dla kolejnego okna. Jeśli okno jest niewidoczne, nie warto go przesuwać czy rozciągać. Następnie wywoływana jest funkcja )GV9KPFQY4GEV. Przyjmuje za pośrednictwem pierw- szego parametru uchwyt okna docelowego, zwracając w drugim parametrze rozmiary okna opisane strukturą 4 6 (opisującą współrzędne prostokątnego obszaru okna po- lami NGHV, VQR, TKIJV i DQVVQO). Po określeniu rozmiarów okien wyznaczamy funkcją TCPF liczbę losową z zakresu od zera do jeden. Jeśli wynik jest równy zero, wartości pól VQR i NGHV struktury wymiarów okna są zwiększane o 3. Jeśli wypadnie jeden, wartości tych pól są zmniejszane o 3. Po zmianie parametrów prostokąta przesuwamy okno funkcją /QXG9KPFQY. Przyjmuje ona następujące parametry:  Uchwyt okna, którego pozycja ma zostać zmieniona (J).  Nową pozycję lewej krawędzi okna (TGEVNGHV).  Nową pozycję górnej krawędzi okna (TGEVVQR).  Nową szerokość okna (TGEVTKIJVTGEVNGHV).  Nową szerokość okna (TGEVDQVVQOTGEVVQR). Na koniec funkcja zwrotna zwraca 647 , umożliwiając dalsze poszukiwania okien. Po uruchomieniu programu zobaczysz, jak wyświetlone na pulpicie okna zaczynają drżeć. Program zmienia losowo ich pozycje. Sam sprawdź. Efekt jest… wstrząsający. Kod źródłowy tego przykładu oraz jego pliki wykonywalne znajdują się na dołączo- nej do książki płycie CD-ROM w podkatalogu PrzykładyRozdział3Vibration. 3.3. Przełączanie ekranów Pamiętam, kiedy na rynku pojawiła się pierwsza wersja programu Dashboard (dla Win- dows 3.1). Zainteresowałem się przełączaniem ekranów i próbowałem znaleźć funkcję WinAPI, która przyjmowałaby poprzez parametr pożądany ekran. Nie udało się, nie było takiej funkcji. 104 C++. Elementarz hakera Później odkryłem, że ta funkcja została „zapożyczona” z Linuksa, w którym jądro sys- temu implementuje konsole (ekrany) wirtualne. Taka implementacja była jednak skom- plikowana. Zdołałem napisać jednak własne narzędzie do przełączania ekranów w sys- temach Windows 9x. Spróbuję pokazać, jak wykorzystać zastosowane w nim techniki w prostym programie-żarciku. Jak działa przełączanie pomiędzy ekranami? Zdradzę Ci sekret — w rzeczywistości nie odbywa się żadne przełączanie. Wszystkie widoczne okna są po prostu usuwane z pulpitu, tak aby nie było ich widać. Użytkownik otrzymuje pusty pulpit. Kiedy zechce powrócić do pierwotnego ekranu, wszystko jest po prostu układane z powrotem na swoim miejscu. Jak widać, czasem najprostsze pomysły są najlepsze. Przy przełączaniu ekranów trzeba momentalnie usunąć okna poza ekran. Będziemy to jednak robić powoli, tak aby dało się zaobserwować sposób działania programu. Będzie to wyglądać tak, jakby okna „uciekały”. Sam program będzie niewidoczny, a jedynym sposobem jego przerwania będzie jego zakończenie z poziomu okna menedżera zadań. Tu ciekawostka: jeśli nie zamkniemy programu w ciągu kilku sekund, to również okno menedżera zadań ucieknie z ekranu i trzeba będzie zaczynać zamykanie od początku. Nie będziemy jednak do przesuwania okien wykorzystywać dotychczasowych funkcji. Funkcje, które ustawiają pozycję okna, nie sprawdzą się w tym zadaniu, ponieważ prze- suwają i odrysowują one każde okno z osobna, co zajmuje sporo czasu procesora. Jeśli na pulpicie będzie 20 okien, ich przeniesienie funkcją 5GV9KPFQY2QU będzie trwało zdecydowanie za długo. Aby szybko zaimplementować symulację przełączania ekranów, powinniśmy skorzy- stać ze specjalnych funkcji, które przesuwają całą grupę okien jednocześnie. Spójrzmy na przykład wykorzystujący te funkcje. Utwórz w Visual C++ nowy projekt Win32 Project i przejdź do funkcji AV9KP/CKP. Skorzystaj z listingu 3.2, aby uzupełnić ją (przed główną pętlą komunikatów) o kod prze- noszący okna. Listing 3.2. Kod przemieszczający okna *#0 . J TGCVG XGPV 647 (#.5 GV  Nieskończona pętla: YJKNG 647 ] KPVYKPFQY QWPV KPVKPFGZ *90 YKPNKUV=? *90 Y 4 694EV HQT KPVKK)GV5[UVGO/GVTKEU 5/A :5 4 0 K ] Zlicz okna: YKPFQY QWPV Y)GV9KPFQY )GV GUMVQR9KPFQY )9A *+.  Rozdział 3. ♦ Programowanie w systemie Windows 105 YJKNG Y ] KH +U9KPFQY8KUKDNG Y ] YKPNKUV=YKPFQY QWPV?Y YKPFQY QWPV  _ Y)GV9KPFQY Y)9A*90 0 :6 Szukaj okna _ * 92/95VTWEV$GIKP GHGT9KPFQY2QU YKPFQY QWPV  HQT KPVKPFGZKPFGZYKPFQY QWPVKPFGZ ] )GV9KPFQY4GEV YKPNKUV=KPFGZ?94EV  /95VTWEV GHGT9KPFQY2QU /95VTWEVYKPNKUV=KPFGZ?*90 A$1661/ 94EVNGHV94EVVQR 94EVTKIJV94EVNGHV 94EVDQVVQO94EVVQR 592A01# 6+8#6 ^^592A01 14 4  _  PF GHGT9KPFQY2QU /95VTWEV Właściwe przenosiny _ 9CKV(QT5KPING1DLGEV J Trzysekundowe opóźnienie _ Na początku tego kodu tworzymy zdarzenie puste, które później wykorzystamy w im- plementacji opóźnienia. Następnie uruchamiamy pętlę nieskończoną (YJKNG 647 ). Kod wewnątrz pętli składa się z trzech części: pozyskiwania uchwytów widocznych okien, zbiorowego przesunięcia okien do nowej pozycji i opóźnienia. Opóźnienie wprowadzaliśmy już wielokrotnie, więc nie powinieneś mieć kłopotów z jego zrozumieniem. Wyszukiwanie widocznych okien realizowane jest następująco: Zlicz okna: YKPFQY QWPV Y)GV9KPFQY )GV GUMVQR9KPFQY )9A *+.  YJKNG Y ] KH +U9KPFQY8KUKDNG Y ] YKPNKUV=YKPFQY QWPV?Y YKPFQY QWPV  _ Y)GV9KPFQY Y)9A*90 0 :6 Szukaj okna _ W pierwszym wierszu tego kodu pozyskujemy uchwyt pierwszego okna z pulpitu i za- pisujemy go w zmiennej Y. Następnie uruchamiamy pętlę, w której pozyskujemy ko- lejne uchwyty okien aż do momentu pozyskania uchwytu zerowego. 106 C++. Elementarz hakera Wewnątrz pętli sprawdzamy widoczność okna, korzystając z funkcji +U9KPFQY8KUKDNG wywoływanej z parametrem Y. Jeśli okno jest niewidoczne albo zminimalizowane (funkcja +U9KPFQY8KUKDNG zwraca wtedy (#.5 ), nie trzeba go przesuwać. W przeciw- nym przypadku dodajemy bieżący uchwyt do tablicy uchwytów okien do przesunię- cia YKPNKUV i zwiększamy licznik okien YKPFQY QWPV. Funkcja )GV9KPFQY zwraca uchwyty wszystkich widocznych okien, nie rozróżniając okien nadrzędnych i okien potomnych. Uchwyt znalezionego okna jest zachowywany w zmiennej Y. W tym przykładzie uchwyty okien są przechowywane w tablicy o z góry określonym rozmiarze (YKPNKUV=?). Ustaliłem ten rozmiar na 10 000 elementów, co powinno wystarczyć do przechowywania uchwytów okien wszystkich działających aplikacji. W rzeczy samej chyba nikt nie uruchomi naraz więcej niż 100 programów. Najlepiej byłoby zaprząc do przechowywania uchwytów tablice dynamiczne (takie, których rozmiar da się zmieniać w czasie działania programu wedle potrzeb). Zdecydo- wałem jednak o wykorzystaniu tablicy statycznej, żeby nie komplikować programu. Moim celem było pokazanie ciekawego algorytmu i efektu — możesz samodzielnie ulepszyć program. Po wykonaniu tego kodu tablica YKPNKUV będzie wypełniona uchwytami wszystkich uruchomionych i widocznych okien, a zmienna YKPFQY QWPV zawierać będzie liczbę tych uchwytów. Weźmy się teraz za zbiorowe przenoszenie okien. Proces rozpoczyna się wywołaniem funkcji WinAPI $GIKP GHGT9KPFQY2QU. Funkcja ta przydziela pamięć dla nowego okna pulpitu, do którego przeniesione zostaną wszystkie widoczne okna. Liczba okien do przeniesienia zadawana jest parametrem wywołania. Aby przenieść okna do przydzielonej pamięci, należy wywołać funkcję GHGT9KPFQY2QU. Nie przenosi ona tak naprawdę okien, a jedynie zmienia przypisane do nich informa- cje o pozycjach i rozmiarach okien. Funkcja ta przyjmuje następujące parametry:  Wynik działania funkcji $GIKP GHGT9KPFQY2QU.  Uchwyt przenoszonego okna, czyli następny element tablicy YKPNKUV.  Liczbę porządkową informującą o pozycji, którą powinno zająć dane okno względem pozostałych.  Cztery parametry określające współrzędne okna (zmniejszamy tu współrzędną poziomą o 10) i jego rozmiary (szerokość i wysokość). Zostały one wcześniej pozyskane wywołaniem funkcji )GV9KPFQY2QU.  Znaczniki sterujące aktywnością i pozycją okna względem innych okien. Po przeniesieniu wszystkich okien wywołujemy funkcję PF GHGT9KPFQY2QU. W tym momencie wszystkie okna „przeskakują” do nowych pozycji. Odbywa się to błyska- wicznie. Gdybyśmy do przesuwania wykorzystali w pętli instrukcję 5GV9KPFQY2QU, od- rysowywanie i przesuwanie kolejnych okien trwałoby znacznie dłużej. Dobrą praktyką jest inicjalizowanie i zwalnianie wszystkich zmiennych wymagających znacznych ilości pamięci (np. obiektów i tablic). Inicjalizacja oznacza przydział pamięci, Rozdział 3. ♦ Programowanie w systemie Windows 107 a zwolnienie — jej zwrócenie do dyspozycji systemu. Jeśli nie zwolnimy zajmowanych zasobów, komputer być może później odczuje ich niedostatek, co może spowolnić jego działanie albo nawet wymusić przeładowanie systemu. W tym przykładzie utworzyliśmy obiekt, ale go nie zwolniliśmy, a to dlatego, że program jest przeznaczony do działania w pętli nieskończonej, którą można przerwać jedynie na dwa sposoby:  Odłączeniem zasilania komputera — w takim przypadku żadna z aplikacji nie zdoła zwolnić pamięci, bo cały system przestanie nagle działać.  Zakończeniem procesu programu — jeśli nawet użytkownik będzie na tyle sprytny, żeby to zrobić, program zostanie zatrzymany w trybie natychmiastowym, więc i tak nie udałoby mu się zwolnić pamięci, nawet, gdyby był wyposażony w stosowny kod — system bezwzględnie przerwie działanie programu. Okazuje się więc, że zwalnianie obiektu jest tu bezcelowe. Nie znaczy to, że można darować sobie zwalnianie obiektów w pozostałych programach. Jeden dodatkowy wiersz kodu nikomu nie zaszkodzi, a pozwoli na zachowanie stabilności i efektywności systemu. Jeśli uruchomisz program, wszystkie otwarte okna zaczną uciekać na lewo. Spróbuj choćby wywołać menu podręczne pulpitu (prawym przyciskiem myszy) — nawet ono po chwili ucieknie. W ten sposób z ekranu zniknie każdy uruchomiony program. Bardzo polubiłem ten program. Bawiłem się nim przeszło pół godziny. Zaciekawił mnie na tyle, że nie potrafiłem sobie odmówić takiego marnotrawstwa czasu. Szczególnie spodobał mi się przymus szybkiego przerywania programu — to naprawdę nie jest proste. Na początku ustawiłem opóźnienie na 5 sekund, potem na cztery. Ćwiczyłem intensywnie naciskanie kombinacji Ctrl+Alt+Del, wyszukiwanie programu na liście procesów i naciskanie przycisku Zakończ zadanie. Trudność polega na tym, że okno z listą procesów również przesuwa się po ekranie. Jeśli nie zdążysz na czas wykonać wszystkich czynności, będziesz musiał powtarzać próbę. W podobny do pokazanego sposób implementowanych jest większość aplikacji prze- łączających pulpity. W każdym razie ja nie znam innej metody i nie znalazłem żad- nych innych przydatnych w takim zadaniu funkcji systemowych. Kod źródłowy tego przykładu oraz jego pliki wykonywalne znajdują się na dołączonej do książki płycie CD-ROM w podkatalogu PrzykładyRozdział3DesktopSwitch. 3.4. Niestandardowe okna W zamierzchłych czasach, w połowie lat dziewięćdziesiątych, wszystkie okna były prostokątne i nikomu to nie przeszkadzało. W ciągu ostatnich kilku lat modne stały się jednak okna o kształtach nieregularnych. Każdy szanujący się programista czuje się więc w obowiązku stworzyć program z takimi oknami, aby bez wstydu i skutecz- nie konkurować z oknami innych programistów. 108 C++. Elementarz hakera Osobiście jestem przeciwny udziwnieniom interfejsu i okna o nieregularnych kształtach wykorzystuję jedynie sporadycznie. Pisałem o tym wcześniej i będę się powtarzał, ponieważ temat jest istotny dla całego rynku oprogramowania komercyjnego. Progra- mista musi jednak niekiedy utworzyć okno o nieregularnych kształtach. Poza tym projektowanie takich okien jest dobrym ćwiczeniem wyobraźni, a niniejsza książka ma na celu między innymi pobudzenie kreatywności Czytelników. Dlatego zajmiemy się teraz kwestą kształtów okien. Na początek stwórzmy okno owalne. Przyda się do tego nowy projekt Win32 Project w Visual C++. Zmień jego funkcję +PKV+PUVCPEG tak jak na listingu 3.3. Kod, który na- leży dodać do funkcji, jest na listingu oznaczony komentarzami. Listing 3.3. Tworzenie owalnego okna $11.+PKV+PUVCPEG *+056#0 J+PUVCPEGKPVP OF5JQY ] *90 J9PF J+PUVJ+PUVCPEG5VQTGKPUVCPEGJCPFNGKPQWTINQDCNXCTKCDNG J9PF TGCVG9KPFQY U9KPFQY NCUUU6KVNG95A18 4.#22 9+0 19  9A75 (#7.6 9A75 (#7.607..07..J+PUVCPEG07..  KH J9PF ] TGVWTP(#.5  _ Początek kodu do dodania *4)0(QTO4IP 4 694EV )GV9KPFQY4GEV J9PF94EV  (QTO4IP TGCVG NNKRVKE4IP 94EVTKIJV94EVNGHV 94EVDQVVQO94EVVQR  5GV9KPFQY4IP J9PF(QTO4IP647  Koniec dodanego kodu 5JQY9KPFQY J9PFP OF5JQY  7RFCVG9KPFQY J9PF  TGVWTP647  _ W dodanym fragmencie kodu po pierwsze deklarujemy dwie zmienne:   (QTO4IP typu *4)0 służącą do przechowywania tzw. regionów opisujących wygląd okna. 94GEV typu 4 6 służącą do przechowywania rozmiaru i pozycji okna. Określają one obszar, wewnątrz którego zamknięty będzie owal okna. Dalej wywoływana jest znana już nam dobrze funkcja )GV9KPFQY4GEV wypełniająca zmienną 94EV wymiarami i pozycją okna programu. Jesteśmy już gotowi do skonstruowa- nia owalnego okna. Będą nam do tego potrzebne dwie funkcje: TGCVG NNKRVKE4IP i 5GV9KPFQY4IP. Przyjrzyjmy się im bliżej: Rozdział 3. ♦ Programowanie w systemie Windows 109 *4)0 TGCVG NNKRVKE4IP KPVP.GHV4GEVwspółrzędna x górnego lewego narożnika obszaru elipsy KPVP6QR4GEVwspółrzędna y górnego lewego narożnika obszaru elipsy KPVP4KIJV4GEVwspółrzędna x dolnego prawego narożnika obszaru elipsy KPVP$QVVQO4GEVwspółrzędna y dolnego prawego narożnika obszaru elipsy  Funkcja ta tworzy owalny (eliptyczny) region okna. Robi to na podstawie zadanych w wywołaniu wymiarów prostokąta ograniczającego owal. KPV5GV9KPFQY4IP *90 J9PFuchwyt okna *4)0J4IPuchwyt regionu $11.D4GFTCYznacznik odrysowania okna po zmianie regionu  Ta funkcja przypisuje do okna określonego pierwszym parametrem wskazany drugim parametrem region. Jeśli trzeci parametr ma wartość 647 , okno zostanie po zmianie regionu odrysowane. W przeciwnym razie trzeba będzie odrysowanie wymusić sa- modzielnie. W powyższym kodzie po ustawieniu regionu wywoływana jest funkcja 7RFCVG9KPFQY. Okno zostanie i tak odrysowane — trzeci parametr wywołania 5GV 9KPFQY4IP mógłby więc mieć równie dobrze wartość (#.5 . Uruchom program, a zobaczysz na ekranie okno owalne, jak na rysunku 3.3. Rysunek 3.3. Owalne okno programu 110 C++. Elementarz hakera Pójdźmy nieco dalej i utwórzmy owalne okno z prostokątną „dziurą” we wnętrzu elipsy. Zmień kod następująco: *4)0(QTO4IP4GEV4IP 4 694EV )GV9KPFQY4GEV J9PF94EV  (QTO4IP TGCVG NNKRVKE4IP 94EVTKIJV94EVNGHV 94EVDQVVQO94EVVQR  4GEV4IP TGCVG4GEV4IP 94EVTKIJV94EVNGHV 94EVDQVVQO94EVVQR  QODKPG4IP (QTO4IP(QTO4IP4GEV4IP4)0A +((  5GV9KPFQY4IP J9PF(QTO4IP647  Mamy tu deklaracje dwóch zmiennych typu *4)0. Pierwsza z nich, (QTO4IP, będzie prze- chowywać region owalny, utworzony funkcją TGCVG NNKRVKE4IP. Druga ma prze- chowywać region prostokątny utworzony funkcją TGCVG4GEV4IP. Tak jak przy tworze- niu regionu owalnego funkcja ta wymaga określenia współrzędnych i rozmiarów prostokąta. Wynik działania funkcji zapisywany jest w zmiennej 4GEV4IP. Po utworzeniu obu regionów składamy je funkcją QODKPG4IP: KPV QODKPG4IP *4)0JTIP GUVuchwyt regionu wynikowego *4)0JTIP5TEuchwyt pierwszego regionu źródłowego *4)0JTIP5TEuchwyt drugiego regionu źródłowego KPVHP QODKPG/QFGtryb składania  Funkcja ta składa dwa regiony źródłowe (przekazane parametrami JTIP5TE i JTIP5TE) i zapisuje wynik złożenia w regionie JTIP GUV. Tryb składania można określić, nadając czwartemu parametrowi wywołania funkcji (HP QODKPG/QFG) jedną z następujących wartości:      40 A#0 — region wynikowy będzie iloczynem regionów źródłowych. 40 A 12; — region wynikowy będzie kopią regionu pierwszego. 40 A +(( — region wynikowy będzie zawierał te obszary, które są w regionie pierwszym, z wyjątkiem tych, które określa region drugi. 4)0A14 — region wynikowy będzie sumą regionów źródłowych. 4)0A:14 — region wynikowy będzie sumą wyłączającą regionów źródłowych. Wynik działania programu widać na rysunku 3.4. Celowo w tle okna programu umie- ściłem jednolity barwnie podkład, żeby można było na jego tle zobaczyć właściwy kształt okna. Kod źródłowy tego przykładu oraz jego pliki wykonywalne znajdują się na dołączonej do książki płycie CD-ROM w podkatalogu PrzykładyRozdział3NoneUniformWindow. Rozdział 3. ♦ Programowanie w systemie Windows 111 Rysunek 3.4. Owalne okno z prostokątną „dziurą” Możesz zmieniać nie tylko kształty okien, ale również kształty niektórych ich elemen- tów sterujących. Zobaczmy to na przykładzie. Utwórz projekt typu MFC Application. Nie potrzebujemy tym razem zwartości programu, możemy więc uprościć sobie programowanie, korzystając z biblioteki MFC. W kreatorze aplikacji przejdź na zakładkę Application Type i zaznacz pozycję Dialog based (patrz rysunek 3.5). Pozostałe parametry zostaw bez zmian. Ja swój projekt na- zwałem None. Rysunek 3.5. Wybór typu aplikacji w oknie kreatora aplikacji MFC Otwórz przeglądarkę zasobów i kliknij dwukrotnie pozycję IDD_NONE_DIALOG w ga- łęzi Dialog. Umieść na formularzu programu jeden komponent ListControl (jak na ry- sunku 3.6). Aby móc obsługiwać nowy element sterujący, kliknij go prawym przyciskiem myszy i wybierz z menu podręcznego polecenie Add Variable…. W oknie, które się pojawi, wpisz w polu Variable Name nazwę zmiennej. Nazwijmy ją +VGOU.KUV (patrz rysunek 3.7). Możesz już kliknąć przycisk Finish kończący definiowanie zmiennej. 112 C++. Elementarz hakera Rysunek 3.6. Formularz okna tworzonego programu Rysunek 3.7. Okno definiowania zmiennych uchwytów elementów sterujących Otwórz teraz plik kodu źródłowego NoneDlg.cpp i znajdź w nim funkcję 0QPG NI 1P+PKV KCNQI. Dodaj do niej poniższy kod, umieszczając go na końcu funkcji za ko- mentarzem // TODO: Add extra initializacion here: 61 1#FFGZVTCKPKVKCNKCVKQPJGTG 4 694EV *4)0(QTO4IP Rozdział 3. ♦ Programowanie w systemie Windows 113 )GV9KPFQY4GEV +VGOU.KUV94EV  (QTO4IP TGCVG NNKRVKECN4IP 94EVTKIJV94EVNGHV94EVDQVVQO 94EVVQR  5GV9KPFQY4IP +VGOU.KUV(QTO4IP647  Powyższy kod powinien być Ci znajomy; zmienna +VGOU.KUV występuje tu w roli uchwytu okna. Funkcje )GV9KPFQY4GEV i 5GV9KPFQY4GEV są poprzedzane znakami  wskazujący- mi, że funkcje te są wywoływane z biblioteki WinAPI, a nie z MFC. Efekt działania programu widać na rysunku 3.8. Rysunek 3.8. Efekt działania programu None Kod źródłowy tego przykładu oraz jego pliki wykonywalne znajdują się na dołączo- nej do książki płycie CD-ROM w podkatalogu PrzykładyRozdział3None. 3.5. Finezyjne kształty okien Wiemy już, jak tworzyć okna o prostych kształtach geometrycznych (owali i prostoką- tów) i ich kombinacji. Pora na tworzenie okien o dosłownie dowolnych kształtach. Jest to — to zrozumiałe — zadanie znacznie bardziej skomplikowane niż kombinacja dwóch prostych figur geometrycznych. Na rysunku 3.9 możesz zobaczyć obrazek z czerwonym tłem. Spróbujemy utworzyć okno, które będzie zawierać ten obrazek i mieć przezroczyste tło (a nie czerwone, jak na obrazku), tak by kształt okna miał formę obrazka. Efekt taki byłoby niezwykle trudno uzyskać, gdybyśmy chcieli kombinować regiony w sposób przypadkowy. WinAPI pozwala co prawda na konstruowanie wielokątnych regionów, ale ich zasto- sowanie bynajmniej nie ułatwia zadania. Cóż, spróbujmy utworzyć region o kształcie obrazka. Zaprezentuję tu sposób na tyle uniwersalny, że można go stosować z dowolnymi obrazkami. Jest on przy tym prosty. 114 Rysunek 3.9. Maska kształtu okna C++. Elementarz hakera Najpierw zastanówmy się, co to jest obrazek. To po prostu dwuwymiarowa tablica pikseli. Możemy każdy z wierszy tej tablicy potraktować jako osobny region. Innymi słowy, dla każdego wiersza pikseli obrazka utworzymy jeden region, a potem połączymy wszystkie regiony w jeden, wyznaczający kształt okna. Algorytm ten można rozpisać następująco: 1. Przejrzyj bieżący wiersz obrazka i odszukaj w nim pierwszy piksel niebędący pikselem tła. Zapamiętaj współrzędną początku prostokątnego regionu w zmiennej :. 2. Przejrzyj resztę wiersza obrazka w poszukiwaniu przeciwległej granicy tła. Pozycję ostatniego nieprzezroczystego piksela zapamiętaj jako :. Jeśli do końca wiersza nie znajdziesz pikseli tła, rozciągnij region do końca wiersza. 3. Ustaw współrzędną ; na numer wiersza, a ; na ;  (wysokość regionu prostokątnego obejmującego pojedynczy wiersz obrazka to jeden piksel). 4. Skonstruuj region na bazie otrzymanych współrzędnych. 5. Przejdź do następnego wiersza i powtórz kroki od 1. do 4. 6. Połącz otrzymane regiony i skojarz je z oknem. To algorytm uproszczony, ponieważ niekiedy jeden wiersz wymagać będzie więcej niż jednego regionu, jeśli właściwy obrazek będzie w danym wierszu przerywany tłem. Powyższy algorytm, zaimplementowany w języku C++, prezentowany jest na listingu 3.4. Przeanalizujemy go nieco później. Na razie chciałbym skupić się na obrazku. Może być nim dowolna bitmapa systemu Windows. Rozmiar pliku obrazka zależy od rozmiaru obrazka. W naszym przykładzie obrazek ma 200 na 200 pikseli i takie rozmiary zostały ustawione w kodzie. Możesz jednak spróbować uniezależnić kod od rozmiaru obrazka. Zakładam, że piksel znajdujący się na pozycji (0, 0) jest pikselem tła. Przygotowując obrazek, upewnij się, że wszystkie piksele tła mają ten sam kolor co piksel z narożnika. Takie założenie zwiększa elastyczność algorytmu, ponieważ nie blokuje żadnego okre- ślonego koloru jako koloru tła. Przy tym w narożniku obrazka rzadko znajduje się Rozdział 3. ♦ Programowanie w systemie Windows 115 istotny element obrazka i zawsze można wstawić tam jeden piksel tła. Nie zniszczy to zapewne estetyki obrazka. Utwórz nowy projekt typu Win32 Project i znajdź w kodzie źródłowym funkcję +PKV+P UVCPEG. Zmień funkcję tworzącą okno: J9PF TGCVG9KPFQY U9KPFQY NCUUU6KVNG95A18 4.#22 9+0 19  9A75 (#7.607..07.. J+PUVCPEG07..  Dwie kolejne liczby 200 odnoszą się do wymiarów okna dopasowanych do rozmiarów obrazka. Jeśli masz zamiar wykorzystać inny obrazek, powinieneś odpowiednio zmienić wartości parametrów. Z okna usuniemy też menu, bo nie będzie nam potrzebne. W tym celu znajdź funkcję /[4GIKUVGT NCUU i wiersz, w którym ustawiane jest pole YEGZNRU/GPW0COG. Przypisz do niej zero: YEGZNRU/GPW0COG W sekcji zmiennych globalnych dodaj dwie nowe zmienne: *$+6/#2OCUM$KVOCR *90 J9PF Pierwsza z nich będzie przechowywać uchwyt obrazka, a druga to znana nam już dobrze zmienna uchwytu okna programu. Jej zadeklarowanie jako globalnej wymusza usunięcie lokalnej zmiennej J9PF z funkcji +PKV+PUVCPEG. Zmień funkcję AV9KP/CKP zgodnie z listingiem 3.4. Program jest gotowy. Zanim uruchomisz program, skompiluj go i otwórz katalog, w którym znajduje się kod źródłowy. Jeśli w czasie pracy włączony był tryb kompilacji Debug, zobaczysz podka- talog Debug. W innym przypadku znajdziesz tam podkatalog Release. Aby uniknąć błędu uruchomienia, powinieneś skopiować do tego katalogu plik obrazka. Listing 3.4. Tworzenie okna o dowolnych rozmiarach na bazie obrazka-maski KPV#2+ 064;AV9KP/CKP *+056#0 J+PUVCPEG *+056#0 J2TGX+PUVCPEG .26564NR OF.KPG KPVP OF5JQY ] 61 12NCEGEQFGJGTG /5)OUI *# .J#EEGN6CDNG +PKVKCNKGINQDCNUVTKPIU .QCF5VTKPI J+PUVCPEG+ 5A#22A6+6. U6KVNG/#:A.1# 564+0)  .QCF5VTKPI J+PUVCPEG+ A/#5-9+0 19U9KPFQY NCUU/#:A.1# 564+0)  /[4GIKUVGT NCUU J+PUVCPEG  2GTHQTOCRRNKECVKQPKPKVKCNKCVKQP KH +PKV+PUVCPEG J+PUVCPEGP OF5JQY ] 116 C++. Elementarz hakera TGVWTP(#.5  _ J#EEGN6CDNG.QCF#EEGNGTCVQTU J+PUVCPEG .2 6564 + A/#5-9+0 19  Dodaj poniższy kod Na początek pozbaw okno belki tytułowej i menu systemowego KPV5V[NG 5V[NG)GV9KPFQY.QPI J9PF)9.A56;.  5V[NG5V[NG^^95A #26+10 5V[NG5V[NG^^95A5;5/ 07 5GV9KPFQY.QPI J9PF)9.A56;. 5V[NG  5JQY9KPFQY J9PFP OF5JQY  7RFCVG9KPFQY J9PF  Wczytaj rysunek OCUM$KVOCR *$+6/#2 .QCF+OCIG 07..OCUMDOR +/#) A$+6/#2.4A.1# (41/(+.  KH OCUM$KVOCR TGVWTP07.. Deklaracje niezbędnych zmiennych $+6/#2DK $;6 DRR  914 6TCPU2KZGN  914 RKZGN KPVUVCTVZ +06KL *4)04IP4GU4IP TGCVG4GEV4IP   )GV1DLGEV OCUM$KVOCRUKGQH $+6/#2 DK  DRRDKDO$KVU2KZGN  $;6  R$KVUPGY$;6 =DKDO9KFVJ DKDO*GKIJV DRR? Skopiuj pamięć rysunku KPVR)GV$KVOCR$KVU OCUM$KVOCRDKDO9KFVJ DKDO*GKIJV DRRR$KVU  Znajdź kolor przezroczystości 6TCPU2KZGN 914 R$KVU 6TCPU2KZGNDKDO$KVU2KZGN Pętla przeglądająca linie rysunku HQT KKDKDO*GKIJVK ] UVCTVZ HQT LLDKDO9KFVJL ] RKZGN 914 R$KVU  K DKDO9KFVJ L  DRR  DKDO$KVU2KZGN  KH RKZGN6TCPU2KZGN ] KH UVCTVZ ] UVCTVZL _GNUGKH L DKDO9KFVJ Rozdział 3. ♦ Programowanie w systemie Windows 117 ] 4IP TGCVG4GEV4IP UVCTVZKLK    QODKPG4IP 4GU4IP4GU4IP4IP4)0A14  UVCTVZ _ _GNUGKH UVCTVZ  ] 4IP TGCVG4GEV4IP UVCTVZKLK    QODKPG4IP 4GU4IP4GU4IP4IP4)0A14  UVCTVZ _ _ _ FGNGVGR$KVU 5GV9KPFQY4IP J9PF4GU4IP647  +PXCNKFCVG4GEV J9PFHCNUG  Koniec dodanego kodu /CKPOGUUCIGNQQR YJKNG )GV/GUUCIG OUI07..HCNUG ] KH 6TCPUNCVG#EEGNGTCVQT OUIJYPFJ#EEGN6CDNGOUI ] 6TCPUNCVG/GUUCIG OUI   KURCVEJ/GUUCIG OUI  _ _ TGVWTP KPV OUIY2CTCO _ W pierwszej kolejności usuwamy z okna belkę tytułową i menu systemowe. Następnie wczytujemy do pamięci programu bitmapę, korzystając z funkcji .QCF+OCIG. Obrazek jest wczytywany z pliku, więc pierwszy parametr ma wartość 07.., drugi to nazwa pliku obrazka, a ostatni — znacznik .4A.1# (41/(+. . Ponieważ określamy samą tylko nazwę pliku obrazka (bez ścieżki dostępu) program będzie szukał pliku w tym samym katalogu, z którego został uruchomiony. Dlatego właśnie przed urucho- mieniem skompilowanego programu trzeba ręcznie skopiować plik obrazka do pod- katalogu z plikiem wykonywalnym programu (Debug albo Release). Program powinien sprawdzać, czy plik znajduje się w bieżącym katalogu. Jeśli OCUM$KVOCR ma wartość zero, należy uznać, że wczytanie obrazka się nie powiodło (najprawdopo- dobniej z powodu jego braku) i program powinniśmy zakończyć. KH OCUM$KVOCR TGVWTP07.. Test ten jest niezbędny, ponieważ próba odwołania się do pamięci nienależącej faktycz- nie do obrazka spowodowałaby natychmiastowe załamanie programu. Dalej zaczyna się dość skomplikowany kod. Aby go zrozumieć, musisz wiedzieć, jak korzystać ze wskaźników. Nie będę jednak tego wyjaśniał — to temat na inną książkę. 118 C++. Elementarz hakera Jeśli uruchomisz przykład, zobaczysz okno takie jak na rysunku 3.10. Okno przyjmie kształt obrazka, ale będzie puste. Utworzyliśmy bowiem tylko kształt okna. Aby wypeł- nić okno obrazkiem, będziemy musieli uzupełnić program o następujący kod obsługi komunikatu 9/A2#+06: ECUG9/A2#+06 JFE$GIKP2CKPV J9PFRU  61 1#P[FTCYKPIEQFGJGTG JFE$KVU TGCVG QORCVKDNG JFE  5GNGEV1DLGEV JFE$KVUOCUM$KVOCR  $KV$NV JFEJFE$KVU54 12;   GNGVG JFE$KVU   PF2CKPV J9PFRU  DTGCM Rysunek 3.10. Pusty kształt okna Odrysowujemy zawartość okna tak samo jak swego czasu odrysowywaliśmy w oknie ob- raz przycisku Start. Efekt możesz podziwiać na swoim ekranie i rysunku 3.11. Rysunek 3.11. Kompletne okno o dowolnym kształcie Kod źródłowy tego przykładu oraz jego pliki wykonywalne znajdują się na dołączonej do książki płycie CD-ROM w podkatalogu PrzykładyRozdział3MaskWindow. Rozdział 3. ♦ Programowanie w systemie Windows 119 3.6. Sposoby chwytania nietypowego okna Korzystając z kodu z podrozdziału 3.5, możemy uzyskać okno o dowolnym niemal kształcie. Ma ono jednak pewną dotkliwą wadę — okna nie można przesuwać po ekra- nie, gdyż nie ma go po prostu za co chwycić myszą! Okno nie posiada belki tytułowej ani menu systemowego, za pomocą których można przesuwać zwykłe okna. Posiada za to prostokątny obszar roboczy, co dodatkowo utrudnia zadanie. Aby pozbyć się tej niedogodności, powinniśmy „nauczyć” program, jak przesuwać okno po kliknięciu myszą w dowolnym punkcie kształtu okna. Mamy do wyboru dwa sposoby:  Kiedy użytkownik kliknie w obszarze roboczym okna, możemy oszukać system operacyjny, „udając”, że użytkownik kliknął w obszarze (nieistniejącej) belki tytułowej. To najprostsze rozwiązanie i wymaga zaledwie jednego wiersza kodu. Jest jednak w praktyce mało wygodne, dlatego zainteresujemy się sposobem drugim.  Możemy samodzielnie przesuwać okno. Wymaga to większej ilości kodu, ale daje rozwiązanie uniwersalne i elastyczne. Aby zaimplementować drugie z proponowanych rozwiązań, powinniśmy oprogramować obsługę następujących zdarzeń:  Zdarzenia naciśnięcia przycisku myszy — należy wtedy zapisać bieżącą pozycję wskaźnika myszy i sygnał zdarzenia w odpowiedniej zmiennej. W naszym przykładzie zastosujemy zmienną FTCIIKPI typu DQQN. Dodatkowo powinniśmy przechwycić mysz tak, aby po kliknięciu okna wszystkie komunikaty o ruchu myszy były kierowane do naszego okna. Służy do tego funkcja 5GV CRVWTG wymagająca przekazania uchwytu okna-odbiorcy komunikatów.  Zdarzenia przesunięcia wskaźnika myszy — jeśli zmienna FTCIIKPI ma wartość 647 , oznacza to, że użytkownik ostatnio kliknął w obszarze okna i obecne przesunięcia powinny poruszać oknem. W tym przypadku powinniśmy aktualizować pozycję okna zgodnie z nowymi współrzędnymi wskaźnika myszy. Jeśli FTCIIKPI ma wartość (#.5 , nie trzeba przesuwać okna.  Zdarzenia zwolnienia przycisku myszy — należy przypisać zmiennej FTCIIKPI wartość (#.5 , aby zablokować dalsze przesuwanie okna wraz z przesunięciami wskaźnika myszy. Możemy wykorzystać kod poprzedniego przykładu, wystarczy znaleźć w nim funkcję 9PF2TQE i dodać do niej oznaczony odpowiednimi komentarzami kod z listingu 3.5. Wcześniej w sekcji zmiennych globalnych należałoby zadeklarować dwie zmienne: DQQNFTCIIKPI(#.5  21+06/QWUG2PV 120 C++. Elementarz hakera Listing 3.5. Kod przeciągający okno za wskaźnikiem myszy .4 57.6 #..$# -9PF2TQE *90 J9PF7+06OGUUCIG92#4#/Y2CTCO.2#4#/N2CTCO ] KPVYO+FYO XGPV 2#+065647 6RU * JFE * JFE$KVU 4 6YPFTGEV 21+06RQKPV UYKVEJ OGUUCIG ] ECUG9/A 1//#0  YO+F.1914 Y2CTCO  YO XGPV*+914 Y2CTCO  2CTUGVJGOGPWUGNGEVKQPU UYKVEJ YO+F ] ECUG+ /A#$176  KCNQI$QZ J+PUV .2 6564 + A#$176$1:J9PF .)241 #DQWV  DTGCM ECUG+ /A :+6  GUVTQ[9KPFQY J9PF  DTGCM FGHCWNV TGVWTP GH9KPFQY2TQE J9PFOGUUCIGY2CTCON2CTCO  _ DTGCM ECUG9/A2#+06 JFE$GIKP2CKPV J9PFRU  61 1#P[FTCYKPIEQFGJGTG JFE$KVU TGCVG QORCVKDNG JFE  5GNGEV1DLGEV JFE$KVUOCUM$KVOCR  $KV$NV JFEJFE$KVU54 12;   GNGVG JFE$KVU   PF2CKPV J9PFRU  DTGCM ECUG9/A 5641; 2QUV3WKV/GUUCIG   DTGCM Kod obsługi interesujących nas zdarzeń Naciśnięcie lewego przycisku myszy: ECUG9/A.$76610 190 )GV WTUQT2QU /QWUG2PV  FTCIIKPIVTWG 5GV CRVWTG J9PF  DTGCM Przesuwanie wskaźnika myszy: ECUG9/A/175 /18  KH FTCIIKPI jeśli wcześniej naciśnięto przycisk myszy ] Pobierz bieżącą pozycję wskaźnika: )GV WTUQT2QU RQKPV  Pobierz bieżący obszar okna: Rozdział 3. ♦ Programowanie w systemie Windows 121 )GV9KPFQY4GEV J9PFYPFTGEV  Dostosuj pozycję okna YPFTGEVNGHVYPFTGEVNGHV  RQKPVZ/QWUG2PVZ  YPFTGEVVQRYPFTGEVVQR  RQKPV[/QWUG2PV[  Ustaw nowy obszar okna: 5GV9KPFQY2QU J9PF07..YPFTGEVNGHVYPFTGEVVQR 592A01 14 4^592A015+  Zapisz bieżącą pozycję wskaźnika myszy w zmiennej: /QWUG2PVRQKPV _ DTGCM Zwolnienie lewego przycisku myszy: ECUG9/A.$7661072 KH FTCIIKPI ] FTCIIKPIHCNUG 4GNGCUG CRVWTG  _ FGHCWNV TGVWTP GH9KPFQY2TQE J9PFOGUUCIGY2CTCON2CTCO  _ TGVWTP _ Wszystkie funkcje wykorzystane w tym przykładzie są już Czytelnikowi znane. Program jest jednak dość rozległy, więc opatrzyłem go większą niż zwykle liczbą komentarzy, które powinny pomóc w analizie jego działania. Kod źródłowy tego przykładu oraz jego pliki wykonywalne znajdują się na dołączonej do książki płycie CD-ROM w podkatalogu PrzykładyRozdział3MaskWindow2. 3.7. Ujawnianie haseł W większości aplikacji wprowadzane do nich hasła są wyświetlane w postaci szeregu gwiazdek. Ma to zapobiec podejrzeniu hasła przez osoby niepowołane. Ale co, jeśli za- pomnimy hasła? Jak je odczytać, jeśli w polu hasła widać tylko gwiazdki? Istnieje kilka narzędzi, które na to pozwalają. Jestem jednak daleki od odsyłania do nich Czytelnika. Zamiast iść na łatwiznę, sami napiszemy potrzebny program. Program będzie się składać z dwóch plików. Pierwszy z nich — plik wykonywalny — będzie wczytywał do pamięci programu inny plik (plik biblioteki DLL). Kod z tej bi- blioteki zostanie zarejestrowany w systemie w roli kodu obsługi komunikatów naci- śnięcia prawego przycisku myszy w konkretnym oknie. W tym momencie tekst z tegoż okna zostanie zamieniony z postaci ciągu gwiazdek na postać zwykłego ciągu znaków. Brzmi to bardzo uczenie, ale da się oprogramować w parę minut. 122 C++. Elementarz hakera 3.7.1. Biblioteka deszyfrowania haseł Dla potrzeb tego przykładu oprogramowałem specjalną bibliotekę DLL. Teraz zrobimy to samo wspólnie. Utw
Pobierz darmowy fragment (pdf)

Gdzie kupić całą publikację:

C++. Elementarz hakera
Autor:

Opinie na temat publikacji:


Inne popularne pozycje z tej kategorii:


Czytaj również:


Prowadzisz stronę lub blog? Wstaw link do fragmentu tej książki i współpracuj z Cyfroteką: