Wiele aplikacji, które posiadają własne rozszerzenia plików mają ciekawą funkcjonalność. Otóż, gdy kliknie się dwukrotnie na plik o danym rozszerzeniu to otwierany jest on w określonej aplikacji. Przykładowo plik
*.txt jest odczytywany przez notatnik. Jak osiągnąd coś takiego? Sprawa jest stosunkowo prosta :)
Jak to się dzieje?
Przecież nie włączysz pliku z danymi :P Musi być wywołana aplikacja, która jest poinformowana o otwieranym pliku. Jak system postępuje w przypadku próby otwarcia pliku z danymi? Sprawdza
rejestr. Tam są zapisane informacje o rozszerzeniach oraz o tym, jak postępować w przypadkach próby otwarcia.
Pora na wizytę w rejestrze :)
Rejestr jest to największy śmietnik w Windowsie – głoszą słowa przeczytane kiedyś przeze mnie w Internecie. Mimo to, jest to także bardzo ciekawe miejsce i źródło wielu cennych informacji. My dodamy własne. Zajrzyjmy więc do rejestru :)
W Menu Start wybieramy „Uruchom”, wpisujemy „regedit” i zatwierdzamy. W Viście (przepraszam za formę, nie wiem jak to odmienić :P) i nowszych windowsach wystarczy na pasku do wyszukiwania wpisać rzekomą frazę i stamtąd to włączyć. Uruchomi się nam edytor rejestru. Najlepiej uruchomić go jako Administrator. Jak widać jest kilka głównych kluczy:
Nas interesuje klucz
HKEY_CLASSES_ROOT. Właśnie tam znajdują się informacje na temat rozszerzeń plików. Przyjrzyjmy się przykładowo rozszerzeniu
*.txt (chcesz to możesz wybrać inne).
Odszukajmy zatem klucz
.txt. Klikamy na niego i patrzymy na wartość domyślną:
Jak widać jest to ciąg znaków „txtfile”. On jest ważny, reszta nas nie interesuje :). Szukamy zatem nowego klucza o nazwie
txtfile w kluczu głównym
HKEY_CLASSES_ROOT (czyli jakby „obok” klucza
*.txt). Możesz użyć opcji szukaj niż ręcznie to robić :P. Znaleźliśmy i mamy takie o to drzewko:
Nas będzie interesować drzewko kluczy zaznaczone na obrazku. Znowu sprawa z wartościami domyślnymi :). Objaśnię co one oznaczają w konkretnych podkluczach. Użyłem
*.XXX oraz
<ext>, dlatego bo te wartości zależą od rozszerzenia, którym się aktualnie zajmujemy :)
Użyłem
<tryb> zamiast
open. Sprawa tkwi w tym, że tych trybów możemy sobie robić ile chcemy! Jednak w zupełności wystarczy nam ten jeden –
open. Przykładowy obrazek z wieloma trybami:
To w czerwonej jasnej ramce to wszystkie tryby jakie ma plik
*.txt. Możemy dopisać własne (zob. czerwona ciemna ramka)! Mogą się one odwoływać do, np. naszego programu! :). W zielonym kółku widać ikonkę pliku tekstowego… W rejestrze możemy ją zmienić :)! Jeszcze jedna warta uwagi rzecz to zawartość pomarańczowej elipsy. Są tam propozycje programów, przez które można otworzyć dany plik. System na podstawie rejestru sam sobie tę listę robi.
Rejestrujemy własne rozszerzenie
Na podstawie powyższych informacji jesteśmy w stanie zarejestrować własne rozszerzenie w systemie. My zrobimy sobie to ręcznie. Będzie to krótko opisane, ponieważ większość informacji jest zawarta wyżej :). Można to zrobić także korzystając z WinAPI bądź w pliku instalacyjnym – co jest raczej zalecane. Przecież nie zrobimy pliku „CzytajTo!.txt”, w którym krok po kroku każemy użytkownikowi rejestrować naszego rozszerzenia, nieprawdaż :)? Więc do dzieła :P!
Jak zapewne zdążyłeś zauważyć, standardowe rozszerzenia składają się z trzech znaków. To nie jest wymóg. My sobie zrobimy piecioznakowe :P. Załóżmy, że będzie to
*.myext (od
my extension).
Uwaga! Aby móc edytować rejestr trzeba Edytor Rejestru włączyć jako administrator. Otwieramy zatem główny klucz
HKEY_CLASSES_ROOT i dodajemy tam nasz podklucz – nazwany
.myext. Jako jego wartość główną musimy wpisać jakiś
unikalny (tzn. niepowtarzalny) ciąg znaków. Jeśliby istniał już taki klucz, to tak jakbyśmy postanowili wykorzystać obsługę innego rozszerzenia, a tego nie chcemy :). My wpiszemy sobie ”My_extension_unique_string”. W rzeczywistości wystarczy, że w tym stringu zawrze się jakieś krótkie informacje o naszej aplikacji… małe jest prawdopodobieństwo powtórzenia :). Zobaczmy co mamy:
Jak widać nad naszym rozszerzeniem znajduje się inne – jeszcze dłuższe :P. Nie musimy się ograniczać do trzech znaków. Dobra, teraz robimy kolejny klucz o takiej samej nazwie, co wartość domyślna poprzedniego klucza, czyli w tym przypadku to będzie ”My_extension_unique_string”. Klucz ma się znajdować na równi z
.myext, czyli w kluczu głównym
HKEY_CLASSES_ROOT. Zakładamy teraz takie drzewko kluczy:
Nie będę powtarzał jeszcze raz co znaczą konkretne wartości danych kluczy – to jest bez sensu. Zerknij w górę na tabelkę – tam masz objaśnienie. Zaznaczyłem jeszcze na obrazku wartość domyślną podklucza
command. Ja tu przesadziłem z cudzysłowami. Stawia się je wtedy, gdy w ścieżce są spacje. Chodzi o to, że są one ogranicznikami parametru. Jeśli w parametrze nie ma spacji – nie trzeba ujmować go w cudzysłów (co ja zrobiłem :) – to w niczym nie przeszkadza). Jest tam zapisane:
”C:\my_app\my_app.exe” ”--shell” ”%1”
Wyszczególniłem sobie ten środkowy parametr. Co on oznacza? Dla systemu – nic. Zrobiliśmy sobie to dla siebie :). Gdy ktoś będzie „włączał” plik
*.myext poprzez system (tzn. nie wczytując go normalnie w programie) będziemy o tym powiadomieni przez dodatkowy parametr
––shell :). Wcale nie musisz tego dodawać. Chciałem tylko pokazać, że tak wolno :P.
Czas odpalić nasze IDE ;)
Wreszcie dobrnęliśmy do tego momentu! :). Nic innego, tylko się cieszyć, co :P? Więc klawiatura do rąk (a raczej ręce na klawiaturę :P) i klepać kod :D.
Jak zapewne wiesz, funkcja
main ma taką formę:
Posiada ona także inną formę:
int main( int argc, char * argv[] );
Teraz sprawa co oznaczają te argumenty. Spostrzegawcze osoby zapewne powiedzą, że ma to coś wspólnego z parametrami wywołania programu – i mają rację :).
argc to skrót od Argument Counter (ang. Licznik argumentów). Jak nazwa mówi – jest to zmienna przechowująca liczbę przysłanych argumentów do funkcji.
argv jest to skrót od Argument Vector (ang. Wektor argumentów). Jest to tablica wskaźników (ale nie odwrotnie!) wskazujących na C-stringi będące parametrami (czyli argumentami) wywołania aplikacji. Uwaga! Parametr o indeksie 0
to zawsze relatywna ścieżka do wywołanej aplikacji. Relatywna, czyli jak np. wywołamy ją spod wiersza poleceń jako ”my_app” (może być nawet bez .exe!) to parametr przesłany do aplikacji to będzie właśnie to co wpisaliśmy w wierszu poleceń, czyli w naszym przypadku ”my_app” :).
Jak widzisz, kod będzie prosty, więc napisze go za Ciebie (:P):
int main( int argc, char * argv[] )
{
if( argc == 3 )
{
if( strcmp( argv[ 1 ], "--shell" ) == 0 )
{
}
}
else
}
Dlaczego
argc ma być równy 3? Jeśli system wywoła naszą aplikację, wywoła ją z trzema argumentami: relatywna ścieżka programu, ”--shell” oraz ścieżka otwieranego pliku –
my sami to określiliśmy w rejestrze. Funckja
strcmp porównuje określone C-stringi. Jeśli są one identyczne zwraca zero. ”No dobra, ale czemu po prostu nie użyć operatora ==?”. Odpowiedź jest prosta. Gdybyś napisał:
if( argv[ 1 ] == "--shell" )
To wtedy to wyrażenie zawsze by było fałszywe. Dlaczego? Otóż jest to porównanie
adresów C-stringów. A jak wiadomo, dwa
osobne ciągi znaków nie mogą się znajdować w jednym miejscu. (Pomieściłbyś dwa kilogramy jabłek w jednym? :P).
No, to by było na tyle… Nie jest to takie trudne, co :P? W rejestrze przy tym zapewne da się tam zapisać wiele innych informacji… Na Internecie nie mogłem znaleźć o tym informacji i wszystko co o rejestrze pisze to szczerze mówiąc „sam odkryłem”, dlatego jest trochę ubogo w dodatkowe szczegóły :P. Mimo, że rejestr jest największym śmietniskiem w Windowsie to czasem można z niego wygrzebać ciekawe informacje… :P