annotate foosdk/sdk/libPPUI/DarkMode.h @ 1:20d02a178406 default tip

*: check in everything else yay
author Paper <paper@tflc.us>
date Mon, 05 Jan 2026 02:15:46 -0500
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
1 #pragma once
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
2 #include <functional>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
3 #include <list>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
4
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
5 namespace DarkMode {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
6 // Is dark mode supported on this system or not?
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
7 bool IsSupportedSystem();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
8 // Is system in dark mode or not?
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
9 bool QueryUserOption();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
10
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
11 // Darken menus etc app-wide
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
12 void SetAppDarkMode(bool bDark);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
13 // Darken window title bar
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
14 void UpdateTitleBar(HWND wnd, bool bDark );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
15 void ApplyDarkThemeCtrl(HWND ctrl, bool bDark, const wchar_t * ThemeID = L"Explorer");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
16 void ApplyDarkThemeCtrl2(HWND ctrl, bool bDark, const wchar_t* ThemeID_light = L"Explorer", const wchar_t* ThemeID_dark = L"DarkMode_Explorer");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
17 void AllowDarkModeForWindow(HWND wnd, bool bDark);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
18
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
19 // One-shot version of darkening function for editboxes
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
20 void DarkenEditLite(HWND ctrl);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
21 // One-shot version of darkening function for comboboxes
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
22 void DarkenComboLite(HWND ctrl);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
23
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
24 // Returns if the dialog appears to be using dark mode (text brighter than background)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
25 bool IsDialogDark(HWND dlg, UINT msgSend = WM_CTLCOLORDLG);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
26 // Returns if the DC appears to be using dark mode (text brighter than background)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
27 bool IsDCDark(HDC dc);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
28
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
29 // Returns if these colors (text, background) look like dark theme
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
30 bool IsThemeDark(COLORREF text, COLORREF background);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
31
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
32 COLORREF GetSysColor(int, bool bDark = true);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
33
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
34 LRESULT CustomDrawToolbar(NMHDR*);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
35 // Custom draw handler that paints registered darkened controls.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
36 // Can be used with NOTIFY_CODE_HANDLER() directly
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
37 LRESULT OnCustomDraw(int, NMHDR*, BOOL & bHandled);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
38
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
39 // Handle WM_NCPAINT drawing dark frame
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
40 void NCPaintDarkFrame(HWND ctrl, HRGN rgn);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
41
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
42 bool IsHighContrast();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
43
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
44 // msgSetDarkMode
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
45 // return 1 if understood, 0 otherwise
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
46 // WPARAM = 0, DISABLE dark mode
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
47 // WPARAM = 1, ENABLE dark mode
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
48 // WPARAM = -1, query if supported
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
49 UINT msgSetDarkMode();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
50
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
51 //! CHooks class: entrypoint class for all Dark Mode hacks. \n
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
52 //! Usage: Keep CHooks m_dark = detectDarkMode(); as a member of your window class, replacing detectDarkMode() with your own function returning dark mode on/off state. \n
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
53 //! When initializing your window (WM_CREATE, WM_INITDIALOG), call m_dark.AddDialogWithControls(m_hWnd); \n
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
54 //! AddDialogWithControls() walks all child windows of your window; call other individual methods to finetune handling of Dark Mode if that's not acceptable in your case.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
55 class CHooks {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
56 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
57 CHooks(bool enabled = false) : m_dark(enabled) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
58 CHooks(const CHooks&) = delete;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
59 void operator=(const CHooks&) = delete;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
60
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
61 void AddDialog(HWND);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
62 void AddTabCtrl(HWND);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
63 void AddComboBox(HWND);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
64 void AddComboBoxEx(HWND);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
65 void AddButton(HWND);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
66 void AddEditBox(HWND);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
67 void AddPopup(HWND);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
68 void AddStatusBar(HWND);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
69 void AddScrollBar(HWND);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
70 void AddToolBar(HWND, bool bExplorerTheme = true);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
71 void AddReBar(HWND);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
72 void AddStatic(HWND);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
73 void AddUpDown(HWND);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
74 void AddListBox(HWND);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
75 void AddListView(HWND);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
76 void AddTreeView(HWND);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
77 void AddPPListControl(HWND);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
78
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
79
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
80 // SetWindowTheme with DarkMode_Explorer <=> Explorer
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
81 void AddGeneric(HWND, const wchar_t * name = L"explorer");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
82 // SetWindowTheme(wnd, L"", L"") for dark, Explorer theme for normal
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
83 void AddClassic(HWND, const wchar_t* normalTheme = L"explorer");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
84
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
85 void AddCtrlAuto(HWND);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
86 void AddCtrlMsg(HWND);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
87
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
88 void AddDialogWithControls(HWND);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
89 void AddControls(HWND wndParent);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
90
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
91 void SetDark(bool v = true);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
92 bool IsDark() const { return m_dark; }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
93 operator bool() const { return m_dark; }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
94
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
95 ~CHooks() { clear(); }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
96 void clear();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
97
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
98 void AddApp();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
99 private:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
100 template<typename obj_t> void addObj(obj_t* arg) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
101 m_apply.push_back([arg, this] { arg->SetDark(m_dark); });
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
102 m_cleanup.push_back([arg] { delete arg; });
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
103 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
104 void addOp(std::function<void()> f) { f(); m_apply.push_back(f); }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
105 bool m_dark = false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
106 std::list<std::function<void()> > m_apply;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
107 std::list<std::function<void()> > m_cleanup;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
108
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
109 void flushMoveToBack();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
110 std::list<HWND> m_lstMoveToBack;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
111 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
112 }