Otwieranie dowolnego pliku z listBoxa

Otwieranie dowolnego pliku z listBoxa
rucksick
  • Rejestracja: dni
  • Ostatnio: dni
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:

Kopiuj
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:

Kopiuj
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ść.

T2
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 164
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?

rucksick
  • Rejestracja: dni
  • Ostatnio: dni
0

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

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

i przekazuję w ten sposób:

Kopiuj
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ę ;)

n0name_l
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 2412
1
Kopiuj
char* _C_STRING_ = (char*)Marshal::StringToHGlobalAnsi(_SYSTEM_STRING_).ToPointer();
T2
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 164
rucksick
  • Rejestracja: dni
  • Ostatnio: dni
0

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

Kopiuj
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ć:

Kopiuj
 
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)

rucksick
  • Rejestracja: dni
  • Ostatnio: dni
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ę :)

Azarien
  • Rejestracja: dni
  • Ostatnio: dni
1
Kopiuj
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#.

Kopiuj
#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:

Kopiuj
#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);
rucksick
  • Rejestracja: dni
  • Ostatnio: dni
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)

rucksick
  • Rejestracja: dni
  • Ostatnio: dni
0

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

Kopiuj
 
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

Kopiuj
 
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

Kopiuj
 
C:\.....

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

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.