Mercurial > dwindows
comparison win/dw.c @ 2141:709f8bfa711f
Win: Fix a problem where full dark mode was functioning as forced.
Added sysmenu and icon for the window menu when operating in full dark mode.
I can't seem to convert from a menubar to a popup menu... will keep looking but...
because of this we will need to use the titlebar menu even in light mode when
full dark mode is enabled. When dark mode is disabled or basic will use the
classic menu bar. Also prefix some of the internal dark mode functions.
author | bsmith@81767d24-ef19-dc11-ae90-00e081727c95 |
---|---|
date | Thu, 16 Jul 2020 20:47:15 +0000 |
parents | b6e09fb597aa |
children | 81362474b5e9 |
comparison
equal
deleted
inserted
replaced
2140:b6e09fb597aa | 2141:709f8bfa711f |
---|---|
765 _PreferredAppMode (WINAPI * _SetPreferredAppMode)(_PreferredAppMode) = NULL; | 765 _PreferredAppMode (WINAPI * _SetPreferredAppMode)(_PreferredAppMode) = NULL; |
766 BOOL (WINAPI * _IsDarkModeAllowedForWindow)(HWND) = NULL; | 766 BOOL (WINAPI * _IsDarkModeAllowedForWindow)(HWND) = NULL; |
767 BOOL (WINAPI * _ShouldSystemUseDarkMode)(VOID) = NULL; | 767 BOOL (WINAPI * _ShouldSystemUseDarkMode)(VOID) = NULL; |
768 BOOL (WINAPI* _SetWindowCompositionAttribute)(HWND, _WINDOWCOMPOSITIONATTRIBDATA *) = NULL; | 768 BOOL (WINAPI* _SetWindowCompositionAttribute)(HWND, _WINDOWCOMPOSITIONATTRIBDATA *) = NULL; |
769 | 769 |
770 BOOL IsHighContrast(VOID) | 770 BOOL _DW_IsHighContrast(VOID) |
771 { | 771 { |
772 HIGHCONTRASTW highContrast = { sizeof(highContrast) }; | 772 HIGHCONTRASTW highContrast = { sizeof(highContrast) }; |
773 if(SystemParametersInfoW(SPI_GETHIGHCONTRAST, sizeof(highContrast), &highContrast, FALSE)) | 773 if(SystemParametersInfoW(SPI_GETHIGHCONTRAST, sizeof(highContrast), &highContrast, FALSE)) |
774 return highContrast.dwFlags & HCF_HIGHCONTRASTON; | 774 return highContrast.dwFlags & HCF_HIGHCONTRASTON; |
775 return FALSE; | 775 return FALSE; |
776 } | 776 } |
777 | 777 |
778 /* Our own ShouldAppsUseDarkMode() that handles the forced option */ | 778 /* Our own ShouldAppsUseDarkMode() that handles the forced option */ |
779 BOOL _DW_ShouldAppsUseDarkMode(void) | 779 BOOL _DW_ShouldAppsUseDarkMode(void) |
780 { | 780 { |
781 if(_DW_DARK_MODE_ALLOWED == DW_DARK_MODE_FULL) | 781 if(_DW_DARK_MODE_ALLOWED == DW_DARK_MODE_FORCED) |
782 return TRUE; | 782 return TRUE; |
783 return (_ShouldAppsUseDarkMode() && !IsHighContrast()); | 783 return (_ShouldAppsUseDarkMode() && !_DW_IsHighContrast()); |
784 } | 784 } |
785 | 785 |
786 void _dw_init_dark_mode(void) | 786 void _dw_init_dark_mode(void) |
787 { | 787 { |
788 if(_DW_DARK_MODE_ALLOWED && dwVersion && huxtheme) | 788 if(_DW_DARK_MODE_ALLOWED && dwVersion && huxtheme) |
821 | 821 |
822 /* Return a margins struct based on the calculated window rect */ | 822 /* Return a margins struct based on the calculated window rect */ |
823 MARGINS _dw_rect_to_margins(RECT rect) | 823 MARGINS _dw_rect_to_margins(RECT rect) |
824 { | 824 { |
825 /* Left, Right, Top, Bottom */ | 825 /* Left, Right, Top, Bottom */ |
826 MARGINS mar = { rect.left, rect.right, rect.top, rect.bottom }, none = {0}; | 826 MARGINS mar = { 1, 1, rect.top, 1 }, none = {0}; |
827 | 827 |
828 if(_DW_DARK_MODE_ALLOWED > DW_DARK_MODE_BASIC & _DW_DARK_MODE_ENABLED) | 828 if(_DW_DARK_MODE_ALLOWED > DW_DARK_MODE_BASIC & _DW_DARK_MODE_ENABLED) |
829 return mar; | 829 return mar; |
830 return none; | 830 return none; |
831 } | 831 } |
832 | 832 |
833 BOOL _CanThemeWindow(HWND window) | 833 BOOL _DW_CanThemeWindow(HWND window) |
834 { | 834 { |
835 TCHAR tmpbuf[100] = {0}; | 835 TCHAR tmpbuf[100] = {0}; |
836 LONG_PTR style = GetWindowLongPtr(window, GWL_STYLE); | 836 LONG_PTR style = GetWindowLongPtr(window, GWL_STYLE); |
837 | 837 |
838 GetClassName(window, tmpbuf, 99); | 838 GetClassName(window, tmpbuf, 99); |
855 } | 855 } |
856 #endif | 856 #endif |
857 return TRUE; | 857 return TRUE; |
858 } | 858 } |
859 | 859 |
860 BOOL AllowDarkModeForWindow(HWND window, BOOL allow) | 860 BOOL _DW_AllowDarkModeForWindow(HWND window, BOOL allow) |
861 { | 861 { |
862 if(_DW_DARK_MODE_SUPPORTED) | 862 if(_DW_DARK_MODE_SUPPORTED) |
863 { | 863 { |
864 if(_CanThemeWindow(window)) | 864 if(_DW_CanThemeWindow(window)) |
865 { | 865 { |
866 if(_DW_DARK_MODE_ALLOWED > DW_DARK_MODE_BASIC) | 866 if(_DW_DARK_MODE_ALLOWED > DW_DARK_MODE_BASIC) |
867 { | 867 { |
868 if(_DW_DARK_MODE_ENABLED) | 868 if(_DW_DARK_MODE_ENABLED) |
869 _SetWindowTheme(window, L"DarkMode_Explorer", NULL); | 869 _SetWindowTheme(window, L"DarkMode_Explorer", NULL); |
874 return _AllowDarkModeForWindow(window, allow); | 874 return _AllowDarkModeForWindow(window, allow); |
875 } | 875 } |
876 return FALSE; | 876 return FALSE; |
877 } | 877 } |
878 | 878 |
879 BOOL IsColorSchemeChangeMessage(LPARAM lParam) | 879 BOOL _DW_IsColorSchemeChangeMessage(LPARAM lParam) |
880 { | 880 { |
881 BOOL is = FALSE; | 881 BOOL is = FALSE; |
882 if(lParam && _wcsicmp((LPCWCH)lParam, L"ImmersiveColorSet") == 0) | 882 if(lParam && _wcsicmp((LPCWCH)lParam, L"ImmersiveColorSet") == 0) |
883 { | 883 { |
884 _RefreshImmersiveColorPolicyState(); | 884 _RefreshImmersiveColorPolicyState(); |
886 } | 886 } |
887 _GetIsImmersiveColorUsingHighContrast(IHCM_REFRESH); | 887 _GetIsImmersiveColorUsingHighContrast(IHCM_REFRESH); |
888 return is; | 888 return is; |
889 } | 889 } |
890 | 890 |
891 void RefreshTitleBarThemeColor(HWND window) | 891 void _DW_RefreshTitleBarThemeColor(HWND window) |
892 { | 892 { |
893 BOOL dark = FALSE; | 893 BOOL dark = FALSE; |
894 if (_IsDarkModeAllowedForWindow(window) && _DW_ShouldAppsUseDarkMode()) | 894 if (_IsDarkModeAllowedForWindow(window) && _DW_ShouldAppsUseDarkMode()) |
895 dark = TRUE; | 895 dark = TRUE; |
896 if(HIWORD(dwVersion) < 18362) | 896 if(HIWORD(dwVersion) < 18362) |
906 /* Call this on a window to apply the style */ | 906 /* Call this on a window to apply the style */ |
907 BOOL CALLBACK _dw_set_child_window_theme(HWND window, LPARAM lParam) | 907 BOOL CALLBACK _dw_set_child_window_theme(HWND window, LPARAM lParam) |
908 { | 908 { |
909 if(_DW_DARK_MODE_SUPPORTED) | 909 if(_DW_DARK_MODE_SUPPORTED) |
910 { | 910 { |
911 AllowDarkModeForWindow(window, _DW_DARK_MODE_ENABLED); | 911 _DW_AllowDarkModeForWindow(window, _DW_DARK_MODE_ENABLED); |
912 SendMessageW(window, WM_THEMECHANGED, 0, 0); | 912 SendMessageW(window, WM_THEMECHANGED, 0, 0); |
913 } | 913 } |
914 return TRUE; | 914 return TRUE; |
915 } | 915 } |
916 | 916 |
956 HBITMAP hbmOld = (HBITMAP)SelectObject(hdcPaint, hbm); | 956 HBITMAP hbmOld = (HBITMAP)SelectObject(hdcPaint, hbm); |
957 LOGFONT lgFont; | 957 LOGFONT lgFont; |
958 HFONT hFontOld = NULL; | 958 HFONT hFontOld = NULL; |
959 RECT rcPaint = rcClient; | 959 RECT rcPaint = rcClient; |
960 TCHAR *tempbuf; | 960 TCHAR *tempbuf; |
961 HICON icon = (HICON)SendMessage(hWnd, WM_GETICON, ICON_SMALL2, 0); | |
962 ColorInfo *cinfo = (ColorInfo *)GetWindowLongPtr(hWnd, GWLP_USERDATA); | |
963 LONG_PTR style = GetWindowLongPtr(hWnd, GWL_STYLE); | |
961 int len; | 964 int len; |
962 DWORD nColor = _GetImmersiveColorFromColorSetEx(_GetImmersiveUserColorSetPreference(FALSE, FALSE), | 965 DWORD nColor = _GetImmersiveColorFromColorSetEx(_GetImmersiveUserColorSetPreference(FALSE, FALSE), |
963 _GetImmersiveColorTypeFromName(L"ImmersiveApplicationText"), FALSE, 0); | 966 _GetImmersiveColorTypeFromName(L"ImmersiveApplicationText"), FALSE, 0); |
964 | 967 |
965 /* Setup the theme drawing options. */ | 968 /* Setup the theme drawing options. */ |
980 if((tempbuf = _alloca(len * sizeof(TCHAR)))) | 983 if((tempbuf = _alloca(len * sizeof(TCHAR)))) |
981 GetWindowText(hWnd, tempbuf, len); | 984 GetWindowText(hWnd, tempbuf, len); |
982 rcPaint.top += 8; | 985 rcPaint.top += 8; |
983 rcPaint.right -= 125; | 986 rcPaint.right -= 125; |
984 rcPaint.left += 8; | 987 rcPaint.left += 8; |
988 if(style & WS_SYSMENU) | |
989 rcPaint.left += 24; | |
990 if(cinfo && cinfo->hmenu) | |
991 rcPaint.left += 24; | |
985 rcPaint.bottom = 50; | 992 rcPaint.bottom = 50; |
986 _DrawThemeTextEx(hTheme, | 993 _DrawThemeTextEx(hTheme, |
987 hdcPaint, | 994 hdcPaint, |
988 0, 0, | 995 0, 0, |
989 tempbuf ? tempbuf : TEXT("<no title>"), | 996 tempbuf ? tempbuf : TEXT("<no title>"), |
990 -1, | 997 -1, |
991 DT_LEFT | DT_WORD_ELLIPSIS, | 998 DT_LEFT | DT_WORD_ELLIPSIS, |
992 &rcPaint, | 999 &rcPaint, |
993 &DttOpts); | 1000 &DttOpts); |
994 | 1001 |
1002 if(style & WS_SYSMENU) | |
1003 { | |
1004 /* Draw the application icon sysmenu */ | |
1005 DrawIconEx(hdcPaint, 8, 8, icon ? icon : LoadIcon(NULL, MAKEINTRESOURCE(32512)), 16, 16, 0, NULL, DI_NORMAL); | |
1006 } | |
1007 if(cinfo && cinfo->hmenu) | |
1008 { | |
1009 /* Draw an icon to use as a menu click location */ | |
1010 DrawIconEx(hdcPaint, 32, 8, LoadIcon(NULL, MAKEINTRESOURCE(32516)), 16, 16, 0, NULL, DI_NORMAL); | |
1011 } | |
1012 | |
995 /* Blit text to the frame. */ | 1013 /* Blit text to the frame. */ |
996 BitBlt(hdc, 0, 0, cx, cy, hdcPaint, 0, 0, SRCCOPY); | 1014 BitBlt(hdc, 0, 0, cx, cy, hdcPaint, 0, 0, SRCCOPY); |
997 | 1015 |
998 SelectObject(hdcPaint, hbmOld); | 1016 SelectObject(hdcPaint, hbmOld); |
999 if(hFontOld) | 1017 if(hFontOld) |
1000 { | |
1001 SelectObject(hdcPaint, hFontOld); | 1018 SelectObject(hdcPaint, hFontOld); |
1002 } | |
1003 DeleteObject(hbm); | 1019 DeleteObject(hbm); |
1004 } | 1020 } |
1005 DeleteDC(hdcPaint); | 1021 DeleteDC(hdcPaint); |
1006 } | 1022 } |
1007 _CloseThemeData(hTheme); | 1023 _CloseThemeData(hTheme); |
2127 #ifdef DARK_MODE_TITLEBAR_MENU | 2143 #ifdef DARK_MODE_TITLEBAR_MENU |
2128 /* Expand the client area into the titlebar so we can draw our alternate dark mode button | 2144 /* Expand the client area into the titlebar so we can draw our alternate dark mode button |
2129 * which when clicked will display the window's menubar menu. Since the menubar cannot be | 2145 * which when clicked will display the window's menubar menu. Since the menubar cannot be |
2130 * made dark, hide it and add the button to the titlebar instead. | 2146 * made dark, hide it and add the button to the titlebar instead. |
2131 */ | 2147 */ |
2132 if(msg == WM_NCCALCSIZE && mp2 && _DW_DARK_MODE_ENABLED && _DW_DARK_MODE_ALLOWED > DW_DARK_MODE_BASIC) | 2148 if(msg == WM_NCCALCSIZE && mp2 && _DW_DARK_MODE_SUPPORTED && _DW_DARK_MODE_ALLOWED > DW_DARK_MODE_BASIC) |
2133 { | 2149 { |
2134 ColorInfo *cinfo = _dw_window_get_cinfo(hWnd); | 2150 ColorInfo *cinfo = _dw_window_get_cinfo(hWnd); |
2135 | 2151 |
2136 if(cinfo) | 2152 if(cinfo) |
2137 { | 2153 { |
2141 sz->rgrc[0].right -= cinfo->rect.right; | 2157 sz->rgrc[0].right -= cinfo->rect.right; |
2142 sz->rgrc[0].bottom -= cinfo->rect.bottom; | 2158 sz->rgrc[0].bottom -= cinfo->rect.bottom; |
2143 return 0; | 2159 return 0; |
2144 } | 2160 } |
2145 } | 2161 } |
2146 else if(msg == WM_NCPAINT && _DW_DARK_MODE_ENABLED && _DW_DARK_MODE_ALLOWED > DW_DARK_MODE_BASIC) | 2162 else if(msg == WM_NCPAINT && _DW_DARK_MODE_SUPPORTED && _DW_DARK_MODE_ALLOWED > DW_DARK_MODE_BASIC) |
2147 { | 2163 { |
2148 /* Handle close/minimize/maximize/help button */ | 2164 /* Handle close/minimize/maximize/help button */ |
2149 LRESULT lResult; | 2165 LRESULT lResult; |
2150 | 2166 |
2151 if(_DwmDefWindowProc && _DwmDefWindowProc(hWnd, msg, mp1, mp2, &lResult)) | 2167 if(_DwmDefWindowProc && _DwmDefWindowProc(hWnd, msg, mp1, mp2, &lResult)) |
2152 return lResult; | 2168 return lResult; |
2153 } | 2169 } |
2154 else if(msg == WM_NCHITTEST && _DW_DARK_MODE_ENABLED && _DW_DARK_MODE_ALLOWED > DW_DARK_MODE_BASIC) | 2170 else if(msg == WM_NCHITTEST && _DW_DARK_MODE_SUPPORTED && _DW_DARK_MODE_ALLOWED > DW_DARK_MODE_BASIC) |
2155 { | 2171 { |
2156 /* Handle close/minimize/maximize/help button */ | 2172 /* Handle close/minimize/maximize/help button */ |
2157 LRESULT lResult; | 2173 LRESULT lResult; |
2158 | 2174 |
2159 if(_DwmDefWindowProc && _DwmDefWindowProc(hWnd, msg, mp1, mp2, &lResult)) | 2175 if(_DwmDefWindowProc && _DwmDefWindowProc(hWnd, msg, mp1, mp2, &lResult)) |
2168 if(cinfo) | 2184 if(cinfo) |
2169 { | 2185 { |
2170 POINT pt = { LOWORD(mp2), HIWORD(mp2) }; | 2186 POINT pt = { LOWORD(mp2), HIWORD(mp2) }; |
2171 | 2187 |
2172 ScreenToClient(hWnd, &pt); | 2188 ScreenToClient(hWnd, &pt); |
2173 if (pt.y < cinfo->rect.top) return HTTOP; | 2189 /* The top border should be the same as the bottom. */ |
2174 /*if (pt.y < margins->cyTopHeight) return HTCAPTION;*/ | 2190 if (pt.y < cinfo->rect.bottom) return HTTOP; |
2191 /* The caption is any part of the top besides the border */ | |
2192 if (pt.y < cinfo->rect.top) | |
2193 { | |
2194 ColorInfo *cinfo = (ColorInfo *)GetWindowLongPtr(hWnd, GWLP_USERDATA); | |
2195 LONG_PTR style = GetWindowLongPtr(hWnd, GWL_STYLE); | |
2196 int pos = 32; | |
2197 | |
2198 if(style & WS_SYSMENU) | |
2199 { | |
2200 if(pt.x < (pos + cinfo->rect.left)) | |
2201 return HTSYSMENU; | |
2202 pos += 24; | |
2203 } | |
2204 if(cinfo && cinfo->hmenu) | |
2205 { | |
2206 if(pt.x < (pos + cinfo->rect.left)) | |
2207 { | |
2208 if(cinfo->hmenu) | |
2209 { | |
2210 TrackPopupMenu(cinfo->hmenu, 0, LOWORD(mp2), HIWORD(mp2), 0, hWnd, NULL); | |
2211 return HTNOWHERE; | |
2212 } | |
2213 } | |
2214 } | |
2215 return HTCAPTION; | |
2216 } | |
2175 } | 2217 } |
2176 } | 2218 } |
2177 return lResult; | 2219 return lResult; |
2220 } | |
2221 else if(msg == WM_ACTIVATE && _DW_DARK_MODE_SUPPORTED && _DW_DARK_MODE_ALLOWED > DW_DARK_MODE_BASIC) | |
2222 { | |
2223 RECT r; | |
2224 GetWindowRect(hWnd, &r); | |
2225 SetWindowPos(hWnd, NULL, r.left, r.top, RECTWIDTH(r), RECTHEIGHT(r), SWP_FRAMECHANGED); | |
2226 } | |
2227 else if(msg == WM_PAINT && _DW_DARK_MODE_ALLOWED > DW_DARK_MODE_BASIC && _DW_DARK_MODE_SUPPORTED && GetParent(hWnd) == HWND_DESKTOP) | |
2228 { | |
2229 PAINTSTRUCT ps; | |
2230 HDC hdc = BeginPaint(hWnd, &ps); | |
2231 _DW_DrawDarkModeTitleBar(hWnd, hdc); | |
2232 EndPaint(hWnd, &ps); | |
2178 } | 2233 } |
2179 #endif | 2234 #endif |
2180 | 2235 |
2181 /* Deal with translating some messages */ | 2236 /* Deal with translating some messages */ |
2182 if (msg == WM_USER+2) | 2237 if (msg == WM_USER+2) |
2376 { | 2431 { |
2377 PAINTSTRUCT ps; | 2432 PAINTSTRUCT ps; |
2378 DWExpose exp; | 2433 DWExpose exp; |
2379 int (DWSIGNAL *exposefunc)(HWND, DWExpose *, void *) = tmp->signalfunction; | 2434 int (DWSIGNAL *exposefunc)(HWND, DWExpose *, void *) = tmp->signalfunction; |
2380 | 2435 |
2381 #ifdef DARK_MODE_TITLEBAR_MENU | |
2382 if(_DW_DARK_MODE_ALLOWED > DW_DARK_MODE_BASIC && _DW_DARK_MODE_ENABLED && GetParent(hWnd) == HWND_DESKTOP) | |
2383 { | |
2384 HDC hdc = BeginPaint(hWnd, &ps); | |
2385 _DW_DrawDarkModeTitleBar(hWnd, hdc); | |
2386 EndPaint(hWnd, &ps); | |
2387 } | |
2388 #endif | |
2389 if ( hWnd == tmp->window ) | 2436 if ( hWnd == tmp->window ) |
2390 { | 2437 { |
2391 BeginPaint(hWnd, &ps); | 2438 BeginPaint(hWnd, &ps); |
2392 exp.x = ps.rcPaint.left; | 2439 exp.x = ps.rcPaint.left; |
2393 exp.y = ps.rcPaint.top; | 2440 exp.y = ps.rcPaint.top; |
2725 } | 2772 } |
2726 } | 2773 } |
2727 break; | 2774 break; |
2728 case WM_SETTINGCHANGE: | 2775 case WM_SETTINGCHANGE: |
2729 { | 2776 { |
2730 if(_DW_DARK_MODE_SUPPORTED && IsColorSchemeChangeMessage(mp2)) | 2777 if(_DW_DARK_MODE_SUPPORTED && _DW_IsColorSchemeChangeMessage(mp2)) |
2731 { | 2778 { |
2732 _DW_DARK_MODE_ENABLED = _DW_ShouldAppsUseDarkMode(); | 2779 _DW_DARK_MODE_ENABLED = _DW_ShouldAppsUseDarkMode(); |
2733 | 2780 |
2734 RefreshTitleBarThemeColor(hWnd); | 2781 _DW_RefreshTitleBarThemeColor(hWnd); |
2735 _dw_set_child_window_theme(hWnd, 0); | 2782 _dw_set_child_window_theme(hWnd, 0); |
2736 EnumChildWindows(hWnd, _dw_set_child_window_theme, 0); | 2783 EnumChildWindows(hWnd, _dw_set_child_window_theme, 0); |
2737 #ifdef DARK_MODE_TITLEBAR_MENU | |
2738 if(_DW_DARK_MODE_ALLOWED > DW_DARK_MODE_BASIC && _DW_DARK_MODE_ENABLED) | |
2739 SetMenu(hWnd, NULL); | |
2740 else | |
2741 { | |
2742 HMENU menu = (HMENU)dw_window_get_data(hWnd, "_dw_menu"); | |
2743 SetMenu(hWnd, menu); | |
2744 } | |
2745 #endif | |
2746 } | 2784 } |
2747 } | 2785 } |
2748 break; | 2786 break; |
2749 #endif | 2787 #endif |
2750 #ifdef AEROGLASS1 | 2788 #ifdef AEROGLASS1 |
2771 EndPaint(hWnd, &ps); | 2809 EndPaint(hWnd, &ps); |
2772 } | 2810 } |
2773 break; | 2811 break; |
2774 case WM_SIZE: | 2812 case WM_SIZE: |
2775 { | 2813 { |
2776 static int lastx = -1, lasty = -1; | |
2777 static HWND lasthwnd = 0; | |
2778 int x = LOWORD(mp2), y = HIWORD(mp2); | 2814 int x = LOWORD(mp2), y = HIWORD(mp2); |
2779 | 2815 |
2780 if(lastx != x || lasty != y || lasthwnd != hWnd) | 2816 Box *mybox = (Box *)GetWindowLongPtr(hWnd, GWLP_USERDATA); |
2817 | |
2818 if(mybox && mybox->count) | |
2781 { | 2819 { |
2782 Box *mybox = (Box *)GetWindowLongPtr(hWnd, GWLP_USERDATA); | 2820 static int lastx = -1, lasty = -1; |
2783 | 2821 static HWND lasthwnd = 0; |
2784 if(mybox && mybox->count) | 2822 int xborder = 0, yborder = 0; |
2823 | |
2824 #ifdef DARK_MODE_TITLEBAR_MENU | |
2825 if(_DW_DARK_MODE_ALLOWED > DW_DARK_MODE_BASIC && _DW_DARK_MODE_SUPPORTED) | |
2785 { | 2826 { |
2786 int xborder = 0, yborder = 0; | 2827 ColorInfo *cinfo = _dw_window_get_cinfo(hWnd); |
2787 | 2828 |
2829 if(cinfo) | |
2830 { | |
2831 x -= (cinfo->rect.left + cinfo->rect.right); | |
2832 y -= (cinfo->rect.top + cinfo->rect.bottom); | |
2833 xborder = cinfo->rect.left; | |
2834 yborder = cinfo->rect.top; | |
2835 } | |
2836 } | |
2837 #endif | |
2838 | |
2839 /* Simple check to prevent duplicate sizing calls */ | |
2840 if(lastx != x || lasty != y || lasthwnd != hWnd) | |
2841 { | |
2788 lastx = x; | 2842 lastx = x; |
2789 lasty = y; | 2843 lasty = y; |
2790 lasthwnd = hWnd; | 2844 lasthwnd = hWnd; |
2791 | |
2792 #ifdef DARK_MODE_TITLEBAR_MENU | |
2793 if(_DW_DARK_MODE_ALLOWED > DW_DARK_MODE_BASIC && _DW_DARK_MODE_ENABLED) | |
2794 { | |
2795 ColorInfo *cinfo = _dw_window_get_cinfo(hWnd); | |
2796 | |
2797 if(cinfo) | |
2798 { | |
2799 x -= (cinfo->rect.left + cinfo->rect.right); | |
2800 y -= (cinfo->rect.top + cinfo->rect.bottom); | |
2801 xborder = cinfo->rect.left; | |
2802 yborder = cinfo->rect.top; | |
2803 } | |
2804 } | |
2805 #endif | |
2806 | 2845 |
2807 ShowWindow(mybox->items[0].hwnd, SW_HIDE); | 2846 ShowWindow(mybox->items[0].hwnd, SW_HIDE); |
2808 _do_resize(mybox, x, y, xborder, yborder); | 2847 _do_resize(mybox, x, y, xborder, yborder); |
2809 ShowWindow(mybox->items[0].hwnd, SW_SHOW); | 2848 ShowWindow(mybox->items[0].hwnd, SW_SHOW); |
2810 return 0; | 2849 return 0; |
2903 } | 2942 } |
2904 break; | 2943 break; |
2905 case WM_DESTROY: | 2944 case WM_DESTROY: |
2906 { | 2945 { |
2907 HMENU menu = GetMenu(hWnd); | 2946 HMENU menu = GetMenu(hWnd); |
2908 | 2947 ColorInfo *cinfo = _dw_window_get_cinfo(hWnd); |
2909 if(menu) | 2948 |
2949 if(menu || (cinfo && (menu = cinfo->hmenu))) | |
2910 _free_menu_data(menu); | 2950 _free_menu_data(menu); |
2911 | 2951 |
2912 /* Free memory before destroying */ | 2952 /* Free memory before destroying */ |
2913 _free_window_memory(hWnd, 0); | 2953 _free_window_memory(hWnd, 0); |
2914 EnumChildWindows(hWnd, _free_window_memory, 0); | 2954 EnumChildWindows(hWnd, _free_window_memory, 0); |
5022 { | 5062 { |
5023 /* Try to enable dark mode support if our OS supports it */ | 5063 /* Try to enable dark mode support if our OS supports it */ |
5024 _dw_set_child_window_theme(handle, 0); | 5064 _dw_set_child_window_theme(handle, 0); |
5025 EnumChildWindows(handle, _dw_set_child_window_theme, 0); | 5065 EnumChildWindows(handle, _dw_set_child_window_theme, 0); |
5026 if(GetParent(handle) == HWND_DESKTOP) | 5066 if(GetParent(handle) == HWND_DESKTOP) |
5027 RefreshTitleBarThemeColor(handle); | 5067 _DW_RefreshTitleBarThemeColor(handle); |
5028 } | 5068 } |
5029 #endif | 5069 #endif |
5030 | 5070 |
5031 GetClientRect(handle, &rect); | 5071 GetClientRect(handle, &rect); |
5032 | 5072 |
5830 SetParent(hwndframe, hwndOwner); | 5870 SetParent(hwndframe, hwndOwner); |
5831 | 5871 |
5832 #ifdef AEROGLASS | 5872 #ifdef AEROGLASS |
5833 /* Determine the borders of the default window frame */ | 5873 /* Determine the borders of the default window frame */ |
5834 AdjustWindowRectEx(&(newbox->cinfo.rect), flStyle, FALSE, 0); | 5874 AdjustWindowRectEx(&(newbox->cinfo.rect), flStyle, FALSE, 0); |
5835 newbox->cinfo.rect.right = newbox->cinfo.rect.left = newbox->cinfo.rect.bottom = 1; | 5875 newbox->cinfo.rect.left = newbox->cinfo.rect.right = newbox->cinfo.rect.bottom = 1; |
5836 newbox->cinfo.rect.top *= -1; | 5876 newbox->cinfo.rect.top *= -1; |
5837 | 5877 |
5838 if(flStyle & DW_FCF_COMPOSITED) | 5878 if(flStyle & DW_FCF_COMPOSITED) |
5839 { | 5879 { |
5840 /* Attempt to enable Aero glass background on the entire window */ | 5880 /* Attempt to enable Aero glass background on the entire window */ |
6236 */ | 6276 */ |
6237 HMENUI API dw_menubar_new(HWND location) | 6277 HMENUI API dw_menubar_new(HWND location) |
6238 { | 6278 { |
6239 HMENUI tmp; | 6279 HMENUI tmp; |
6240 MENUINFO mi; | 6280 MENUINFO mi; |
6241 | 6281 ColorInfo *cinfo = _dw_window_get_cinfo(location); |
6282 | |
6283 if(!cinfo) | |
6284 return NULL; | |
6285 | |
6286 #ifdef DARK_MODE_TITLEBAR_MENU | |
6287 if(_DW_DARK_MODE_ALLOWED > DW_DARK_MODE_BASIC && _DW_DARK_MODE_SUPPORTED) | |
6288 tmp = (HMENUI)CreatePopupMenu(); | |
6289 else | |
6290 #else | |
6242 tmp = (HMENUI)CreateMenu(); | 6291 tmp = (HMENUI)CreateMenu(); |
6292 #endif | |
6243 | 6293 |
6244 mi.cbSize = sizeof(MENUINFO); | 6294 mi.cbSize = sizeof(MENUINFO); |
6245 mi.fMask = MIM_MENUDATA; | 6295 mi.fMask = MIM_MENUDATA; |
6246 mi.dwMenuData = (ULONG_PTR)1; | 6296 mi.dwMenuData = (ULONG_PTR)1; |
6247 | 6297 |
6248 SetMenuInfo( (HMENU)tmp, &mi ); | 6298 SetMenuInfo((HMENU)tmp, &mi); |
6249 | 6299 |
6250 dw_window_set_data(location, "_dw_menu", (void *)tmp); | 6300 cinfo->hmenu = (HMENU)tmp; |
6251 | 6301 |
6252 #ifdef DARK_MODE_TITLEBAR_MENU | 6302 #ifdef DARK_MODE_TITLEBAR_MENU |
6253 if(!(_DW_DARK_MODE_ALLOWED > DW_DARK_MODE_BASIC && _DW_DARK_MODE_ENABLED)) | 6303 if(!(_DW_DARK_MODE_ALLOWED > DW_DARK_MODE_BASIC && _DW_DARK_MODE_SUPPORTED)) |
6254 #endif | 6304 #endif |
6255 SetMenu(location, (HMENU)tmp); | 6305 SetMenu(location, (HMENU)tmp); |
6256 return location; | 6306 return location; |
6257 } | 6307 } |
6258 | 6308 |
6266 if(menu) | 6316 if(menu) |
6267 { | 6317 { |
6268 HMENU mymenu = (HMENU)*menu; | 6318 HMENU mymenu = (HMENU)*menu; |
6269 | 6319 |
6270 if(IsWindow((HWND)mymenu) && !IsMenu(mymenu)) | 6320 if(IsWindow((HWND)mymenu) && !IsMenu(mymenu)) |
6271 mymenu = (HMENU)dw_window_get_data((HWND)mymenu, "_dw_menu"); | 6321 { |
6272 if(IsMenu(mymenu)) | 6322 ColorInfo *cinfo = _dw_window_get_cinfo((HWND)mymenu); |
6323 | |
6324 if(cinfo) | |
6325 mymenu = cinfo->hmenu; | |
6326 } | |
6327 if(IsMenu(mymenu)) | |
6273 DestroyMenu(mymenu); | 6328 DestroyMenu(mymenu); |
6274 } | 6329 } |
6275 } | 6330 } |
6276 | 6331 |
6277 /* Internal function to make sure menu ID isn't in use */ | 6332 /* Internal function to make sure menu ID isn't in use */ |
6309 | 6364 |
6310 /* | 6365 /* |
6311 * Check if this is a menubar; if so get the menu object | 6366 * Check if this is a menubar; if so get the menu object |
6312 * for the menubar | 6367 * for the menubar |
6313 */ | 6368 */ |
6314 if (IsWindow(menux) && !IsMenu(mymenu)) | 6369 if(IsWindow(menux) && !IsMenu(mymenu)) |
6315 mymenu = (HMENU)dw_window_get_data(menux, "_dw_menu"); | 6370 { |
6371 ColorInfo *cinfo = _dw_window_get_cinfo((HWND)menux); | |
6372 | |
6373 if(cinfo) | |
6374 mymenu = cinfo->hmenu; | |
6375 else | |
6376 return NULL; | |
6377 } | |
6316 | 6378 |
6317 memset( &mii, 0, sizeof(mii) ); | 6379 memset( &mii, 0, sizeof(mii) ); |
6318 mii.cbSize = sizeof(MENUITEMINFO); | 6380 mii.cbSize = sizeof(MENUITEMINFO); |
6319 mii.fMask = MIIM_ID | MIIM_SUBMENU | MIIM_TYPE | MIIM_STATE; | 6381 mii.fMask = MIIM_ID | MIIM_SUBMENU | MIIM_TYPE | MIIM_STATE; |
6320 | 6382 |
6428 { | 6490 { |
6429 MENUITEMINFO mii; | 6491 MENUITEMINFO mii; |
6430 HMENU mymenu = (HMENU)menux; | 6492 HMENU mymenu = (HMENU)menux; |
6431 char buffer[30]; | 6493 char buffer[30]; |
6432 | 6494 |
6433 if (IsWindow(menux) && !IsMenu(mymenu)) | 6495 if(IsWindow(menux) && !IsMenu(mymenu)) |
6434 mymenu = (HMENU)dw_window_get_data(menux, "_dw_menu"); | 6496 { |
6497 ColorInfo *cinfo = _dw_window_get_cinfo((HWND)menux); | |
6498 | |
6499 if(cinfo) | |
6500 mymenu = cinfo->hmenu; | |
6501 else | |
6502 return; | |
6503 } | |
6435 | 6504 |
6436 /* | 6505 /* |
6437 * Get the current state of the menu item in case it already has some other state set on it | 6506 * Get the current state of the menu item in case it already has some other state set on it |
6438 */ | 6507 */ |
6439 memset( &mii, 0, sizeof(mii) ); | 6508 memset( &mii, 0, sizeof(mii) ); |
6459 * menu: The handle to the existing menu. | 6528 * menu: The handle to the existing menu. |
6460 * id: Menuitem id. | 6529 * id: Menuitem id. |
6461 * flags: DW_MIS_ENABLED/DW_MIS_DISABLED | 6530 * flags: DW_MIS_ENABLED/DW_MIS_DISABLED |
6462 * DW_MIS_CHECKED/DW_MIS_UNCHECKED | 6531 * DW_MIS_CHECKED/DW_MIS_UNCHECKED |
6463 */ | 6532 */ |
6464 void API dw_menu_item_set_state( HMENUI menux, unsigned long id, unsigned long state) | 6533 void API dw_menu_item_set_state(HMENUI menux, unsigned long id, unsigned long state) |
6465 { | 6534 { |
6466 MENUITEMINFO mii; | 6535 MENUITEMINFO mii; |
6467 HMENU mymenu = (HMENU)menux; | 6536 HMENU mymenu = (HMENU)menux; |
6468 char buffer1[31] = {0},buffer2[31] = {0}; | 6537 char buffer1[31] = {0}, buffer2[31] = {0}; |
6469 int check; | 6538 int check; |
6470 int disabled; | 6539 int disabled; |
6471 | 6540 |
6472 if (IsWindow(menux) && !IsMenu(mymenu)) | 6541 if(IsWindow(menux) && !IsMenu(mymenu)) |
6473 mymenu = (HMENU)dw_window_get_data(menux, "_dw_menu"); | 6542 { |
6543 ColorInfo *cinfo = _dw_window_get_cinfo((HWND)menux); | |
6544 | |
6545 if(cinfo) | |
6546 mymenu = cinfo->hmenu; | |
6547 else | |
6548 return; | |
6549 } | |
6474 | 6550 |
6475 _snprintf( buffer1, 30, "_dw_ischecked%ld", id ); | 6551 _snprintf( buffer1, 30, "_dw_ischecked%ld", id ); |
6476 check = DW_POINTER_TO_INT(dw_window_get_data( DW_HWND_OBJECT, buffer1 )); | 6552 check = DW_POINTER_TO_INT(dw_window_get_data( DW_HWND_OBJECT, buffer1 )); |
6477 _snprintf( buffer2, 30, "_dw_isdisabled%ld", id ); | 6553 _snprintf( buffer2, 30, "_dw_isdisabled%ld", id ); |
6478 disabled = DW_POINTER_TO_INT(dw_window_get_data( DW_HWND_OBJECT, buffer2 )); | 6554 disabled = DW_POINTER_TO_INT(dw_window_get_data( DW_HWND_OBJECT, buffer2 )); |
6479 | 6555 |
6480 memset( &mii, 0, sizeof(mii) ); | 6556 memset(&mii, 0, sizeof(mii)); |
6481 | 6557 |
6482 mii.cbSize = sizeof(MENUITEMINFO); | 6558 mii.cbSize = sizeof(MENUITEMINFO); |
6483 mii.fMask = MIIM_STATE | MIIM_CHECKMARKS; | 6559 mii.fMask = MIIM_STATE | MIIM_CHECKMARKS; |
6484 if ( (state & DW_MIS_CHECKED) || (state & DW_MIS_UNCHECKED) ) | 6560 if((state & DW_MIS_CHECKED) || (state & DW_MIS_UNCHECKED)) |
6485 { | 6561 { |
6486 /* | 6562 /* |
6487 * If we are changing state of "checked" base our setting on the passed flag... | 6563 * If we are changing state of "checked" base our setting on the passed flag... |
6488 */ | 6564 */ |
6489 if ( state & DW_MIS_CHECKED ) | 6565 if ( state & DW_MIS_CHECKED ) |
6509 else | 6585 else |
6510 { | 6586 { |
6511 mii.fState |= MFS_UNCHECKED; | 6587 mii.fState |= MFS_UNCHECKED; |
6512 } | 6588 } |
6513 } | 6589 } |
6514 if ( (state & DW_MIS_ENABLED) || (state & DW_MIS_DISABLED) ) | 6590 if((state & DW_MIS_ENABLED) || (state & DW_MIS_DISABLED)) |
6515 { | 6591 { |
6516 if ( state & DW_MIS_DISABLED ) | 6592 if ( state & DW_MIS_DISABLED ) |
6517 { | 6593 { |
6518 mii.fState |= MFS_DISABLED; | 6594 mii.fState |= MFS_DISABLED; |
6519 disabled = 1; | 6595 disabled = 1; |
6536 else | 6612 else |
6537 { | 6613 { |
6538 mii.fState |= MFS_ENABLED; | 6614 mii.fState |= MFS_ENABLED; |
6539 } | 6615 } |
6540 } | 6616 } |
6541 SetMenuItemInfo( mymenu, id, FALSE, &mii ); | 6617 SetMenuItemInfo(mymenu, id, FALSE, &mii); |
6542 /* | 6618 /* |
6543 * Keep our internal checked state consistent | 6619 * Keep our internal checked state consistent |
6544 */ | 6620 */ |
6545 dw_window_set_data( DW_HWND_OBJECT, buffer1, DW_INT_TO_POINTER(check) ); | 6621 dw_window_set_data(DW_HWND_OBJECT, buffer1, DW_INT_TO_POINTER(check)); |
6546 dw_window_set_data( DW_HWND_OBJECT, buffer2, DW_INT_TO_POINTER(disabled) ); | 6622 dw_window_set_data(DW_HWND_OBJECT, buffer2, DW_INT_TO_POINTER(disabled)); |
6547 } | 6623 } |
6548 | 6624 |
6549 /* | 6625 /* |
6550 * Deletes the menu item specified | 6626 * Deletes the menu item specified |
6551 * Parameters: | 6627 * Parameters: |
6556 */ | 6632 */ |
6557 int API dw_menu_delete_item(HMENUI menux, unsigned long id) | 6633 int API dw_menu_delete_item(HMENUI menux, unsigned long id) |
6558 { | 6634 { |
6559 HMENU mymenu = (HMENU)menux; | 6635 HMENU mymenu = (HMENU)menux; |
6560 | 6636 |
6561 if ( IsWindow(menux) && !IsMenu(mymenu) ) | 6637 if(IsWindow(menux) && !IsMenu(mymenu)) |
6562 mymenu = (HMENU)dw_window_get_data(menux, "_dw_menu"); | 6638 { |
6563 | 6639 ColorInfo *cinfo = _dw_window_get_cinfo((HWND)menux); |
6564 if ( mymenu == 0 || DeleteMenu(mymenu, id, MF_BYCOMMAND) == 0 ) | 6640 |
6641 if(cinfo) | |
6642 mymenu = cinfo->hmenu; | |
6643 else | |
6644 return DW_ERROR_UNKNOWN; | |
6645 } | |
6646 | |
6647 if(mymenu == 0 || DeleteMenu(mymenu, id, MF_BYCOMMAND) == 0) | |
6565 return DW_ERROR_UNKNOWN; | 6648 return DW_ERROR_UNKNOWN; |
6566 | 6649 |
6567 /* If the ID was autogenerated it is safe to remove it */ | 6650 /* If the ID was autogenerated it is safe to remove it */ |
6568 if(id >= 30000) | 6651 if(id >= 30000) |
6569 dw_signal_disconnect_by_window((HWND)(uintptr_t)id); | 6652 dw_signal_disconnect_by_window((HWND)(uintptr_t)id); |
6570 | 6653 |
6571 /* Make sure the menu is redrawn if needed */ | 6654 /* Make sure the menu is redrawn if needed */ |
6572 if( (HMENU)menux != mymenu ) | 6655 if((HMENU)menux != mymenu) |
6573 DrawMenuBar(menux); | 6656 DrawMenuBar(menux); |
6574 return DW_ERROR_NONE; | 6657 return DW_ERROR_NONE; |
6575 } | 6658 } |
6576 | 6659 |
6577 /* | 6660 /* |
6587 if(menu) | 6670 if(menu) |
6588 { | 6671 { |
6589 HMENU mymenu = (HMENU)*menu; | 6672 HMENU mymenu = (HMENU)*menu; |
6590 | 6673 |
6591 if(IsWindow(*menu) && !IsMenu(mymenu)) | 6674 if(IsWindow(*menu) && !IsMenu(mymenu)) |
6592 mymenu = (HMENU)dw_window_get_data(*menu, "_dw_menu"); | 6675 { |
6676 ColorInfo *cinfo = _dw_window_get_cinfo((HWND)*menu); | |
6677 | |
6678 if(cinfo) | |
6679 mymenu = cinfo->hmenu; | |
6680 else | |
6681 return; | |
6682 } | |
6593 | 6683 |
6594 popup = parent; | 6684 popup = parent; |
6595 TrackPopupMenu(mymenu, 0, x, y, 0, parent, NULL); | 6685 TrackPopupMenu(mymenu, 0, x, y, 0, parent, NULL); |
6596 PostMessage(DW_HWND_OBJECT, WM_USER+5, (LPARAM)mymenu, 0); | 6686 PostMessage(DW_HWND_OBJECT, WM_USER+5, (LPARAM)mymenu, 0); |
6597 } | 6687 } |
7882 free(thisitem); | 7972 free(thisitem); |
7883 | 7973 |
7884 thisbox->count++; | 7974 thisbox->count++; |
7885 | 7975 |
7886 #ifdef AEROGLASS | 7976 #ifdef AEROGLASS |
7887 AllowDarkModeForWindow(item, _DW_DARK_MODE_ENABLED); | 7977 _DW_AllowDarkModeForWindow(item, _DW_DARK_MODE_ENABLED); |
7888 #endif | 7978 #endif |
7889 SetParent(item, box); | 7979 SetParent(item, box); |
7890 if(_tcsnicmp(tmpbuf, UPDOWN_CLASS, _tcslen(UPDOWN_CLASS)+1)==0) | 7980 if(_tcsnicmp(tmpbuf, UPDOWN_CLASS, _tcslen(UPDOWN_CLASS)+1)==0) |
7891 { | 7981 { |
7892 ColorInfo *cinfo = _dw_window_get_cinfo(item); | 7982 ColorInfo *cinfo = _dw_window_get_cinfo(item); |