Problem opis
Chcę utworzyć aplikację Windows API w C, który renderuje menu i przyciski z napisami w tym samym obszarze non-klient, podobnie jak Firefox części wyciągnięte z DrawThemeBackground na Windows 10 nie są poprawne
w tym celu, już ustalił, że rozwiązanie musi:
- być typu WS_POPUP, w celu menu, aby być wyrównane do górnej
- Przyswojenie spoza strefy klienta (gdzie menu jest renderowany)
- ręcznie uczynić zminimalizować/zmaksymalizować/przyciski zamknięcia
Rozwiązanie musi działać w systemie Windows 7, 8 i 10 (a najlepiej również przyszłe wersje).
Jak to wygląda teraz
I have a test program available on GitHub.
W moim app, mam przesłonięte odpowiednie wydarzenia:
WM_NCCALCSIZE
, WM_NCHITTEST
, WM_NCLBUTTONDOWN
, WM_NCLBUTTONUP
, WM_NCMOUSEMOVE
, WM_NCPAINT
a potem przemalować obszarów non-klienckie na tych wydarzeń: WM_NCACTIVATE
, WM_SETTEXT
Oto przykład tego, jak wykonuję renderowanie:
// globals set elsewhere
RECT customAreaRect, minRect, maxRect, closeRect, coverMenuRect;
BOOL maximized;
// ...
LRESULT OnPaintNCA(HWND hWnd, WPARAM wParam, LPARAM lParam) {
RECT windowRect;
HRGN hRgn = NULL;
GetWindowRect(hWnd, &windowRect);
if (wParam == 1) {
hRgn = CreateRectRgnIndirect(&windowRect);
} else {
hRgn = (HRGN)wParam;
}
if (hRgn) {
// Carve out the area for custom content
HRGN captionButtonRgn = CreateRectRgnIndirect(&customAreaRect);
CombineRgn(hRgn, hRgn, captionButtonRgn, RGN_XOR);
DeleteObject(captionButtonRgn);
// Force default painting for non-client area
LRESULT ret = DefWindowProc(hWnd, WM_NCPAINT, (WPARAM)hRgn, 0);
// black background covering part of menu, behind buttons
HDC hDC = GetWindowDC(hWnd);
FillRect(hDC, &coverMenuRect, (HBRUSH)GetStockObject(BLACK_BRUSH));
HTHEME hTheme = OpenThemeData(hWnd, TEXT("WINDOW"));
DrawThemeBackground(hTheme, hDC, WP_MINBUTTON, partState, minRect, NULL);
DrawThemeBackground(hTheme, hDC, maximized ? WP_RESTOREBUTTON : WP_MAXBUTTON, partState, maxRect, NULL);
DrawThemeBackground(hTheme, hDC, WP_CLOSEBUTTON, partState, closeRect, NULL);
CloseThemeData(hTheme);
}
}
wytopione wynik wygląda tak: Niestety, style używane do części (minimalizować, maksymalizować/przywracania zamknij) wyglądać style for Windows 7/8, a nie natywnego systemu Windows 10 steruje. Szukałem sposobu, aby zrobić to przez kilka dni bez powodzenia. Potrzebuję pomocy w zrozumieniu sposobu renderowania tych przycisków w systemie Windows 10 przy użyciu interfejsu API systemu Windows.
Obecny status (i co starałem tak daleko)
Moje pierwsze przeczucie, że muszę prawidłowo włączyć style wizualne.
Per this article wzywa sprawdzania wersji systemu operacyjnego Windows 8 dostanie chyba że wyraźnie podsystemie Windows 10 poprzez oczywistym. Click here to view my manifest. to działa:
- Przed GetVersionEx powrócił głównym = 6, poboczny = 2, budować = 9200
- Teraz GetVersionEx zwraca główną = 10, minor = 0, budować = 10586
Per the official "Enabling Visual Styles" article, Upewniłem się, że używam Common Controls w wersji 6.
- Dodany łącznik wejściowy dla Comctl32.lib
- nawiązane połączenie do InitCommonControls na starcie programu
- Dodano zależność dla wersji 6 do application manifest
Oto kilka screenów z istotnych ustawienia projektu, które próbowałem:
Inne pomysły
biegnę mało rzeczy spróbować. Przed wyrzuceniem w ręcznik, było kilka rzeczy, które miałem zamiar spróbować:
Pomysł 1: using GetThemeStream który pozwala odzyskać rozmiar/bitmapę do kontroli. złożyć
- aero obciążenia msstyles tak:
HMODULE themeFile = LoadLibraryEx(TEXT("C:\\Windows\\Resources\\Themes\\aero\\aero.msstyles"), NULL, LOAD_LIBRARY_AS_DATAFILE);
- Uzyskaj bitmapy dla części (przycisk minimalizacji, przycisk maksymalizacji, etc) jak tak (przechodząc załadowanego pliku theme) :
GetThemeStream(h, WP_MAXBUTTON, MAXBS_NORMAL, TMT_DISKSTREAM, (void**)&buffer, &bufferSize, themeFile);
- Załaduj bitmapę; wydaje się być w formacie PNG (I nie dostał tak daleko)
- Draw bitmapę
Pomysł 2: skopiuj część dla klienta z ukrytym oknie, które ma powierzchnię napisów (i zminimalizować , zmaksymalizuj, zamknij przyciski).
- Utwórz okno z przyciskami caption i min/max, nigdy go nie aktywując.
- w farbie nie klienckim uzyskać DC do tego okna i uchwycić piksele na min/max przycisku zamykania/
- uznać je za pomocą bitblt
Czy możemy zobaczyć plik manifestu, który utworzyłeś (i połączyć z plikiem binarnym)? Chociaż nie widzę żadnego wskazania, renderowanie motywu było powiązane z manifestem aplikacji. Skąd masz te informacje? – IInspectable
Manifest dodany :) Oto link do strony MSDN, gdzie przeczytałem, że manifest jest powiązany z Visual Styles: https://msdn.microsoft.com/en-us/library/windows/desktop/bb773175(v=vs .85) .aspx –
Pliki manifestu kontrolują wiele aspektów aplikacji (na przykład zgodność z platformami, serwery COM itp.). Link w poprzednim komentarzu wyjaśnia, w jaki sposób kontrolować używanie funkcji Common Controls w wersji 6. Jest to wymagane do używania stylów wizualnych (ale brakuje ich w manifeście). Istnieją również dwa sposoby rozmieszczania plików manifestu: jako zasób osadzony, a także oddzielny plik obok obrazu wykonywalnego. Jeśli oba są obecne, manifest wbudowany ma pierwszeństwo. Czy sprawdziłeś, że plik, który utworzyłeś, jest również tym, który zostanie użyty? – IInspectable