Okno wyboru plików w Windows 7 i 8

0

Zawsze mi się wydawało, że w systemie Windows jest jedno standardowe okno wyboru pliku, w każdej technologii tworzenia programu dla Windows (czy to WinApi, czy Qt, czy .NET, czy Delphi) jest jedno polecenie, które uruchamia to okienko.

W wersjach od 98 do XP był jeden standard i wszystko było w porządku. W Windows 7 i 8 to okno zostało ulepszone, szczególnie doceniam niezwykle przydatną możliwość dodawania ulubionych folderów. Okazuje się, że w Win7 i 8 są dwie wersje tego okna, jedno to ulepszone, które spotyka się najczęściej, ale jest jeszcze druga wersja, taka sama, jak ta z XP. Jakby ktoś nie wiedział o co chodzi, załączam zrzuty obu wersji.

Od czego to zależy, która wersja zostanie uruchomiona?

W Qt i .NET jest uruchamiana ta nowa wersja, w Lazarus, o ile się nie mylę, jest stara wersja, ale nie pamiętam.

Schodząc na niski poziom, w WinApi jest po prostu funkcja "GetOpenFileName"
https://msdn.microsoft.com/en-us/library/ms646927%28VS.85%29.aspx
Którą wersję ta funkcja otwiera? Czy może to zależy od jakiegoś parametru?

0

Obstawiam, że chodzi o istnienie odpowiedniego manifestu w zasobach aplikacji.

2

Zawsze mi się wydawało, że w systemie Windows jest jedno standardowe okno wyboru pliku, w każdej technologii tworzenia programu dla Windows (czy to WinApi, czy Qt, czy .NET, czy Delphi) jest jedno polecenie, które uruchamia to okienko.

Niektóre "technologie" nie wyświetlają windowsowego okienka tylko rysują własne. Zawsze mnie to wkurza, jak widzę okastrowane i trudniejsze w użyciu okno bo komuś się nie podobało systemowe.

W Qt i .NET jest uruchamiana ta nowa wersja, w Lazarus, o ile się nie mylę, jest stara wersja, ale nie pamiętam.

Jeżeli widzisz "stare", to zapewne nie jest to okno systemowe tylko jego imitacja.

Od czego to zależy, która wersja zostanie uruchomiona?

Uruchomiona domyślnie zostanie wersja nowa. Jednak niektóre pola struktury OPENFILENAME powodują wyłączenie nowego okna i przywrócenie starego dla kompatybilności. Tak się dzieje np. jeśli użyto flagi OFN_ENABLEHOOK.

Program nie musi mieć manifestu ani używać obiektów "Common Item Dialog" żeby wyświetlić nowe okienko. Standardowe GetOpenFileName wystarczy.

3
#include <windows.h>
UINT_PTR CALLBACK hook(HWND h, UINT u, WPARAM w, LPARAM l)
{
	return FALSE;
}

int main()
{
	char fname[256];
	fname[0] = '\0';
	OPENFILENAME ofn;
	ZeroMemory(&ofn, sizeof(ofn));
	ofn.lStructSize = sizeof(ofn);
	ofn.lpstrFile = fname;
	ofn.nMaxFile = sizeof(fname);
	ofn.Flags = OFN_ENABLEHOOK;
	ofn.lpfnHook = hook;
	GetOpenFileName(&ofn);
}

bez manifestu:
t1.png

z manifestem:
t1m.png


```cpp #include <windows.h> UINT_PTR CALLBACK hook(HWND h, UINT u, WPARAM w, LPARAM l) { return FALSE; }

int main()
{
char fname[256];
fname[0] = '\0';
OPENFILENAME ofn;
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.lpstrFile = fname;
ofn.nMaxFile = sizeof(fname);
ofn.Flags = OFN_ENABLEHOOK | OFN_EXPLORER;
ofn.lpfnHook = hook;
GetOpenFileName(&ofn);
}

bez manifestu:
![t2.png](//static.4programmers.net/uploads/attachment/90163147955784c35c22c2.png)
z manifestem:
![t2m.png](//static.4programmers.net/uploads/attachment/55762223855784da8d63cb.png)
<hr>
```cpp
#include <windows.h>

int main()
{
	char fname[256];
	fname[0] = '\0';
	OPENFILENAME ofn;
	ZeroMemory(&ofn, sizeof(ofn));
	ofn.lStructSize = sizeof(ofn);
	ofn.lpstrFile = fname;
	ofn.nMaxFile = sizeof(fname);
	GetOpenFileName(&ofn);
}

z manifestem i bez:
t3.png

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