Otwieranie dowolnego pliku z listBoxa

0

Witam wszystkich.

Właśnie pracuję nad wakacyjnym projektem-managerem plików.
Pobieram wszystki pliki z wybranego folderu, wyświetlam kolejno w listBoxie. Dobrze działa mi przejście do wybranego folderu i powrót z niego. Mam jednak 2 problemy. Ten najważniejszy polega na tym, że nie wiem jak otworzyć plik o dowolnym rozszerzeniu po podwójnym kliknięciu. Próbowałem kilku metod:

system(nazwa); //wydaje mi się, że działa to dla plików .exe, ale pewności nie mam
ShellExecute(0, "open", nazwa, NULL, NULL, SW_SHOWNORMAL);
System::Diagnostics::Process::Start(nazwa);

jednak wyrzuca mi błedy przy argumentach wejściowych. Czy jest tu ktoś, kto mógłby mi powiedzieć w jaki sposób przekazać nazwę jako argument? Nazwę pobieram sposób następujący:

System::String^ nazwa=listBox1->SelectedItem->ToString();

Próbowałem również przepisać string nazwa do const* char, ale zdaje się, że nie jest to możliwe, ponieważ const nie pozwala na dopisywanie literka po literce w pętli nazwy pliku.

Drugim problemem jest przechodzenie do folderów, które są skrótami, natomiast właściwy folder znajduje się na innej partycji. Tu nie mam żadnego pomysłu.

Prosiłbym o jakieś wskazówki, a nie konkretne rozwiązanie. Ewentualnie gdzie mogę znaleźć informację na ten temat.

Z góry dziękuję! Liczę na wyrozumiałość.

0

A jaki błąd zwraca ci ShellExecute? Czy jako nazwę pliku podajesz samą nazwę z ListBoxa, czy całą ścieżkę do pliku?
Tutaj
http://msdn.microsoft.com/en-us/library/windows/desktop/bb762153%28v=vs.85%29.aspx

jest napisane o dobrej zasadzie odpalania CoInitializeEx() przy starcie programu. Czy próbowałeś z tym?

0

Mam problem z rzutowaniem stringa na const* char. Z Listboxa wyciągam to:

 System::String^ nazwa=listBox1->SelectedItem->ToString();

i przekazuję w ten sposób:

ShellExecute(0, "open", nazwa, NULL, NULL, SW_SHOWNORMAL);

Jednak argumentem nie może chyć uchwyt od stringa i tu pojawia się błąd już przed kompilacją (nie moża przekonwertować trzeciego argumentu ze String do LPCSTR). Jak próbowałem przepisywać to do char'a to wyrzucał błędy podobnej natury czyli coś nie tak przepisywałem.

Dla sprawdzenia samej metody otwierałem wiersz poleceń przy wyborze dowolnego pliku i działało ok, czyli po prostu gubię się gdzieś po drodze. Trochę to różni się od klasycznego c++ :)

Co do CoInitializeEx() to nie próbowałem, ale już spieszę do wujka Google po radę ;)

1
char* _C_STRING_ = (char*)Marshal::StringToHGlobalAnsi(_SYSTEM_STRING_).ToPointer();
0

Niestety jeszcze coś jest źle. Kod wygląda następująco:

System::String^ odczyt=listBox1->SelectedItem->ToString();
char* nazwa = (char*)Marshal::StringToHGlobalAnsi(odczyt).ToPointer();
ShellExecute(0, "open", nazwa, NULL, NULL, SW_SHOWNORMAL);
Marshal::FreeHGlobal(IntPtr(nazwa));
 

A dziwny błąd wyskakujący przy kompilacji ma postać:

 
unresolved token (0A00047B) "extern "C" struct HINSTANCE__ * __stdcall ShellExecuteA(struct HWND__ *,char const *,char const *,char const *,char const *,int)" (?ShellExecuteA@@$$J224YGPAUHINSTANCE__@@PAUHWND__@@PBD111H@Z)

0

Haha, chyba znalazłem już błąd. Sposób w jaki odczytuję nazwę zaznaczonego pliku podaje mi również jego rozmiar czyli wygląda to np. w ten sposób: "jakisPlik 10MB". Mam nadzieję, że teraz sobie poradzę :)

1
System::String^ odczyt=listBox1->SelectedItem->ToString();
char* nazwa = (char*)Marshal::StringToHGlobalAnsi(odczyt).ToPointer();
ShellExecute(0, "open", nazwa, NULL, NULL, SW_SHOWNORMAL);
Marshal::FreeHGlobal(IntPtr(nazwa));

Blee... tak to się robi w C#.

#include <msclr\marshal.h>
...
msclr::interop::marshal_context ctx;
System::String^ odczyt = listBox1->SelectedItem->ToString();
ShellExecuteW(0, L"open", ctx.marshal_as<const wchar_t*>(odczyt), NULL, NULL, SW_SHOWNORMAL);

albo:

#include <msclr\marshal_cppstd.h>
...
std::wstring odczyt = marshal_as<std::wstring>(listBox1->SelectedItem->ToString());
ShellExecuteW(0, L"open", odczyt.c_str(), NULL, NULL, SW_SHOWNORMAL);
0

Dalej bez zmian. Do listBoxa wczytuje się zawartość folderu, ale jak klikam dwukrotnie na pliki to brak reakcji (foldery działają poprawnie). Próbowałem na początek wpisać na sztywno nazwę pliku z rozszerzeniem i bez, z całą ścieżką i bez i brak rezultatu. W linkerze dodałem Shell32.lib $(NOINHERIT)

0

Po przerwie powróciłem do mojego projektu i program działa. Może to przyda się potomnym. Opcja

 
ShellExecute(0, "open",  "sciezka.rozszerzenie" , NULL, NULL, SW_SHOWNORMAL);

była od początku poprawna, błąd polegał na tym, że przy podaniu samej nazwy pliku np

 
image.jpeg

działa dla pliku znajdującego sie w folderze projektu. W przeciwnym przypadku należy podać scieżkę. Mój błąd plegał na tym, że chciałem otworzyć plik np z pulpitu to nie podawałem ścieżki, a gdy już podawałem to.... cóż, wstyd się przyznać, nie podałem dwukropka po wyborze dysku czyli

 
C:\.....

Zagapienie a tyle nerwów :)
Serdecznie dziękuję wszystkim za pomoc. POZADRAWIAM!!

1 użytkowników online, w tym zalogowanych: 0, gości: 1