Programowanie w języku C/C++ » Artykuły

Obsługa uruchamiania programu poprzez przeciągnięcie i opuszczenie na jego ikonę plików

Drogi czytelniku, zapewne zdajesz sobie sprawę z tego, że aplikacje mogą być uruchamiane z pewnymi parametrami. Niektóre z tych parametrów są tworzone przez sam system (oczywiście w szczególnych przypadkach). Chciałbym omówić pewien taki przypadek, a mianowicie: przeciągnięcie i opuszczenie plików na ikonę programu. W wyniku tejże czynności system w parametrze cmdLine funkcji WinMain przekazuje nam następujące wiadomości:

a) pełną ścieżkę do lokalizacji programu (wraz z jego nazwą)

b) pełną ścieżkę lub ścieżki do plików, które zostały na nasz ukochany program przeciągnięte i upuszczone.

Dla utrudnienia Microsoft dodał możliwość przekazywania ścieżek dostępu w dwóch postaciach:

a) w cudzysłowie, gdy ścieżka zawiera choćby jeden znak spacji np.: "C:\Moje dokumenty\program.exe"

b) bez cudzysłowia, gdy ścieżka nie zawiera w swej nazwie spacji  np.: "C:\program.exe"

Poszczególne ścieżki plików są oddzielone od siebie spacją. Nie muszę chyba pisać, że cała małpia sztuczka polega na jakimś sensownym wyciągnięciu poszczególnych ścieżek do lokalizacji plików w celu przebiegłego ich wykorzystania do otworzenia ich w programie (o ile program obsługuje pliki tego typu).

Drogi czytelniku, ja jestem zwykłym, drobnym zjadaczem chleba i w związku z powyższym rozwiązałem ten problem na swój własny (no i może trochę pokręcony) sposób, być może ktoś ma lepszą lub wspanialszą koncepcję jego rozwiązania. Tak więc jeśli ktoś ma coś do dodania, niech wypowie się na tym forum, lub zamilknie po wsze czasy. A tera moje rozwiązanie:

GetFileFromCmdLine(LPSTR CmdLine,std::vector<std::string> &fileTable){
        char *end;
        char *begin = strlen(CmdLine) ? CmdLine + 1 : NULL;
        while(begin){
                if(*(begin - 1) == '"'){
                        end = strchr(begin,'"');
                        if(end){
                                *end = NULL;
                                std::string s = begin;
                                fileTable.push_back(s);
                                *end = '"';
                                if(strlen(end) > 1){
                                        begin = end + 3;
                                }else{
                                        begin = NULL;
                                }
                        }else{
                                begin = NULL;
                        }
                }else{
                        end = strchr(begin, ' ');
                        if(end){
                                *end = NULL;
                                std::string s = begin - 1;
                                fileTable.push_back(s);
                                *end = ' ';
                                if(strlen(end) > 1){
                                        begin = end + 2;
                                }else{
                                        begin = NULL;
                                }
                        }else if(strlen(begin)){
                                std::string s = begin - 1;
                                fileTable.push_back(s);
                                begin = NULL;
                        }else{
                                begin = NULL;
                        }
                }
        }
}