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