diff --git a/.github/workflows/build-on-msys2.yml b/.github/workflows/build-on-msys2.yml index f9adee36b3..a6b9fe1b93 100644 --- a/.github/workflows/build-on-msys2.yml +++ b/.github/workflows/build-on-msys2.yml @@ -25,6 +25,8 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v5 + with: + submodules: true - name: Set up MSYS2 uses: msys2/setup-msys2@v2 diff --git a/.github/workflows/build-sakura.yml b/.github/workflows/build-sakura.yml index e868125871..40bb0909da 100644 --- a/.github/workflows/build-sakura.yml +++ b/.github/workflows/build-sakura.yml @@ -37,7 +37,7 @@ jobs: ## see https://github.com/actions/checkout - uses: actions/checkout@v5 with: - fetch-depth: 0 + submodules: true ## see https://github.com/microsoft/setup-msbuild - name: Add msbuild to PATH diff --git a/.github/workflows/sonarscan.yml b/.github/workflows/sonarscan.yml index 43705ca7ca..7701a13056 100644 --- a/.github/workflows/sonarscan.yml +++ b/.github/workflows/sonarscan.yml @@ -34,7 +34,7 @@ jobs: uses: actions/checkout@v5 with: ref: '${{ github.event.pull_request.head.sha }}' - fetch-depth: 0 + submodules: true - name: Setup environment variables run: | diff --git a/.gitmodules b/.gitmodules index d41dd11d1a..6529257a9e 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "tests/googletest"] path = tests/googletest url = https://github.com/google/googletest.git +[submodule "externals/darkmodelib"] + path = externals/darkmodelib + url = https://github.com/ozone10/darkmodelib.git diff --git a/resource/mytool.bmp b/resource/mytool.bmp index 01a1591dee..cb81c0b6f2 100644 Binary files a/resource/mytool.bmp and b/resource/mytool.bmp differ diff --git a/sakura/sakura.vcxproj b/sakura/sakura.vcxproj index 433b6b59bc..6cb4b58dc7 100644 --- a/sakura/sakura.vcxproj +++ b/sakura/sakura.vcxproj @@ -54,7 +54,7 @@ - ..\sakura_core;%(AdditionalIncludeDirectories) + ..\sakura_core;..\externals\darkmodelib\include;%(AdditionalIncludeDirectories) _WIN32_WINNT=_WIN32_WINNT_WIN10;%(PreprocessorDefinitions) true true @@ -500,6 +500,16 @@ + + + + + + + + + + diff --git a/sakura/sakura.vcxproj.filters b/sakura/sakura.vcxproj.filters index 3444152fb6..217a0d122b 100644 --- a/sakura/sakura.vcxproj.filters +++ b/sakura/sakura.vcxproj.filters @@ -119,6 +119,9 @@ {930f3f82-ab3f-49e3-af4a-d4f9c2d51f46} + + {57c87b7d-0c3b-4adb-9840-ce2292af594e} + @@ -2309,6 +2312,36 @@ Cpp Source Files\parse + + Cpp Source Files\darkmodelib + + + Cpp Source Files\darkmodelib + + + Cpp Source Files\darkmodelib + + + Cpp Source Files\darkmodelib + + + Cpp Source Files\darkmodelib + + + Cpp Source Files\darkmodelib + + + Cpp Source Files\darkmodelib + + + Cpp Source Files\darkmodelib + + + Cpp Source Files\darkmodelib + + + Cpp Source Files\darkmodelib + diff --git a/sakura_core/CPropertyManager.cpp b/sakura_core/CPropertyManager.cpp index 309e4431e6..6c210703e1 100644 --- a/sakura_core/CPropertyManager.cpp +++ b/sakura_core/CPropertyManager.cpp @@ -13,6 +13,7 @@ #include "apiwrap/StdApi.h" #include #include "config/system_constants.h" +#include "DarkModeSubclass.h" void CPropertyManager::Create( HWND hwndOwner, CImageListMgr* pImageList, CMenuDrawer* pMenuDrawer ) { diff --git a/sakura_core/_main/CControlTray.cpp b/sakura_core/_main/CControlTray.cpp index 361dea5f04..df9194f744 100644 --- a/sakura_core/_main/CControlTray.cpp +++ b/sakura_core/_main/CControlTray.cpp @@ -390,30 +390,7 @@ LRESULT CControlTray::DispatchEvent( case WM_MENUCHAR: /* メニューアクセスキー押下時の処理(WM_MENUCHAR処理) */ return m_cMenuDrawer.OnMenuChar( hwnd, uMsg, wParam, lParam ); - case WM_DRAWITEM: - lpdis = (DRAWITEMSTRUCT*) lParam; /* 項目描画情報 */ - switch( lpdis->CtlType ){ - case ODT_MENU: /* オーナー描画メニュー */ - /* メニューアイテム描画 */ - m_cMenuDrawer.DrawItem( lpdis ); - return TRUE; - } - return FALSE; - case WM_MEASUREITEM: - lpmis = (MEASUREITEMSTRUCT*) lParam; // item-size information - switch( lpmis->CtlType ){ - case ODT_MENU: /* オーナー描画メニュー */ - /* メニューアイテムの描画サイズを計算 */ - nItemWidth = m_cMenuDrawer.MeasureItem( lpmis->itemID, &nItemHeight ); - if( 0 < nItemWidth ){ - lpmis->itemWidth = nItemWidth; - lpmis->itemHeight = nItemHeight; - } - return TRUE; - } - return FALSE; case WM_EXITMENULOOP: - m_cMenuDrawer.EndDrawMenu(); break; /* タスクトレイ左クリックメニューへのショートカットキー登録 */ diff --git a/sakura_core/_main/WinMain.cpp b/sakura_core/_main/WinMain.cpp index 66b8e4fd87..51902217b9 100644 --- a/sakura_core/_main/WinMain.cpp +++ b/sakura_core/_main/WinMain.cpp @@ -32,6 +32,7 @@ #include "version.h" #include "util/std_macro.h" #include "env/DLLSHAREDATA.h" +#include "DarkModeSubclass.h" /*! Windows Entry point @@ -71,6 +72,13 @@ int WINAPI wWinMain( DEBUG_TRACE(L"-- -- WinMain -- --\n"); DEBUG_TRACE(L"sizeof(DLLSHAREDATA) = %d\n",sizeof(DLLSHAREDATA)); +#if 1 + DarkMode::initDarkMode(); + //DarkMode::setDarkModeConfigEx(static_cast(DarkMode::DarkModeType::classic)); + DarkMode::setDarkModeConfigEx(static_cast(DarkMode::DarkModeType::dark)); + DarkMode::setDefaultColors(true); +#endif + //コマンドラインクラスのインスタンスを確保する CCommandLine cCommandLine; diff --git a/sakura_core/apiwrap/CommonControl.h b/sakura_core/apiwrap/CommonControl.h index 7a573a2ea9..ea4665fde7 100644 --- a/sakura_core/apiwrap/CommonControl.h +++ b/sakura_core/apiwrap/CommonControl.h @@ -77,6 +77,13 @@ namespace ApiWrap inline DWORD Toolbar_SetExtendedStyle(HWND hwndCtl, DWORD styles) { return (DWORD)::SendMessage(hwndCtl, TB_SETEXTENDEDSTYLE, 0L, (LPARAM)styles); } inline int Toolbar_GetState(HWND hwndCtl, int index) { return (int)::SendMessage(hwndCtl, TB_GETSTATE, (WPARAM)index, 0L); } inline BOOL Toolbar_SetState(HWND hwndCtl, int index, WORD state) { return (BOOL)::SendMessage(hwndCtl, TB_SETSTATE, (WPARAM)index, state); } + inline HIMAGELIST Toolbar_SetImageList(HWND hwndCtl, int index, HIMAGELIST hImageList) { return (HIMAGELIST)::SendMessage(hwndCtl, TB_SETIMAGELIST, (WPARAM)index, (LPARAM)hImageList); } + inline HIMAGELIST Toolbar_SetDisabledImageList(HWND hwndCtl, int index, HIMAGELIST hImageList) { return (HIMAGELIST)::SendMessage(hwndCtl, TB_SETDISABLEDIMAGELIST, (WPARAM)index, (LPARAM)hImageList); } + inline int Toolbar_LoadImages(HWND hwndCtl, int id) { return (int)::SendMessage(hwndCtl, TB_LOADIMAGES, (WPARAM)id, (LPARAM)HINST_COMMCTRL); } + inline void Toolbar_AutoSize(HWND hwndCtl) { ::SendMessage(hwndCtl, TB_AUTOSIZE, 0, 0); } + inline BOOL Toolbar_SetBitmapSize(HWND hwndCtl, int width, int height) { + return (BOOL)::SendMessage(hwndCtl, TB_SETBITMAPSIZE, 0, MAKELPARAM(width, height)); + } // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- // // Tooltip コントロール // diff --git a/sakura_core/cmd/CViewCommander_Outline.cpp b/sakura_core/cmd/CViewCommander_Outline.cpp index d220bf7db5..0aed6d060a 100644 --- a/sakura_core/cmd/CViewCommander_Outline.cpp +++ b/sakura_core/cmd/CViewCommander_Outline.cpp @@ -28,6 +28,7 @@ #include "plugin/COutlineIfObj.h" #include "apiwrap/StdApi.h" #include "sakura_rc.h" +#include "DarkModeSubclass.h" /*! アウトライン解析 @@ -167,7 +168,7 @@ BOOL CViewCommander::Command_FUNCLIST( /* アウトライン ダイアログの表示 */ CLayoutPoint poCaret = GetCaret().GetCaretLayoutPos(); if( nullptr == GetEditWindow()->m_cDlgFuncList.GetHwnd() ){ - GetEditWindow()->m_cDlgFuncList.DoModeless( + HWND hWnd = GetEditWindow()->m_cDlgFuncList.DoModeless( G_AppInstance(), m_pCommanderView->GetHwnd(), (LPARAM)m_pCommanderView, @@ -178,6 +179,7 @@ BOOL CViewCommander::Command_FUNCLIST( nListType, m_pCommanderView->m_pTypeData->m_bLineNumIsCRLF /* 行番号の表示 false=折り返し単位/true=改行単位 */ ); + DarkMode::setDarkWndSafe(hWnd); }else{ /* アクティブにする */ GetEditWindow()->m_cDlgFuncList.Redraw( nOutlineType, nListType, &cFuncInfoArr, poCaret.GetY2() + 1, poCaret.GetX2() + 1 ); diff --git a/sakura_core/cmd/CViewCommander_Settings.cpp b/sakura_core/cmd/CViewCommander_Settings.cpp index 3b2fad2bc2..980b27b2d9 100644 --- a/sakura_core/cmd/CViewCommander_Settings.cpp +++ b/sakura_core/cmd/CViewCommander_Settings.cpp @@ -33,6 +33,7 @@ #include #include "config/system_constants.h" #include "config/app_constants.h" +#include "DarkModeSubclass.h" /*! ツールバーの表示/非表示 @@ -67,6 +68,10 @@ void CViewCommander::Command_SHOWFUNCKEY( void ) pCEditWnd->LayoutFuncKey(); pCEditWnd->EndLayoutBars(); + auto hWnd = pCEditWnd->GetHwnd(); + DarkMode::setChildCtrlsTheme(hWnd); + DarkMode::setWindowMenuBarSubclass(hWnd); + //全ウインドウに変更を通知する。 CAppNodeGroupHandle(0).PostMessageToAllEditors( MYWM_BAR_CHANGE_NOTIFY, diff --git a/sakura_core/dlg/CDialog.cpp b/sakura_core/dlg/CDialog.cpp index 7a4e7d3f7d..94387c5a03 100644 --- a/sakura_core/dlg/CDialog.cpp +++ b/sakura_core/dlg/CDialog.cpp @@ -34,6 +34,7 @@ #include "util/window.h" #include "apiwrap/StdApi.h" #include "apiwrap/StdControl.h" +#include "DarkModeSubclass.h" /* ダイアログプロシージャ */ INT_PTR CALLBACK MyDialogProc( @@ -187,6 +188,14 @@ BOOL CDialog::OnInitDialog( HWND hwndDlg, WPARAM wParam, LPARAM lParam ) m_hFontDialog = UpdateDialogFont( hwndDlg ); + // --- Dark Mode --- + auto hWnd = m_hWnd; + DarkMode::setColorizeTitleBarConfig(true); + DarkMode::setDarkWndNotifySafeEx(hWnd, true, true); + DarkMode::setWindowEraseBgSubclass(hWnd); + DarkMode::setWindowMenuBarSubclass(hWnd); + DarkMode::setWindowExStyle(hWnd, false, WS_EX_COMPOSITED); + /* ダイアログデータの設定 */ SetData(); diff --git a/sakura_core/outline/CDlgFuncList.cpp b/sakura_core/outline/CDlgFuncList.cpp index 7b4bda2695..82a2a2063d 100644 --- a/sakura_core/outline/CDlgFuncList.cpp +++ b/sakura_core/outline/CDlgFuncList.cpp @@ -55,6 +55,7 @@ #include "config/system_constants.h" #include "config/app_constants.h" #include "String_define.h" +#include "DarkModeSubclass.h" // 画面ドッキング用の定義 // 2010.06.05 ryoji #define DEFINE_SYNCCOLOR @@ -3114,33 +3115,30 @@ INT_PTR CDlgFuncList::OnNcPaint( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lPa default: break; } - ::MyFillRect( gr, rcWk, COLOR_3DFACE ); + //::MyFillRect( gr, rcWk, COLOR_3DFACE ); + ::MyFillRect(gr, rcWk, DarkMode::getBackgroundColor()); ::DrawEdge( gr, &rcWk, EDGE_ETCHED, BF_TOPLEFT ); // タイトルを描画する BOOL bThemeActive = ::IsThemeActive(); - BOOL bGradient = FALSE; - ::SystemParametersInfo( SPI_GETGRADIENTCAPTIONS, 0, &bGradient, 0 ); - if( !bThemeActive ) bGradient = FALSE; // 適当に調整 HWND hwndFocus = ::GetFocus(); BOOL bActive = (GetHwnd() == hwndFocus || ::IsChild(GetHwnd(), hwndFocus)); RECT rcCaption; GetCaptionRect( &rcCaption ); ::OffsetRect( &rcCaption, -rcScr.left, -rcScr.top ); rcWk = rcCaption; - rcWk.top += 1; - rcWk.right -= DOCK_BUTTON_NUM * (::GetSystemMetrics( SM_CXSMSIZE )); // ↓DrawCaption() に DC_SMALLCAP を指定してはいけないっぽい // ↓DC_SMALLCAP 指定のものを Win7(64bit版) で動かしてみたら描画位置が下にずれて上半分しか見えなかった(x86ビルド/x64ビルドのどちらも NG) - ::DrawCaption( hwnd, gr, &rcWk, DC_TEXT | (bGradient? DC_GRADIENT: 0) /*| DC_SMALLCAP*/ | (bActive? DC_ACTIVE: 0) ); - rcWk.left = rcCaption.right; - int nClrCaption; - if( bGradient ) - nClrCaption = ( bActive? COLOR_GRADIENTACTIVECAPTION: COLOR_GRADIENTINACTIVECAPTION ); - else - nClrCaption = ( bActive? COLOR_ACTIVECAPTION: COLOR_INACTIVECAPTION ); - ::MyFillRect( gr, rcWk, nClrCaption ); + gr.SetTextForeColor(DarkMode::getTextColor()); + gr.SetTextBackColor(DarkMode::getBackgroundColor()); + //::DrawCaption( hwnd, gr, &rcWk, DC_TEXT /*| DC_SMALLCAP*/ | (bActive? DC_ACTIVE: 0) ); + wchar_t buff[256]; + ::GetWindowText(GetHwnd(), buff, 256); + //COLORREF clrCaption = ::GetSysColor( bActive? COLOR_ACTIVECAPTION: COLOR_INACTIVECAPTION ); + COLORREF clrCaption = bActive ? DarkMode::getHotBackgroundColor() : DarkMode::getBackgroundColor(); + ::MyFillRect( gr, rcWk, clrCaption ); ::DrawEdge( gr, &rcCaption, BDR_SUNKENOUTER, BF_TOP ); + ::DrawText(gr, buff, -1, &rcCaption, DT_TOP|DT_LEFT); // タイトル上のボタンを描画する NONCLIENTMETRICS ncm; @@ -3170,8 +3168,8 @@ INT_PTR CDlgFuncList::OnNcPaint( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lPa int nClrCaptionText; // マウスカーソルがボタン上にあればハイライト if( ::PtInRect( &rcBtn, pt ) ){ - ::MyFillRect( gr, rcBtn, (bGradient && !bActive)? COLOR_INACTIVECAPTION: COLOR_ACTIVECAPTION ); - nClrCaptionText = ( (bGradient && !bActive)? COLOR_INACTIVECAPTIONTEXT: COLOR_CAPTIONTEXT ); + ::MyFillRect( gr, rcBtn, COLOR_ACTIVECAPTION ); + nClrCaptionText = COLOR_CAPTIONTEXT; }else{ nClrCaptionText = ( bActive? COLOR_CAPTIONTEXT: COLOR_INACTIVECAPTIONTEXT ); } diff --git a/sakura_core/print/CPrintPreview.cpp b/sakura_core/print/CPrintPreview.cpp index 0a89690515..0526d21df7 100644 --- a/sakura_core/print/CPrintPreview.cpp +++ b/sakura_core/print/CPrintPreview.cpp @@ -38,6 +38,7 @@ #include "sakura_rc.h" #include "config/system_constants.h" #include "String_define.h" +#include "DarkModeSubclass.h" #define MIN_PREVIEW_ZOOM 10 #define MAX_PREVIEW_ZOOM 400 @@ -1958,7 +1959,6 @@ void CPrintPreview::CreatePrintPreviewControls( void ) si.nPos = 0; si.nTrackPos = 1; ::SetScrollInfo( m_hwndVScrollBar, SB_CTL, &si, TRUE ); - ::ShowScrollBar( m_hwndVScrollBar, SB_CTL, TRUE ); /* 横スクロールバーの作成 */ m_hwndHScrollBar = ::CreateWindowEx( @@ -1983,7 +1983,6 @@ void CPrintPreview::CreatePrintPreviewControls( void ) si.nPos = 0; si.nTrackPos = 1; ::SetScrollInfo( m_hwndHScrollBar, SB_CTL, &si, TRUE ); - ::ShowScrollBar( m_hwndHScrollBar, SB_CTL, TRUE ); /* サイズボックスの作成 */ m_hwndSizeBox = ::CreateWindowEx( @@ -2000,7 +1999,12 @@ void CPrintPreview::CreatePrintPreviewControls( void ) CEditApp::getInstance()->GetAppInstance(), /* instance owning this window */ (LPVOID) nullptr /* pointer not needed */ ); - ::ShowWindow( m_hwndPrintPreviewBar, SW_SHOW ); + + DarkMode::setDarkWndSafe(m_hwndPrintPreviewBar); + DarkMode::setChildCtrlsTheme(m_pParentWnd->GetHwnd()); + ::ShowScrollBar(m_hwndVScrollBar, SB_CTL, TRUE); + ::ShowScrollBar(m_hwndHScrollBar, SB_CTL, TRUE); + ::ShowWindow(m_hwndPrintPreviewBar, SW_SHOW); /* WM_SIZE 処理 */ RECT rc1; diff --git a/sakura_core/prop/CPropComGeneral.cpp b/sakura_core/prop/CPropComGeneral.cpp index dc0e6dd2a2..aff4687341 100644 --- a/sakura_core/prop/CPropComGeneral.cpp +++ b/sakura_core/prop/CPropComGeneral.cpp @@ -28,6 +28,7 @@ #include "String_define.h" #include "recent/CRecentFile.h" #include "recent/CRecentFolder.h" +#include "DarkModeSubclass.h" //@@@ 2001.02.04 Start by MIK: Popup Help TYPE_NAME_ID SpecialScrollModeArr[] = { @@ -123,7 +124,6 @@ INT_PTR CPropGeneral::DispatchEvent( SetData( hwndDlg ); // Modified by KEITA for WIN64 2003.9.6 ::SetWindowLongPtr( hwndDlg, DWLP_USER, lParam ); - /* ユーザーがエディット コントロールに入力できるテキストの長さを制限する */ return TRUE; diff --git a/sakura_core/prop/CPropComToolbar.cpp b/sakura_core/prop/CPropComToolbar.cpp index 73df8cfd16..b782f3aed7 100644 --- a/sakura_core/prop/CPropComToolbar.cpp +++ b/sakura_core/prop/CPropComToolbar.cpp @@ -30,6 +30,7 @@ #include "sakura_rc.h" #include "sakura.hh" #include "String_define.h" +#include "DarkModeSubclass.h" //@@@ 2001.02.04 Start by MIK: Popup Help static const DWORD p_helpids[] = { //11000 @@ -573,25 +574,29 @@ void CPropToolbar::DrawToolBarItemList( DRAWITEMSTRUCT* pDis ) RECT rcFrame = rcText; // アイテム背景をウインドウ背景色で塗りつぶす - ::MyFillRect( pDis->hDC, rcItem, COLOR_WINDOW ); + ::MyFillRect( pDis->hDC, rcItem, DarkMode::getCtrlBackgroundColor() ); // 背景色と前景色 - int bkColor; - int textColor; + COLORREF bkColor; + COLORREF textColor; /* アイテムが選択されている */ if( pDis->itemState & ODS_SELECTED ){ - bkColor = COLOR_HIGHLIGHT; - textColor = COLOR_HIGHLIGHTTEXT; + //bkColor = ::GetSysColor(COLOR_HIGHLIGHT); + //textColor = ::GetSysColor(COLOR_HIGHLIGHTTEXT); + bkColor = ::GetSysColor(COLOR_HIGHLIGHT); + textColor = DarkMode::getTextColor(); }else{ - bkColor = COLOR_WINDOW; - textColor = COLOR_WINDOWTEXT; + //bkColor = ::GetSysColor(COLOR_WINDOW); + //textColor = ::GetSysColor(COLOR_WINDOWTEXT); + bkColor = DarkMode::getCtrlBackgroundColor(); + textColor = DarkMode::getTextColor(); } // デバイスコンテキストのオプションを設定する int bkModeOld = ::SetBkMode( pDis->hDC, TRANSPARENT ); - COLORREF bkColorOld = ::SetBkColor( pDis->hDC, ::GetSysColor( bkColor ) ); - COLORREF textColorOld = ::SetTextColor( pDis->hDC, ::GetSysColor( textColor ) ); + COLORREF bkColorOld = ::SetBkColor( pDis->hDC, bkColor ); + COLORREF textColorOld = ::SetTextColor( pDis->hDC, textColor ); // itemDataに紐づくボタン情報を取得する TBBUTTON tbb = m_pcMenuDrawer->getButton(pDis->itemData); @@ -618,7 +623,7 @@ void CPropToolbar::DrawToolBarItemList( DRAWITEMSTRUCT* pDis ) rcItem.left + cxEdge, rcItem.top + cyEdge + (rcItem.bottom - rcItem.top - cySmIcon) / 2, tbb.iBitmap, - ILD_NORMAL, + true, cxSmIcon, cySmIcon ); diff --git a/sakura_core/prop/CPropCommon.cpp b/sakura_core/prop/CPropCommon.cpp index 583681bbb1..ff0fae7c79 100644 --- a/sakura_core/prop/CPropCommon.cpp +++ b/sakura_core/prop/CPropCommon.cpp @@ -31,6 +31,7 @@ #include "apiwrap/StdControl.h" #include "sakura_rc.h" #include "String_define.h" +#include "DarkModeSubclass.h" int CPropCommon::SearchIntArr( int nKey, int* pnArr, int nArrNum ) { @@ -66,6 +67,7 @@ INT_PTR CPropCommon::DlgProc( pCPropCommon = ( CPropCommon* )(pPsp->lParam); if( nullptr != pCPropCommon ){ UpdateDialogFont( hwndDlg ); + DarkMode::setDarkWndSafe(hwndDlg); return (pCPropCommon->*DispatchPage)( hwndDlg, uMsg, wParam, pPsp->lParam ); }else{ return FALSE; @@ -94,6 +96,7 @@ INT_PTR CPropCommon::DlgProc2( pCPropCommon = ( CPropCommon* )(lParam); if( nullptr != pCPropCommon ){ UpdateDialogFont( hwndDlg ); + DarkMode::setDarkWndSafe(hwndDlg); return (pCPropCommon->*DispatchPage)( hwndDlg, uMsg, IDOK, lParam ); }else{ return FALSE; diff --git a/sakura_core/typeprop/CPropTypes.cpp b/sakura_core/typeprop/CPropTypes.cpp index 89c629b7fe..b976f22785 100644 --- a/sakura_core/typeprop/CPropTypes.cpp +++ b/sakura_core/typeprop/CPropTypes.cpp @@ -33,6 +33,7 @@ #include "env/DLLSHAREDATA.h" #include "sakura_rc.h" #include "String_define.h" +#include "DarkModeSubclass.h" // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- // // メッセージ処理 // @@ -49,6 +50,7 @@ INT_PTR CALLBACK PropTypesCommonProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPA case WM_INITDIALOG: pPsp = (PROPSHEETPAGE*)lParam; pCPropTypes = reinterpret_cast(pPsp->lParam); + DarkMode::setDarkWndSafe(hwndDlg); if( nullptr != pCPropTypes ){ UpdateDialogFont( hwndDlg ); return (pCPropTypes->*pDispatch)( hwndDlg, uMsg, wParam, pPsp->lParam ); diff --git a/sakura_core/typeprop/CPropTypesColor.cpp b/sakura_core/typeprop/CPropTypesColor.cpp index 678da68f2d..59b41326d1 100644 --- a/sakura_core/typeprop/CPropTypesColor.cpp +++ b/sakura_core/typeprop/CPropTypesColor.cpp @@ -40,6 +40,7 @@ #include "apiwrap/StdControl.h" #include "config/app_constants.h" #include "String_define.h" +#include "DarkModeSubclass.h" namespace { //! カスタムカラー用の識別文字列 @@ -1094,7 +1095,7 @@ void CPropTypesColor::DrawColorListItem( DRAWITEMSTRUCT* pDis ) ColorInfo* pColorInfo; // RECT rc0,rc1,rc2; RECT rc1; - COLORREF cRim = (COLORREF)::GetSysColor( COLOR_3DSHADOW ); + COLORREF cRim = (COLORREF)DarkMode::getEdgeColor(); if( pDis == nullptr || pDis->itemData == 0 ) return; @@ -1109,27 +1110,27 @@ void CPropTypesColor::DrawColorListItem( DRAWITEMSTRUCT* pDis ) pColorInfo = (ColorInfo*)pDis->itemData; /* アイテム矩形塗りつぶし */ - gr.SetBrushColor( ::GetSysColor( COLOR_WINDOW ) ); + gr.SetBrushColor( DarkMode::getCtrlBackgroundColor() ); gr.FillMyRect( pDis->rcItem ); /* アイテムが選択されている */ if( pDis->itemState & ODS_SELECTED ){ - gr.SetBrushColor( ::GetSysColor( COLOR_HIGHLIGHT ) ); - gr.SetTextForeColor( ::GetSysColor( COLOR_HIGHLIGHTTEXT ) ); + gr.SetBrushColor(::GetSysColor(COLOR_HIGHLIGHT)); + gr.SetTextForeColor( DarkMode::getTextColor() ); }else{ - gr.SetBrushColor( ::GetSysColor( COLOR_WINDOW ) ); - gr.SetTextForeColor( ::GetSysColor( COLOR_WINDOWTEXT ) ); + gr.SetBrushColor(DarkMode::getCtrlBackgroundColor()); + gr.SetTextForeColor(DarkMode::getTextColor()); } const int xOffset = ::MulDiv(m_uFocusBorderWidth, 2, 3); const int yOffset = ::MulDiv(m_uFocusBorderHeight, 2, 3); // 少し重ならせる const int colorSampleWidth = DpiScaleX(12); - rc1.left += xOffset + DpiScaleX(16); rc1.top += yOffset; rc1.right -= 2 * (colorSampleWidth + xOffset) + DpiScaleX(2); rc1.bottom -= yOffset; /* 選択ハイライト矩形 */ gr.FillMyRect(rc1); + rc1.left += xOffset + DpiScaleX(16); /* テキスト */ ::SetBkMode( gr, TRANSPARENT ); SFontAttr sFontAttr; @@ -1152,7 +1153,7 @@ void CPropTypesColor::DrawColorListItem( DRAWITEMSTRUCT* pDis ) rc1.bottom = rc1.top + DpiScaleY(12); if( pColorInfo->m_bDisp ){ /* 色分け/表示する */ // 2006.04.26 ryoji テキスト色を使う(「ハイコントラスト黒」のような設定でも見えるように) - gr.SetPen( ::GetSysColor( COLOR_WINDOWTEXT ) ); + gr.SetPen( DarkMode::getTextColor() ); // チェックマークを2本の直線で描画する際に使用する3点の座標 const POINT pts[3] = { { rc1.left + DpiScaleX(2), rc1.top + DpiScaleY(3) }, // 左 @@ -1208,16 +1209,13 @@ void CPropTypesColor::DrawColorListItem( DRAWITEMSTRUCT* pDis ) /* 色選択ダイアログ */ BOOL CPropTypesColor::SelectColor( HWND hwndParent, COLORREF* pColor, DWORD* pCustColors ) { - CHOOSECOLOR cc; - cc.lStructSize = sizeof_raw( cc ); + CHOOSECOLOR cc = {sizeof(cc)}; cc.hwndOwner = hwndParent; cc.hInstance = nullptr; cc.rgbResult = *pColor; cc.lpCustColors = pCustColors; - cc.Flags = /*CC_PREVENTFULLOPEN |*/ CC_RGBINIT; - cc.lCustData = 0; - cc.lpfnHook = nullptr; - cc.lpTemplateName = nullptr; + cc.Flags = CC_FULLOPEN | CC_RGBINIT | CC_ENABLEHOOK; + cc.lpfnHook = static_cast(DarkMode::HookDlgProc); if( !::ChooseColor( &cc ) ){ return FALSE; } diff --git a/sakura_core/uiparts/CImageListMgr.cpp b/sakura_core/uiparts/CImageListMgr.cpp index 85813a082d..c768207278 100644 --- a/sakura_core/uiparts/CImageListMgr.cpp +++ b/sakura_core/uiparts/CImageListMgr.cpp @@ -41,6 +41,7 @@ CImageListMgr::CImageListMgr() : m_cx( 16 ), m_cy( 16 ) , m_cTrans( RGB( 0, 0, 0 )) , m_hIconBitmap( nullptr ) + , m_hDC( nullptr ) , m_nIconCount( MAX_TOOLBAR_ICON_COUNT ) { } @@ -85,10 +86,13 @@ CImageListMgr::~CImageListMgr() if( m_hIconBitmap != nullptr ){ DeleteObject( m_hIconBitmap ); } + if (m_hDC != nullptr) { + ::DeleteDC(m_hDC); + } } static -HBITMAP ConvertTo32bppBMP(HBITMAP hbmpSrc) +HBITMAP ConvertTo32bppBMP(HBITMAP hbmpSrc, uint32_t*& pBits, LONG& bmpWidth, LONG& bmpHeight) { BITMAP bmp; if (0 == GetObject(hbmpSrc, sizeof(BITMAP), &bmp )) { @@ -100,7 +104,7 @@ HBITMAP ConvertTo32bppBMP(HBITMAP hbmpSrc) BITMAPINFO bmi; bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader); bmi.bmiHeader.biWidth = bmp.bmWidth; - bmi.bmiHeader.biHeight = bmp.bmHeight; + bmi.bmiHeader.biHeight = -bmp.bmHeight; bmi.bmiHeader.biPlanes = bmp.bmPlanes; bmi.bmiHeader.biBitCount = 32; bmi.bmiHeader.biCompression = BI_RGB; @@ -109,7 +113,7 @@ HBITMAP ConvertTo32bppBMP(HBITMAP hbmpSrc) bmi.bmiHeader.biYPelsPerMeter = 0; bmi.bmiHeader.biClrUsed = 0; bmi.bmiHeader.biClrImportant = 0; - HBITMAP hdib = CreateDIBSection(nullptr, &bmi, DIB_RGB_COLORS, nullptr, nullptr, 0); + HBITMAP hdib = CreateDIBSection(nullptr, &bmi, DIB_RGB_COLORS, (void**)&pBits, nullptr, 0); if (hdib == nullptr) { return hbmpSrc; } @@ -132,6 +136,8 @@ HBITMAP ConvertTo32bppBMP(HBITMAP hbmpSrc) DeleteDC(hdcSrc); DeleteDC(hdcDst); DeleteObject(hbmpSrc); + bmpWidth = bmp.bmWidth; + bmpHeight = bmp.bmHeight; return hdib; } @@ -172,7 +178,7 @@ bool CImageListMgr::Create(HINSTANCE hInstance) } } - hRscbmp = ConvertTo32bppBMP(hRscbmp); + hRscbmp = ConvertTo32bppBMP(hRscbmp, m_pBits, m_bmpWidth, m_bmpHeight); // To Here 2001.7.1 GAE @@ -197,7 +203,7 @@ bool CImageListMgr::Create(HINSTANCE hInstance) m_cy = ::GetSystemMetrics( SM_CYSMICON ); // アイコンサイズが異なる場合、拡大縮小する - hRscbmp = ResizeToolIcons( hRscbmp, m_cTrans ); + hRscbmp = ResizeToolIcons( hRscbmp, m_pBits, m_bmpWidth, m_bmpHeight, m_cTrans ); if( hRscbmp == nullptr ){ // リソースからBitmapを読み込む hRscbmp = LoadMyToolFromModule( hInstance ); @@ -205,10 +211,10 @@ bool CImageListMgr::Create(HINSTANCE hInstance) return false; } - hRscbmp = ConvertTo32bppBMP(hRscbmp); + hRscbmp = ConvertTo32bppBMP(hRscbmp, m_pBits, m_bmpWidth, m_bmpHeight); // アイコンサイズが異なる場合、拡大縮小する - hRscbmp = ResizeToolIcons( hRscbmp, m_cTrans ); + hRscbmp = ResizeToolIcons( hRscbmp, m_pBits, m_bmpWidth, m_bmpHeight, m_cTrans ); if( hRscbmp == nullptr ){ return false; } @@ -217,281 +223,11 @@ bool CImageListMgr::Create(HINSTANCE hInstance) // クラスメンバに変更を保存する m_hIconBitmap = hRscbmp; - return true; -} - -/*! RGBQUADラッパー - * STLコンテナに入れられるよう == 演算子を実装したもの。 - */ -struct MyRGBQUAD : tagRGBQUAD -{ - using tagRGBQUAD::rgbRed; - using tagRGBQUAD::rgbGreen; - using tagRGBQUAD::rgbBlue; - using tagRGBQUAD::rgbReserved; - - MyRGBQUAD() noexcept - : tagRGBQUAD() - { - rgbBlue = 0; - rgbGreen = 0; - rgbRed = 0; - rgbReserved = 0; - } - bool operator == ( const RGBQUAD &rhs ) const noexcept - { - return rgbBlue == rhs.rgbBlue - && rgbGreen == rhs.rgbGreen - && rgbRed == rhs.rgbRed - && rgbReserved == rhs.rgbReserved; - } - bool operator != ( const RGBQUAD &rhs ) const noexcept - { - return !(*this == rhs); - } - operator COLORREF ( void ) const noexcept - { - return RGB( rgbRed, rgbGreen, rgbBlue ); - } -}; - -// HLS色情報タプル -typedef std::tuple _HlsTuple; -enum { HLS_H, HLS_S, HLS_L, }; - -/*! - * @brief RGB⇒HLS(円柱モデル)変換する - */ -_HlsTuple ToHLS( const COLORREF color ) -{ - auto R = (double) GetRValue( color ) / 255.; - auto G = (double) GetGValue( color ) / 255.; - auto B = (double) GetBValue( color ) / 255.; - auto MIN = std::min( { R, G, B } ); - auto MAX = std::max( { R, G, B } ); - auto M = MAX + MIN; - auto m = MAX - MIN; - double H; - if ( MIN == MAX ) { - H = std::numeric_limits::infinity(); - } - else if ( MIN == B ) { - H = 60. * (m == 0 ? 0 : ((G - R) / m)) + 60.; - } - else if ( MIN == R ) { - H = 60. * (m == 0 ? 0 : ((B - G) / m)) + 180.; - } - else if ( MIN == G ) { - H = 60. * (m == 0 ? 0 : ((R - B) / m)) + 300.; - } - auto L = M / 2.; - auto S = M == 0 ? 0 : m / (1 - std::abs( M - 1 )); - return std::make_tuple( H, S, L ); -} - -/*! - * @brief HLS(円柱モデル)⇒RGB変換する - */ -COLORREF FromHLS( const _HlsTuple &hls ) -{ - auto H = std::get( hls ); - auto S = std::get( hls ); - auto L = std::get( hls ); - - // 彩度の範囲を補正する - if ( S < 0 ) S = 0; - if ( 1 < S ) S = 1; - - // 輝度の範囲を補正する - if ( L < 0 ) L = 0; - if ( 1 < L ) L = 1; - - // 色相が無効値(=白黒)の場合 - if ( std::isinf( H ) ) { - return RGB( L * 255, L * 255, L * 255 ); - } - - // 色相の範囲を補正する - while ( H < 0 ) H = 360 - H; - while ( 360 <= H ) H = H - 360; - - double R, G, B; - double MIN = L + S * (1 - std::abs( 2 * L - 1 )) / 2; - double MAX = L - S * (1 - std::abs( 2 * L - 1 )) / 2; - if ( H < 60 ) { - R = MAX; - G = MAX + (MAX - MIN) * H / 60; - B = MIN; - } - else if ( H < 120 ) { - R = MIN + (MAX - MIN) * (120 - H) / 60; - G = MAX; - B = MIN; - } - else if ( H < 180 ) { - R = MIN; - G = MAX; - B = MIN + (MAX - MIN) * (H - 120) / 60; - } - else if ( H < 240 ) { - R = MIN; - G = MIN + (MAX - MIN) * (240 - H) / 60; - B = MAX; - } - else if ( H < 300 ) { - R = MIN + (MAX - MIN) * (H - 240) / 60; - G = MIN; - B = MAX; - } - else { //if ( H < 360 ) { - R = MAX; - G = MIN; - B = MIN + (MAX - MIN) * (360 - H) / 60; - } - return RGB( R * 255, G * 255, B * 255 ); -} - -/*! ビットマップの表示 灰色を透明描画 - - @author Nakatani - @date 2003.07.21 genta 以前のCMenuDrawerより移転復活 - @date 2003.08.27 Moca 背景は透過処理に変更し、colBkColorを削除 - @date 2010.01.30 syat 透明にする色を引数に移動 -*/ -void CImageListMgr::MyBitBlt( - HDC drawdc, - int nXDest, - int nYDest, - int nWidth, - int nHeight, - int nXSrc, - int nYSrc -) const -{ - // 仮想DCを生成してビットマップを展開する - const HBITMAP &bmpSrc = m_hIconBitmap; - HDC hdcSrc = ::CreateCompatibleDC( drawdc ); - HGDIOBJ bmpSrcOld = ::SelectObject( hdcSrc, bmpSrc ); - - // 透過色の変数名が分かりづらいので別名定義する - const COLORREF &cTransparent = m_cTrans; - - // 透過色を考慮して転送 - ::TransparentBlt( drawdc, nXDest, nYDest, nWidth, nHeight, - hdcSrc, nXSrc, nYSrc, cx(), cy(), cTransparent ); + m_hDC = ::CreateCompatibleDC(nullptr); - // 後始末 - ::SelectObject( hdcSrc, bmpSrcOld ); - ::DeleteDC( hdcSrc ); - return; -} - - -/*! メニューアイコンの淡色表示 - - @author Nakatani - - @date 2003.07.21 genta 以前のCMenuDrawerより移転復活 - @date 2003.08.27 Moca 背景色は透過処理する -*/ -void CImageListMgr::MyDitherBlt( HDC drawdc, int nXDest, int nYDest, - int nWidth, int nHeight, int nXSrc, int nYSrc ) const -{ - // 仮想DCを生成してビットマップを展開する - const HBITMAP &bmpSrc = m_hIconBitmap; - HDC hdcSrc = ::CreateCompatibleDC( drawdc ); - HGDIOBJ bmpSrcOld = ::SelectObject( hdcSrc, bmpSrc ); - - // 作業DCを作成 - HDC hdcWork = ::CreateCompatibleDC( drawdc ); - - // DIB作成 - BITMAPINFO bmi; - char* pBits; - BITMAPINFOHEADER& bmih = bmi.bmiHeader; - bmih.biSize = sizeof(BITMAPINFOHEADER); - bmih.biWidth = nWidth; - assert(nHeight > 0); - bmih.biHeight = -nHeight; // top down - bmih.biPlanes = 1; - bmih.biBitCount = 32; - bmih.biCompression = BI_RGB; - const int lineStride = ((((bmih.biWidth * bmih.biBitCount) + 31) & ~31) / 8); - bmih.biSizeImage = lineStride * nHeight; - bmih.biXPelsPerMeter = 0; - bmih.biYPelsPerMeter = 0; - bmih.biClrUsed = 0; - bmih.biClrImportant = 0; - HBITMAP bmpWork = ::CreateDIBSection(nullptr, &bmi, DIB_RGB_COLORS, (void**)&pBits, nullptr, 0); - HGDIOBJ bmpWorkOld = ::SelectObject( hdcWork, bmpWork ); - - // 作業DCに転送 - ::StretchBlt( hdcWork, 0, 0, nWidth, nHeight, - hdcSrc, nXSrc, nYSrc, cx(), cy(), SRCCOPY ); - - // ディザカラーを決める - // 淡色テキスト色が背景色と同じなら灰色に避ける、違うなら淡色テキストを使う。 - COLORREF grayText = ::GetSysColor( COLOR_GRAYTEXT ); - COLORREF btnFace = ::GetSysColor( COLOR_3DFACE ); - COLORREF textColor = grayText == btnFace ? RGB( 0x80, 0x80, 0x80 ) : grayText; - auto textColorH = ToHLS( textColor ); - double textColorL; - { - auto r = GetRValue( textColor ); - auto g = GetGValue( textColor ); - auto b = GetBValue( textColor ); - textColorL = (0.299 * r + 0.587 * g + 0.114 * b) / 255.0; //[0,1] - } - double textColorR = (1.0 - textColorL) / 255.0; - - // ディザカラー256諧調の配列を作る - std::array ditherColors; - for ( size_t i = 0; i < ditherColors.size(); ++i ) { - auto ditherColorH( textColorH ); - std::get(ditherColorH) = textColorL + i * textColorR; - ditherColors[i] = FromHLS( ditherColorH ); - } - - // 透過色の変数名が分かりづらいので別名定義する - const COLORREF cTransparent = m_cTrans; - - // スキャンライン全行を順に取得して処理する - for (auto n = 0; n < nHeight; ++n) { - - // スキャンラインを1ピクセルずつ処理する - auto pixels = reinterpret_cast(pBits); - for ( auto m = 0; m < nWidth; ++m ) { - MyRGBQUAD& px = pixels[m]; - - // 透過色はスキップする - if ( px == cTransparent ) continue; - - // ピクセル色をディザカラーに変換する - auto r = px.rgbRed; - auto g = px.rgbGreen; - auto b = px.rgbBlue; - auto mono = (77 * r + 150 * g + 29 * b) >> 8; //[0,255] - - // ディザカラーを書き込む - px.rgbRed = GetRValue( ditherColors[mono] ); - px.rgbGreen = GetGValue( ditherColors[mono] ); - px.rgbBlue = GetBValue( ditherColors[mono] ); - } + ::SelectObject(m_hDC, m_hIconBitmap); - pBits += lineStride; - } - - // 背景を透過させつつ転送 - ::TransparentBlt( drawdc, nXDest, nYDest, nWidth, nHeight, - hdcWork, 0, 0, nWidth, nHeight, cTransparent ); - - // 後始末 - ::SelectObject( hdcWork, bmpWorkOld ); - ::DeleteObject( bmpWork ); - ::DeleteDC( hdcWork ); - ::SelectObject( hdcSrc, bmpSrcOld ); - ::DeleteDC( hdcSrc ); - return; + return true; } /*! @@ -514,20 +250,42 @@ void CImageListMgr::MyDitherBlt( HDC drawdc, int nXDest, int nYDest, * @date 2007.11.02 ryoji アイコン番号が負の場合は描画しない */ bool CImageListMgr::DrawToolIcon( HDC drawdc, LONG x, LONG y, - int imageNo, DWORD fStyle, LONG cx, LONG cy ) const + int imageNo, bool enabled, LONG cx, LONG cy ) const { if ( m_hIconBitmap == nullptr ) return false; if ( imageNo < 0 || m_nIconCount < imageNo ) return false; - if ( (fStyle&ILD_MASK) == ILD_MASK ) { - MyDitherBlt( drawdc, x, y, cx, cy, - (imageNo % MAX_X) * m_cx, (imageNo / MAX_X) * m_cy ); - } else { - MyBitBlt( drawdc, x, y, cx, cy, - (imageNo % MAX_X) * m_cx, (imageNo / MAX_X) * m_cy ); + BLENDFUNCTION bf = { 0 }; + bf.BlendOp = AC_SRC_OVER; + bf.SourceConstantAlpha = enabled ? 255 : 127; // 0-255, 全体の不透明度 + bf.AlphaFormat = AC_SRC_ALPHA; // ピクセル単位の α を使う + ::AlphaBlend(drawdc, x, y, cx, cy, m_hDC, (imageNo % MAX_X) * m_cx, (imageNo / MAX_X) * m_cy, cx, cy, bf); + return true; +} + +bool CImageListMgr::DrawToolIcon(uint32_t* pixels, int imageNo, bool enabled, LONG cx, LONG cy) const +{ + if (m_hIconBitmap == nullptr) + return false; + if (imageNo < 0 || m_nIconCount < imageNo) + return false; + + auto sy = (imageNo / MAX_X) * m_cy; + auto sx = (imageNo % MAX_X) * m_cx; + for (LONG y = 0; y < cy; ++y) { + const auto* srcLine = &m_pBits[m_bmpWidth * (sy + y) + sx]; + auto* dstLine = &pixels[cx * y]; + for (LONG x = 0; x < cx; ++x) { + auto srcPixel = srcLine[x]; + if (!enabled && (srcPixel & 0xFF000000)) { + srcPixel = 0x80000000 | (0x00FFFFFF & srcPixel); + } + dstLine[x] = srcPixel; + } } + return true; } @@ -611,6 +369,9 @@ int CImageListMgr::Add( const WCHAR* szPath ) // ツールイメージをリサイズする HBITMAP CImageListMgr::ResizeToolIcons( HBITMAP bmpSrc, //!< [in] 変換前Bmpのハンドル + uint32_t*& pBits, + LONG& bmpWidth, + LONG& bmpHeight, COLORREF& clrTransparent //!< [out] 透過色 ) const noexcept { @@ -677,12 +438,36 @@ HBITMAP CImageListMgr::ResizeToolIcons( const int cxSmIcon = m_cx; const int cySmIcon = m_cy; + auto setAlpha = [&]() { + uint32_t* pixels = (uint32_t*)pBits; + auto clrTransparent = pixels[0]; + for (int j = 0; j < cxSmIcon * cols * cySmIcon * rows; ++j) { + uint32_t& pixel = pixels[j]; + if (pixel == clrTransparent) { + pixel = 0; + } + else { + pixel |= 0xFF000000; + } + } + }; // アイコンサイズが異なる場合、拡大縮小する if ( cx != cxSmIcon ) { // 作業DCを作成する HDC hdcWork = ::CreateCompatibleDC( hdcSrc ); - HBITMAP bmpWork = ::CreateCompatibleBitmap( hdcSrc, cxSmIcon * cols, cySmIcon * rows ); + + BITMAPINFO bmi = {}; + bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader); + bmi.bmiHeader.biWidth = cxSmIcon * cols; + bmi.bmiHeader.biHeight = -cySmIcon * rows; + bmi.bmiHeader.biPlanes = 1; + bmi.bmiHeader.biBitCount = 32; + bmi.bmiHeader.biCompression = BI_RGB; + + bmpWidth = cxSmIcon * cols; + bmpHeight = cySmIcon * rows; + HBITMAP bmpWork = CreateDIBSection(nullptr, &bmi, DIB_RGB_COLORS, (void**)&pBits, nullptr, 0); HGDIOBJ bmpWorkOld = ::SelectObject( hdcWork, bmpWork ); // 作業DCを透過色で塗りつぶす @@ -698,7 +483,7 @@ HBITMAP CImageListMgr::ResizeToolIcons( for ( int row = 0; row < rows; ++row ) { for ( int col = 0; col < cols; ++col ) { // 拡大・縮小する - ::TransparentBlt( + ::StretchBlt( hdcWork, col * cxSmIcon, row * cySmIcon, @@ -709,11 +494,13 @@ HBITMAP CImageListMgr::ResizeToolIcons( row * cy, cx, cy, - m_cTrans + SRCCOPY ); } } + setAlpha(); + // 作業DCで元Bmpを選択して変換後Bmpを解放する ::SelectObject( hdcWork, bmpWorkOld ); @@ -731,6 +518,9 @@ HBITMAP CImageListMgr::ResizeToolIcons( return bmpWork; } + else { + setAlpha(); + } // 仮想DCで元Bmpを選択して変換前Bmpを解放する ::SelectObject( hdcSrc, hFOldbmp ); @@ -748,30 +538,26 @@ void CImageListMgr::Extend(bool bExtend) if( curY < MAX_Y ) curY = MAX_Y; - HDC hSrcDC = ::CreateCompatibleDC( nullptr ); - HBITMAP hSrcBmpOld = (HBITMAP)::SelectObject( hSrcDC, m_hIconBitmap ); + ::SelectObject( m_hDC, m_hIconBitmap ); //1行拡張したビットマップを作成 - HDC hDestDC = ::CreateCompatibleDC( hSrcDC ); - HBITMAP hDestBmp = ::CreateCompatibleBitmap( hSrcDC, MAX_X * cx(), (curY + (bExtend ? 1 : 0)) * cy() ); - HBITMAP hDestBmpOld = (HBITMAP)::SelectObject( hDestDC, hDestBmp ); + HDC hDestDC = ::CreateCompatibleDC( nullptr ); + HBITMAP hDestBmp = ::CreateCompatibleBitmap( hDestDC, MAX_X * cx(), (curY + (bExtend ? 1 : 0)) * cy() ); + ::SelectObject( hDestDC, hDestBmp ); - ::BitBlt( hDestDC, 0, 0, MAX_X * cx(), curY * cy(), hSrcDC, 0, 0, SRCCOPY ); + ::BitBlt( hDestDC, 0, 0, MAX_X * cx(), curY * cy(), m_hDC, 0, 0, SRCCOPY ); //拡張した部分は透過色で塗る if( bExtend ){ FillSolidRect( hDestDC, 0, curY * cy(), MAX_X * cx(), cy(), m_cTrans ); } - ::SelectObject( hSrcDC, hSrcBmpOld ); ::DeleteObject( m_hIconBitmap ); - ::DeleteDC( hSrcDC ); - - ::SelectObject( hDestDC, hDestBmpOld ); - ::DeleteDC( hDestDC ); + ::DeleteDC( m_hDC ); //ビットマップの差し替え m_hIconBitmap = hDestBmp; + m_hDC = hDestDC; } void CImageListMgr::ResetExtend() diff --git a/sakura_core/uiparts/CImageListMgr.h b/sakura_core/uiparts/CImageListMgr.h index 81031ce22a..707ab3486b 100644 --- a/sakura_core/uiparts/CImageListMgr.h +++ b/sakura_core/uiparts/CImageListMgr.h @@ -61,7 +61,9 @@ class CImageListMgr { @param [in] cy アイコン高さ */ bool DrawToolIcon( HDC drawdc, LONG x, LONG y, - int imageNo, DWORD fStyle, LONG cx, LONG cy ) const; + int imageNo, bool enabled, LONG cx, LONG cy ) const; + + bool DrawToolIcon(uint32_t* pixels, int imageNo, bool enabled, LONG cx, LONG cy) const; //! アイコン数を返す int Count(void) const; // アイコン数 @@ -77,17 +79,6 @@ class CImageListMgr { //! アイコンの追加を元に戻す void ResetExtend(); - /*! - イメージのToolBarへの登録 - - @param hToolBar [in] 登録するToolBar - @param id [in] 登録する先頭アイコン番号 - - @date 2003.07.21 genta ここでは何も行わないが,受け皿だけ残しておく - @date 2003.07.21 genta 戻り型をvoidに変更 - */ - void SetToolBarImages(HWND hToolBar, int id = 0) const {} - protected: int m_cx; //!< width of icon int m_cy; //!< height of icon @@ -102,17 +93,16 @@ class CImageListMgr { @date 2003.07.21 genta */ HBITMAP m_hIconBitmap; + uint32_t* m_pBits = nullptr; + LONG m_bmpWidth = 0; + LONG m_bmpHeight = 0; - int m_nIconCount; //!< アイコンの個数 + HDC m_hDC; - // アイコン描画関数 - void MyBitBlt( HDC drawdc, int nXDest, int nYDest, - int nWidth, int nHeight, int nXSrc, int nYSrc ) const; - void MyDitherBlt( HDC drawdc, int nXDest, int nYDest, - int nWidth, int nHeight, int nXSrc, int nYSrc ) const; + int m_nIconCount; //!< アイコンの個数 //! ツールイメージをリサイズする - HBITMAP ResizeToolIcons( HBITMAP hRscbmp, COLORREF& clrTransparent ) const noexcept; + HBITMAP ResizeToolIcons( HBITMAP hRscbmp, uint32_t*& pBits, LONG& bmpWidth, LONG& bmpHeight, COLORREF& clrTransparent ) const noexcept; //! ビットマップを一行拡張する void Extend(bool = true); diff --git a/sakura_core/uiparts/CMenuDrawer.cpp b/sakura_core/uiparts/CMenuDrawer.cpp index 704d73b04c..76703cb10d 100644 --- a/sakura_core/uiparts/CMenuDrawer.cpp +++ b/sakura_core/uiparts/CMenuDrawer.cpp @@ -28,12 +28,12 @@ #include "func/CKeyBind.h" #include "uiparts/CGraphics.h" #include "util/window.h" +#include "DarkModeSubclass.h" +#include "CEditApp.h" +#include "sakura_rc.h" -// メニューアイコンの背景をボタンの色にする -#define DRAW_MENU_ICON_BACKGROUND_3DFACE - -// メニューの選択色を淡くする -#define DRAW_MENU_SELECTION_LIGHT +#include +#include // @date 2002.2.17 YAZAKI CShareDataのインスタンスは、CProcessにひとつあるのみ。 CMenuDrawer::CMenuDrawer() @@ -726,7 +726,26 @@ void CMenuDrawer::Create( HINSTANCE hInstance, HWND hWndOwner, CImageListMgr* pc m_hInstance = hInstance; m_hWndOwner = hWndOwner; m_pcIcons = pcIcons; - + m_dibs.resize(pcIcons->Count()); + + BITMAPINFO bminfo = {}; + BITMAPINFOHEADER& bmih = bminfo.bmiHeader; + bmih.biSize = sizeof(BITMAPINFOHEADER); + auto cx = ::GetSystemMetrics(SM_CXSMICON); + auto cy = ::GetSystemMetrics(SM_CYSMICON); + bmih.biWidth = (LONG)cx; + bmih.biHeight = -(LONG)cy; + bmih.biPlanes = 1; + bmih.biBitCount = 32; + bmih.biCompression = BI_RGB; + HDC hdc = CreateCompatibleDC(nullptr); + for (int i = 0; i < pcIcons->Count(); ++i) { + DIB& dib = m_dibs[i]; + dib.hBMP = ::CreateDIBSection(hdc, &bminfo, DIB_RGB_COLORS, &dib.pvBits, nullptr, 0); + ::SelectObject(hdc, dib.hBMP); + m_pcIcons->DrawToolIcon(hdc, 0, 0, i, true, cx, cy); + } + ::DeleteDC(hdc); return; } @@ -808,58 +827,49 @@ void CMenuDrawer::MyAppendMenu( _countof(szLabel) ); - /* アイコン用ビットマップを持つものは、オーナードロウにする */ { MyMenuItemInfo item; - item.m_nBitmapIdx = -1; item.m_nFuncId = nFuncId; item.m_cmemLabel.SetString( szLabel ); - // メニュー項目をオーナー描画にして、アイコンを表示する - // 2010.03.29 アクセスキーの分を詰めるためいつもオーナードローにする。ただしVista未満限定 - // Vista以上ではメニューもテーマが適用されるので、オーナードローにすると見た目がXP風になってしまう。 - if( m_pShareData->m_Common.m_sWindow.m_bMenuIcon ){ - nFlagAdd = MF_OWNERDRAW; - } /* 機能のビットマップの情報を覚えておく */ item.m_nBitmapIdx = GetIconIdByFuncId( nForceIconId ); + if( m_pShareData->m_Common.m_sWindow.m_bMenuIcon && item.m_nBitmapIdx != -1 ){ + nFlagAdd = MF_BITMAP; + } m_menuItems.push_back( item ); } }else{ -#ifdef DRAW_MENU_ICON_BACKGROUND_3DFACE - // セパレータかサブメニュー - if( nFlag & (MF_SEPARATOR | MF_POPUP) ){ - if( m_pShareData->m_Common.m_sWindow.m_bMenuIcon ){ - nFlagAdd = MF_OWNERDRAW; - } - } -#endif } // メニュー項目に関する情報を設定します。 MENUITEMINFO mii = { sizeof(MENUITEMINFO) }; mii.cbSize = sizeof(MENUITEMINFO); - mii.fMask = MIIM_CHECKMARKS | MIIM_DATA | MIIM_ID | MIIM_STATE | MIIM_SUBMENU | MIIM_TYPE; + mii.fMask = MIIM_CHECKMARKS | MIIM_DATA | MIIM_ID | MIIM_STATE | MIIM_SUBMENU | MIIM_FTYPE | MIIM_STRING; mii.fType = 0; - if( MF_OWNERDRAW & ( nFlag | nFlagAdd ) ) mii.fType |= MFT_OWNERDRAW; if( MF_SEPARATOR & ( nFlag | nFlagAdd ) ) mii.fType |= MFT_SEPARATOR; if( MF_STRING & ( nFlag | nFlagAdd ) ) mii.fType |= MFT_STRING; if( MF_MENUBREAK & ( nFlag | nFlagAdd ) ) mii.fType |= MFT_MENUBREAK; if( MF_MENUBARBREAK & ( nFlag | nFlagAdd ) ) mii.fType |= MFT_MENUBARBREAK; mii.fState = 0; - if( MF_GRAYED & ( nFlag | nFlagAdd ) ) mii.fState |= MFS_GRAYED; + //if( MF_GRAYED & ( nFlag | nFlagAdd ) ) mii.fState |= MFS_GRAYED; if( MF_CHECKED & ( nFlag | nFlagAdd ) ) mii.fState |= MFS_CHECKED; mii.wID = nFuncId; mii.hSubMenu = (nFlag&MF_POPUP)?((HMENU)nFuncId):nullptr; mii.hbmpChecked = nullptr; mii.hbmpUnchecked = nullptr; + if (MF_BITMAP & (nFlag | nFlagAdd)) { + mii.fMask |= MIIM_BITMAP; + mii.hbmpItem = m_dibs[GetIconIdByFuncId(nForceIconId)].hBMP; + } mii.dwItemData = (ULONG_PTR)this; mii.dwTypeData = szLabel; mii.cch = 0; // メニュー内の指定された位置に、新しいメニュー項目を挿入します。 ::InsertMenuItem( hMenu, 0xFFFFFFFF, TRUE, &mii ); + return; } @@ -891,418 +901,6 @@ inline int CMenuDrawer::GetIconIdByFuncId( int nFuncID ) const return m_tbMyButton[index].iBitmap; } -/*! メニューアイテムの描画サイズを計算 - @param pnItemHeight [out] 高さ。いつも高さを返す - @retval 0 機能がない場合 - @retval 1 <= val 機能のメニュー幅/セパレータの場合はダミーの値 -*/ -int CMenuDrawer::MeasureItem( int nFuncID, int* pnItemHeight ) -{ - // pixel数をベタ書きするとHighDPI環境でずれるのでシステム値を取得して使う - const int cxBorder = ::GetSystemMetrics(SM_CXBORDER); - const int cyBorder = ::GetSystemMetrics(SM_CYBORDER); - const int cxEdge = ::GetSystemMetrics(SM_CXEDGE); - const int cyEdge = ::GetSystemMetrics(SM_CYEDGE); - const int cxFrame = ::GetSystemMetrics(SM_CXFRAME); - const int cyFrame = ::GetSystemMetrics(SM_CYFRAME); - const int cxSmIcon = ::GetSystemMetrics(SM_CXSMICON); - const int cySmIcon = ::GetSystemMetrics(SM_CYSMICON); - - const WCHAR* pszLabel; - CMyRect rc, rcSp; - HDC hdc; - HFONT hFontOld; - - if( F_0 == nFuncID ){ // F_0, なぜか F_SEPARATOR ではない - // セパレータ。フォントの方の通常項目の半分の高さ - *pnItemHeight = m_nMenuFontHeight / 2; - return 30; // ダミーの幅 - }else if( nullptr == ( pszLabel = GetLabel( nFuncID ) ) ){ - *pnItemHeight = m_nMenuHeight; - return 0; - } - //正常な高さは幅と一緒に決める - - hdc = ::GetDC( m_hWndOwner ); - hFontOld = (HFONT)::SelectObject( hdc, m_hFontMenu ); - // DT_EXPANDTABSをやめる - ::DrawText( hdc, pszLabel, -1, &rc, DT_SINGLELINE | DT_VCENTER | DT_CALCRECT ); - ::SelectObject( hdc, hFontOld ); - ::ReleaseDC( m_hWndOwner, hdc ); - -// *pnItemHeight = 20; -// *pnItemHeight = 2 + 15 + 1; - //@@@ 2002.2.2 YAZAKI Windowsの設定でメニューのフォントを大きくすると表示が崩れる問題に対処 - - // インデント + テキスト幅 + アクセスキー隙間 - int nMenuWidth = cxSmIcon / 4 + rc.Width() + cxSmIcon / 2; - if( m_pShareData->m_Common.m_sWindow.m_bMenuIcon ){ - // アイコンと枠 + 縦線隙間 + 縦線 - // 2+[2+16+2]+2 + 2+2 + 1 - nMenuWidth += cxSmIcon + cxEdge * 6 + cxBorder; - }else{ - // WM_MEASUREITEMで報告するメニュー幅より実際の幅は1文字分相当位広いので、その分は加えない - nMenuWidth += ::GetSystemMetrics(SM_CXMENUCHECK) + 2 + 2; - } - // アイコンと枠 or フォント高さと太枠 - // 2+[2+16+2]+2 or 2+9+2 - *pnItemHeight = std::max(cySmIcon + cyEdge * 4, m_nMenuHeight + cyEdge * 2); - return nMenuWidth; -} - -/*! メニューアイテム描画 - @date 2001.12.21 YAZAKI デバッグモードでもメニューを選択したらハイライト。 - @date 2003.08.27 Moca システムカラーのブラシはCreateSolidBrushをやめGetSysColorBrushに - @date 2010.07.24 Moca アイコン部分をボタン色にしてフラット表示にするなどの変更 - 大きいフォント、黒背景対応 -*/ -void CMenuDrawer::DrawItem( DRAWITEMSTRUCT* lpdis ) -{ - // pixel数をベタ書きするとHighDPI環境でずれるのでシステム値を取得して使う - const int cxBorder = ::GetSystemMetrics(SM_CXBORDER); - const int cyBorder = ::GetSystemMetrics(SM_CYBORDER); - const int cxEdge = ::GetSystemMetrics(SM_CXEDGE); - const int cyEdge = ::GetSystemMetrics(SM_CYEDGE); - const int cxFrame = ::GetSystemMetrics(SM_CXFRAME); - const int cyFrame = ::GetSystemMetrics(SM_CYFRAME); - const int cxSmIcon = ::GetSystemMetrics(SM_CXSMICON); - const int cySmIcon = ::GetSystemMetrics(SM_CYSMICON); - - CMyRect rcItem( lpdis->rcItem ); - - const bool bMenuIconDraw = !!m_pShareData->m_Common.m_sWindow.m_bMenuIcon; - const int nCxCheck = ::GetSystemMetrics(SM_CXMENUCHECK); - const int nCyCheck = ::GetSystemMetrics(SM_CYMENUCHECK); - - // アイコンとテキストの間の縦線の位置 - const int nIndentLeft = bMenuIconDraw - ? cxSmIcon + cxEdge * 6 + cxBorder - : cxEdge * 2 + nCxCheck; - - // サブメニューの|>の分は必要 最低8ぐらい - const int nIndentRight = cxSmIcon / 2; - - // 2010.07.24 Moca アイコンを描くときにチラつくので、バックサーフェスを使う - const bool bBackSurface = bMenuIconDraw; - const int nTargetWidth = lpdis->rcItem.right - lpdis->rcItem.left; - const int nTargetHeight = lpdis->rcItem.bottom - lpdis->rcItem.top; - HDC hdcOrg = nullptr; - HDC hdc = nullptr; - if( bBackSurface ){ - hdcOrg = lpdis->hDC; - if( m_hCompDC && nTargetWidth <= m_nCompBitmapWidth && nTargetHeight <= m_nCompBitmapHeight ){ - hdc = m_hCompDC; - }else{ - if( m_hCompDC ){ - DeleteCompDC(); - } - hdc = m_hCompDC = ::CreateCompatibleDC( hdcOrg ); - m_hCompBitmap = ::CreateCompatibleBitmap( hdcOrg, nTargetWidth + 20, nTargetHeight + 4 ); - m_hCompBitmapOld = (HBITMAP)::SelectObject( hdc, m_hCompBitmap ); - m_nCompBitmapWidth = nTargetWidth + 20; - m_nCompBitmapHeight = nTargetHeight + 4; - } - ::SetWindowOrgEx( hdc, lpdis->rcItem.left, lpdis->rcItem.top, nullptr ); - }else{ - hdc = lpdis->hDC; - } - - // 作画範囲を背景色で矩形塗りつぶし - if( lpdis->itemState & ODS_SELECTED ){ - // アイテムが選択されている - RECT rc1 = lpdis->rcItem; - if( bMenuIconDraw -#ifdef DRAW_MENU_ICON_BACKGROUND_3DFACE -#else - && -1 != m_menuItems[nItemIndex].m_nBitmapIdx || lpdis->itemState & ODS_CHECKED -#endif - ){ - //rc1.left += (nIndentLeft - 3); - } -#ifdef DRAW_MENU_SELECTION_LIGHT - HPEN hPenBorder = ::CreatePen( PS_SOLID, 1, ::GetSysColor( COLOR_HIGHLIGHT ) ); - HPEN hOldPen = (HPEN)::SelectObject( hdc, hPenBorder ); - COLORREF colHilight = ::GetSysColor( COLOR_HIGHLIGHT ); - COLORREF colMenu = ::GetSysColor( COLOR_MENU ); - BYTE valR = ((GetRValue(colHilight) * 4 + GetRValue(colMenu) * 6) / 10) | 0x18; - BYTE valG = ((GetGValue(colHilight) * 4 + GetGValue(colMenu) * 6) / 10) | 0x18; - BYTE valB = ((GetBValue(colHilight) * 4 + GetBValue(colMenu) * 6) / 10) | 0x18; - HBRUSH hBrush = ::CreateSolidBrush( RGB(valR, valG, valB) ); - HBRUSH hOldBrush = (HBRUSH)::SelectObject( hdc, hBrush ); - ::Rectangle( hdc, rc1.left, rc1.top, rc1.right, rc1.bottom ); - ::SelectObject( hdc, hOldPen ); - ::SelectObject( hdc, hOldBrush ); - ::DeleteObject( hPenBorder ); - ::DeleteObject( hBrush ); -#else - /* 選択ハイライト矩形 */ - ::MyFillRect( hdc, rc1, COLOR_HIGHLIGHT ); -#endif -#ifdef DRAW_MENU_ICON_BACKGROUND_3DFACE - }else if( bMenuIconDraw ){ - // アイコン部分の背景を灰色にする - CMyRect rcFillMenuBack( rcItem ); - rcFillMenuBack.left += nIndentLeft; - ::MyFillRect( hdc, rcFillMenuBack, COLOR_MENU ); - -// hBrush = ::GetSysColorBrush( COLOR_3DFACE ); - COLORREF colMenu = ::GetSysColor( COLOR_MENU ); - COLORREF colFace = ::GetSysColor( COLOR_3DFACE ); - COLORREF colIconBack; - // 明度らしきもの - if( 64 < t_abs(t_max(t_max(GetRValue(colFace),GetGValue(colFace)),GetBValue(colFace)) - - t_max(t_max(GetRValue(colMenu),GetGValue(colMenu)),GetBValue(colMenu))) ){ - colIconBack = colFace; - }else{ - // 明るさが近いなら混色にして(XPテーマ等で)違和感を減らす - BYTE valR = ((GetRValue(colFace) * 7 + GetRValue(colMenu) * 3) / 10); - BYTE valG = ((GetGValue(colFace) * 7 + GetGValue(colMenu) * 3) / 10); - BYTE valB = ((GetBValue(colFace) * 7 + GetBValue(colMenu) * 3) / 10); - colIconBack = RGB(valR, valG, valB); - } - - CMyRect rcIconBk( rcItem ); - rcIconBk.right = rcItem.left + nIndentLeft; - ::MyFillRect( hdc, rcIconBk, colIconBack ); - - }else{ - // アイテム矩形塗りつぶし - ::MyFillRect( hdc, lpdis->rcItem, COLOR_MENU ); - } -#else - }else{ - ::MyFillRect( hdc, lpdis->rcItem, COLOR_MENU ); - } -#endif - - if( bMenuIconDraw ){ - // アイコンとテキストの間に縦線を描画する - int nSepColor = (::GetSysColor(COLOR_3DSHADOW) != ::GetSysColor(COLOR_MENU) ? COLOR_3DSHADOW : COLOR_3DHIGHLIGHT); - HPEN hPen = ::CreatePen( PS_SOLID, cxBorder, ::GetSysColor(nSepColor) ); - HPEN hPenOld = (HPEN)::SelectObject( hdc, hPen ); - ::MoveToEx( hdc, lpdis->rcItem.left + nIndentLeft, lpdis->rcItem.top, nullptr ); - ::LineTo( hdc, lpdis->rcItem.left + nIndentLeft, lpdis->rcItem.bottom ); - ::SelectObject( hdc, hPenOld ); - ::DeleteObject( hPen ); - - } - - if( lpdis->itemID == F_0 ){ - // セパレータの作画(セパレータのFuncCodeはF_SEPARETORではなくF_0) - int y = lpdis->rcItem.top + (lpdis->rcItem.bottom - lpdis->rcItem.top) / 2; - int nSepColor = (::GetSysColor(COLOR_3DSHADOW) != ::GetSysColor(COLOR_MENU) ? COLOR_3DSHADOW : COLOR_3DHIGHLIGHT); - HPEN hPen = ::CreatePen( PS_SOLID, 1, ::GetSysColor(nSepColor) ); - HPEN hPenOld = (HPEN)::SelectObject( hdc, hPen ); - ::MoveToEx( hdc, lpdis->rcItem.left + (bMenuIconDraw ? nIndentLeft : cxEdge + cxBorder) + cxEdge, y, nullptr ); - ::LineTo( hdc, lpdis->rcItem.right - cxEdge, y ); - ::SelectObject( hdc, hPenOld ); - ::DeleteObject( hPen ); - - if( bBackSurface ){ - ::BitBlt( hdcOrg, lpdis->rcItem.left, lpdis->rcItem.top, nTargetWidth, nTargetHeight, - hdc, lpdis->rcItem.left, lpdis->rcItem.top, SRCCOPY ); - } - return; // セパレータ。作画終了 - } - - // テキスト前景色を決定する - COLORREF textColor; - if( lpdis->itemState & ODS_DISABLED ){ - // アイテムが使用不可(淡色表示にする) - textColor = ::GetSysColor( COLOR_GRAYTEXT ); - }else if( lpdis->itemState & ODS_SELECTED ){ -#ifdef DRAW_MENU_SELECTION_LIGHT - textColor = ::GetSysColor( COLOR_MENUTEXT ); -#else - textColor = ::GetSysColor( COLOR_HIGHLIGHTTEXT ); -#endif - }else{ - textColor = ::GetSysColor( COLOR_MENUTEXT ); - } - -#ifdef _DEBUG - // デバッグ用:メニュー項目に対して、ヘルプがない場合に前景色を青くする - // メニュー項目に関する情報を取得します。 - MENUITEMINFO mii = { sizeof(MENUITEMINFO) }; - mii.fMask = MIIM_ID | MIIM_STATE | MIIM_SUBMENU; - if( 0 != ::GetMenuItemInfo( (HMENU)lpdis->hwndItem, lpdis->itemID, FALSE, &mii ) - && nullptr == mii.hSubMenu - && 0 == ::FuncID_To_HelpContextID( (EFunctionCode)lpdis->itemID ) /* 機能IDに対応するメニューコンテキスト番号を返す */ - ){ - //@@@ 2001.12.21 YAZAKI - if( lpdis->itemState & ODS_SELECTED ){ - textColor = ::GetSysColor( COLOR_HIGHLIGHTTEXT ); // ハイライトカラー - } - else { - textColor = RGB( 0, 0, 255 ); // 青くしてる。 - } - } -#endif - - // テキスト矩形(インデント込み) - CMyRect rcText( lpdis->rcItem ); - rcText.left += nIndentLeft + cxSmIcon / 4; - rcText.right -= nIndentRight; - - const int nItemIndex = Find( (int)lpdis->itemID ); - LPCWSTR pszItemStr = m_menuItems[nItemIndex].m_cmemLabel.GetStringPtr(); - size_t nItemStrLen = m_menuItems[nItemIndex].m_cmemLabel.GetStringLength(); - - int nBkModeOld = ::SetBkMode( hdc, TRANSPARENT ); - HFONT hFontOld = (HFONT)::SelectObject( hdc, m_hFontMenu ); - COLORREF textColorOld = (COLORREF)::SetTextColor( hdc, textColor ); - - /* TAB文字の前と後ろに分割してテキストを描画する */ - size_t j; - for( j = 0; j < nItemStrLen; ++j ){ - if( pszItemStr[j] == L'\t' ){ - break; - } - } - /* TAB文字の前側のテキストを描画する */ - ::DrawText( - hdc, - pszItemStr, - static_cast(j), - &rcText, - DT_LEFT | DT_VCENTER | DT_SINGLELINE - ); - /* TAB文字の後ろ側のテキストを描画する */ - if( j < nItemStrLen ){ - ::DrawText( - hdc, - &pszItemStr[j + 1], - static_cast(nItemStrLen - ( j + 1 )), - &rcText, - DT_RIGHT | DT_VCENTER | DT_SINGLELINE - ); - } - ::SetTextColor( hdc, textColorOld ); - ::SelectObject( hdc, hFontOld ); - ::SetBkMode( hdc, nBkModeOld ); - - // アイコン矩形 - CMyRect rcIcon( rcItem ); - rcIcon.left += ( rcItem.Height() - m_pcIcons->cy() ) / 2; - rcIcon.top += ( rcItem.Height() - m_pcIcons->cy() ) / 2; - rcIcon.SetSize( m_pcIcons->cx(), m_pcIcons->cy() ); - - // 枠は アイコン横幅xメニュー縦幅で表示し真ん中にアイコンを置く - if( bMenuIconDraw && (lpdis->itemState & ODS_CHECKED) ){ - { - // フラットな枠 + 半透明の背景色 - CMyRect rcFrame( rcIcon ); - ::InflateRect( &rcFrame, cxEdge * 2, cyEdge * 2 ); - ::MyFillRect( hdc, rcFrame, COLOR_HIGHLIGHT ); - - COLORREF colHilight = ::GetSysColor( COLOR_HIGHLIGHT ); - COLORREF colMenu = ::GetSysColor( COLOR_MENU ); - // 16bitカラーの黒色でも少し明るくするように or 0x18 する - BYTE valR; - BYTE valG; - BYTE valB; - if( lpdis->itemState & ODS_SELECTED ){ // 選択状態 - valR = ((GetRValue(colHilight) * 6 + GetRValue(colMenu) * 4) / 10) | 0x18; - valG = ((GetGValue(colHilight) * 6 + GetGValue(colMenu) * 4) / 10) | 0x18; - valB = ((GetBValue(colHilight) * 6 + GetBValue(colMenu) * 4) / 10) | 0x18; - } else { // 非選択状態 - valR = ((GetRValue(colHilight) * 2 + GetRValue(colMenu) * 8) / 10) | 0x18; - valG = ((GetGValue(colHilight) * 2 + GetGValue(colMenu) * 8) / 10) | 0x18; - valB = ((GetBValue(colHilight) * 2 + GetBValue(colMenu) * 8) / 10) | 0x18; - } - CMyRect rcBkFrame( rcIcon ); - ::InflateRect( &rcBkFrame, cxEdge , cyEdge ); - ::MyFillRect( hdc, rcBkFrame, RGB( valR, valG, valB ) ); - } - } - - /* 機能の画像が存在するならメニューアイコン?を描画する */ - if( bMenuIconDraw && -1 != m_menuItems[nItemIndex].m_nBitmapIdx ){ - // アイコン番号 - int nIconNo = m_menuItems[nItemIndex].m_nBitmapIdx; - - // メニューアイコン描画 - m_pcIcons->DrawToolIcon( - hdc, - rcIcon.left, - rcIcon.top, - nIconNo, - ( lpdis->itemState & ODS_DISABLED ) ? ILD_MASK : ILD_NORMAL, - cxSmIcon, - cySmIcon - ); - - }else{ - // チェックボックスを表示 - if( lpdis->itemState & ODS_CHECKED ){ - /* チェックマークの表示 */ - if( bMenuIconDraw ){ - // だいたい中心座標 - int nX = rcItem.left + rcIcon.Height() / 2; - int nY = rcIcon.top + rcIcon.Height() /2; - HPEN hPen = nullptr; - HPEN hPenOld = nullptr; - // 2010.05.31 チェックの色を黒(未指定)からテキスト色に変更 - hPen = ::CreatePen( PS_SOLID, 1, ::GetSysColor(COLOR_MENUTEXT) ); - hPenOld = (HPEN)::SelectObject( hdc, hPen ); -#if 0 -// チェックマークも自分で書く場合 - if( !bMenuIconDraw ){ - nX -= 4; // iconがない場合、左マージン=2アイコン枠=2分がない - } -#endif - const int nBASE = 100*100; // 座標,nScale共に0.01単位 - // 16dot幅しかないので 1.0倍から2.1倍までスケールする(10-23) - const int nScale = t_max(100, t_min(210, int((lpdis->rcItem.bottom - lpdis->rcItem.top - 2) * 100) / (16-2) )); - for( int nBold = 1; nBold <= (281*nScale)/nBASE; nBold++ ){ - ::MoveToEx( hdc, nX - (187*nScale)/nBASE, nY - (187*nScale)/nBASE, nullptr ); - ::LineTo( hdc, nX - (0*nScale)/nBASE, nY - (0*nScale)/nBASE ); - ::LineTo( hdc, nX + (468*nScale)/nBASE, nY - (468*nScale)/nBASE ); - nY++; - } - if( hPen ){ - ::SelectObject( hdc, hPenOld ); - ::DeleteObject( hPen ); - } - }else{ - // OSにアイコン作画をしてもらう(黒背景等対応) - HDC hdcMem = ::CreateCompatibleDC( hdc ); - HBITMAP hBmpMono = ::CreateBitmap( nCxCheck, nCyCheck, 1, 1, nullptr ); - HBITMAP hOld = (HBITMAP)::SelectObject( hdcMem, hBmpMono ); - RECT rcCheck = {0,0, nCxCheck, nCyCheck}; - ::DrawFrameControl( hdcMem, &rcCheck, DFC_MENU, DFCS_MENUCHECK ); - COLORREF colTextOld = ::SetTextColor(hdc, RGB(0,0,0) ); - COLORREF colBackOld = ::SetBkColor(hdc, RGB(255,255,255) ); - ::BitBlt( hdc, lpdis->rcItem.left+2, lpdis->rcItem.top+2, nCxCheck, nCyCheck, hdcMem, 0, 0, SRCAND ); - ::SetTextColor( hdc, textColor ); - ::SetBkColor( hdc, RGB(0,0,0) ); - ::BitBlt( hdc, lpdis->rcItem.left+2, lpdis->rcItem.top+2, nCxCheck, nCyCheck, hdcMem, 0, 0, SRCPAINT ); - ::SetTextColor( hdc, colTextOld ); - ::SetBkColor( hdc, colBackOld ); - ::SelectObject( hdcMem, hOld ); - ::DeleteObject( hBmpMono ); - ::DeleteDC( hdcMem ); - } - } - } - if( bBackSurface ){ - ::BitBlt( hdcOrg, lpdis->rcItem.left, lpdis->rcItem.top, nTargetWidth, nTargetHeight, - hdc, lpdis->rcItem.left, lpdis->rcItem.top, SRCCOPY ); - } - return; -} - -/*! - 作画終了 - メニューループ終了時に呼び出すとリソース節約になる - - @date 20100724 Moca バックサーフェス用に新設 -*/ -void CMenuDrawer::EndDrawMenu() -{ - DeleteCompDC(); -} - void CMenuDrawer::DeleteCompDC() { if( m_hCompDC ){ diff --git a/sakura_core/uiparts/CMenuDrawer.h b/sakura_core/uiparts/CMenuDrawer.h index af7b8af203..0f13ad3ed1 100644 --- a/sakura_core/uiparts/CMenuDrawer.h +++ b/sakura_core/uiparts/CMenuDrawer.h @@ -70,9 +70,6 @@ class CMenuDrawer { MyAppendMenu(hMenu,nFlag,nFuncId,pszLabel,L"",bAddKeyStr,nForceIconId); } - int MeasureItem( int nFuncID, int* pnItemHeight ); /* メニューアイテムの描画サイズを計算 */ - void DrawItem( DRAWITEMSTRUCT* ); /* メニューアイテム描画 */ - void EndDrawMenu(); LRESULT OnMenuChar( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ); int FindToolbarNoFromCommandId( int idCommand, bool bOnlyFunc = true )const; // ツールバーNoの取得 int GetIconIdByFuncId( int nIndex ) const; @@ -122,6 +119,11 @@ class CMenuDrawer HDC m_hCompDC; int m_nCompBitmapHeight; int m_nCompBitmapWidth; + struct DIB { + HBITMAP hBMP; + void* pvBits; + }; + std::vector m_dibs; public: // 2010.01.30 syat アイコンイメージリストをprivate->public diff --git a/sakura_core/util/shell.cpp b/sakura_core/util/shell.cpp index c6a09ad6bc..1d432e849d 100644 --- a/sakura_core/util/shell.cpp +++ b/sakura_core/util/shell.cpp @@ -11,6 +11,7 @@ #include #include #include // Nov. 3, 2005 genta //CDERR_FINDRESFAILURE等 +#include #include "util/shell.h" #include "util/string_ex2.h" #include "util/file.h" @@ -22,8 +23,7 @@ #include "extmodule/CHtmlHelp.h" #include "config/app_constants.h" #include "String_define.h" -#include - +#include "DarkModeSubclass.h" /* フォルダー選択ダイアログ */ BOOL SelectDir( HWND hWnd, const WCHAR* pszTitle, const WCHAR* pszInitFolder, WCHAR* strFolderName, size_t nMaxCount ) @@ -123,6 +123,7 @@ static LRESULT CALLBACK PropSheetWndProc( HWND hwnd, UINT uMsg, WPARAM wParam, L pt.y = rcOk.top; ::ScreenToClient( hwnd, &pt ); ::MoveWindow( hwndBtn, pt.x, pt.y, DpiScaleX(140), rcOk.bottom - rcOk.top, FALSE ); + } break; @@ -230,6 +231,8 @@ static int CALLBACK PropSheetProc( HWND hwndDlg, UINT uMsg, [[maybe_unused]] LPA ::SendMessage( hwndBtn, WM_SETFONT, (WPARAM)hFont, MAKELPARAM( FALSE, 0 ) ); ::SetWindowPos( hwndBtn, ::GetDlgItem( hwndDlg, IDHELP), 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE ); } + + DarkMode::setDarkWndSafe(hwndDlg); } return 0; } @@ -553,12 +556,14 @@ BOOL MySelectFont( LOGFONT* plf, INT* piPointSize, HWND hwndDlgOwner, bool Fixed cf.lStructSize = sizeof( cf ); cf.hwndOwner = hwndDlgOwner; cf.hDC = nullptr; - cf.Flags = CF_SCREENFONTS | CF_INITTOLOGFONTSTRUCT; + cf.Flags = CF_SCREENFONTS | CF_INITTOLOGFONTSTRUCT | CF_EFFECTS | CF_ENABLEHOOK; if( FixedFontOnly ){ //FIXEDフォント cf.Flags |= CF_FIXEDPITCHONLY; } cf.lpLogFont = plf; + cf.lpfnHook = static_cast(DarkMode::HookDlgProc); + cf.hInstance = GetModuleHandleW(nullptr); if( !ChooseFont( &cf ) ){ #ifdef _DEBUG DWORD nErr; diff --git a/sakura_core/view/CEditView.cpp b/sakura_core/view/CEditView.cpp index fef1b9d7bf..7ee3ff8feb 100644 --- a/sakura_core/view/CEditView.cpp +++ b/sakura_core/view/CEditView.cpp @@ -48,6 +48,7 @@ #include "CSelectLang.h" #include "String_define.h" +#include "DarkModeSubclass.h" LRESULT CALLBACK EditViewWndProc( HWND, UINT, WPARAM, LPARAM ); VOID CALLBACK EditViewTimerProc( HWND, UINT, UINT_PTR, DWORD ); @@ -294,6 +295,7 @@ BOOL CEditView::Create( if( nullptr == GetHwnd() ){ return FALSE; } + DarkMode::setDarkRichEdit(GetHwnd()); if( !m_bMiniMap ){ m_pcDropTarget = new CDropTarget( this ); @@ -455,6 +457,7 @@ LRESULT CEditView::DispatchEvent( if (m_hwndSizeBoxPlaceholder == nullptr) { return -1; } + DarkMode::setWindowCtlColorSubclass(hwnd); return 0L; // From Here 2007.09.09 Moca 互換BMPによる画面バッファ diff --git a/sakura_core/view/CEditView_Scroll.cpp b/sakura_core/view/CEditView_Scroll.cpp index 384b3041d5..f65680498f 100644 --- a/sakura_core/view/CEditView_Scroll.cpp +++ b/sakura_core/view/CEditView_Scroll.cpp @@ -31,6 +31,7 @@ #include "types/CTypeSupport.h" #include #include "config/app_constants.h" +#include "DarkModeSubclass.h" /*! スクロールバー作成 @date 2006.12.19 ryoji 新規作成(CEditView::Createから分離) @@ -100,6 +101,9 @@ BOOL CEditView::CreateScrollBar() ::ShowWindow( m_hwndSizeBox, SW_HIDE ); ::ShowWindow( m_hwndSizeBoxPlaceholder, SW_SHOW ); } + + DarkMode::setChildCtrlsTheme(GetHwnd()); + return TRUE; } diff --git a/sakura_core/window/CEditWnd.cpp b/sakura_core/window/CEditWnd.cpp index 226160357e..87f4f8ab11 100644 --- a/sakura_core/window/CEditWnd.cpp +++ b/sakura_core/window/CEditWnd.cpp @@ -61,6 +61,7 @@ #include "recent/CRecentEditNode.h" #include "recent/CRecentFile.h" #include "recent/CRecentFolder.h" +#include "DarkModeSubclass.h" //@@@ 2002.01.14 YAZAKI 印刷プレビューをCPrintPreviewに独立させたので // 定義を削除 @@ -615,6 +616,8 @@ HWND CEditWnd::Create( if(!hWnd)return nullptr; m_hWnd = hWnd; + DarkMode::setDarkTitleBarEx(hWnd, true); + // 初回アイドリング検出用のゼロ秒タイマーをセットする // 2008.04.19 ryoji // ゼロ秒タイマーが発動(初回アイドリング検出)したら MYWM_FIRST_IDLE を起動元プロセスにポストする。 // ※起動元での起動先アイドリング検出については CControlTray::OpenNewEditor を参照 @@ -686,6 +689,10 @@ HWND CEditWnd::Create( /* バーの配置終了 */ EndLayoutBars( FALSE ); + DarkMode::setChildCtrlsTheme(hWnd); + DarkMode::setWindowMenuBarSubclass(hWnd); + DarkMode::setChildCtrlsSubclassAndTheme(hWnd); + // -- -- -- -- その他調整など -- -- -- -- // // 画面表示直前にDispatchEventを有効化する @@ -910,6 +917,7 @@ void CEditWnd::LayoutMainMenu() DestroyMenu( hMenuOld ); } + DarkMode::setWindowMenuBarSubclass(hWnd); DrawMenuBar( hWnd ); } @@ -1055,6 +1063,9 @@ void CEditWnd::MessageLoop( void ) MSG msg; int ret; + auto hWnd = GetHwnd(); + DarkMode::setDarkWndNotifySafeEx(hWnd, false, true); + while(GetHwnd()) { //メッセージ取得 @@ -1204,34 +1215,8 @@ LRESULT CEditWnd::DispatchEvent( } } return 0; - }else{ - switch( lpdis->CtlType ){ - case ODT_MENU: /* オーナー描画メニュー */ - /* メニューアイテム描画 */ - m_cMenuDrawer.DrawItem( lpdis ); - return TRUE; - } } return FALSE; - case WM_MEASUREITEM: - idCtl = (UINT) wParam; // control identifier - lpmis = (MEASUREITEMSTRUCT*) lParam; // item-size information - switch( lpmis->CtlType ){ - case ODT_MENU: /* オーナー描画メニュー */ -// CMenuDrawer* pCMenuDrawer; -// pCMenuDrawer = (CMenuDrawer*)lpmis->itemData; - -// MYTRACE( L"WM_MEASUREITEM lpmis->itemID=%d\n", lpmis->itemID ); - /* メニューアイテムの描画サイズを計算 */ - nItemWidth = m_cMenuDrawer.MeasureItem( lpmis->itemID, &nItemHeight ); - if( 0 < nItemWidth ){ - lpmis->itemWidth = nItemWidth; - lpmis->itemHeight = nItemHeight; - } - return TRUE; - } - return FALSE; - case WM_PAINT: return OnPaint( hwnd, uMsg, wParam, lParam ); @@ -1371,7 +1356,6 @@ LRESULT CEditWnd::DispatchEvent( if( nullptr != m_cStatusBar.GetStatusHwnd() ){ m_cStatusBar.SetStatusText(0, SBT_NOBORDERS, L""); } - m_cMenuDrawer.EndDrawMenu(); /* メッセージの配送 */ return Views_DispatchEvent( hwnd, uMsg, wParam, lParam ); @@ -1499,14 +1483,6 @@ LRESULT CEditWnd::DispatchEvent( if( nId != 0 ) OnCommand( (WORD)0 /*メニュー*/, (WORD)nId, nullptr ); } return FALSE; - // From Here Jul. 21, 2003 genta - case NM_CUSTOMDRAW: - if( pnmh->hwndFrom == m_cToolbar.GetToolbarHwnd() ){ - // ツールバーのOwner Draw - return m_cToolbar.ToolBarOwnerDraw( (LPNMCUSTOMDRAW)pnmh ); - } - break; - // To Here Jul. 21, 2003 genta } return 0L; case WM_COMMAND: @@ -1988,6 +1964,7 @@ LRESULT CEditWnd::DispatchEvent( } EndLayoutBars(); // 2006.12.19 ryoji } + DarkMode::setChildCtrlsSubclassAndTheme(hwnd); return 0L; //by 鬼 (2) MYWM_CHECKSYSMENUDBLCLKは不要に, WM_LBUTTONDBLCLK追加 @@ -2256,6 +2233,11 @@ void CEditWnd::InitMenu( HMENU hMenu, UINT uPos, BOOL fSystemMenu ) int i; HMENU hMenuPopUp; + MENUINFO mi = { sizeof(mi) }; + mi.fMask = MIM_STYLE; + mi.dwStyle = MNS_CHECKORBMP; + SetMenuInfo(hMenu, &mi); + if( hMenu == ::GetSubMenu( ::GetMenu( GetHwnd() ), uPos ) && !fSystemMenu ){ // 情報取得 @@ -2359,7 +2341,7 @@ void CEditWnd::InitMenu( HMENU hMenu, UINT uPos, BOOL fSystemMenu ) /* 機能が利用可能か調べる */ // Jan. 8, 2006 genta 機能が有効な場合には明示的に再設定しないようにする. if( ! IsFuncEnable( GetDocument(), m_pShareData, id ) ){ - fuFlags = MF_BYCOMMAND | MF_GRAYED; + fuFlags = MF_BYCOMMAND | MF_DISABLED; ::EnableMenuItem(hMenu, id, fuFlags); } @@ -3944,8 +3926,8 @@ void CEditWnd::PrintMenubarMessage( const WCHAR* msg ) rc.right = rc.left + nStrLen * m_nCaretPosInfoCharWidth + 2; rc.top = po.y - m_nCaretPosInfoCharHeight - 2; rc.bottom = rc.top + m_nCaretPosInfoCharHeight; - ::SetTextColor( hdc, ::GetSysColor( COLOR_MENUTEXT ) ); - ::SetBkColor( hdc, ::GetSysColor( COLOR_MENUBAR ) ); + ::SetTextColor( hdc, DarkMode::getTextColor() ); + ::SetBkColor( hdc, DarkMode::getDlgBackgroundColor()); { const WCHAR* pchText = m_pszMenubarMessage; const ULONG cchText = nStrLen; diff --git a/sakura_core/window/CMainStatusBar.cpp b/sakura_core/window/CMainStatusBar.cpp index b8004f7110..c068fcef7b 100644 --- a/sakura_core/window/CMainStatusBar.cpp +++ b/sakura_core/window/CMainStatusBar.cpp @@ -9,6 +9,7 @@ #include "window/CEditWnd.h" #include "CEditApp.h" #include "apiwrap/CommonControl.h" +#include "DarkModeSubclass.h" CMainStatusBar::CMainStatusBar(CEditWnd* pOwner) : m_pOwner(pOwner) @@ -34,6 +35,8 @@ void CMainStatusBar::CreateStatusBar() nullptr ); + DarkMode::setStatusBarCtrlSubclass(m_hwndStatusBar); + /* プログレスバー */ m_hwndProgressBar = ::CreateWindowEx( WS_EX_TOOLWINDOW, @@ -50,6 +53,8 @@ void CMainStatusBar::CreateStatusBar() nullptr ); + DarkMode::setProgressBarCtrlSubclass(m_hwndProgressBar); + if( nullptr != m_pOwner->m_cFuncKeyWnd.GetHwnd() ){ m_pOwner->m_cFuncKeyWnd.SizeBox_ONOFF( FALSE ); } diff --git a/sakura_core/window/CMainToolBar.cpp b/sakura_core/window/CMainToolBar.cpp index 2e8d1a3fec..c2fc4a4c6b 100644 --- a/sakura_core/window/CMainToolBar.cpp +++ b/sakura_core/window/CMainToolBar.cpp @@ -19,6 +19,7 @@ #include "apiwrap/StdControl.h" #include "CSelectLang.h" #include "String_define.h" +#include "DarkModeSubclass.h" CMainToolBar::CMainToolBar(CEditWnd* pOwner) : m_pOwner(pOwner) @@ -129,6 +130,8 @@ void CMainToolBar::CreateToolBar( void ) CEditApp::getInstance()->GetAppInstance(), nullptr ); + SetWindowTheme(m_hwndReBar, L"", L""); + SendMessage(m_hwndReBar, RB_SETBKCOLOR, 0, DarkMode::getBackgroundColor()); if( nullptr == m_hwndReBar ){ TopWarningMessage( m_pOwner->GetHwnd(), LS(STR_ERR_DLGEDITWND04) ); @@ -176,7 +179,6 @@ void CMainToolBar::CreateToolBar( void ) // 2006.09.06 ryoji ツールバーをサブクラス化する ::SetWindowSubclass(m_hwndToolBar, &ToolBarWndProc, 0, 0); - // pixel数をベタ書きするとHighDPI環境でずれるのでシステム値を取得して使う const int cxBorder = DpiScaleX( 1 ); const int cyBorder = DpiScaleY( 1 ); const int cxEdge = DpiScaleX( 1 ); @@ -187,16 +189,15 @@ void CMainToolBar::CreateToolBar( void ) const int cyToolButton = cyBorder + cyEdge + cySmIcon + cyEdge + cyBorder; //22 Toolbar_SetButtonSize( m_hwndToolBar, cxToolButton, cyToolButton ); // 2009.10.01 ryoji 高DPI対応スケーリング Toolbar_ButtonStructSize( m_hwndToolBar, sizeof(TBBUTTON) ); - // Oct. 12, 2000 genta - // 既に用意されているImage Listをアイコンとして登録 - m_pcIcons->SetToolBarImages( m_hwndToolBar ); /* ツールバーにボタンを追加 */ int count = 0; //@@@ 2002.06.15 MIK int nToolBarButtonNum = 0;// 2005/8/29 aroka // From Here 2005.08.29 aroka // はじめにツールバー構造体の配列を作っておく - TBBUTTON *pTbbArr = new TBBUTTON[GetDllShareData().m_Common.m_sToolBar.m_nToolBarButtonNum]; - for( i = 0; i < GetDllShareData().m_Common.m_sToolBar.m_nToolBarButtonNum; ++i ){ + const auto nButtons = GetDllShareData().m_Common.m_sToolBar.m_nToolBarButtonNum; + + TBBUTTON* pTbbArr = new TBBUTTON[nButtons]; + for (i = 0; i < nButtons; ++i) { nIdx = GetDllShareData().m_Common.m_sToolBar.m_nToolBarButtonIdxArr[i]; pTbbArr[nToolBarButtonNum] = m_pOwner->GetMenuDrawer().getButton(nIdx); // セパレータが続くときはひとつにまとめる @@ -219,6 +220,42 @@ void CMainToolBar::CreateToolBar( void ) } // To Here 2005.08.29 aroka + BITMAPINFO bminfo = {}; + BITMAPINFOHEADER& bmih = bminfo.bmiHeader; + bmih.biSize = sizeof(BITMAPINFOHEADER); + bmih.biWidth = (LONG)cxSmIcon; + bmih.biHeight = -(LONG)cySmIcon; + bmih.biPlanes = 1; + bmih.biBitCount = 32; + bmih.biCompression = BI_RGB; + HDC hdc = CreateCompatibleDC(nullptr); + m_hImageList = ImageList_Create(cxSmIcon, cySmIcon, ILC_COLOR32, nButtons, 0); + m_hDisabledImageList = ImageList_Create(cxSmIcon, cySmIcon, ILC_COLOR32, nButtons, 0); + for (int i = 0; i < nButtons; ++i) { + TBBUTTON& tbb = pTbbArr[i]; + if (tbb.fsStyle == TBSTYLE_BUTTON || tbb.fsStyle == TBSTYLE_DROPDOWN) { + uint32_t* pBits; + HBITMAP hBMP; + { + hBMP = ::CreateDIBSection(hdc, &bminfo, DIB_RGB_COLORS, (void**)&pBits, nullptr, 0); + m_pcIcons->DrawToolIcon(pBits, tbb.iBitmap, true, cxSmIcon, cySmIcon); + auto ret = ImageList_Add(m_hImageList, hBMP, nullptr); + ::DeleteObject(hBMP); + } + { + hBMP = ::CreateDIBSection(hdc, &bminfo, DIB_RGB_COLORS, (void**)&pBits, nullptr, 0); + m_pcIcons->DrawToolIcon(pBits, tbb.iBitmap, false, cxSmIcon, cySmIcon); + auto ret = ImageList_Add(m_hDisabledImageList, hBMP, nullptr); + tbb.iBitmap = ret; + ::DeleteObject(hBMP); + } + } + } + ::DeleteDC(hdc); + + Toolbar_SetImageList(m_hwndToolBar, 0, m_hImageList); + Toolbar_SetDisabledImageList(m_hwndToolBar, 0, m_hDisabledImageList); + for( i = 0; i < nToolBarButtonNum; ++i ){ tbb = pTbbArr[i]; @@ -337,6 +374,7 @@ void CMainToolBar::CreateToolBar( void ) } //@@@ 2002.06.15 MIK end } + Toolbar_SetBitmapSize(m_hwndToolBar, cxSmIcon, cySmIcon); if( GetDllShareData().m_Common.m_sToolBar.m_bToolBarIsFlat ){ /* フラットツールバーにする/しない */ lToolType = ::GetWindowLongPtr(m_hwndToolBar, GWL_STYLE); lToolType |= (TBSTYLE_FLAT); @@ -366,6 +404,7 @@ void CMainToolBar::CreateToolBar( void ) // バンドを追加する Rebar_InsertBand( m_hwndReBar, -1, &rbBand ); ::ShowWindow( m_hwndToolBar, SW_SHOW ); + DarkMode::setDarkWndSafe(m_hwndReBar); } return; @@ -402,6 +441,17 @@ void CMainToolBar::DestroyToolBar( void ) m_hwndReBar = nullptr; } + if (m_hImageList) + { + ImageList_Destroy(m_hImageList); + m_hImageList = nullptr; + } + if (m_hDisabledImageList) + { + ImageList_Destroy(m_hDisabledImageList); + m_hDisabledImageList = nullptr; + } + return; } @@ -415,70 +465,6 @@ bool CMainToolBar::EatMessage(MSG* msg) return false; } -/*! @brief ToolBarのOwnerDraw - - @param pnmh [in] Owner Draw情報 - - @note Common Control V4.71以降はNMTBCUSTOMDRAWを送ってくるが, - Common Control V4.70はLPNMCUSTOMDRAWしか送ってこないので - 安全のため小さい方に合わせて処理を行う. - - @author genta - @date 2003.07.21 作成 - -*/ -LPARAM CMainToolBar::ToolBarOwnerDraw( LPNMCUSTOMDRAW pnmh ) -{ - switch( pnmh->dwDrawStage ){ - case CDDS_PREPAINT: - // 描画開始前 - // アイテムを自前で描画する旨を通知する - return CDRF_NOTIFYITEMDRAW; - - case CDDS_ITEMPREPAINT: - // 面倒くさいので,枠はToolbarに描いてもらう - // アイコンが登録されていないので中身は何も描かれない - // 2010.07.15 Moca 検索(ボックス)なら枠を描かない - if( pnmh->dwItemSpec == F_SEARCH_BOX ){ - return CDRF_SKIPDEFAULT; - } - return CDRF_NOTIFYPOSTPAINT; - - case CDDS_ITEMPOSTPAINT: - { - // 描画 - // コマンド番号(pnmh->dwItemSpec)からアイコン番号を取得する // 2007.11.02 ryoji - int nIconId = Toolbar_GetBitmap( pnmh->hdr.hwndFrom, (WPARAM)pnmh->dwItemSpec ); - - // アイテム矩形からの画像のオフセット // 2007.03.25 ryoji - CMyRect rc( pnmh->rc ); - int offset = ( rc.Height() - m_pcIcons->cy() ) / 2; - - const int cxEdge = DpiScaleX( 1 ); - const int cyEdge = DpiScaleY( 1 ); - const int cxSmIcon = DpiScaleX( 16 ); - const int cySmIcon = DpiScaleY( 16 ); - - // ボタンを押されたらちょっと画像をずらす // Aug. 30, 2003 genta - int shift = pnmh->uItemState & ( CDIS_SELECTED | CDIS_CHECKED ) ? cxEdge : 0; - - // アイコン描画 - m_pcIcons->DrawToolIcon( - pnmh->hdc, - rc.left + offset + shift, - rc.top + offset + shift, // 押下時は右だけでなく下にもずらす // Sep. 6, 2003 genta - nIconId, - ( pnmh->uItemState & CDIS_DISABLED ) ? ILD_MASK : ILD_NORMAL, - cxSmIcon, cySmIcon - ); - } - break; - default: - break; - } - return CDRF_DODEFAULT; -} - /*! ツールバー更新用タイマーの処理 @date 2002.01.03 YAZAKI m_tbMyButtonなどをCShareDataからCMenuDrawerへ移動したことによる修正。 @date 2003.08.29 wmlhq, ryoji nTimerCountの導入 diff --git a/sakura_core/window/CMainToolBar.h b/sakura_core/window/CMainToolBar.h index aae44742ad..0178f84a3e 100644 --- a/sakura_core/window/CMainToolBar.h +++ b/sakura_core/window/CMainToolBar.h @@ -32,9 +32,6 @@ class CMainToolBar{ void OnToolbarTimer( void ); //!< タイマーの処理 20060128 aroka void UpdateToolbar( void ); //!< ツールバーの表示を更新する // 2008.09.23 nasukoji - //描画 - LPARAM ToolBarOwnerDraw( LPNMCUSTOMDRAW pnmh ); - //共有データとの同期 void AcceptSharedSearchKey(); @@ -62,5 +59,7 @@ class CMainToolBar{ CRecentSearch m_cRecentSearch; CImageListMgr* m_pcIcons = nullptr; + HIMAGELIST m_hImageList = nullptr; + HIMAGELIST m_hDisabledImageList = nullptr; }; #endif /* SAKURA_CMAINTOOLBAR_FEA7E388_DFEC_4E15_94CC_90A7E779797B_H_ */ diff --git a/sakura_core/window/CSplitBoxWnd.cpp b/sakura_core/window/CSplitBoxWnd.cpp index 7d9be74443..95f9d2ba29 100644 --- a/sakura_core/window/CSplitBoxWnd.cpp +++ b/sakura_core/window/CSplitBoxWnd.cpp @@ -52,7 +52,7 @@ HWND CSplitBoxWnd::Create( HINSTANCE hInstance, HWND hwndParent, int bVertical ) nullptr, // Handle to the class icon. nullptr, // Handle to a small icon hCursor,// Handle to the class cursor. - (HBRUSH)(COLOR_3DFACE + 1),// Handle to the class background brush. + (HBRUSH)(COLOR_3DSHADOW + 1),// Handle to the class background brush. nullptr/*MAKEINTRESOURCE( MYDOCUMENT )*/,// Pointer to a null-terminated character string that specifies the resource name of the class menu, as the name appears in the resource file. pszClassName// Pointer to a null-terminated string or is an atom. ); @@ -74,8 +74,8 @@ HWND CSplitBoxWnd::Create( HINSTANCE hInstance, HWND hwndParent, int bVertical ) WS_CHILD | WS_VISIBLE, // window style bVertical ? ( rc.right - nCxVScroll ):( 0 ), // horizontal position of window bVertical ? ( 0 ):( rc.bottom - nCyHScroll ), // vertical position of window - bVertical ? ( nCxVScroll ):( 7 ), // window width - bVertical ? ( 7 ):( nCyHScroll ), // window height + bVertical ? ( nCxVScroll ):( 37 ), // window width + bVertical ? ( 37 ):( nCyHScroll ), // window height nullptr // handle to menu, or child-window identifier ); } @@ -124,23 +124,26 @@ LRESULT CSplitBoxWnd::OnPaint( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lPara nVSplitHeight = 7; /* 垂直分割ボックスの高さ */ nHSplitWidth = 7; /* 水平分割ボックスの幅 */ +#if 1 + COLORREF cTL0 = RGB(136, 136, 136); + COLORREF cBR0 = RGB(63, 63, 63); + COLORREF cTL1 = RGB(153, 153, 153); + COLORREF cBR1 = RGB(96, 96, 96); +#else + COLORREF cTL0 = ::GetSysColor(COLOR_3DLIGHT); + COLORREF cBR0 = ::GetSysColor(COLOR_3DDKSHADOW); + COLORREF cTL1 = ::GetSysColor(COLOR_3DHILIGHT); + COLORREF cBR1 = ::GetSysColor(COLOR_3DSHADOW); +#endif + if( m_bVertical ){ /* 垂直分割ボックスの描画 */ - Draw3dRect( hdc, 0, 0, nCxVScroll, nVSplitHeight, - ::GetSysColor( COLOR_3DLIGHT ), ::GetSysColor( COLOR_3DDKSHADOW ) - ); - Draw3dRect( hdc, 1, 1, nCxVScroll - 2, nVSplitHeight - 2, - ::GetSysColor( COLOR_3DHILIGHT ), ::GetSysColor( COLOR_3DSHADOW ) - ); + Draw3dRect(hdc, 0, 0, nCxVScroll, nVSplitHeight, cTL0, cBR0); + Draw3dRect(hdc, 1, 1, nCxVScroll - 2, nVSplitHeight - 2, cTL1, cBR1); }else{ /* 水平分割ボックスの描画 */ - Draw3dRect( hdc, 0, 0, nHSplitWidth, nCyHScroll, - ::GetSysColor( COLOR_3DLIGHT ), ::GetSysColor( COLOR_3DDKSHADOW ) - ); - - Draw3dRect( hdc, 1, 1, nHSplitWidth - 2, nCyHScroll - 2, - ::GetSysColor( COLOR_3DHILIGHT ), ::GetSysColor( COLOR_3DSHADOW ) - ); + Draw3dRect(hdc, 0, 0, nHSplitWidth, nCyHScroll, cTL0, cBR0); + Draw3dRect(hdc, 1, 1, nHSplitWidth - 2, nCyHScroll - 2, cTL1, cBR1); } ::EndPaint(hwnd, &ps); diff --git a/sakura_core/window/CSplitterWnd.cpp b/sakura_core/window/CSplitterWnd.cpp index 46663a3525..20b4bb6037 100644 --- a/sakura_core/window/CSplitterWnd.cpp +++ b/sakura_core/window/CSplitterWnd.cpp @@ -27,6 +27,7 @@ #include "CSelectLang.h" #include "config/system_constants.h" #include "String_define.h" +#include "DarkModeSubclass.h" constexpr auto SPLITTER_FRAME_WIDTH = 3; constexpr auto SPLITTER_MARGIN = 2; @@ -83,7 +84,7 @@ HWND CSplitterWnd::Create( HWND hwndParent ) } /* 基底クラスメンバ呼び出し */ - return CWnd::Create( + HWND hWnd = CWnd::Create( hwndParent, 0, // extended window style pszClassName, // Pointer to a null-terminated string or is an atom. @@ -95,6 +96,8 @@ HWND CSplitterWnd::Create( HWND hwndParent ) 0, // window height nullptr // handle to menu, or child-window identifier ); + DarkMode::setDarkWndSafe(hWnd); + return hWnd; } /* 子ウィンドウの設定 @@ -119,20 +122,6 @@ void CSplitterWnd::SetChildWndArr( HWND* hwndEditViewArr ) return; } -/* 分割フレーム描画 */ -void CSplitterWnd::DrawFrame( HDC hdc, RECT* prc ) -{ - CSplitBoxWnd::Draw3dRect( hdc, prc->left, prc->top, prc->right, prc->bottom, - ::GetSysColor( COLOR_3DSHADOW ), - ::GetSysColor( COLOR_3DHILIGHT ) - ); - CSplitBoxWnd::Draw3dRect( hdc, prc->left + 1, prc->top + 1, prc->right - 2, prc->bottom - 2, - RGB( 0, 0, 0 ), - ::GetSysColor( COLOR_3DFACE ) - ); - return; -} - /* 分割トラッカーの表示 */ void CSplitterWnd::DrawSplitter( int xPos, int yPos, int bEraseOld ) { @@ -787,13 +776,14 @@ LRESULT CSplitterWnd::OnPaint( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lPara const int nFrameWidth = DpiScaleX(SPLITTER_FRAME_WIDTH); hdc = ::BeginPaint( hwnd, &ps ); ::GetClientRect( GetHwnd(), &rc ); + auto color = DarkMode::getViewBackgroundColor(); if( m_nAllSplitRows > 1 ){ ::SetRect( &rcFrame, rc.left, m_nVSplitPos, rc.right, m_nVSplitPos + nFrameWidth ); - ::MyFillRect( hdc, rcFrame, COLOR_3DFACE ); + ::MyFillRect( hdc, rcFrame, color ); } if( m_nAllSplitCols > 1 ){ ::SetRect( &rcFrame, m_nHSplitPos, rc.top, m_nHSplitPos + nFrameWidth, rc.bottom ); - ::MyFillRect( hdc, rcFrame, COLOR_3DFACE ); + ::MyFillRect( hdc, rcFrame, color ); } ::EndPaint(hwnd, &ps); return 0L; diff --git a/sakura_core/window/CSplitterWnd.h b/sakura_core/window/CSplitterWnd.h index a0a4499637..487a55a67b 100644 --- a/sakura_core/window/CSplitterWnd.h +++ b/sakura_core/window/CSplitterWnd.h @@ -88,7 +88,6 @@ class CSplitterWnd final : public CWnd /* || 実装ヘルパ関数 */ - void DrawFrame(HDC hdc, RECT* prc); /* 分割フレーム描画 */ int HitTestSplitter(int xPos, int yPos); /* 分割バーへのヒットテスト */ void DrawSplitter(int xPos, int yPos, int bEraseOld); /* 分割トラッカーの表示 */ }; diff --git a/sakura_core/window/CTabWnd.cpp b/sakura_core/window/CTabWnd.cpp index f6379de714..63d3846827 100644 --- a/sakura_core/window/CTabWnd.cpp +++ b/sakura_core/window/CTabWnd.cpp @@ -38,6 +38,7 @@ #include #include "config/system_constants.h" #include "String_define.h" +#include "DarkModeSubclass.h" // 2006.01.30 ryoji タブのサイズ/位置に関する定義 // 2009.10.01 ryoji 高DPI対応スケーリング @@ -945,6 +946,7 @@ HWND CTabWnd::Open( HINSTANCE hInstance, HWND hwndParent ) GetAppInstance(), nullptr ); + DarkMode::setDarkTooltips(m_hwndToolTip, static_cast(DarkMode::ToolTipsType::tooltip)); // ツールチップをマルチライン可能にする(SHRT_MAX: Win95でINT_MAXだと表示されない) // 2007.03.03 ryoji Tooltip_SetMaxTipWidth( m_hwndToolTip, SHRT_MAX ); @@ -1060,6 +1062,12 @@ LRESULT CTabWnd::OnDestroy( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) m_hIml = nullptr; } + for (auto [key, value] : m_bmpMap) + { + ::DeleteObject(value); + } + m_bmpMap.clear(); + ::KillTimer( hwnd, 1 ); // 2006.02.01 ryoji _SetHwnd(nullptr); @@ -1244,67 +1252,8 @@ LRESULT CTabWnd::OnMeasureItem( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lPar LRESULT CTabWnd::OnDrawItem( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) { DRAWITEMSTRUCT* lpdis = (DRAWITEMSTRUCT*)lParam; - if( lpdis->CtlType == ODT_MENU ) - { - // タブ一覧メニューを描画する - TABMENU_DATA* pData = (TABMENU_DATA*)lpdis->itemData; - - //描画対象 - HDC hdc = lpdis->hDC; - CGraphics gr(hdc); - RECT rcItem = lpdis->rcItem; - - // 状態に従ってテキストと背景色を決める - COLORREF clrText; - int nSysClrBk; - if (lpdis->itemState & ODS_SELECTED) - { - clrText = ::GetSysColor( COLOR_HIGHLIGHTTEXT ); - nSysClrBk = COLOR_HIGHLIGHT; - } - else - { - clrText = ::GetSysColor( COLOR_MENUTEXT ); - nSysClrBk = COLOR_MENU; - } - - // 背景描画 - ::MyFillRect( gr, rcItem, nSysClrBk ); - - // アイコン描画 - int cxIcon = CX_SMICON; - int cyIcon = CY_SMICON; - if( nullptr != m_hIml ) - { - ImageList_GetIconSize( m_hIml, &cxIcon, &cyIcon ); - if( 0 <= pData->iImage ) - { - int top = rcItem.top + ( rcItem.bottom - rcItem.top - cyIcon ) / 2; - ImageList_Draw( m_hIml, pData->iImage, lpdis->hDC, rcItem.left + DpiScaleX(2), top, ILD_TRANSPARENT ); - } - } - - // テキスト描画 - gr.PushTextForeColor( clrText ); - gr.SetTextBackTransparent(true); - HFONT hFont = CreateMenuFont(); - gr.PushMyFont(hFont); - RECT rcText = rcItem; - rcText.left += (cxIcon + DpiScaleX(8)); - - ::DrawText( gr, pData->szText, -1, &rcText, DT_SINGLELINE | DT_LEFT | DT_VCENTER ); - - gr.PopTextForeColor(); - gr.PopMyFont(); - ::DeleteObject( hFont ); - - // チェック状態なら外枠描画 - if( lpdis->itemState & ODS_CHECKED ) - { - gr.SetPen( ::GetSysColor(COLOR_HIGHLIGHT) ); - gr.SetBrushColor(-1); //NULL_BRUSH - ::Rectangle( gr, rcItem.left, rcItem.top, rcItem.right, rcItem.bottom ); - } + if( lpdis->CtlType == ODT_MENU ) { + assert(0); } else if( lpdis->CtlType == ODT_TAB ) { // タブを描画する @@ -1335,7 +1284,7 @@ LRESULT CTabWnd::OnDrawItem( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam }else{ int iPartId = TABP_TABITEM; int iStateId = TIS_NORMAL; - HTHEME hTheme = ::OpenThemeData( m_hwndTab, L"TAB" ); + HTHEME hTheme = ::OpenThemeData( m_hwndTab, L"Explorer" ); if( hTheme ) { if( !bSelected ){ ::InflateRect( &rcFullItem, DpiScaleX(2), DpiScaleY(2) ); @@ -1404,7 +1353,8 @@ LRESULT CTabWnd::OnDrawItem( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam // テキスト描画 COLORREF clrText; - clrText = ::GetSysColor(COLOR_MENUTEXT); + //clrText = ::GetSysColor(COLOR_MENUTEXT); + clrText = DarkMode::getTextColor(); gr.PushTextForeColor( clrText ); gr.SetTextBackTransparent(true); RECT rcText = rcItem; @@ -1574,14 +1524,19 @@ LRESULT CTabWnd::OnPaint( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) // 背景を描画する ::GetClientRect( hwnd, &rc ); - ::MyFillRect( gr, rc, COLOR_3DFACE ); + ::MyFillRect( gr, rc, DarkMode::getBackgroundColor() ); // ボタンを描画する DrawListBtn( gr, &rc ); DrawCloseBtn( gr, &rc ); // 2006.10.21 ryoji 追加 // 上側に境界線を描画する - ::DrawEdge(gr, &rc, EDGE_ETCHED, BF_TOP); + // Sunken outer edge. + gr.SetPen(RGB(60, 60, 60)); + gr.DrawLine(0, 0, rc.right, 0); + // Raised inner edge. + gr.SetPen(RGB(100, 100, 100)); + gr.DrawLine(0, 1, rc.right, 1); // トップバンドを描画する if( auto nCurSel = TabCtrl_GetCurSel( m_hwndTab ); 0 <= nCurSel ){ @@ -2351,6 +2306,17 @@ void CTabWnd::LayoutTab( void ) } } +static HBITMAP getIconBmp(HICON hIcon) +{ + ICONINFOEX ii; + ii.cbSize = sizeof(ii); + ::GetIconInfoEx(hIcon, &ii); + auto ret = (HBITMAP)CopyImage(ii.hbmColor, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION); + ::DeleteObject(ii.hbmColor); + ::DeleteObject(ii.hbmMask); + return ret; +} + /*! イメージリストの初期化処理 @date 2006.02.22 ryoji 新規作成 */ @@ -2401,9 +2367,15 @@ HIMAGELIST CTabWnd::InitImageList( void ) // (利用しないアイコンと差し替える) m_hIconApp = GetAppIcon( GetAppInstance(), ICON_DEFAULT_APP, FN_APP_ICON, true ); ImageList_ReplaceIcon( hImlNew, m_iIconApp, m_hIconApp ); + if (m_bmpMap.count(m_iIconApp) == 0) { + m_bmpMap[m_iIconApp] = getIconBmp(m_hIconApp); + } if( m_iIconApp != m_iIconGrep ){ m_hIconGrep = GetAppIcon( GetAppInstance(), ICON_DEFAULT_GREP, FN_GREP_ICON, true ); ImageList_ReplaceIcon( hImlNew, m_iIconGrep, m_hIconGrep ); + if (m_bmpMap.count(m_iIconGrep) == 0) { + m_bmpMap[m_iIconGrep] = getIconBmp(m_hIconGrep); + } } } @@ -2415,6 +2387,7 @@ HIMAGELIST CTabWnd::InitImageList( void ) if( nullptr != m_hIml ) ImageList_Destroy( m_hIml ); m_hIml = hImlNew; + auto cnt = ImageList_GetImageCount(m_hIml); return m_hIml; // 新しいイメージリストを返す } @@ -2443,6 +2416,14 @@ int CTabWnd::GetImageIndex( EditNode* pNode ) hImlSys = (HIMAGELIST)::SHGetFileInfo( szExt, FILE_ATTRIBUTE_NORMAL, &sfi, sizeof(sfi), SHGFI_SYSICONINDEX | SHGFI_SMALLICON | SHGFI_USEFILEATTRIBUTES ); if( nullptr == hImlSys ) return -1; + if (m_bmpMap.count(sfi.iIcon) == 0) + { + HICON hIcon = ::ImageList_GetIcon(hImlSys, sfi.iIcon, ILD_TRANSPARENT); + if (hIcon != nullptr) + { + m_bmpMap[sfi.iIcon] = getIconBmp(hIcon); + } + } if( ImageList_GetImageCount( m_hIml ) > sfi.iIcon ) return sfi.iIcon; // インデックスを返す @@ -2529,8 +2510,9 @@ void CTabWnd::DrawBtnBkgnd( HDC hdc, const LPRECT lprcBtn, BOOL bBtnHilighted ) if( bBtnHilighted ) { CGraphics gr(hdc); - gr.SetPen( ::GetSysColor(COLOR_HIGHLIGHT) ); - gr.SetBrushColor( ::GetSysColor(COLOR_MENU) ); + auto color = DarkMode::getHotBackgroundColor(); + gr.SetPen(color); + gr.SetBrushColor(color); ::Rectangle( gr, lprcBtn->left, lprcBtn->top, lprcBtn->right, lprcBtn->bottom ); } } @@ -2555,9 +2537,10 @@ void CTabWnd::DrawListBtn( CGraphics& gr, const LPRECT lprcClient ) rcBtn.right = rcBtn.left + (rcBtnBase.right - rcBtnBase.left); rcBtn.bottom = rcBtn.top + (rcBtnBase.bottom - rcBtnBase.left); - int nIndex = m_bListBtnHilighted? COLOR_MENUTEXT: COLOR_BTNTEXT; - gr.SetPen( ::GetSysColor( nIndex ) ); - gr.SetBrushColor( ::GetSysColor( nIndex ) ); //$$ GetSysColorBrushを用いた実装のほうが効率は良い + //auto color = ::GetSysColor(m_bListBtnHilighted ? COLOR_MENUTEXT : COLOR_BTNTEXT); + auto color = DarkMode::getTextColor(); + gr.SetPen( color ); + gr.SetBrushColor( color ); //$$ GetSysColorBrushを用いた実装のほうが効率は良い for( int i = 0; i < _countof(ptBase); i++ ) { pt[i].x = ptBase[i].x + rcBtn.left; @@ -2621,7 +2604,8 @@ void CTabWnd::DrawCloseBtn( CGraphics& gr, const LPRECT lprcClient ) GetCloseBtnRect( lprcClient, &rcBtn ); // ボタンの左側にセパレータを描画する // 2007.02.27 ryoji - gr.SetPen( ::GetSysColor( COLOR_3DSHADOW ) ); + gr.SetPen( DarkMode::getDlgBackgroundColor() ); + //gr.SetPen( ::GetSysColor( COLOR_3DSHADOW ) ); ::MoveToEx( gr, rcBtn.left - DpiScaleX(4), rcBtn.top + 1, nullptr ); ::LineTo( gr, rcBtn.left - DpiScaleX(4), rcBtn.bottom - 1 ); @@ -2633,9 +2617,10 @@ void CTabWnd::DrawCloseBtn( CGraphics& gr, const LPRECT lprcClient ) rcBtn.right = rcBtn.left + (rcBtnBase.right - rcBtnBase.left); rcBtn.bottom = rcBtn.top + (rcBtnBase.bottom - rcBtnBase.left); - int nIndex = m_bCloseBtnHilighted? COLOR_MENUTEXT: COLOR_BTNTEXT; - gr.SetPen( ::GetSysColor(nIndex) ); - gr.SetBrushColor( ::GetSysColor(nIndex) ); + //auto color = ::GetSysColor(m_bCloseBtnHilighted ? COLOR_MENUTEXT : COLOR_BTNTEXT); + auto color = DarkMode::getTextColor(); + gr.SetPen( color ); + gr.SetBrushColor( color ); if( m_pShareData->m_Common.m_sTabBar.m_bDispTabWnd && !m_pShareData->m_Common.m_sTabBar.m_bDispTabWndMultiWin && !m_pShareData->m_Common.m_sTabBar.m_bTab_CloseOneWin // 2007.02.13 ryoji 条件追加(ウィンドウの閉じるボタンは全部閉じる) @@ -2673,9 +2658,10 @@ void CTabWnd::DrawTabCloseBtn( CGraphics& gr, const LPRECT lprcClient, bool sele rcBtn.right = rcBtn.left + (rcBtnBase.right - rcBtnBase.left); rcBtn.bottom = rcBtn.top + (rcBtnBase.bottom - rcBtnBase.left); - int nIndex = COLOR_BTNTEXT; - gr.SetPen( ::GetSysColor(nIndex) ); - gr.SetBrushColor( ::GetSysColor(nIndex) ); + //auto color = ::GetSysColor(COLOR_BTNTEXT); + auto color = DarkMode::getTextColor(); + gr.SetPen( color ); + gr.SetBrushColor( color ); DrawCloseFigure( gr, rcBtn ); } @@ -2907,20 +2893,26 @@ LRESULT CTabWnd::TabListMenu( POINT pt, BOOL bSel/* = TRUE*/, BOOL bFull/* = FAL // メニューを作成する // 2007.02.28 ryoji 表示切替をメニューに追加 - int iMenuSel = -1; - UINT uFlags = MF_BYPOSITION | (m_hIml? MF_OWNERDRAW: MF_STRING); + UINT fMask = MIIM_STATE | MIIM_ID | MIIM_DATA | MIIM_STRING | (m_hIml ? MIIM_BITMAP : 0); HMENU hMenu = ::CreatePopupMenu(); + MENUITEMINFO mii{}; + mii.cbSize = sizeof(mii); + mii.fMask = fMask; + mii.fType = 0; + IMAGEINFO ii; for( i = 0; i < nSelfTab; i++ ) { - ::InsertMenu( hMenu, i, uFlags, IDM_SELWINDOW + i, m_hIml? (LPCWSTR)&pData[i]: pData[i].szText ); - if( pData[i].hwnd == GetParentHwnd() ) - iMenuSel = i; - } - - // 自ウィンドウに対応するメニューをチェック状態にする - if( iMenuSel >= 0 ) - { - ::CheckMenuRadioItem( hMenu, 0, nSelfTab - 1, iMenuSel, MF_BYPOSITION ); + mii.wID = IDM_SELWINDOW + i; + mii.dwTypeData = pData[i].szText; + mii.dwItemData = (ULONG_PTR)pData[i].hwnd; + mii.cch = wcslen(pData[i].szText); + if (m_hIml) + { + auto it = m_bmpMap.find(pData[i].iImage); + mii.hbmpItem = it == m_bmpMap.end() ? nullptr : it->second; + } + mii.fState = (pData[i].hwnd == GetParentHwnd()) ? (MFS_HILITE|MFS_DEFAULT) : MF_UNHILITE; + auto ret = ::InsertMenuItem( hMenu, i, TRUE, &mii ); } // 他グループのウィンドウ一覧を追加する @@ -2930,7 +2922,17 @@ LRESULT CTabWnd::TabListMenu( POINT pt, BOOL bSel/* = TRUE*/, BOOL bFull/* = FAL { for( i = nSelfTab; i < nTab; i++ ) { - ::InsertMenu( hMenu, i, uFlags, IDM_SELWINDOW + i, m_hIml? (LPCWSTR)&pData[i]: pData[i].szText ); + mii.wID = IDM_SELWINDOW + i; + mii.dwTypeData = pData[i].szText; + mii.dwItemData = (ULONG_PTR)pData[i].hwnd; + mii.cch = wcslen(pData[i].szText); + if (m_hIml) + { + auto it = m_bmpMap.find(pData[i].iImage); + mii.hbmpItem = it == m_bmpMap.end() ? nullptr : it->second; + } + mii.fState = MF_UNHILITE; + ::InsertMenuItem(hMenu, i, TRUE, &mii); } } else @@ -3260,6 +3262,7 @@ void CTabWnd::SizeBox_ONOFF( bool bSizeBox ) GetAppInstance(), /* instance owning this window */ (LPVOID) nullptr /* pointer not needed */ ); + DarkMode::setDarkWndSafe(GetHwnd()); ::ShowWindow( m_hwndSizeBox, SW_SHOW ); m_bSizeBox = true; OnSize(); diff --git a/sakura_core/window/CTabWnd.h b/sakura_core/window/CTabWnd.h index f959173646..a67f5f6b59 100644 --- a/sakura_core/window/CTabWnd.h +++ b/sakura_core/window/CTabWnd.h @@ -169,6 +169,7 @@ class CTabWnd final : public CWnd HICON m_hIconGrep; //!< Grepアイコン int m_iIconApp; //!< アプリケーションアイコンのインデックス int m_iIconGrep; //!< Grepアイコンのインデックス + std::map m_bmpMap; BOOL m_bVisualStyle; //!< ビジュアルスタイルかどうか // 2007.04.01 ryoji BOOL m_bHovering;