Darmowy fragment publikacji:
Visual C++. Gotowe
rozwi¹zania dla
programistów Windows
Autorzy: Jacek Matulewski, Maciej Pakulski, Dawid
Borycki, Bartosz Bia³y, Piotr Pep³owski, Micha³
Matuszak, Daniel Szlag, Dawid Urbañski
ISBN: 978-83-246-1928-3
Format: 158×235, stron: 536
Zostañ znawc¹ œrodowiska programistycznego Visual C++
(cid:129) Podstawowe funkcje i technologie systemu Windows w oczach programistów
(cid:129) Praktyczne u¿ycie funkcji WinAPI i biblioteki MFC
(cid:129) Programowanie wspó³bie¿ne dla procesorów wielordzeniowych
Œrodowisko programistyczne Microsoft Visual C++ idealnie nadaje siê do wykorzystania
w przypadku pisania programów dla platformy Win32 i jest chêtnie wykorzystywane
przez profesjonalnych programistów, tworz¹cych aplikacje dla systemu Windows.
Zarówno biblioteka MFC, jak i wbudowane funkcje WinAPI oraz mo¿liwoœci programowania
wspó³bie¿nego œwietnie sprawdzaj¹ siê w codziennej pracy programistycznej, oszczêdzaj¹c
czas, pozwalaj¹c na wykorzystanie mnóstwa kontrolek i funkcji, a tak¿e elastycznie
dopasowuj¹c siê do potrzeb tworzonej aplikacji.
Autorzy ksi¹¿ki „Visual C++. Gotowe rozwi¹zania dla programistów Windows” skupiaj¹
siê w niej nie tyle na opisie samego œrodowiska programistycznego, ile na mo¿liwoœciach,
jakie oferuje ono swoim u¿ytkownikom. Po krótkim wprowadzeniu do projektowania
interfejsu aplikacji przechodz¹ do kontroli stanu systemu, obs³ugi tworzonego programu,
omówienia systemów plików, multimediów i rejestru, komunikatów Windows, bibliotek
DLL oraz automatyzacji i wielu innych zagadnieñ. W publikacji tej znajdziesz gotowe
odpowiedzi na wiele pytañ dotycz¹cych konkretnych kwestii programistycznych,
rzeczowe porady oraz sposoby wykorzystania funkcji i technologii dostêpnych podczas
programowania w œrodowisku Visual C++.
(cid:129) Projektowanie interfejsu aplikacji przy u¿yciu biblioteki MFC
(cid:129) Kontrola stanu systemu
(cid:129) Uruchamianie i kontrolowanie aplikacji oraz ich okien
(cid:129) Systemy plików, multimedia i inne funkcje WinAPI
(cid:129) Rejestr systemu Windows
(cid:129) Komunikaty Windows
(cid:129) Biblioteki DLL
(cid:129) Automatyzacja i inne technologie oparte na COM
(cid:129) Sieci komputerowe
(cid:129) Programowanie wspó³bie¿ne z OpenMP
(cid:129) Biblioteka Threading Building Blocks
Dla tych, którzy w œrodowisku Visual C++ chc¹ siê poczuæ jak ryby w wodzie!
Spis treści
Wstęp .............................................................................................. 9
Rozdział 1. Bardzo krótkie wprowadzenie do projektowania interfejsu aplikacji
przy użyciu biblioteki MFC .............................................................. 13
Tworzenie projektu ......................................................................................................... 13
Dodawanie kontrolki ...................................................................................................... 15
Wiązanie metody z komunikatem domyślnym kontrolki ............................................... 16
IntelliSense ..................................................................................................................... 17
Wiązanie komunikatów .................................................................................................. 18
Metoda MessageBox — trochę filozofii MFC ............................................................... 19
Okno Properties: własności i zdarzenia .......................................................................... 21
Wiązanie zmiennej z kontrolką ....................................................................................... 22
Usuwanie zbędnych kontrolek ........................................................................................ 24
Analiza kodu aplikacji .................................................................................................... 24
Blokowanie zamykania okna dialogowego po naciśnięciu klawisza Enter ..................... 25
Więcej kontrolek ............................................................................................................ 26
Kolory ............................................................................................................................. 29
Użycie kontrolki ActiveX ............................................................................................... 31
Rozdział 2. Kontrola stanu systemu .................................................................. 33
Zamykanie i wstrzymywanie systemu Windows ............................................................ 33
Funkcja ExitWindowsEx
(zamykanie lub ponowne uruchamianie systemu Windows) ................................. 33
Funkcja InitiateSystemShutdown (zamykanie wybranego komputera w sieci) ........ 41
Hibernacja i wstrzymywanie systemu („usypianie”)
za pomocą funkcji SetSystemPowerState .............................................................. 46
Blokowanie dostępu do komputera .......................................................................... 49
Odczytywanie informacji o baterii notebooka .......................................................... 50
Kontrola trybu wyświetlania karty graficznej ................................................................. 52
Pobieranie dostępnych trybów pracy karty graficznej .............................................. 52
Identyfikowanie bieżącego trybu działania karty graficznej .................................... 56
Zmiana trybu wyświetlania ...................................................................................... 57
Rozdział 3. Uruchamianie i kontrolowanie aplikacji oraz ich okien ..................... 59
Uruchamianie, zamykanie i zmiana priorytetu aplikacji ................................................. 59
Uruchamianie aplikacji za pomocą funkcji WinExec ............................................... 60
Uruchamianie aplikacji za pomocą ShellExecute ..................................................... 62
Przygotowanie e-maila za pomocą ShellExecute ..................................................... 63
Zmiana priorytetu bieżącej aplikacji ........................................................................ 63
4
Visual C++. Gotowe rozwiązania dla programistów Windows
Sprawdzenie priorytetu bieżącej aplikacji ................................................................ 65
Zmiana priorytetu innej aplikacji ............................................................................. 66
Zamykanie innej aplikacji ........................................................................................ 67
Uruchamianie aplikacji za pomocą funkcji CreateProcess ....................................... 68
Wykrywanie zakończenia działania uruchomionej aplikacji .................................... 73
Kontrolowanie ilości instancji aplikacji ................................................................... 74
Uruchamianie aplikacji w Windows Vista ...................................................................... 75
Uruchamianie procesu jako administrator ................................................................ 76
Program z tarczą ....................................................................................................... 78
Kontrolowanie własności okien ...................................................................................... 79
Lista okien ................................................................................................................ 79
Okno tylko na wierzchu ........................................................................................... 83
Ukrywanie okna aplikacji ......................................................................................... 83
Mrugnij do mnie! ..................................................................................................... 84
Sygnał dźwiękowy ................................................................................................... 84
Numery identyfikacyjne procesu i uchwyt okna ............................................................. 85
Jak zdobyć identyfikator procesu, znając uchwyt okna? .......................................... 85
Jak zdobyć uchwyt głównego okna, znając identyfikator procesu? .......................... 86
Kontrolowanie okna innej aplikacji .......................................................................... 90
Kontrolowanie grupy okien ...................................................................................... 94
Okna o dowolnym kształcie ............................................................................................ 98
Okno w kształcie elipsy ............................................................................................ 99
Łączenie obszarów. Dodanie ikon z paska tytułu ..................................................... 99
Okno z wizjerem .................................................................................................... 101
Aby przenosić okno, chwytając za dowolny punkt ................................................ 102
Rozdział 4. Systemy plików, multimedia i inne funkcje WinAPI ........................ 105
Pliki i system plików (funkcje powłoki) ....................................................................... 105
Odczytywanie ścieżek do katalogów specjalnych .................................................. 106
Tworzenie skrótu (.lnk) .......................................................................................... 107
Odczyt i edycja skrótu .lnk ..................................................................................... 110
Umieszczenie skrótu na pulpicie ............................................................................ 112
Operacje na plikach i katalogach (funkcje WinAPI) .............................................. 113
Operacje na plikach i katalogach (funkcje powłoki) .............................................. 114
Operacje na plikach i katalogach w Windows Vista (interfejs IFileOperation) ...... 116
Jak usunąć plik, umieszczając go w koszu? ........................................................... 118
Operacje na całym katalogu ................................................................................... 119
Odczytywanie wersji pliku .exe i .dll ..................................................................... 120
Jak dodać nazwę dokumentu do listy ostatnio
otwartych dokumentów w menu Start? ............................................................. 124
Odczytywanie informacji o dysku ................................................................................ 125
Odczytywanie danych ............................................................................................ 125
Testy ....................................................................................................................... 129
Kontrolka MFC ...................................................................................................... 131
Ikona w obszarze powiadamiania (zasobniku) ............................................................. 137
Funkcja Shell_NotifyIcon ...................................................................................... 137
Menu kontekstowe ikony ....................................................................................... 138
„Dymek” ................................................................................................................ 140
Multimedia (CD-Audio, MCI) ...................................................................................... 141
Aby wysunąć lub wsunąć tackę w napędzie CD lub DVD ..................................... 141
Wykrywanie wysunięcia płyty z napędu lub umieszczenia jej
w napędzie CD lub DVD ..................................................................................... 143
Sprawdzanie stanu wybranego napędu CD-Audio ................................................. 143
Jak zbadać, czy w napędzie jest płyta CD-Audio ................................................... 144
Kontrola napędu CD-Audio ................................................................................... 145
Spis treści
5
Multimedia (pliki dźwiękowe WAVE) ......................................................................... 147
Asynchroniczne odtwarzanie pliku dźwiękowego .................................................. 147
Jak wykryć obecność karty dźwiękowej ................................................................. 147
Kontrola poziomu głośności odtwarzania plików dźwiękowych ............................ 148
Kontrola poziomu głośności CD-Audio ................................................................. 150
Inne ............................................................................................................................... 150
Pisanie i malowanie na pulpicie ............................................................................. 150
Czy Windows mówi po polsku? ............................................................................. 153
Jak zablokować uruchamiany automatycznie wygaszacz ekranu? ......................... 153
Zmiana tła pulpitu .................................................................................................. 154
Rozdział 5. Rejestr systemu Windows ............................................................ 155
Rejestr ........................................................................................................................... 155
Klasa obsługująca operacje na rejestrze ................................................................. 156
Przechowywanie położenia i rozmiaru okna .......................................................... 162
Automatyczne uruchamianie aplikacji po zalogowaniu się użytkownika ............... 165
Umieszczanie informacji o zainstalowanym programie
(aplet Dodaj/Usuń programy) .............................................................................. 169
Gdzie jest katalog z moimi dokumentami? ............................................................ 176
Dodawanie pozycji do menu kontekstowego związanego
z zarejestrowanym typem pliku ........................................................................... 176
Obsługa rejestru i plików INI za pomocą MFC ............................................................ 180
Przechowywanie położenia i rozmiaru okna w rejestrze (MFC) ............................ 180
Przechowywanie położenia i rozmiaru okna w pliku INI (MFC) ........................... 182
Skrót internetowy (.url) .......................................................................................... 183
Rozdział 6. Komunikaty Windows ................................................................... 185
Pętla główna aplikacji ................................................................................................... 185
Obsługa komunikatów w procedurze okna (MFC) ....................................................... 187
Reakcja okna lub kontrolki na konkretny typ komunikatu ..................................... 187
Lista komunikatów odbieranych przez okno .......................................................... 188
Filtrowanie zdarzeń ................................................................................................ 191
Przykład odczytywania informacji dostarczanych przez komunikat ...................... 191
Lista wszystkich komunikatów odbieranych przez okno i jego kontrolki .............. 193
Wykrycie zmiany trybu pracy karty graficznej ...................................................... 193
Wysyłanie komunikatów .............................................................................................. 196
Wysyłanie komunikatów. „Symulowanie” zdarzeń ............................................... 196
Wysłanie komunikatu uruchamiającego wygaszacz ekranu
i detekcja włączenia wygaszacza ......................................................................... 197
Wykorzystanie komunikatów do kontroli innej aplikacji na przykładzie Winampa ..... 197
Przykłady reakcji na komunikaty (MFC) ..................................................................... 198
Blokowanie zamknięcia sesji Windows ................................................................. 198
Wykrycie włożenia do napędu lub wysunięcia z niego płyty CD lub DVD;
wykrycie podłączenia do gniazda USB lub odłączenia pamięci Flash ................. 199
Przeciąganie plików między aplikacjami ............................................................... 201
Poprawny sposób blokowania zamykania okna dialogowego
po naciśnięciu klawisza Enter .............................................................................. 204
Zmiana aktywnego komponentu za pomocą klawisza Enter .................................. 205
XKill dla Windows ................................................................................................. 206
Modyfikowanie menu systemowego formy ........................................................... 208
Haki .............................................................................................................................. 210
Biblioteka DLL z procedurą haka .......................................................................... 211
Rejestrowanie klawiszy naciskanych na klawiaturze ............................................. 216
6
Visual C++. Gotowe rozwiązania dla programistów Windows
Rozdział 7. Biblioteki DLL .............................................................................. 217
Funkcje i klasy w bibliotece DLL ................................................................................. 218
Tworzenie regularnej biblioteki DLL — eksport funkcji ....................................... 218
Statyczne łączenie bibliotek DLL — import funkcji .............................................. 220
Dynamiczne ładowanie bibliotek DLL — import funkcji ...................................... 222
Tworzenie biblioteki DLL z rozszerzeniem MFC — eksport funkcji .................... 224
Tworzenie biblioteki DLL z rozszerzeniem MFC — eksport klasy ....................... 224
Statyczne łączenie biblioteki DLL — import klasy ................................................ 226
Tworzenie biblioteki DLL z rozszerzeniem MFC
— eksport klasy. Modyfikacja dla dynamicznie ładowanych bibliotek ............... 227
Dynamiczne łączenie bibliotek DLL — import klasy ............................................ 228
Powiadamianie biblioteki o jej załadowaniu lub usunięciu z pamięci .................... 230
Zasoby w bibliotece DLL ............................................................................................. 232
Łańcuchy w bibliotece DLL ................................................................................... 232
Bitmapa w bibliotece DLL ..................................................................................... 234
Okno dialogowe w bibliotece DLL ........................................................................ 237
Tworzenie apletu panelu sterowania wyświetlającego informacje o dyskach .............. 240
Rozdział 8. Automatyzacja i inne technologie bazujące na COM ...................... 249
Technologia COM ........................................................................................................ 249
Osadzanie obiektów OLE2 ........................................................................................... 250
Statyczne osadzanie obiektu ................................................................................... 251
Kończenie edycji dokumentu. Łączenie menu aplikacji klienckiej i serwera OLE ....... 252
Wykrywanie niezakończonej edycji podczas zamykania programu ....................... 254
Inicjowanie edycji osadzonego obiektu z poziomu kodu ................................... 255
Dynamiczne osadzanie obiektu .............................................................................. 256
Automatyzacja .............................................................................................................. 258
Typ VARIANT i klasa COleVariant ...................................................................... 258
Łączenie z serwerem automatyzacji aplikacji Excel .............................................. 259
Uruchamianie aplikacji Excel za pośrednictwem mechanizmu automatyzacji ....... 265
Uruchamianie procedur serwera automatyzacji ...................................................... 266
Eksplorowanie danych w arkuszu kalkulacyjnym .................................................. 266
Korzystanie z okien dialogowych serwera automatyzacji.
Zapisywanie danych w pliku ................................................................................ 268
Zapisywanie danych z wykorzystaniem okna dialogowego aplikacji klienckiej .... 268
Edycja danych w komórkach Excela ...................................................................... 269
Korzystanie z funkcji matematycznych i statystycznych Excela ............................ 271
Konwersja skoroszytu Excela do pliku HTML ...................................................... 273
Uruchamianie aplikacji Microsoft Word i tworzenie nowego dokumentu
lub otwieranie istniejącego .................................................................................. 276
Wywoływanie funkcji Worda na przykładzie sprawdzania pisowni
i drukowania ........................................................................................................ 278
Wstawianie tekstu do bieżącego dokumentu Worda .............................................. 278
Zapisywanie bieżącego dokumentu Worda ............................................................ 279
Zaznaczanie i kopiowanie całego tekstu dokumentu Worda do schowka .............. 280
Kopiowanie zawartości dokumentu Worda do komponentu CRichEditCtrl
bez użycia schowka (z pominięciem formatowania tekstu) ................................. 280
Formatowanie zaznaczonego fragmentu tekstu w dokumencie Worda .................. 281
Serwer automatyzacji OLE przeglądarki Internet Explorer .................................... 282
Własny serwer automatyzacji ....................................................................................... 284
Projektowanie serwera automatyzacji .................................................................... 284
Testowanie serwera automatyzacji ......................................................................... 287
ActiveX ........................................................................................................................ 289
Korzystanie z kontrolek ActiveX ........................................................................... 289
Spis treści
7
Rozdział 9. Sieci komputerowe ....................................................................... 293
Struktura sieci komputerowych .................................................................................... 293
Lista połączeń sieciowych i diagnoza sieci ................................................................... 296
Aktywne połączenia TCP ....................................................................................... 296
Aktywne gniazda UDP ........................................................................................... 299
Sprawdzanie konfiguracji interfejsów sieciowych ................................................. 300
Ping ........................................................................................................................ 302
Sprawdzanie adresu IP hosta (funkcja DnsQuery) ................................................. 305
Sprawdzanie adresu IP i nazwy hosta (funkcje gethostbyaddr i gethostbyname) ... 307
Odczytywanie adresów MAC z tablicy ARP ......................................................... 311
Tablica ARP — wiązanie wpisów z interfejsem .................................................... 314
Protokoły TCP i UDP ................................................................................................... 316
Tworzenie i zamykanie gniazda — klasa bazowa .................................................. 316
Klasa implementująca serwer TCP ......................................................................... 317
Klasa implementująca serwer UDP ........................................................................ 319
Aplikacja działająca jako serwer TCP i UDP ......................................................... 320
Klasa implementująca klienta TCP ........................................................................ 322
Klasa implementująca klienta UDP ........................................................................ 324
Aplikacja działająca jako klient TCP i UDP .......................................................... 325
Serwer TCP działający asynchronicznie (funkcja WSAAsyncSelect) .................... 327
Serwer TCP — użycie klasy CSocket .................................................................... 330
Klient TCP — użycie klasy CSocket ..................................................................... 334
Inne protokoły sieciowe ................................................................................................ 336
Protokół FTP (przesyłanie plików) ......................................................................... 336
Protokół SMTP (poczta elektroniczna) .................................................................. 343
Inne ............................................................................................................................... 350
Aby pobrać plik z Internetu .................................................................................... 350
Mapowanie dysków sieciowych ............................................................................. 350
Rozdział 10. Wątki .......................................................................................... 353
Tworzenie wątków ....................................................................................................... 353
Tworzenie wątku .................................................................................................... 354
Tworzenie wątku roboczego za pomocą MFC ....................................................... 355
Usypianie wątków (funkcja Sleep) ......................................................................... 357
Czas wykonywania wątków ................................................................................... 359
Wstrzymywanie i wznawianie wątków .................................................................. 361
Kończenie wątku .......................................................................................................... 362
Funkcja TerminateThread ...................................................................................... 362
Funkcja ExitThread ................................................................................................ 362
Funkcje TerminateProcess i ExitProcess ................................................................ 363
Priorytety wątków ........................................................................................................ 364
Priorytety procesu .................................................................................................. 365
Statyczna kontrola priorytetów wątków ................................................................. 369
Dynamiczna kontrola priorytetów wątków ............................................................. 370
Flaga CREATE_SUSPENDED .............................................................................. 371
Wątek działający z ukrycia ..................................................................................... 373
Programowanie koligacji .............................................................................................. 374
Informacja o liczbie procesorów (funkcja GetSystemInfo) .................................... 374
Przypisywanie procesu do procesora ...................................................................... 375
Odczytywanie maski koligacji procesu .................................................................. 377
Programowanie koligacji wątku ............................................................................. 378
Wątki interfejsu użytkownika ....................................................................................... 380
Tworzenie wątku UI ............................................................................................... 380
Wykonywanie zadań w tle ..................................................................................... 383
Uwolnienie głównego okna aplikacji ..................................................................... 385
8
Visual C++. Gotowe rozwiązania dla programistów Windows
Synchronizacja wątków ................................................................................................ 386
Wyzwalanie wątków za pomocą zdarzeń ............................................................... 387
Sekcje krytyczne .................................................................................................... 390
Semafory (zliczanie użycia zasobów) .................................................................... 393
Muteksy .................................................................................................................. 398
Rozdział 11. Programowanie współbieżne z OpenMP ......................................... 403
Blok równoległy ........................................................................................................... 405
Dynamiczne tworzenie wątków, zmienne środowiskowe i funkcje biblioteczne ......... 407
Zrównoleglenie pętli ..................................................................................................... 408
Sposoby podziału iteracji między wątki ....................................................................... 417
Redukcja i bloki krytyczne ........................................................................................... 420
Sekcje, czyli współbieżność zadań ............................................................................... 422
Zmienne prywatne i zmienne wspólne ......................................................................... 427
Synchronizacja wątków ................................................................................................ 429
Rozdział 12. Biblioteka Threading Building Blocks ............................................ 431
Instalacja ....................................................................................................................... 432
Inicjalizacja biblioteki ............................................................................................ 434
Zrównoleglanie pętli .............................................................................................. 436
Rozmiar ziarna i podział przestrzeni danych ................................................................ 441
Pomiar czasu wykonywania kodu .......................................................................... 443
Równoległa redukcja .............................................................................................. 444
Łączenie zrównoleglania pętli z redukcją ............................................................... 446
Równoległe przetwarzanie potoków ...................................................................... 447
Wykorzystanie parallel_do ..................................................................................... 451
Własne przestrzenie danych ................................................................................... 454
Równoległe sortowanie .......................................................................................... 457
Równoległe obliczanie prefiksu ............................................................................. 458
Skalowalne alokatory pamięci ...................................................................................... 460
Kontenery ..................................................................................................................... 462
Wykorzystanie concurrent_vector .......................................................................... 465
Wykorzystanie concurrent_hash_map .................................................................... 467
Wzajemne wykluczanie i operacje atomowe ................................................................ 468
Wykorzystanie blokad ............................................................................................ 470
Łączenie TBB z OpenMP ....................................................................................... 472
Bezpośrednie korzystanie z planisty ............................................................................. 473
Tworzenie zadań za pomocą metody blokowania .................................................. 474
Tworzenie zadań za pomocą metody kontynuacji .................................................. 477
Dodatek A CUDA .......................................................................................... 481
Skorowidz ................................................................................... 507
Rozdział 4.
Systemy plików,
multimedia
i inne funkcje WinAPI
Pliki i system plików (funkcje powłoki)
Interfejs użytkownika systemu Windows pozwala na uruchamianie programów, kon-
trolę plików i katalogów (z funkcjami kosza systemowego włącznie), drukowanie doku-
mentów, tworzenie skrótów do nich itp. W interfejsie programisty WinAPI tym opera-
cjom odpowiadają tzw. funkcje powłoki, gdzie przez powłokę (ang. shell) rozumie się tę
najwyższą warstwę systemu, która odpowiada za komunikację z użytkownikiem1.
W ten sposób powłoka przesłania jądro i warstwy, do których użytkownik nie musi
sięgać2.
Funkcje WinAPI dotyczące powłoki są zazwyczaj prostsze w użyciu i bardziej
zautomatyzowane niż ich głębsze odpowiedniki. Najlepszym przykładem jest opisana
w poprzednim rozdziale funkcja ShellExecute, która jest znacznie łatwiejsza w użyciu
od CreateProcess. Teraz Czytelnik pozna inne funkcje pozwalające na wygodniejsze
manipulowanie plikami, w tym m.in. na korzystanie z kosza, operacje na grupach pli-
ków i całych katalogach. Omówimy także interfejsy COM należące do powłoki, które
pozwalają na tworzenie skrótów, oraz interfejs IFileOperation, który jest dostępny
w systemie Windows Vista.
1 Słowo „interfejs” w tym i w poprzednim zdaniu oznacza oczywiście coś innego. W pierwszym przypadku
chodzi o GUI (ang. graphic user interface), a więc okna, menu i inne graficzne elementy aplikacji
widoczne na ekranie, podczas gdy w drugim mowa o bibliotece funkcji pozwalających na kontrolę
systemu Windows. Funkcje powłoki to podzbiór funkcji interfejsu WinAPI, które pozwalają na kontrolę
interfejsu GUI.
2 Zob. „Blokowanie dostępu do komputera” w rozdziale 2.
106
Visual C++. Gotowe rozwiązania dla programistów Windows
Odczytywanie ścieżek do katalogów specjalnych
Ścieżki do katalogów specjalnych użytkownika (np. katalogu z dokumentami czy
pulpitu) można odczytać z rejestru (por. rozdział 5.). Jednak nie jest to sposób za-
lecany. Przedstawione tutaj rozwiązanie korzystające z funkcji powłoki jest po-
prawnym sposobem odczytywania ścieżki do tych katalogów.
Do odczytania katalogów specjalnych systemu i profilu użytkownika służy funkcja
SHGetSpecialFolderPath3 zdefiniowana w nagłówku shlobj.h. Jej trzeci argument wska-
zuje interesujący nas katalog. Najbardziej popularne to: CSIDL_PERSONAL (Moje dokumen-
ty), CSIDL_DESKTOP (Pulpit), CSIDL_WINDOWS (C:\Windows) i CSIDL_SYSTEM (C:\ Windows\
System32). Część stałych odpowiadających katalogom definiowanym dla każdego
użytkownika ma wersje zawierające _COMMON_. Odnoszą się one do odpowiednich
katalogów zawierających elementy dostępne w profilach wszystkich użytkowników
(w Windows XP są to podkatalogi katalogu C:\Documents and Settings\All Users,
a w Windows Vista są to podkatalogi katalogu C:\Users (Użytkownicy)), np. CSIDL_
(cid:180)COMMON_DESKTOPDIRECTORY4. Listing 4.1 zawiera kilka przykładowych funkcji zwracają-
cych uzyskane dzięki wywołaniu funkcji SHGetSpecialFolderPath ścieżki do katalogów
specjalnych w postaci obiektu CString — łańcucha wygodnego do użycia w aplikacjach
korzystających z biblioteki MFC.
Listing 4.1. Zbiór funkcji zwracających ścieżki do katalogów specjalnych
CString Katalog_Windows()
{
TCHAR path[MAX_PATH];
SHGetSpecialFolderPath(NULL, path, CSIDL_WINDOWS, FALSE);
return CString(path);
}
CString Katalog_System()
{
TCHAR path[MAX_PATH];
SHGetSpecialFolderPath(NULL, path, CSIDL_SYSTEM, FALSE);
return CString(path);
}
CString Katalog_MojeDokumenty()
{
TCHAR path[MAX_PATH];
SHGetSpecialFolderPath(NULL, path, CSIDL_PERSONAL, FALSE);
return CString(path);
}
CString Katalog_AllUsers_Pulpit()
{
TCHAR path[MAX_PATH];
3 Funkcja ta działa w każdej wersji systemu Windows, jednak w Windows 95 i NT 4.0 wymaga
zainstalowania Internet Explorera 4.0.
4 Wszystkie stałe CSIDL znajdzie Czytelnik w dokumentacji MSDN pod hasłem CSIDL.
Rozdział 4. ♦ Systemy plików, multimediai inne funkcje WinAPI
107
SHGetSpecialFolderPath(NULL, path, CSIDL_COMMON_DESKTOPDIRECTORY, FALSE);
return CString(path);
}
CString Katalog_Pulpit()
{
TCHAR path[MAX_PATH];
SHGetSpecialFolderPath(NULL, path, CSIDL_DESKTOPDIRECTORY, FALSE);
return CString(path);
}
Tworzenie skrótu (.lnk)
W tym projekcie po raz pierwszy będziemy mieli do czynienia z obiektem zdefiniowa-
nym w systemie Windows i udostępnionym programistom w ramach mechanizmu
COM (ang. Component Object Model). Pełniejsze wprowadzenie do COM i zwią-
zanych z nim technologii znajdzie Czytelnik w rozdziale 4. Tutaj ograniczę się zatem
jedynie do omówienia funkcji wykorzystanych w poniższym kodzie (w komentarzu
na końcu tego projektu).
Zgodnie z zasadami przedstawionymi we wstępie zasadnicze funkcje napisane zosta-
ną w taki sposób, aby mogły być użyte w dowolnym projekcie, lecz w przykładach
ich użycia skorzystamy z typów zdefiniowanych w MFC, w szczególności dotyczy to
łańcuchów.
1. Tworzymy nowy projekt aplikacji MFC z oknem dialogowym o nazwie PlikSkrotu.
2. Do projektu dodajemy pliki Skrot.h i Skrot.cpp (oczywiście do odpowiednich
gałęzi w drzewie plików projektu widocznym w Solution Explorer).
3. W pliku nagłówkowym Skrot.h definiujemy strukturę pomocniczą
CParametrySkrotu, której pola będą przechowywały następujące własności
skrótu: pełną ścieżkę wraz z nazwą pliku, do którego chcemy utworzyć skrót,
opis, katalog roboczy, klawisz skrótu (litera, która razem z klawiszami Ctrl
i Alt będzie uruchamiała skrót, jeżeli będzie umieszczony na pulpicie lub na
pasku szybkiego uruchamiania), ścieżkę do pliku zawierającego ikonę skrótu
oraz numer ikony w tym pliku (listing 4.2).
Listing 4.2. Zawartość pliku nagłówkowego Skrot.h
#pragma once
struct CParametrySkrotu
{
TCHAR sciezkaPliku[MAX_PATH], katalogRoboczy[MAX_PATH], sciezkaIkony[MAX_PATH];
TCHAR argumenty[256], opis[256];
int rodzajOkna, numerIkony;
wchar_t klawiszSkrotu;
};
BOOL TworzSkrot(LPCTSTR sciezkaLinku, CParametrySkrotu parametrySkrotu);
108
Visual C++. Gotowe rozwiązania dla programistów Windows
4. Listing 4.2 zawiera również deklaracje dwóch funkcji, które zdefiniujemy
w pliku Skrot.cpp, a które służyć będą do tworzenia i odczytywania pliku skrótu.
5. Przechodzimy do edycji pliku Skrot.cpp. Umieszczamy w nim dyrektywę
dołączającą nagłówek shlwapi.h, zawierający deklarację m.in. funkcji służących
do operacji na ścieżkach do pliku, w szczególności funkcji PathRemoveFileSpec,
która usuwa z pełnej ścieżki do pliku nazwę pliku, a pozostawia jedynie ścieżkę
katalogu. Definiujemy w pliku również funkcję tworzącą skrót (listing 4.3).
Listing 4.3. Omówienie funkcji znajduje się w komentarzu poniżej
#include stdafx.h
#include Skrot.h
#include shlwapi.h // PathRemoveFileSpec
BOOL TworzSkrot(LPCTSTR sciezkaLinku, CParametrySkrotu parametrySkrotu)
{
CoInitializeEx(NULL, COINIT_MULTITHREADED);
IShellLink* pISLink;
if (CoCreateInstance(CLSID_ShellLink,
NULL,
CLSCTX_INPROC_SERVER,
IID_IShellLink,
(void**) pISLink) != S_OK) return FALSE;
IPersistFile* pIPFile;
pISLink- QueryInterface(IID_IPersistFile,(void**) pIPFile);
//przygotowanie parametrów
if (wcscmp(parametrySkrotu.sciezkaPliku,L )==0) THROW( Brak nazwy pliku, do
(cid:180)którego ma zostać utworzony skrót );
if (wcscmp(parametrySkrotu.katalogRoboczy,L )==0)
{
wcscpy_s(parametrySkrotu.katalogRoboczy, MAX_PATH, parametrySkrotu.sciezkaPliku);
PathRemoveFileSpecW(parametrySkrotu.katalogRoboczy);//parametrySkrotu.katalogRoboczy.
(cid:180)GetBuffer());
}
if (parametrySkrotu.rodzajOkna == 0) parametrySkrotu.rodzajOkna = SW_SHOWNORMAL;
//nie dopuszczamy SW_HIDE=0 ze względu na taką domyślną inicjację
parametrySkrotu.klawiszSkrotu = toupper(parametrySkrotu.klawiszSkrotu);
//przygotowanie obiektu
pISLink- SetPath(parametrySkrotu.sciezkaPliku);
pISLink- SetWorkingDirectory(parametrySkrotu.katalogRoboczy);
pISLink- SetArguments(parametrySkrotu.argumenty);
if (parametrySkrotu.opis != L ) pISLink- SetDescription(parametrySkrotu.opis);
pISLink- SetShowCmd(parametrySkrotu.rodzajOkna);
if (parametrySkrotu.sciezkaIkony != L ) pISLink- SetIconLocation(parametry
(cid:180)Skrotu.sciezkaIkony, parametrySkrotu.numerIkony);
if (parametrySkrotu.klawiszSkrotu != NULL) pISLink- SetHotkey(((HOTKEYF_ALT |
(cid:180)HOTKEYF_CONTROL) 8) | parametrySkrotu.klawiszSkrotu);
BOOL wynik = (pIPFile- Save(sciezkaLinku, FALSE) == S_OK);
pISLink- Release();
Rozdział 4. ♦ Systemy plików, multimediai inne funkcje WinAPI
109
CoUninitialize();
return wynik;
}
6. Aby przetestować funkcję TworzSkrot, przechodzimy do widoku projektowania
i na podglądzie formy umieszczamy przycisk. Klikając go dwukrotnie, tworzymy
domyślną metodę zdarzeniową, w której umieszczamy polecenia z listingu 4.4.
W pliku nagłówkowym PlikSkrotuDlg.h należy wcześniej dołączyć nowy
nagłówek za pomocą dyrektywy prekompilatora: #include Skrot.h .
Listing 4.4. Tworzymy skrót do bieżącej aplikacji w bieżącym katalogu
void CPlikSkrotuDlg::OnBnClickedButton1()
{
CParametrySkrotu parametrySkrotu;
GetModuleFileName(GetModuleHandle(NULL), parametrySkrotu.sciezkaPliku, MAX_PATH);
wcscpy_s(parametrySkrotu.katalogRoboczy,MAX_PATH,parametrySkrotu.sciezkaPliku);
PathRemoveFileSpec(parametrySkrotu.katalogRoboczy);
wcscpy_s(parametrySkrotu.argumenty,260,L );
wcscpy_s(parametrySkrotu.opis,260,AfxGetApp()- m_pszAppName);
parametrySkrotu.rodzajOkna = SW_SHOWNORMAL;
wcscpy_s(parametrySkrotu.sciezkaIkony,MAX_PATH,parametrySkrotu.sciezkaPliku);
parametrySkrotu.numerIkony = 0;
parametrySkrotu.klawiszSkrotu = y ;
TworzSkrot(L Skrot.lnk , parametrySkrotu);
}
Listing 4.3 zawiera zasadniczą funkcję TworzSkrot. W pierwszej linii kodu tej funkcji
inicjujemy bibliotekę COM, korzystając z funkcji CoInitializeEx. Zwykle polecenie
to umieszcza się w jednej z funkcji inicjujących aplikacji, np. na początku funkcji
OnInitDialog, w pliku PlikSkrotuDlg.cpp. My umieściliśmy ją w funkcji TworzSkrot,
aby zwrócić uwagę Czytelnika, że powinna być wywołana przed utworzeniem obiektu
COM, a poza tym, aby funkcja TworzSkrot była bardziej autonomiczna, co ułatwi jej
użycie w projektach Czytelnika. Następnie tworzymy instancję obiektu COM, posłu-
gując się funkcją CoCreateInstance z identyfikatorem obiektu CLSID_ShellLink. Funkcja
ta zapisuje we wskaźniku typu IShellLink* (nazwa użytej przez nas zmiennej to pISLink)
wskaźnik do utworzonego obiektu COM. Typ IShellLink oraz użyty później IPersist
(cid:180)File to interfejsy, czyli w nomenklaturze technologii COM zbiory funkcji (metod),
które podobnie jak klasy mogą dziedziczyć z innych interfejsów (w tym przypadku
z IUnknown). Interfejsy te umożliwiają dostęp do metod utworzonego przez nas obiektu
COM. Interfejs IShellLink udostępnia metody pozwalające na ustalenie lub odczyta-
nie własności skrótu (pliku z rozszerzeniem .lnk). Natomiast IPersistFile5 zawiera
metody Save i Load, które pozwalają zapisać w pliku i odczytać z niego atrybuty ustalone
przez interfejs IShellLink. Po zakończeniu korzystania z obiektu należy go jeszcze
zwolnić, używając metody Release.
5 Oba interfejsy dostępne są we wszystkich 32-bitowych wersjach Windows, poza Windows NT 3.x.
110
Visual C++. Gotowe rozwiązania dla programistów Windows
Jeżeli skrót o podanej nazwie już istnieje, powyższa funkcja nadpisze go bez pyta-
nia o zgodę.
Do wskazania ścieżki pliku, do którego tworzymy skrót, wykorzystujemy metodę
IShellLink::SetPath; do wskazania katalogu roboczego — IShellLink::SetWorking
(cid:180)Directory; do opisu — ISLink::SetDescription itd. Klawisz skrótu (w przypadku
plików .lnk obowiązkowa jest kombinacja klawiszy Ctrl+Alt) ustalamy metodą
ISLink::SetHotKey. Jej argument to liczba typu Word, w której mniej znaczący bajt zaj-
muje znak typu char, a w górnym, bardziej znaczącym bajcie zapalamy bity wskazane
przez stałe HOTKEYF_ALT i HOTKEYF_CONTROL (czyli w efekcie 00000110).
Plik zapisany przez metodę z listingu 4.4 można sprawdzić za pomocą systemowego
edytora skrótów (rysunek 4.1).
Rysunek 4.1. Systemowy edytor skrótów. Dziwny opis pliku na lewym rysunku jest domyślnym opisem
aplikacji w zasobach projektu; można go oczywiście z łatwością zmienić
Odczyt i edycja skrótu .lnk
Zdefiniujemy funkcję CzytajSkrot, która umieści informacje o skrócie w strukturze
CParametrySkrotu zdefiniowanej w listingu 4.2. Edycja tej struktury nie powinna
sprawić żadnych trudności. Po modyfikacji informacje o skrócie można ponownie za-
pisać, korzystając z funkcji TworzSkrot.
1. Funkcja CzytajSkrot z listingu 4.5 powinna znaleźć się w pliku Skrot.cpp,
natomiast do pliku nagłówkowego Skrot.h należy dodać jej deklarację. Nie
zawiera ona zasadniczo nowych elementów. Jeszcze raz wykorzystujemy obiekt
identyfikowany przez stałą CLSID_ShellLink i interfejsy IShellLink oraz
IPersistFile.
Rozdział 4. ♦ Systemy plików, multimediai inne funkcje WinAPI
111
Listing 4.5. Definicja funkcji CzytajSkrot w wersji dla Win32
BOOL CzytajSkrot(LPCTSTR sciezkaLinku, CParametrySkrotu parametrySkrotu)
{
CoInitializeEx(NULL, COINIT_MULTITHREADED);
IShellLink* pISLink;
if (CoCreateInstance (CLSID_ShellLink,
NULL,
CLSCTX_INPROC_SERVER,
IID_IShellLink,
(void**) pISLink) != S_OK) return FALSE;
IPersistFile* pIPFile;
pISLink- QueryInterface(IID_IPersistFile,(void**) pIPFile);
if (pIPFile- Load(sciezkaLinku, 0) != S_OK)
{
pISLink- Release();
return FALSE;
}
TCHAR cstr[MAX_PATH];
WIN32_FIND_DATA informacjeOPliku; //tu nie wykorzystywane
pISLink- GetPath(parametrySkrotu.sciezkaPliku, MAX_PATH, informacjeOPliku,
(cid:180)SLGP_UNCPRIORITY);
pISLink- GetWorkingDirectory(parametrySkrotu.katalogRoboczy , MAX_PATH);
pISLink- GetArguments(cstr, MAX_PATH);
wcscpy_s(parametrySkrotu.argumenty,260,cstr);
pISLink- GetDescription(cstr, MAX_PATH);
wcscpy_s(parametrySkrotu.opis,260,cstr);
pISLink- GetShowCmd( (parametrySkrotu.rodzajOkna));
pISLink- GetIconLocation(parametrySkrotu.sciezkaIkony, MAX_PATH,
(cid:180) (parametrySkrotu.numerIkony));
WORD klawiszSkrotu;
pISLink- GetHotkey( klawiszSkrotu);
parametrySkrotu.klawiszSkrotu = (klawiszSkrotu 255);
pISLink- Release();
return TRUE;
}
2. Aby przetestować funkcję CzytajSkrot, umieszczamy na podglądzie formy
kolejny przycisk i tworzymy jego domyślną metodę zdarzeniową.
Umieszczamy w niej polecenia z listingu 4.6.
Listing 4.6. Ograniczymy się do zaprezentowania parametrów skrótu w oknie komunikatu
void CPlikSkrotuDlg::OnBnClickedButton2()
{
CParametrySkrotu parametrySkrotu;
if (CzytajSkrot(L Skrot.lnk , parametrySkrotu))
112
Visual C++. Gotowe rozwiązania dla programistów Windows
{
CString temp;
temp.Format(L Informacje o pliku skrótu\nSciezka pliku: s\nArgumenty:
(cid:180) s,\nKatalog roboczy: s\nOpis: s\nIkona: s (nr ikony: d)\nKlawisz
(cid:180)skrótu: c ,
parametrySkrotu.sciezkaPliku,
parametrySkrotu.argumenty,
parametrySkrotu.katalogRoboczy,
parametrySkrotu.opis,
parametrySkrotu.sciezkaIkony,
parametrySkrotu.numerIkony,
parametrySkrotu.klawiszSkrotu);
AfxMessageBox(temp);
}
}
3. Po uruchomieniu aplikacji możemy kliknąć nowy przycisk. Powinniśmy wówczas
zobaczyć opis skrótu jak na rysunku 4.2.
Rysunek 4.2.
Odczytane z pliku
parametry skrótu
Umieszczenie skrótu na pulpicie
Aby umieścić skrót na pulpicie, wystarczy połączyć wiedzę z dwóch pierwszych projektów
w rozdziale. Listing 4.7 pokazuje, jak to zrobić. Zupełnie analogicznie wyglądałoby
umieszczenie skrótu np. w menu Start.
Listing 4.7. Wykorzystujemy funkcję TworzSkrot, wskazując ścieżkę pliku skonstruowaną za pomocą
funkcji Katalog_Pulpit
void CPlikSkrotuDlg::TworzSkrotNaPulpicie(LPCTSTR sciezkaLinku, CParametrySkrotu
(cid:180)parametrySkrotu)
{
CString temp;
temp.Format(L s\\ s , Katalog_Pulpit(), sciezkaLinku);
TworzSkrot(temp, parametrySkrotu);
}
Rozdział 4. ♦ Systemy plików, multimediai inne funkcje WinAPI
113
Operacje na plikach i katalogach (funkcje WinAPI)
Użytkownik ma do wyboru trzy sposoby, za pomocą których może wykonywać ope-
racje na plikach. Po pierwsze, może wykorzystać standardowe funkcje C++ (ten sposób
omówiono niżej). Po drugie, może użyć zbioru funkcji WinAPI (CopyFile, MoveFile,
DeleteFile itp.). Te niestety zostały dodane do WinAPI dopiero od Windows 2000,
co oczywiście ogranicza przenośność korzystających z nich aplikacji. I po trzecie,
użytkownik może użyć funkcji powłoki o nazwie SHFileOperation, która pozwala
między innymi na operacje na grupach plików, całych katalogach, czy na przeniesie-
nie pliku do kosza. Ten ostatni sposób zostanie omówiony w następnych projektach.
Wybór między pierwszym i drugim sposobem nie jest rozłączny; nie wszystkie opera-
cje da się łatwo wykonać za pomocą funkcji C++. Nie ma na przykład gotowej funkcji
pozwalającej na kopiowanie pliku. Do tego koniecznie trzeba użyć funkcji WinAPI, np.
CopyFile(L D:\\TMP\\Log.txt ,L D:\\TMP\\Log.bak ,FALSE)
lub bardziej złożonej konstrukcji:
if (!CopyFile(L D:\\TMP\\Log.txt ,L D:\\TMP\\Log.bak ,FALSE))
::MessageBox(NULL,L Operacja kopiowania nie powiodła się! ,L Błąd ,MB_OK);
else
::MessageBox(NULL,L Kopiowanie zakończone ,L Informacja ,MB_OK);
Jak łatwo się domyślić, pierwsze dwa argumenty wskazują nazwę pliku źródłowego
i nową nazwę pliku. Natomiast trzeci argument to wartość logiczna określająca, czy
możliwe jest nadpisywanie istniejącego pliku. Funkcja ta pozwala kopiować także
katalogi razem z zawartością i podkatalogami.
Istnieje również funkcja CopyFileEx, pozwalająca na śledzenie postępu kopiowania
pliku, który można np. pokazać na pasku postępu.
Podobnie działa funkcja MoveFile (także z WinAPI), przenosząca plik (zmieniająca jego
położenie w tablicy alokacji plików):
MoveFile(L D:\\TMP\\Log.txt ,L D:\\TMP\\Log_nowy.txt );
Funkcja MoveFileWithProgress pozwala na śledzenie postępu przenoszenia pliku, a także
na ustalenie sposobu przenoszenia (np. opóźnienie do momentu ponownego urucha-
miania). Ta ostatnia możliwość dostępna jest także w funkcji MoveFileEx.
Aby usunąć plik, można skorzystać z funkcji DeleteFile:
DeleteFile(L D:\\TMP\\Log.txt );
Podobnie wygląda sprawa z katalogami. Do tworzenia katalogu można użyć funkcji
C++ mkdir lub funkcji WinAPI CreateDirectory. Ta ostatnia dołączona została jednak
dopiero w Windows 2000. Do zmiany bieżącego katalogu można użyć funkcji chdir, na-
tomiast do usuwania pustego katalogu — rmdir lub wspomnianej już funkcji DeleteFile.
Funkcje te są zadeklarowane w nagłówku dir.h i „od zawsze” należą do standardu C++.
Nie należy się jednak obawiać używania ich w 32-bitowych wersjach Windows, gdyż
obecnie są one po prostu „nakładkami” na analogiczne funkcje WinAPI. Do pobrania
ścieżki bieżącego katalogu można użyć funkcji GetCurrentDirectory.
114
Visual C++. Gotowe rozwiązania dla programistów Windows
Operacje na plikach i katalogach (funkcje powłoki)
W poprzednim projekcie użyliśmy niskopoziomowych funkcji interfejsu programi-
stycznego Windows (WinAPI) CopyFile, MoveFile czy DeleteFile do wykonywania
podstawowych operacji na plikach. Chciałbym jednak zwrócić uwagę Czytelnika na
inny sposób wykonania tych operacji, który może wydawać się z początku nieco bar-
dziej skomplikowany, ale za to daje dodatkowe korzyści i przy wykonywaniu bardziej
złożonych operacji okazuje się o wiele prostszy niż korzystanie z funkcji niskopozio-
mowych. Użyjemy do tego funkcji WinAPI SHFileOperation z biblioteki shell32.dll.
Jedną z ich zalet jest to, że dostępne są już od Windows 95 i NT 4.0, czyli we wszyst-
kich 32-bitowych wersjach Windows. Biblioteka ta wykorzystywana jest m.in. przez
Eksploratora Windows i dlatego funkcje odwołują się do mechanizmów charakterystycz-
nych dla eksploratora, m.in. kosza systemowego czy katalogów specjalnych. W odróżnie-
niu od poprzednio użytych funkcji niskopoziomowych funkcja SHFileOperation należy
do warstwy powłoki (interfejsu graficznego) i dlatego jej działaniu towarzyszą okna żą-
dające potwierdzenia chęci utworzenia katalogu, ostrzegające przed nadpisaniem pliku itp.
1. Tworzymy nowy projekt aplikacji MFC z oknem dialogowym o nazwie
OperacjeNaPlikach.
2. W pliku nagłówkowym OperacjeNaPlikachDlg.h importujemy potrzebny moduł:
#include shlwapi.h
3. W tym samym pliku deklarujmy również funkcje składowe:
BOOL KopiowaniePliku(HWND uchwyt, LPCTSTR szZrodlo, LPCTSTR szCel);
BOOL PrzenoszeniePliku(HWND uchwyt, LPCTSTR szZrodlo, LPCTSTR szCel);
BOOL UsuwaniePliku(HWND uchwyt, LPCTSTR szZrodlo);
4. Przejdźmy do pliku źródłowego i zdefiniujmy funkcję pomocniczą
OperacjaNaPliku, dzięki której korzystanie z SHFileOperation będzie
łatwiejsze (listing 4.8).
Listing 4.8. Funkcja „prywatna” pozwalająca na uniknięcie powtarzania kodu
BOOL COperacjeNaPlikachDlg::OperacjaNaPliku(HWND uchwyt, LPCTSTR szZrodlo,
(cid:180)LPCTSTR szCel, DWORD operacja, DWORD opcje)
{
if(!PathFileExists(szZrodlo)) // Czy plik źródłowy istnieje?
{
AfxMessageBox(L Nie odnaleziono pliku );
return FALSE;
}
SHFILEOPSTRUCT parametryOperacji;
parametryOperacji.hwnd = uchwyt;
parametryOperacji.wFunc = operacja;
if (szZrodlo != L )
parametryOperacji.pFrom = szZrodlo;
else
parametryOperacji.pFrom = NULL;
if (szCel != L )
parametryOperacji.pTo = szCel;
Rozdział 4. ♦ Systemy plików, multimediai inne funkcje WinAPI
115
else
{
parametryOperacji.pTo = NULL;
parametryOperacji.fFlags = opcje;
parametryOperacji.hNameMappings = NULL;
parametryOperacji.lpszProgressTitle = NULL;
}
return (SHFileOperation( parametryOperacji) == 0);
}
5. Wreszcie definiujemy zadeklarowany w pliku nagłówkowym zestaw metod
(zadeklarowaliśmy je w nagłówku) wykonujących konkretne czynności na plikach
(listing 4.9).
Listing 4.9. Zbiór funkcji „publicznych”
BOOL COperacjeNaPlikachDlg::KopiowaniePliku(HWND uchwyt, LPCTSTR szZrodlo,
(cid:180)LPCTSTR szCel)
{
TCHAR lpBuffer[MAX_PATH] = {0};
GetFullPathName(szZrodlo, MAX_PATH, lpBuffer, NULL);
return OperacjaNaPliku(uchwyt, lpBuffer, szCel, FO_COPY, 0);
}
BOOL COperacjeNaPlikachDlg::PrzenoszeniePliku(HWND uchwyt, LPCTSTR szZrodlo,
(cid:180)LPCTSTR szCel)
{
TCHAR lpBuffer[MAX_PATH] = {0};
GetFullPathName(szZrodlo, MAX_PATH, lpBuffer, NULL);
return OperacjaNaPliku(uchwyt, lpBuffer, szCel, FO_MOVE, 0);
}
BOOL COperacjeNaPlikachDlg::UsuwaniePliku(HWND uchwyt, LPCTSTR szZrodlo)
{
TCHAR lpBuffer[MAX_PATH] = {0};
GetFullPathName(szZrodlo, MAX_PATH, lpBuffer, NULL);
return OperacjaNaPliku(uchwyt, lpBuffer, L , FO_DELETE, 0);
}
6. Listing 4.10 zawiera domyślną metodę zdarzeniową kliknięcia przycisku
Button1, która testuje działanie powyższych funkcji.
Listing 4.10. Aby poniższy test zadziałał, musimy dysponować dyskiem d:. Można to oczywiście łatwo zmienić
void COperacjeNaPlikachDlg::OnBnClickedButton1()
{
TCHAR path[MAX_PATH] = {0};
GetModuleFileName(GetModuleHandle(NULL), path, MAX_PATH);
KopiowaniePliku(m_hWnd, path, L d:\\Kopia projektu.sln );
PrzenoszeniePliku(m_hWnd, L d:\\Kopia projektu.sln , L d:\\Kopia pliku.xml );
UsuwaniePliku(m_hWnd, L d:\\Kopia pliku.xml );
}
116
Visual C++. Gotowe rozwiązania dla programistów Windows
Operacje na plikach i katalogach w Windows Vista
(interfejs IFileOperation)
W systemie Windows Vista oddano do użytku interfejs IFileOperation, który zastę-
puje opisaną wcześniej strukturę SHFILEOPSTRUCT. Nie oznacza to jednak, iż nie możemy
już korzystać z tej struktury w nowych wersjach Windows. Interfejs IFileOperation
wydaje się jednak wygodniejszy w użyciu. Ułatwia śledzenie postępu wykonywanych
operacji oraz zapewnia możliwość wykonywania wielu operacji jednocześnie, a także
bardziej szczegółowo informuje o błędach. W celu użycia funkcji udostępnianych
przez interfejs IFileOperation należy korzystać z obiektu IShellItem przy określeniu
ścieżki do plików i katalogów. Dzięki temu można wykonywać operacje nie tylko na
plikach i katalogach, ale również na takich obiektach, jak foldery wirtualne. Przykład
wykorzystania omawianego interfejsu przedstawiają poniższe projekty.
1. Tworzymy nowy projekt aplikacji MFC z oknem dialogowym o nazwie
OperacjeNaPlikachIF.
2. Na początku pliku OperacjeNaPlikachIFDlg.cpp umieszczamy trzy dyrektywy:
#include shobjidl.h
#include shlobj.h
#include shlwapi.h
3. Natomiast w pliku nagłówkowym deklarujemy prywatną funkcję
OperacjaNaPlikuIF i definiujemy ją zgodnie z listingiem 4.11.
Listing 4.11. Funkcja wykonująca operacje na pliku (kopiowanie, przenoszenie, usuwanie)
wykorzystująca interfejs IFileOperation
HRESULT COperacjeNaPlikachIFDlg::OperacjaNaPlikuIF(LPCTSTR szZrodlo, LPCTSTR szCel,
(cid:180)DWORD operacja, DWORD opcje)
{
if(!PathFileExists(szZrodlo)) // Czy plik źródłowy istnieje?
{
AfxMessageBox(L Nie odnaleziono pliku );
return E_POINTER;
}
CT2W wszZrodlo(szZrodlo);
CT2W wszCel(szCel);
CString wszNowaNazwa = PathFindFileNameW(wszCel);
PathRemoveFileSpec(wszCel);
// Tworzenie nowej instancji interfejsu IFileOperation
IFileOperation *iFo;
HRESULT hr = CoCreateInstance(CLSID_FileOperation,
NULL,
CLSCTX_LOCAL_SERVER,
IID_PPV_ARGS( iFo));
if(!SUCCEEDED(hr))
return hr;
iFo- SetOperationFlags(opcje);
// Tworzenie obiektów IShellItem
Rozdział 4. ♦ Systemy plików, multimediai inne funkcje WinAPI
117
IShellItem *psiCel = NULL, *psiZrodlo = NULL;
SHCreateItemFromParsingName(wszZrodlo, NULL, IID_PPV_ARGS( psiZrodlo));
if(wszCel != NULL)
SHCreateItemFromParsingName(wszCel, NULL, IID_PPV_ARGS( psiCel));
// Kopiowanie, przenoszenie czy usuwanie?
switch(operacja)
{
case FO_COPY: iFo- CopyItem(psiZrodlo, psiCel, wszNowaNazwa, NULL); break;
case FO_MOVE: iFo- MoveItem(psiZrodlo, psiCel, wszNowaNazwa, NULL); break;
case FO_DELETE: iFo- DeleteItem(psiZrodlo, NULL); break;
}
// Potwierdzenie wykonania operacji
hr = iFo- PerformOperations();
if(!SUCCEEDED(hr))
return hr;
psiZrodlo- Release();
if(psiCel != NULL)
psiCel- Release();
// Zwolnienie interfejsu
iFo- Release();
return hr;
}
4. Analogicznie jak w poprzednim projekcie deklarujemy i definiujemy publiczne
metody odpowiedzialne za kopiowanie, przenoszenie i usuwanie plików
(listing 4.12). Jednakże teraz zamiast zwracać wartość BOOL, zwracamy HRESULT.
Listing 4.12. Metody realizujące kopiowanie, przenoszenie i usuwanie plików
HRESULT COperacjeNaPlikachIFDlg::KopiowaniePliku(LPCTSTR szZrodlo, LPCTSTR szCel)
{
TCHAR lpBuffer[MAX_PATH] = {0};
GetFullPathName(szZrodlo, MAX_PATH, lpBuffer, NULL);
return OperacjaNaPlikuIF(lpBuffer, szCel, FO_COPY, 0);
}
HRESULT COperacjeNaPlikachIFDlg::PrzenoszeniePliku(LPCTSTR szZrodlo, LPCTSTR szCel)
{
TCHAR lpBuffer[MAX_PATH] = {0};
GetFullPathName(szZrodlo, MAX_PATH, lpBuffer, NULL);
return OperacjaNaPlikuIF(lpBuffer, szCel, FO_MOVE, 0);
}
HRESULT COperacjeNaPlikachIFDlg::UsuwaniePliku(LPCTSTR szZrodlo)
{
TCHAR lpBuffer[MAX_PATH] = {0};
GetFullPathName(szZrodlo, MAX_PATH, lpBuffer, NULL);
return OperacjaNaPlikuIF(lpBuffer, NULL, FO_DELETE, 0);
}
118
Visual C++. Gotowe rozwiązania dla programistów Windows
5. W podglądzie okna umieszczamy przycisk i tworzymy jego domyślną metodę
zdarzeniową, w której umieszczamy wywołanie funkcji z listingu 4.13.
Listing 4.13. Na potrzeby naszego przykładu tworzymy plik test.txt, który wykorzystujemy do
testowania funkcji opartych na interfejsie IFileOperation
CString sciezkaPliku = L d:\\test.txt ;
HANDLE hFile = CreateFileW(sciezkaPliku, GENERIC_READ | GENERIC_WRITE, 0, NULL,
CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
CloseHandle(hFile);
KopiowaniePliku(sciezkaPliku, L d:\\test kopia.txt );
PrzenoszeniePliku(L d:\\test kopia.txt , L d:\\kopia xml.xml );
UsuwaniePliku(L d:\\kopia xml.xml );
Czytelnik powinien zauważyć, że w przypadku kopiowania większych plików pojawia się
teraz okno dialogowe, charakterystyczne dla systemu Windows Vista, informujące
o postępie kopiowania (rysunek 4.3). Jeśli korzystamy ze struktury SHFILEOPSTRUCT,
to nie mamy dostępu do własności specyficznych dla Visty.
Rysunek 4.3.
Kopiowanie elementu
za pomocą
IFileOperation
Przy usuwaniu pliku (funkcja UsuwaniePliku) pojawi się okno dialogowe z prośbą
o potwierdzenie operacji. Jeżeli nie jest ono pożądane, należy w ciele funkcji Usuwanie
(cid:180)Pliku, w ostatnim argumencie funkcji OperacjaNaPlikuIF, zamiast zera użyć stałej
FOF_NOCONFIRMATION (listing 4.14). Poza bardzo szczególnymi sytuacjami nie jest to
jednak rozwiązanie godne polecenia.
Listing 4.14. Usuwanie pliku bez konieczności potwierdzenia
HRESULT COperacjeNaPlikachIFDlg::UsuwaniePlikuBezPotwierdzenia(LPCTSTR szZrodlo)
{
TCHAR lpBuffer[MAX_PATH] = {0};
GetFullPathName(szZrodlo, MAX_PATH, lpBuffer, NULL);
return OperacjaNaPlikuIF(lpBuffer, NULL, FO_DELETE, FOF_NOCONFIRMATION);
}
Jak usunąć plik, umieszczając go w koszu?
Listing 4.15 zawiera funkcję, która różni się od funkcji UsuwaniePliku z poprzedniego
projektu jednym szczegółem. Użyta została opcja FOF_ALLOWUNDO, która nakazuje prze-
niesienie pliku do kosza zamiast usunięcia.
Rozdział 4. ♦ Systemy plików, multimediai inne funkcje WinAPI
119
Listing 4.15. Usuwanie pliku z wykorzystaniem mechanizmu powłoki kosza systemowego
HRESULT COperacjeNaPlikachIFDlg::UsuwaniePlikuDoKosza(LPCTSTR szZrodlo)
{
TCHAR lpBuffer[MAX_PATH] = {0};
GetFullPathName(szZrodlo, MAX_PATH, lpBuffer, NULL);
return OperacjaNaPlikuIF(lpBuffer, NULL, FO_DELETE, FOF_ALLOWUNDO);
}
Teraz przed skasowaniem pliku wyświetlone zostanie okno dialogowe z pytaniem
o umieszczenie pliku w koszu. Tej samej stałej można użyć w metodzie OperacjeNaPliku
w rozwiązaniu nie korzystającym z interfejsu IFileOperation.
Operacje na całym katalogu
Kopiowanie całego katalogu z podkatalogami jest również możliwe i równie łatwe jak
kasowanie pliku. W przypadku funkcji WinAPI i funkcji C++, które poznaliśmy wcze-
śniej, programowanie tej operacji jest możliwe, ale wszelkie informacje prezentowane
w trakcie użytkownikowi wymagałyby sporej dodatkowej pracy. A gdy korzysta się
z funkcji powłoki, wystarczy jedno polecenie. W listingu 4.16 zaprezentowane są funkcje
dla Windows Vista, t
Pobierz darmowy fragment (pdf)