Skip to content

Commit c3bcb45

Browse files
committed
Enable Rounded Corners for WinMerge Menu on Windows 11 (#2364) (2)
1 parent eae750d commit c3bcb45

File tree

2 files changed

+43
-1
lines changed

2 files changed

+43
-1
lines changed

Src/Common/BCMenu.cpp

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
#include "stdafx.h" // Standard windows header file
2727
#include "BCMenu.h" // BCMenu class declaration
2828
#include <afxpriv.h> //SK: makes A2W and other spiffy AFX macros work
29+
#include <../src/mfc/afximpl.h>
30+
#include <cmath>
2931

3032
#pragma comment(lib, "uxtheme.lib")
3133

@@ -225,6 +227,12 @@ void BCMenuData::SetWideString(const wchar_t *szWideString)
225227
m_szMenuText=nullptr;//set to nullptr so we need not bother about dangling non-nullptr Ptrs
226228
}
227229

230+
void BCMenu::DisableOwnerDraw()
231+
{
232+
m_bEnableOwnerDraw = false;
233+
afxData.hbmMenuDot = reinterpret_cast<HBITMAP>(CreateRadioDotBitmap()->Detach());
234+
}
235+
228236
bool BCMenu::IsMenu(HMENU submenu)
229237
{
230238
INT_PTR m;
@@ -1854,6 +1862,39 @@ int BCMenu::GlobalImageListOffset(int nID)
18541862
return existsloc;
18551863
}
18561864

1865+
CBitmap* BCMenu::CreateRadioDotBitmap()
1866+
{
1867+
const COLORREF color = GetSysColor(COLOR_MENUTEXT);
1868+
const DWORD dibcolor = (GetRValue(color) << 16) | (GetGValue(color) << 8) | GetBValue(color);
1869+
const int cxSMIcon = GetSystemMetrics(SM_CXSMICON);
1870+
const int cySMIcon = GetSystemMetrics(SM_CYSMICON);
1871+
BYTE* pBits;
1872+
BITMAPINFO bmi{ sizeof(BITMAPINFOHEADER), cxSMIcon, -cySMIcon, 1, 32, BI_RGB };
1873+
CBitmap *pBitmap = new CBitmap();
1874+
HBITMAP hBitmap = CreateDIBSection(nullptr, &bmi, DIB_RGB_COLORS, (void**)&pBits, nullptr, 0);
1875+
pBitmap->Attach(hBitmap);
1876+
CDC dcMem;
1877+
dcMem.CreateCompatibleDC(nullptr);
1878+
CBitmap* pOldBitmap = dcMem.SelectObject(pBitmap);
1879+
CRect rcDot(cxSMIcon/2-cxSMIcon/5,cySMIcon/2-cxSMIcon/5,cxSMIcon/2+cxSMIcon/5,cySMIcon/2+cySMIcon/5);
1880+
DWORD* p = reinterpret_cast<DWORD*>(pBits);
1881+
const int cx = (rcDot.left + rcDot.right ) / 2;
1882+
const int cy = (rcDot.top + rcDot.bottom) / 2;
1883+
const double r = std::sqrt((cxSMIcon / 5) * (cxSMIcon / 5));
1884+
for (int y = rcDot.top; y < rcDot.bottom; ++y)
1885+
{
1886+
for (int x = rcDot.left; x < rcDot.right; ++x)
1887+
{
1888+
const double d = std::sqrt((x - cx) * (x - cx) + (y - cy) * (y - cy));
1889+
if (d <= r)
1890+
p[x + y * cxSMIcon] = dibcolor | ((r - d >= 1.0) ? 0xff000000 : (static_cast<BYTE>(255.0 * (r - d)) << 24));
1891+
1892+
}
1893+
}
1894+
dcMem.SelectObject(pOldBitmap);
1895+
return pBitmap;
1896+
}
1897+
18571898
void BCMenu::LoadImages()
18581899
{
18591900
if (!m_bHasNotLoadedImages)

Src/Common/BCMenu.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ class BCMenu : public CMenu
5858
BCMenu();
5959
virtual ~BCMenu();
6060

61-
static void DisableOwnerDraw() { m_bEnableOwnerDraw = false; }
61+
static void DisableOwnerDraw();
6262

6363
// Functions for loading and applying bitmaps to menus (see example application)
6464
virtual BOOL LoadMenu(LPCTSTR lpszResourceName);
@@ -172,6 +172,7 @@ class BCMenu : public CMenu
172172
void LoadImages();
173173
inline unsigned MakeOwnerDrawFlag() const { return BCMenu::m_bEnableOwnerDraw ? MF_OWNERDRAW : MF_STRING; }
174174
inline const tchar_t *MakeItemData(const BCMenuData* mdata) const { return m_bEnableOwnerDraw ? reinterpret_cast<const tchar_t *>(mdata) : mdata->GetWideString(); }
175+
static CBitmap* CreateRadioDotBitmap();
175176

176177
// Member Variables
177178
protected:

0 commit comments

Comments
 (0)