1
// TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2008-2013, 2016-2020 - TortoiseGit
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License
7 // as published by the Free Software Foundation; either version 2
8 // of the License, or (at your option) any later version.
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software Foundation,
17 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 // MainFrm.cpp : implementation of the CMainFrame class
25 #include "TortoiseGitBlame.h"
26 #include "MenuEncode.h"
28 #include "TaskbarUUID.h"
29 #include "ThemeMFCVisualManager.h"
37 IMPLEMENT_DYNCREATE(CMainFrame
, CFrameWndEx
)
39 const int iMaxUserToolbars
= 10;
40 const UINT uiFirstUserToolBarId
= AFX_IDW_CONTROLBAR_FIRST
+ 40;
41 const UINT uiLastUserToolBarId
= uiFirstUserToolBarId
+ iMaxUserToolbars
- 1;
43 BEGIN_MESSAGE_MAP(CMainFrame
, CFrameWndEx
)
46 ON_WM_SYSCOLORCHANGE()
47 // Global help commands
48 ON_COMMAND(ID_HELP_FINDER
, &CFrameWndEx::OnHelpFinder
)
49 ON_UPDATE_COMMAND_UI(ID_HELP_FINDER
, &CMainFrame::OnUpdateHelpFinder
)
50 ON_COMMAND(ID_HELP
, &CFrameWndEx::OnHelp
)
51 ON_COMMAND(ID_CONTEXT_HELP
, &CFrameWndEx::OnContextHelp
)
52 ON_COMMAND(ID_DEFAULT_HELP
, &CFrameWndEx::OnHelpFinder
)
53 ON_COMMAND(ID_VIEW_CUSTOMIZE
, &CMainFrame::OnViewCustomize
)
54 ON_REGISTERED_MESSAGE(AFX_WM_CREATETOOLBAR
, &CMainFrame::OnToolbarCreateNew
)
55 ON_REGISTERED_MESSAGE(TaskBarButtonCreated
, &CMainFrame::OnTaskbarButtonCreated
)
58 static UINT indicators
[] =
60 ID_SEPARATOR
, // status line indicator
61 ID_INDICATOR_ENCODING
,
65 // CMainFrame construction/destruction
67 CMainFrame::CMainFrame()
71 CMainFrame::~CMainFrame()
75 int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct
)
77 if (CFrameWndEx::OnCreate(lpCreateStruct
) == -1)
82 if (!m_wndMenuBar
.Create(this))
84 TRACE0("Failed to create menubar\n");
85 return -1; // fail to create
88 m_wndMenuBar
.SetPaneStyle(m_wndMenuBar
.GetPaneStyle() | CBRS_SIZE_DYNAMIC
| CBRS_TOOLTIPS
| CBRS_FLYBY
);
90 // prevent the menu bar from taking the focus on activation
91 CMFCPopupMenu::SetForceMenuFocus(FALSE
);
93 if (!m_wndToolBar
.CreateEx(this, TBSTYLE_FLAT
, WS_CHILD
| WS_VISIBLE
| CBRS_TOP
| CBRS_GRIPPER
| CBRS_TOOLTIPS
| CBRS_FLYBY
| CBRS_SIZE_DYNAMIC
) ||
94 !m_wndToolBar
.LoadToolBar(theApp
.m_bHiColorIcons
? IDR_TORTOISE_GIT_BLAME_MAINFRAME_256
: IDR_TORTOISE_GIT_BLAME_MAINFRAME
))
96 TRACE0("Failed to create toolbar\n");
97 return -1; // fail to create
100 CString strToolBarName
;
101 bNameValid
= strToolBarName
.LoadString(IDS_TOOLBAR_STANDARD
);
103 m_wndToolBar
.SetWindowText(strToolBarName
);
105 CString strCustomize
;
106 bNameValid
= strCustomize
.LoadString(IDS_TOOLBAR_CUSTOMIZE
);
108 m_wndToolBar
.EnableCustomizeButton(TRUE
, ID_VIEW_CUSTOMIZE
, strCustomize
);
110 // Allow user-defined toolbars operations:
111 InitUserToolbars(nullptr, uiFirstUserToolBarId
, uiLastUserToolBarId
);
113 if (!m_wndStatusBar
.Create(this))
115 TRACE0("Failed to create status bar\n");
116 return -1; // fail to create
118 m_wndStatusBar
.SetIndicators(indicators
, _countof(indicators
));
120 // Delete these five lines if you don't want the toolbar and menubar to be dockable
121 m_wndMenuBar
.EnableDocking(CBRS_ALIGN_ANY
);
122 m_wndToolBar
.EnableDocking(CBRS_ALIGN_ANY
);
123 EnableDocking(CBRS_ALIGN_ANY
);
124 DockPane(&m_wndMenuBar
);
125 DockPane(&m_wndToolBar
);
128 // enable Visual Studio 2005 style docking window behavior
129 CDockingManager::SetDockingMode(DT_SMART
);
130 // enable Visual Studio 2005 style docking window auto-hide behavior
131 EnableAutoHidePanes(CBRS_ALIGN_ANY
);
133 // create docking windows
134 if (!CreateDockingWindows())
136 TRACE0("Failed to create docking windows\n");
140 m_wndOutput
.EnableDocking(CBRS_ALIGN_ANY
);
141 DockPane(&m_wndOutput
);
142 m_wndProperties
.EnableDocking(CBRS_ALIGN_ANY
);
143 DockPane(&m_wndProperties
);
146 // Enable toolbar and docking window menu replacement
147 EnablePaneMenu(TRUE
, ID_VIEW_CUSTOMIZE
, strCustomize
, ID_VIEW_TOOLBAR
);
149 // enable quick (Alt+drag) toolbar customization
150 CMFCToolBar::EnableQuickCustomization();
152 m_themeCallbackId
= CTheme::Instance().RegisterThemeChangeCallback([this]() { SetTheme(CTheme::Instance().IsDarkTheme()); });
153 SetTheme(theApp
.GetInt(L
"DarkMode") && CTheme::Instance().IsDarkModeAllowed() && DarkModeHelper::Instance().ShouldAppsUseDarkMode());
157 void CMainFrame::OnSysColorChange()
159 __super::OnSysColorChange();
160 CTheme::Instance().OnSysColorChanged();
161 SetTheme(CTheme::Instance().IsDarkTheme());
164 void CMainFrame::SetTheme(bool bDark
)
168 DarkModeHelper::Instance().AllowDarkModeForApp(TRUE
);
169 DarkModeHelper::Instance().AllowDarkModeForWindow(GetSafeHwnd(), TRUE
);
170 SetClassLongPtr(GetSafeHwnd(), GCLP_HBRBACKGROUND
, reinterpret_cast<LONG_PTR
>(GetStockObject(BLACK_BRUSH
)));
171 BOOL darkFlag
= TRUE
;
172 DarkModeHelper::WINDOWCOMPOSITIONATTRIBDATA data
= { DarkModeHelper::WINDOWCOMPOSITIONATTRIB::WCA_USEDARKMODECOLORS
, &darkFlag
, sizeof(darkFlag
) };
173 DarkModeHelper::Instance().SetWindowCompositionAttribute(GetSafeHwnd(), &data
);
174 DarkModeHelper::Instance().FlushMenuThemes();
175 DarkModeHelper::Instance().RefreshImmersiveColorPolicyState();
177 DwmSetWindowAttribute(GetSafeHwnd(), 19, &dark
, sizeof(dark
));
181 DarkModeHelper::Instance().AllowDarkModeForWindow(GetSafeHwnd(), FALSE
);
182 BOOL darkFlag
= FALSE
;
183 DarkModeHelper::WINDOWCOMPOSITIONATTRIBDATA data
= { DarkModeHelper::WINDOWCOMPOSITIONATTRIB::WCA_USEDARKMODECOLORS
, &darkFlag
, sizeof(darkFlag
) };
184 DarkModeHelper::Instance().SetWindowCompositionAttribute(GetSafeHwnd(), &data
);
185 DarkModeHelper::Instance().FlushMenuThemes();
186 DarkModeHelper::Instance().RefreshImmersiveColorPolicyState();
187 DarkModeHelper::Instance().AllowDarkModeForApp(FALSE
);
188 SetClassLongPtr(GetSafeHwnd(), GCLP_HBRBACKGROUND
, reinterpret_cast<LONG_PTR
>(GetSysColorBrush(COLOR_3DFACE
)));
189 CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerWindows
));
191 if (bDark
|| CTheme::Instance().IsHighContrastModeDark())
192 CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CThemeMFCVisualManager
));
193 CTheme::Instance().SetThemeForDialog(GetSafeHwnd(), bDark
);
194 ::RedrawWindow(GetSafeHwnd(), nullptr, nullptr, RDW_FRAME
| RDW_INVALIDATE
| RDW_ERASE
| RDW_INTERNALPAINT
| RDW_ALLCHILDREN
| RDW_UPDATENOW
);
195 DarkModeHelper::Instance().RefreshTitleBarThemeColor(*this, bDark
);
198 void CMainFrame::OnDestroy()
200 CTheme::Instance().RemoveRegisteredCallback(m_themeCallbackId
);
201 __super::OnDestroy();
204 LRESULT
CMainFrame::OnTaskbarButtonCreated(WPARAM
/*wParam*/, LPARAM
/*lParam*/)
206 SetUUIDOverlayIcon(m_hWnd
);
210 BOOL
CMainFrame::PreCreateWindow(CREATESTRUCT
& cs
)
212 if( !CFrameWndEx::PreCreateWindow(cs
) )
214 // TODO: Modify the Window class or styles here by modifying
215 // the CREATESTRUCT cs
220 BOOL
CMainFrame::CreateDockingWindows()
223 // Create output window
224 CString strOutputWnd
;
225 bNameValid
= strOutputWnd
.LoadString(IDS_OUTPUT_WND
);
227 if (!m_wndOutput
.Create(strOutputWnd
, this, CRect(0, 0, 100, 100), TRUE
, ID_VIEW_OUTPUTWND
, WS_CHILD
| WS_VISIBLE
| WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
| CBRS_BOTTOM
| CBRS_FLOAT_MULTI
))
229 TRACE0("Failed to create Output window\n");
230 return FALSE
; // failed to create
233 // Create properties window
234 CString strPropertiesWnd
;
235 bNameValid
= strPropertiesWnd
.LoadString(IDS_PROPERTIES_WND
);
237 if (!m_wndProperties
.Create(strPropertiesWnd
, this, CRect(0, 0, 200, 200), TRUE
, ID_VIEW_PROPERTIESWND
, WS_CHILD
| WS_VISIBLE
| WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
| CBRS_RIGHT
| CBRS_FLOAT_MULTI
))
239 TRACE0("Failed to create Properties window\n");
240 return FALSE
; // failed to create
243 SetDockingWindowIcons(theApp
.m_bHiColorIcons
);
247 void CMainFrame::SetDockingWindowIcons(BOOL bHiColorIcons
)
249 auto hOutputBarIcon
= static_cast<HICON
>(::LoadImage(::AfxGetResourceHandle(), MAKEINTRESOURCE(bHiColorIcons
? IDI_OUTPUT_WND_HC
: IDI_OUTPUT_WND
), IMAGE_ICON
, ::GetSystemMetrics(SM_CXSMICON
), ::GetSystemMetrics(SM_CYSMICON
), 0));
250 m_wndOutput
.SetIcon(hOutputBarIcon
, FALSE
);
252 auto hPropertiesBarIcon
= static_cast<HICON
>(::LoadImage(::AfxGetResourceHandle(), MAKEINTRESOURCE(bHiColorIcons
? IDI_PROPERTIES_WND_HC
: IDI_PROPERTIES_WND
), IMAGE_ICON
, ::GetSystemMetrics(SM_CXSMICON
), ::GetSystemMetrics(SM_CYSMICON
), 0));
253 m_wndProperties
.SetIcon(hPropertiesBarIcon
, FALSE
);
256 // CMainFrame diagnostics
259 void CMainFrame::AssertValid() const
261 CFrameWndEx::AssertValid();
264 void CMainFrame::Dump(CDumpContext
& dc
) const
266 CFrameWndEx::Dump(dc
);
271 // CMainFrame message handlers
273 void CMainFrame::OnUpdateHelpFinder(CCmdUI
*pCmdUI
)
275 pCmdUI
->Enable(FALSE
);
278 void CMainFrame::OnViewCustomize()
280 CMFCToolBarsCustomizeDialog
* pDlgCust
= new CMFCToolBarsCustomizeDialog(this, TRUE
/* scan menus */);
281 pDlgCust
->EnableUserDefinedToolbars();
285 LRESULT
CMainFrame::OnToolbarCreateNew(WPARAM wp
,LPARAM lp
)
287 LRESULT lres
= CFrameWndEx::OnToolbarCreateNew(wp
,lp
);
291 auto pUserToolbar
= reinterpret_cast<CMFCToolBar
*>(lres
);
292 ASSERT_VALID(pUserToolbar
);
295 CString strCustomize
;
296 bNameValid
= strCustomize
.LoadString(IDS_TOOLBAR_CUSTOMIZE
);
299 pUserToolbar
->EnableCustomizeButton(TRUE
, ID_VIEW_CUSTOMIZE
, strCustomize
);
303 BOOL
CMainFrame::LoadFrame(UINT nIDResource
, DWORD dwDefaultStyle
, CWnd
* pParentWnd
, CCreateContext
* pContext
)
305 // base class does the real work
307 if (!CFrameWndEx::LoadFrame(nIDResource
, dwDefaultStyle
, pParentWnd
, pContext
))
310 // enable customization button for all user toolbars
312 CString strCustomize
;
313 bNameValid
= strCustomize
.LoadString(IDS_TOOLBAR_CUSTOMIZE
);
316 for (int i
= 0; i
< iMaxUserToolbars
; ++i
)
318 CMFCToolBar
* pUserToolbar
= GetUserToolBarByIndex(i
);
320 pUserToolbar
->EnableCustomizeButton(TRUE
, ID_VIEW_CUSTOMIZE
, strCustomize
);