Добавлена папка source в CristalDiskMark
This commit is contained in:
@@ -0,0 +1,991 @@
|
||||
/*---------------------------------------------------------------------------*/
|
||||
// Author : hiyohiyo
|
||||
// Mail : hiyohiyo@crystalmark.info
|
||||
// Web : https://crystalmark.info/
|
||||
// License : MIT License
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "ButtonFx.h"
|
||||
|
||||
#if _MSC_VER <= 1310
|
||||
#define ON_WM_MOUSEHOVER() \
|
||||
{ 0x2A1 /*WM_MOUSEHOVER*/, 0, 0, 0, AfxSig_vwp, \
|
||||
(AFX_PMSG)(AFX_PMSGW) \
|
||||
(static_cast< void (AFX_MSG_CALL CWnd::*)(UINT, CPoint) > (OnMouseHover)) },
|
||||
|
||||
#define ON_WM_MOUSELEAVE() \
|
||||
{ 0x2A3 /*WM_MOUSELEAVE*/, 0, 0, 0, AfxSig_vv, \
|
||||
(AFX_PMSG)(AFX_PMSGW) \
|
||||
(static_cast< void (AFX_MSG_CALL CWnd::*)(void) > (OnMouseLeave)) },
|
||||
#endif
|
||||
|
||||
////------------------------------------------------
|
||||
// CButtonFx
|
||||
////------------------------------------------------
|
||||
|
||||
CButtonFx::CButtonFx()
|
||||
{
|
||||
// Control
|
||||
m_X = 0;
|
||||
m_Y = 0;
|
||||
m_RenderMode = SystemDraw;
|
||||
m_bHighContrast = FALSE;
|
||||
m_bDarkMode = FALSE;
|
||||
m_bDrawFrame = FALSE;
|
||||
m_FrameColor = RGB(128, 128, 128);
|
||||
m_hPal = NULL;
|
||||
|
||||
// Glass
|
||||
m_GlassColor = RGB(255, 255, 255);
|
||||
m_GlassAlpha = 255;
|
||||
|
||||
// Meter
|
||||
m_bMeter = FALSE;
|
||||
m_MeterRatio = 0.0;
|
||||
|
||||
// Image
|
||||
m_ImageCount = 0;
|
||||
m_BkDC = NULL;
|
||||
m_bBkBitmapInit = FALSE;
|
||||
m_bBkLoad = FALSE;
|
||||
|
||||
// Font
|
||||
m_TextAlign = BS_LEFT;
|
||||
m_TextColor = RGB(0, 0, 0);
|
||||
|
||||
// Mouse
|
||||
m_bHover = FALSE;
|
||||
m_bFocas = FALSE;
|
||||
m_bTrackingNow = FALSE;
|
||||
m_bHandCursor = FALSE;
|
||||
m_bSelected = FALSE;
|
||||
|
||||
// Text Format
|
||||
m_TextFormat = 0;
|
||||
m_LabelFormat = DT_LEFT | DT_TOP | DT_SINGLELINE;
|
||||
m_UnitFormat = DT_RIGHT | DT_BOTTOM | DT_SINGLELINE;
|
||||
|
||||
// Margin
|
||||
m_Margin.top = 0;
|
||||
m_Margin.left = 0;
|
||||
m_Margin.bottom = 0;
|
||||
m_Margin.right = 0;
|
||||
}
|
||||
|
||||
CButtonFx::~CButtonFx()
|
||||
{
|
||||
}
|
||||
|
||||
IMPLEMENT_DYNAMIC(CButtonFx, CButton)
|
||||
|
||||
BEGIN_MESSAGE_MAP(CButtonFx, CButton)
|
||||
//{{AFX_MSG_MAP(CButtonFx)
|
||||
ON_WM_ERASEBKGND()
|
||||
ON_WM_MOUSEMOVE()
|
||||
ON_WM_MOUSEHOVER()
|
||||
ON_WM_MOUSELEAVE()
|
||||
ON_WM_KILLFOCUS()
|
||||
ON_WM_SETFOCUS()
|
||||
ON_WM_SETCURSOR()
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
//------------------------------------------------
|
||||
// Control
|
||||
//------------------------------------------------
|
||||
|
||||
BOOL CButtonFx::InitControl(int x, int y, int width, int height, double zoomRatio, HPALETTE hPal, CDC* bkDC,
|
||||
LPCTSTR imagePath, int imageCount, DWORD textAlign, int renderMode, BOOL bHighContrast, BOOL bDarkMode, BOOL bDrawFrame)
|
||||
{
|
||||
m_X = (int)(x * zoomRatio);
|
||||
m_Y = (int)(y * zoomRatio);
|
||||
m_CtrlSize.cx = (int)(width * zoomRatio + 0.5);
|
||||
m_CtrlSize.cy = (int)(height * zoomRatio + 0.5);
|
||||
MoveWindow(m_X, m_Y, m_CtrlSize.cx, m_CtrlSize.cy);
|
||||
|
||||
m_hPal = hPal;
|
||||
m_BkDC = bkDC;
|
||||
m_ImagePath = imagePath;
|
||||
m_ImageCount = imageCount;
|
||||
m_RenderMode = renderMode;
|
||||
|
||||
if (BS_LEFT <= textAlign && textAlign <= BS_CENTER)
|
||||
{
|
||||
m_TextAlign = textAlign;
|
||||
}
|
||||
|
||||
if(m_ToolTip.m_hWnd != NULL)
|
||||
{
|
||||
if (m_ToolTip.GetToolCount() != 0)
|
||||
{
|
||||
m_ToolTip.DelTool(this, 1);
|
||||
}
|
||||
CRect rect;
|
||||
GetClientRect(rect);
|
||||
m_ToolTip.AddTool(this, m_ToolTipText, rect, 1);
|
||||
}
|
||||
|
||||
m_bHighContrast = bHighContrast;
|
||||
m_bDarkMode = bDarkMode;
|
||||
m_bDrawFrame = bDrawFrame;
|
||||
|
||||
if (m_bHighContrast)
|
||||
{
|
||||
ModifyStyle(BS_OWNERDRAW, m_TextAlign);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
else if(renderMode & SystemDraw)
|
||||
{
|
||||
ModifyStyle(BS_OWNERDRAW, m_TextAlign);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
SetBkReload();
|
||||
ModifyStyle(0, BS_OWNERDRAW);
|
||||
}
|
||||
|
||||
if (renderMode & OwnerDrawImage)
|
||||
{
|
||||
if (!LoadBitmap(imagePath))
|
||||
{
|
||||
ModifyStyle(BS_OWNERDRAW, m_TextAlign);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ImageCount = 1;
|
||||
m_CtrlImage.Destroy();
|
||||
m_CtrlImage.Create(m_CtrlSize.cx, m_CtrlSize.cy * m_ImageCount, 32);
|
||||
m_CtrlBitmap.Detach();
|
||||
m_CtrlBitmap.Attach((HBITMAP)m_CtrlImage);
|
||||
DWORD length = m_CtrlSize.cx * m_CtrlSize.cy * m_ImageCount * 4;
|
||||
BYTE* bitmapBits = new BYTE[length];
|
||||
m_CtrlBitmap.GetBitmapBits(length, bitmapBits);
|
||||
|
||||
BYTE r, g, b, a;
|
||||
if (renderMode & OwnerDrawGlass)
|
||||
{
|
||||
r = (BYTE)GetRValue(m_GlassColor);
|
||||
g = (BYTE)GetGValue(m_GlassColor);
|
||||
b = (BYTE)GetBValue(m_GlassColor);
|
||||
a = m_GlassAlpha;
|
||||
}
|
||||
else // OwnerDrawTransparent
|
||||
{
|
||||
r = 0;
|
||||
g = 0;
|
||||
b = 0;
|
||||
a = 0;
|
||||
}
|
||||
|
||||
for (int y = 0; y < (int)(m_CtrlSize.cy * m_ImageCount); y++)
|
||||
{
|
||||
for (int x = 0; x < m_CtrlSize.cx; x++)
|
||||
{
|
||||
DWORD p = (y * m_CtrlSize.cx + x) * 4;
|
||||
#if _MSC_VER > 1310
|
||||
#pragma warning( disable : 6386 )
|
||||
#endif
|
||||
bitmapBits[p + 0] = b;
|
||||
bitmapBits[p + 1] = g;
|
||||
bitmapBits[p + 2] = r;
|
||||
bitmapBits[p + 3] = a;
|
||||
#if _MSC_VER > 1310
|
||||
#pragma warning( default : 6386 )
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
m_CtrlBitmap.SetBitmapBits(length, bitmapBits);
|
||||
delete[] bitmapBits;
|
||||
}
|
||||
|
||||
Invalidate();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL CButtonFx::ReloadImage(LPCTSTR imagePath, UINT imageCount)
|
||||
{
|
||||
if (imagePath != NULL && m_ImagePath.Compare(imagePath) == 0)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
m_ImagePath = imagePath;
|
||||
m_ImageCount = imageCount;
|
||||
|
||||
LoadBitmap(imagePath);
|
||||
|
||||
Invalidate();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void CButtonFx::SetMargin(int top, int left, int bottom, int right, double zoomRatio)
|
||||
{
|
||||
m_Margin.top = (int)(top * zoomRatio);
|
||||
m_Margin.left = (int)(left * zoomRatio);
|
||||
m_Margin.bottom = (int)(bottom * zoomRatio);
|
||||
m_Margin.right = (int)(right * zoomRatio);
|
||||
}
|
||||
|
||||
CSize CButtonFx::GetSize(void)
|
||||
{
|
||||
return m_CtrlSize;
|
||||
}
|
||||
|
||||
void CButtonFx::SetDrawFrame(BOOL bDrawFrame)
|
||||
{
|
||||
if (bDrawFrame && m_bHighContrast)
|
||||
{
|
||||
ModifyStyleEx(0, WS_EX_STATICEDGE, SWP_DRAWFRAME);
|
||||
}
|
||||
else
|
||||
{
|
||||
ModifyStyleEx(WS_EX_STATICEDGE, 0, SWP_DRAWFRAME);
|
||||
}
|
||||
m_bDrawFrame = bDrawFrame;
|
||||
}
|
||||
|
||||
void CButtonFx::SetGlassColor(COLORREF glassColor, BYTE glassAlpha)
|
||||
{
|
||||
m_GlassColor = glassColor;
|
||||
m_GlassAlpha = glassAlpha;
|
||||
}
|
||||
|
||||
void CButtonFx::SetMeter(BOOL bMeter, double meterRatio)
|
||||
{
|
||||
m_bMeter = bMeter;
|
||||
if (meterRatio > 1.0)
|
||||
{
|
||||
m_MeterRatio = 1.0;
|
||||
}
|
||||
else if (meterRatio > 0)
|
||||
{
|
||||
m_MeterRatio = meterRatio;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_MeterRatio = 0.0;
|
||||
}
|
||||
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
void CButtonFx::SetLabelUnit(CString label, CString unit)
|
||||
{
|
||||
m_Label = label;
|
||||
m_Unit = unit;
|
||||
}
|
||||
|
||||
void CButtonFx::SetLabelUnitFormat(UINT labelFormat, UINT unitFormat)
|
||||
{
|
||||
m_LabelFormat = labelFormat;
|
||||
m_UnitFormat = unitFormat;
|
||||
}
|
||||
|
||||
void CButtonFx::SetTextFormat(UINT format)
|
||||
{
|
||||
m_TextFormat = format;
|
||||
}
|
||||
|
||||
//------------------------------------------------
|
||||
// Draw Control
|
||||
//------------------------------------------------
|
||||
|
||||
void CButtonFx::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
|
||||
{
|
||||
if (m_bHighContrast) { return CButton::DrawItem(lpDrawItemStruct); }
|
||||
|
||||
CDC* drawDC = CDC::FromHandle(lpDrawItemStruct->hDC);
|
||||
LoadCtrlBk(drawDC);
|
||||
|
||||
if (! (GetStyle() & BS_NOTIFY))
|
||||
{
|
||||
DrawControl(drawDC, lpDrawItemStruct, m_CtrlBitmap, m_BkBitmap, ControlImageNormal);
|
||||
}
|
||||
else if (IsWindowEnabled())
|
||||
{
|
||||
if (m_bSelected && m_ImageCount > ControlImageSelected)
|
||||
{
|
||||
DrawControl(drawDC, lpDrawItemStruct, m_CtrlBitmap, m_BkBitmap, ControlImageSelected);
|
||||
}
|
||||
else if ((lpDrawItemStruct->itemState & ODS_SELECTED || m_bHover) && m_ImageCount > ControlImageHover)
|
||||
{
|
||||
DrawControl(drawDC, lpDrawItemStruct, m_CtrlBitmap, m_BkBitmap, ControlImageHover);
|
||||
}
|
||||
else if ((lpDrawItemStruct->itemState & ODS_FOCUS || m_bFocas) && m_ImageCount > ControlImageFocus)
|
||||
{
|
||||
DrawControl(drawDC, lpDrawItemStruct, m_CtrlBitmap, m_BkBitmap, ControlImageFocus);
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawControl(drawDC, lpDrawItemStruct, m_CtrlBitmap, m_BkBitmap, ControlImageNormal);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_ImageCount > ControlImageDisabled)
|
||||
{
|
||||
DrawControl(drawDC, lpDrawItemStruct, m_CtrlBitmap, m_BkBitmap, ControlImageDisabled);
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawControl(drawDC, lpDrawItemStruct, m_CtrlBitmap, m_BkBitmap, ControlImageNormal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CButtonFx::DrawControl(CDC* drawDC, LPDRAWITEMSTRUCT lpDrawItemStruct, CBitmap& ctrlBitmap, CBitmap& bkBitmap, int no)
|
||||
{
|
||||
CDC* pMemDC = new CDC;
|
||||
CBitmap* pOldMemBitmap;
|
||||
if(m_hPal && drawDC->GetDeviceCaps(RASTERCAPS) & RC_PALETTE)
|
||||
{
|
||||
SelectPalette( drawDC->GetSafeHdc(), m_hPal, FALSE );
|
||||
drawDC->RealizePalette();
|
||||
drawDC->SetStretchBltMode(HALFTONE);
|
||||
}
|
||||
pMemDC->CreateCompatibleDC(drawDC);
|
||||
if(m_hPal && pMemDC->GetDeviceCaps(RASTERCAPS) & RC_PALETTE)
|
||||
{
|
||||
SelectPalette( pMemDC->GetSafeHdc(), m_hPal, FALSE );
|
||||
pMemDC->RealizePalette();
|
||||
pMemDC->SetStretchBltMode(HALFTONE);
|
||||
}
|
||||
pOldMemBitmap = pMemDC->SelectObject(&ctrlBitmap);
|
||||
CDC* pBkDC = new CDC;
|
||||
CBitmap* pOldBkBitmap;
|
||||
pBkDC->CreateCompatibleDC(drawDC);
|
||||
if(m_hPal && pBkDC->GetDeviceCaps(RASTERCAPS) & RC_PALETTE)
|
||||
{
|
||||
SelectPalette( pBkDC->GetSafeHdc(), m_hPal, FALSE );
|
||||
pBkDC->RealizePalette();
|
||||
pBkDC->SetStretchBltMode(HALFTONE);
|
||||
}
|
||||
pOldBkBitmap = pBkDC->SelectObject(&bkBitmap);
|
||||
|
||||
CBitmap DrawBmp;
|
||||
DrawBmp.CreateCompatibleBitmap(drawDC, m_CtrlSize.cx, m_CtrlSize.cy);
|
||||
CDC* pDrawBmpDC = new CDC;
|
||||
CBitmap* pOldDrawBitmap;
|
||||
pDrawBmpDC->CreateCompatibleDC(drawDC);
|
||||
if(m_hPal && pDrawBmpDC->GetDeviceCaps(RASTERCAPS) & RC_PALETTE)
|
||||
{
|
||||
SelectPalette( pDrawBmpDC->GetSafeHdc(), m_hPal, FALSE );
|
||||
pDrawBmpDC->RealizePalette();
|
||||
pDrawBmpDC->SetStretchBltMode(HALFTONE);
|
||||
}
|
||||
pOldDrawBitmap = pDrawBmpDC->SelectObject(&DrawBmp);
|
||||
|
||||
int color = drawDC->GetDeviceCaps(BITSPIXEL) * drawDC->GetDeviceCaps(PLANES);
|
||||
|
||||
if (!m_CtrlImage.IsNull())
|
||||
{
|
||||
if (m_CtrlImage.GetBPP() == 32)
|
||||
{
|
||||
CBitmap* bk32Bitmap;
|
||||
CImage bk32Image;
|
||||
if (color == 32)
|
||||
{
|
||||
bk32Bitmap = &bkBitmap;
|
||||
}
|
||||
else
|
||||
{
|
||||
bk32Image.Create(m_CtrlSize.cx, m_CtrlSize.cy, 32);
|
||||
::StretchBlt(bk32Image.GetDC(), 0, 0, m_CtrlSize.cx, m_CtrlSize.cy, *pBkDC, 0, 0, m_CtrlSize.cx, m_CtrlSize.cy, SRCCOPY);
|
||||
bk32Bitmap = CBitmap::FromHandle((HBITMAP)bk32Image);
|
||||
}
|
||||
|
||||
BITMAP CtlBmpInfo, DstBmpInfo;
|
||||
bk32Bitmap->GetBitmap(&DstBmpInfo);
|
||||
DWORD DstLineBytes = DstBmpInfo.bmWidthBytes;
|
||||
DWORD DstMemSize = DstLineBytes * DstBmpInfo.bmHeight;
|
||||
ctrlBitmap.GetBitmap(&CtlBmpInfo);
|
||||
DWORD CtlLineBytes = CtlBmpInfo.bmWidthBytes;
|
||||
DWORD CtlMemSize = CtlLineBytes * CtlBmpInfo.bmHeight;
|
||||
|
||||
if ((DstBmpInfo.bmWidthBytes != CtlBmpInfo.bmWidthBytes)
|
||||
|| (DstBmpInfo.bmHeight != CtlBmpInfo.bmHeight / m_ImageCount))
|
||||
{
|
||||
// Error Check //
|
||||
}
|
||||
else
|
||||
{
|
||||
BYTE* DstBuffer = new BYTE[DstMemSize];
|
||||
bk32Bitmap->GetBitmapBits(DstMemSize, DstBuffer);
|
||||
BYTE* CtlBuffer = new BYTE[CtlMemSize];
|
||||
ctrlBitmap.GetBitmapBits(CtlMemSize, CtlBuffer);
|
||||
|
||||
if (m_bMeter)
|
||||
{
|
||||
int meter = (int)(m_CtrlSize.cx * m_MeterRatio);
|
||||
int baseY;
|
||||
baseY = m_CtrlSize.cy;
|
||||
for (LONG py = 0; py < DstBmpInfo.bmHeight; py++)
|
||||
{
|
||||
int dn = py * DstLineBytes;
|
||||
int cn = (baseY + py) * CtlLineBytes;
|
||||
for (LONG px = 0; px < meter; px++)
|
||||
{
|
||||
BYTE a = CtlBuffer[cn + 3];
|
||||
BYTE na = 255 - a;
|
||||
DstBuffer[dn + 0] = (BYTE)((CtlBuffer[cn + 0] * a + DstBuffer[dn + 0] * na) / 255);
|
||||
DstBuffer[dn + 1] = (BYTE)((CtlBuffer[cn + 1] * a + DstBuffer[dn + 1] * na) / 255);
|
||||
DstBuffer[dn + 2] = (BYTE)((CtlBuffer[cn + 2] * a + DstBuffer[dn + 2] * na) / 255);
|
||||
dn += (DstBmpInfo.bmBitsPixel / 8);
|
||||
cn += (CtlBmpInfo.bmBitsPixel / 8);
|
||||
}
|
||||
cn -= baseY * CtlLineBytes;
|
||||
for (LONG px = meter; px < DstBmpInfo.bmWidth; px++)
|
||||
{
|
||||
BYTE a = CtlBuffer[cn + 3];
|
||||
BYTE na = 255 - a;
|
||||
DstBuffer[dn + 0] = (BYTE)((CtlBuffer[cn + 0] * a + DstBuffer[dn + 0] * na) / 255);
|
||||
DstBuffer[dn + 1] = (BYTE)((CtlBuffer[cn + 1] * a + DstBuffer[dn + 1] * na) / 255);
|
||||
DstBuffer[dn + 2] = (BYTE)((CtlBuffer[cn + 2] * a + DstBuffer[dn + 2] * na) / 255);
|
||||
dn += (DstBmpInfo.bmBitsPixel / 8);
|
||||
cn += (CtlBmpInfo.bmBitsPixel / 8);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int baseY = m_CtrlSize.cy * no;
|
||||
for (LONG py = 0; py < DstBmpInfo.bmHeight; py++)
|
||||
{
|
||||
int dn = py * DstLineBytes;
|
||||
int cn = (baseY + py) * CtlLineBytes;
|
||||
for (LONG px = 0; px < DstBmpInfo.bmWidth; px++)
|
||||
{
|
||||
#if _MSC_VER > 1310
|
||||
#pragma warning( disable : 6385 )
|
||||
#pragma warning( disable : 6386 )
|
||||
#endif
|
||||
BYTE a = CtlBuffer[cn + 3];
|
||||
BYTE na = 255 - a;
|
||||
DstBuffer[dn + 0] = (BYTE)((CtlBuffer[cn + 0] * a + DstBuffer[dn + 0] * na) / 255);
|
||||
DstBuffer[dn + 1] = (BYTE)((CtlBuffer[cn + 1] * a + DstBuffer[dn + 1] * na) / 255);
|
||||
DstBuffer[dn + 2] = (BYTE)((CtlBuffer[cn + 2] * a + DstBuffer[dn + 2] * na) / 255);
|
||||
dn += (DstBmpInfo.bmBitsPixel / 8);
|
||||
cn += (CtlBmpInfo.bmBitsPixel / 8);
|
||||
#if _MSC_VER > 1310
|
||||
#pragma warning( default : 6386 )
|
||||
#pragma warning( default : 6385 )
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (color == 32)
|
||||
{
|
||||
DrawBmp.SetBitmapBits(DstMemSize, DstBuffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
bk32Bitmap->SetBitmapBits(DstMemSize, DstBuffer);
|
||||
::StretchBlt(pDrawBmpDC->GetSafeHdc(), 0, 0, m_CtrlSize.cx, m_CtrlSize.cy, bk32Image.GetDC(), 0, 0, m_CtrlSize.cx, m_CtrlSize.cy, SRCCOPY);
|
||||
bk32Image.ReleaseDC();
|
||||
}
|
||||
DrawString(pDrawBmpDC, lpDrawItemStruct);
|
||||
drawDC->StretchBlt(0, 0, m_CtrlSize.cx, m_CtrlSize.cy, pDrawBmpDC, 0, 0, m_CtrlSize.cx, m_CtrlSize.cy, SRCCOPY);
|
||||
|
||||
delete[] DstBuffer;
|
||||
delete[] CtlBuffer;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_bMeter)
|
||||
{
|
||||
int meter = (int)(m_CtrlSize.cx * (m_MeterRatio));
|
||||
pDrawBmpDC->StretchBlt(meter, 0, m_CtrlSize.cx - meter, m_CtrlSize.cy, pMemDC, meter, m_CtrlSize.cy * 0, m_CtrlSize.cx - meter, m_CtrlSize.cy, SRCCOPY);
|
||||
pDrawBmpDC->StretchBlt(0, 0, meter, m_CtrlSize.cy, pMemDC, 0, m_CtrlSize.cy * 1, meter, m_CtrlSize.cy, SRCCOPY);
|
||||
DrawString(pDrawBmpDC, lpDrawItemStruct);
|
||||
drawDC->StretchBlt(0, 0, m_CtrlSize.cx, m_CtrlSize.cy, pDrawBmpDC, 0, 0, m_CtrlSize.cx, m_CtrlSize.cy, SRCCOPY);
|
||||
}
|
||||
else
|
||||
{
|
||||
pDrawBmpDC->StretchBlt(0, 0, m_CtrlSize.cx, m_CtrlSize.cy, pMemDC, 0, m_CtrlSize.cy * no, m_CtrlSize.cx, m_CtrlSize.cy, SRCCOPY);
|
||||
DrawString(pDrawBmpDC, lpDrawItemStruct);
|
||||
drawDC->StretchBlt(0, 0, m_CtrlSize.cx, m_CtrlSize.cy, pDrawBmpDC, 0, 0, m_CtrlSize.cx, m_CtrlSize.cy, SRCCOPY);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pDrawBmpDC->StretchBlt(0, 0, m_CtrlSize.cx, m_CtrlSize.cy, pBkDC, 0, m_CtrlSize.cy * no, m_CtrlSize.cx, m_CtrlSize.cy, SRCCOPY);
|
||||
DrawString(pDrawBmpDC, lpDrawItemStruct);
|
||||
drawDC->StretchBlt(0, 0, m_CtrlSize.cx, m_CtrlSize.cy, pDrawBmpDC, 0, 0, m_CtrlSize.cx, m_CtrlSize.cy, SRCCOPY);
|
||||
}
|
||||
|
||||
if (m_bDrawFrame)
|
||||
{
|
||||
HGDIOBJ oldPen;
|
||||
POINT point;
|
||||
|
||||
COLORREF color1;
|
||||
COLORREF color2;
|
||||
|
||||
if (m_bHover)
|
||||
{
|
||||
color1 = RGB(0x20, 0x98, 0xF4);
|
||||
color2 = RGB(0x20, 0x8B, 0xDE);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Windows 11 color
|
||||
color1 = RGB(0x00, 0x78, 0xD4);
|
||||
color2 = RGB(0x00, 0x6B, 0xBE);
|
||||
}
|
||||
|
||||
CPen pen1; pen1.CreatePen(PS_SOLID, 1, color1);
|
||||
CPen pen2; pen2.CreatePen(PS_SOLID, 1, color2);
|
||||
|
||||
oldPen = SelectObject(drawDC->m_hDC, pen1);
|
||||
MoveToEx(drawDC->m_hDC, 0, m_CtrlSize.cy - 1, &point);
|
||||
LineTo(drawDC->m_hDC, m_CtrlSize.cx - 1, m_CtrlSize.cy - 1);
|
||||
LineTo(drawDC->m_hDC, m_CtrlSize.cx - 1, 0);
|
||||
LineTo(drawDC->m_hDC, m_CtrlSize.cx - 1, m_CtrlSize.cy - 1);
|
||||
SelectObject(drawDC->m_hDC, pen2);
|
||||
MoveToEx(drawDC->m_hDC, 0, m_CtrlSize.cy - 2, &point);
|
||||
LineTo(drawDC->m_hDC, 0, 0);
|
||||
LineTo(drawDC->m_hDC, m_CtrlSize.cx - 1, 0);
|
||||
SelectObject(drawDC->m_hDC, oldPen);
|
||||
|
||||
pen1.DeleteObject();
|
||||
pen2.DeleteObject();
|
||||
}
|
||||
|
||||
pDrawBmpDC->SelectObject(&pOldDrawBitmap);
|
||||
pDrawBmpDC->DeleteDC();
|
||||
delete pDrawBmpDC;
|
||||
pMemDC->SelectObject(&pOldMemBitmap);
|
||||
pMemDC->DeleteDC();
|
||||
delete pMemDC;
|
||||
pBkDC->SelectObject(&pOldBkBitmap);
|
||||
pBkDC->DeleteDC();
|
||||
delete pBkDC;
|
||||
}
|
||||
|
||||
void CButtonFx::DrawString(CDC* drawDC, LPDRAWITEMSTRUCT lpDrawItemStruct)
|
||||
{
|
||||
CString title;
|
||||
GetWindowText(title);
|
||||
|
||||
if (title.IsEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
drawDC->SetBkMode(TRANSPARENT);
|
||||
CRect rect = (CRect)(lpDrawItemStruct->rcItem);
|
||||
rect.top += m_Margin.top;
|
||||
rect.left += m_Margin.left;
|
||||
rect.bottom -= m_Margin.bottom;
|
||||
rect.right -= m_Margin.right;
|
||||
|
||||
HGDIOBJ oldFont = drawDC->SelectObject(m_Font);
|
||||
CArray<CString, CString> arr;
|
||||
arr.RemoveAll();
|
||||
|
||||
CString resToken;
|
||||
int curPos = 0;
|
||||
resToken = title.Tokenize(_T("\r\n"), curPos);
|
||||
while (resToken != _T(""))
|
||||
{
|
||||
arr.Add(resToken);
|
||||
resToken = title.Tokenize(_T("\r\n"), curPos);
|
||||
}
|
||||
|
||||
CSize extent;
|
||||
if ((m_RenderMode & OwnerDrawTransparent) && m_bDarkMode)
|
||||
{
|
||||
SetTextColor(drawDC->m_hDC, RGB(255, 255, 255));
|
||||
}
|
||||
else
|
||||
{
|
||||
SetTextColor(drawDC->m_hDC, m_TextColor);
|
||||
}
|
||||
|
||||
if (m_bMeter && rect.Width() < extent.cx)
|
||||
{
|
||||
title.Replace(_T(","), _T("."));
|
||||
int score = _tstoi((LPCTSTR)title);
|
||||
title.Format(_T("%d"), score);
|
||||
extent = drawDC->GetTextExtent(title);
|
||||
}
|
||||
|
||||
if (!m_Label.IsEmpty() && m_TextFormat != BS_CENTER)
|
||||
{
|
||||
drawDC->DrawText(title, title.GetLength(), rect, m_TextFormat);
|
||||
drawDC->SelectObject(oldFont);
|
||||
|
||||
oldFont = drawDC->SelectObject(m_FontToolTip);
|
||||
drawDC->DrawText(m_Label, m_Label.GetLength(), rect, m_LabelFormat);
|
||||
drawDC->DrawText(m_Unit, m_Unit.GetLength(), rect, m_UnitFormat);
|
||||
}
|
||||
else if (!m_Label.IsEmpty())
|
||||
{
|
||||
drawDC->DrawText(title, title.GetLength(), rect, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
|
||||
drawDC->SelectObject(oldFont);
|
||||
|
||||
oldFont = drawDC->SelectObject(m_FontToolTip);
|
||||
drawDC->DrawText(m_Label, m_Label.GetLength(), rect, m_LabelFormat);
|
||||
drawDC->DrawText(m_Unit, m_Unit.GetLength(), rect, m_UnitFormat);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < arr.GetCount(); i++)
|
||||
{
|
||||
CRect r;
|
||||
r.top = rect.top + (LONG)(((double)rect.Height()) / arr.GetCount() * i);
|
||||
r.bottom = rect.top + (LONG)(((double)rect.Height()) / arr.GetCount() * (i + 1.0));
|
||||
r.left = rect.left;
|
||||
r.right = rect.right;
|
||||
|
||||
CRect rectI;
|
||||
HGDIOBJ oldFont = drawDC->SelectObject(m_Font);
|
||||
if ((m_RenderMode & OwnerDrawTransparent) && m_bDarkMode)
|
||||
{
|
||||
SetTextColor(drawDC->m_hDC, RGB(255, 255, 255));
|
||||
}
|
||||
else
|
||||
{
|
||||
SetTextColor(drawDC->m_hDC, m_TextColor);
|
||||
}
|
||||
GetTextExtentPoint32(drawDC->m_hDC, arr.GetAt(i), arr.GetAt(i).GetLength() + 1, &extent);
|
||||
|
||||
if (m_TextAlign == BS_LEFT)
|
||||
{
|
||||
drawDC->DrawText(arr.GetAt(i), arr.GetAt(i).GetLength(), r, DT_LEFT | DT_VCENTER | DT_SINGLELINE);
|
||||
}
|
||||
else if (m_TextAlign == BS_RIGHT)
|
||||
{
|
||||
drawDC->DrawText(arr.GetAt(i), arr.GetAt(i).GetLength(), r, DT_RIGHT | DT_VCENTER | DT_SINGLELINE);
|
||||
}
|
||||
else
|
||||
{
|
||||
drawDC->DrawText(arr.GetAt(i), arr.GetAt(i).GetLength(), r, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
|
||||
}
|
||||
|
||||
drawDC->SelectObject(oldFont);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------
|
||||
// Image
|
||||
//------------------------------------------------
|
||||
|
||||
BOOL CButtonFx::LoadBitmap(LPCTSTR fileName)
|
||||
{
|
||||
if (m_bHighContrast) { return FALSE; }
|
||||
if (fileName == NULL) { return FALSE; }
|
||||
|
||||
m_CtrlImage.Destroy();
|
||||
m_CtrlImage.Load(fileName);
|
||||
if (m_CtrlImage.IsNull()) { return FALSE; }
|
||||
|
||||
return LoadBitmap((HBITMAP)m_CtrlImage);
|
||||
}
|
||||
|
||||
BOOL CButtonFx::LoadBitmap(HBITMAP hBitmap)
|
||||
{
|
||||
if (m_bHighContrast) { return FALSE; }
|
||||
|
||||
m_CtrlBitmap.Detach();
|
||||
m_CtrlBitmap.Attach(hBitmap);
|
||||
|
||||
return SetBitmap(m_CtrlBitmap);
|
||||
}
|
||||
|
||||
void CButtonFx::SetBkReload(void)
|
||||
{
|
||||
m_bBkBitmapInit = FALSE;
|
||||
m_bBkLoad = FALSE;
|
||||
}
|
||||
|
||||
BOOL CButtonFx::SetBitmap(CBitmap& bitmap)
|
||||
{
|
||||
if (m_bHighContrast) { return FALSE; }
|
||||
|
||||
BITMAP bitmapInfo;
|
||||
bitmap.GetBitmap(&bitmapInfo);
|
||||
|
||||
if (m_CtrlSize.cx != bitmapInfo.bmWidth
|
||||
|| m_CtrlSize.cy != bitmapInfo.bmHeight / m_ImageCount)
|
||||
{
|
||||
ModifyStyle(BS_OWNERDRAW, 0);
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
ModifyStyle(0, BS_OWNERDRAW);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
void CButtonFx::LoadCtrlBk(CDC* drawDC)
|
||||
{
|
||||
if (m_bHighContrast) { SetBkReload(); return; }
|
||||
|
||||
if (m_BkBitmap.m_hObject != NULL)
|
||||
{
|
||||
BITMAP bitmapInfo;
|
||||
m_BkBitmap.GetBitmap(&bitmapInfo);
|
||||
if (bitmapInfo.bmBitsPixel != drawDC->GetDeviceCaps(BITSPIXEL))
|
||||
{
|
||||
SetBkReload();
|
||||
}
|
||||
}
|
||||
|
||||
if (&m_CtrlBitmap != NULL)
|
||||
{
|
||||
if (!m_bBkBitmapInit)
|
||||
{
|
||||
m_BkBitmap.DeleteObject();
|
||||
m_BkBitmap.CreateCompatibleBitmap(drawDC, m_CtrlSize.cx, m_CtrlSize.cy);
|
||||
m_bBkBitmapInit = TRUE;
|
||||
}
|
||||
|
||||
if (!m_bBkLoad)
|
||||
{
|
||||
CBitmap* pOldBitmap;
|
||||
CDC* pMemDC = new CDC;
|
||||
pMemDC->CreateCompatibleDC(drawDC);
|
||||
pOldBitmap = pMemDC->SelectObject(&m_BkBitmap);
|
||||
pMemDC->StretchBlt(0, 0, m_CtrlSize.cx, m_CtrlSize.cy, m_BkDC, m_X, m_Y, m_CtrlSize.cx, m_CtrlSize.cy, SRCCOPY);
|
||||
pMemDC->SelectObject(pOldBitmap);
|
||||
pMemDC->DeleteDC();
|
||||
delete pMemDC;
|
||||
m_bBkLoad = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------
|
||||
// Font
|
||||
//------------------------------------------------
|
||||
|
||||
void CButtonFx::SetFontEx(CString face, int size, int sizeToolTip, double zoomRatio, double fontRatio, COLORREF textColor, LONG fontWeight, BYTE fontRender)
|
||||
{
|
||||
LOGFONT logFont = { 0 };
|
||||
logFont.lfCharSet = DEFAULT_CHARSET;
|
||||
logFont.lfHeight = (LONG)(-1 * size * zoomRatio * fontRatio);
|
||||
logFont.lfQuality = fontRender;
|
||||
logFont.lfWeight = fontWeight;
|
||||
|
||||
if (face.GetLength() < 32)
|
||||
{
|
||||
wsprintf(logFont.lfFaceName, _T("%s"), (LPCTSTR)face);
|
||||
}
|
||||
else
|
||||
{
|
||||
wsprintf(logFont.lfFaceName, _T(""));
|
||||
}
|
||||
|
||||
m_Font.DeleteObject();
|
||||
m_Font.CreateFontIndirect(&logFont);
|
||||
SetFont(&m_Font);
|
||||
|
||||
logFont.lfHeight = (LONG)(-1 * sizeToolTip * zoomRatio * fontRatio);
|
||||
m_FontToolTip.DeleteObject();
|
||||
m_FontToolTip.CreateFontIndirect(&logFont);
|
||||
|
||||
m_TextColor = textColor;
|
||||
|
||||
if (m_ToolTip.m_hWnd != NULL)
|
||||
{
|
||||
m_ToolTip.SetFont(&m_FontToolTip);
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------
|
||||
// Mouse
|
||||
//------------------------------------------------
|
||||
|
||||
void CButtonFx::SetHandCursor(BOOL bHandCuror)
|
||||
{
|
||||
m_bHandCursor = bHandCuror;
|
||||
}
|
||||
|
||||
void CButtonFx::OnMouseMove(UINT nFlags, CPoint point)
|
||||
{
|
||||
if (!m_bTrackingNow)
|
||||
{
|
||||
#if _MSC_VER <= 1310
|
||||
typedef BOOL(WINAPI* Func_TrackMouseEvent)(LPTRACKMOUSEEVENT);
|
||||
static Func_TrackMouseEvent p_TrackMouseEvent = NULL;
|
||||
static BOOL bInit_TrackMouseEvent = FALSE;
|
||||
|
||||
if (bInit_TrackMouseEvent && p_TrackMouseEvent == NULL)
|
||||
{
|
||||
return; // TrackMouseEvent is not available
|
||||
}
|
||||
else
|
||||
{
|
||||
HMODULE hModule = GetModuleHandle(_T("user32.dll"));
|
||||
if (hModule)
|
||||
{
|
||||
p_TrackMouseEvent = (Func_TrackMouseEvent)GetProcAddress(hModule, "TrackMouseEvent");
|
||||
}
|
||||
}
|
||||
|
||||
if (p_TrackMouseEvent != NULL)
|
||||
{
|
||||
TRACKMOUSEEVENT tme = { sizeof(TRACKMOUSEEVENT) };
|
||||
tme.hwndTrack = m_hWnd;
|
||||
tme.dwFlags = TME_LEAVE | TME_HOVER;
|
||||
tme.dwHoverTime = 1;
|
||||
m_bTrackingNow = p_TrackMouseEvent(&tme);
|
||||
}
|
||||
bInit_TrackMouseEvent = TRUE;
|
||||
#else
|
||||
if (!m_bTrackingNow)
|
||||
{
|
||||
TRACKMOUSEEVENT tme = { sizeof(TRACKMOUSEEVENT) };
|
||||
tme.hwndTrack = m_hWnd;
|
||||
tme.dwFlags = TME_LEAVE | TME_HOVER;
|
||||
tme.dwHoverTime = 1;
|
||||
m_bTrackingNow = _TrackMouseEvent(&tme);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
CButton::OnMouseMove(nFlags, point);
|
||||
}
|
||||
|
||||
void CButtonFx::OnMouseHover(UINT nFlags, CPoint point)
|
||||
{
|
||||
#if _MSC_VER > 1310
|
||||
CButton::OnMouseHover(nFlags, point);
|
||||
#endif
|
||||
|
||||
m_bHover = TRUE;
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
void CButtonFx::OnMouseLeave()
|
||||
{
|
||||
#if _MSC_VER > 1310
|
||||
CButton::OnMouseLeave();
|
||||
#endif
|
||||
|
||||
m_bTrackingNow = FALSE;
|
||||
m_bHover = FALSE;
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
void CButtonFx::OnSetfocus()
|
||||
{
|
||||
m_bFocas = TRUE;
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
void CButtonFx::OnKillfocus()
|
||||
{
|
||||
m_bFocas = FALSE;
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
BOOL CButtonFx::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
|
||||
{
|
||||
HCURSOR hCursor = NULL;
|
||||
if (m_bHandCursor)
|
||||
{
|
||||
hCursor = AfxGetApp()->LoadStandardCursor(IDC_HAND);
|
||||
if (hCursor)
|
||||
{
|
||||
::SetCursor(hCursor);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
hCursor = AfxGetApp()->LoadStandardCursor(IDC_ARROW);
|
||||
if (hCursor)
|
||||
{
|
||||
::SetCursor(hCursor);
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void CButtonFx::SetSelected(BOOL bSelected)
|
||||
{
|
||||
m_bSelected = bSelected;
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
//------------------------------------------------
|
||||
// ToolTip
|
||||
//------------------------------------------------
|
||||
|
||||
void CButtonFx::SetToolTipText(LPCTSTR text)
|
||||
{
|
||||
if (text == NULL) { return; }
|
||||
|
||||
InitToolTip();
|
||||
m_ToolTipText = text;
|
||||
if (m_ToolTip.GetToolCount() == 0)
|
||||
{
|
||||
CRect rect;
|
||||
GetClientRect(rect);
|
||||
m_ToolTip.AddTool(this, m_ToolTipText, rect, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ToolTip.UpdateTipText(m_ToolTipText, this, 1);
|
||||
}
|
||||
|
||||
SetToolTipActivate(TRUE);
|
||||
}
|
||||
|
||||
void CButtonFx::SetToolTipActivate(BOOL bActivate)
|
||||
{
|
||||
if (m_ToolTip.GetToolCount() == 0) { return; }
|
||||
m_ToolTip.Activate(bActivate);
|
||||
}
|
||||
|
||||
void CButtonFx::SetToolTipWindowText(LPCTSTR text)
|
||||
{
|
||||
SetToolTipText(text);
|
||||
SetWindowText(text);
|
||||
}
|
||||
|
||||
CString CButtonFx::GetToolTipText()
|
||||
{
|
||||
return m_ToolTipText;
|
||||
}
|
||||
|
||||
void CButtonFx::InitToolTip()
|
||||
{
|
||||
if (m_ToolTip.m_hWnd == NULL)
|
||||
{
|
||||
m_ToolTip.Create(this, TTS_ALWAYSTIP | TTS_BALLOON | TTS_NOANIMATE | TTS_NOFADE);
|
||||
m_ToolTip.Activate(FALSE);
|
||||
m_ToolTip.SetFont(&m_FontToolTip);
|
||||
m_ToolTip.SendMessage(TTM_SETMAXTIPWIDTH, 0, 1024);
|
||||
m_ToolTip.SetDelayTime(TTDT_AUTOPOP, 8000);
|
||||
m_ToolTip.SetDelayTime(TTDT_INITIAL, 500);
|
||||
m_ToolTip.SetDelayTime(TTDT_RESHOW, 100);
|
||||
}
|
||||
}
|
||||
|
||||
BOOL CButtonFx::PreTranslateMessage(MSG* pMsg)
|
||||
{
|
||||
InitToolTip();
|
||||
m_ToolTip.RelayEvent(pMsg);
|
||||
|
||||
return CButton::PreTranslateMessage(pMsg);
|
||||
}
|
||||
|
||||
BOOL CButtonFx::OnEraseBkgnd(CDC* pDC)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
/*---------------------------------------------------------------------------*/
|
||||
// Author : hiyohiyo
|
||||
// Mail : hiyohiyo@crystalmark.info
|
||||
// Web : https://crystalmark.info/
|
||||
// License : MIT License
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <afxtempl.h>
|
||||
|
||||
#include "ImageFx.h"
|
||||
|
||||
class CButtonFx : public CButton
|
||||
{
|
||||
DECLARE_DYNAMIC(CButtonFx);
|
||||
|
||||
public:
|
||||
// Constructors
|
||||
CButtonFx();
|
||||
virtual ~CButtonFx();
|
||||
|
||||
// Control
|
||||
BOOL InitControl(int x, int y, int width, int height, double zoomRatio, HPALETTE hPal, CDC* bkDC,
|
||||
LPCTSTR imagePath, int imageCount, DWORD textAlign, int renderMode, BOOL bHighContrast, BOOL bDarkMode, BOOL bDrawFrame);
|
||||
BOOL ReloadImage(LPCTSTR imagePath, UINT imageCount);
|
||||
void SetMargin(int top, int left, int bottom, int right, double zoomRatio);
|
||||
CSize GetSize(void);
|
||||
void SetDrawFrame(BOOL bDrawFrame);
|
||||
void SetGlassColor(COLORREF glassColor, BYTE glassAlpha);
|
||||
void SetMeter(BOOL bMeter, double meterRatio);
|
||||
void SetLabelUnit(CString label, CString unit);
|
||||
void SetLabelUnitFormat(UINT labelFormat, UINT unitFormat);
|
||||
void SetTextFormat(UINT format);
|
||||
|
||||
// Font
|
||||
void SetFontEx(CString face, int size, int sizeToolTip, double zoomRatio, double fontRatio = 1.0,
|
||||
COLORREF textColor = RGB(0, 0, 0), LONG fontWeight = FW_NORMAL, BYTE fontRender = CLEARTYPE_NATURAL_QUALITY);
|
||||
|
||||
// Mouse
|
||||
void SetHandCursor(BOOL bHandCuror = TRUE);
|
||||
void SetSelected(BOOL bSelected = TRUE);
|
||||
|
||||
// ToolTip
|
||||
void SetToolTipText(LPCTSTR text);
|
||||
void SetToolTipActivate(BOOL bActivate = TRUE);
|
||||
void SetToolTipWindowText(LPCTSTR text);
|
||||
CString GetToolTipText();
|
||||
|
||||
protected:
|
||||
// Draw Control
|
||||
virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
|
||||
virtual void DrawControl(CDC* drawDC, LPDRAWITEMSTRUCT lpDrawItemStruct, CBitmap& ctrlBitmap, CBitmap& bkBitmap, int no);
|
||||
virtual void DrawString(CDC* drawDC, LPDRAWITEMSTRUCT lpDrawItemStruct);
|
||||
|
||||
// Image
|
||||
BOOL LoadBitmap(LPCTSTR pFileName);
|
||||
BOOL LoadBitmap(HBITMAP hBitmap);
|
||||
void SetBkReload(void);
|
||||
BOOL SetBitmap(CBitmap& bitmap);
|
||||
void LoadCtrlBk(CDC* drawDC);
|
||||
|
||||
// ToolTip
|
||||
void InitToolTip();
|
||||
virtual BOOL PreTranslateMessage(MSG* pMsg);
|
||||
|
||||
// Message Map
|
||||
DECLARE_MESSAGE_MAP()
|
||||
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
|
||||
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
|
||||
afx_msg void OnMouseHover(UINT nFlags, CPoint point);
|
||||
afx_msg void OnMouseLeave();
|
||||
afx_msg void OnKillfocus();
|
||||
afx_msg void OnSetfocus();
|
||||
afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);
|
||||
|
||||
protected:
|
||||
// Control
|
||||
int m_X;
|
||||
int m_Y;
|
||||
CSize m_CtrlSize;
|
||||
CRect m_Margin;
|
||||
int m_RenderMode;
|
||||
BOOL m_bHighContrast;
|
||||
BOOL m_bDarkMode;
|
||||
BOOL m_bDrawFrame;
|
||||
COLORREF m_FrameColor;
|
||||
HPALETTE m_hPal;
|
||||
|
||||
CString m_Label;
|
||||
CString m_Unit;
|
||||
|
||||
UINT m_TextFormat;
|
||||
UINT m_LabelFormat;
|
||||
UINT m_UnitFormat;
|
||||
|
||||
// Glass
|
||||
COLORREF m_GlassColor;
|
||||
BYTE m_GlassAlpha;
|
||||
|
||||
// Meter
|
||||
BOOL m_bMeter;
|
||||
double m_MeterRatio;
|
||||
|
||||
// Image
|
||||
CString m_ImagePath;
|
||||
int m_ImageCount;
|
||||
CDC* m_BkDC;
|
||||
CBitmap m_BkBitmap;
|
||||
BOOL m_bBkBitmapInit;
|
||||
BOOL m_bBkLoad;
|
||||
CBitmap m_CtrlBitmap;
|
||||
CImage m_CtrlImage;
|
||||
|
||||
// Font
|
||||
DWORD m_TextAlign;
|
||||
CFont m_Font;
|
||||
CFont m_FontToolTip;
|
||||
COLORREF m_TextColor;
|
||||
|
||||
// ToolTip
|
||||
CToolTipCtrl m_ToolTip;
|
||||
CString m_ToolTipText;
|
||||
|
||||
// Mouse
|
||||
BOOL m_bHover;
|
||||
BOOL m_bFocas;
|
||||
BOOL m_bTrackingNow;
|
||||
BOOL m_bHandCursor;
|
||||
BOOL m_bSelected;
|
||||
};
|
||||
@@ -0,0 +1,836 @@
|
||||
/*---------------------------------------------------------------------------*/
|
||||
// Author : hiyohiyo
|
||||
// Mail : hiyohiyo@crystalmark.info
|
||||
// Web : https://crystalmark.info/
|
||||
// License : MIT License
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "ComboBoxFx.h"
|
||||
|
||||
#if _MSC_VER <= 1310
|
||||
#define ON_WM_MOUSEHOVER() \
|
||||
{ 0x2A1 /*WM_MOUSEHOVER*/, 0, 0, 0, AfxSig_vwp, \
|
||||
(AFX_PMSG)(AFX_PMSGW) \
|
||||
(static_cast< void (AFX_MSG_CALL CWnd::*)(UINT, CPoint) > (OnMouseHover)) },
|
||||
|
||||
#define ON_WM_MOUSELEAVE() \
|
||||
{ 0x2A3 /*WM_MOUSELEAVE*/, 0, 0, 0, AfxSig_vv, \
|
||||
(AFX_PMSG)(AFX_PMSGW) \
|
||||
(static_cast< void (AFX_MSG_CALL CWnd::*)(void) > (OnMouseLeave)) },
|
||||
#endif
|
||||
|
||||
////------------------------------------------------
|
||||
// CComboBoxFx
|
||||
////------------------------------------------------
|
||||
|
||||
CComboBoxFx::CComboBoxFx()
|
||||
{
|
||||
// Control
|
||||
m_X = 0;
|
||||
m_Y = 0;
|
||||
m_ZoomRatio = 1.0;
|
||||
m_bHighContrast = FALSE;
|
||||
m_bDarkMode = FALSE;
|
||||
m_RenderMode = SystemDraw;
|
||||
m_Margin.top = 0;
|
||||
m_Margin.left = 0;
|
||||
m_Margin.bottom = 0;
|
||||
m_Margin.right = 0;
|
||||
|
||||
// Alpha/Glass
|
||||
m_Alpha = 255;
|
||||
m_GlassColor = RGB(255, 255, 255);
|
||||
m_GlassAlpha = 255;
|
||||
|
||||
// Image
|
||||
m_ImageCount = 0;
|
||||
m_ImagePath = _T("");
|
||||
m_BkDC = NULL;
|
||||
m_bBkBitmapInit = FALSE;
|
||||
m_bBkLoad = FALSE;
|
||||
|
||||
// Font
|
||||
m_TextAlign = SS_LEFT;
|
||||
m_TextColor = RGB(0, 0, 0);
|
||||
m_TextColorSelected = RGB(255, 255, 255);
|
||||
m_BkColor = RGB(255, 255, 255);
|
||||
m_BkColorSelected = RGB(230, 230, 230);
|
||||
m_TextColorHc = RGB(255, 255, 255);
|
||||
m_TextColorSelectedHc = RGB(0, 0, 0);
|
||||
m_BkColorHc = RGB(0, 0, 0);
|
||||
m_BkColorSelectedHc = RGB(0, 255, 255);
|
||||
m_FontHeight = 16;
|
||||
m_FontRender = CLEARTYPE_NATURAL_QUALITY;
|
||||
|
||||
// Mouse
|
||||
m_bHover = FALSE;
|
||||
m_bFocas = FALSE;
|
||||
m_bTrackingNow = FALSE;
|
||||
m_bHandCursor = FALSE;
|
||||
}
|
||||
|
||||
CComboBoxFx::~CComboBoxFx()
|
||||
{
|
||||
m_BkBrush.DeleteObject();
|
||||
}
|
||||
|
||||
IMPLEMENT_DYNAMIC(CComboBoxFx, CComboBox)
|
||||
|
||||
BEGIN_MESSAGE_MAP(CComboBoxFx, CComboBox)
|
||||
//{{AFX_MSG_MAP(CComboBoxFx)
|
||||
ON_WM_CTLCOLOR()
|
||||
ON_WM_MOUSEMOVE()
|
||||
ON_WM_MOUSEHOVER()
|
||||
ON_WM_MOUSELEAVE()
|
||||
ON_WM_KILLFOCUS()
|
||||
ON_WM_SETFOCUS()
|
||||
ON_WM_SETCURSOR()
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
//------------------------------------------------
|
||||
// Control
|
||||
//------------------------------------------------
|
||||
|
||||
BOOL CComboBoxFx::InitControl(int x, int y, int width, int height, double zoomRatio, CDC* bkDC,
|
||||
LPCWSTR imagePath, int imageCount, DWORD textAlign, int renderMode, BOOL bHighContrast, BOOL bDarkMode,
|
||||
COLORREF bkColor, COLORREF bkColorSelected, COLORREF glassColor, BYTE glassAlpha)
|
||||
{
|
||||
m_X = (int)(x * zoomRatio);
|
||||
m_Y = (int)(y * zoomRatio);
|
||||
m_ZoomRatio = zoomRatio;
|
||||
m_CtrlSize.cx = (int)(width * zoomRatio);
|
||||
m_CtrlSize.cy = (int)(height * zoomRatio);
|
||||
MoveWindow(m_X, m_Y, m_CtrlSize.cx, m_CtrlSize.cy);
|
||||
|
||||
m_BkDC = bkDC;
|
||||
m_ImagePath = imagePath;
|
||||
m_ImageCount = imageCount;
|
||||
m_RenderMode = renderMode;
|
||||
|
||||
m_BkColor = bkColor;
|
||||
m_BkColorSelected = bkColorSelected;
|
||||
m_GlassColor = glassColor;
|
||||
m_GlassAlpha = glassAlpha;
|
||||
|
||||
// BkBrush
|
||||
m_BkBrush.DeleteObject();
|
||||
if (bDarkMode)
|
||||
{
|
||||
m_BkBrush.CreateSolidBrush(RGB(32, 32, 32));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_BkBrush.CreateSolidBrush(bkColor);
|
||||
}
|
||||
|
||||
if (ES_LEFT <= textAlign && textAlign <= ES_RIGHT)
|
||||
{
|
||||
m_TextAlign = textAlign;
|
||||
ModifyStyle(0, m_TextAlign);
|
||||
}
|
||||
|
||||
if (m_ToolTip.m_hWnd != NULL)
|
||||
{
|
||||
if (m_ToolTip.GetToolCount() != 0)
|
||||
{
|
||||
m_ToolTip.DelTool(this, 1);
|
||||
}
|
||||
CRect rect;
|
||||
GetClientRect(rect);
|
||||
m_ToolTip.AddTool(this, m_ToolTipText, rect, 1);
|
||||
}
|
||||
|
||||
m_bHighContrast = bHighContrast;
|
||||
m_bDarkMode = bDarkMode;
|
||||
|
||||
if (renderMode & SystemDraw)
|
||||
{
|
||||
#if _MSC_VER <= 1310
|
||||
if (IsNT3())
|
||||
{
|
||||
ModifyStyle(0, WS_BORDER, SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_FRAMECHANGED);
|
||||
}
|
||||
#endif
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ImageCount = 1;
|
||||
m_CtrlImage.Destroy();
|
||||
m_CtrlImage.Create(m_CtrlSize.cx, m_CtrlSize.cy * m_ImageCount, 32);
|
||||
m_CtrlBitmap.Detach();
|
||||
m_CtrlBitmap.Attach((HBITMAP)m_CtrlImage);
|
||||
DWORD length = m_CtrlSize.cx * m_CtrlSize.cy * m_ImageCount * 4;
|
||||
BYTE* bitmapBits = new BYTE[length];
|
||||
m_CtrlBitmap.GetBitmapBits(length, bitmapBits);
|
||||
|
||||
BYTE r, g, b, a;
|
||||
if (renderMode & OwnerDrawGlass)
|
||||
{
|
||||
r = (BYTE)GetRValue(m_GlassColor);
|
||||
g = (BYTE)GetGValue(m_GlassColor);
|
||||
b = (BYTE)GetBValue(m_GlassColor);
|
||||
a = m_GlassAlpha;
|
||||
}
|
||||
else // OwnerDrawTransparent
|
||||
{
|
||||
r = 0;
|
||||
g = 0;
|
||||
b = 0;
|
||||
a = 0;
|
||||
}
|
||||
|
||||
for (int y = 0; y < (int)(m_CtrlSize.cy * m_ImageCount); y++)
|
||||
{
|
||||
for (int x = 0; x < m_CtrlSize.cx; x++)
|
||||
{
|
||||
DWORD p = (y * m_CtrlSize.cx + x) * 4;
|
||||
#if _MSC_VER > 1310
|
||||
#pragma warning( disable : 6386 )
|
||||
#endif
|
||||
bitmapBits[p + 0] = b;
|
||||
bitmapBits[p + 1] = g;
|
||||
bitmapBits[p + 2] = r;
|
||||
bitmapBits[p + 3] = a;
|
||||
#if _MSC_VER > 1310
|
||||
#pragma warning( default : 6386 )
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
m_CtrlBitmap.SetBitmapBits(length, bitmapBits);
|
||||
delete[] bitmapBits;
|
||||
}
|
||||
|
||||
SetBkReload();
|
||||
Invalidate();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void CComboBoxFx::SetFontHeight(int height, double zoomRatio, double fontRatio)
|
||||
{
|
||||
m_FontHeight = (LONG)(-1 * height * zoomRatio * fontRatio);
|
||||
}
|
||||
|
||||
void CComboBoxFx::SetItemHeightEx(int nIndex, int height, double zoomRatio, double fontRatio)
|
||||
{
|
||||
if (nIndex == -1)
|
||||
{
|
||||
CRect rc;
|
||||
GetWindowRect(&rc);
|
||||
CComboBox::SetItemHeight(-1, (UINT)(height * zoomRatio - rc.Height() + GetItemHeight(-1)));
|
||||
}
|
||||
else
|
||||
{
|
||||
CComboBox::SetItemHeight(nIndex, (UINT)(height * zoomRatio * fontRatio));
|
||||
}
|
||||
}
|
||||
|
||||
void CComboBoxFx::SetItemHeightAll(int height, double zoomRatio, double fontRatio)
|
||||
{
|
||||
m_FontHeight = (LONG)(-1 * height * zoomRatio * fontRatio);
|
||||
|
||||
CRect rc;
|
||||
GetWindowRect(&rc);
|
||||
CComboBox::SetItemHeight(-1, (UINT)(height * zoomRatio - rc.Height() + GetItemHeight(-1)));
|
||||
|
||||
for(int i = 0; i < this->GetCount(); i++)
|
||||
{
|
||||
CComboBox::SetItemHeight(i, (UINT)(height * zoomRatio * fontRatio));
|
||||
}
|
||||
}
|
||||
|
||||
void CComboBoxFx::SetMargin(int top, int left, int bottom, int right, double zoomRatio)
|
||||
{
|
||||
m_Margin.top = (int)(top * zoomRatio);
|
||||
m_Margin.left = (int)(left * zoomRatio);
|
||||
m_Margin.bottom = (int)(bottom * zoomRatio);
|
||||
m_Margin.right = (int)(right * zoomRatio);
|
||||
m_ZoomRatio = zoomRatio;
|
||||
}
|
||||
|
||||
CSize CComboBoxFx::GetSize(void)
|
||||
{
|
||||
return m_CtrlSize;
|
||||
}
|
||||
|
||||
void CComboBoxFx::SetGlassColor(COLORREF glassColor, BYTE glassAlpha)
|
||||
{
|
||||
m_GlassColor = glassColor;
|
||||
m_GlassAlpha = glassAlpha;
|
||||
}
|
||||
|
||||
void CComboBoxFx::SetAlpha(BYTE alpha)
|
||||
{
|
||||
m_Alpha = alpha;
|
||||
}
|
||||
|
||||
HWND CComboBoxFx::GetListHwnd()
|
||||
{
|
||||
#if _MSC_VER > 1310
|
||||
COMBOBOXINFO info = { 0 };
|
||||
info.cbSize = sizeof(COMBOBOXINFO);
|
||||
GetComboBoxInfo(&info);
|
||||
|
||||
return info.hwndList;
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
HBRUSH CComboBoxFx::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
|
||||
{
|
||||
HBRUSH hbr = CComboBox::OnCtlColor(pDC, pWnd, nCtlColor);
|
||||
switch (nCtlColor) {
|
||||
case CTLCOLOR_EDIT:
|
||||
pDC->SetBkMode(TRANSPARENT);
|
||||
return hbr;
|
||||
case CTLCOLOR_LISTBOX:
|
||||
pDC->SetBkMode(TRANSPARENT);
|
||||
return m_BkBrush;
|
||||
default:
|
||||
return hbr;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------
|
||||
// Draw Control
|
||||
//------------------------------------------------
|
||||
|
||||
void CComboBoxFx::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
|
||||
{
|
||||
if (lpDrawItemStruct->itemID == -1) { return; }
|
||||
|
||||
static COLORREF textColor;
|
||||
static COLORREF textColorSelected;
|
||||
static COLORREF bkColor;
|
||||
static COLORREF bkColorSelected;
|
||||
|
||||
static int count = 0;
|
||||
if (m_bHighContrast)
|
||||
{
|
||||
textColor = GetTextColor(lpDrawItemStruct->hDC);
|
||||
textColorSelected = RGB(0, 0, 0);
|
||||
bkColor = GetBkColor(lpDrawItemStruct->hDC);
|
||||
bkColorSelected = RGB(0, 255, 255);
|
||||
|
||||
if (bkColor <= RGB(0x80, 0x80, 0x80)) { textColor = RGB(255, 255, 255); }
|
||||
else { textColor = RGB(0, 0, 0); }
|
||||
}
|
||||
else if (m_bDarkMode)
|
||||
{
|
||||
textColor = RGB(255, 255, 255);
|
||||
textColorSelected = RGB(255, 255, 255);
|
||||
bkColor = RGB(32, 32, 32);
|
||||
bkColorSelected = RGB(77, 77, 77);
|
||||
}
|
||||
else
|
||||
{
|
||||
textColor = m_TextColor;
|
||||
textColorSelected = m_TextColorSelected;
|
||||
bkColor = m_BkColor;
|
||||
bkColorSelected = m_BkColorSelected;
|
||||
}
|
||||
|
||||
CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
|
||||
LoadCtrlBk(pDC);
|
||||
CString title;
|
||||
GetLBText(lpDrawItemStruct->itemID, title);
|
||||
|
||||
CBrush Brush;
|
||||
CBrush* pOldBrush;
|
||||
if (lpDrawItemStruct->rcItem.left != 0 && !m_bHighContrast)
|
||||
{
|
||||
DrawControl(title, pDC, lpDrawItemStruct, m_CtrlBitmap, m_BkBitmap, ControlImageNormal);
|
||||
Brush.CreateSolidBrush(bkColorSelected);
|
||||
pOldBrush = pDC->SelectObject(&Brush);
|
||||
if (lpDrawItemStruct->itemState & ODS_SELECTED)
|
||||
{
|
||||
RECT rc = lpDrawItemStruct->rcItem;
|
||||
// rc.top = (LONG)(rc.bottom - 2 * m_ZoomRatio);
|
||||
rc.right = (LONG)(rc.left + 3 * m_ZoomRatio);
|
||||
FillRect(lpDrawItemStruct->hDC, &rc, (HBRUSH)Brush);
|
||||
}
|
||||
DrawString(title, pDC, lpDrawItemStruct, textColor);
|
||||
|
||||
#if _MSC_VER <= 1310
|
||||
if (IsNT3() && IsWindowEnabled())
|
||||
{
|
||||
DWORD oldTextAlign = m_TextAlign;
|
||||
m_TextAlign = ES_RIGHT;
|
||||
DrawString(_T("v"), pDC, lpDrawItemStruct, textColor);
|
||||
m_TextAlign = oldTextAlign;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
if (lpDrawItemStruct->itemState & ODS_SELECTED)
|
||||
{
|
||||
Brush.CreateSolidBrush(bkColorSelected);
|
||||
pOldBrush = pDC->SelectObject(&Brush);
|
||||
FillRect(lpDrawItemStruct->hDC, &lpDrawItemStruct->rcItem, (HBRUSH)Brush);
|
||||
DrawString(title, pDC, lpDrawItemStruct, textColorSelected);
|
||||
}
|
||||
else
|
||||
{
|
||||
Brush.CreateSolidBrush(bkColor);
|
||||
pOldBrush = pDC->SelectObject(&Brush);
|
||||
FillRect(lpDrawItemStruct->hDC, &lpDrawItemStruct->rcItem, (HBRUSH)Brush);
|
||||
DrawString(title, pDC, lpDrawItemStruct, textColor);
|
||||
}
|
||||
}
|
||||
pDC->SelectObject(pOldBrush);
|
||||
Brush.DeleteObject();
|
||||
}
|
||||
|
||||
void CComboBoxFx::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct)
|
||||
{
|
||||
lpMeasureItemStruct->itemHeight = abs(m_FontHeight);
|
||||
}
|
||||
|
||||
void CComboBoxFx::DrawControl(CString title, CDC* drawDC, LPDRAWITEMSTRUCT lpDrawItemStruct, CBitmap& ctrlBitmap, CBitmap& bkBitmap, int no)
|
||||
{
|
||||
CDC* pMemDC = new CDC;
|
||||
CBitmap* pOldMemBitmap;
|
||||
pMemDC->CreateCompatibleDC(drawDC);
|
||||
pOldMemBitmap = pMemDC->SelectObject(&ctrlBitmap);
|
||||
CDC* pBkDC = new CDC;
|
||||
CBitmap* pOldBkBitmap;
|
||||
pBkDC->CreateCompatibleDC(drawDC);
|
||||
pOldBkBitmap = pBkDC->SelectObject(&bkBitmap);
|
||||
|
||||
CBitmap DrawBmp;
|
||||
DrawBmp.CreateCompatibleBitmap(drawDC, m_CtrlSize.cx, m_CtrlSize.cy);
|
||||
CDC* pDrawBmpDC = new CDC;
|
||||
CBitmap* pOldDrawBitmap;
|
||||
pDrawBmpDC->CreateCompatibleDC(drawDC);
|
||||
pOldDrawBitmap = pDrawBmpDC->SelectObject(&DrawBmp);
|
||||
|
||||
int color = drawDC->GetDeviceCaps(BITSPIXEL) * drawDC->GetDeviceCaps(PLANES);
|
||||
|
||||
if (!m_CtrlImage.IsNull())
|
||||
{
|
||||
if (m_CtrlImage.GetBPP() == 32)
|
||||
{
|
||||
CBitmap* bk32Bitmap;
|
||||
CImage bk32Image;
|
||||
if (color == 32)
|
||||
{
|
||||
bk32Bitmap = &bkBitmap;
|
||||
}
|
||||
else
|
||||
{
|
||||
bk32Image.Create(m_CtrlSize.cx, m_CtrlSize.cy, 32);
|
||||
::BitBlt(bk32Image.GetDC(), 0, 0, m_CtrlSize.cx, m_CtrlSize.cy, *pBkDC, 0, 0, SRCCOPY);
|
||||
bk32Bitmap = CBitmap::FromHandle((HBITMAP)bk32Image);
|
||||
}
|
||||
|
||||
BITMAP CtlBmpInfo, DstBmpInfo;
|
||||
bk32Bitmap->GetBitmap(&DstBmpInfo);
|
||||
DWORD DstLineBytes = DstBmpInfo.bmWidthBytes;
|
||||
DWORD DstMemSize = DstLineBytes * DstBmpInfo.bmHeight;
|
||||
ctrlBitmap.GetBitmap(&CtlBmpInfo);
|
||||
DWORD CtlLineBytes = CtlBmpInfo.bmWidthBytes;
|
||||
DWORD CtlMemSize = CtlLineBytes * CtlBmpInfo.bmHeight;
|
||||
BYTE* DstBuffer = new BYTE[DstMemSize];
|
||||
bk32Bitmap->GetBitmapBits(DstMemSize, DstBuffer);
|
||||
BYTE* CtlBuffer = new BYTE[CtlMemSize];
|
||||
ctrlBitmap.GetBitmapBits(CtlMemSize, CtlBuffer);
|
||||
|
||||
int baseY = m_CtrlSize.cy * no;
|
||||
for (LONG py = 0; py < DstBmpInfo.bmHeight; py++)
|
||||
{
|
||||
int dn = py * DstLineBytes;
|
||||
int cn = (baseY + py) * CtlLineBytes;
|
||||
for (LONG px = 0; px < DstBmpInfo.bmWidth; px++)
|
||||
{
|
||||
#if _MSC_VER > 1310
|
||||
#pragma warning( disable : 6385 )
|
||||
#pragma warning( disable : 6386 )
|
||||
#endif
|
||||
BYTE a = CtlBuffer[cn + 3];
|
||||
BYTE na = 255 - a;
|
||||
DstBuffer[dn + 0] = (BYTE)((CtlBuffer[cn + 0] * a + DstBuffer[dn + 0] * na) / 255);
|
||||
DstBuffer[dn + 1] = (BYTE)((CtlBuffer[cn + 1] * a + DstBuffer[dn + 1] * na) / 255);
|
||||
DstBuffer[dn + 2] = (BYTE)((CtlBuffer[cn + 2] * a + DstBuffer[dn + 2] * na) / 255);
|
||||
dn += (DstBmpInfo.bmBitsPixel / 8);
|
||||
cn += (CtlBmpInfo.bmBitsPixel / 8);
|
||||
#if _MSC_VER > 1310
|
||||
#pragma warning( default : 6386 )
|
||||
#pragma warning( default : 6385 )
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (color == 32)
|
||||
{
|
||||
DrawBmp.SetBitmapBits(DstMemSize, DstBuffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
bk32Bitmap->SetBitmapBits(DstMemSize, DstBuffer);
|
||||
::BitBlt(pDrawBmpDC->GetSafeHdc(), 0, 0, m_CtrlSize.cx, m_CtrlSize.cy, bk32Image.GetDC(), 0, 0, SRCCOPY);
|
||||
bk32Image.ReleaseDC();
|
||||
}
|
||||
drawDC->BitBlt(0, 0, m_CtrlSize.cx, m_CtrlSize.cy, pDrawBmpDC, 0, 0, SRCCOPY);
|
||||
|
||||
delete[] DstBuffer;
|
||||
delete[] CtlBuffer;
|
||||
}
|
||||
else
|
||||
{
|
||||
pDrawBmpDC->BitBlt(0, 0, m_CtrlSize.cx, m_CtrlSize.cy, pMemDC, 0, m_CtrlSize.cy * no, SRCCOPY);
|
||||
drawDC->BitBlt(0, 0, m_CtrlSize.cx, m_CtrlSize.cy, pDrawBmpDC, 0, 0, SRCCOPY);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pDrawBmpDC->BitBlt(0, 0, m_CtrlSize.cx, m_CtrlSize.cy, pBkDC, 0, m_CtrlSize.cy * no, SRCCOPY);
|
||||
drawDC->BitBlt(0, 0, m_CtrlSize.cx, m_CtrlSize.cy, pDrawBmpDC, 0, 0, SRCCOPY);
|
||||
}
|
||||
|
||||
pDrawBmpDC->SelectObject(&pOldDrawBitmap);
|
||||
pDrawBmpDC->DeleteDC();
|
||||
delete pDrawBmpDC;
|
||||
pMemDC->SelectObject(&pOldMemBitmap);
|
||||
pMemDC->DeleteDC();
|
||||
delete pMemDC;
|
||||
pBkDC->SelectObject(&pOldBkBitmap);
|
||||
pBkDC->DeleteDC();
|
||||
delete pBkDC;
|
||||
}
|
||||
|
||||
void CComboBoxFx::DrawString(CString title, CDC* drawDC, LPDRAWITEMSTRUCT lpDrawItemStruct, COLORREF textColor)
|
||||
{
|
||||
if (title.IsEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
drawDC->SetBkMode(TRANSPARENT);
|
||||
CRect rect = (CRect)(lpDrawItemStruct->rcItem);
|
||||
rect.top += m_Margin.top;
|
||||
rect.left += m_Margin.left;
|
||||
rect.bottom -= m_Margin.bottom;
|
||||
rect.right -= m_Margin.right;
|
||||
drawDC->SetTextColor(textColor);
|
||||
|
||||
if (m_TextAlign == ES_LEFT)
|
||||
{
|
||||
drawDC->DrawText(title, title.GetLength(), rect, DT_LEFT | DT_VCENTER | DT_SINGLELINE);
|
||||
}
|
||||
else if (m_TextAlign == ES_RIGHT)
|
||||
{
|
||||
drawDC->DrawText(title, title.GetLength(), rect, DT_RIGHT | DT_VCENTER | DT_SINGLELINE);
|
||||
}
|
||||
else
|
||||
{
|
||||
drawDC->DrawText(title, title.GetLength(), rect, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------
|
||||
// Image
|
||||
//------------------------------------------------
|
||||
|
||||
BOOL CComboBoxFx::LoadBitmap(LPCTSTR fileName)
|
||||
{
|
||||
if (m_bHighContrast) { return FALSE; }
|
||||
if (fileName == NULL) { return FALSE; }
|
||||
|
||||
m_CtrlImage.Destroy();
|
||||
m_CtrlImage.Load(fileName);
|
||||
if (m_CtrlImage.IsNull()) { return FALSE; }
|
||||
|
||||
return LoadBitmap((HBITMAP)m_CtrlImage);
|
||||
}
|
||||
|
||||
BOOL CComboBoxFx::LoadBitmap(HBITMAP hBitmap)
|
||||
{
|
||||
if (m_bHighContrast) { return FALSE; }
|
||||
|
||||
m_CtrlBitmap.Detach();
|
||||
m_CtrlBitmap.Attach(hBitmap);
|
||||
|
||||
return SetBitmap(m_CtrlBitmap);
|
||||
}
|
||||
|
||||
void CComboBoxFx::SetBkReload(void)
|
||||
{
|
||||
m_bBkBitmapInit = FALSE;
|
||||
m_bBkLoad = FALSE;
|
||||
}
|
||||
|
||||
BOOL CComboBoxFx::SetBitmap(CBitmap& bitmap)
|
||||
{
|
||||
if (m_bHighContrast) { return FALSE; }
|
||||
|
||||
BITMAP bitmapinfo;
|
||||
bitmap.GetBitmap(&bitmapinfo);
|
||||
|
||||
if (m_CtrlSize.cx != bitmapinfo.bmWidth
|
||||
|| m_CtrlSize.cy != bitmapinfo.bmHeight / m_ImageCount)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
void CComboBoxFx::LoadCtrlBk(CDC* drawDC)
|
||||
{
|
||||
if (m_bHighContrast) { SetBkReload(); return; }
|
||||
|
||||
if (m_BkBitmap.m_hObject != NULL)
|
||||
{
|
||||
BITMAP bitmapInfo;
|
||||
m_BkBitmap.GetBitmap(&bitmapInfo);
|
||||
if (bitmapInfo.bmBitsPixel != drawDC->GetDeviceCaps(BITSPIXEL))
|
||||
{
|
||||
SetBkReload();
|
||||
}
|
||||
}
|
||||
|
||||
if (&m_CtrlBitmap != NULL)
|
||||
{
|
||||
if (!m_bBkBitmapInit)
|
||||
{
|
||||
m_BkBitmap.DeleteObject();
|
||||
m_BkBitmap.CreateCompatibleBitmap(drawDC, m_CtrlSize.cx, m_CtrlSize.cy);
|
||||
m_bBkBitmapInit = TRUE;
|
||||
}
|
||||
|
||||
if (!m_bBkLoad)
|
||||
{
|
||||
CBitmap* pOldBitmap;
|
||||
CDC* pMemDC = new CDC;
|
||||
pMemDC->CreateCompatibleDC(drawDC);
|
||||
pOldBitmap = pMemDC->SelectObject(&m_BkBitmap);
|
||||
pMemDC->BitBlt(0, 0, m_CtrlSize.cx, m_CtrlSize.cy, m_BkDC, m_X, m_Y, SRCCOPY);
|
||||
pMemDC->SelectObject(pOldBitmap);
|
||||
pMemDC->DeleteDC();
|
||||
delete pMemDC;
|
||||
m_bBkLoad = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------
|
||||
// Font
|
||||
//------------------------------------------------
|
||||
|
||||
void CComboBoxFx::SetFontEx(CString face, int size, int sizeToolTip, double zoomRatio, double fontRatio,
|
||||
COLORREF textColor, COLORREF textColorSelected, LONG fontWeight, BYTE fontRender)
|
||||
{
|
||||
LOGFONT logFont = { 0 };
|
||||
logFont.lfCharSet = DEFAULT_CHARSET;
|
||||
logFont.lfHeight = (LONG)(-1 * size * zoomRatio * fontRatio);
|
||||
logFont.lfQuality = fontRender;
|
||||
logFont.lfWeight = fontWeight;
|
||||
m_FontRender = fontRender;
|
||||
|
||||
if (face.GetLength() < 32)
|
||||
{
|
||||
wsprintf(logFont.lfFaceName, _T("%s"), (LPCTSTR)face);
|
||||
}
|
||||
else
|
||||
{
|
||||
wsprintf(logFont.lfFaceName, _T(""));
|
||||
}
|
||||
|
||||
m_Font.DeleteObject();
|
||||
m_Font.CreateFontIndirect(&logFont);
|
||||
SetFont(&m_Font);
|
||||
|
||||
logFont.lfHeight = (LONG)(-1 * sizeToolTip * zoomRatio);
|
||||
m_FontToolTip.DeleteObject();
|
||||
m_FontToolTip.CreateFontIndirect(&logFont);
|
||||
|
||||
if (! m_bHighContrast)
|
||||
{
|
||||
m_TextColor = textColor;
|
||||
m_TextColorSelected = textColorSelected;
|
||||
}
|
||||
|
||||
if (m_ToolTip.m_hWnd != NULL)
|
||||
{
|
||||
m_ToolTip.SetFont(&m_FontToolTip);
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------
|
||||
// Mouse
|
||||
//------------------------------------------------
|
||||
|
||||
void CComboBoxFx::SetHandCursor(BOOL bHandCuror)
|
||||
{
|
||||
m_bHandCursor = bHandCuror;
|
||||
}
|
||||
|
||||
void CComboBoxFx::OnMouseMove(UINT nFlags, CPoint point)
|
||||
{
|
||||
#if _MSC_VER <= 1310
|
||||
typedef BOOL(WINAPI* Func_TrackMouseEvent)(LPTRACKMOUSEEVENT);
|
||||
static Func_TrackMouseEvent p_TrackMouseEvent = NULL;
|
||||
static BOOL bInit_TrackMouseEvent = FALSE;
|
||||
|
||||
if (bInit_TrackMouseEvent && p_TrackMouseEvent == NULL)
|
||||
{
|
||||
return; // TrackMouseEvent is not available
|
||||
}
|
||||
else
|
||||
{
|
||||
HMODULE hModule = GetModuleHandle(_T("user32.dll"));
|
||||
if (hModule)
|
||||
{
|
||||
p_TrackMouseEvent = (Func_TrackMouseEvent)GetProcAddress(hModule, "TrackMouseEvent");
|
||||
}
|
||||
}
|
||||
|
||||
if (p_TrackMouseEvent != NULL)
|
||||
{
|
||||
TRACKMOUSEEVENT tme = { sizeof(TRACKMOUSEEVENT) };
|
||||
tme.hwndTrack = m_hWnd;
|
||||
tme.dwFlags = TME_LEAVE | TME_HOVER;
|
||||
tme.dwHoverTime = 1;
|
||||
m_bTrackingNow = p_TrackMouseEvent(&tme);
|
||||
}
|
||||
bInit_TrackMouseEvent = TRUE;
|
||||
#else
|
||||
if (!m_bTrackingNow)
|
||||
{
|
||||
TRACKMOUSEEVENT tme = { sizeof(TRACKMOUSEEVENT) };
|
||||
tme.hwndTrack = m_hWnd;
|
||||
tme.dwFlags = TME_LEAVE | TME_HOVER;
|
||||
tme.dwHoverTime = 1;
|
||||
m_bTrackingNow = _TrackMouseEvent(&tme);
|
||||
}
|
||||
#endif
|
||||
|
||||
CComboBox::OnMouseMove(nFlags, point);
|
||||
}
|
||||
|
||||
void CComboBoxFx::OnMouseHover(UINT nFlags, CPoint point)
|
||||
{
|
||||
#if _MSC_VER > 1310
|
||||
CComboBox::OnMouseHover(nFlags, point);
|
||||
#endif
|
||||
m_bHover = TRUE;
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
void CComboBoxFx::OnMouseLeave()
|
||||
{
|
||||
#if _MSC_VER > 1310
|
||||
CComboBox::OnMouseLeave();
|
||||
#endif
|
||||
m_bTrackingNow = FALSE;
|
||||
m_bHover = FALSE;
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
void CComboBoxFx::OnSetfocus()
|
||||
{
|
||||
m_bFocas = TRUE;
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
void CComboBoxFx::OnKillfocus()
|
||||
{
|
||||
m_bFocas = FALSE;
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
BOOL CComboBoxFx::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
|
||||
{
|
||||
HCURSOR hCursor = NULL;
|
||||
if (m_bHandCursor)
|
||||
{
|
||||
hCursor = AfxGetApp()->LoadStandardCursor(IDC_HAND);
|
||||
if (hCursor)
|
||||
{
|
||||
::SetCursor(hCursor);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
hCursor = AfxGetApp()->LoadStandardCursor(IDC_ARROW);
|
||||
if (hCursor)
|
||||
{
|
||||
::SetCursor(hCursor);
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//------------------------------------------------
|
||||
// ToolTip
|
||||
//------------------------------------------------
|
||||
|
||||
void CComboBoxFx::SetToolTipText(LPCTSTR text)
|
||||
{
|
||||
if (text == NULL) { return; }
|
||||
|
||||
InitToolTip();
|
||||
m_ToolTipText = text;
|
||||
|
||||
if (m_ToolTip.GetToolCount() == 0)
|
||||
{
|
||||
CRect rect;
|
||||
GetClientRect(rect);
|
||||
m_ToolTip.AddTool(this, m_ToolTipText, rect, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ToolTip.UpdateTipText(m_ToolTipText, this, 1);
|
||||
}
|
||||
|
||||
SetToolTipActivate(TRUE);
|
||||
}
|
||||
|
||||
void CComboBoxFx::SetToolTipActivate(BOOL bActivate)
|
||||
{
|
||||
if (m_ToolTip.GetToolCount() == 0) { return; }
|
||||
m_ToolTip.Activate(bActivate);
|
||||
}
|
||||
|
||||
void CComboBoxFx::SetToolTipWindowText(LPCTSTR pText)
|
||||
{
|
||||
SetToolTipText(pText);
|
||||
SetWindowText(pText);
|
||||
}
|
||||
|
||||
CString CComboBoxFx::GetToolTipText()
|
||||
{
|
||||
return m_ToolTipText;
|
||||
}
|
||||
|
||||
void CComboBoxFx::InitToolTip()
|
||||
{
|
||||
if (m_ToolTip.m_hWnd == NULL)
|
||||
{
|
||||
m_ToolTip.Create(this, TTS_ALWAYSTIP | TTS_BALLOON | TTS_NOANIMATE | TTS_NOFADE);
|
||||
m_ToolTip.Activate(FALSE);
|
||||
m_ToolTip.SetFont(&m_FontToolTip);
|
||||
m_ToolTip.SendMessage(TTM_SETMAXTIPWIDTH, 0, 1024);
|
||||
m_ToolTip.SetDelayTime(TTDT_AUTOPOP, 8000);
|
||||
m_ToolTip.SetDelayTime(TTDT_INITIAL, 500);
|
||||
m_ToolTip.SetDelayTime(TTDT_RESHOW, 100);
|
||||
}
|
||||
}
|
||||
|
||||
BOOL CComboBoxFx::PreTranslateMessage(MSG* pMsg)
|
||||
{
|
||||
InitToolTip();
|
||||
m_ToolTip.RelayEvent(pMsg);
|
||||
|
||||
return CComboBox::PreTranslateMessage(pMsg);
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
/*---------------------------------------------------------------------------*/
|
||||
// Author : hiyohiyo
|
||||
// Mail : hiyohiyo@crystalmark.info
|
||||
// Web : https://crystalmark.info/
|
||||
// License : MIT License
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ImageFx.h"
|
||||
|
||||
class CComboBoxFx : public CComboBox
|
||||
{
|
||||
DECLARE_DYNAMIC(CComboBoxFx);
|
||||
|
||||
// Constructors
|
||||
public:
|
||||
CComboBoxFx();
|
||||
virtual ~CComboBoxFx();
|
||||
|
||||
// Control
|
||||
public:
|
||||
BOOL InitControl(int x, int y, int width, int height, double zoomRatio, CDC* bkDC,
|
||||
LPCWSTR imagePath, int imageCount, DWORD textAlign, int renderMode, BOOL bHighContrast, BOOL m_bDarkMode,
|
||||
COLORREF bkColor, COLORREF bkColorSelected, COLORREF glassColor, BYTE glassAlpha
|
||||
);
|
||||
void SetFontHeight(int height, double zoomRatio, double fontRatio = 1.0);
|
||||
void SetItemHeightEx(int nIndex, int height, double zoomRatio, double fontRatio = 1.0);
|
||||
void SetItemHeightAll(int height, double zoomRatio, double fontRatio = 1.0);
|
||||
void SetMargin(int top, int left, int bottom, int right, double zoomRatio);
|
||||
CSize GetSize(void);
|
||||
void SetGlassColor(COLORREF glassColor, BYTE glassAlpha);
|
||||
void SetAlpha(BYTE alpha);
|
||||
HWND GetListHwnd();
|
||||
|
||||
// Font
|
||||
void SetFontEx(CString face, int size, int sizeToolTip, double zoomRatio, double fontRatio = 1.0,
|
||||
COLORREF textColor = RGB(0, 0, 0), COLORREF textColorSelected = RGB(0, 0, 0), LONG fontWeight = FW_NORMAL, BYTE fontRender = CLEARTYPE_NATURAL_QUALITY);
|
||||
|
||||
// ToolTip
|
||||
void SetToolTipText(LPCTSTR pText);
|
||||
void SetToolTipActivate(BOOL bActivate = TRUE);
|
||||
void SetToolTipWindowText(LPCTSTR pText);
|
||||
CString GetToolTipText();
|
||||
|
||||
// Mouse
|
||||
void SetHandCursor(BOOL bHandCuror = TRUE);
|
||||
|
||||
protected:
|
||||
// Draw Control
|
||||
virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
|
||||
virtual void MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct);
|
||||
virtual void DrawControl(CString title, CDC* drawDC, LPDRAWITEMSTRUCT lpDrawItemStruct, CBitmap& ctrlBitmap, CBitmap& bkBitmap, int no);
|
||||
virtual void DrawString(CString title, CDC* drawDC, LPDRAWITEMSTRUCT lpDrawItemStruct, COLORREF textColor);
|
||||
|
||||
// Image
|
||||
BOOL LoadBitmap(LPCTSTR fileName);
|
||||
BOOL LoadBitmap(HBITMAP hBitmap);
|
||||
void SetBkReload(void);
|
||||
BOOL SetBitmap(CBitmap& bitmap);
|
||||
void LoadCtrlBk(CDC* drawDC);
|
||||
|
||||
// ToolTip
|
||||
void InitToolTip();
|
||||
virtual BOOL PreTranslateMessage(MSG* pMsg);
|
||||
|
||||
// Message Map
|
||||
DECLARE_MESSAGE_MAP()
|
||||
afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
|
||||
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
|
||||
afx_msg void OnMouseHover(UINT nFlags, CPoint point);
|
||||
afx_msg void OnMouseLeave();
|
||||
afx_msg void OnKillfocus();
|
||||
afx_msg void OnSetfocus();
|
||||
afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);
|
||||
|
||||
protected:
|
||||
// Control
|
||||
int m_X;
|
||||
int m_Y;
|
||||
double m_ZoomRatio;
|
||||
CSize m_CtrlSize;
|
||||
CRect m_Margin;
|
||||
int m_RenderMode;
|
||||
BOOL m_bHighContrast;
|
||||
BOOL m_bDarkMode;
|
||||
BYTE m_FontRender; // For FontComboBoxFx
|
||||
|
||||
// Alpha/Glass
|
||||
BYTE m_Alpha;
|
||||
COLORREF m_GlassColor;
|
||||
BYTE m_GlassAlpha;
|
||||
|
||||
// Image
|
||||
CString m_ImagePath;
|
||||
int m_ImageCount;
|
||||
CDC* m_BkDC;
|
||||
CBitmap m_BkBitmap;
|
||||
BOOL m_bBkBitmapInit;
|
||||
BOOL m_bBkLoad;
|
||||
CBitmap m_CtrlBitmap;
|
||||
CImage m_CtrlImage;
|
||||
|
||||
// Font
|
||||
DWORD m_TextAlign;
|
||||
CFont m_Font;
|
||||
CFont m_FontToolTip;
|
||||
COLORREF m_TextColor;
|
||||
COLORREF m_TextColorSelected;
|
||||
COLORREF m_BkColor;
|
||||
COLORREF m_BkColorSelected;
|
||||
COLORREF m_TextColorHc;
|
||||
COLORREF m_TextColorSelectedHc;
|
||||
COLORREF m_BkColorHc;
|
||||
COLORREF m_BkColorSelectedHc;
|
||||
LONG m_FontHeight;
|
||||
|
||||
// ToolTip
|
||||
CToolTipCtrl m_ToolTip;
|
||||
CString m_ToolTipText;
|
||||
|
||||
// Mouse
|
||||
BOOL m_bHover;
|
||||
BOOL m_bFocas;
|
||||
BOOL m_bTrackingNow;
|
||||
BOOL m_bHandCursor;
|
||||
|
||||
// Brush
|
||||
CBrush m_BkBrush;
|
||||
};
|
||||
@@ -0,0 +1,89 @@
|
||||
/*---------------------------------------------------------------------------*/
|
||||
// Author : hiyohiyo
|
||||
// Mail : hiyohiyo@crystalmark.info
|
||||
// Web : https://crystalmark.info/
|
||||
// License : MIT License
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
//------------------------------------------------
|
||||
// Naming Conventions
|
||||
//------------------------------------------------
|
||||
// BOOL bXxxxYyyy
|
||||
// HANDLE hXxxxYyyy
|
||||
// Pointer pXxxxYyyy
|
||||
// Function SampleFunction
|
||||
// Variable sampleVariable
|
||||
// Const Value ConstVaiable
|
||||
// Member Variable m_XxxxYyyy
|
||||
|
||||
//------------------------------------------------
|
||||
// Order for C*****Fx Control
|
||||
//------------------------------------------------
|
||||
// Control > Draw Control > Image > Font > Mouse > ToolTip
|
||||
//
|
||||
|
||||
//------------------------------------------------
|
||||
// Utility Macros
|
||||
//------------------------------------------------
|
||||
|
||||
#define SAFE_DELETE(p) {if(p){delete (p);(p)=NULL;}}
|
||||
|
||||
#if _MSC_VER > 1310
|
||||
#define MENU_MODIFY_MENU menu->ModifyMenu
|
||||
#define SUBMENU_MODIFY_MENU subMenu.ModifyMenu
|
||||
#else
|
||||
#define MENU_MODIFY_MENU if(!IsNT3())menu->ModifyMenu
|
||||
#define SUBMENU_MODIFY_MENU if(!IsNT3())subMenu.ModifyMenu
|
||||
#endif
|
||||
|
||||
//------------------------------------------------
|
||||
// WM_APP
|
||||
//------------------------------------------------
|
||||
// WM_APP + 0x0000-0x0BFF: User Application
|
||||
// WM_APP + 0x0C00-0x0FFF: Project Priscilla
|
||||
// WM_APP + 0x0C00-0x0CFF: Theme
|
||||
// WM_APP + 0x0D00-0x0DFF: Language
|
||||
// WP_APP + 0x0E00-0x0FFF: Reserved
|
||||
// WM_APP + 0x1000-0x3FFF: User Application
|
||||
|
||||
#define WM_THEME_ID (WM_APP + 0x0C00)
|
||||
#define WM_LANGUAGE_ID (WM_APP + 0x0D00)
|
||||
|
||||
//------------------------------------------------
|
||||
// TIMER ID
|
||||
//------------------------------------------------
|
||||
// 0x0000 - 0x0FFF: Project Priscilla
|
||||
// 0x1000 - : User Application
|
||||
|
||||
static const int TimerUpdateDialogSizeDpiChanged = 0x0001;
|
||||
static const int TimerUpdateDialogSizeDisplayChange = 0x0002;
|
||||
static const int TimerUpdateDialogSizeSysColorChange = 0x0003;
|
||||
static const int TimerUpdateDialogSizeSettingChange = 0x0004;
|
||||
|
||||
//------------------------------------------------
|
||||
// Const Values
|
||||
//------------------------------------------------
|
||||
|
||||
static const int ControlImageNormal = 0x0000;
|
||||
static const int ControlImageHover = 0x0001;
|
||||
static const int ControlImageFocus = 0x0002;
|
||||
static const int ControlImageSelected = 0x0003;
|
||||
static const int ControlImageDisabled = 0x0004;
|
||||
|
||||
static const int SystemDraw = 0x0001;
|
||||
static const int OwnerDrawImage = 0x0002;
|
||||
static const int OwnerDrawGlass = 0x0004;
|
||||
static const int OwnerDrawTransparent = 0x0008;
|
||||
|
||||
static const int ZoomTypeAuto = 0;
|
||||
static const int ZoomType050 = 50;
|
||||
static const int ZoomType064 = 64;
|
||||
static const int ZoomType075 = 75;
|
||||
static const int ZoomType100 = 100;
|
||||
static const int ZoomType125 = 125;
|
||||
static const int ZoomType150 = 150;
|
||||
static const int ZoomType200 = 200;
|
||||
static const int ZoomType250 = 250;
|
||||
static const int ZoomType300 = 300;
|
||||
@@ -0,0 +1,261 @@
|
||||
/*---------------------------------------------------------------------------*/
|
||||
// Author : Richard Yu
|
||||
// Web : https://github.com/ysc3839/win32-darkmode
|
||||
// License : MIT License
|
||||
// https://github.com/ysc3839/win32-darkmode/blob/master/LICENSE
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "OsInfoFx.h"
|
||||
#include "IatHook.h"
|
||||
|
||||
enum IMMERSIVE_HC_CACHE_MODE
|
||||
{
|
||||
IHCM_USE_CACHED_VALUE,
|
||||
IHCM_REFRESH
|
||||
};
|
||||
|
||||
// 1903 18362
|
||||
enum class PreferredAppMode
|
||||
{
|
||||
Default,
|
||||
AllowDark,
|
||||
ForceDark,
|
||||
ForceLight,
|
||||
Max
|
||||
};
|
||||
|
||||
enum WINDOWCOMPOSITIONATTRIB
|
||||
{
|
||||
WCA_UNDEFINED = 0,
|
||||
WCA_NCRENDERING_ENABLED = 1,
|
||||
WCA_NCRENDERING_POLICY = 2,
|
||||
WCA_TRANSITIONS_FORCEDISABLED = 3,
|
||||
WCA_ALLOW_NCPAINT = 4,
|
||||
WCA_CAPTION_BUTTON_BOUNDS = 5,
|
||||
WCA_NONCLIENT_RTL_LAYOUT = 6,
|
||||
WCA_FORCE_ICONIC_REPRESENTATION = 7,
|
||||
WCA_EXTENDED_FRAME_BOUNDS = 8,
|
||||
WCA_HAS_ICONIC_BITMAP = 9,
|
||||
WCA_THEME_ATTRIBUTES = 10,
|
||||
WCA_NCRENDERING_EXILED = 11,
|
||||
WCA_NCADORNMENTINFO = 12,
|
||||
WCA_EXCLUDED_FROM_LIVEPREVIEW = 13,
|
||||
WCA_VIDEO_OVERLAY_ACTIVE = 14,
|
||||
WCA_FORCE_ACTIVEWINDOW_APPEARANCE = 15,
|
||||
WCA_DISALLOW_PEEK = 16,
|
||||
WCA_CLOAK = 17,
|
||||
WCA_CLOAKED = 18,
|
||||
WCA_ACCENT_POLICY = 19,
|
||||
WCA_FREEZE_REPRESENTATION = 20,
|
||||
WCA_EVER_UNCLOAKED = 21,
|
||||
WCA_VISUAL_OWNER = 22,
|
||||
WCA_HOLOGRAPHIC = 23,
|
||||
WCA_EXCLUDED_FROM_DDA = 24,
|
||||
WCA_PASSIVEUPDATEMODE = 25,
|
||||
WCA_USEDARKMODECOLORS = 26,
|
||||
WCA_LAST = 27
|
||||
};
|
||||
|
||||
struct WINDOWCOMPOSITIONATTRIBDATA
|
||||
{
|
||||
WINDOWCOMPOSITIONATTRIB Attrib;
|
||||
PVOID pvData;
|
||||
SIZE_T cbData;
|
||||
};
|
||||
|
||||
using fnRtlGetNtVersionNumbers = void (WINAPI*)(LPDWORD major, LPDWORD minor, LPDWORD build);
|
||||
using fnSetWindowCompositionAttribute = BOOL(WINAPI*)(HWND hWnd, WINDOWCOMPOSITIONATTRIBDATA*);
|
||||
// 1809 17763
|
||||
using fnShouldAppsUseDarkMode = bool (WINAPI*)(); // ordinal 132
|
||||
using fnAllowDarkModeForWindow = bool (WINAPI*)(HWND hWnd, bool allow); // ordinal 133
|
||||
using fnAllowDarkModeForApp = bool (WINAPI*)(bool allow); // ordinal 135, in 1809
|
||||
using fnFlushMenuThemes = void (WINAPI*)(); // ordinal 136
|
||||
using fnRefreshImmersiveColorPolicyState = void (WINAPI*)(); // ordinal 104
|
||||
using fnIsDarkModeAllowedForWindow = bool (WINAPI*)(HWND hWnd); // ordinal 137
|
||||
using fnGetIsImmersiveColorUsingHighContrast = bool (WINAPI*)(IMMERSIVE_HC_CACHE_MODE mode); // ordinal 106
|
||||
using fnOpenNcThemeData = HTHEME(WINAPI*)(HWND hWnd, LPCWSTR pszClassList); // ordinal 49
|
||||
// 1903 18362
|
||||
using fnShouldSystemUseDarkMode = bool (WINAPI*)(); // ordinal 138
|
||||
using fnSetPreferredAppMode = PreferredAppMode(WINAPI*)(PreferredAppMode appMode); // ordinal 135, in 1903
|
||||
using fnIsDarkModeAllowedForApp = bool (WINAPI*)(); // ordinal 139
|
||||
|
||||
fnSetWindowCompositionAttribute _SetWindowCompositionAttribute = nullptr;
|
||||
fnShouldAppsUseDarkMode _ShouldAppsUseDarkMode = nullptr;
|
||||
fnAllowDarkModeForWindow _AllowDarkModeForWindow = nullptr;
|
||||
fnAllowDarkModeForApp _AllowDarkModeForApp = nullptr;
|
||||
fnFlushMenuThemes _FlushMenuThemes = nullptr;
|
||||
fnRefreshImmersiveColorPolicyState _RefreshImmersiveColorPolicyState = nullptr;
|
||||
fnIsDarkModeAllowedForWindow _IsDarkModeAllowedForWindow = nullptr;
|
||||
fnGetIsImmersiveColorUsingHighContrast _GetIsImmersiveColorUsingHighContrast = nullptr;
|
||||
fnOpenNcThemeData _OpenNcThemeData = nullptr;
|
||||
// 1903 18362
|
||||
fnShouldSystemUseDarkMode _ShouldSystemUseDarkMode = nullptr;
|
||||
fnSetPreferredAppMode _SetPreferredAppMode = nullptr;
|
||||
|
||||
bool g_darkModeSupported = false;
|
||||
bool g_darkModeEnabled = false;
|
||||
DWORD g_buildNumber = 0;
|
||||
|
||||
bool AllowDarkModeForWindow(HWND hWnd, bool allow)
|
||||
{
|
||||
if (g_darkModeSupported)
|
||||
return _AllowDarkModeForWindow(hWnd, allow);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IsHighContrast()
|
||||
{
|
||||
HIGHCONTRASTW highContrast = { sizeof(highContrast) };
|
||||
if (SystemParametersInfoW(SPI_GETHIGHCONTRAST, sizeof(highContrast), &highContrast, FALSE))
|
||||
return highContrast.dwFlags & HCF_HIGHCONTRASTON;
|
||||
return false;
|
||||
}
|
||||
|
||||
void AllowDarkModeForApp(bool allow)
|
||||
{
|
||||
if (_AllowDarkModeForApp)
|
||||
_AllowDarkModeForApp(allow);
|
||||
else if (_SetPreferredAppMode)
|
||||
_SetPreferredAppMode(allow ? PreferredAppMode::AllowDark : PreferredAppMode::Default);
|
||||
}
|
||||
|
||||
void RefreshTitleBarThemeColor(HWND hWnd)
|
||||
{
|
||||
BOOL dark = FALSE;
|
||||
if (_IsDarkModeAllowedForWindow(hWnd) &&
|
||||
_ShouldAppsUseDarkMode() &&
|
||||
!IsHighContrast())
|
||||
{
|
||||
dark = TRUE;
|
||||
}
|
||||
if (g_buildNumber < 18362)
|
||||
SetPropW(hWnd, L"UseImmersiveDarkModeColors", reinterpret_cast<HANDLE>(static_cast<INT_PTR>(dark)));
|
||||
else if (_SetWindowCompositionAttribute)
|
||||
{
|
||||
WINDOWCOMPOSITIONATTRIBDATA data = { WCA_USEDARKMODECOLORS, &dark, sizeof(dark) };
|
||||
_SetWindowCompositionAttribute(hWnd, &data);
|
||||
}
|
||||
}
|
||||
|
||||
constexpr bool CheckBuildNumber(DWORD buildNumber)
|
||||
{
|
||||
return (buildNumber >= 17763);
|
||||
}
|
||||
|
||||
void FixDarkScrollBar()
|
||||
{
|
||||
HMODULE hComctl = LoadLibraryExW(L"comctl32.dll", nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32);
|
||||
if (hComctl)
|
||||
{
|
||||
auto addr = FindDelayLoadThunkInModule(hComctl, "uxtheme.dll", 49); // OpenNcThemeData
|
||||
if (addr)
|
||||
{
|
||||
DWORD oldProtect;
|
||||
if (VirtualProtect(addr, sizeof(IMAGE_THUNK_DATA), PAGE_READWRITE, &oldProtect))
|
||||
{
|
||||
auto MyOpenThemeData = [](HWND hWnd, LPCWSTR classList) -> HTHEME {
|
||||
if (wcscmp(classList, L"ScrollBar") == 0)
|
||||
{
|
||||
hWnd = nullptr;
|
||||
classList = L"Explorer::ScrollBar";
|
||||
}
|
||||
return _OpenNcThemeData(hWnd, classList);
|
||||
};
|
||||
|
||||
addr->u1.Function = reinterpret_cast<ULONG_PTR>(static_cast<fnOpenNcThemeData>(MyOpenThemeData));
|
||||
VirtualProtect(addr, sizeof(IMAGE_THUNK_DATA), oldProtect, &oldProtect);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BOOL InitDarkMode()
|
||||
{
|
||||
HMODULE ntdll = GetModuleHandleW(L"ntdll.dll");
|
||||
HMODULE user32 = GetModuleHandleW(L"user32.dll");
|
||||
if (!ntdll || !user32) return FALSE;
|
||||
auto RtlGetNtVersionNumbers = reinterpret_cast<fnRtlGetNtVersionNumbers>(GetProcAddress(ntdll, "RtlGetNtVersionNumbers"));
|
||||
if (RtlGetNtVersionNumbers)
|
||||
{
|
||||
DWORD major, minor;
|
||||
RtlGetNtVersionNumbers(&major, &minor, &g_buildNumber);
|
||||
g_buildNumber &= ~0xF0000000;
|
||||
if (major == 10 && minor == 0 && CheckBuildNumber(g_buildNumber))
|
||||
{
|
||||
HMODULE hUxtheme = LoadLibraryExW(L"uxtheme.dll", nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32);
|
||||
if (hUxtheme)
|
||||
{
|
||||
_OpenNcThemeData = reinterpret_cast<fnOpenNcThemeData>(GetProcAddress(hUxtheme, MAKEINTRESOURCEA(49)));
|
||||
_RefreshImmersiveColorPolicyState = reinterpret_cast<fnRefreshImmersiveColorPolicyState>(GetProcAddress(hUxtheme, MAKEINTRESOURCEA(104)));
|
||||
_GetIsImmersiveColorUsingHighContrast = reinterpret_cast<fnGetIsImmersiveColorUsingHighContrast>(GetProcAddress(hUxtheme, MAKEINTRESOURCEA(106)));
|
||||
_ShouldAppsUseDarkMode = reinterpret_cast<fnShouldAppsUseDarkMode>(GetProcAddress(hUxtheme, MAKEINTRESOURCEA(132)));
|
||||
_AllowDarkModeForWindow = reinterpret_cast<fnAllowDarkModeForWindow>(GetProcAddress(hUxtheme, MAKEINTRESOURCEA(133)));
|
||||
|
||||
auto ord135 = GetProcAddress(hUxtheme, MAKEINTRESOURCEA(135));
|
||||
if (g_buildNumber < 18362)
|
||||
_AllowDarkModeForApp = reinterpret_cast<fnAllowDarkModeForApp>(ord135);
|
||||
else
|
||||
_SetPreferredAppMode = reinterpret_cast<fnSetPreferredAppMode>(ord135);
|
||||
|
||||
//_FlushMenuThemes = reinterpret_cast<fnFlushMenuThemes>(GetProcAddress(hUxtheme, MAKEINTRESOURCEA(136)));
|
||||
_IsDarkModeAllowedForWindow = reinterpret_cast<fnIsDarkModeAllowedForWindow>(GetProcAddress(hUxtheme, MAKEINTRESOURCEA(137)));
|
||||
|
||||
_SetWindowCompositionAttribute = reinterpret_cast<fnSetWindowCompositionAttribute>(GetProcAddress(user32, "SetWindowCompositionAttribute"));
|
||||
|
||||
if (_OpenNcThemeData &&
|
||||
_RefreshImmersiveColorPolicyState &&
|
||||
_ShouldAppsUseDarkMode &&
|
||||
_AllowDarkModeForWindow &&
|
||||
(_AllowDarkModeForApp || _SetPreferredAppMode) &&
|
||||
//_FlushMenuThemes &&
|
||||
_IsDarkModeAllowedForWindow)
|
||||
{
|
||||
g_darkModeSupported = true;
|
||||
|
||||
AllowDarkModeForApp(true);
|
||||
_RefreshImmersiveColorPolicyState();
|
||||
|
||||
g_darkModeEnabled = _ShouldAppsUseDarkMode() && !IsHighContrast();
|
||||
|
||||
// FixDarkScrollBar();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (BOOL)g_darkModeEnabled;
|
||||
}
|
||||
|
||||
BOOL SetDarkMode(HWND hWnd)
|
||||
{
|
||||
BOOL bDarkMode = FALSE;
|
||||
if (IsDarkModeSupport())
|
||||
{
|
||||
bDarkMode = InitDarkMode();
|
||||
AllowDarkModeForWindow(hWnd, bDarkMode);
|
||||
RefreshTitleBarThemeColor(hWnd);
|
||||
}
|
||||
|
||||
return bDarkMode;
|
||||
}
|
||||
|
||||
void UnsetDarkMode(HWND hWnd)
|
||||
{
|
||||
if (IsDarkModeSupport())
|
||||
{
|
||||
InitDarkMode();
|
||||
AllowDarkModeForWindow(hWnd, FALSE);
|
||||
RefreshTitleBarThemeColor(hWnd);
|
||||
}
|
||||
}
|
||||
|
||||
void SetDarkModeControl(HWND hWnd, BOOL bDarkMode)
|
||||
{
|
||||
if (IsDarkModeSupport())
|
||||
{
|
||||
SetWindowTheme(hWnd, L"Explorer", nullptr);
|
||||
AllowDarkModeForWindow(hWnd, bDarkMode);
|
||||
SendMessageW(hWnd, WM_THEMECHANGED, 0, 0);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
/*---------------------------------------------------------------------------*/
|
||||
// Author : Richard Yu
|
||||
// Web : https://github.com/ysc3839/win32-darkmode
|
||||
// License : MIT License
|
||||
// https://github.com/ysc3839/win32-darkmode/blob/master/LICENSE
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
BOOL SetDarkMode(HWND hWnd);
|
||||
void UnsetDarkMode(HWND hWnd);
|
||||
void SetDarkModeControl(HWND hWnd, BOOL bDarkMode);
|
||||
|
||||
void FixDarkScrollBar();
|
||||
bool AllowDarkModeForWindow(HWND hWnd, bool allow);
|
||||
|
||||
// BOOL InitDarkMode();
|
||||
// void RefreshTitleBarThemeColor(HWND hWnd);
|
||||
@@ -0,0 +1,738 @@
|
||||
/*---------------------------------------------------------------------------*/
|
||||
// Author : hiyohiyo
|
||||
// Mail : hiyohiyo@crystalmark.info
|
||||
// Web : https://crystalmark.info/
|
||||
// License : MIT License
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "Resource.h"
|
||||
#include "DialogFx.h"
|
||||
#include "UtilityFx.h"
|
||||
#include "OsInfoFx.h"
|
||||
#include <cmath>
|
||||
#include "DarkMode.h"
|
||||
|
||||
// defined by Windows 8.1/Windows 2012 R2
|
||||
#ifndef WM_DPICHANGED
|
||||
#define WM_DPICHANGED 0x02E0
|
||||
#endif
|
||||
|
||||
////------------------------------------------------
|
||||
// CDialogFx
|
||||
////------------------------------------------------
|
||||
|
||||
CDialogFx::CDialogFx(UINT dlgResouce, CWnd* pParent)
|
||||
:CDialog(dlgResouce, pParent)
|
||||
{
|
||||
// Dialog
|
||||
m_bInitializing = TRUE;
|
||||
m_bDpiChanging = FALSE;
|
||||
m_bShowWindow = FALSE;
|
||||
m_bModelessDlg = FALSE;
|
||||
m_bHighContrast = FALSE;
|
||||
m_bDarkMode = FALSE;
|
||||
m_bDisableDarkMode = FALSE;
|
||||
m_bBkImage = FALSE;
|
||||
m_MenuId = 0;
|
||||
m_ParentWnd = NULL;
|
||||
m_DlgWnd = NULL;
|
||||
m_hAccelerator = NULL;
|
||||
m_bDrag = FALSE;
|
||||
m_FontScale = 100;
|
||||
m_FontRatio = 1.0;
|
||||
m_FontRender = CLEARTYPE_NATURAL_QUALITY;
|
||||
m_hPal = NULL;
|
||||
|
||||
m_SizeX = 0;
|
||||
m_MaxSizeX = 65535;
|
||||
m_MinSizeX = 0;
|
||||
m_SizeY = 0;
|
||||
m_MaxSizeY = 65535;
|
||||
m_MinSizeY = 0;
|
||||
|
||||
// Zoom
|
||||
m_Dpi = 96;
|
||||
m_ZoomRatio = 1.0;
|
||||
m_ZoomType = ZoomTypeAuto;
|
||||
|
||||
// Color for SubClass
|
||||
m_LabelText = 0x00000000;
|
||||
m_MeterText = 0x00000000;
|
||||
m_ComboText = 0x00000000;
|
||||
m_ComboTextSelected = 0x00808080;
|
||||
m_ComboBk = 0x00FFFFFF;
|
||||
m_ComboBkSelected = 0x00808080;
|
||||
m_ButtonText = 0x00000000;
|
||||
m_EditText = 0x00000000;
|
||||
m_EditBk = 0x00FFFFFF;
|
||||
m_ListText1 = 0x00000000;
|
||||
m_ListText2 = 0x00000000;
|
||||
m_ListTextSelected = 0x00000000;
|
||||
m_ListBk1 = 0x00FFFFFF;
|
||||
m_ListBk2 = 0x00FFFFFF;
|
||||
m_ListBkSelected = 0x00808080;
|
||||
m_ListLine1 = 0x00000000;
|
||||
m_ListLine2 = 0x00000000;
|
||||
m_Glass = 0x00808080;
|
||||
m_Frame = 0x00808080;
|
||||
m_Background = 0xFFFFFFFF; // Disabled
|
||||
|
||||
m_ComboAlpha = 0;
|
||||
m_EditAlpha = 0;
|
||||
m_GlassAlpha = 0;
|
||||
|
||||
m_CharacterPosition = 0;
|
||||
|
||||
// Theme for SubClass
|
||||
m_OffsetX = 0;
|
||||
|
||||
// Voice for SubClass
|
||||
m_VoiceVolume = 0;
|
||||
}
|
||||
|
||||
CDialogFx::~CDialogFx()
|
||||
{
|
||||
if(m_hPal) DeleteObject(m_hPal);
|
||||
}
|
||||
|
||||
BEGIN_MESSAGE_MAP(CDialogFx, CDialog)
|
||||
ON_WM_SIZE()
|
||||
ON_WM_TIMER()
|
||||
ON_WM_ERASEBKGND()
|
||||
ON_MESSAGE(WM_DPICHANGED, &CDialogFx::OnDpiChanged)
|
||||
ON_MESSAGE(WM_DISPLAYCHANGE, &CDialogFx::OnDisplayChange)
|
||||
ON_MESSAGE(WM_SYSCOLORCHANGE, &CDialogFx::OnSysColorChange)
|
||||
ON_MESSAGE(WM_SETTINGCHANGE, &CDialogFx::OnSettingChange)
|
||||
ON_MESSAGE(WM_ENTERSIZEMOVE, &CDialogFx::OnEnterSizeMove)
|
||||
ON_MESSAGE(WM_EXITSIZEMOVE, &CDialogFx::OnExitSizeMove)
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
//------------------------------------------------
|
||||
// Dialog
|
||||
//------------------------------------------------
|
||||
|
||||
BOOL CDialogFx::Create(UINT nIDTemplate, CWnd* pDlgWnd, UINT menuId, CWnd* pParentWnd)
|
||||
{
|
||||
m_bModelessDlg = TRUE;
|
||||
m_ParentWnd = pParentWnd;
|
||||
m_DlgWnd = pDlgWnd;
|
||||
m_MenuId = menuId;
|
||||
|
||||
if (m_MenuId != 0 && m_ParentWnd != NULL)
|
||||
{
|
||||
CMenu* menu = m_ParentWnd->GetMenu();
|
||||
menu->EnableMenuItem(m_MenuId, MF_GRAYED);
|
||||
m_ParentWnd->SetMenu(menu);
|
||||
m_ParentWnd->DrawMenuBar();
|
||||
}
|
||||
|
||||
return CDialog::Create(nIDTemplate, pParentWnd);
|
||||
}
|
||||
|
||||
int CDialogFx::GetDpi()
|
||||
{
|
||||
INT dpi = 96;
|
||||
CDC* pDC = GetDC();
|
||||
dpi = GetDeviceCaps(pDC->m_hDC, LOGPIXELSY);
|
||||
ReleaseDC(pDC);
|
||||
|
||||
HMODULE hModule = GetModuleHandle(_T("Shcore.dll"));
|
||||
if (hModule)
|
||||
{
|
||||
typedef HRESULT(WINAPI* FuncGetDpiForMonitor) (HMONITOR hmonitor, UINT dpiType, UINT* dpiX, UINT* dpiY);
|
||||
typedef HMONITOR(WINAPI* FuncMonitorFromWindow) (HWND hwnd, DWORD dwFlags);
|
||||
|
||||
FuncGetDpiForMonitor pGetDpiForMonitor = (FuncGetDpiForMonitor)GetProcAddress(hModule, "GetDpiForMonitor");
|
||||
FuncMonitorFromWindow pMonitorFromWindow = (FuncMonitorFromWindow)GetProcAddress(hModule, "MonitorFromWindow");
|
||||
|
||||
if (pGetDpiForMonitor && pMonitorFromWindow)
|
||||
{
|
||||
UINT dpiX, dpiY;
|
||||
pGetDpiForMonitor(pMonitorFromWindow(m_hWnd, MONITOR_DEFAULTTONEAREST), 0, &dpiX, &dpiY);
|
||||
dpi = dpiY;
|
||||
}
|
||||
}
|
||||
|
||||
return dpi;
|
||||
}
|
||||
|
||||
BOOL CDialogFx::OnInitDialog()
|
||||
{
|
||||
CDialog::OnInitDialog();
|
||||
|
||||
m_bHighContrast = IsHighContrast();
|
||||
m_Dpi = GetDpi();
|
||||
m_hAccelerator = ::LoadAccelerators(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDR_ACCELERATOR));
|
||||
|
||||
// m_bInitializing = FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void CDialogFx::OnSize(UINT nType, int cx, int cy)
|
||||
{
|
||||
CDialog::OnSize(nType, cx, cy);
|
||||
|
||||
if (nType == SIZE_RESTORED)
|
||||
{
|
||||
UpdateBackground(TRUE, FALSE);
|
||||
Invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
BOOL CDialogFx::PreTranslateMessage(MSG* pMsg)
|
||||
{
|
||||
if(m_hAccelerator != NULL)
|
||||
{
|
||||
if(::TranslateAccelerator(m_hWnd, m_hAccelerator, pMsg) != 0)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return CDialog::PreTranslateMessage(pMsg);
|
||||
}
|
||||
|
||||
void CDialogFx::PostNcDestroy()
|
||||
{
|
||||
if (m_bModelessDlg)
|
||||
{
|
||||
m_DlgWnd = NULL;
|
||||
delete this;
|
||||
}
|
||||
else
|
||||
{
|
||||
CDialog::PostNcDestroy();
|
||||
}
|
||||
}
|
||||
|
||||
void CDialogFx::UpdateDialogSize()
|
||||
{
|
||||
#if _MSC_VER > 1310
|
||||
if (! m_bDisableDarkMode)
|
||||
{
|
||||
m_bDarkMode = SetDarkMode(m_hWnd);
|
||||
}
|
||||
else
|
||||
{
|
||||
UnsetDarkMode(m_hWnd);
|
||||
m_bDarkMode = FALSE;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void CDialogFx::SetClientSize(int sizeX, int sizeY, double zoomRatio)
|
||||
{
|
||||
RECT rw, rc;
|
||||
GetWindowRect(&rw);
|
||||
GetClientRect(&rc);
|
||||
|
||||
if (rc.right != 0)
|
||||
{
|
||||
int ncaWidth = (rw.right - rw.left) - (rc.right - rc.left);
|
||||
int ncaHeight = (rw.bottom - rw.top) - (rc.bottom - rc.top);
|
||||
|
||||
SetWindowPos(NULL, 0, 0, (int)(sizeX * zoomRatio) + ncaWidth, (int)(sizeY * zoomRatio) + ncaHeight, SWP_NOMOVE | SWP_NOZORDER);
|
||||
|
||||
GetWindowRect(&rw);
|
||||
GetClientRect(&rc);
|
||||
|
||||
int ncaHeightMenu = (rw.bottom - rw.top) - (rc.bottom - rc.top);
|
||||
|
||||
if (ncaHeight != ncaHeightMenu)
|
||||
{
|
||||
SetWindowPos(NULL, 0, 0, (int)(sizeX * zoomRatio) + ncaWidth, (int)(sizeY * zoomRatio) + ncaHeightMenu, SWP_NOMOVE | SWP_NOZORDER);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CDialogFx::UpdateBackground(BOOL resize, BOOL bDarkMode)
|
||||
{
|
||||
BOOL result = FALSE;
|
||||
CImage srcBitmap;
|
||||
double ratio = m_ZoomRatio;
|
||||
m_bBkImage = FALSE;
|
||||
|
||||
#if _MSC_VER > 1310
|
||||
if (resize) { m_ZoomRatio = 3.0; }
|
||||
result = srcBitmap.Load(IP(m_BackgroundName));
|
||||
if (resize) { m_ZoomRatio = ratio; }
|
||||
#else
|
||||
if (resize) { m_ZoomRatio = 1.0; }
|
||||
result = srcBitmap.Load(IP(m_BackgroundName));
|
||||
if (resize) { m_ZoomRatio = ratio; }
|
||||
#endif
|
||||
|
||||
HDC hScreenDC = ::GetDC(NULL); // get desktop DC
|
||||
if(!m_hPal && GetDeviceCaps(hScreenDC, RASTERCAPS) & RC_PALETTE)
|
||||
{
|
||||
m_hPal = CreateHalftonePalette(hScreenDC);
|
||||
}
|
||||
DeleteDC(hScreenDC); // delete it after use
|
||||
|
||||
if (result)
|
||||
{
|
||||
m_bBkImage = TRUE;
|
||||
CBitmap baseBitmap;
|
||||
CDC baseDC;
|
||||
CDC* pWndDC = GetDC();
|
||||
|
||||
#if _MSC_VER > 1310
|
||||
int w = (int)(m_ZoomRatio / 3.0 * srcBitmap.GetWidth());
|
||||
int h = (int)(m_ZoomRatio / 3.0 * srcBitmap.GetHeight());
|
||||
#else
|
||||
int w = (int)(m_ZoomRatio * srcBitmap.GetWidth());
|
||||
int h = (int)(m_ZoomRatio * srcBitmap.GetHeight());
|
||||
#endif
|
||||
int orgw = srcBitmap.GetWidth();
|
||||
int orgh = srcBitmap.GetHeight();
|
||||
if(m_hPal && pWndDC->GetDeviceCaps(RASTERCAPS) & RC_PALETTE)
|
||||
{
|
||||
SelectPalette( pWndDC->GetSafeHdc(), m_hPal, TRUE );
|
||||
pWndDC->RealizePalette();
|
||||
pWndDC->SetStretchBltMode(HALFTONE);
|
||||
}
|
||||
baseBitmap.CreateCompatibleBitmap(pWndDC, orgw, orgh);
|
||||
baseDC.CreateCompatibleDC(pWndDC);
|
||||
if(m_hPal && baseDC.GetDeviceCaps(RASTERCAPS) & RC_PALETTE)
|
||||
{
|
||||
SelectPalette( baseDC.GetSafeHdc(), m_hPal, FALSE );
|
||||
baseDC.RealizePalette();
|
||||
baseDC.SetStretchBltMode(HALFTONE);
|
||||
}
|
||||
|
||||
m_BkBitmap.DeleteObject();
|
||||
m_BkDC.DeleteDC();
|
||||
m_BkBitmap.CreateCompatibleBitmap(pWndDC, w, h);
|
||||
m_BkDC.CreateCompatibleDC(pWndDC);
|
||||
if(m_hPal && baseDC.GetDeviceCaps(RASTERCAPS) & RC_PALETTE)
|
||||
{
|
||||
SelectPalette( m_BkDC.GetSafeHdc(), m_hPal, FALSE );
|
||||
m_BkDC.RealizePalette();
|
||||
m_BkDC.SetStretchBltMode(HALFTONE);
|
||||
}
|
||||
|
||||
ReleaseDC(pWndDC);
|
||||
|
||||
baseDC.SelectObject(&baseBitmap);
|
||||
m_BkDC.SelectObject(&m_BkBitmap);
|
||||
|
||||
srcBitmap.BitBlt(baseDC.GetSafeHdc(), 0, 0, SRCCOPY);
|
||||
srcBitmap.Destroy();
|
||||
|
||||
m_BkDC.SetStretchBltMode(HALFTONE);
|
||||
SetBrushOrgEx(m_BkDC, 0, 0, NULL);
|
||||
m_BkDC.StretchBlt(0, 0, w, h, &baseDC, 0, 0, orgw, orgh, SRCCOPY);
|
||||
|
||||
baseBitmap.DeleteObject();
|
||||
baseDC.DeleteDC();
|
||||
|
||||
m_BrushDlg.DeleteObject();
|
||||
m_BrushDlg.CreatePatternBrush(&m_BkBitmap);
|
||||
|
||||
return;
|
||||
}
|
||||
else if (m_bHighContrast)
|
||||
{
|
||||
m_BrushDlg.DeleteObject();
|
||||
m_BrushDlg.CreateSolidBrush(RGB(0, 0, 0));
|
||||
}
|
||||
else
|
||||
{
|
||||
CBitmap baseBitmap;
|
||||
CDC baseDC;
|
||||
CDC* pWndDC = GetDC();
|
||||
|
||||
CRect rect;
|
||||
GetClientRect(&rect);
|
||||
int w = rect.Width();
|
||||
int h = rect.Height();
|
||||
|
||||
m_BkBitmap.DeleteObject();
|
||||
m_BkBitmap.CreateCompatibleBitmap(pWndDC, w, h);
|
||||
m_BkDC.DeleteDC();
|
||||
m_BkDC.CreateCompatibleDC(pWndDC);
|
||||
m_BkDC.SelectObject(&m_BkBitmap);
|
||||
|
||||
m_BrushDlg.DeleteObject();
|
||||
COLORREF bkColor;
|
||||
|
||||
if (m_Background != 0xFFFFFFFF)
|
||||
{
|
||||
bkColor = m_Background;
|
||||
}
|
||||
else if (bDarkMode)
|
||||
{
|
||||
bkColor = RGB(32, 32, 32);
|
||||
}
|
||||
else
|
||||
{
|
||||
bkColor = RGB(255, 255, 255);
|
||||
}
|
||||
m_BrushDlg.CreateSolidBrush(bkColor);
|
||||
|
||||
m_BkDC.FillRect(&rect, &m_BrushDlg);
|
||||
|
||||
ReleaseDC(pWndDC);
|
||||
}
|
||||
}
|
||||
|
||||
void CDialogFx::SetWindowTitle(CString title)
|
||||
{
|
||||
SetWindowText(_T(" ") + title + _T(" "));
|
||||
}
|
||||
|
||||
void CDialogFx::OnOK()
|
||||
{
|
||||
}
|
||||
|
||||
void CDialogFx::OnCancel()
|
||||
{
|
||||
if (m_bModelessDlg)
|
||||
{
|
||||
if (m_MenuId != 0 && m_ParentWnd != NULL)
|
||||
{
|
||||
CMenu* menu = m_ParentWnd->GetMenu();
|
||||
menu->EnableMenuItem(m_MenuId, MF_ENABLED);
|
||||
m_ParentWnd->SetMenu(menu);
|
||||
m_ParentWnd->DrawMenuBar();
|
||||
}
|
||||
CDialog::DestroyWindow();
|
||||
}
|
||||
else
|
||||
{
|
||||
CDialog::OnCancel();
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------
|
||||
// Font
|
||||
//------------------------------------------------
|
||||
|
||||
int CDialogFx::GetFontScale()
|
||||
{
|
||||
return m_FontScale;
|
||||
}
|
||||
|
||||
BYTE CDialogFx::GetFontRender()
|
||||
{
|
||||
return m_FontRender;
|
||||
}
|
||||
|
||||
double CDialogFx::GetFontRatio()
|
||||
{
|
||||
return m_FontRatio;
|
||||
}
|
||||
|
||||
CString CDialogFx::GetFontFace()
|
||||
{
|
||||
return m_FontFace;
|
||||
}
|
||||
|
||||
//------------------------------------------------
|
||||
// Zoom
|
||||
//------------------------------------------------
|
||||
|
||||
DWORD CDialogFx::ChangeZoomType(DWORD zoomType)
|
||||
{
|
||||
DWORD current = (DWORD)ceil(m_Dpi / 96.0 * 100);
|
||||
int width = GetSystemMetrics(SM_CXSCREEN);
|
||||
|
||||
if(zoomType == ZoomTypeAuto)
|
||||
{
|
||||
#if _MSC_VER > 1310
|
||||
if (current >= 300)
|
||||
{
|
||||
zoomType = ZoomType300;
|
||||
}
|
||||
else if (current >= 250)
|
||||
{
|
||||
zoomType = ZoomType250;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if(current >= 200)
|
||||
{
|
||||
zoomType = ZoomType200;
|
||||
}
|
||||
else if(current >= 150)
|
||||
{
|
||||
zoomType = ZoomType150;
|
||||
}
|
||||
else if(current >= 125)
|
||||
{
|
||||
zoomType = ZoomType125;
|
||||
}
|
||||
#ifdef CRYSTALMARK_RETRO
|
||||
#ifdef SUISHO_SHIZUKU_SUPPORT
|
||||
else if (width < 900) { zoomType = ZoomType050; }
|
||||
else if (width < 1200){ zoomType = ZoomType075; }
|
||||
#else
|
||||
// else if (width < 732) { zoomType = ZoomType050; }
|
||||
else if (width < 732) { zoomType = ZoomType064; }
|
||||
else if (width < 976) { zoomType = ZoomType075; }
|
||||
#endif
|
||||
#endif
|
||||
else
|
||||
{
|
||||
zoomType = ZoomType100;
|
||||
}
|
||||
}
|
||||
|
||||
m_ZoomRatio = zoomType / 100.0;
|
||||
|
||||
return zoomType;
|
||||
}
|
||||
|
||||
//------------------------------------------------
|
||||
// Theme
|
||||
//------------------------------------------------
|
||||
|
||||
BOOL CDialogFx::IsHighContrast()
|
||||
{
|
||||
HIGHCONTRAST hc = { sizeof(HIGHCONTRAST) };
|
||||
SystemParametersInfoW(SPI_GETHIGHCONTRAST, sizeof(HIGHCONTRAST), &hc, 0);
|
||||
|
||||
return hc.dwFlags & HCF_HIGHCONTRASTON;
|
||||
}
|
||||
|
||||
BOOL CDialogFx::IsDisableDarkMode()
|
||||
{
|
||||
return m_bDisableDarkMode;
|
||||
}
|
||||
|
||||
//------------------------------------------------
|
||||
// Utility
|
||||
//------------------------------------------------
|
||||
|
||||
CString CDialogFx::IP(CString imageName) /// ImagePath
|
||||
{
|
||||
CString imagePath;
|
||||
imagePath.Format(_T("%s%s\\%s-%03d.png"), (LPCTSTR)m_ThemeDir, (LPCTSTR)m_CurrentTheme, (LPCTSTR)imageName, (DWORD)(m_ZoomRatio * 100));
|
||||
if (IsFileExist(imagePath))
|
||||
{
|
||||
return imagePath;
|
||||
}
|
||||
imagePath.Format(_T("%s%s\\%s-%03d.png"), (LPCTSTR)m_ThemeDir, (LPCTSTR)m_ParentTheme1, (LPCTSTR)imageName, (DWORD)(m_ZoomRatio * 100));
|
||||
if (IsFileExist(imagePath))
|
||||
{
|
||||
return imagePath;
|
||||
}
|
||||
imagePath.Format(_T("%s%s\\%s-%03d.png"), (LPCTSTR)m_ThemeDir, (LPCTSTR)m_ParentTheme2, (LPCTSTR)imageName, (DWORD)(m_ZoomRatio * 100));
|
||||
if (IsFileExist(imagePath))
|
||||
{
|
||||
return imagePath;
|
||||
}
|
||||
imagePath.Format(_T("%s%s\\%s-%03d.png"), (LPCTSTR)m_ThemeDir, (LPCTSTR)m_DefaultTheme, (LPCTSTR)imageName, (DWORD)(m_ZoomRatio * 100));
|
||||
if (IsFileExist(imagePath))
|
||||
{
|
||||
return imagePath;
|
||||
}
|
||||
|
||||
return _T("");
|
||||
}
|
||||
|
||||
CString CDialogFx::i18n(CString section, CString key, BOOL inEnglish)
|
||||
{
|
||||
TCHAR str[256];
|
||||
CString cstr;
|
||||
|
||||
if(inEnglish)
|
||||
{
|
||||
GetPrivateProfileStringFx(section, key, _T(""), str, 256, m_DefaultLangPath);
|
||||
cstr = str;
|
||||
}
|
||||
else
|
||||
{
|
||||
GetPrivateProfileStringFx(section, key, _T(""), str, 256, m_CurrentLangPath);
|
||||
cstr = str;
|
||||
if(cstr.IsEmpty())
|
||||
{
|
||||
GetPrivateProfileStringFx(section, key, _T(""), str, 256, m_DefaultLangPath);
|
||||
cstr = str;
|
||||
}
|
||||
}
|
||||
|
||||
return cstr;
|
||||
}
|
||||
|
||||
void CDialogFx::OpenUrl(CString url)
|
||||
{
|
||||
INT_PTR result = 0;
|
||||
result = (INT_PTR)(ShellExecute(NULL, _T("open"), (LPCTSTR)url, NULL, NULL, SW_SHOWNORMAL));
|
||||
if(result <= 32)
|
||||
{
|
||||
CString args;
|
||||
args.Format(_T("url.dll,FileProtocolHandler %s"), (LPCTSTR)url);
|
||||
ShellExecute(NULL, _T("open"), _T("rundll32.exe"), args, NULL, SW_SHOWNORMAL);
|
||||
}
|
||||
}
|
||||
|
||||
void CDialogFx::SetLayeredWindow(HWND hWnd, BYTE alpha)
|
||||
{
|
||||
#if _MSC_VER > 1310
|
||||
if (IsWin2k()) { return; }
|
||||
|
||||
::SetWindowLong(hWnd, GWL_EXSTYLE, ::GetWindowLong(hWnd, GWL_EXSTYLE) ^ WS_EX_LAYERED);
|
||||
::SetWindowLong(hWnd, GWL_EXSTYLE, ::GetWindowLong(hWnd, GWL_EXSTYLE) | WS_EX_LAYERED);
|
||||
if (m_bHighContrast)
|
||||
{
|
||||
::SetLayeredWindowAttributes(hWnd, 0, 255, LWA_ALPHA);
|
||||
}
|
||||
else
|
||||
{
|
||||
::SetLayeredWindowAttributes(hWnd, 0, alpha, LWA_ALPHA);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
//------------------------------------------------
|
||||
// MessageMap
|
||||
//------------------------------------------------
|
||||
|
||||
void CDialogFx::OnTimer(UINT_PTR nIDEvent)
|
||||
{
|
||||
switch (nIDEvent)
|
||||
{
|
||||
case TimerUpdateDialogSizeDpiChanged:
|
||||
if (m_bDrag)
|
||||
{
|
||||
KillTimer(TimerUpdateDialogSizeDpiChanged);
|
||||
SetTimer(TimerUpdateDialogSizeDpiChanged, TIMER_UPDATE_DIALOG, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_bDpiChanging = FALSE;
|
||||
KillTimer(TimerUpdateDialogSizeDpiChanged);
|
||||
UpdateDialogSize();
|
||||
}
|
||||
break;
|
||||
case TimerUpdateDialogSizeDisplayChange:
|
||||
KillTimer(TimerUpdateDialogSizeDisplayChange);
|
||||
UpdateDialogSize();
|
||||
break;
|
||||
case TimerUpdateDialogSizeSysColorChange:
|
||||
KillTimer(TimerUpdateDialogSizeSysColorChange);
|
||||
UpdateDialogSize();
|
||||
break;
|
||||
case TimerUpdateDialogSizeSettingChange:
|
||||
KillTimer(TimerUpdateDialogSizeSettingChange);
|
||||
UpdateDialogSize();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
BOOL CDialogFx::OnEraseBkgnd(CDC* pDC)
|
||||
{
|
||||
if (m_bHighContrast)
|
||||
{
|
||||
return CDialog::OnEraseBkgnd(pDC);
|
||||
}
|
||||
|
||||
if(m_hPal && pDC->GetDeviceCaps(RASTERCAPS) & RC_PALETTE)
|
||||
{
|
||||
SelectPalette( pDC->GetSafeHdc(), m_hPal, TRUE );
|
||||
pDC->RealizePalette();
|
||||
pDC->SetStretchBltMode(HALFTONE);
|
||||
}
|
||||
|
||||
CRect rect;
|
||||
GetClientRect(&rect);
|
||||
|
||||
return pDC->StretchBlt(0, 0, rect.Width(), rect.Height(), &m_BkDC, 0, 0, rect.Width(), rect.Height(), SRCCOPY);
|
||||
}
|
||||
|
||||
afx_msg LRESULT CDialogFx::OnDpiChanged(WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
if (m_bInitializing) { return 0; }
|
||||
|
||||
static ULONGLONG preTime = 0;
|
||||
ULONGLONG currentTime = GetTickCountFx();
|
||||
if (currentTime - preTime < 1000)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
preTime = currentTime;
|
||||
}
|
||||
|
||||
m_Dpi = (INT)HIWORD(wParam);
|
||||
|
||||
#if _MSC_VER > 1310
|
||||
if (IsWindowsBuildOrGreater(16299)) // DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2
|
||||
{
|
||||
ChangeZoomType(m_ZoomType);
|
||||
m_bDpiChanging = TRUE;
|
||||
SetTimer(TimerUpdateDialogSizeDpiChanged, TIMER_UPDATE_DIALOG, NULL);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if(m_ZoomType == ZoomTypeAuto)
|
||||
{
|
||||
DWORD oldZoomRatio = (DWORD)(m_ZoomRatio * 100);
|
||||
if (ChangeZoomType(m_ZoomType) != oldZoomRatio)
|
||||
{
|
||||
m_bDpiChanging = TRUE;
|
||||
SetTimer(TimerUpdateDialogSizeDpiChanged, TIMER_UPDATE_DIALOG, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
afx_msg LRESULT CDialogFx::OnDisplayChange(WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
if (m_bInitializing) { return 0; }
|
||||
|
||||
CDC* cdc = GetDC();
|
||||
if (cdc)
|
||||
{
|
||||
int color = cdc->GetDeviceCaps(BITSPIXEL) * cdc->GetDeviceCaps(PLANES);
|
||||
if (color != wParam)
|
||||
{
|
||||
SetTimer(TimerUpdateDialogSizeDisplayChange, TIMER_UPDATE_DIALOG, NULL);
|
||||
}
|
||||
ReleaseDC(cdc);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
afx_msg LRESULT CDialogFx::OnSysColorChange(WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
if (m_bInitializing) { return 0; }
|
||||
|
||||
m_bHighContrast = IsHighContrast();
|
||||
|
||||
SetTimer(TimerUpdateDialogSizeSysColorChange, TIMER_UPDATE_DIALOG, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
afx_msg LRESULT CDialogFx::OnSettingChange(WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
if (m_bInitializing) { return 0; }
|
||||
|
||||
if (!lstrcmp(LPCTSTR(lParam), _T("ImmersiveColorSet")))
|
||||
{
|
||||
SetTimer(TimerUpdateDialogSizeSettingChange, TIMER_UPDATE_DIALOG, NULL);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
afx_msg LRESULT CDialogFx::OnEnterSizeMove(WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
m_bDrag = TRUE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
afx_msg LRESULT CDialogFx::OnExitSizeMove(WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
m_bDrag = FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
/*---------------------------------------------------------------------------*/
|
||||
// Author : hiyohiyo
|
||||
// Mail : hiyohiyo@crystalmark.info
|
||||
// Web : https://crystalmark.info/
|
||||
// License : MIT License
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ImageFx.h"
|
||||
|
||||
class CDialogFx : public CDialog
|
||||
{
|
||||
public:
|
||||
CDialogFx(UINT dlgResouce, CWnd* pParent = NULL);
|
||||
virtual ~CDialogFx();
|
||||
|
||||
// Dialog
|
||||
virtual BOOL Create(UINT nIDTemplate, CWnd* dlgWnd, UINT menuId, CWnd* pParentWnd = NULL);
|
||||
|
||||
// Font
|
||||
int GetFontScale();
|
||||
BYTE GetFontRender();
|
||||
double GetFontRatio();
|
||||
CString GetFontFace();
|
||||
|
||||
// Theme
|
||||
BOOL IsDisableDarkMode();
|
||||
|
||||
protected:
|
||||
// Dialog
|
||||
virtual BOOL OnInitDialog();
|
||||
virtual BOOL PreTranslateMessage(MSG* pMsg);
|
||||
virtual void PostNcDestroy();
|
||||
virtual void UpdateDialogSize();
|
||||
virtual void SetClientSize(int sizeX, int sizeY, double zoomRatio);
|
||||
virtual void UpdateBackground(BOOL resize, BOOL darkMode);
|
||||
virtual void SetWindowTitle(CString title);
|
||||
virtual void OnOK();
|
||||
virtual void OnCancel();
|
||||
|
||||
// Zoom
|
||||
DWORD ChangeZoomType(DWORD zoomType);
|
||||
|
||||
// Theme
|
||||
BOOL IsHighContrast();
|
||||
|
||||
// Utility
|
||||
virtual CString IP(CString imageName);
|
||||
CString i18n(CString section, CString key, BOOL inEnglish = FALSE);
|
||||
void OpenUrl(CString url);
|
||||
void SetLayeredWindow(HWND hWnd, BYTE alpha);
|
||||
int GetDpi();
|
||||
|
||||
// MessageMap
|
||||
DECLARE_MESSAGE_MAP()
|
||||
afx_msg void OnSize(UINT nType, int cx, int cy);
|
||||
afx_msg void OnTimer(UINT_PTR nIDEvent);
|
||||
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
|
||||
afx_msg LRESULT OnDpiChanged(WPARAM wParam, LPARAM lParam);
|
||||
afx_msg LRESULT OnDisplayChange(WPARAM wParam, LPARAM lParam);
|
||||
afx_msg LRESULT OnSysColorChange(WPARAM wParam, LPARAM lParam);
|
||||
afx_msg LRESULT OnSettingChange(WPARAM wParam, LPARAM lParam);
|
||||
afx_msg LRESULT OnEnterSizeMove(WPARAM wParam, LPARAM lParam);
|
||||
afx_msg LRESULT OnExitSizeMove(WPARAM wParam, LPARAM lParam);
|
||||
|
||||
protected:
|
||||
// Dialog
|
||||
BOOL m_bInitializing;
|
||||
BOOL m_bDpiChanging;
|
||||
BOOL m_bShowWindow;
|
||||
BOOL m_bModelessDlg;
|
||||
BOOL m_bHighContrast;
|
||||
BOOL m_bDarkMode;
|
||||
BOOL m_bDisableDarkMode;
|
||||
BOOL m_bBkImage;
|
||||
UINT m_MenuId;
|
||||
CWnd* m_ParentWnd;
|
||||
CWnd* m_DlgWnd;
|
||||
CString m_Ini;
|
||||
HACCEL m_hAccelerator;
|
||||
BOOL m_bDrag;
|
||||
CString m_FontFace;
|
||||
int m_FontScale;
|
||||
double m_FontRatio;
|
||||
BYTE m_FontRender;
|
||||
HPALETTE m_hPal;
|
||||
|
||||
int m_SizeX;
|
||||
int m_MaxSizeX;
|
||||
int m_MinSizeX;
|
||||
int m_SizeY;
|
||||
int m_MaxSizeY;
|
||||
int m_MinSizeY;
|
||||
|
||||
// Zoom
|
||||
int m_Dpi;
|
||||
DWORD m_ZoomType;
|
||||
double m_ZoomRatio;
|
||||
|
||||
// Color for SubClass
|
||||
COLORREF m_LabelText;
|
||||
COLORREF m_MeterText;
|
||||
COLORREF m_ComboText;
|
||||
COLORREF m_ComboTextSelected;
|
||||
COLORREF m_ComboBk;
|
||||
COLORREF m_ComboBkSelected;
|
||||
COLORREF m_ButtonText;
|
||||
COLORREF m_EditText;
|
||||
COLORREF m_EditBk;
|
||||
COLORREF m_ListText1;
|
||||
COLORREF m_ListText2;
|
||||
COLORREF m_ListTextSelected;
|
||||
COLORREF m_ListBk1;
|
||||
COLORREF m_ListBk2;
|
||||
COLORREF m_ListBkSelected;
|
||||
COLORREF m_ListLine1;
|
||||
COLORREF m_ListLine2;
|
||||
COLORREF m_Glass;
|
||||
COLORREF m_Frame;
|
||||
COLORREF m_Background;
|
||||
|
||||
BYTE m_ComboAlpha;
|
||||
BYTE m_EditAlpha;
|
||||
BYTE m_GlassAlpha;
|
||||
|
||||
BYTE m_CharacterPosition;
|
||||
|
||||
// Theme for SubClass
|
||||
int m_OffsetX;
|
||||
CString m_ThemeDir;
|
||||
CString m_CurrentTheme;
|
||||
CString m_DefaultTheme;
|
||||
CString m_ParentTheme1;
|
||||
CString m_ParentTheme2;
|
||||
CString m_RandomThemeLabel;
|
||||
CString m_RandomThemeName;
|
||||
|
||||
// Language for SubClass
|
||||
CString m_LangDir;
|
||||
CString m_CurrentLang;
|
||||
CString m_CurrentLangPath;
|
||||
CString m_DefaultLangPath;
|
||||
CString m_BackgroundName;
|
||||
|
||||
// Voice for SubClass
|
||||
CString m_VoiceDir;
|
||||
CString m_CurrentVoice;
|
||||
INT m_VoiceVolume;
|
||||
|
||||
// Class
|
||||
CBitmap m_BkBitmap;
|
||||
CDC m_BkDC;
|
||||
CImage m_BkImage;
|
||||
CBrush m_BrushDlg;
|
||||
};
|
||||
@@ -0,0 +1,629 @@
|
||||
/*---------------------------------------------------------------------------*/
|
||||
// Author : hiyohiyo
|
||||
// Mail : hiyohiyo@crystalmark.info
|
||||
// Web : https://crystalmark.info/
|
||||
// License : MIT License
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "EditFx.h"
|
||||
|
||||
////------------------------------------------------
|
||||
// CEditFx
|
||||
////------------------------------------------------
|
||||
|
||||
CEditFx::CEditFx()
|
||||
{
|
||||
// Control
|
||||
m_X = 0;
|
||||
m_Y = 0;
|
||||
m_bHighContrast = FALSE;
|
||||
m_bDarkMode = FALSE;
|
||||
m_bDrawFrame = FALSE;
|
||||
m_FrameColor = RGB(128, 128, 128);
|
||||
m_RenderMode = OwnerDrawImage;
|
||||
m_bMultiLine = FALSE;
|
||||
m_BkColor = RGB(255, 255, 255);
|
||||
|
||||
// Glass
|
||||
m_GlassColor = RGB(255, 255, 255);
|
||||
m_GlassAlpha = 128;
|
||||
|
||||
// Image
|
||||
m_ImageCount = 0;
|
||||
m_BkDC = NULL;
|
||||
m_bBkBitmapInit = FALSE;
|
||||
m_bBkLoad = FALSE;
|
||||
|
||||
// Font
|
||||
m_TextAlign = SS_LEFT;
|
||||
m_TextColor = RGB(0, 0, 0);
|
||||
|
||||
// Margin
|
||||
m_Margin.top = 0;
|
||||
m_Margin.left = 0;
|
||||
m_Margin.bottom = 0;
|
||||
m_Margin.right = 0;
|
||||
}
|
||||
|
||||
CEditFx::~CEditFx()
|
||||
{
|
||||
}
|
||||
|
||||
IMPLEMENT_DYNAMIC(CEditFx, CEdit)
|
||||
|
||||
BEGIN_MESSAGE_MAP(CEditFx, CEdit)
|
||||
//{{AFX_MSG_MAP(CEditFx)
|
||||
ON_WM_CTLCOLOR_REFLECT()
|
||||
ON_CONTROL_REFLECT(EN_CHANGE, OnEnChange)
|
||||
ON_WM_KEYDOWN()
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
//------------------------------------------------
|
||||
// Control
|
||||
//------------------------------------------------
|
||||
|
||||
BOOL CEditFx::InitControl(int x, int y, int width, int height, double zoomRatio, CDC* bkDC,
|
||||
LPCTSTR imagePath, int imageCount, DWORD textAlign, int renderMode, BOOL bHighContrast, BOOL bDarkMode, BOOL bDrawFrame, BOOL bMultiLine)
|
||||
{
|
||||
m_X = (int)(x * zoomRatio);
|
||||
m_Y = (int)(y * zoomRatio);
|
||||
m_CtrlSize.cx = (int)(width * zoomRatio);
|
||||
m_CtrlSize.cy = (int)(height * zoomRatio);
|
||||
MoveWindow(m_X, m_Y, m_CtrlSize.cx, m_CtrlSize.cy);
|
||||
m_bMultiLine = bMultiLine;
|
||||
|
||||
m_BkDC = bkDC;
|
||||
m_ImagePath = imagePath;
|
||||
m_ImageCount = imageCount;
|
||||
m_RenderMode = renderMode;
|
||||
|
||||
if (ES_LEFT <= textAlign && textAlign <= ES_RIGHT)
|
||||
{
|
||||
m_TextAlign = textAlign;
|
||||
ModifyStyle(0, m_TextAlign);
|
||||
}
|
||||
|
||||
if (m_ToolTip.m_hWnd != NULL)
|
||||
{
|
||||
if (m_ToolTip.GetToolCount() != 0)
|
||||
{
|
||||
m_ToolTip.DelTool(this, 1);
|
||||
}
|
||||
CRect rect;
|
||||
GetClientRect(rect);
|
||||
m_ToolTip.AddTool(this, m_ToolTipText, rect, 1);
|
||||
}
|
||||
|
||||
m_bHighContrast = bHighContrast;
|
||||
m_bDarkMode = bDarkMode;
|
||||
m_bDrawFrame = bDrawFrame;
|
||||
|
||||
if (m_bHighContrast)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
else if (renderMode & SystemDraw)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
SetBkReload();
|
||||
LoadCtrlBk(m_BkDC);
|
||||
}
|
||||
|
||||
if (renderMode & OwnerDrawImage)
|
||||
{
|
||||
if (!LoadBitmap(imagePath))
|
||||
{
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ImageCount = 1;
|
||||
m_CtrlImage.Destroy();
|
||||
m_CtrlImage.Create(m_CtrlSize.cx, m_CtrlSize.cy * m_ImageCount, 32);
|
||||
m_CtrlBitmap.Detach();
|
||||
m_CtrlBitmap.Attach((HBITMAP)m_CtrlImage);
|
||||
DWORD length = m_CtrlSize.cx * m_CtrlSize.cy * m_ImageCount * 4;
|
||||
BYTE* bitmapBits = new BYTE[length];
|
||||
m_CtrlBitmap.GetBitmapBits(length, bitmapBits);
|
||||
|
||||
BYTE r, g, b, a;
|
||||
if (renderMode & OwnerDrawGlass)
|
||||
{
|
||||
r = (BYTE)GetRValue(m_GlassColor);
|
||||
g = (BYTE)GetGValue(m_GlassColor);
|
||||
b = (BYTE)GetBValue(m_GlassColor);
|
||||
a = m_GlassAlpha;
|
||||
}
|
||||
else // OwnerDrawTransparent
|
||||
{
|
||||
r = 0;
|
||||
g = 0;
|
||||
b = 0;
|
||||
a = 0;
|
||||
}
|
||||
|
||||
for (int y = 0; y < (int)(m_CtrlSize.cy * m_ImageCount); y++)
|
||||
{
|
||||
for (int x = 0; x < m_CtrlSize.cx; x++)
|
||||
{
|
||||
DWORD p = (y * m_CtrlSize.cx + x) * 4;
|
||||
#if _MSC_VER > 1310
|
||||
#pragma warning( disable : 6386 )
|
||||
#endif
|
||||
bitmapBits[p + 0] = b;
|
||||
bitmapBits[p + 1] = g;
|
||||
bitmapBits[p + 2] = r;
|
||||
bitmapBits[p + 3] = a;
|
||||
#if _MSC_VER > 1310
|
||||
#pragma warning( default : 6386 )
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
m_CtrlBitmap.SetBitmapBits(length, bitmapBits);
|
||||
delete[] bitmapBits;
|
||||
}
|
||||
|
||||
SetupControlImage(m_BkBitmap, m_CtrlBitmap);
|
||||
|
||||
m_BkBrush.DeleteObject();
|
||||
m_BkBrush.CreatePatternBrush(&m_CtrlBitmap);
|
||||
|
||||
Invalidate();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void CEditFx::SetMargin(int top, int left, int bottom, int right, double zoomRatio)
|
||||
{
|
||||
m_Margin.top = (int)(top * zoomRatio);
|
||||
m_Margin.left = (int)(left * zoomRatio);
|
||||
m_Margin.bottom = (int)(bottom * zoomRatio);
|
||||
m_Margin.right = (int)(right * zoomRatio);
|
||||
|
||||
if (GetWindowLongPtr(m_hWnd, GWL_STYLE) & ES_MULTILINE)
|
||||
{
|
||||
CRect rectGet, rectSet;
|
||||
GetRect(rectGet);
|
||||
|
||||
rectSet.top = m_Margin.top;
|
||||
rectSet.bottom = rectGet.bottom - m_Margin.bottom - m_Margin.top;
|
||||
rectSet.left = m_Margin.left;
|
||||
rectSet.right = rectGet.right - m_Margin.right - m_Margin.left;
|
||||
|
||||
SetRect(rectSet);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetMargins(m_Margin.left, m_Margin.right);
|
||||
}
|
||||
}
|
||||
|
||||
CSize CEditFx::GetSize(void)
|
||||
{
|
||||
return m_CtrlSize;
|
||||
}
|
||||
|
||||
void CEditFx::SetDrawFrame(BOOL bDrawFrame)
|
||||
{
|
||||
#if _MSC_VER > 1310
|
||||
if (bDrawFrame)
|
||||
{
|
||||
ModifyStyleEx(0, WS_EX_STATICEDGE, SWP_DRAWFRAME);
|
||||
}
|
||||
else
|
||||
{
|
||||
ModifyStyleEx(WS_EX_STATICEDGE, 0, SWP_DRAWFRAME);
|
||||
}
|
||||
#else
|
||||
if (bDrawFrame)
|
||||
{
|
||||
if (IsNT3())
|
||||
{
|
||||
ModifyStyle(0, WS_BORDER, SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_FRAMECHANGED);
|
||||
}
|
||||
else
|
||||
{
|
||||
ModifyStyleEx(0, WS_EX_STATICEDGE, SWP_DRAWFRAME);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (IsNT3())
|
||||
{
|
||||
ModifyStyle(WS_BORDER, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_FRAMECHANGED);
|
||||
}
|
||||
else
|
||||
{
|
||||
ModifyStyleEx(WS_EX_STATICEDGE, 0, SWP_DRAWFRAME);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
m_bDrawFrame = bDrawFrame;
|
||||
}
|
||||
|
||||
void CEditFx::SetGlassColor(COLORREF glassColor, BYTE glassAlpha)
|
||||
{
|
||||
m_GlassColor = glassColor;
|
||||
m_GlassAlpha = glassAlpha;
|
||||
}
|
||||
|
||||
void CEditFx::SetBkColor(COLORREF bkColor)
|
||||
{
|
||||
m_BkColor = bkColor;
|
||||
}
|
||||
|
||||
void CEditFx::Adjust()
|
||||
{
|
||||
CRect rectGet, rectSet;
|
||||
GetRect(rectGet);
|
||||
|
||||
CClientDC dc(this);
|
||||
HGDIOBJ oldFont = dc.SelectObject(&m_Font);
|
||||
#ifdef UNICODE
|
||||
CSize size = dc.GetTextExtent(L"ÁAaPpQqYy8!");
|
||||
#else
|
||||
CSize size = dc.GetTextExtent("AaPpQqYy8!");
|
||||
#endif
|
||||
|
||||
dc.SelectObject(oldFont);
|
||||
|
||||
rectSet.top = (m_CtrlSize.cy - size.cy) / 2;
|
||||
rectSet.bottom = rectSet.top + size.cy;
|
||||
rectSet.left = rectGet.left;
|
||||
rectSet.right = rectGet.right;
|
||||
|
||||
SetRect(rectSet);
|
||||
}
|
||||
|
||||
HBRUSH CEditFx::CtlColor(CDC* pDC, UINT nCtlColor)
|
||||
{
|
||||
if (m_bHighContrast)
|
||||
{
|
||||
pDC->SetBkMode(TRANSPARENT);
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef UNICODE
|
||||
pDC->SetTextColor(m_TextColor);
|
||||
pDC->SetBkMode(TRANSPARENT);
|
||||
return m_BkBrush;
|
||||
#else
|
||||
pDC->SetTextColor(m_TextColor);
|
||||
pDC->SetBkColor(m_BkColor);
|
||||
pDC->SetBkMode(OPAQUE);
|
||||
|
||||
return CreateSolidBrush(m_BkColor);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------
|
||||
// Image
|
||||
//------------------------------------------------
|
||||
|
||||
BOOL CEditFx::LoadBitmap(LPCTSTR fileName)
|
||||
{
|
||||
if (m_bHighContrast) { return FALSE; }
|
||||
if (fileName == NULL) { return FALSE; }
|
||||
|
||||
m_CtrlImage.Destroy();
|
||||
m_CtrlImage.Load(fileName);
|
||||
if (m_CtrlImage.IsNull()) { return FALSE; }
|
||||
|
||||
return LoadBitmap((HBITMAP)m_CtrlImage);
|
||||
}
|
||||
|
||||
BOOL CEditFx::LoadBitmap(HBITMAP hBitmap)
|
||||
{
|
||||
if (m_bHighContrast) { return FALSE; }
|
||||
|
||||
m_CtrlBitmap.Detach();
|
||||
m_CtrlBitmap.Attach(hBitmap);
|
||||
|
||||
return SetBitmap(m_CtrlBitmap);
|
||||
}
|
||||
|
||||
void CEditFx::SetBkReload(void)
|
||||
{
|
||||
m_bBkBitmapInit = FALSE;
|
||||
m_bBkLoad = FALSE;
|
||||
}
|
||||
|
||||
BOOL CEditFx::SetBitmap(CBitmap& bitmap)
|
||||
{
|
||||
if (m_bHighContrast) { return FALSE; }
|
||||
|
||||
BITMAP bitmapInfo;
|
||||
bitmap.GetBitmap(&bitmapInfo);
|
||||
|
||||
if (m_CtrlSize.cx != bitmapInfo.bmWidth
|
||||
|| m_CtrlSize.cy != bitmapInfo.bmHeight / m_ImageCount)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
void CEditFx::LoadCtrlBk(CDC* drawDC)
|
||||
{
|
||||
if (m_bHighContrast) { SetBkReload(); return; }
|
||||
|
||||
if (m_BkBitmap.m_hObject != NULL)
|
||||
{
|
||||
BITMAP bitmapInfo;
|
||||
m_BkBitmap.GetBitmap(&bitmapInfo);
|
||||
if (bitmapInfo.bmBitsPixel != drawDC->GetDeviceCaps(BITSPIXEL))
|
||||
{
|
||||
SetBkReload();
|
||||
}
|
||||
}
|
||||
|
||||
if (&m_CtrlBitmap != NULL)
|
||||
{
|
||||
if (!m_bBkBitmapInit)
|
||||
{
|
||||
m_BkBitmap.DeleteObject();
|
||||
m_BkBitmap.CreateCompatibleBitmap(drawDC, m_CtrlSize.cx, m_CtrlSize.cy);
|
||||
m_bBkBitmapInit = TRUE;
|
||||
}
|
||||
|
||||
if (!m_bBkLoad)
|
||||
{
|
||||
CBitmap* pOldBitmap;
|
||||
CDC* pMemDC = new CDC;
|
||||
pMemDC->CreateCompatibleDC(drawDC);
|
||||
pOldBitmap = pMemDC->SelectObject(&m_BkBitmap);
|
||||
pMemDC->BitBlt(0, 0, m_CtrlSize.cx, m_CtrlSize.cy, m_BkDC, m_X, m_Y, SRCCOPY);
|
||||
pMemDC->SelectObject(pOldBitmap);
|
||||
pMemDC->DeleteDC();
|
||||
delete pMemDC;
|
||||
m_bBkLoad = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CEditFx::SetupControlImage(CBitmap& bkBitmap, CBitmap& ctrlBitmap)
|
||||
{
|
||||
int color = m_BkDC->GetDeviceCaps(BITSPIXEL) * m_BkDC->GetDeviceCaps(PLANES);
|
||||
|
||||
if (!m_CtrlImage.IsNull())
|
||||
{
|
||||
if (m_CtrlImage.GetBPP() == 32)
|
||||
{
|
||||
CBitmap* bk32Bitmap;
|
||||
CImage bk32Image;
|
||||
if (color == 32)
|
||||
{
|
||||
bk32Bitmap = &bkBitmap;
|
||||
}
|
||||
else
|
||||
{
|
||||
bk32Image.Create(m_CtrlSize.cx, m_CtrlSize.cy, 32);
|
||||
::BitBlt(bk32Image.GetDC(), 0, 0, m_CtrlSize.cx, m_CtrlSize.cy, *m_BkDC, m_X, m_Y, SRCCOPY);
|
||||
bk32Bitmap = CBitmap::FromHandle((HBITMAP)bk32Image);
|
||||
bk32Image.ReleaseDC();
|
||||
}
|
||||
|
||||
BITMAP CtlBmpInfo, DstBmpInfo;
|
||||
bk32Bitmap->GetBitmap(&DstBmpInfo);
|
||||
DWORD DstLineBytes = DstBmpInfo.bmWidthBytes;
|
||||
DWORD DstMemSize = DstLineBytes * DstBmpInfo.bmHeight;
|
||||
ctrlBitmap.GetBitmap(&CtlBmpInfo);
|
||||
DWORD CtlLineBytes = CtlBmpInfo.bmWidthBytes;
|
||||
DWORD CtlMemSize = CtlLineBytes * CtlBmpInfo.bmHeight;
|
||||
|
||||
if ((DstBmpInfo.bmWidthBytes != CtlBmpInfo.bmWidthBytes)
|
||||
|| (DstBmpInfo.bmHeight != CtlBmpInfo.bmHeight / m_ImageCount))
|
||||
{
|
||||
// Error Check //
|
||||
}
|
||||
else
|
||||
{
|
||||
BYTE* DstBuffer = new BYTE[DstMemSize];
|
||||
bk32Bitmap->GetBitmapBits(DstMemSize, DstBuffer);
|
||||
BYTE* CtlBuffer = new BYTE[CtlMemSize];
|
||||
ctrlBitmap.GetBitmapBits(CtlMemSize, CtlBuffer);
|
||||
|
||||
int baseY = 0;
|
||||
for (LONG py = 0; py < DstBmpInfo.bmHeight; py++)
|
||||
{
|
||||
int dn = py * DstLineBytes;
|
||||
int cn = (baseY + py) * CtlLineBytes;
|
||||
for (LONG px = 0; px < DstBmpInfo.bmWidth; px++)
|
||||
{
|
||||
#if _MSC_VER > 1310
|
||||
#pragma warning( disable : 6385 )
|
||||
#pragma warning( disable : 6386 )
|
||||
#endif
|
||||
BYTE a = CtlBuffer[cn + 3];
|
||||
BYTE na = 255 - a;
|
||||
CtlBuffer[dn + 0] = (BYTE)((CtlBuffer[cn + 0] * a + DstBuffer[dn + 0] * na) / 255);
|
||||
CtlBuffer[dn + 1] = (BYTE)((CtlBuffer[cn + 1] * a + DstBuffer[dn + 1] * na) / 255);
|
||||
CtlBuffer[dn + 2] = (BYTE)((CtlBuffer[cn + 2] * a + DstBuffer[dn + 2] * na) / 255);
|
||||
dn += (DstBmpInfo.bmBitsPixel / 8);
|
||||
cn += (CtlBmpInfo.bmBitsPixel / 8);
|
||||
#if _MSC_VER > 1310
|
||||
#pragma warning( default : 6386 )
|
||||
#pragma warning( default : 6385 )
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (color == 32)
|
||||
{
|
||||
ctrlBitmap.SetBitmapBits(CtlMemSize, CtlBuffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
bk32Bitmap->SetBitmapBits(CtlMemSize, CtlBuffer);
|
||||
m_CtrlImage.Detach();
|
||||
m_CtrlImage.Attach(ctrlBitmap);
|
||||
::BitBlt(m_CtrlImage.GetDC(), 0, 0, m_CtrlSize.cx, m_CtrlSize.cy, bk32Image.GetDC(), 0, 0, SRCCOPY);
|
||||
m_CtrlImage.ReleaseDC();
|
||||
bk32Image.ReleaseDC();
|
||||
|
||||
ctrlBitmap.SetBitmapBits(CtlMemSize, CtlBuffer);
|
||||
}
|
||||
|
||||
if (m_bDrawFrame)
|
||||
{
|
||||
HGDIOBJ oldPen;
|
||||
POINT point;
|
||||
CPen pen1; pen1.CreatePen(PS_SOLID, 1, RGB(0xF8, 0xF8, 0xF8));
|
||||
CPen pen2; pen2.CreatePen(PS_SOLID, 1, RGB(0x98, 0x98, 0x98));
|
||||
|
||||
HDC hDC = m_CtrlImage.GetDC();
|
||||
|
||||
oldPen = SelectObject(hDC, pen1);
|
||||
MoveToEx(hDC, 0, m_CtrlSize.cy - 1, &point);
|
||||
LineTo(hDC, m_CtrlSize.cx - 1, m_CtrlSize.cy - 1);
|
||||
LineTo(hDC, m_CtrlSize.cx - 1, 0);
|
||||
LineTo(hDC, m_CtrlSize.cx - 1, m_CtrlSize.cy - 1);
|
||||
SelectObject(hDC, pen2);
|
||||
MoveToEx(hDC, 0, m_CtrlSize.cy - 2, &point);
|
||||
LineTo(hDC, 0, 0);
|
||||
LineTo(hDC, m_CtrlSize.cx - 1, 0);
|
||||
SelectObject(hDC, oldPen);
|
||||
|
||||
pen1.DeleteObject();
|
||||
pen2.DeleteObject();
|
||||
m_CtrlImage.ReleaseDC();
|
||||
}
|
||||
|
||||
delete[] DstBuffer;
|
||||
delete[] CtlBuffer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------
|
||||
// Font
|
||||
//------------------------------------------------
|
||||
|
||||
void CEditFx::SetFontEx(CString face, int size, int sizeToolTip, double zoomRatio, double fontRatio,
|
||||
COLORREF textColor, LONG fontWeight, BYTE fontRender)
|
||||
{
|
||||
LOGFONT logFont = { 0 };
|
||||
logFont.lfCharSet = DEFAULT_CHARSET;
|
||||
logFont.lfHeight = (LONG)(-1 * size * zoomRatio * fontRatio);
|
||||
logFont.lfQuality = fontRender;
|
||||
logFont.lfWeight = fontWeight;
|
||||
if (face.GetLength() < 32)
|
||||
{
|
||||
wsprintf(logFont.lfFaceName, _T("%s"), (LPCTSTR)face);
|
||||
}
|
||||
else
|
||||
{
|
||||
wsprintf(logFont.lfFaceName, _T(""));
|
||||
}
|
||||
|
||||
m_Font.DeleteObject();
|
||||
m_Font.CreateFontIndirect(&logFont);
|
||||
SetFont(&m_Font);
|
||||
|
||||
logFont.lfHeight = (LONG)(-1 * sizeToolTip * zoomRatio);
|
||||
m_FontToolTip.DeleteObject();
|
||||
m_FontToolTip.CreateFontIndirect(&logFont);
|
||||
|
||||
m_TextColor = textColor;
|
||||
|
||||
if (m_ToolTip.m_hWnd != NULL)
|
||||
{
|
||||
m_ToolTip.SetFont(&m_FontToolTip);
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------
|
||||
// Message Map
|
||||
//------------------------------------------------
|
||||
|
||||
void CEditFx::OnEnChange()
|
||||
{
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
void CEditFx::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
|
||||
{
|
||||
if (nChar == VK_RETURN && m_bMultiLine == FALSE)
|
||||
{
|
||||
return ;
|
||||
}
|
||||
else
|
||||
{
|
||||
CEdit::OnKeyDown(nChar, nRepCnt, nFlags);
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------
|
||||
// ToolTip
|
||||
//------------------------------------------------
|
||||
|
||||
void CEditFx::SetToolTipText(LPCTSTR text)
|
||||
{
|
||||
if (text == NULL) { return; }
|
||||
|
||||
InitToolTip();
|
||||
m_ToolTipText = text;
|
||||
if (m_ToolTip.GetToolCount() == 0)
|
||||
{
|
||||
CRect rect;
|
||||
GetClientRect(rect);
|
||||
m_ToolTip.AddTool(this, m_ToolTipText, rect, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ToolTip.UpdateTipText(m_ToolTipText, this, 1);
|
||||
}
|
||||
|
||||
SetToolTipActivate(TRUE);
|
||||
}
|
||||
|
||||
void CEditFx::SetToolTipActivate(BOOL bActivate)
|
||||
{
|
||||
if (m_ToolTip.GetToolCount() == 0) { return; }
|
||||
m_ToolTip.Activate(bActivate);
|
||||
}
|
||||
|
||||
void CEditFx::SetToolTipWindowText(LPCTSTR text)
|
||||
{
|
||||
SetToolTipText(text);
|
||||
SetWindowText(text);
|
||||
}
|
||||
|
||||
CString CEditFx::GetToolTipText()
|
||||
{
|
||||
return m_ToolTipText;
|
||||
}
|
||||
|
||||
void CEditFx::InitToolTip()
|
||||
{
|
||||
if (m_ToolTip.m_hWnd == NULL)
|
||||
{
|
||||
m_ToolTip.Create(this, TTS_ALWAYSTIP | TTS_BALLOON | TTS_NOANIMATE | TTS_NOFADE);
|
||||
m_ToolTip.Activate(FALSE);
|
||||
m_ToolTip.SetFont(&m_FontToolTip);
|
||||
m_ToolTip.SendMessage(TTM_SETMAXTIPWIDTH, 0, 1024);
|
||||
m_ToolTip.SetDelayTime(TTDT_AUTOPOP, 8000);
|
||||
m_ToolTip.SetDelayTime(TTDT_INITIAL, 500);
|
||||
m_ToolTip.SetDelayTime(TTDT_RESHOW, 100);
|
||||
}
|
||||
}
|
||||
|
||||
BOOL CEditFx::PreTranslateMessage(MSG* pMsg)
|
||||
{
|
||||
InitToolTip();
|
||||
m_ToolTip.RelayEvent(pMsg);
|
||||
|
||||
return CEdit::PreTranslateMessage(pMsg);
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
/*---------------------------------------------------------------------------*/
|
||||
// Author : hiyohiyo
|
||||
// Mail : hiyohiyo@crystalmark.info
|
||||
// Web : https://crystalmark.info/
|
||||
// License : MIT License
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ImageFx.h"
|
||||
|
||||
class CEditFx : public CEdit
|
||||
{
|
||||
DECLARE_DYNAMIC(CEditFx);
|
||||
|
||||
public:
|
||||
// Constructors
|
||||
CEditFx();
|
||||
virtual ~CEditFx();
|
||||
|
||||
// Control
|
||||
BOOL InitControl(int x, int y, int width, int height, double zoomRatio, CDC* bkDC, LPCTSTR imagePath,
|
||||
int imageCount, DWORD textAlign, int renderMode, BOOL bHighContrast, BOOL bDarkMode, BOOL bDrawFrame, BOOL bMultiLine = FALSE);
|
||||
void SetMargin(int top, int left, int bottom, int right, double zoomRatio);
|
||||
CSize GetSize(void);
|
||||
void SetDrawFrame(BOOL bDrawFrame);
|
||||
void SetGlassColor(COLORREF glassColor, BYTE glassAlpha);
|
||||
void SetBkColor(COLORREF bkColor);
|
||||
void Adjust();
|
||||
|
||||
// Font
|
||||
void SetFontEx(CString face, int size, int sizeToolTip, double zoomRatio, double fontRatio = 1.0,
|
||||
COLORREF textColor = RGB(0, 0, 0), LONG fontWeight = FW_NORMAL, BYTE fontRender = CLEARTYPE_NATURAL_QUALITY);
|
||||
|
||||
// ToolTip
|
||||
void SetToolTipText(LPCTSTR text);
|
||||
void SetToolTipActivate(BOOL bActivate = TRUE);
|
||||
void SetToolTipWindowText(LPCTSTR text);
|
||||
CString GetToolTipText();
|
||||
|
||||
protected:
|
||||
// Image
|
||||
BOOL LoadBitmap(LPCTSTR fileName);
|
||||
BOOL LoadBitmap(HBITMAP hBitmap);
|
||||
void SetBkReload(void);
|
||||
BOOL SetBitmap(CBitmap& bitmap);
|
||||
void LoadCtrlBk(CDC* drawDC);
|
||||
void SetupControlImage(CBitmap& bkBitmap, CBitmap& ctrlBitmap);
|
||||
|
||||
// ToolTip
|
||||
void InitToolTip();
|
||||
virtual BOOL PreTranslateMessage(MSG* pMsg);
|
||||
|
||||
// MessageMap
|
||||
DECLARE_MESSAGE_MAP()
|
||||
afx_msg HBRUSH CtlColor(CDC* pDC, UINT nCtlColor);
|
||||
afx_msg void OnEnChange();
|
||||
afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
|
||||
|
||||
protected:
|
||||
// Control
|
||||
int m_X;
|
||||
int m_Y;
|
||||
CSize m_CtrlSize;
|
||||
CRect m_Margin;
|
||||
int m_RenderMode;
|
||||
BOOL m_bHighContrast;
|
||||
BOOL m_bDarkMode;
|
||||
BOOL m_bDrawFrame;
|
||||
COLORREF m_FrameColor;
|
||||
BOOL m_bMultiLine;
|
||||
COLORREF m_BkColor;
|
||||
|
||||
// Glass
|
||||
COLORREF m_GlassColor;
|
||||
BYTE m_GlassAlpha;
|
||||
|
||||
// Image
|
||||
CString m_ImagePath;
|
||||
int m_ImageCount;
|
||||
CDC* m_BkDC;
|
||||
CBitmap m_BkBitmap;
|
||||
CBrush m_BkBrush;
|
||||
BOOL m_bBkBitmapInit;
|
||||
BOOL m_bBkLoad;
|
||||
CBitmap m_CtrlBitmap;
|
||||
CImage m_CtrlImage;
|
||||
|
||||
// Font
|
||||
DWORD m_TextAlign;
|
||||
CFont m_Font;
|
||||
CFont m_FontToolTip;
|
||||
COLORREF m_TextColor;
|
||||
|
||||
// ToolTip
|
||||
CToolTipCtrl m_ToolTip;
|
||||
CString m_ToolTipText;
|
||||
};
|
||||
@@ -0,0 +1,134 @@
|
||||
/*---------------------------------------------------------------------------*/
|
||||
// Author : hiyohiyo
|
||||
// Mail : hiyohiyo@crystalmark.info
|
||||
// Web : https://crystalmark.info/
|
||||
// License : MIT License
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "FontComboBoxFx.h"
|
||||
|
||||
////------------------------------------------------
|
||||
// CFontComboBox
|
||||
////------------------------------------------------
|
||||
|
||||
IMPLEMENT_DYNAMIC(CFontComboBox, CComboBoxFx)
|
||||
|
||||
CFontComboBox::CFontComboBox()
|
||||
{
|
||||
m_Brush = NULL;
|
||||
}
|
||||
|
||||
CFontComboBox::~CFontComboBox()
|
||||
{
|
||||
m_BkBrush.DeleteObject();
|
||||
}
|
||||
|
||||
BEGIN_MESSAGE_MAP(CFontComboBox, CComboBoxFx)
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
void CFontComboBox::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
|
||||
{
|
||||
if (lpDrawItemStruct->itemID == -1) { return; }
|
||||
|
||||
static COLORREF textColor;
|
||||
static COLORREF textColorSelected;
|
||||
static COLORREF bkColor;
|
||||
static COLORREF bkColorSelected;
|
||||
|
||||
if (m_bHighContrast)
|
||||
{
|
||||
textColor = GetTextColor(lpDrawItemStruct->hDC);
|
||||
textColorSelected = RGB(0, 0, 0);
|
||||
bkColor = GetBkColor(lpDrawItemStruct->hDC);
|
||||
bkColorSelected = RGB(0, 255, 255);
|
||||
|
||||
if (bkColor <= RGB(0x80, 0x80, 0x80)) { textColor = RGB(255, 255, 255); }
|
||||
else { textColor = RGB(0, 0, 0); }
|
||||
}
|
||||
else if (m_bDarkMode)
|
||||
{
|
||||
textColor = RGB(255, 255, 255);
|
||||
textColorSelected = RGB(255, 255, 255);
|
||||
bkColor = RGB(32, 32, 32);
|
||||
bkColorSelected = RGB(77, 77, 77);
|
||||
}
|
||||
else
|
||||
{
|
||||
textColor = m_TextColor;
|
||||
textColorSelected = m_TextColorSelected;
|
||||
bkColor = m_BkColor;
|
||||
bkColorSelected = m_BkColorSelected;
|
||||
}
|
||||
|
||||
CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
|
||||
LoadCtrlBk(pDC);
|
||||
CString title;
|
||||
GetLBText(lpDrawItemStruct->itemID, title);
|
||||
|
||||
CFont font;
|
||||
LOGFONT logfont;
|
||||
memset(&logfont, 0, sizeof(logfont));
|
||||
logfont.lfHeight = m_FontHeight;
|
||||
logfont.lfWidth = 0;
|
||||
logfont.lfWeight = FW_NORMAL;
|
||||
logfont.lfQuality = m_FontRender;
|
||||
logfont.lfCharSet = DEFAULT_CHARSET;
|
||||
|
||||
#if _MSC_VER <= 1310
|
||||
_tcscpy(logfont.lfFaceName, (LPCTSTR)title);
|
||||
#else
|
||||
_tcscpy_s(logfont.lfFaceName, 32, (LPCTSTR)title);
|
||||
#endif
|
||||
font.CreateFontIndirect(&logfont);
|
||||
HGDIOBJ oldFont = pDC->SelectObject(&font);
|
||||
|
||||
CBrush Brush;
|
||||
CBrush* pOldBrush;
|
||||
if (lpDrawItemStruct->rcItem.left != 0 && !m_bHighContrast)
|
||||
{
|
||||
DrawControl(title, pDC, lpDrawItemStruct, m_CtrlBitmap, m_BkBitmap, ControlImageNormal);
|
||||
Brush.CreateSolidBrush(bkColorSelected);
|
||||
pOldBrush = pDC->SelectObject(&Brush);
|
||||
if (lpDrawItemStruct->itemState & ODS_SELECTED)
|
||||
{
|
||||
RECT rc = lpDrawItemStruct->rcItem;
|
||||
// rc.top = (LONG)(rc.bottom - 2 * m_ZoomRatio);
|
||||
rc.right = (LONG)(rc.left + 3 * m_ZoomRatio);
|
||||
FillRect(lpDrawItemStruct->hDC, &rc, (HBRUSH)Brush);
|
||||
}
|
||||
DrawString(title, pDC, lpDrawItemStruct, textColor);
|
||||
|
||||
#if _MSC_VER <= 1310
|
||||
if (IsNT3() && IsWindowEnabled())
|
||||
{
|
||||
DWORD oldTextAlign = m_TextAlign;
|
||||
HGDIOBJ myoldFont = pDC->SelectStockObject(SYSTEM_FONT);
|
||||
m_TextAlign = ES_RIGHT;
|
||||
DrawString(_T("v"), pDC, lpDrawItemStruct, textColor);
|
||||
m_TextAlign = oldTextAlign;
|
||||
pDC->SelectObject(myoldFont);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
if (lpDrawItemStruct->itemState & ODS_SELECTED)
|
||||
{
|
||||
Brush.CreateSolidBrush(bkColorSelected);
|
||||
pOldBrush = pDC->SelectObject(&Brush);
|
||||
FillRect(lpDrawItemStruct->hDC, &lpDrawItemStruct->rcItem, (HBRUSH)Brush);
|
||||
DrawString(title, pDC, lpDrawItemStruct, textColorSelected);
|
||||
}
|
||||
else
|
||||
{
|
||||
Brush.CreateSolidBrush(bkColor);
|
||||
pOldBrush = pDC->SelectObject(&Brush);
|
||||
FillRect(lpDrawItemStruct->hDC, &lpDrawItemStruct->rcItem, (HBRUSH)Brush);
|
||||
DrawString(title, pDC, lpDrawItemStruct, textColor);
|
||||
}
|
||||
}
|
||||
pDC->SelectObject(pOldBrush);
|
||||
Brush.DeleteObject();
|
||||
pDC->SelectObject(oldFont);
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*---------------------------------------------------------------------------*/
|
||||
// Author : hiyohiyo
|
||||
// Mail : hiyohiyo@crystalmark.info
|
||||
// Web : https://crystalmark.info/
|
||||
// License : MIT License
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ComboBoxFx.h"
|
||||
|
||||
class CFontComboBox : public CComboBoxFx
|
||||
{
|
||||
DECLARE_DYNAMIC(CFontComboBox)
|
||||
|
||||
public:
|
||||
CFontComboBox();
|
||||
virtual ~CFontComboBox();
|
||||
|
||||
protected:
|
||||
DECLARE_MESSAGE_MAP()
|
||||
virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
|
||||
|
||||
HBRUSH m_Brush;
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,203 @@
|
||||
/*---------------------------------------------------------------------------*/
|
||||
// Author : hiyohiyo
|
||||
// Mail : hiyohiyo@crystalmark.info
|
||||
// Web : https://crystalmark.info/
|
||||
// License : MIT License
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "HeaderCtrlFx.h"
|
||||
#include "OsInfoFx.h"
|
||||
|
||||
IMPLEMENT_DYNAMIC(CHeaderCtrlFx, CHeaderCtrl)
|
||||
|
||||
CHeaderCtrlFx::CHeaderCtrlFx()
|
||||
{
|
||||
m_X = 0;
|
||||
m_Y = 0;
|
||||
|
||||
m_TextColor = RGB(0, 0, 0);
|
||||
m_LineColor = RGB(224, 224, 224);
|
||||
m_BkColor = RGB(255, 255, 255);
|
||||
m_ZoomRatio = 1.0;
|
||||
m_FontRatio = 1.0;
|
||||
m_FontSize = 12;
|
||||
m_BkDC = NULL;
|
||||
m_CtrlBitmap = NULL;
|
||||
m_bHighContrast = FALSE;
|
||||
m_bDarkMode = FALSE;
|
||||
m_RenderMode = SystemDraw;
|
||||
}
|
||||
|
||||
CHeaderCtrlFx::~CHeaderCtrlFx()
|
||||
{
|
||||
}
|
||||
|
||||
BEGIN_MESSAGE_MAP(CHeaderCtrlFx, CHeaderCtrl)
|
||||
ON_WM_PAINT()
|
||||
ON_MESSAGE(HDM_LAYOUT, OnLayout)
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
void CHeaderCtrlFx::InitControl(int x, int y, double zoomRatio, CDC* bkDC, CBitmap* ctrlBitmap, COLORREF textColor, COLORREF bkColor, COLORREF lineColor, int renderMode, BOOL bHighContrast, BOOL bDarkMode)
|
||||
{
|
||||
m_X = (int)(x * zoomRatio);
|
||||
m_Y = (int)(y * zoomRatio);
|
||||
m_ZoomRatio = zoomRatio;
|
||||
m_BkDC = bkDC;
|
||||
m_TextColor = textColor;
|
||||
m_LineColor = lineColor;
|
||||
m_BkColor = bkColor;
|
||||
|
||||
m_CtrlBitmap = ctrlBitmap;
|
||||
m_RenderMode = renderMode;
|
||||
m_bHighContrast = bHighContrast;
|
||||
m_bDarkMode = bDarkMode;
|
||||
}
|
||||
|
||||
void CHeaderCtrlFx::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
|
||||
{
|
||||
if (m_bHighContrast || m_RenderMode & SystemDraw)
|
||||
{
|
||||
return CHeaderCtrl::DrawItem(lpDrawItemStruct);
|
||||
}
|
||||
|
||||
CDC* drawDC = CDC::FromHandle(lpDrawItemStruct->hDC);
|
||||
|
||||
drawDC->SetBkMode(TRANSPARENT);
|
||||
drawDC->SetTextColor(m_TextColor);
|
||||
|
||||
CRect clientRect;
|
||||
GetClientRect(&clientRect);
|
||||
|
||||
CDC BkDC;
|
||||
BkDC.CreateCompatibleDC(m_BkDC);
|
||||
BkDC.SelectObject(m_CtrlBitmap);
|
||||
CRect rc = lpDrawItemStruct->rcItem;
|
||||
CBrush br;
|
||||
|
||||
if (m_CtrlBitmap != NULL)
|
||||
{
|
||||
drawDC->BitBlt(rc.left, rc.top, rc.right, rc.bottom, &BkDC, rc.left, rc.top, SRCCOPY);
|
||||
}
|
||||
else
|
||||
{
|
||||
br.CreateSolidBrush(m_BkColor);
|
||||
drawDC->FillRect(&rc, &br);
|
||||
}
|
||||
|
||||
br.DeleteObject();
|
||||
br.CreateSolidBrush(m_LineColor);
|
||||
|
||||
CRect rect = lpDrawItemStruct->rcItem;
|
||||
rect.left = rect.right - 1;
|
||||
drawDC->FillRect(&rect, &br);
|
||||
|
||||
rect = lpDrawItemStruct->rcItem;
|
||||
rect.top = rect.bottom - 1;
|
||||
drawDC->FillRect(&rect, &br);
|
||||
|
||||
HDITEM hi{};
|
||||
TCHAR str[256]{};
|
||||
hi.mask = HDI_TEXT | HDI_FORMAT;
|
||||
hi.pszText = str;
|
||||
hi.cchTextMax = 256;
|
||||
GetItem(lpDrawItemStruct->itemID, &hi);
|
||||
|
||||
rect = (CRect)(lpDrawItemStruct->rcItem);
|
||||
|
||||
if (hi.fmt & HDF_CENTER)
|
||||
{
|
||||
drawDC->DrawText(hi.pszText, lstrlen(hi.pszText), rect, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
|
||||
}
|
||||
else if (hi.fmt & HDF_RIGHT)
|
||||
{
|
||||
rect.right -= 6;
|
||||
drawDC->DrawText(hi.pszText, lstrlen(hi.pszText), rect, DT_RIGHT | DT_VCENTER | DT_SINGLELINE);
|
||||
}
|
||||
else
|
||||
{
|
||||
rect.left += 6;
|
||||
drawDC->DrawText(hi.pszText, lstrlen(hi.pszText), rect, DT_LEFT | DT_VCENTER | DT_SINGLELINE);
|
||||
}
|
||||
}
|
||||
|
||||
void CHeaderCtrlFx::OnPaint()
|
||||
{
|
||||
if (m_bHighContrast || m_RenderMode & SystemDraw)
|
||||
{
|
||||
return CHeaderCtrl::OnPaint();
|
||||
}
|
||||
|
||||
CHeaderCtrl::OnPaint();
|
||||
|
||||
RECT rectRightItem;
|
||||
int iItemCount = Header_GetItemCount(this->m_hWnd);
|
||||
if (iItemCount > 0)
|
||||
{
|
||||
Header_GetItemRect(this->m_hWnd, (WPARAM)iItemCount - 1, &rectRightItem);
|
||||
RECT rectClient;
|
||||
GetClientRect(&rectClient);
|
||||
if (rectRightItem.right < rectClient.right)
|
||||
{
|
||||
CDC* drawDC = GetDC();
|
||||
if (m_CtrlBitmap != NULL)
|
||||
{
|
||||
CDC BkDC;
|
||||
BkDC.CreateCompatibleDC(m_BkDC);
|
||||
BkDC.SelectObject(m_CtrlBitmap);
|
||||
drawDC->BitBlt(rectRightItem.right, rectClient.top, rectClient.right, rectClient.bottom, &BkDC, rectRightItem.right, rectRightItem.top, SRCCOPY);
|
||||
}
|
||||
else
|
||||
{
|
||||
CBrush br;
|
||||
br.CreateSolidBrush(m_BkColor);
|
||||
rectClient.left = rectRightItem.right;
|
||||
drawDC->FillRect(&rectClient, &br);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LRESULT CHeaderCtrlFx::OnLayout(WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
LRESULT lResult = CHeaderCtrl::DefWindowProc(HDM_LAYOUT, 0, lParam);
|
||||
|
||||
if (IsWinXpLuna())
|
||||
{
|
||||
HD_LAYOUT& hdl = *(HD_LAYOUT*)lParam;
|
||||
RECT* prc = hdl.prc;
|
||||
WINDOWPOS* pwpos = hdl.pwpos;
|
||||
|
||||
int nHeight = (int)(pwpos->cy * (m_ZoomRatio * m_FontRatio));
|
||||
|
||||
pwpos->cy = nHeight;
|
||||
prc->top = nHeight;
|
||||
}
|
||||
|
||||
return lResult;
|
||||
}
|
||||
|
||||
void CHeaderCtrlFx::SetFontEx(CString face, int size, double zoomRatio, double fontRatio, LONG fontWeight, BYTE fontRender)
|
||||
{
|
||||
m_FontSize = size;
|
||||
m_ZoomRatio = zoomRatio;
|
||||
m_FontRatio = fontRatio;
|
||||
|
||||
LOGFONT logFont = { 0 };
|
||||
logFont.lfCharSet = DEFAULT_CHARSET;
|
||||
logFont.lfHeight = (LONG)(-1 * size * zoomRatio * fontRatio);
|
||||
logFont.lfQuality = fontRender;
|
||||
logFont.lfWeight = fontWeight;
|
||||
if (face.GetLength() < 32)
|
||||
{
|
||||
wsprintf(logFont.lfFaceName, _T("%s"), (LPCTSTR)face);
|
||||
}
|
||||
else
|
||||
{
|
||||
wsprintf(logFont.lfFaceName, _T(""));
|
||||
}
|
||||
|
||||
m_Font.DeleteObject();
|
||||
m_Font.CreateFontIndirect(&logFont);
|
||||
SetFont(&m_Font);
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*---------------------------------------------------------------------------*/
|
||||
// Author : hiyohiyo
|
||||
// Mail : hiyohiyo@crystalmark.info
|
||||
// Web : https://crystalmark.info/
|
||||
// License : MIT License
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
class CHeaderCtrlFx : public CHeaderCtrl
|
||||
{
|
||||
DECLARE_DYNAMIC(CHeaderCtrlFx)
|
||||
|
||||
public:
|
||||
CHeaderCtrlFx();
|
||||
virtual ~CHeaderCtrlFx();
|
||||
void InitControl(int x, int y, double zoomRatio, CDC* bkDC, CBitmap* ctrlBitmap, COLORREF textColor, COLORREF bkColor, COLORREF lineColor, int renderMode, BOOL bHighContrast, BOOL bDarkMode);
|
||||
void SetFontEx(CString face, int size, double zoomRatio, double fontRatio, LONG fontWeight, BYTE fontRender);
|
||||
|
||||
protected:
|
||||
// Draw Control
|
||||
virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
|
||||
|
||||
DECLARE_MESSAGE_MAP()
|
||||
afx_msg void OnPaint();
|
||||
afx_msg LRESULT OnLayout(WPARAM wParam, LPARAM lParam);
|
||||
|
||||
int m_X;
|
||||
int m_Y;
|
||||
COLORREF m_TextColor;
|
||||
COLORREF m_BkColor;
|
||||
COLORREF m_LineColor;
|
||||
double m_ZoomRatio;
|
||||
double m_FontRatio;
|
||||
int m_RenderMode;
|
||||
BOOL m_bHighContrast;
|
||||
BOOL m_bDarkMode;
|
||||
|
||||
CFont m_Font;
|
||||
int m_FontSize;
|
||||
CDC* m_BkDC;
|
||||
CBitmap* m_CtrlBitmap;
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
/*---------------------------------------------------------------------------*/
|
||||
// Author : Richard Yu
|
||||
// Web : https://github.com/ysc3839/win32-darkmode
|
||||
// License : The MIT License
|
||||
// https://github.com/ysc3839/win32-darkmode/blob/master/LICENSE
|
||||
/*---------------------------------------------------------------------------*/
|
||||
// This file contains code from
|
||||
// https://github.com/stevemk14ebr/PolyHook_2_0/blob/master/sources/IatHook.cpp
|
||||
// which is licensed under the MIT License.
|
||||
// See PolyHook_2_0-LICENSE for more information.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
template <typename T, typename T1, typename T2>
|
||||
constexpr T RVA2VA(T1 base, T2 rva)
|
||||
{
|
||||
return reinterpret_cast<T>(reinterpret_cast<ULONG_PTR>(base) + rva);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
constexpr T DataDirectoryFromModuleBase(void *moduleBase, size_t entryID)
|
||||
{
|
||||
auto dosHdr = reinterpret_cast<PIMAGE_DOS_HEADER>(moduleBase);
|
||||
auto ntHdr = RVA2VA<PIMAGE_NT_HEADERS>(moduleBase, dosHdr->e_lfanew);
|
||||
auto dataDir = ntHdr->OptionalHeader.DataDirectory;
|
||||
return RVA2VA<T>(moduleBase, dataDir[entryID].VirtualAddress);
|
||||
}
|
||||
|
||||
PIMAGE_THUNK_DATA FindAddressByName(void *moduleBase, PIMAGE_THUNK_DATA impName, PIMAGE_THUNK_DATA impAddr, const char *funcName)
|
||||
{
|
||||
for (; impName->u1.Ordinal; ++impName, ++impAddr)
|
||||
{
|
||||
if (IMAGE_SNAP_BY_ORDINAL(impName->u1.Ordinal))
|
||||
continue;
|
||||
|
||||
auto import = RVA2VA<PIMAGE_IMPORT_BY_NAME>(moduleBase, impName->u1.AddressOfData);
|
||||
if (strcmp(import->Name, funcName) != 0)
|
||||
continue;
|
||||
return impAddr;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PIMAGE_THUNK_DATA FindAddressByOrdinal(void *moduleBase, PIMAGE_THUNK_DATA impName, PIMAGE_THUNK_DATA impAddr, uint16_t ordinal)
|
||||
{
|
||||
for (; impName->u1.Ordinal; ++impName, ++impAddr)
|
||||
{
|
||||
if (IMAGE_SNAP_BY_ORDINAL(impName->u1.Ordinal) && IMAGE_ORDINAL(impName->u1.Ordinal) == ordinal)
|
||||
return impAddr;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PIMAGE_THUNK_DATA FindIatThunkInModule(void *moduleBase, const char *dllName, const char *funcName)
|
||||
{
|
||||
auto imports = DataDirectoryFromModuleBase<PIMAGE_IMPORT_DESCRIPTOR>(moduleBase, IMAGE_DIRECTORY_ENTRY_IMPORT);
|
||||
for (; imports->Name; ++imports)
|
||||
{
|
||||
if (_stricmp(RVA2VA<LPCSTR>(moduleBase, imports->Name), dllName) != 0)
|
||||
continue;
|
||||
|
||||
auto origThunk = RVA2VA<PIMAGE_THUNK_DATA>(moduleBase, imports->OriginalFirstThunk);
|
||||
auto thunk = RVA2VA<PIMAGE_THUNK_DATA>(moduleBase, imports->FirstThunk);
|
||||
return FindAddressByName(moduleBase, origThunk, thunk, funcName);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PIMAGE_THUNK_DATA FindDelayLoadThunkInModule(void *moduleBase, const char *dllName, const char *funcName)
|
||||
{
|
||||
auto imports = DataDirectoryFromModuleBase<PIMAGE_DELAYLOAD_DESCRIPTOR>(moduleBase, IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT);
|
||||
for (; imports->DllNameRVA; ++imports)
|
||||
{
|
||||
if (_stricmp(RVA2VA<LPCSTR>(moduleBase, imports->DllNameRVA), dllName) != 0)
|
||||
continue;
|
||||
|
||||
auto impName = RVA2VA<PIMAGE_THUNK_DATA>(moduleBase, imports->ImportNameTableRVA);
|
||||
auto impAddr = RVA2VA<PIMAGE_THUNK_DATA>(moduleBase, imports->ImportAddressTableRVA);
|
||||
return FindAddressByName(moduleBase, impName, impAddr, funcName);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PIMAGE_THUNK_DATA FindDelayLoadThunkInModule(void *moduleBase, const char *dllName, uint16_t ordinal)
|
||||
{
|
||||
auto imports = DataDirectoryFromModuleBase<PIMAGE_DELAYLOAD_DESCRIPTOR>(moduleBase, IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT);
|
||||
for (; imports->DllNameRVA; ++imports)
|
||||
{
|
||||
if (_stricmp(RVA2VA<LPCSTR>(moduleBase, imports->DllNameRVA), dllName) != 0)
|
||||
continue;
|
||||
|
||||
auto impName = RVA2VA<PIMAGE_THUNK_DATA>(moduleBase, imports->ImportNameTableRVA);
|
||||
auto impAddr = RVA2VA<PIMAGE_THUNK_DATA>(moduleBase, imports->ImportAddressTableRVA);
|
||||
return FindAddressByOrdinal(moduleBase, impName, impAddr, ordinal);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
@@ -0,0 +1,420 @@
|
||||
#pragma once
|
||||
#include <windows.h>
|
||||
#include <tchar.h>
|
||||
|
||||
#include "stb_image.h"
|
||||
#include "stb_image_write.h"
|
||||
|
||||
class CImage
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
createAlphaChannel = 0x01
|
||||
};
|
||||
|
||||
CImage()
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
~CImage()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
||||
operator HBITMAP() const { return m_hBitmap; }
|
||||
BOOL IsNull() const { return m_hBitmap == NULL; }
|
||||
|
||||
int GetWidth() const { return m_width; }
|
||||
int GetHeight() const { return m_height; }
|
||||
int GetPitch() const { return m_pitch; }
|
||||
int GetBPP() const { return 32; }
|
||||
void* GetBits() const { return m_bits; }
|
||||
|
||||
BOOL Create(int w, int h, int bpp, DWORD flags = 0)
|
||||
{
|
||||
Destroy();
|
||||
|
||||
if (bpp != 32) return FALSE;
|
||||
|
||||
BITMAPINFO bmi = {};
|
||||
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
||||
bmi.bmiHeader.biWidth = w;
|
||||
bmi.bmiHeader.biHeight = -h;
|
||||
bmi.bmiHeader.biPlanes = 1;
|
||||
bmi.bmiHeader.biBitCount = 32;
|
||||
bmi.bmiHeader.biCompression = BI_RGB;
|
||||
|
||||
void* bits = NULL;
|
||||
|
||||
m_hBitmap = CreateDIBSection(NULL, &bmi, DIB_RGB_COLORS, &bits, NULL, 0);
|
||||
if (!m_hBitmap) return FALSE;
|
||||
|
||||
m_bits = (BYTE*)bits;
|
||||
m_width = w;
|
||||
m_height = h;
|
||||
m_pitch = w * 4;
|
||||
|
||||
m_hasAlpha = (flags & createAlphaChannel) != 0;
|
||||
|
||||
memset(m_bits, 0, w * h * 4);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void Destroy()
|
||||
{
|
||||
ReleaseDC();
|
||||
|
||||
if (m_hBitmap)
|
||||
{
|
||||
DeleteObject(m_hBitmap);
|
||||
m_hBitmap = NULL;
|
||||
}
|
||||
|
||||
Init();
|
||||
}
|
||||
|
||||
BOOL Load(LPCTSTR fileName)
|
||||
{
|
||||
Destroy();
|
||||
|
||||
HANDLE hFile = CreateFile(fileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
|
||||
if (hFile == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
DWORD size = GetFileSize(hFile, NULL);
|
||||
BYTE* buf = (BYTE*)malloc(size);
|
||||
|
||||
DWORD read = 0;
|
||||
if (ReadFile(hFile, buf, size, &read, NULL) == FALSE || read != size)
|
||||
{
|
||||
free(buf);
|
||||
CloseHandle(hFile);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL result = FALSE;
|
||||
|
||||
if (IsPNG(buf))
|
||||
{
|
||||
result = LoadPNG(buf, size);
|
||||
}
|
||||
else if (IsBMP(buf))
|
||||
{
|
||||
result = LoadBMP(buf, size);
|
||||
}
|
||||
|
||||
free(buf);
|
||||
return result;
|
||||
}
|
||||
|
||||
static void png_write_func(void* context, void* data, int size)
|
||||
{
|
||||
HANDLE hFile = (HANDLE)context;
|
||||
DWORD written = 0;
|
||||
WriteFile(hFile, data, size, &written, NULL);
|
||||
}
|
||||
|
||||
BOOL Save(LPCTSTR fileName)
|
||||
{
|
||||
if (!m_bits || !fileName)
|
||||
return FALSE;
|
||||
|
||||
if (IsPNGFileName(fileName))
|
||||
return SavePNG(fileName);
|
||||
|
||||
if (IsBMPFileName(fileName))
|
||||
return SaveBMP(fileName);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL IsPNGFileName(LPCTSTR fileName)
|
||||
{
|
||||
LPCTSTR ext = _tcsrchr(fileName, _T('.'));
|
||||
if (!ext) return FALSE;
|
||||
return _tcsicmp(ext, _T(".png")) == 0;
|
||||
}
|
||||
|
||||
BOOL IsBMPFileName(LPCTSTR fileName)
|
||||
{
|
||||
LPCTSTR ext = _tcsrchr(fileName, _T('.'));
|
||||
if (!ext) return FALSE;
|
||||
return _tcsicmp(ext, _T(".bmp")) == 0;
|
||||
}
|
||||
|
||||
BOOL SavePNG(LPCTSTR fileName)
|
||||
{
|
||||
HANDLE hFile = CreateFile(
|
||||
fileName,
|
||||
GENERIC_WRITE,
|
||||
0,
|
||||
NULL,
|
||||
CREATE_ALWAYS,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
NULL);
|
||||
|
||||
if (hFile == INVALID_HANDLE_VALUE)
|
||||
return FALSE;
|
||||
|
||||
size_t size = (size_t)m_width * m_height * 4;
|
||||
BYTE* tmp = (BYTE*)malloc(size);
|
||||
if (!tmp) {
|
||||
CloseHandle(hFile);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
for (int y = 0; y < m_height; y++)
|
||||
{
|
||||
BYTE* src = m_bits + y * m_pitch;
|
||||
BYTE* dst = tmp + y * m_width * 4;
|
||||
|
||||
for (int x = 0; x < m_width; x++)
|
||||
{
|
||||
dst[x * 4 + 0] = src[x * 4 + 2];
|
||||
dst[x * 4 + 1] = src[x * 4 + 1];
|
||||
dst[x * 4 + 2] = src[x * 4 + 0];
|
||||
dst[x * 4 + 3] = 255;
|
||||
}
|
||||
}
|
||||
|
||||
int result = stbi_write_png_to_func(
|
||||
png_write_func,
|
||||
(void*)hFile,
|
||||
m_width,
|
||||
m_height,
|
||||
4,
|
||||
tmp,
|
||||
m_width * 4);
|
||||
|
||||
free(tmp);
|
||||
CloseHandle(hFile);
|
||||
|
||||
return result != 0;
|
||||
}
|
||||
|
||||
BOOL SaveBMP(LPCTSTR fileName)
|
||||
{
|
||||
HANDLE hFile = CreateFile(
|
||||
fileName,
|
||||
GENERIC_WRITE,
|
||||
0,
|
||||
NULL,
|
||||
CREATE_ALWAYS,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
NULL);
|
||||
|
||||
if (hFile == INVALID_HANDLE_VALUE)
|
||||
return FALSE;
|
||||
|
||||
int rowSize = ((m_width * 3 + 3) / 4) * 4;
|
||||
int dataSize = rowSize * m_height;
|
||||
|
||||
BITMAPFILEHEADER bf = {};
|
||||
bf.bfType = 0x4D42; // 'BM'
|
||||
bf.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
|
||||
bf.bfSize = bf.bfOffBits + dataSize;
|
||||
|
||||
BITMAPINFOHEADER bi = {};
|
||||
bi.biSize = sizeof(BITMAPINFOHEADER);
|
||||
bi.biWidth = m_width;
|
||||
bi.biHeight = m_height; // bottom-up
|
||||
bi.biPlanes = 1;
|
||||
bi.biBitCount = 24;
|
||||
bi.biCompression = BI_RGB;
|
||||
|
||||
DWORD written = 0;
|
||||
|
||||
WriteFile(hFile, &bf, sizeof(bf), &written, NULL);
|
||||
WriteFile(hFile, &bi, sizeof(bi), &written, NULL);
|
||||
|
||||
BYTE* line = (BYTE*)malloc(rowSize);
|
||||
if (!line)
|
||||
{
|
||||
CloseHandle(hFile);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
for (int y = m_height - 1; y >= 0; y--)
|
||||
{
|
||||
BYTE* src = m_bits + y * m_pitch;
|
||||
BYTE* dst = line;
|
||||
|
||||
memset(line, 0, rowSize);
|
||||
|
||||
for (int x = 0; x < m_width; x++)
|
||||
{
|
||||
dst[0] = src[0]; // B
|
||||
dst[1] = src[1]; // G
|
||||
dst[2] = src[2]; // R
|
||||
|
||||
src += 4;
|
||||
dst += 3;
|
||||
}
|
||||
|
||||
if (!WriteFile(hFile, line, rowSize, &written, NULL) || written != (DWORD)rowSize)
|
||||
{
|
||||
free(line);
|
||||
CloseHandle(hFile);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
free(line);
|
||||
CloseHandle(hFile);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL BitBlt(HDC hDest, int x, int y, DWORD rop = SRCCOPY) const
|
||||
{
|
||||
return BitBlt(hDest, x, y, m_width, m_height, 0, 0, rop);
|
||||
}
|
||||
|
||||
BOOL BitBlt(HDC hDest, int x, int y, int w, int h, int sx, int sy, DWORD rop) const
|
||||
{
|
||||
HDC hSrc = GetDC();
|
||||
|
||||
BOOL r = ::BitBlt(hDest, x, y, w, h, hSrc, sx, sy, rop);
|
||||
|
||||
ReleaseDC();
|
||||
return r;
|
||||
}
|
||||
|
||||
COLORREF GetPixel(int x, int y) const
|
||||
{
|
||||
BYTE* p = m_bits + y * m_pitch + x * 4;
|
||||
return RGB(p[2], p[1], p[0]);
|
||||
}
|
||||
|
||||
HDC GetDC() const
|
||||
{
|
||||
if (!m_hDC)
|
||||
{
|
||||
m_hDC = CreateCompatibleDC(NULL);
|
||||
m_hOldBitmap = (HBITMAP)SelectObject(m_hDC, m_hBitmap);
|
||||
}
|
||||
return m_hDC;
|
||||
}
|
||||
|
||||
void ReleaseDC() const
|
||||
{
|
||||
if (m_hDC)
|
||||
{
|
||||
SelectObject(m_hDC, m_hOldBitmap);
|
||||
DeleteDC(m_hDC);
|
||||
m_hDC = NULL;
|
||||
m_hOldBitmap = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void Attach(HBITMAP hBitmap)
|
||||
{
|
||||
Destroy();
|
||||
|
||||
m_hBitmap = hBitmap;
|
||||
|
||||
BITMAP bm;
|
||||
GetObject(hBitmap, sizeof(bm), &bm);
|
||||
|
||||
m_width = bm.bmWidth;
|
||||
m_height = bm.bmHeight;
|
||||
m_pitch = bm.bmWidthBytes;
|
||||
m_bits = (BYTE*)bm.bmBits;
|
||||
|
||||
m_hasAlpha = (bm.bmBitsPixel == 32);
|
||||
}
|
||||
|
||||
HBITMAP Detach()
|
||||
{
|
||||
HBITMAP h = m_hBitmap;
|
||||
Init();
|
||||
return h;
|
||||
}
|
||||
|
||||
private:
|
||||
void Init()
|
||||
{
|
||||
m_hBitmap = NULL;
|
||||
m_bits = NULL;
|
||||
m_width = m_height = m_pitch = 0;
|
||||
m_hDC = NULL;
|
||||
m_hOldBitmap = NULL;
|
||||
m_hasAlpha = false;
|
||||
}
|
||||
|
||||
BOOL IsPNG(BYTE* p)
|
||||
{
|
||||
static BYTE sig[8] = { 137,80,78,71,13,10,26,10 };
|
||||
return memcmp(p, sig, 8) == 0;
|
||||
}
|
||||
|
||||
BOOL IsBMP(BYTE* p)
|
||||
{
|
||||
return p[0] == 'B' && p[1] == 'M';
|
||||
}
|
||||
|
||||
BOOL LoadPNG(BYTE* data, int size)
|
||||
{
|
||||
int w, h, c;
|
||||
unsigned char* img = stbi_load_from_memory(data, size, &w, &h, &c, 4);
|
||||
if (!img) return FALSE;
|
||||
|
||||
Create(w, h, 32, createAlphaChannel);
|
||||
|
||||
for (int i = 0; i < w * h; i++)
|
||||
{
|
||||
BYTE r = img[i * 4 + 0];
|
||||
BYTE g = img[i * 4 + 1];
|
||||
BYTE b = img[i * 4 + 2];
|
||||
BYTE a = img[i * 4 + 3];
|
||||
|
||||
m_bits[i * 4 + 0] = b;
|
||||
m_bits[i * 4 + 1] = g;
|
||||
m_bits[i * 4 + 2] = r;
|
||||
m_bits[i * 4 + 3] = a;
|
||||
}
|
||||
|
||||
stbi_image_free(img);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL LoadBMP(BYTE* data, int)
|
||||
{
|
||||
BITMAPFILEHEADER* bf = (BITMAPFILEHEADER*)data;
|
||||
BITMAPINFOHEADER* bi = (BITMAPINFOHEADER*)(data + sizeof(BITMAPFILEHEADER));
|
||||
|
||||
BYTE* src = data + bf->bfOffBits;
|
||||
|
||||
Create(bi->biWidth, abs(bi->biHeight), 32);
|
||||
|
||||
for (int y = 0; y < m_height; y++)
|
||||
{
|
||||
BYTE* d = m_bits + y * m_pitch;
|
||||
BYTE* s = src + (m_height - 1 - y) * ((m_width * 3 + 3) & ~3);
|
||||
|
||||
for (int x = 0; x < m_width; x++)
|
||||
{
|
||||
d[0] = s[0];
|
||||
d[1] = s[1];
|
||||
d[2] = s[2];
|
||||
d[3] = 255;
|
||||
d += 4; s += 3;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
private:
|
||||
HBITMAP m_hBitmap;
|
||||
BYTE* m_bits;
|
||||
int m_width, m_height, m_pitch;
|
||||
|
||||
mutable HDC m_hDC;
|
||||
mutable HBITMAP m_hOldBitmap;
|
||||
|
||||
bool m_hasAlpha;
|
||||
};
|
||||
@@ -0,0 +1,269 @@
|
||||
/*---------------------------------------------------------------------------*/
|
||||
// Author : hiyohiyo
|
||||
// Mail : hiyohiyo@crystalmark.info
|
||||
// Web : https://crystalmark.info/
|
||||
// License : MIT License
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "ImageToast.h"
|
||||
|
||||
#ifndef CMK_MIN
|
||||
#define CMK_MIN(a,b) (( (a) < (b) ) ? (a) : (b))
|
||||
#endif
|
||||
#ifndef CMK_MAX
|
||||
#define CMK_MAX(a,b) (( (a) > (b) ) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
using namespace Gdiplus;
|
||||
|
||||
static const UINT IDT_CLOSE = 1;
|
||||
static const UINT IDT_FADE = 2;
|
||||
|
||||
BEGIN_MESSAGE_MAP(CImageToast, CWnd)
|
||||
ON_WM_CREATE()
|
||||
ON_WM_TIMER()
|
||||
ON_WM_LBUTTONDOWN()
|
||||
ON_WM_RBUTTONDOWN()
|
||||
ON_WM_ERASEBKGND()
|
||||
ON_WM_KEYDOWN()
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
CImageToast::CImageToast() {}
|
||||
CImageToast::~CImageToast() {
|
||||
if (m_hDib) { ::DeleteObject(m_hDib); m_hDib = nullptr; }
|
||||
}
|
||||
|
||||
int CImageToast::OnCreate(LPCREATESTRUCT lpCreateStruct)
|
||||
{
|
||||
if (CWnd::OnCreate(lpCreateStruct) == -1)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
BOOL CImageToast::OnEraseBkgnd(CDC* /*pDC*/) { return TRUE; }
|
||||
|
||||
void CImageToast::OnLButtonDown(UINT, CPoint)
|
||||
{
|
||||
OpenUrlIfAny();
|
||||
BeginClose(FALSE);
|
||||
}
|
||||
|
||||
void CImageToast::OnRButtonDown(UINT, CPoint)
|
||||
{
|
||||
BeginClose(FALSE);
|
||||
}
|
||||
|
||||
void CImageToast::OnKeyDown(UINT, UINT, UINT)
|
||||
{
|
||||
BeginClose(FALSE);
|
||||
}
|
||||
|
||||
BOOL CImageToast::EnsureWindowCreated()
|
||||
{
|
||||
if (m_hWnd && ::IsWindow(m_hWnd)) return TRUE;
|
||||
|
||||
CString cls = AfxRegisterWndClass(0, ::LoadCursor(nullptr, IDC_HAND), 0, 0);
|
||||
DWORD ex = WS_EX_TOPMOST | WS_EX_TOOLWINDOW | WS_EX_LAYERED;
|
||||
DWORD st = WS_POPUP;
|
||||
|
||||
if (!CreateEx(ex, cls, _T(""), st, CRect(0,0,0,0), nullptr, 0))
|
||||
return FALSE;
|
||||
|
||||
ShowWindow(SW_SHOWNOACTIVATE);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL CreateARGBDIB(HDC hdc, int w, int h, HBITMAP& outBmp, void** outBits)
|
||||
{
|
||||
BITMAPINFO bi{};
|
||||
bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
||||
bi.bmiHeader.biWidth = w;
|
||||
bi.bmiHeader.biHeight = -h; // top-down
|
||||
bi.bmiHeader.biPlanes = 1;
|
||||
bi.bmiHeader.biBitCount = 32;
|
||||
bi.bmiHeader.biCompression = BI_RGB;
|
||||
|
||||
void* bits = nullptr;
|
||||
HBITMAP hbmp = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, &bits, nullptr, 0);
|
||||
if (!hbmp || !bits) return FALSE;
|
||||
outBmp = hbmp; *outBits = bits; return TRUE;
|
||||
}
|
||||
|
||||
BOOL CImageToast::LoadPngToDIB(LPCWSTR path)
|
||||
{
|
||||
Gdiplus::Bitmap bmp(path);
|
||||
if (bmp.GetLastStatus() != Gdiplus::Ok) return FALSE;
|
||||
|
||||
const int w = (int)bmp.GetWidth();
|
||||
const int h = (int)bmp.GetHeight();
|
||||
if (w <= 0 || h <= 0) return FALSE;
|
||||
|
||||
HDC hdcScreen = ::GetDC(nullptr);
|
||||
|
||||
HBITMAP hbmp = nullptr;
|
||||
void* bits = nullptr;
|
||||
if (!CreateARGBDIB(hdcScreen, w, h, hbmp, &bits)) {
|
||||
::ReleaseDC(nullptr, hdcScreen);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
HDC hdcMem = ::CreateCompatibleDC(hdcScreen);
|
||||
HGDIOBJ oldBmp = ::SelectObject(hdcMem, hbmp);
|
||||
|
||||
{
|
||||
Gdiplus::Graphics g(hdcMem);
|
||||
g.SetCompositingMode(Gdiplus::CompositingModeSourceCopy);
|
||||
Gdiplus::SolidBrush clearBrush(Gdiplus::Color(0, 0, 0, 0));
|
||||
g.FillRectangle(&clearBrush, 0, 0, w, h);
|
||||
g.DrawImage(&bmp, 0, 0, w, h);
|
||||
}
|
||||
|
||||
::SelectObject(hdcMem, oldBmp);
|
||||
::DeleteDC(hdcMem);
|
||||
::ReleaseDC(nullptr, hdcScreen);
|
||||
|
||||
if (m_hDib) ::DeleteObject(m_hDib);
|
||||
m_hDib = hbmp;
|
||||
m_bmpSize.cx = w; m_bmpSize.cy = h;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void CImageToast::UpdateLayered()
|
||||
{
|
||||
if (!m_hWnd || !::IsWindow(m_hWnd) || !m_hDib) return;
|
||||
|
||||
HDC hdcScreen = ::GetDC(nullptr);
|
||||
HDC hdcMem = ::CreateCompatibleDC(hdcScreen);
|
||||
HBITMAP hOld = (HBITMAP)::SelectObject(hdcMem, m_hDib);
|
||||
|
||||
POINT ptSrc{ 0,0 };
|
||||
SIZE sz{ m_bmpSize.cx, m_bmpSize.cy };
|
||||
BLENDFUNCTION bf{};
|
||||
bf.BlendOp = AC_SRC_OVER;
|
||||
bf.SourceConstantAlpha = m_curAlpha;
|
||||
bf.AlphaFormat = AC_SRC_ALPHA;
|
||||
|
||||
POINT cursor{}; ::GetCursorPos(&cursor);
|
||||
HMONITOR mon = ::MonitorFromPoint(cursor, MONITOR_DEFAULTTONEAREST);
|
||||
MONITORINFO mi{ sizeof(mi) }; ::GetMonitorInfo(mon, &mi);
|
||||
RECT wa = mi.rcWork;
|
||||
|
||||
POINT ptDst{};
|
||||
ptDst.x = wa.right - sz.cx - m_margin;
|
||||
ptDst.y = wa.bottom - sz.cy - m_margin;
|
||||
|
||||
::UpdateLayeredWindow(m_hWnd, hdcScreen, &ptDst, &sz, hdcMem, &ptSrc, 0, &bf, ULW_ALPHA);
|
||||
|
||||
::SelectObject(hdcMem, hOld);
|
||||
::DeleteDC(hdcMem);
|
||||
::ReleaseDC(nullptr, hdcScreen);
|
||||
}
|
||||
|
||||
void CImageToast::StartFadeTimer(BOOL fadeIn)
|
||||
{
|
||||
if (!m_enableFade) return;
|
||||
m_closing = !fadeIn;
|
||||
SetTimer(IDT_FADE, 16, nullptr);
|
||||
}
|
||||
|
||||
void CImageToast::BeginClose(BOOL force)
|
||||
{
|
||||
if (!m_hWnd) return;
|
||||
|
||||
if (force || !m_enableFade) {
|
||||
KillTimer(IDT_FADE);
|
||||
KillTimer(IDT_CLOSE);
|
||||
DestroyWindow();
|
||||
return;
|
||||
}
|
||||
if (!m_closing) {
|
||||
m_closing = TRUE;
|
||||
SetTimer(IDT_FADE, 16, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void CImageToast::OnTimer(UINT_PTR id)
|
||||
{
|
||||
if (id == IDT_CLOSE) {
|
||||
KillTimer(IDT_CLOSE);
|
||||
BeginClose(FALSE);
|
||||
return;
|
||||
}
|
||||
if (id == IDT_FADE) {
|
||||
int stepIn = CMK_MAX(1, (int)m_maxAlpha * 16 / CMK_MAX(1, m_fadeInMs));
|
||||
int stepOut = CMK_MAX(1, (int)m_maxAlpha * 16 / CMK_MAX(1, m_fadeOutMs));
|
||||
|
||||
if (!m_closing) {
|
||||
if (m_curAlpha < m_maxAlpha) {
|
||||
m_curAlpha = (BYTE)CMK_MIN((int)m_maxAlpha, (int)m_curAlpha + stepIn);
|
||||
UpdateLayered();
|
||||
}
|
||||
else {
|
||||
KillTimer(IDT_FADE);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (m_curAlpha > 0) {
|
||||
m_curAlpha = (BYTE)CMK_MAX(0, (int)m_curAlpha - stepOut);
|
||||
UpdateLayered();
|
||||
}
|
||||
else {
|
||||
KillTimer(IDT_FADE);
|
||||
DestroyWindow();
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
CWnd::OnTimer(id);
|
||||
}
|
||||
|
||||
BOOL CImageToast::Show(LPCWSTR pngPath, UINT showMillis, BOOL enableFade, BYTE maxAlpha,
|
||||
int margin, int fadeInMs, int fadeOutMs, LPCWSTR urlToOpen)
|
||||
{
|
||||
m_pngPath = pngPath;
|
||||
m_showMillis = showMillis;
|
||||
m_enableFade = enableFade;
|
||||
m_maxAlpha = maxAlpha;
|
||||
m_margin = margin;
|
||||
m_fadeInMs = fadeInMs;
|
||||
m_fadeOutMs = fadeOutMs;
|
||||
m_curAlpha = enableFade ? 0 : maxAlpha;
|
||||
m_closing = FALSE;
|
||||
m_opened = FALSE;
|
||||
m_url = (urlToOpen ? urlToOpen : L"");
|
||||
|
||||
if (!EnsureWindowCreated()) return FALSE;
|
||||
if (!LoadPngToDIB(m_pngPath)) {
|
||||
BeginClose(TRUE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
UpdateLayered();
|
||||
ShowWindow(SW_SHOWNOACTIVATE);
|
||||
|
||||
SetTimer(IDT_CLOSE, m_showMillis, nullptr);
|
||||
if (m_enableFade) StartFadeTimer(TRUE);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void CImageToast::SetLink(LPCWSTR urlToOpen)
|
||||
{
|
||||
m_url = (urlToOpen ? urlToOpen : L"");
|
||||
}
|
||||
|
||||
void CImageToast::CloseNow()
|
||||
{
|
||||
BeginClose(FALSE);
|
||||
}
|
||||
|
||||
void CImageToast::OpenUrlIfAny()
|
||||
{
|
||||
if (m_opened) return;
|
||||
if (m_url.IsEmpty()) return;
|
||||
|
||||
m_opened = TRUE;
|
||||
|
||||
::ShellExecuteW(nullptr, _T("open"), m_url, nullptr, nullptr, SW_SHOWNORMAL);
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
/*---------------------------------------------------------------------------*/
|
||||
// Author : hiyohiyo
|
||||
// Mail : hiyohiyo@crystalmark.info
|
||||
// Web : https://crystalmark.info/
|
||||
// License : MIT License
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
#include <gdiplus.h>
|
||||
#pragma comment(lib, "gdiplus.lib")
|
||||
#pragma comment(lib, "Shcore.lib")
|
||||
|
||||
class CImageToast : public CWnd
|
||||
{
|
||||
public:
|
||||
CImageToast();
|
||||
virtual ~CImageToast();
|
||||
|
||||
BOOL Show(LPCWSTR pngPath, UINT showMillis = 30000,
|
||||
BOOL enableFade = TRUE, BYTE maxAlpha = 255,
|
||||
int margin = 16, int fadeInMs = 200, int fadeOutMs = 250,
|
||||
LPCWSTR urlToOpen = nullptr);
|
||||
|
||||
void SetLink(LPCWSTR urlToOpen);
|
||||
|
||||
void CloseNow();
|
||||
|
||||
protected:
|
||||
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
|
||||
afx_msg void OnTimer(UINT_PTR nIDEvent);
|
||||
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
|
||||
afx_msg void OnRButtonDown(UINT nFlags, CPoint point);
|
||||
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
|
||||
afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
|
||||
DECLARE_MESSAGE_MAP()
|
||||
|
||||
BOOL EnsureWindowCreated();
|
||||
BOOL LoadPngToDIB(LPCWSTR path);
|
||||
void UpdateLayered();
|
||||
void BeginClose(BOOL force = FALSE);
|
||||
void StartFadeTimer(BOOL fadeIn);
|
||||
|
||||
void OpenUrlIfAny();
|
||||
|
||||
private:
|
||||
CString m_pngPath;
|
||||
UINT m_showMillis{ 30000 };
|
||||
BOOL m_enableFade{ TRUE };
|
||||
BYTE m_maxAlpha{ 255 };
|
||||
int m_margin{ 16 };
|
||||
int m_fadeInMs{ 200 };
|
||||
int m_fadeOutMs{ 250 };
|
||||
CString m_url;
|
||||
|
||||
HBITMAP m_hDib{ nullptr };
|
||||
SIZE m_bmpSize{ 0,0 };
|
||||
BYTE m_curAlpha{ 0 };
|
||||
BOOL m_closing{ FALSE };
|
||||
BOOL m_opened{ FALSE };
|
||||
};
|
||||
@@ -0,0 +1,372 @@
|
||||
/*---------------------------------------------------------------------------*/
|
||||
// Author : hiyohiyo
|
||||
// Mail : hiyohiyo@crystalmark.info
|
||||
// Web : https://crystalmark.info/
|
||||
// License : MIT License
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "ListCtrlFx.h"
|
||||
#include "OsInfoFx.h"
|
||||
|
||||
IMPLEMENT_DYNAMIC(CListCtrlFx, CListCtrl)
|
||||
|
||||
CListCtrlFx::CListCtrlFx()
|
||||
{
|
||||
m_X = 0;
|
||||
m_Y = 0;
|
||||
m_bNT6orLater = IsNT6orLater();
|
||||
m_BkDC = NULL;
|
||||
m_bHighContrast = FALSE;
|
||||
m_RenderMode = SystemDraw;
|
||||
m_bDarkMode = FALSE;
|
||||
|
||||
// Color
|
||||
m_TextColor1 = RGB(0, 0, 0);
|
||||
m_TextColor2 = RGB(0, 0, 0);
|
||||
m_TextSelected = RGB(0, 0, 0);
|
||||
m_BkColor1 = RGB(255, 255, 255);
|
||||
m_BkColor2 = RGB(248, 248, 248);
|
||||
m_BkSelected = RGB(248, 248, 255);
|
||||
m_LineColor1 = RGB(224, 224, 224);
|
||||
m_LineColor2 = RGB(240, 240, 240);
|
||||
|
||||
// Glass
|
||||
m_GlassColor = RGB(255, 255, 255);
|
||||
m_GlassAlpha = 128;
|
||||
}
|
||||
|
||||
CListCtrlFx::~CListCtrlFx()
|
||||
{
|
||||
}
|
||||
|
||||
#pragma warning( disable : 26454 )
|
||||
BEGIN_MESSAGE_MAP(CListCtrlFx, CListCtrl)
|
||||
ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, &CListCtrlFx::OnCustomdraw)
|
||||
END_MESSAGE_MAP()
|
||||
#pragma warning( default : 26454 )
|
||||
|
||||
BOOL CListCtrlFx::InitControl(int x, int y, int width, int height, int maxWidth, int maxHeight, double zoomRatio, CDC* bkDC, int renderMode, BOOL bHighContrast, BOOL bDarkMode)
|
||||
{
|
||||
m_X = (int)(x * zoomRatio);
|
||||
m_Y = (int)(y * zoomRatio);
|
||||
m_CtrlSize.cx = (int)(width * zoomRatio);
|
||||
m_CtrlSize.cy = (int)(height * zoomRatio);
|
||||
MoveWindow(m_X, m_Y, m_CtrlSize.cx, m_CtrlSize.cy);
|
||||
maxWidth = (int)(maxWidth * zoomRatio);
|
||||
maxHeight = (int)(maxHeight * zoomRatio);
|
||||
|
||||
m_BkDC = bkDC;
|
||||
m_RenderMode = renderMode;
|
||||
m_bHighContrast = bHighContrast;
|
||||
m_bDarkMode = bDarkMode;
|
||||
|
||||
if (m_bHighContrast)
|
||||
{
|
||||
SetBkImage((LPTSTR)_T(""));
|
||||
}
|
||||
else if (renderMode & OwnerDrawGlass || renderMode & OwnerDrawTransparent)
|
||||
{
|
||||
m_BkBitmap.DeleteObject();
|
||||
m_BkBitmap.CreateCompatibleBitmap(m_BkDC, maxWidth, maxHeight);
|
||||
CDC BkDC;
|
||||
BkDC.CreateCompatibleDC(m_BkDC);
|
||||
BkDC.SelectObject(m_BkBitmap);
|
||||
BkDC.BitBlt(0, 0, maxWidth, maxHeight, m_BkDC, m_X + 2, m_Y + 2, SRCCOPY);
|
||||
|
||||
m_CtrlImage.Destroy();
|
||||
m_CtrlImage.Create(maxWidth, maxHeight, 32);
|
||||
|
||||
RECT rect{};
|
||||
rect.top = 0;
|
||||
rect.left = 0;
|
||||
rect.right = maxWidth;
|
||||
rect.bottom = maxHeight;
|
||||
|
||||
m_CtrlBitmap.Detach();
|
||||
m_CtrlBitmap.Attach((HBITMAP)m_CtrlImage);
|
||||
|
||||
DWORD length = maxWidth * maxHeight * 4;
|
||||
BYTE* bitmapBits = new BYTE[length];
|
||||
m_CtrlBitmap.GetBitmapBits(length, bitmapBits);
|
||||
|
||||
BYTE r, g, b, a;
|
||||
if (renderMode & OwnerDrawGlass)
|
||||
{
|
||||
r = (BYTE)GetRValue(m_GlassColor);
|
||||
g = (BYTE)GetGValue(m_GlassColor);
|
||||
b = (BYTE)GetBValue(m_GlassColor);
|
||||
a = m_GlassAlpha;
|
||||
}
|
||||
else // OwnerDrawTransparent
|
||||
{
|
||||
r = 0;
|
||||
g = 0;
|
||||
b = 0;
|
||||
a = 0;
|
||||
}
|
||||
|
||||
for (int y = 0; y < maxHeight; y++)
|
||||
{
|
||||
for (int x = 0; x < maxWidth; x++)
|
||||
{
|
||||
DWORD p = (y * maxWidth + x) * 4;
|
||||
#pragma warning( disable : 6386 )
|
||||
bitmapBits[p + 0] = b;
|
||||
bitmapBits[p + 1] = g;
|
||||
bitmapBits[p + 2] = r;
|
||||
bitmapBits[p + 3] = a;
|
||||
#pragma warning( default : 6386 )
|
||||
}
|
||||
}
|
||||
|
||||
m_CtrlBitmap.SetBitmapBits(length, bitmapBits);
|
||||
delete[] bitmapBits;
|
||||
|
||||
SetupControlImage(m_BkBitmap, m_CtrlBitmap);
|
||||
if(m_bNT6orLater)
|
||||
{
|
||||
SetBkImage((HBITMAP)m_CtrlBitmap);
|
||||
m_Header.InitControl(x, y, zoomRatio, bkDC, &m_CtrlBitmap, m_TextColor1, m_BkColor1, m_LineColor1, m_RenderMode, m_bHighContrast, m_bDarkMode);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetBkColor(m_BkColor1);
|
||||
m_Header.InitControl(x, y, zoomRatio, bkDC, NULL, m_TextColor1, m_BkColor1, m_LineColor1, m_RenderMode, m_bHighContrast, m_bDarkMode);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(m_bNT6orLater)
|
||||
{
|
||||
SetBkImage((LPTSTR)_T(""));
|
||||
SetBkColor(m_BkColor1);
|
||||
m_Header.InitControl(x, y, zoomRatio, bkDC, NULL, m_TextColor1, m_BkColor1, m_LineColor1, m_RenderMode, m_bHighContrast, m_bDarkMode);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetBkColor(m_BkColor1);
|
||||
m_Header.InitControl(x, y, zoomRatio, bkDC, NULL, m_TextColor1, m_BkColor1, m_LineColor1, m_RenderMode, m_bHighContrast, m_bDarkMode);
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void CListCtrlFx::SetupControlImage(CBitmap& bkBitmap, CBitmap& ctrlBitmap)
|
||||
{
|
||||
int color = m_BkDC->GetDeviceCaps(BITSPIXEL) * m_BkDC->GetDeviceCaps(PLANES);
|
||||
|
||||
CBitmap* bk32Bitmap;
|
||||
CImage bk32Image;
|
||||
if (color == 32)
|
||||
{
|
||||
bk32Bitmap = &bkBitmap;
|
||||
}
|
||||
else
|
||||
{
|
||||
bk32Image.Create(m_CtrlSize.cx, m_CtrlSize.cy, 32);
|
||||
::BitBlt(bk32Image.GetDC(), 0, 0, m_CtrlSize.cx, m_CtrlSize.cy, *m_BkDC, m_X, m_Y, SRCCOPY);
|
||||
bk32Bitmap = CBitmap::FromHandle((HBITMAP)bk32Image);
|
||||
bk32Image.ReleaseDC();
|
||||
}
|
||||
|
||||
BITMAP CtlBmpInfo, DstBmpInfo;
|
||||
bk32Bitmap->GetBitmap(&DstBmpInfo);
|
||||
DWORD DstLineBytes = DstBmpInfo.bmWidthBytes;
|
||||
DWORD DstMemSize = DstLineBytes * DstBmpInfo.bmHeight;
|
||||
ctrlBitmap.GetBitmap(&CtlBmpInfo);
|
||||
DWORD CtlLineBytes = CtlBmpInfo.bmWidthBytes;
|
||||
DWORD CtlMemSize = CtlLineBytes * CtlBmpInfo.bmHeight;
|
||||
BYTE* DstBuffer = new BYTE[DstMemSize];
|
||||
bk32Bitmap->GetBitmapBits(DstMemSize, DstBuffer);
|
||||
BYTE* CtlBuffer = new BYTE[CtlMemSize];
|
||||
ctrlBitmap.GetBitmapBits(CtlMemSize, CtlBuffer);
|
||||
|
||||
int baseY = 0;
|
||||
for (LONG py = 0; py < DstBmpInfo.bmHeight; py++)
|
||||
{
|
||||
int dn = py * DstLineBytes;
|
||||
int cn = (baseY + py) * CtlLineBytes;
|
||||
for (LONG px = 0; px < DstBmpInfo.bmWidth; px++)
|
||||
{
|
||||
#pragma warning( disable : 6385 )
|
||||
#pragma warning( disable : 6386 )
|
||||
BYTE a = CtlBuffer[cn + 3];
|
||||
BYTE na = 255 - a;
|
||||
CtlBuffer[dn + 0] = (BYTE)((CtlBuffer[cn + 0] * a + DstBuffer[dn + 0] * na) / 255);
|
||||
CtlBuffer[dn + 1] = (BYTE)((CtlBuffer[cn + 1] * a + DstBuffer[dn + 1] * na) / 255);
|
||||
CtlBuffer[dn + 2] = (BYTE)((CtlBuffer[cn + 2] * a + DstBuffer[dn + 2] * na) / 255);
|
||||
dn += (DstBmpInfo.bmBitsPixel / 8);
|
||||
cn += (CtlBmpInfo.bmBitsPixel / 8);
|
||||
#pragma warning( default : 6386 )
|
||||
#pragma warning( default : 6385 )
|
||||
}
|
||||
}
|
||||
|
||||
if (color == 32)
|
||||
{
|
||||
ctrlBitmap.SetBitmapBits(CtlMemSize, CtlBuffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
bk32Bitmap->SetBitmapBits(CtlMemSize, CtlBuffer);
|
||||
m_CtrlImage.Detach();
|
||||
m_CtrlImage.Attach(ctrlBitmap);
|
||||
::BitBlt(m_CtrlImage.GetDC(), 0, 0, m_CtrlSize.cx - 1, m_CtrlSize.cy - 1, bk32Image.GetDC(), 1, 1, SRCCOPY);
|
||||
m_CtrlImage.ReleaseDC();
|
||||
bk32Image.ReleaseDC();
|
||||
}
|
||||
|
||||
delete[] DstBuffer;
|
||||
delete[] CtlBuffer;
|
||||
}
|
||||
|
||||
void CListCtrlFx::OnCustomdraw(NMHDR *pNMHDR, LRESULT *pResult)
|
||||
{
|
||||
LPNMLVCUSTOMDRAW lpLVCustomDraw = reinterpret_cast<LPNMLVCUSTOMDRAW>(pNMHDR);
|
||||
|
||||
switch(lpLVCustomDraw->nmcd.dwDrawStage)
|
||||
{
|
||||
case CDDS_ITEMPREPAINT:
|
||||
case CDDS_ITEMPREPAINT | CDDS_SUBITEM:
|
||||
if(! m_bHighContrast)
|
||||
{
|
||||
if(lpLVCustomDraw->nmcd.dwItemSpec % 2 == 0)
|
||||
{
|
||||
lpLVCustomDraw->clrText = m_TextColor1;
|
||||
lpLVCustomDraw->clrTextBk = m_BkColor1;
|
||||
}
|
||||
else
|
||||
{
|
||||
lpLVCustomDraw->clrText = m_TextColor2;
|
||||
lpLVCustomDraw->clrTextBk = m_BkColor2;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CDDS_ITEMPOSTPAINT | CDDS_SUBITEM:
|
||||
{
|
||||
RECT rc{};
|
||||
CBrush br1(m_LineColor1);
|
||||
CBrush br2(m_LineColor2);
|
||||
|
||||
CHeaderCtrl* header = this->GetHeaderCtrl();
|
||||
if(header != NULL)
|
||||
{
|
||||
int count = header->GetItemCount();
|
||||
for(int i = 0; i < count; i++)
|
||||
{
|
||||
ListView_GetSubItemRect(m_hWnd, lpLVCustomDraw->nmcd.dwItemSpec, i, LVIR_LABEL, &rc);
|
||||
LONG left = rc.left;
|
||||
rc.left = rc.right - 1;
|
||||
FillRect(lpLVCustomDraw->nmcd.hdc, &rc, (HBRUSH)br1.GetSafeHandle());
|
||||
rc.left = left;
|
||||
rc.top = rc.bottom - 1;
|
||||
FillRect(lpLVCustomDraw->nmcd.hdc, &rc, (HBRUSH)br2.GetSafeHandle());
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
*pResult = 0;
|
||||
*pResult |= CDRF_NOTIFYPOSTPAINT;
|
||||
*pResult |= CDRF_NOTIFYITEMDRAW;
|
||||
*pResult |= CDRF_NOTIFYSUBITEMDRAW;
|
||||
}
|
||||
|
||||
void CListCtrlFx::SetTextColor1(COLORREF color){m_TextColor1 = color;}
|
||||
void CListCtrlFx::SetTextColor2(COLORREF color){m_TextColor2 = color;}
|
||||
void CListCtrlFx::SetTextSelected(COLORREF color){m_TextSelected = color;}
|
||||
void CListCtrlFx::SetBkColor1(COLORREF color){m_BkColor1 = color;}
|
||||
void CListCtrlFx::SetBkColor2(COLORREF color){m_BkColor2 = color;}
|
||||
void CListCtrlFx::SetBkSelected(COLORREF color){m_BkSelected = color;}
|
||||
void CListCtrlFx::SetLineColor1(COLORREF color){m_LineColor1 = color;}
|
||||
void CListCtrlFx::SetLineColor2(COLORREF color){m_LineColor2 = color;}
|
||||
|
||||
void CListCtrlFx::SetGlassColor(COLORREF glassColor, BYTE glassAlpha)
|
||||
{
|
||||
m_GlassColor = glassColor;
|
||||
m_GlassAlpha = glassAlpha;
|
||||
}
|
||||
|
||||
COLORREF CListCtrlFx::GetTextColor1(){return m_TextColor1;}
|
||||
COLORREF CListCtrlFx::GetTextColor2(){return m_TextColor2;}
|
||||
COLORREF CListCtrlFx::GetTextSelected(){return m_TextSelected;}
|
||||
COLORREF CListCtrlFx::GetBkColor1(){return m_BkColor1;}
|
||||
COLORREF CListCtrlFx::GetBkColor2(){return m_BkColor2;}
|
||||
COLORREF CListCtrlFx::GetBkSelected(){return m_BkSelected;}
|
||||
COLORREF CListCtrlFx::GetLineColor1(){return m_LineColor1;}
|
||||
COLORREF CListCtrlFx::GetLineColor2(){return m_LineColor2;}
|
||||
|
||||
void CListCtrlFx::SetFontEx(CString face, int size, double zoomRatio, double fontRatio, LONG fontWeight, BYTE fontRender)
|
||||
{
|
||||
LOGFONT logFont = { 0 };
|
||||
logFont.lfCharSet = DEFAULT_CHARSET;
|
||||
logFont.lfHeight = (LONG)(-1 * size * zoomRatio * fontRatio);
|
||||
logFont.lfQuality = fontRender;
|
||||
logFont.lfWeight = fontWeight;
|
||||
if (face.GetLength() < 32)
|
||||
{
|
||||
wsprintf(logFont.lfFaceName, _T("%s"), (LPCTSTR)face);
|
||||
}
|
||||
else
|
||||
{
|
||||
wsprintf(logFont.lfFaceName, _T(""));
|
||||
}
|
||||
|
||||
m_Font.DeleteObject();
|
||||
m_Font.CreateFontIndirect(&logFont);
|
||||
SetFont(&m_Font);
|
||||
|
||||
m_Header.SetFontEx(face, size, zoomRatio, fontRatio, fontWeight, fontRender);
|
||||
}
|
||||
|
||||
void CListCtrlFx::PreSubclassWindow()
|
||||
{
|
||||
CListCtrl::PreSubclassWindow();
|
||||
|
||||
CHeaderCtrlFx* pHeader = (CHeaderCtrlFx*)GetHeaderCtrl();
|
||||
m_Header.SubclassWindow(pHeader->GetSafeHwnd());
|
||||
}
|
||||
|
||||
void CListCtrlFx::EnableHeaderOwnerDraw(BOOL bOwnerDraw)
|
||||
{
|
||||
if (m_bHighContrast)
|
||||
{
|
||||
HDITEM hi = { 0 };
|
||||
hi.mask = HDI_FORMAT;
|
||||
for (int i = 0; i < m_Header.GetItemCount(); i++)
|
||||
{
|
||||
m_Header.GetItem(i, &hi);
|
||||
hi.fmt &= ~HDF_OWNERDRAW;
|
||||
m_Header.SetItem(i, &hi);
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (m_RenderMode & OwnerDrawGlass)
|
||||
{
|
||||
HDITEM hi = {0};
|
||||
hi.mask = HDI_FORMAT;
|
||||
if (bOwnerDraw)
|
||||
{
|
||||
for (int i = 0; i < m_Header.GetItemCount(); i++)
|
||||
{
|
||||
m_Header.GetItem(i, &hi);
|
||||
hi.fmt |= HDF_OWNERDRAW;
|
||||
m_Header.SetItem(i, &hi);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < m_Header.GetItemCount(); i++)
|
||||
{
|
||||
m_Header.GetItem(i, &hi);
|
||||
hi.fmt &= ~HDF_OWNERDRAW;
|
||||
m_Header.SetItem(i, &hi);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
/*---------------------------------------------------------------------------*/
|
||||
// Author : hiyohiyo
|
||||
// Mail : hiyohiyo@crystalmark.info
|
||||
// Web : https://crystalmark.info/
|
||||
// License : MIT License
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "HeaderCtrlFx.h"
|
||||
#include "ImageFx.h"
|
||||
|
||||
class CListCtrlFx : public CListCtrl
|
||||
{
|
||||
DECLARE_DYNAMIC(CListCtrlFx)
|
||||
|
||||
public:
|
||||
CListCtrlFx();
|
||||
virtual ~CListCtrlFx();
|
||||
|
||||
void SetTextColor1(COLORREF color);
|
||||
void SetTextColor2(COLORREF color);
|
||||
void SetTextSelected(COLORREF color);
|
||||
void SetBkColor1(COLORREF color);
|
||||
void SetBkColor2(COLORREF color);
|
||||
void SetBkSelected(COLORREF color);
|
||||
void SetLineColor1(COLORREF color);
|
||||
void SetLineColor2(COLORREF color);
|
||||
void SetGlassColor(COLORREF glassColor, BYTE glassAlpha);
|
||||
|
||||
COLORREF GetTextColor1();
|
||||
COLORREF GetTextColor2();
|
||||
COLORREF GetTextSelected();
|
||||
COLORREF GetBkColor1();
|
||||
COLORREF GetBkColor2();
|
||||
COLORREF GetBkSelected();
|
||||
COLORREF GetLineColor1();
|
||||
COLORREF GetLineColor2();
|
||||
|
||||
BOOL InitControl(int x, int y, int width, int height, int maxWidth, int maxHeight, double zoomRatio, CDC* bkDC, int renderMode, BOOL bHighContrast, BOOL bDarkMode);
|
||||
void SetFontEx(CString face, int size, double zoomRatio, double fontRatio, LONG fontWeight, BYTE fontRender);
|
||||
void EnableHeaderOwnerDraw(BOOL bOwnerDraw);
|
||||
|
||||
protected:
|
||||
virtual void PreSubclassWindow();
|
||||
|
||||
void SetupControlImage(CBitmap& bkBitmap, CBitmap& ctrlBitmap);
|
||||
|
||||
DECLARE_MESSAGE_MAP()
|
||||
afx_msg void OnCustomdraw(NMHDR* pNMHDR, LRESULT* pResult);
|
||||
|
||||
int m_X;
|
||||
int m_Y;
|
||||
BOOL m_bNT6orLater;
|
||||
CSize m_CtrlSize;
|
||||
CRect m_Margin;
|
||||
int m_RenderMode;
|
||||
BOOL m_bHighContrast;
|
||||
BOOL m_bDarkMode;
|
||||
CHeaderCtrlFx m_Header;
|
||||
|
||||
COLORREF m_TextColor1;
|
||||
COLORREF m_TextColor2;
|
||||
COLORREF m_TextSelected;
|
||||
COLORREF m_BkColor1;
|
||||
COLORREF m_BkColor2;
|
||||
COLORREF m_BkSelected;
|
||||
COLORREF m_LineColor1;
|
||||
COLORREF m_LineColor2;
|
||||
|
||||
CFont m_Font;
|
||||
CImageList m_Image;
|
||||
CDC* m_BkDC;
|
||||
|
||||
// Glass
|
||||
COLORREF m_GlassColor;
|
||||
BYTE m_GlassAlpha;
|
||||
|
||||
// Image
|
||||
CBitmap m_BkBitmap;
|
||||
CBitmap m_CtrlBitmap;
|
||||
CImage m_CtrlImage;
|
||||
};
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,85 @@
|
||||
/*---------------------------------------------------------------------------*/
|
||||
// Author : hiyohiyo
|
||||
// Mail : hiyohiyo@crystalmark.info
|
||||
// Web : https://crystalmark.info/
|
||||
// License : MIT License
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
#include "DialogFx.h"
|
||||
|
||||
class CMainDialogFx : public CDialogFx
|
||||
{
|
||||
public:
|
||||
CMainDialogFx(UINT dlgResouce, CWnd* pParent = NULL);
|
||||
virtual ~CMainDialogFx();
|
||||
|
||||
// Zoom
|
||||
DWORD GetZoomType();
|
||||
void SetZoomType(DWORD zoomType);
|
||||
|
||||
// Getter
|
||||
CString GetCurrentLangPath();
|
||||
CString GetDefaultLangPath();
|
||||
CString GetThemeDir();
|
||||
CString GetCurrentTheme();
|
||||
CString GetDefaultTheme();
|
||||
CString GetParentTheme1();
|
||||
CString GetParentTheme2();
|
||||
CString GetIniPath();
|
||||
|
||||
void SaveImage();
|
||||
|
||||
protected:
|
||||
void InitMenu();
|
||||
void InitThemeLang();
|
||||
void ChangeTheme(CString themeName);
|
||||
void SetWindowTitle(CString message);
|
||||
void UpdateThemeInfo();
|
||||
COLORREF GetControlColor(CString name, BYTE defaultColor, CString theme);
|
||||
COLORREF GetBackgroundColor(CString name, CString theme);
|
||||
BYTE GetControlAlpha(CString name, BYTE defaultAlpha, CString theme);
|
||||
BYTE GetCharacterPosition(CString theme);
|
||||
CString GetParentTheme(int i, CString theme);
|
||||
CString GetRandomTheme();
|
||||
void SaveImageDlg(CImage* image);
|
||||
|
||||
virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
|
||||
virtual BOOL OnInitDialog();
|
||||
virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam);
|
||||
virtual BOOL CheckThemeEdition(CString name);
|
||||
virtual CString GetDefaultFont();
|
||||
|
||||
virtual void SaveWindowPosition();
|
||||
virtual void RestoreWindowPosition();
|
||||
|
||||
DECLARE_MESSAGE_MAP()
|
||||
afx_msg void OnWindowPosChanging(WINDOWPOS* lpwndpos);
|
||||
afx_msg void OnGetMinMaxInfo(MINMAXINFO* lpMMI);
|
||||
|
||||
// Common
|
||||
BOOL m_bStartup;
|
||||
BOOL m_bWindowMinimizeOnce;
|
||||
BOOL m_bResident;
|
||||
BOOL m_bResidentMinimize;
|
||||
|
||||
// Theme
|
||||
CString m_ThemeKeyName;
|
||||
CString m_RecommendTheme;
|
||||
CStringArray m_MenuArrayTheme;
|
||||
|
||||
// Language
|
||||
CStringArray m_MenuArrayLang;
|
||||
|
||||
#ifdef OPTION_TASK_TRAY
|
||||
// Task Tray
|
||||
static UINT wmTaskbarCreated;
|
||||
BOOL AddTaskTray(UINT id, UINT callback, HICON icon, CString tip);
|
||||
BOOL RemoveTaskTray(UINT id);
|
||||
BOOL ModifyTaskTray(UINT id, HICON icon, CString tip);
|
||||
BOOL ModifyTaskTrayIcon(UINT id, HICON icon);
|
||||
BOOL ModifyTaskTrayTip(UINT id, CString tip);
|
||||
BOOL ShowBalloon(UINT id, DWORD infoFlag, CString infoTitle, CString info);
|
||||
#endif
|
||||
|
||||
};
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,242 @@
|
||||
/*---------------------------------------------------------------------------*/
|
||||
// Author : hiyohiyo
|
||||
// Mail : hiyohiyo@crystalmark.info
|
||||
// Web : https://crystalmark.info/
|
||||
// License : MIT License
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
////------------------------------------------------
|
||||
// OS Info
|
||||
////------------------------------------------------
|
||||
|
||||
#if _MSC_VER > 1310
|
||||
BOOL IsWindowsVersionOrGreaterFx(WORD wMajorVersion, WORD wMinorVersion, WORD wServicePackMajor = 0);
|
||||
BOOL IsWindowsBuildOrGreater(DWORD build);
|
||||
BOOL IsX64();
|
||||
BOOL IsIa64();
|
||||
BOOL IsArm32();
|
||||
BOOL IsArm64();
|
||||
BOOL IsWow64();
|
||||
BOOL IsIe556();
|
||||
BOOL IsDotNet2();
|
||||
BOOL IsDotNet4();
|
||||
BOOL IsDotNet48();
|
||||
BOOL IsNT5();
|
||||
BOOL IsNT6orLater();
|
||||
BOOL IsWin2k();
|
||||
BOOL IsWinXpOrLater();
|
||||
BOOL IsWinXpLuna();
|
||||
BOOL IsWin8orLater();
|
||||
BOOL IsWin81orLater();
|
||||
BOOL IsDarkModeSupport();
|
||||
BOOL HasSidebar();
|
||||
#endif
|
||||
|
||||
#if _MSC_VER <= 1310
|
||||
#ifdef UNICODE
|
||||
BOOL IsCurrentUserLocalAdministrator(void);
|
||||
BOOL IsUserAdmin(VOID);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
BOOL IsNT3();
|
||||
BOOL IsNT4();
|
||||
BOOL IsWin9x();
|
||||
BOOL IsWin95();
|
||||
BOOL IsWin95First();
|
||||
BOOL IsPC98();
|
||||
BOOL IsNT51orlater();
|
||||
BOOL IsRunningOnWine();
|
||||
|
||||
DWORD GetIeVersion();
|
||||
// DWORD GetWin10Version();
|
||||
void GetOsName(CString& osFullName, CString& osName, CString& osVersion, CString& osArchitecture);
|
||||
void GetOsNameWmi(CString& osFullName);
|
||||
|
||||
////------------------------------------------------
|
||||
// Define
|
||||
////------------------------------------------------
|
||||
|
||||
#define PRODUCT_UNDEFINED 0x00000000
|
||||
|
||||
#define PRODUCT_ULTIMATE 0x00000001
|
||||
#define PRODUCT_HOME_BASIC 0x00000002
|
||||
#define PRODUCT_HOME_PREMIUM 0x00000003
|
||||
#define PRODUCT_ENTERPRISE 0x00000004
|
||||
#define PRODUCT_HOME_BASIC_N 0x00000005
|
||||
#define PRODUCT_BUSINESS 0x00000006
|
||||
#define PRODUCT_STANDARD_SERVER 0x00000007
|
||||
#define PRODUCT_DATACENTER_SERVER 0x00000008
|
||||
#define PRODUCT_SMALLBUSINESS_SERVER 0x00000009
|
||||
#define PRODUCT_ENTERPRISE_SERVER 0x0000000A
|
||||
#define PRODUCT_STARTER 0x0000000B
|
||||
#define PRODUCT_DATACENTER_SERVER_CORE 0x0000000C
|
||||
#define PRODUCT_STANDARD_SERVER_CORE 0x0000000D
|
||||
#define PRODUCT_ENTERPRISE_SERVER_CORE 0x0000000E
|
||||
#define PRODUCT_ENTERPRISE_SERVER_IA64 0x0000000F
|
||||
#define PRODUCT_BUSINESS_N 0x00000010
|
||||
#define PRODUCT_WEB_SERVER 0x00000011
|
||||
#define PRODUCT_CLUSTER_SERVER 0x00000012
|
||||
#define PRODUCT_HOME_SERVER 0x00000013
|
||||
#define PRODUCT_STORAGE_EXPRESS_SERVER 0x00000014
|
||||
#define PRODUCT_STORAGE_STANDARD_SERVER 0x00000015
|
||||
#define PRODUCT_STORAGE_WORKGROUP_SERVER 0x00000016
|
||||
#define PRODUCT_STORAGE_ENTERPRISE_SERVER 0x00000017
|
||||
#define PRODUCT_SERVER_FOR_SMALLBUSINESS 0x00000018
|
||||
#define PRODUCT_SMALLBUSINESS_SERVER_PREMIUM 0x00000019
|
||||
#define PRODUCT_HOME_PREMIUM_N 0x0000001A
|
||||
#define PRODUCT_ENTERPRISE_N 0x0000001B
|
||||
#define PRODUCT_ULTIMATE_N 0x0000001C
|
||||
#define PRODUCT_WEB_SERVER_CORE 0x0000001D
|
||||
#define PRODUCT_MEDIUMBUSINESS_SERVER_MANAGEMENT 0x0000001E
|
||||
#define PRODUCT_MEDIUMBUSINESS_SERVER_SECURITY 0x0000001F
|
||||
#define PRODUCT_MEDIUMBUSINESS_SERVER_MESSAGING 0x00000020
|
||||
#define PRODUCT_SERVER_FOUNDATION 0x00000021
|
||||
#define PRODUCT_HOME_PREMIUM_SERVER 0x00000022
|
||||
#define PRODUCT_SERVER_FOR_SMALLBUSINESS_V 0x00000023
|
||||
#define PRODUCT_STANDARD_SERVER_V 0x00000024
|
||||
#define PRODUCT_DATACENTER_SERVER_V 0x00000025
|
||||
#define PRODUCT_ENTERPRISE_SERVER_V 0x00000026
|
||||
#define PRODUCT_DATACENTER_SERVER_CORE_V 0x00000027
|
||||
#define PRODUCT_STANDARD_SERVER_CORE_V 0x00000028
|
||||
#define PRODUCT_ENTERPRISE_SERVER_CORE_V 0x00000029
|
||||
#define PRODUCT_HYPERV 0x0000002A
|
||||
#define PRODUCT_STORAGE_EXPRESS_SERVER_CORE 0x0000002B
|
||||
#define PRODUCT_STORAGE_STANDARD_SERVER_CORE 0x0000002C
|
||||
#define PRODUCT_STORAGE_WORKGROUP_SERVER_CORE 0x0000002D
|
||||
#define PRODUCT_STORAGE_ENTERPRISE_SERVER_CORE 0x0000002E
|
||||
#define PRODUCT_STARTER_N 0x0000002F
|
||||
#define PRODUCT_PROFESSIONAL 0x00000030
|
||||
#define PRODUCT_PROFESSIONAL_N 0x00000031
|
||||
#define PRODUCT_SB_SOLUTION_SERVER 0x00000032
|
||||
#define PRODUCT_SERVER_FOR_SB_SOLUTIONS 0x00000033
|
||||
#define PRODUCT_STANDARD_SERVER_SOLUTIONS 0x00000034
|
||||
#define PRODUCT_STANDARD_SERVER_SOLUTIONS_CORE 0x00000035
|
||||
#define PRODUCT_SB_SOLUTION_SERVER_EM 0x00000036
|
||||
#define PRODUCT_SERVER_FOR_SB_SOLUTIONS_EM 0x00000037
|
||||
#define PRODUCT_SOLUTION_EMBEDDEDSERVER 0x00000038
|
||||
#define PRODUCT_SOLUTION_EMBEDDEDSERVER_CORE 0x00000039
|
||||
#define PRODUCT_PROFESSIONAL_EMBEDDED 0x0000003A
|
||||
#define PRODUCT_ESSENTIALBUSINESS_SERVER_MGMT 0x0000003B
|
||||
#define PRODUCT_ESSENTIALBUSINESS_SERVER_ADDL 0x0000003C
|
||||
#define PRODUCT_ESSENTIALBUSINESS_SERVER_MGMTSVC 0x0000003D
|
||||
#define PRODUCT_ESSENTIALBUSINESS_SERVER_ADDLSVC 0x0000003E
|
||||
#define PRODUCT_SMALLBUSINESS_SERVER_PREMIUM_CORE 0x0000003F
|
||||
#define PRODUCT_CLUSTER_SERVER_V 0x00000040
|
||||
#define PRODUCT_EMBEDDED 0x00000041
|
||||
#define PRODUCT_STARTER_E 0x00000042
|
||||
#define PRODUCT_HOME_BASIC_E 0x00000043
|
||||
#define PRODUCT_HOME_PREMIUM_E 0x00000044
|
||||
#define PRODUCT_PROFESSIONAL_E 0x00000045
|
||||
#define PRODUCT_ENTERPRISE_E 0x00000046
|
||||
#define PRODUCT_ULTIMATE_E 0x00000047
|
||||
#define PRODUCT_ENTERPRISE_EVALUATION 0x00000048
|
||||
#define PRODUCT_MULTIPOINT_STANDARD_SERVER 0x0000004C
|
||||
#define PRODUCT_MULTIPOINT_PREMIUM_SERVER 0x0000004D
|
||||
#define PRODUCT_STANDARD_EVALUATION_SERVER 0x0000004F
|
||||
#define PRODUCT_DATACENTER_EVALUATION_SERVER 0x00000050
|
||||
#define PRODUCT_ENTERPRISE_N_EVALUATION 0x00000054
|
||||
#define PRODUCT_EMBEDDED_AUTOMOTIVE 0x00000055
|
||||
#define PRODUCT_EMBEDDED_INDUSTRY_A 0x00000056
|
||||
#define PRODUCT_THINPC 0x00000057
|
||||
#define PRODUCT_EMBEDDED_A 0x00000058
|
||||
#define PRODUCT_EMBEDDED_INDUSTRY 0x00000059
|
||||
#define PRODUCT_EMBEDDED_E 0x0000005A
|
||||
#define PRODUCT_EMBEDDED_INDUSTRY_E 0x0000005B
|
||||
#define PRODUCT_EMBEDDED_INDUSTRY_A_E 0x0000005C
|
||||
#define PRODUCT_STORAGE_WORKGROUP_EVALUATION_SERVER 0x0000005F
|
||||
#define PRODUCT_STORAGE_STANDARD_EVALUATION_SERVER 0x00000060
|
||||
#define PRODUCT_CORE_ARM 0x00000061
|
||||
#define PRODUCT_CORE_N 0x00000062
|
||||
#define PRODUCT_CORE_COUNTRYSPECIFIC 0x00000063
|
||||
#define PRODUCT_CORE_SINGLELANGUAGE 0x00000064
|
||||
#define PRODUCT_CORE 0x00000065
|
||||
#define PRODUCT_PROFESSIONAL_WMC 0x00000067
|
||||
#define PRODUCT_EMBEDDED_INDUSTRY_EVAL 0x00000069
|
||||
#define PRODUCT_EMBEDDED_INDUSTRY_E_EVAL 0x0000006A
|
||||
#define PRODUCT_EMBEDDED_EVAL 0x0000006B
|
||||
#define PRODUCT_EMBEDDED_E_EVAL 0x0000006C
|
||||
#define PRODUCT_NANO_SERVER 0x0000006D
|
||||
#define PRODUCT_CLOUD_STORAGE_SERVER 0x0000006E
|
||||
#define PRODUCT_CORE_CONNECTED 0x0000006F
|
||||
#define PRODUCT_PROFESSIONAL_STUDENT 0x00000070
|
||||
#define PRODUCT_CORE_CONNECTED_N 0x00000071
|
||||
#define PRODUCT_PROFESSIONAL_STUDENT_N 0x00000072
|
||||
#define PRODUCT_CORE_CONNECTED_SINGLELANGUAGE 0x00000073
|
||||
#define PRODUCT_CORE_CONNECTED_COUNTRYSPECIFIC 0x00000074
|
||||
#define PRODUCT_CONNECTED_CAR 0x00000075
|
||||
#define PRODUCT_INDUSTRY_HANDHELD 0x00000076
|
||||
#define PRODUCT_PPI_PRO 0x00000077
|
||||
#define PRODUCT_ARM64_SERVER 0x00000078
|
||||
#define PRODUCT_EDUCATION 0x00000079
|
||||
#define PRODUCT_EDUCATION_N 0x0000007A
|
||||
#define PRODUCT_IOTUAP 0x0000007B
|
||||
#define PRODUCT_CLOUD_HOST_INFRASTRUCTURE_SERVER 0x0000007C
|
||||
#define PRODUCT_ENTERPRISE_S 0x0000007D
|
||||
#define PRODUCT_ENTERPRISE_S_N 0x0000007E
|
||||
#define PRODUCT_PROFESSIONAL_S 0x0000007F
|
||||
#define PRODUCT_PROFESSIONAL_S_N 0x00000080
|
||||
#define PRODUCT_ENTERPRISE_S_EVALUATION 0x00000081
|
||||
#define PRODUCT_ENTERPRISE_S_N_EVALUATION 0x00000082
|
||||
#define PRODUCT_HOLOGRAPHIC 0x00000087
|
||||
#define PRODUCT_HOLOGRAPHIC_BUSINESS 0x00000088
|
||||
#define PRODUCT_PRO_SINGLE_LANGUAGE 0x0000008A
|
||||
#define PRODUCT_PRO_CHINA 0x0000008B
|
||||
#define PRODUCT_ENTERPRISE_SUBSCRIPTION 0x0000008C
|
||||
#define PRODUCT_ENTERPRISE_SUBSCRIPTION_N 0x0000008D
|
||||
#define PRODUCT_DATACENTER_NANO_SERVER 0x0000008F
|
||||
#define PRODUCT_STANDARD_NANO_SERVER 0x00000090
|
||||
#define PRODUCT_DATACENTER_A_SERVER_CORE 0x00000091
|
||||
#define PRODUCT_STANDARD_A_SERVER_CORE 0x00000092
|
||||
#define PRODUCT_DATACENTER_WS_SERVER_CORE 0x00000093
|
||||
#define PRODUCT_STANDARD_WS_SERVER_CORE 0x00000094
|
||||
#define PRODUCT_UTILITY_VM 0x00000095
|
||||
#define PRODUCT_DATACENTER_EVALUATION_SERVER_CORE 0x0000009F
|
||||
#define PRODUCT_STANDARD_EVALUATION_SERVER_CORE 0x000000A0
|
||||
#define PRODUCT_PRO_WORKSTATION 0x000000A1
|
||||
#define PRODUCT_PRO_WORKSTATION_N 0x000000A2
|
||||
#define PRODUCT_PRO_FOR_EDUCATION 0x000000A4
|
||||
#define PRODUCT_PRO_FOR_EDUCATION_N 0x000000A5
|
||||
#define PRODUCT_AZURE_SERVER_CORE 0x000000A8
|
||||
#define PRODUCT_AZURE_NANO_SERVER 0x000000A9
|
||||
#define PRODUCT_ENTERPRISEG 0x000000AB
|
||||
#define PRODUCT_ENTERPRISEGN 0x000000AC
|
||||
#define PRODUCT_SERVERRDSH 0x000000AF
|
||||
#define PRODUCT_CLOUD 0x000000B2
|
||||
#define PRODUCT_CLOUDN 0x000000B3
|
||||
#define PRODUCT_HUBOS 0x000000B4
|
||||
#define PRODUCT_ONECOREUPDATEOS 0x000000B6
|
||||
#define PRODUCT_CLOUDE 0x000000B7
|
||||
#define PRODUCT_IOTOS 0x000000B9
|
||||
#define PRODUCT_CLOUDEN 0x000000BA
|
||||
#define PRODUCT_IOTEDGEOS 0x000000BB
|
||||
#define PRODUCT_IOTENTERPRISE 0x000000BC
|
||||
#define PRODUCT_LITE 0x000000BD
|
||||
#define PRODUCT_IOTENTERPRISES 0x000000BF
|
||||
#define PRODUCT_XBOX_SYSTEMOS 0x000000C0
|
||||
#define PRODUCT_XBOX_GAMEOS 0x000000C2
|
||||
#define PRODUCT_XBOX_ERAOS 0x000000C3
|
||||
#define PRODUCT_XBOX_DURANGOHOSTOS 0x000000C4
|
||||
#define PRODUCT_XBOX_SCARLETTHOSTOS 0x000000C5
|
||||
#define PRODUCT_XBOX_KEYSTONE 0x000000C6
|
||||
#define PRODUCT_AZURE_SERVER_CLOUDHOST 0x000000C7
|
||||
#define PRODUCT_AZURE_SERVER_CLOUDMOS 0x000000C8
|
||||
#define PRODUCT_CLOUDEDITIONN 0x000000CA
|
||||
#define PRODUCT_CLOUDEDITION 0x000000CB
|
||||
#define PRODUCT_AZURESTACKHCI_SERVER_CORE 0x00000196
|
||||
#define PRODUCT_DATACENTER_SERVER_AZURE_EDITION 0x00000197
|
||||
#define PRODUCT_DATACENTER_SERVER_CORE_AZURE_EDITION 0x00000198
|
||||
|
||||
#define PRODUCT_UNLICENSED 0xABCDABCD
|
||||
|
||||
// ChatGPT...
|
||||
#define PRODUCT_ENTERPRISE_G 0x00000067
|
||||
#define PRODUCT_PROFESSIONAL_WORKSTATION 0x000000B5
|
||||
#define PRODUCT_PROFESSIONAL_WORKSTATION_N 0x000000B6
|
||||
|
||||
#define SM_TABLETPC 86
|
||||
#define SM_MEDIACENTER 87
|
||||
#define SM_STARTER 88
|
||||
#define SM_SERVERR2 89
|
||||
@@ -0,0 +1,93 @@
|
||||
/*---------------------------------------------------------------------------*/
|
||||
// Author : hiyohiyo
|
||||
// Mail : hiyohiyo@crystalmark.info
|
||||
// Web : https://crystalmark.info/
|
||||
// License : The MIT License
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "../stdafx.h"
|
||||
#include "ScrollBarFx.h"
|
||||
#include "OsInfoFx.h"
|
||||
|
||||
CScrollBarFx::CScrollBarFx()
|
||||
{
|
||||
m_X = 0;
|
||||
m_Y = 0;
|
||||
m_BkDC = NULL;
|
||||
m_RenderMode = SystemDraw;
|
||||
m_bHighContrast = FALSE;
|
||||
m_bDarkMode = FALSE;
|
||||
}
|
||||
|
||||
CScrollBarFx::~CScrollBarFx()
|
||||
{
|
||||
m_BkBrush.DeleteObject();
|
||||
}
|
||||
|
||||
IMPLEMENT_DYNAMIC(CScrollBarFx, CScrollBar)
|
||||
|
||||
BEGIN_MESSAGE_MAP(CScrollBarFx, CScrollBar)
|
||||
//{{AFX_MSG_MAP(CScrollBarFx)
|
||||
ON_WM_HSCROLL_REFLECT()
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
BOOL CScrollBarFx::InitControl(int x, int y, int width, int height, double zoomRatio, CDC* bkDC, int renderMode, BOOL bHighContrast, BOOL bDarkMode, int min, int max, int pos)
|
||||
{
|
||||
m_X = (int)(x * zoomRatio);
|
||||
m_Y = (int)(y * zoomRatio);
|
||||
m_CtrlSize.cx = (int)(width * zoomRatio);
|
||||
m_CtrlSize.cy = (int)(height * zoomRatio);
|
||||
MoveWindow(m_X, m_Y, m_CtrlSize.cx, m_CtrlSize.cy);
|
||||
|
||||
m_BkDC = bkDC;
|
||||
m_RenderMode = renderMode;
|
||||
m_bHighContrast = bHighContrast;
|
||||
m_bDarkMode = bDarkMode;
|
||||
|
||||
// BkBrush
|
||||
m_BkBrush.DeleteObject();
|
||||
if (bDarkMode)
|
||||
{
|
||||
m_BkBrush.CreateSolidBrush(RGB(32, 32, 32));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_BkBrush.CreateSolidBrush(RGB(255, 255, 255));
|
||||
}
|
||||
|
||||
SetScrollRange(min, max, TRUE);
|
||||
SetScrollPos(pos);
|
||||
|
||||
Invalidate();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void CScrollBarFx::HScroll(UINT nSBCode, UINT nPos)
|
||||
{
|
||||
int position = GetScrollPos();
|
||||
switch (nSBCode)
|
||||
{
|
||||
case SB_LINELEFT:
|
||||
position -= 1;
|
||||
break;
|
||||
case SB_LINERIGHT:
|
||||
position += 1;
|
||||
break;
|
||||
case SB_PAGELEFT:
|
||||
position -= 5;
|
||||
break;
|
||||
case SB_PAGERIGHT:
|
||||
position += 5;
|
||||
break;
|
||||
case SB_LEFT:
|
||||
break;
|
||||
case SB_RIGHT:
|
||||
break;
|
||||
case SB_THUMBTRACK:
|
||||
position = nPos;
|
||||
break;
|
||||
}
|
||||
SetScrollPos(position);
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*---------------------------------------------------------------------------*/
|
||||
// Author : hiyohiyo
|
||||
// Mail : hiyohiyo@crystalmark.info
|
||||
// Web : https://crystalmark.info/
|
||||
// License : The MIT License
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CommonFx.h"
|
||||
#include <atlimage.h>
|
||||
#include <gdiplus.h>
|
||||
#pragma comment(lib, "Gdiplus.lib")
|
||||
using namespace Gdiplus;
|
||||
|
||||
class CScrollBarFx : public CScrollBar
|
||||
{
|
||||
DECLARE_DYNAMIC(CScrollBarFx)
|
||||
|
||||
public:
|
||||
CScrollBarFx();
|
||||
virtual ~CScrollBarFx();
|
||||
BOOL InitControl(int x, int y, int width, int height, double zoomRatio, CDC* bkDC, int renderMode, BOOL bHighContrast, BOOL bDarkMode, int min, int max, int pos);
|
||||
|
||||
BOOL m_bHighContrast;
|
||||
CBrush m_BkBrush;
|
||||
|
||||
protected:
|
||||
DECLARE_MESSAGE_MAP()
|
||||
afx_msg void HScroll(UINT nSBCode, UINT nPos);
|
||||
|
||||
int m_X;
|
||||
int m_Y;
|
||||
CSize m_CtrlSize;
|
||||
CRect m_Margin;
|
||||
int m_RenderMode;
|
||||
BOOL m_bDarkMode;
|
||||
CDC* m_BkDC;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,129 @@
|
||||
/*---------------------------------------------------------------------------*/
|
||||
// Author : hiyohiyo
|
||||
// Mail : hiyohiyo@crystalmark.info
|
||||
// Web : https://crystalmark.info/
|
||||
// License : MIT License
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "SliderCtrlFx.h"
|
||||
#include "OsInfoFx.h"
|
||||
|
||||
IMPLEMENT_DYNAMIC(CSliderCtrlFx, CSliderCtrl)
|
||||
|
||||
CSliderCtrlFx::CSliderCtrlFx()
|
||||
{
|
||||
m_X = 0;
|
||||
m_Y = 0;
|
||||
m_BkDC = NULL;
|
||||
m_RenderMode = SystemDraw;
|
||||
m_bHighContrast = FALSE;
|
||||
m_bDarkMode = FALSE;
|
||||
m_bBkBitmapInit = FALSE;
|
||||
}
|
||||
|
||||
CSliderCtrlFx::~CSliderCtrlFx()
|
||||
{
|
||||
m_BkBrush.DeleteObject();
|
||||
}
|
||||
|
||||
BEGIN_MESSAGE_MAP(CSliderCtrlFx, CSliderCtrl)
|
||||
ON_WM_KEYDOWN()
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
BOOL CSliderCtrlFx::InitControl(int x, int y, int width, int height, double zoomRatio, CDC* bkDC, int renderMode, BOOL bHighContrast, BOOL bDarkMode, int min, int max, int pos)
|
||||
{
|
||||
m_X = (int)(x * zoomRatio);
|
||||
m_Y = (int)(y * zoomRatio);
|
||||
m_CtrlSize.cx = (int)(width * zoomRatio);
|
||||
m_CtrlSize.cy = (int)(height * zoomRatio);
|
||||
MoveWindow(m_X, m_Y, m_CtrlSize.cx, m_CtrlSize.cy);
|
||||
SendMessage(TBM_SETTHUMBLENGTH, m_CtrlSize.cy, 0);
|
||||
|
||||
m_BkDC = bkDC;
|
||||
m_RenderMode = renderMode;
|
||||
m_bHighContrast = bHighContrast;
|
||||
m_bDarkMode = bDarkMode;
|
||||
|
||||
SetBkReload();
|
||||
LoadCtrlBk(bkDC);
|
||||
m_BkBrush.DeleteObject();
|
||||
if (bDarkMode)
|
||||
{
|
||||
// m_BkBrush.CreateSolidBrush(RGB(32, 32, 32));
|
||||
m_BkBrush.CreatePatternBrush(&m_BkBitmap);
|
||||
}
|
||||
else
|
||||
{
|
||||
// m_BkBrush.CreateSolidBrush(RGB(255, 255, 255));
|
||||
m_BkBrush.CreatePatternBrush(&m_BkBitmap);
|
||||
}
|
||||
|
||||
// Range, Pos
|
||||
SetRange(min, max, TRUE);
|
||||
SetPos(pos);
|
||||
|
||||
Invalidate();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void CSliderCtrlFx::SetBkReload(void)
|
||||
{
|
||||
m_bBkBitmapInit = FALSE;
|
||||
m_bBkLoad = FALSE;
|
||||
}
|
||||
|
||||
void CSliderCtrlFx::LoadCtrlBk(CDC* drawDC)
|
||||
{
|
||||
if (m_bHighContrast) { SetBkReload(); return; }
|
||||
|
||||
if (m_BkBitmap.m_hObject != NULL)
|
||||
{
|
||||
BITMAP bitmapInfo;
|
||||
m_BkBitmap.GetBitmap(&bitmapInfo);
|
||||
if (bitmapInfo.bmBitsPixel != drawDC->GetDeviceCaps(BITSPIXEL))
|
||||
{
|
||||
SetBkReload();
|
||||
}
|
||||
}
|
||||
|
||||
if (&m_CtrlBitmap != NULL)
|
||||
{
|
||||
if (!m_bBkBitmapInit)
|
||||
{
|
||||
m_BkBitmap.DeleteObject();
|
||||
m_BkBitmap.CreateCompatibleBitmap(drawDC, m_CtrlSize.cx, m_CtrlSize.cy);
|
||||
m_bBkBitmapInit = TRUE;
|
||||
}
|
||||
|
||||
if (!m_bBkLoad)
|
||||
{
|
||||
CBitmap* pOldBitmap;
|
||||
CDC* pMemDC = new CDC;
|
||||
pMemDC->CreateCompatibleDC(drawDC);
|
||||
pOldBitmap = pMemDC->SelectObject(&m_BkBitmap);
|
||||
pMemDC->BitBlt(0, 0, m_CtrlSize.cx, m_CtrlSize.cy, m_BkDC, m_X, m_Y, SRCCOPY);
|
||||
pMemDC->SelectObject(pOldBitmap);
|
||||
pMemDC->DeleteDC();
|
||||
delete pMemDC;
|
||||
m_bBkLoad = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CSliderCtrlFx::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
|
||||
{
|
||||
if (nChar == VK_UP)
|
||||
{
|
||||
PostMessage(WM_KEYDOWN, VK_RIGHT, nFlags);
|
||||
return;
|
||||
}
|
||||
else if (nChar == VK_DOWN)
|
||||
{
|
||||
PostMessage(WM_KEYDOWN, VK_LEFT, nFlags);
|
||||
return;
|
||||
}
|
||||
|
||||
CSliderCtrl::OnKeyDown(nChar, nRepCnt, nFlags);
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*---------------------------------------------------------------------------*/
|
||||
// Author : hiyohiyo
|
||||
// Mail : hiyohiyo@crystalmark.info
|
||||
// Web : https://crystalmark.info/
|
||||
// License : MIT License
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ImageFx.h"
|
||||
|
||||
class CSliderCtrlFx : public CSliderCtrl
|
||||
{
|
||||
DECLARE_DYNAMIC(CSliderCtrlFx)
|
||||
|
||||
public:
|
||||
CSliderCtrlFx();
|
||||
virtual ~CSliderCtrlFx();
|
||||
BOOL InitControl(int x, int y, int width, int height, double zoomRatio, CDC* bkDC, int renderMode, BOOL bHighContrast, BOOL bDarkMode, int min, int max, int pos);
|
||||
|
||||
BOOL m_bHighContrast{};
|
||||
CBrush m_BkBrush;
|
||||
|
||||
protected:
|
||||
// Message Map
|
||||
DECLARE_MESSAGE_MAP()
|
||||
afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
|
||||
|
||||
// Image
|
||||
void SetBkReload(void);
|
||||
void LoadCtrlBk(CDC* drawDC);
|
||||
|
||||
int m_X{};
|
||||
int m_Y{};
|
||||
CSize m_CtrlSize;
|
||||
CRect m_Margin;
|
||||
int m_RenderMode{};
|
||||
BOOL m_bDarkMode{};
|
||||
|
||||
// Image
|
||||
CDC* m_BkDC;
|
||||
CBitmap m_BkBitmap;
|
||||
BOOL m_bBkBitmapInit{};
|
||||
BOOL m_bBkLoad{};
|
||||
CBitmap m_CtrlBitmap;
|
||||
CImage m_CtrlImage;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,917 @@
|
||||
/*---------------------------------------------------------------------------*/
|
||||
// Author : hiyohiyo
|
||||
// Mail : hiyohiyo@crystalmark.info
|
||||
// Web : https://crystalmark.info/
|
||||
// License : MIT License
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "StaticFx.h"
|
||||
|
||||
#if _MSC_VER <= 1310
|
||||
#define ON_WM_MOUSEHOVER() \
|
||||
{ 0x2A1 /*WM_MOUSEHOVER*/, 0, 0, 0, AfxSig_vwp, \
|
||||
(AFX_PMSG)(AFX_PMSGW) \
|
||||
(static_cast< void (AFX_MSG_CALL CWnd::*)(UINT, CPoint) > (OnMouseHover)) },
|
||||
|
||||
#define ON_WM_MOUSELEAVE() \
|
||||
{ 0x2A3 /*WM_MOUSELEAVE*/, 0, 0, 0, AfxSig_vv, \
|
||||
(AFX_PMSG)(AFX_PMSGW) \
|
||||
(static_cast< void (AFX_MSG_CALL CWnd::*)(void) > (OnMouseLeave)) },
|
||||
#endif
|
||||
|
||||
////------------------------------------------------
|
||||
// CStaticFx
|
||||
////------------------------------------------------
|
||||
|
||||
CStaticFx::CStaticFx()
|
||||
{
|
||||
// Control
|
||||
m_X = 0;
|
||||
m_Y = 0;
|
||||
m_RenderMode = SystemDraw;
|
||||
m_bHighContrast = FALSE;
|
||||
m_bDarkMode = FALSE;
|
||||
m_DrawFrame = FALSE;
|
||||
m_bDrawFrameEx = FALSE;
|
||||
m_FrameColor = RGB(128, 128, 128);
|
||||
m_hPal = NULL;
|
||||
|
||||
// Glass
|
||||
m_GlassColor = RGB(255, 255, 255);
|
||||
m_GlassAlpha = 255;
|
||||
|
||||
// Meter
|
||||
m_bMeter = FALSE;
|
||||
m_MeterRatio = 0.0;
|
||||
|
||||
// Image
|
||||
m_ImageCount = 0;
|
||||
m_BkDC = NULL;
|
||||
m_bBkBitmapInit = FALSE;
|
||||
m_bBkLoad = FALSE;
|
||||
|
||||
// Font
|
||||
m_TextAlign = SS_LEFT;
|
||||
m_TextColor = RGB(0, 0, 0);
|
||||
|
||||
// Mouse
|
||||
m_bHover = FALSE;
|
||||
m_bFocas = FALSE;
|
||||
m_bTrackingNow = FALSE;
|
||||
m_bHandCursor = FALSE;
|
||||
|
||||
// Text Format
|
||||
m_TextFormat = 0;
|
||||
m_LabelFormat = DT_LEFT | DT_TOP | DT_SINGLELINE;
|
||||
m_UnitFormat = DT_RIGHT | DT_BOTTOM | DT_SINGLELINE;
|
||||
|
||||
// Margin
|
||||
m_Margin.top = 0;
|
||||
m_Margin.left = 0;
|
||||
m_Margin.bottom = 0;
|
||||
m_Margin.right = 0;
|
||||
}
|
||||
|
||||
CStaticFx::~CStaticFx()
|
||||
{
|
||||
}
|
||||
|
||||
IMPLEMENT_DYNAMIC(CStaticFx, CStatic)
|
||||
|
||||
BEGIN_MESSAGE_MAP(CStaticFx, CStatic)
|
||||
//{{AFX_MSG_MAP(CStaticFx)
|
||||
ON_WM_ERASEBKGND()
|
||||
ON_WM_MOUSEMOVE()
|
||||
ON_WM_MOUSEHOVER()
|
||||
ON_WM_MOUSELEAVE()
|
||||
ON_WM_KILLFOCUS()
|
||||
ON_WM_SETFOCUS()
|
||||
ON_WM_SETCURSOR()
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
//------------------------------------------------
|
||||
// Control
|
||||
//------------------------------------------------
|
||||
|
||||
BOOL CStaticFx::InitControl(int x, int y, int width, int height, double zoomRatio, HPALETTE hPal, CDC* bkDC,
|
||||
LPCTSTR imagePath, int imageCount, DWORD textAlign, int renderMode, BOOL bHighContrast, BOOL bDarkMode, DWORD drawFrame)
|
||||
{
|
||||
m_X = (int)(x * zoomRatio);
|
||||
m_Y = (int)(y * zoomRatio);
|
||||
m_CtrlSize.cx = (int)(width * zoomRatio);
|
||||
m_CtrlSize.cy = (int)(height * zoomRatio);
|
||||
MoveWindow(m_X, m_Y, m_CtrlSize.cx, m_CtrlSize.cy);
|
||||
|
||||
m_hPal = hPal;
|
||||
m_BkDC = bkDC;
|
||||
m_ImagePath = imagePath;
|
||||
m_ImageCount = imageCount;
|
||||
m_RenderMode = renderMode;
|
||||
|
||||
if (SS_LEFT <= textAlign && textAlign <= SS_RIGHT)
|
||||
{
|
||||
m_TextAlign = textAlign;
|
||||
}
|
||||
|
||||
if (m_ToolTip.m_hWnd != NULL)
|
||||
{
|
||||
if (m_ToolTip.GetToolCount() != 0)
|
||||
{
|
||||
m_ToolTip.DelTool(this, 1);
|
||||
}
|
||||
CRect rect;
|
||||
GetClientRect(rect);
|
||||
m_ToolTip.AddTool(this, m_ToolTipText, rect, 1);
|
||||
}
|
||||
|
||||
m_bHighContrast = bHighContrast;
|
||||
m_bDarkMode = bDarkMode;
|
||||
m_DrawFrame = drawFrame;
|
||||
|
||||
if (m_bHighContrast)
|
||||
{
|
||||
ModifyStyle(SS_OWNERDRAW, m_TextAlign | SS_CENTERIMAGE);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
else if (renderMode & SystemDraw)
|
||||
{
|
||||
ModifyStyle(SS_OWNERDRAW, m_TextAlign | SS_CENTERIMAGE);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
SetBkReload();
|
||||
ModifyStyle(m_TextAlign | SS_CENTERIMAGE, SS_OWNERDRAW);
|
||||
}
|
||||
|
||||
if (renderMode & OwnerDrawImage)
|
||||
{
|
||||
if (!LoadBitmap(imagePath))
|
||||
{
|
||||
ModifyStyle(SS_OWNERDRAW, m_TextAlign);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ImageCount = 1;
|
||||
m_CtrlImage.Destroy();
|
||||
m_CtrlImage.Create(m_CtrlSize.cx, m_CtrlSize.cy * m_ImageCount, 32);
|
||||
m_CtrlBitmap.Detach();
|
||||
m_CtrlBitmap.Attach((HBITMAP)m_CtrlImage);
|
||||
DWORD length = m_CtrlSize.cx * m_CtrlSize.cy * m_ImageCount * 4;
|
||||
BYTE* bitmapBits = new BYTE[length];
|
||||
m_CtrlBitmap.GetBitmapBits(length, bitmapBits);
|
||||
|
||||
BYTE r, g, b, a;
|
||||
if (renderMode & OwnerDrawGlass)
|
||||
{
|
||||
r = (BYTE)GetRValue(m_GlassColor);
|
||||
g = (BYTE)GetGValue(m_GlassColor);
|
||||
b = (BYTE)GetBValue(m_GlassColor);
|
||||
a = m_GlassAlpha;
|
||||
}
|
||||
else // OwnerDrawTransparent
|
||||
{
|
||||
r = 0;
|
||||
g = 0;
|
||||
b = 0;
|
||||
a = 0;
|
||||
}
|
||||
|
||||
for (int y = 0; y < (int)(m_CtrlSize.cy * m_ImageCount); y++)
|
||||
{
|
||||
for (int x = 0; x < m_CtrlSize.cx; x++)
|
||||
{
|
||||
DWORD p = (y * m_CtrlSize.cx + x) * 4;
|
||||
#if _MSC_VER > 1310
|
||||
#pragma warning( disable : 6386 )
|
||||
#endif
|
||||
bitmapBits[p + 0] = b;
|
||||
bitmapBits[p + 1] = g;
|
||||
bitmapBits[p + 2] = r;
|
||||
bitmapBits[p + 3] = a;
|
||||
#if _MSC_VER > 1310
|
||||
#pragma warning( default : 6386 )
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
m_CtrlBitmap.SetBitmapBits(length, bitmapBits);
|
||||
delete[] bitmapBits;
|
||||
}
|
||||
|
||||
Invalidate();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void CStaticFx::SetMargin(int top, int left, int bottom, int right, double zoomRatio)
|
||||
{
|
||||
m_Margin.top = (int)(top * zoomRatio);
|
||||
m_Margin.left = (int)(left * zoomRatio);
|
||||
m_Margin.bottom = (int)(bottom * zoomRatio);
|
||||
m_Margin.right = (int)(right * zoomRatio);
|
||||
}
|
||||
|
||||
CSize CStaticFx::GetSize(void)
|
||||
{
|
||||
return m_CtrlSize;
|
||||
}
|
||||
|
||||
void CStaticFx::SetDrawFrame(BOOL drawFrame)
|
||||
{
|
||||
if (drawFrame && m_bHighContrast)
|
||||
{
|
||||
ModifyStyleEx(0, WS_EX_STATICEDGE, SWP_DRAWFRAME);
|
||||
}
|
||||
else
|
||||
{
|
||||
ModifyStyleEx(WS_EX_STATICEDGE, 0, SWP_DRAWFRAME);
|
||||
}
|
||||
m_DrawFrame = drawFrame;
|
||||
}
|
||||
|
||||
void CStaticFx::SetDrawFrameEx(BOOL bDrawFrameEx, COLORREF frameColor)
|
||||
{
|
||||
m_bDrawFrameEx = bDrawFrameEx;
|
||||
m_FrameColor = frameColor;
|
||||
}
|
||||
|
||||
void CStaticFx::SetGlassColor(COLORREF glassColor, BYTE glassAlpha)
|
||||
{
|
||||
m_GlassColor = glassColor;
|
||||
m_GlassAlpha = glassAlpha;
|
||||
}
|
||||
|
||||
void CStaticFx::SetMeter(BOOL bMeter, double meterRatio)
|
||||
{
|
||||
m_bMeter = bMeter;
|
||||
if (meterRatio > 1.0)
|
||||
{
|
||||
m_MeterRatio = 1.0;
|
||||
}
|
||||
else if (meterRatio > 0)
|
||||
{
|
||||
m_MeterRatio = meterRatio;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_MeterRatio = 0.0;
|
||||
}
|
||||
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
void CStaticFx::SetLabelUnit(CString label, CString unit)
|
||||
{
|
||||
m_Label = label;
|
||||
m_Unit = unit;
|
||||
}
|
||||
|
||||
void CStaticFx::SetLabelUnitFormat(UINT labelFormat, UINT unitFormat)
|
||||
{
|
||||
m_LabelFormat = labelFormat;
|
||||
m_UnitFormat = unitFormat;
|
||||
}
|
||||
|
||||
void CStaticFx::SetTextFormat(UINT format)
|
||||
{
|
||||
m_TextFormat = format;
|
||||
}
|
||||
|
||||
//------------------------------------------------
|
||||
// Draw Control
|
||||
//------------------------------------------------
|
||||
|
||||
void CStaticFx::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
|
||||
{
|
||||
CDC* drawDC = CDC::FromHandle(lpDrawItemStruct->hDC);
|
||||
LoadCtrlBk(drawDC);
|
||||
|
||||
DrawControl(drawDC, lpDrawItemStruct, m_CtrlBitmap, m_BkBitmap, ControlImageNormal);
|
||||
}
|
||||
|
||||
void CStaticFx::DrawControl(CDC* drawDC, LPDRAWITEMSTRUCT lpDrawItemStruct, CBitmap& ctrlBitmap, CBitmap& bkBitmap, int no)
|
||||
{
|
||||
CDC* pMemDC = new CDC;
|
||||
CBitmap* pOldMemBitmap;
|
||||
if(m_hPal && drawDC->GetDeviceCaps(RASTERCAPS) & RC_PALETTE)
|
||||
{
|
||||
SelectPalette( drawDC->GetSafeHdc(), m_hPal, FALSE );
|
||||
drawDC->RealizePalette();
|
||||
drawDC->SetStretchBltMode(HALFTONE);
|
||||
}
|
||||
pMemDC->CreateCompatibleDC(drawDC);
|
||||
if(m_hPal && pMemDC->GetDeviceCaps(RASTERCAPS) & RC_PALETTE)
|
||||
{
|
||||
SelectPalette( pMemDC->GetSafeHdc(), m_hPal, FALSE );
|
||||
pMemDC->RealizePalette();
|
||||
pMemDC->SetStretchBltMode(HALFTONE);
|
||||
}
|
||||
pOldMemBitmap = pMemDC->SelectObject(&ctrlBitmap);
|
||||
CDC* pBkDC = new CDC;
|
||||
CBitmap* pOldBkBitmap;
|
||||
pBkDC->CreateCompatibleDC(drawDC);
|
||||
if(m_hPal && pBkDC->GetDeviceCaps(RASTERCAPS) & RC_PALETTE)
|
||||
{
|
||||
SelectPalette( pBkDC->GetSafeHdc(), m_hPal, FALSE );
|
||||
pBkDC->RealizePalette();
|
||||
pBkDC->SetStretchBltMode(HALFTONE);
|
||||
}
|
||||
pOldBkBitmap = pBkDC->SelectObject(&bkBitmap);
|
||||
|
||||
CBitmap DrawBmp;
|
||||
DrawBmp.CreateCompatibleBitmap(drawDC, m_CtrlSize.cx, m_CtrlSize.cy);
|
||||
CDC* pDrawBmpDC = new CDC;
|
||||
CBitmap* pOldDrawBitmap;
|
||||
pDrawBmpDC->CreateCompatibleDC(drawDC);
|
||||
if(m_hPal && pDrawBmpDC->GetDeviceCaps(RASTERCAPS) & RC_PALETTE)
|
||||
{
|
||||
SelectPalette( pDrawBmpDC->GetSafeHdc(), m_hPal, FALSE );
|
||||
pDrawBmpDC->RealizePalette();
|
||||
pDrawBmpDC->SetStretchBltMode(HALFTONE);
|
||||
}
|
||||
pOldDrawBitmap = pDrawBmpDC->SelectObject(&DrawBmp);
|
||||
|
||||
int color = drawDC->GetDeviceCaps(BITSPIXEL) * drawDC->GetDeviceCaps(PLANES);
|
||||
|
||||
if (!m_CtrlImage.IsNull())
|
||||
{
|
||||
if (m_CtrlImage.GetBPP() == 32)
|
||||
{
|
||||
CBitmap* bk32Bitmap;
|
||||
CImage bk32Image;
|
||||
if (color == 32)
|
||||
{
|
||||
bk32Bitmap = &bkBitmap;
|
||||
}
|
||||
else
|
||||
{
|
||||
bk32Image.Create(m_CtrlSize.cx, m_CtrlSize.cy, 32);
|
||||
::StretchBlt(bk32Image.GetDC(), 0, 0, m_CtrlSize.cx, m_CtrlSize.cy, *pBkDC, 0, 0, m_CtrlSize.cx, m_CtrlSize.cy, SRCCOPY);
|
||||
bk32Bitmap = CBitmap::FromHandle((HBITMAP)bk32Image);
|
||||
}
|
||||
|
||||
BITMAP CtlBmpInfo, DstBmpInfo;
|
||||
bk32Bitmap->GetBitmap(&DstBmpInfo);
|
||||
DWORD DstLineBytes = DstBmpInfo.bmWidthBytes;
|
||||
DWORD DstMemSize = DstLineBytes * DstBmpInfo.bmHeight;
|
||||
ctrlBitmap.GetBitmap(&CtlBmpInfo);
|
||||
DWORD CtlLineBytes = CtlBmpInfo.bmWidthBytes;
|
||||
DWORD CtlMemSize = CtlLineBytes * CtlBmpInfo.bmHeight;
|
||||
|
||||
if ((DstBmpInfo.bmWidthBytes != CtlBmpInfo.bmWidthBytes)
|
||||
|| (DstBmpInfo.bmHeight != CtlBmpInfo.bmHeight / m_ImageCount))
|
||||
{
|
||||
// Error Check //
|
||||
}
|
||||
else
|
||||
{
|
||||
BYTE* DstBuffer = new BYTE[DstMemSize];
|
||||
bk32Bitmap->GetBitmapBits(DstMemSize, DstBuffer);
|
||||
BYTE* CtlBuffer = new BYTE[CtlMemSize];
|
||||
ctrlBitmap.GetBitmapBits(CtlMemSize, CtlBuffer);
|
||||
|
||||
if (m_bMeter)
|
||||
{
|
||||
int meter = (int)(m_CtrlSize.cx * m_MeterRatio);
|
||||
int baseY;
|
||||
baseY = m_CtrlSize.cy;
|
||||
for (LONG py = 0; py < DstBmpInfo.bmHeight; py++)
|
||||
{
|
||||
int dn = py * DstLineBytes;
|
||||
int cn = (baseY + py) * CtlLineBytes;
|
||||
for (LONG px = 0; px < meter; px++)
|
||||
{
|
||||
BYTE a = CtlBuffer[cn + 3];
|
||||
BYTE na = 255 - a;
|
||||
DstBuffer[dn + 0] = (BYTE)((CtlBuffer[cn + 0] * a + DstBuffer[dn + 0] * na) / 255);
|
||||
DstBuffer[dn + 1] = (BYTE)((CtlBuffer[cn + 1] * a + DstBuffer[dn + 1] * na) / 255);
|
||||
DstBuffer[dn + 2] = (BYTE)((CtlBuffer[cn + 2] * a + DstBuffer[dn + 2] * na) / 255);
|
||||
DstBuffer[dn + 3] = 255;
|
||||
dn += (DstBmpInfo.bmBitsPixel / 8);
|
||||
cn += (CtlBmpInfo.bmBitsPixel / 8);
|
||||
}
|
||||
cn -= baseY * CtlLineBytes;
|
||||
for (LONG px = meter; px < DstBmpInfo.bmWidth; px++)
|
||||
{
|
||||
BYTE a = CtlBuffer[cn + 3];
|
||||
BYTE na = 255 - a;
|
||||
DstBuffer[dn + 0] = (BYTE)((CtlBuffer[cn + 0] * a + DstBuffer[dn + 0] * na) / 255);
|
||||
DstBuffer[dn + 1] = (BYTE)((CtlBuffer[cn + 1] * a + DstBuffer[dn + 1] * na) / 255);
|
||||
DstBuffer[dn + 2] = (BYTE)((CtlBuffer[cn + 2] * a + DstBuffer[dn + 2] * na) / 255);
|
||||
DstBuffer[dn + 3] = 255;
|
||||
dn += (DstBmpInfo.bmBitsPixel / 8);
|
||||
cn += (CtlBmpInfo.bmBitsPixel / 8);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int baseY = m_CtrlSize.cy * no;
|
||||
for (LONG py = 0; py < DstBmpInfo.bmHeight; py++)
|
||||
{
|
||||
int dn = py * DstLineBytes;
|
||||
int cn = (baseY + py) * CtlLineBytes;
|
||||
for (LONG px = 0; px < DstBmpInfo.bmWidth; px++)
|
||||
{
|
||||
#if _MSC_VER > 1310
|
||||
#pragma warning( disable : 6385 )
|
||||
#pragma warning( disable : 6386 )
|
||||
#endif
|
||||
BYTE a = CtlBuffer[cn + 3];
|
||||
BYTE na = 255 - a;
|
||||
DstBuffer[dn + 0] = (BYTE)((CtlBuffer[cn + 0] * a + DstBuffer[dn + 0] * na) / 255);
|
||||
DstBuffer[dn + 1] = (BYTE)((CtlBuffer[cn + 1] * a + DstBuffer[dn + 1] * na) / 255);
|
||||
DstBuffer[dn + 2] = (BYTE)((CtlBuffer[cn + 2] * a + DstBuffer[dn + 2] * na) / 255);
|
||||
DstBuffer[dn + 3] = 255;
|
||||
dn += (DstBmpInfo.bmBitsPixel / 8);
|
||||
cn += (CtlBmpInfo.bmBitsPixel / 8);
|
||||
#if _MSC_VER > 1310
|
||||
#pragma warning( default : 6386 )
|
||||
#pragma warning( default : 6385 )
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (color == 32)
|
||||
{
|
||||
DrawBmp.SetBitmapBits(DstMemSize, DstBuffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
bk32Bitmap->SetBitmapBits(DstMemSize, DstBuffer);
|
||||
::StretchBlt(pDrawBmpDC->GetSafeHdc(), 0, 0, m_CtrlSize.cx, m_CtrlSize.cy, bk32Image.GetDC(), 0, 0, m_CtrlSize.cx, m_CtrlSize.cy, SRCCOPY);
|
||||
bk32Image.ReleaseDC();
|
||||
}
|
||||
DrawString(pDrawBmpDC, lpDrawItemStruct);
|
||||
drawDC->StretchBlt(0, 0, m_CtrlSize.cx, m_CtrlSize.cy, pDrawBmpDC, 0, 0, m_CtrlSize.cx, m_CtrlSize.cy, SRCCOPY);
|
||||
|
||||
delete[] DstBuffer;
|
||||
delete[] CtlBuffer;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_bMeter)
|
||||
{
|
||||
int meter = (int)(m_CtrlSize.cx * (m_MeterRatio));
|
||||
pDrawBmpDC->StretchBlt(meter, 0, m_CtrlSize.cx - meter, m_CtrlSize.cy, pMemDC, meter, m_CtrlSize.cy * 0, m_CtrlSize.cx - meter, m_CtrlSize.cy, SRCCOPY);
|
||||
pDrawBmpDC->StretchBlt(0, 0, meter, m_CtrlSize.cy, pMemDC, 0, m_CtrlSize.cy * 1, meter, m_CtrlSize.cy, SRCCOPY);
|
||||
DrawString(pDrawBmpDC, lpDrawItemStruct);
|
||||
drawDC->StretchBlt(0, 0, m_CtrlSize.cx, m_CtrlSize.cy, pDrawBmpDC, 0, 0, m_CtrlSize.cx, m_CtrlSize.cy, SRCCOPY);
|
||||
}
|
||||
else
|
||||
{
|
||||
pDrawBmpDC->StretchBlt(0, 0, m_CtrlSize.cx, m_CtrlSize.cy, pMemDC, 0, m_CtrlSize.cy* no, m_CtrlSize.cx, m_CtrlSize.cy, SRCCOPY);
|
||||
DrawString(pDrawBmpDC, lpDrawItemStruct);
|
||||
drawDC->StretchBlt(0, 0, m_CtrlSize.cx, m_CtrlSize.cy, pDrawBmpDC, 0, 0, m_CtrlSize.cx, m_CtrlSize.cy, SRCCOPY);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pDrawBmpDC->StretchBlt(0, 0, m_CtrlSize.cx, m_CtrlSize.cy, pBkDC, 0, m_CtrlSize.cy* no, m_CtrlSize.cx, m_CtrlSize.cy, SRCCOPY);
|
||||
DrawString(pDrawBmpDC, lpDrawItemStruct);
|
||||
drawDC->StretchBlt(0, 0, m_CtrlSize.cx, m_CtrlSize.cy, pDrawBmpDC, 0, 0, m_CtrlSize.cx, m_CtrlSize.cy, SRCCOPY);
|
||||
}
|
||||
|
||||
|
||||
if (m_DrawFrame == Border::UNDERLINE)
|
||||
{
|
||||
HGDIOBJ oldPen;
|
||||
POINT point;
|
||||
CPen pen1;
|
||||
COLORREF frameColor;
|
||||
if (m_bDarkMode){frameColor = RGB(0x29, 0x2B, 0x2F);} // Windows 11 color
|
||||
else{ frameColor = RGB(0xCC, 0xCC, 0xCC);}
|
||||
pen1.CreatePen(PS_SOLID, 1, frameColor);
|
||||
|
||||
oldPen = SelectObject(drawDC->m_hDC, pen1);
|
||||
MoveToEx(drawDC->m_hDC, 0, m_CtrlSize.cy - 1, &point);
|
||||
LineTo(drawDC->m_hDC, m_CtrlSize.cx - 1, m_CtrlSize.cy - 1);
|
||||
LineTo(drawDC->m_hDC, 0, m_CtrlSize.cy - 1);
|
||||
SelectObject(drawDC->m_hDC, oldPen);
|
||||
|
||||
pen1.DeleteObject();
|
||||
}
|
||||
else if (m_DrawFrame)
|
||||
{
|
||||
HGDIOBJ oldPen;
|
||||
POINT point;
|
||||
CPen pen1; pen1.CreatePen(PS_SOLID, 1, RGB(0xF8, 0xF8, 0xF8));
|
||||
CPen pen2; pen2.CreatePen(PS_SOLID, 1, RGB(0x98, 0x98, 0x98));
|
||||
|
||||
oldPen = SelectObject(drawDC->m_hDC, pen1);
|
||||
MoveToEx(drawDC->m_hDC, 0, m_CtrlSize.cy - 1, &point);
|
||||
LineTo(drawDC->m_hDC, m_CtrlSize.cx - 1, m_CtrlSize.cy - 1);
|
||||
LineTo(drawDC->m_hDC, m_CtrlSize.cx - 1, 0);
|
||||
LineTo(drawDC->m_hDC, m_CtrlSize.cx - 1, m_CtrlSize.cy - 1);
|
||||
SelectObject(drawDC->m_hDC, pen2);
|
||||
MoveToEx(drawDC->m_hDC, 0, m_CtrlSize.cy - 2, &point);
|
||||
LineTo(drawDC->m_hDC, 0, 0);
|
||||
LineTo(drawDC->m_hDC, m_CtrlSize.cx - 1, 0);
|
||||
SelectObject(drawDC->m_hDC, oldPen);
|
||||
|
||||
pen1.DeleteObject();
|
||||
pen2.DeleteObject();
|
||||
}
|
||||
|
||||
pDrawBmpDC->SelectObject(&pOldDrawBitmap);
|
||||
pDrawBmpDC->DeleteDC();
|
||||
delete pDrawBmpDC;
|
||||
pMemDC->SelectObject(&pOldMemBitmap);
|
||||
pMemDC->DeleteDC();
|
||||
delete pMemDC;
|
||||
pBkDC->SelectObject(&pOldBkBitmap);
|
||||
pBkDC->DeleteDC();
|
||||
delete pBkDC;
|
||||
|
||||
if (m_bDrawFrameEx)
|
||||
{
|
||||
CBrush brush;
|
||||
brush.CreateSolidBrush(m_FrameColor);
|
||||
drawDC->FrameRect(&(lpDrawItemStruct->rcItem), &brush);
|
||||
brush.DeleteObject();
|
||||
}
|
||||
}
|
||||
|
||||
void CStaticFx::DrawString(CDC* drawDC, LPDRAWITEMSTRUCT lpDrawItemStruct)
|
||||
{
|
||||
CString title;
|
||||
GetWindowText(title);
|
||||
|
||||
if (title.IsEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
drawDC->SetBkMode(TRANSPARENT);
|
||||
CRect rect = (CRect)(lpDrawItemStruct->rcItem);
|
||||
CRect rectControl = (CRect)(lpDrawItemStruct->rcItem);
|
||||
rect.top += m_Margin.top;
|
||||
rect.left += m_Margin.left;
|
||||
rect.bottom -= m_Margin.bottom;
|
||||
rect.right -= m_Margin.right;
|
||||
|
||||
CRect rectI;
|
||||
CSize extent;
|
||||
HGDIOBJ oldFont = drawDC->SelectObject(m_Font);
|
||||
if ((m_RenderMode & OwnerDrawTransparent) && m_bDarkMode)
|
||||
{
|
||||
SetTextColor(drawDC->m_hDC, RGB(255, 255, 255));
|
||||
}
|
||||
else
|
||||
{
|
||||
SetTextColor(drawDC->m_hDC, m_TextColor);
|
||||
}
|
||||
extent = drawDC->GetTextExtent(title);
|
||||
|
||||
if (m_bMeter && rect.Width() < extent.cx)
|
||||
{
|
||||
title.Replace(_T(","), _T("."));
|
||||
int score = _tstoi((LPCTSTR)title);
|
||||
title.Format(_T("%d"), score);
|
||||
extent = drawDC->GetTextExtent(title);
|
||||
}
|
||||
|
||||
if (m_TextFormat != 0)
|
||||
{
|
||||
drawDC->DrawText(title, title.GetLength(), rect, m_TextFormat);
|
||||
drawDC->SelectObject(oldFont);
|
||||
|
||||
oldFont = drawDC->SelectObject(m_FontToolTip);
|
||||
drawDC->DrawText(m_Label, m_Label.GetLength(), rect, m_LabelFormat);
|
||||
drawDC->DrawText(m_Unit, m_Unit.GetLength(), rect, m_UnitFormat);
|
||||
}
|
||||
else if (!m_Label.IsEmpty())
|
||||
{
|
||||
drawDC->DrawText(title, title.GetLength(), rect, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
|
||||
drawDC->SelectObject(oldFont);
|
||||
|
||||
oldFont = drawDC->SelectObject(m_FontToolTip);
|
||||
drawDC->DrawText(m_Label, m_Label.GetLength(), rect, m_LabelFormat);
|
||||
drawDC->DrawText(m_Unit, m_Unit.GetLength(), rect, m_UnitFormat);
|
||||
}
|
||||
else if (m_TextAlign == SS_LEFT)
|
||||
{
|
||||
drawDC->DrawText(title, title.GetLength(), rect, DT_LEFT | DT_VCENTER | DT_SINGLELINE);
|
||||
}
|
||||
else if (m_TextAlign == SS_RIGHT)
|
||||
{
|
||||
drawDC->DrawText(title, title.GetLength(), rect, DT_RIGHT | DT_VCENTER | DT_SINGLELINE);
|
||||
}
|
||||
else
|
||||
{
|
||||
drawDC->DrawText(title, title.GetLength(), rect, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
|
||||
}
|
||||
|
||||
drawDC->SelectObject(oldFont);
|
||||
}
|
||||
|
||||
//------------------------------------------------
|
||||
// Image
|
||||
//------------------------------------------------
|
||||
|
||||
BOOL CStaticFx::LoadBitmap(LPCTSTR fileName)
|
||||
{
|
||||
if (m_bHighContrast) { return FALSE; }
|
||||
if (fileName == NULL) { return FALSE; }
|
||||
|
||||
m_CtrlImage.Destroy();
|
||||
m_CtrlImage.Load(fileName);
|
||||
if (m_CtrlImage.IsNull()) { return FALSE; }
|
||||
|
||||
return LoadBitmap((HBITMAP)m_CtrlImage);
|
||||
}
|
||||
|
||||
BOOL CStaticFx::LoadBitmap(HBITMAP hBitmap)
|
||||
{
|
||||
if (m_bHighContrast) { return FALSE; }
|
||||
|
||||
m_CtrlBitmap.Detach();
|
||||
m_CtrlBitmap.Attach(hBitmap);
|
||||
|
||||
return SetBitmap(m_CtrlBitmap);
|
||||
}
|
||||
|
||||
void CStaticFx::SetBkReload(void)
|
||||
{
|
||||
m_bBkBitmapInit = FALSE;
|
||||
m_bBkLoad = FALSE;
|
||||
}
|
||||
|
||||
BOOL CStaticFx::SetBitmap(CBitmap& bitmap)
|
||||
{
|
||||
if (m_bHighContrast) { return FALSE; }
|
||||
|
||||
BITMAP bitmapInfo;
|
||||
bitmap.GetBitmap(&bitmapInfo);
|
||||
if (m_CtrlSize.cx != bitmapInfo.bmWidth
|
||||
|| m_CtrlSize.cy != bitmapInfo.bmHeight / m_ImageCount)
|
||||
{
|
||||
ModifyStyle(SS_OWNERDRAW, 0);
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
ModifyStyle(0, SS_OWNERDRAW);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
void CStaticFx::LoadCtrlBk(CDC* drawDC)
|
||||
{
|
||||
if (m_bHighContrast) { SetBkReload(); return; }
|
||||
|
||||
if (m_BkBitmap.m_hObject != NULL)
|
||||
{
|
||||
BITMAP bitmapInfo;
|
||||
m_BkBitmap.GetBitmap(&bitmapInfo);
|
||||
if (bitmapInfo.bmBitsPixel != drawDC->GetDeviceCaps(BITSPIXEL))
|
||||
{
|
||||
SetBkReload();
|
||||
}
|
||||
}
|
||||
|
||||
if (&m_CtrlBitmap != NULL)
|
||||
{
|
||||
if (!m_bBkBitmapInit)
|
||||
{
|
||||
m_BkBitmap.DeleteObject();
|
||||
m_BkBitmap.CreateCompatibleBitmap(drawDC, m_CtrlSize.cx, m_CtrlSize.cy);
|
||||
m_bBkBitmapInit = TRUE;
|
||||
}
|
||||
|
||||
if (!m_bBkLoad)
|
||||
{
|
||||
CBitmap* pOldBitmap;
|
||||
CDC* pMemDC = new CDC;
|
||||
pMemDC->CreateCompatibleDC(drawDC);
|
||||
pOldBitmap = pMemDC->SelectObject(&m_BkBitmap);
|
||||
pMemDC->StretchBlt(0, 0, m_CtrlSize.cx, m_CtrlSize.cy, m_BkDC, m_X, m_Y, m_CtrlSize.cx, m_CtrlSize.cy, SRCCOPY);
|
||||
pMemDC->SelectObject(pOldBitmap);
|
||||
pMemDC->DeleteDC();
|
||||
delete pMemDC;
|
||||
m_bBkLoad = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------
|
||||
// Font
|
||||
//------------------------------------------------
|
||||
|
||||
void CStaticFx::SetFontEx(CString face, int size, int sizeToolTip, double zoomRatio, double fontRatio,
|
||||
COLORREF textColor, LONG fontWeight, BYTE fontRender)
|
||||
{
|
||||
LOGFONT logFont = { 0 };
|
||||
logFont.lfCharSet = DEFAULT_CHARSET;
|
||||
logFont.lfHeight = (LONG)(-1 * size * zoomRatio * fontRatio);
|
||||
logFont.lfQuality = fontRender;
|
||||
logFont.lfWeight = fontWeight;
|
||||
if (face.GetLength() < 32)
|
||||
{
|
||||
wsprintf(logFont.lfFaceName, _T("%s"), (LPCTSTR)face);
|
||||
}
|
||||
else
|
||||
{
|
||||
wsprintf(logFont.lfFaceName, _T(""));
|
||||
}
|
||||
|
||||
m_Font.DeleteObject();
|
||||
m_Font.CreateFontIndirect(&logFont);
|
||||
SetFont(&m_Font);
|
||||
|
||||
logFont.lfHeight = (LONG)(-1 * sizeToolTip * zoomRatio * fontRatio);
|
||||
m_FontToolTip.DeleteObject();
|
||||
m_FontToolTip.CreateFontIndirect(&logFont);
|
||||
|
||||
m_TextColor = textColor;
|
||||
|
||||
if (m_ToolTip.m_hWnd != NULL)
|
||||
{
|
||||
m_ToolTip.SetFont(&m_FontToolTip);
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------
|
||||
// Mouse
|
||||
//------------------------------------------------
|
||||
|
||||
void CStaticFx::SetHandCursor(BOOL bHandCuror)
|
||||
{
|
||||
m_bHandCursor = bHandCuror;
|
||||
}
|
||||
|
||||
void CStaticFx::OnMouseMove(UINT nFlags, CPoint point)
|
||||
{
|
||||
#if _MSC_VER <= 1310
|
||||
typedef BOOL(WINAPI* Func_TrackMouseEvent)(LPTRACKMOUSEEVENT);
|
||||
static Func_TrackMouseEvent p_TrackMouseEvent = NULL;
|
||||
static BOOL bInit_TrackMouseEvent = FALSE;
|
||||
|
||||
if (bInit_TrackMouseEvent && p_TrackMouseEvent == NULL)
|
||||
{
|
||||
return; // TrackMouseEvent is not available
|
||||
}
|
||||
else
|
||||
{
|
||||
HMODULE hModule = GetModuleHandle(_T("user32.dll"));
|
||||
if (hModule)
|
||||
{
|
||||
p_TrackMouseEvent = (Func_TrackMouseEvent)GetProcAddress(hModule, "TrackMouseEvent");
|
||||
}
|
||||
}
|
||||
|
||||
if (p_TrackMouseEvent != NULL)
|
||||
{
|
||||
TRACKMOUSEEVENT tme = { sizeof(TRACKMOUSEEVENT) };
|
||||
tme.hwndTrack = m_hWnd;
|
||||
tme.dwFlags = TME_LEAVE | TME_HOVER;
|
||||
tme.dwHoverTime = 1;
|
||||
m_bTrackingNow = p_TrackMouseEvent(&tme);
|
||||
}
|
||||
bInit_TrackMouseEvent = TRUE;
|
||||
#else
|
||||
if (!m_bTrackingNow)
|
||||
{
|
||||
TRACKMOUSEEVENT tme = { sizeof(TRACKMOUSEEVENT) };
|
||||
tme.hwndTrack = m_hWnd;
|
||||
tme.dwFlags = TME_LEAVE | TME_HOVER;
|
||||
tme.dwHoverTime = 1;
|
||||
m_bTrackingNow = _TrackMouseEvent(&tme);
|
||||
}
|
||||
#endif
|
||||
|
||||
CStatic::OnMouseMove(nFlags, point);
|
||||
}
|
||||
|
||||
void CStaticFx::OnMouseHover(UINT nFlags, CPoint point)
|
||||
{
|
||||
#if _MSC_VER > 1310
|
||||
CStatic::OnMouseHover(nFlags, point);
|
||||
#endif
|
||||
|
||||
m_bHover = TRUE;
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
void CStaticFx::OnMouseLeave()
|
||||
{
|
||||
#if _MSC_VER > 1310
|
||||
CStatic::OnMouseLeave();
|
||||
#endif
|
||||
|
||||
m_bTrackingNow = FALSE;
|
||||
m_bHover = FALSE;
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
void CStaticFx::OnSetfocus()
|
||||
{
|
||||
m_bFocas = TRUE;
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
void CStaticFx::OnKillfocus()
|
||||
{
|
||||
m_bFocas = FALSE;
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
BOOL CStaticFx::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
|
||||
{
|
||||
HCURSOR hCursor = NULL;
|
||||
if (m_bHandCursor)
|
||||
{
|
||||
hCursor = AfxGetApp()->LoadStandardCursor(IDC_HAND);
|
||||
if (hCursor)
|
||||
{
|
||||
::SetCursor(hCursor);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
hCursor = AfxGetApp()->LoadStandardCursor(IDC_ARROW);
|
||||
if (hCursor)
|
||||
{
|
||||
::SetCursor(hCursor);
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//------------------------------------------------
|
||||
// ToolTip
|
||||
//------------------------------------------------
|
||||
|
||||
void CStaticFx::SetToolTipText(LPCTSTR text)
|
||||
{
|
||||
if (text == NULL) { return; }
|
||||
|
||||
InitToolTip();
|
||||
m_ToolTipText = text;
|
||||
if (m_ToolTip.GetToolCount() == 0)
|
||||
{
|
||||
CRect rect;
|
||||
GetClientRect(rect);
|
||||
m_ToolTip.AddTool(this, m_ToolTipText, rect, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ToolTip.UpdateTipText(m_ToolTipText, this, 1);
|
||||
}
|
||||
|
||||
SetToolTipActivate(TRUE);
|
||||
}
|
||||
|
||||
void CStaticFx::SetToolTipActivate(BOOL bActivate)
|
||||
{
|
||||
if (m_ToolTip.GetToolCount() == 0) { return; }
|
||||
m_ToolTip.Activate(bActivate);
|
||||
}
|
||||
|
||||
void CStaticFx::SetToolTipWindowText(LPCTSTR pText)
|
||||
{
|
||||
SetToolTipText(pText);
|
||||
SetWindowText(pText);
|
||||
}
|
||||
|
||||
CString CStaticFx::GetToolTipText()
|
||||
{
|
||||
return m_ToolTipText;
|
||||
}
|
||||
|
||||
void CStaticFx::InitToolTip()
|
||||
{
|
||||
if (m_ToolTip.m_hWnd == NULL)
|
||||
{
|
||||
m_ToolTip.Create(this, TTS_ALWAYSTIP | TTS_BALLOON | TTS_NOANIMATE | TTS_NOFADE);
|
||||
m_ToolTip.Activate(FALSE);
|
||||
m_ToolTip.SetFont(&m_FontToolTip);
|
||||
m_ToolTip.SendMessage(TTM_SETMAXTIPWIDTH, 0, 1024);
|
||||
m_ToolTip.SetDelayTime(TTDT_AUTOPOP, 8000);
|
||||
m_ToolTip.SetDelayTime(TTDT_INITIAL, 500);
|
||||
m_ToolTip.SetDelayTime(TTDT_RESHOW, 100);
|
||||
}
|
||||
}
|
||||
|
||||
BOOL CStaticFx::PreTranslateMessage(MSG* pMsg)
|
||||
{
|
||||
InitToolTip();
|
||||
m_ToolTip.RelayEvent(pMsg);
|
||||
|
||||
return CStatic::PreTranslateMessage(pMsg);
|
||||
}
|
||||
|
||||
BOOL CStaticFx::OnEraseBkgnd(CDC* pDC)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
/*---------------------------------------------------------------------------*/
|
||||
// Author : hiyohiyo
|
||||
// Mail : hiyohiyo@crystalmark.info
|
||||
// Web : https://crystalmark.info/
|
||||
// License : MIT License
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ImageFx.h"
|
||||
|
||||
class CStaticFx : public CStatic
|
||||
{
|
||||
DECLARE_DYNAMIC(CStaticFx);
|
||||
|
||||
enum Border
|
||||
{
|
||||
NO_BORDER = 0, // FALSE
|
||||
SYSTEM_BORDER = 1, // TRUE
|
||||
UNDERLINE = 2,
|
||||
};
|
||||
|
||||
public:
|
||||
// Constructors
|
||||
CStaticFx();
|
||||
virtual ~CStaticFx();
|
||||
|
||||
// Control
|
||||
BOOL InitControl(int x, int y, int width, int height, double zoomRatio, HPALETTE hPal, CDC* bkDC,
|
||||
LPCTSTR imagePath, int imageCount, DWORD textAlign, int renderMode, BOOL bHighContrast, BOOL bDarkMode, DWORD drawFrame);
|
||||
void SetMargin(int top, int left, int bottom, int right, double zoomRatio);
|
||||
CSize GetSize(void);
|
||||
void SetDrawFrame(BOOL bDrawFrame);
|
||||
void SetDrawFrameEx(BOOL bDrawFrame, COLORREF frameColor = RGB(128, 128, 128));
|
||||
void SetGlassColor(COLORREF glassColor, BYTE glassAlpha);
|
||||
void SetMeter(BOOL bMeter, double meterRatio);
|
||||
void SetLabelUnit(CString label, CString unit);
|
||||
void SetLabelUnitFormat(UINT labelFormat, UINT unitFormat);
|
||||
void SetTextFormat(UINT format);
|
||||
|
||||
// Font
|
||||
void SetFontEx(CString face, int size, int sizeToolTip, double zoomRatio, double fontRatio = 1.0,
|
||||
COLORREF textColor = RGB(0, 0, 0), LONG fontWeight = FW_NORMAL, BYTE fontRender = CLEARTYPE_NATURAL_QUALITY);
|
||||
|
||||
// ToolTip
|
||||
void SetToolTipText(LPCTSTR pText);
|
||||
void SetToolTipActivate(BOOL bActivate = TRUE);
|
||||
void SetToolTipWindowText(LPCTSTR pText);
|
||||
CString GetToolTipText();
|
||||
|
||||
// Mouse
|
||||
void SetHandCursor(BOOL bHandCuror = TRUE);
|
||||
|
||||
protected:
|
||||
// Draw Control
|
||||
virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
|
||||
virtual void DrawControl(CDC* drawDC, LPDRAWITEMSTRUCT lpDrawItemStruct, CBitmap& ctrlBitmap, CBitmap& bkBitmap, int no);
|
||||
virtual void DrawString(CDC* drawDC, LPDRAWITEMSTRUCT lpDrawItemStruct);
|
||||
|
||||
// Image
|
||||
BOOL LoadBitmap(LPCTSTR fileName);
|
||||
BOOL LoadBitmap(HBITMAP hBitmap);
|
||||
void SetBkReload(void);
|
||||
BOOL SetBitmap(CBitmap& bitmap);
|
||||
void LoadCtrlBk(CDC* drawDC);
|
||||
|
||||
// ToolTip
|
||||
void InitToolTip();
|
||||
virtual BOOL PreTranslateMessage(MSG* pMsg);
|
||||
|
||||
// Message Map
|
||||
DECLARE_MESSAGE_MAP()
|
||||
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
|
||||
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
|
||||
afx_msg void OnMouseHover(UINT nFlags, CPoint point);
|
||||
afx_msg void OnMouseLeave();
|
||||
afx_msg void OnKillfocus();
|
||||
afx_msg void OnSetfocus();
|
||||
afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);
|
||||
|
||||
protected:
|
||||
// Control
|
||||
int m_X;
|
||||
int m_Y;
|
||||
CSize m_CtrlSize;
|
||||
CRect m_Margin;
|
||||
int m_RenderMode;
|
||||
BOOL m_bHighContrast;
|
||||
BOOL m_bDarkMode;
|
||||
DWORD m_DrawFrame;
|
||||
BOOL m_bDrawFrameEx;
|
||||
COLORREF m_FrameColor;
|
||||
HPALETTE m_hPal;
|
||||
|
||||
CString m_Label;
|
||||
CString m_Unit;
|
||||
|
||||
UINT m_TextFormat;
|
||||
UINT m_LabelFormat;
|
||||
UINT m_UnitFormat;
|
||||
|
||||
// Glass
|
||||
COLORREF m_GlassColor;
|
||||
BYTE m_GlassAlpha;
|
||||
|
||||
// Meter
|
||||
BOOL m_bMeter;
|
||||
double m_MeterRatio;
|
||||
|
||||
// Image
|
||||
CString m_ImagePath;
|
||||
int m_ImageCount;
|
||||
CDC* m_BkDC;
|
||||
CBitmap m_BkBitmap;
|
||||
BOOL m_bBkBitmapInit;
|
||||
BOOL m_bBkLoad;
|
||||
CBitmap m_CtrlBitmap;
|
||||
CImage m_CtrlImage;
|
||||
|
||||
// Font
|
||||
DWORD m_TextAlign;
|
||||
CFont m_Font;
|
||||
CFont m_FontToolTip;
|
||||
COLORREF m_TextColor;
|
||||
|
||||
// ToolTip
|
||||
CToolTipCtrl m_ToolTip;
|
||||
CString m_ToolTipText;
|
||||
|
||||
// Mouse
|
||||
BOOL m_bHover;
|
||||
BOOL m_bFocas;
|
||||
BOOL m_bTrackingNow;
|
||||
BOOL m_bHandCursor;
|
||||
};
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,30 @@
|
||||
/*---------------------------------------------------------------------------*/
|
||||
// Author : hiyohiyo
|
||||
// Mail : hiyohiyo@crystalmark.info
|
||||
// Web : https://crystalmark.info/
|
||||
// License : MIT License
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
//------------------------------------------------
|
||||
// System Info
|
||||
//------------------------------------------------
|
||||
|
||||
void GetCpuInfo(CString& cpuInfo, CString& cpuName, int* clock, int* cores, int* threads);
|
||||
void GetGpuInfo(CString& gpuInfo);
|
||||
void GetBaseBoardInfo(CString& baseBoardInfo);
|
||||
void GetComputerSystemInfo(CString& computerSystemInfo);
|
||||
void GetScreenInfo(CString& screenInfo, int* width, int* height, int* color, CString& smoothing);
|
||||
void GetMemoryInfo(CString& screenInfo, int* size = NULL);
|
||||
|
||||
#if defined(_M_IX86) || defined(_M_X64)
|
||||
void GetCpuid(unsigned int param, unsigned int* _eax, unsigned int* _ebx, unsigned int* _ecx, unsigned int* _edx);
|
||||
void GetHypervisorVendorString(char* vendorString);
|
||||
#endif
|
||||
|
||||
#if _MSC_VER <= 1310
|
||||
/// https://www.betaarchive.com/wiki/index.php/Microsoft_KB_Archive/124207
|
||||
BOOL IsCoProcessorPresent();
|
||||
BOOL IsFMTOWNS();
|
||||
#endif
|
||||
@@ -0,0 +1,205 @@
|
||||
/*---------------------------------------------------------------------------*/
|
||||
// Author : adzm
|
||||
// Web : https://github.com/adzm/win32-custom-menubar-aero-theme
|
||||
// License : MIT License
|
||||
// https://github.com/adzm/win32-custom-menubar-aero-theme/blob/main/LICENSE
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "stdafx.h"
|
||||
#include <Uxtheme.h>
|
||||
#include <vsstyle.h>
|
||||
#include "UAHMenuBar.h"
|
||||
|
||||
#pragma comment(lib, "uxtheme.lib")
|
||||
|
||||
static HTHEME g_menuTheme = nullptr;
|
||||
extern bool g_darkModeEnabled;
|
||||
|
||||
// ugly colors for illustration purposes
|
||||
static HBRUSH g_brBarBackground = CreateSolidBrush(RGB(0x2C, 0x2C, 0x2C));
|
||||
|
||||
void UAHDrawMenuNCBottomLine(HWND hWnd)
|
||||
{
|
||||
MENUBARINFO mbi = { sizeof(mbi) };
|
||||
if (!GetMenuBarInfo(hWnd, OBJID_MENU, 0, &mbi))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
RECT rcClient = { 0 };
|
||||
GetClientRect(hWnd, &rcClient);
|
||||
MapWindowPoints(hWnd, nullptr, (POINT*)&rcClient, 2);
|
||||
|
||||
RECT rcWindow = { 0 };
|
||||
GetWindowRect(hWnd, &rcWindow);
|
||||
|
||||
OffsetRect(&rcClient, -rcWindow.left, -rcWindow.top);
|
||||
|
||||
// the rcBar is offset by the window rect
|
||||
RECT rcAnnoyingLine = rcClient;
|
||||
rcAnnoyingLine.bottom = rcAnnoyingLine.top;
|
||||
rcAnnoyingLine.top--;
|
||||
|
||||
|
||||
HDC hdc = GetWindowDC(hWnd);
|
||||
FillRect(hdc, &rcAnnoyingLine, g_brBarBackground);
|
||||
ReleaseDC(hWnd, hdc);
|
||||
}
|
||||
|
||||
// processes messages related to UAH / custom menubar drawing.
|
||||
// return true if handled, false to continue with normal processing in your wndproc
|
||||
bool UAHWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, LRESULT* lr)
|
||||
{
|
||||
if (! g_darkModeEnabled)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (message)
|
||||
{
|
||||
case WM_UAHDRAWMENU:
|
||||
{
|
||||
UAHMENU* pUDM = (UAHMENU*)lParam;
|
||||
RECT rc = { 0 };
|
||||
|
||||
// get the menubar rect
|
||||
{
|
||||
MENUBARINFO mbi = { sizeof(mbi) };
|
||||
GetMenuBarInfo(hWnd, OBJID_MENU, 0, &mbi);
|
||||
|
||||
RECT rcWindow;
|
||||
GetWindowRect(hWnd, &rcWindow);
|
||||
|
||||
// the rcBar is offset by the window rect
|
||||
rc = mbi.rcBar;
|
||||
OffsetRect(&rc, -rcWindow.left, -rcWindow.top);
|
||||
}
|
||||
|
||||
FillRect(pUDM->hdc, &rc, g_brBarBackground);
|
||||
|
||||
return true;
|
||||
}
|
||||
case WM_UAHDRAWMENUITEM:
|
||||
{
|
||||
typedef HRESULT(WINAPI* FuncDrawThemeTextEx)(HTHEME hTheme, HDC hdc,
|
||||
int iPartId, int iStateId, LPCWSTR pszText, int iCharCount, DWORD dwTextFlags,
|
||||
LPRECT pRect, const DTTOPTS* pOptions);
|
||||
|
||||
static bool bInitialized = false;
|
||||
static FuncDrawThemeTextEx pDrawThemeTextEx = NULL;
|
||||
|
||||
if (bInitialized == false)
|
||||
{
|
||||
HMODULE hModule = GetModuleHandle(_T("UxTheme.dll"));
|
||||
if (hModule)
|
||||
{
|
||||
pDrawThemeTextEx = (FuncDrawThemeTextEx)GetProcAddress(hModule, "DrawThemeTextEx");
|
||||
}
|
||||
bInitialized = true;
|
||||
}
|
||||
|
||||
if (pDrawThemeTextEx == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
UAHDRAWMENUITEM* pUDMI = (UAHDRAWMENUITEM*)lParam;
|
||||
|
||||
// ugly colors for illustration purposes
|
||||
static HBRUSH g_brItemBackground = CreateSolidBrush(RGB(0x2C, 0x2C, 0x2C));
|
||||
static HBRUSH g_brItemBackgroundHot = CreateSolidBrush(RGB(0x35, 0x35, 0x35));
|
||||
static HBRUSH g_brItemBackgroundSelected = CreateSolidBrush(RGB(0x35, 0x35, 0x35));
|
||||
|
||||
HBRUSH* pbrBackground = &g_brItemBackground;
|
||||
|
||||
// get the menu item string
|
||||
wchar_t menuString[256] = { 0 };
|
||||
MENUITEMINFO mii = { sizeof(mii), MIIM_STRING };
|
||||
{
|
||||
mii.dwTypeData = menuString;
|
||||
mii.cch = (sizeof(menuString) / 2) - 1;
|
||||
|
||||
GetMenuItemInfo(pUDMI->um.hmenu, pUDMI->umi.iPosition, TRUE, &mii);
|
||||
}
|
||||
|
||||
// get the item state for drawing
|
||||
|
||||
DWORD dwFlags = DT_CENTER | DT_SINGLELINE | DT_VCENTER;
|
||||
|
||||
int iTextStateID = 0;
|
||||
int iBackgroundStateID = 0;
|
||||
{
|
||||
if ((pUDMI->dis.itemState & ODS_INACTIVE) | (pUDMI->dis.itemState & ODS_DEFAULT)) {
|
||||
// normal display
|
||||
iTextStateID = MPI_NORMAL;
|
||||
iBackgroundStateID = MPI_NORMAL;
|
||||
}
|
||||
if (pUDMI->dis.itemState & ODS_HOTLIGHT) {
|
||||
// hot tracking
|
||||
iTextStateID = MPI_HOT;
|
||||
iBackgroundStateID = MPI_HOT;
|
||||
|
||||
pbrBackground = &g_brItemBackgroundHot;
|
||||
}
|
||||
if (pUDMI->dis.itemState & ODS_SELECTED) {
|
||||
// clicked -- MENU_POPUPITEM has no state for this, though MENU_BARITEM does
|
||||
iTextStateID = MPI_HOT;
|
||||
iBackgroundStateID = MPI_HOT;
|
||||
|
||||
pbrBackground = &g_brItemBackgroundSelected;
|
||||
}
|
||||
if ((pUDMI->dis.itemState & ODS_GRAYED) || (pUDMI->dis.itemState & ODS_DISABLED)) {
|
||||
// disabled / grey text
|
||||
iTextStateID = MPI_DISABLED;
|
||||
iBackgroundStateID = MPI_DISABLED;
|
||||
}
|
||||
if (pUDMI->dis.itemState & ODS_NOACCEL) {
|
||||
dwFlags |= DT_HIDEPREFIX;
|
||||
}
|
||||
}
|
||||
|
||||
if (!g_menuTheme) {
|
||||
g_menuTheme = OpenThemeData(hWnd, L"Menu");
|
||||
}
|
||||
|
||||
DTTOPTS opts = { sizeof(opts), DTT_TEXTCOLOR | DTT_COMPOSITED | DTT_GLOWSIZE, RGB(0xFF, 0xFF, 0xFF), iTextStateID != MPI_DISABLED ? RGB(0xFF, 0xFF, 0xFF) : RGB(0xC0, 0xC0, 0xC0) };
|
||||
//opts.dwFlags = ;
|
||||
|
||||
FillRect(pUDMI->um.hdc, &pUDMI->dis.rcItem, *pbrBackground);
|
||||
pDrawThemeTextEx(g_menuTheme, pUDMI->um.hdc, MENU_BARITEM, MBI_NORMAL, menuString, mii.cch, dwFlags, &pUDMI->dis.rcItem, &opts);
|
||||
|
||||
return true;
|
||||
}
|
||||
case WM_UAHMEASUREMENUITEM:
|
||||
{
|
||||
UAHMEASUREMENUITEM* pMmi = (UAHMEASUREMENUITEM*)lParam;
|
||||
|
||||
// allow the default window procedure to handle the message
|
||||
// since we don't really care about changing the width
|
||||
*lr = DefWindowProc(hWnd, message, wParam, lParam);
|
||||
|
||||
// but we can modify it here to make it 1/3rd wider for example
|
||||
//pMmi->mis.itemWidth = (pMmi->mis.itemWidth * 5) / 4;
|
||||
|
||||
return true;
|
||||
}
|
||||
case WM_THEMECHANGED:
|
||||
{
|
||||
if (g_menuTheme) {
|
||||
CloseThemeData(g_menuTheme);
|
||||
g_menuTheme = nullptr;
|
||||
}
|
||||
// continue processing in main wndproc
|
||||
return false;
|
||||
}
|
||||
case WM_NCPAINT:
|
||||
case WM_NCACTIVATE:
|
||||
*lr = DefWindowProc(hWnd, message, wParam, lParam);
|
||||
UAHDrawMenuNCBottomLine(hWnd);
|
||||
return true;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
/*---------------------------------------------------------------------------*/
|
||||
// Author : adzm
|
||||
// Web : https://github.com/adzm/win32-custom-menubar-aero-theme
|
||||
// License : MIT License
|
||||
// https://github.com/adzm/win32-custom-menubar-aero-theme/blob/main/LICENSE
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
// processes messages related to UAH / custom menubar drawing.
|
||||
// return true if handled, false to continue with normal processing in your wndproc
|
||||
bool UAHWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, LRESULT* lr);
|
||||
|
||||
// window messages related to menu bar drawing
|
||||
#define WM_UAHDESTROYWINDOW 0x0090 // handled by DefWindowProc
|
||||
#define WM_UAHDRAWMENU 0x0091 // lParam is UAHMENU
|
||||
#define WM_UAHDRAWMENUITEM 0x0092 // lParam is UAHDRAWMENUITEM
|
||||
#define WM_UAHINITMENU 0x0093 // handled by DefWindowProc
|
||||
#define WM_UAHMEASUREMENUITEM 0x0094 // lParam is UAHMEASUREMENUITEM
|
||||
#define WM_UAHNCPAINTMENUPOPUP 0x0095 // handled by DefWindowProc
|
||||
|
||||
// describes the sizes of the menu bar or menu item
|
||||
typedef union tagUAHMENUITEMMETRICS
|
||||
{
|
||||
// cx appears to be 14 / 0xE less than rcItem's width!
|
||||
// cy 0x14 seems stable, i wonder if it is 4 less than rcItem's height which is always 24 atm
|
||||
struct {
|
||||
DWORD cx;
|
||||
DWORD cy;
|
||||
} rgsizeBar[2];
|
||||
struct {
|
||||
DWORD cx;
|
||||
DWORD cy;
|
||||
} rgsizePopup[4];
|
||||
} UAHMENUITEMMETRICS;
|
||||
|
||||
// not really used in our case but part of the other structures
|
||||
typedef struct tagUAHMENUPOPUPMETRICS
|
||||
{
|
||||
DWORD rgcx[4];
|
||||
DWORD fUpdateMaxWidths : 2; // from kernel symbols, padded to full dword
|
||||
} UAHMENUPOPUPMETRICS;
|
||||
|
||||
// hmenu is the main window menu; hdc is the context to draw in
|
||||
typedef struct tagUAHMENU
|
||||
{
|
||||
HMENU hmenu;
|
||||
HDC hdc;
|
||||
DWORD dwFlags; // no idea what these mean, in my testing it's either 0x00000a00 or sometimes 0x00000a10
|
||||
} UAHMENU;
|
||||
|
||||
// menu items are always referred to by iPosition here
|
||||
typedef struct tagUAHMENUITEM
|
||||
{
|
||||
int iPosition; // 0-based position of menu item in menubar
|
||||
UAHMENUITEMMETRICS umim;
|
||||
UAHMENUPOPUPMETRICS umpm;
|
||||
} UAHMENUITEM;
|
||||
|
||||
// the DRAWITEMSTRUCT contains the states of the menu items, as well as
|
||||
// the position index of the item in the menu, which is duplicated in
|
||||
// the UAHMENUITEM's iPosition as well
|
||||
typedef struct UAHDRAWMENUITEM
|
||||
{
|
||||
DRAWITEMSTRUCT dis; // itemID looks uninitialized
|
||||
UAHMENU um;
|
||||
UAHMENUITEM umi;
|
||||
} UAHDRAWMENUITEM;
|
||||
|
||||
// the MEASUREITEMSTRUCT is intended to be filled with the size of the item
|
||||
// height appears to be ignored, but width can be modified
|
||||
typedef struct tagUAHMEASUREMENUITEM
|
||||
{
|
||||
MEASUREITEMSTRUCT mis;
|
||||
UAHMENU um;
|
||||
UAHMENUITEM umi;
|
||||
} UAHMEASUREMENUITEM;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,143 @@
|
||||
/*---------------------------------------------------------------------------*/
|
||||
// Author : hiyohiyo
|
||||
// Mail : hiyohiyo@crystalmark.info
|
||||
// Web : https://crystalmark.info/
|
||||
// License : MIT License
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
////------------------------------------------------
|
||||
// Debug
|
||||
////------------------------------------------------
|
||||
|
||||
void SetDebugMode(DWORD mode);
|
||||
void DebugPrint(CString cstr);
|
||||
|
||||
////------------------------------------------------
|
||||
// File Information
|
||||
////------------------------------------------------
|
||||
|
||||
int GetFileVersion(const TCHAR* fileName, TCHAR* version = NULL);
|
||||
void GetFileVersionEx(const TCHAR* file, CString& version);
|
||||
BOOL IsFileExist(const TCHAR* fileName);
|
||||
BOOL CanWriteFile(const TCHAR* fileName);
|
||||
|
||||
////------------------------------------------------
|
||||
// Utility
|
||||
////------------------------------------------------
|
||||
|
||||
ULONGLONG GetTickCountFx();
|
||||
|
||||
ULONG64 B8toB64(BYTE b0, BYTE b1 = 0, BYTE b2 = 0, BYTE b3 = 0, BYTE b4 = 0, BYTE b5 = 0, BYTE b6 = 0, BYTE b7 = 0);
|
||||
DWORD B8toB32(BYTE b0, BYTE b1 = 0, BYTE b2 = 0, BYTE b3 = 0);
|
||||
void SplitCString(const CString& str, const CString& delimiter, CStringArray& arr);
|
||||
|
||||
#if _MSC_VER > 1310
|
||||
// ---------------------------------------------------------
|
||||
// 20260123: Safe for unaligned/page-boundary (Using memcpy for atomic-like MOV) >>>
|
||||
#ifndef NODISCARD
|
||||
#if (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
|
||||
#define NODISCARD [[nodiscard]]
|
||||
#elif defined(_MSC_VER) && (_MSC_VER >= 1700)
|
||||
#define NODISCARD _Check_return_
|
||||
#else
|
||||
#define NODISCARD
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// SAL annotation support
|
||||
#ifndef _In_reads_
|
||||
#ifdef _MSC_VER
|
||||
#include <sal.h>
|
||||
#endif
|
||||
//without SAL
|
||||
#ifndef _In_reads_
|
||||
#define _In_reads_(s)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* 8byte(le) to ULONG64 (Safe for unaligned/page-boundary) */
|
||||
NODISCARD ULONG64 B8toB64le_ptr(_In_reads_(8) const BYTE* v) noexcept;
|
||||
/* 4byte(le) to DWORD (Safe for unaligned/page-boundary) */
|
||||
NODISCARD DWORD B8toB32le_ptr(_In_reads_(4) const BYTE* v) noexcept;
|
||||
/* 4byte(le) to INT (Controlled sign extension) */
|
||||
NODISCARD INT B8toINTle_ptr(_In_reads_(4) const BYTE* v) noexcept;
|
||||
/* 2byte(le) to USHORT (Safe for unaligned/page-boundary) */
|
||||
NODISCARD USHORT B8toB16le_ptr(_In_reads_(2) const BYTE* v) noexcept;
|
||||
/* 2byte(le) to signed SHORT (Controlled sign extension) */
|
||||
NODISCARD SHORT B8toSHORTle_ptr(_In_reads_(2) const BYTE* v) noexcept;
|
||||
/* 6byte(le) to ULONG64 (Safe for page-boundary) */
|
||||
NODISCARD ULONG64 B8toB64le(const BYTE(&v)[6]) noexcept;
|
||||
/* 6byte(le) to DWORD (Safe for page-boundary) */
|
||||
NODISCARD DWORD B8toB32le(const BYTE(&v)[6]) noexcept;
|
||||
/* 6byte(le) to INT (Controlled sign extension) */
|
||||
NODISCARD INT B8toINTle(const BYTE(&v)[6]) noexcept;
|
||||
/* 6byte(le) to USHORT (Safe for page-boundary) */
|
||||
NODISCARD USHORT B8toB16le(const BYTE(&v)[6]) noexcept;
|
||||
|
||||
// 20260123: Safe for unaligned/page-boundary <<<
|
||||
// ---------------------------------------------------------
|
||||
#endif
|
||||
|
||||
////------------------------------------------------
|
||||
// .ini support function
|
||||
////------------------------------------------------
|
||||
|
||||
DWORD GetPrivateProfileStringFx(LPCTSTR lpAppName, LPCTSTR lpKeyName, LPCTSTR lpDefault, LPTSTR lpReturnedString,DWORD nSize,LPCTSTR lpFileName);
|
||||
UINT GetPrivateProfileIntFx(LPCTSTR lpAppName, LPCTSTR lpKeyName, INT nDefault, LPCTSTR lpFileName);
|
||||
BOOL WritePrivateProfileStringFx(LPCTSTR lpAppName, LPCTSTR lpKeyName, LPCTSTR lpString, LPCTSTR lpFileName);
|
||||
|
||||
////------------------------------------------------
|
||||
// Check CodeSign
|
||||
////------------------------------------------------
|
||||
|
||||
#if _MSC_VER > 1310
|
||||
BOOL CheckCodeSign(LPCWSTR certName, LPCWSTR filePath);
|
||||
#endif
|
||||
|
||||
////------------------------------------------------
|
||||
// Play Sound
|
||||
////------------------------------------------------
|
||||
|
||||
BOOL AlertSound(const CString& alertSoundPath, int volume);
|
||||
|
||||
////------------------------------------------------
|
||||
// Hash
|
||||
////------------------------------------------------
|
||||
|
||||
CStringA MD5(const CStringA& str);
|
||||
|
||||
////------------------------------------------------
|
||||
// Character Converter
|
||||
////------------------------------------------------
|
||||
|
||||
CStringW UTF8toUTF16(const CStringA& utf8str);
|
||||
CStringA UTF16toUTF8(const CStringW& utf16str);
|
||||
CStringA URLEncode(const CStringA& str);
|
||||
CStringA UE(const CStringW& utf16str);
|
||||
CStringA UE(const CStringA& ansiStr);
|
||||
|
||||
////------------------------------------------------
|
||||
// Clipboard
|
||||
////------------------------------------------------
|
||||
|
||||
void SetClipboardText(CString clip);
|
||||
|
||||
////------------------------------------------------
|
||||
// SHLWAPI.DLL compatible functions
|
||||
////------------------------------------------------
|
||||
#if _MSC_VER <= 1310
|
||||
#ifdef UNICODE
|
||||
#define PathRemoveFileSpecFx PathRemoveFileSpecFxW
|
||||
#define PathFindFileNameFx PathFindFileNameFxW
|
||||
#else
|
||||
#define PathRemoveFileSpecFx PathRemoveFileSpecFxA
|
||||
#define PathFindFileNameFx PathFindFileNameFxA
|
||||
#endif
|
||||
|
||||
BOOL PathRemoveFileSpecFxA(char* path);
|
||||
BOOL PathRemoveFileSpecFxW(WCHAR* path);
|
||||
char* PathFindFileNameFxA(const char* path);
|
||||
WCHAR* PathFindFileNameFxW(const WCHAR* path);
|
||||
#endif
|
||||
@@ -0,0 +1,226 @@
|
||||
/*
|
||||
* Derived from the RSA Data Security, Inc. MD5 Message-Digest Algorithm
|
||||
* and modified slightly to be functionally identical but condensed into control structures.
|
||||
*/
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "md5.h"
|
||||
|
||||
/*
|
||||
* Constants defined by the MD5 algorithm
|
||||
*/
|
||||
#define A 0x67452301
|
||||
#define B 0xefcdab89
|
||||
#define C 0x98badcfe
|
||||
#define D 0x10325476
|
||||
|
||||
static uint32_t S[] = {7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,
|
||||
5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20,
|
||||
4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23,
|
||||
6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21};
|
||||
|
||||
static uint32_t K[] = {0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
|
||||
0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
|
||||
0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
|
||||
0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
|
||||
0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
|
||||
0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
|
||||
0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
|
||||
0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
|
||||
0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
|
||||
0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
|
||||
0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05,
|
||||
0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
|
||||
0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
|
||||
0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
|
||||
0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
|
||||
0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391};
|
||||
|
||||
/*
|
||||
* Padding used to make the size (in bits) of the input congruent to 448 mod 512
|
||||
*/
|
||||
static uint8_t PADDING[] = {0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
|
||||
/*
|
||||
* Bit-manipulation functions defined by the MD5 algorithm
|
||||
*/
|
||||
#define F(X, Y, Z) ((X & Y) | (~X & Z))
|
||||
#define G(X, Y, Z) ((X & Z) | (Y & ~Z))
|
||||
#define H(X, Y, Z) (X ^ Y ^ Z)
|
||||
#define I(X, Y, Z) (Y ^ (X | ~Z))
|
||||
|
||||
/*
|
||||
* Rotates a 32-bit word left by n bits
|
||||
*/
|
||||
uint32_t rotateLeft(uint32_t x, uint32_t n){
|
||||
return (x << n) | (x >> (32 - n));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Initialize a context
|
||||
*/
|
||||
void md5Init(MD5Context *ctx){
|
||||
ctx->size = (uint64_t)0;
|
||||
|
||||
ctx->buffer[0] = (uint32_t)A;
|
||||
ctx->buffer[1] = (uint32_t)B;
|
||||
ctx->buffer[2] = (uint32_t)C;
|
||||
ctx->buffer[3] = (uint32_t)D;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add some amount of input to the context
|
||||
*
|
||||
* If the input fills out a block of 512 bits, apply the algorithm (md5Step)
|
||||
* and save the result in the buffer. Also updates the overall size.
|
||||
*/
|
||||
void md5Update(MD5Context *ctx, uint8_t *input_buffer, size_t input_len){
|
||||
uint32_t input[16];
|
||||
unsigned int offset = (unsigned int)(ctx->size % 64);
|
||||
ctx->size += (uint64_t)input_len;
|
||||
|
||||
// Copy each byte in input_buffer into the next space in our context input
|
||||
for(unsigned int i = 0; i < input_len; ++i){
|
||||
ctx->input[offset++] = (uint8_t)*(input_buffer + i);
|
||||
|
||||
// If we've filled our context input, copy it into our local array input
|
||||
// then reset the offset to 0 and fill in a new buffer.
|
||||
// Every time we fill out a chunk, we run it through the algorithm
|
||||
// to enable some back and forth between cpu and i/o
|
||||
if(offset % 64 == 0){
|
||||
for(unsigned int j = 0; j < 16; ++j){
|
||||
// Convert to little-endian
|
||||
// The local variable `input` our 512-bit chunk separated into 32-bit words
|
||||
// we can use in calculations
|
||||
input[j] = (uint32_t)(ctx->input[(j * 4) + 3]) << 24 |
|
||||
(uint32_t)(ctx->input[(j * 4) + 2]) << 16 |
|
||||
(uint32_t)(ctx->input[(j * 4) + 1]) << 8 |
|
||||
(uint32_t)(ctx->input[(j * 4)]);
|
||||
}
|
||||
md5Step(ctx->buffer, input);
|
||||
offset = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Pad the current input to get to 448 bytes, append the size in bits to the very end,
|
||||
* and save the result of the final iteration into digest.
|
||||
*/
|
||||
void md5Finalize(MD5Context *ctx){
|
||||
uint32_t input[16];
|
||||
unsigned int offset = (unsigned int)(ctx->size % 64);
|
||||
unsigned int padding_length = offset < 56 ? 56 - offset : (56 + 64) - offset;
|
||||
|
||||
// Fill in the padding and undo the changes to size that resulted from the update
|
||||
md5Update(ctx, PADDING, padding_length);
|
||||
ctx->size -= (uint64_t)padding_length;
|
||||
|
||||
// Do a final update (internal to this function)
|
||||
// Last two 32-bit words are the two halves of the size (converted from bytes to bits)
|
||||
for(unsigned int j = 0; j < 14; ++j){
|
||||
input[j] = (uint32_t)(ctx->input[(j * 4) + 3]) << 24 |
|
||||
(uint32_t)(ctx->input[(j * 4) + 2]) << 16 |
|
||||
(uint32_t)(ctx->input[(j * 4) + 1]) << 8 |
|
||||
(uint32_t)(ctx->input[(j * 4)]);
|
||||
}
|
||||
input[14] = (uint32_t)(ctx->size * 8);
|
||||
input[15] = (uint32_t)((ctx->size * 8) >> 32);
|
||||
|
||||
md5Step(ctx->buffer, input);
|
||||
|
||||
// Move the result into digest (convert from little-endian)
|
||||
for(unsigned int i = 0; i < 4; ++i){
|
||||
ctx->digest[(i * 4) + 0] = (uint8_t)((ctx->buffer[i] & 0x000000FF));
|
||||
ctx->digest[(i * 4) + 1] = (uint8_t)((ctx->buffer[i] & 0x0000FF00) >> 8);
|
||||
ctx->digest[(i * 4) + 2] = (uint8_t)((ctx->buffer[i] & 0x00FF0000) >> 16);
|
||||
ctx->digest[(i * 4) + 3] = (uint8_t)((ctx->buffer[i] & 0xFF000000) >> 24);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Step on 512 bits of input with the main MD5 algorithm.
|
||||
*/
|
||||
void md5Step(uint32_t *buffer, uint32_t *input){
|
||||
uint32_t AA = buffer[0];
|
||||
uint32_t BB = buffer[1];
|
||||
uint32_t CC = buffer[2];
|
||||
uint32_t DD = buffer[3];
|
||||
|
||||
uint32_t E;
|
||||
|
||||
unsigned int j;
|
||||
|
||||
for(unsigned int i = 0; i < 64; ++i){
|
||||
switch(i / 16){
|
||||
case 0:
|
||||
E = F(BB, CC, DD);
|
||||
j = i;
|
||||
break;
|
||||
case 1:
|
||||
E = G(BB, CC, DD);
|
||||
j = ((i * 5) + 1) % 16;
|
||||
break;
|
||||
case 2:
|
||||
E = H(BB, CC, DD);
|
||||
j = ((i * 3) + 5) % 16;
|
||||
break;
|
||||
default:
|
||||
E = I(BB, CC, DD);
|
||||
j = (i * 7) % 16;
|
||||
break;
|
||||
}
|
||||
|
||||
uint32_t temp = DD;
|
||||
DD = CC;
|
||||
CC = BB;
|
||||
BB = BB + rotateLeft(AA + E + K[i] + input[j], S[i]);
|
||||
AA = temp;
|
||||
}
|
||||
|
||||
buffer[0] += AA;
|
||||
buffer[1] += BB;
|
||||
buffer[2] += CC;
|
||||
buffer[3] += DD;
|
||||
}
|
||||
|
||||
/*
|
||||
* Functions that run the algorithm on the provided input and put the digest into result.
|
||||
* result should be able to store 16 bytes.
|
||||
*/
|
||||
void md5String(char *input, uint8_t *result){
|
||||
MD5Context ctx = {0};
|
||||
md5Init(&ctx);
|
||||
md5Update(&ctx, (uint8_t *)input, strlen(input));
|
||||
md5Finalize(&ctx);
|
||||
|
||||
memcpy(result, ctx.digest, 16);
|
||||
}
|
||||
|
||||
/*
|
||||
void md5File(FILE *file, uint8_t *result){
|
||||
char *input_buffer = malloc(1024);
|
||||
size_t input_size = 0;
|
||||
|
||||
MD5Context ctx;
|
||||
md5Init(&ctx);
|
||||
|
||||
while((input_size = fread(input_buffer, 1, 1024, file)) > 0){
|
||||
md5Update(&ctx, (uint8_t *)input_buffer, input_size);
|
||||
}
|
||||
|
||||
md5Finalize(&ctx);
|
||||
|
||||
free(input_buffer);
|
||||
|
||||
memcpy(result, ctx.digest, 16);
|
||||
}
|
||||
*/
|
||||
@@ -0,0 +1,29 @@
|
||||
#ifndef MD5_H
|
||||
#define MD5_H
|
||||
|
||||
typedef signed char int8_t;
|
||||
typedef short int16_t;
|
||||
typedef int int32_t;
|
||||
typedef long long int64_t;
|
||||
|
||||
typedef unsigned char uint8_t;
|
||||
typedef unsigned short uint16_t;
|
||||
typedef unsigned int uint32_t;
|
||||
typedef unsigned long long uint64_t;
|
||||
|
||||
typedef struct{
|
||||
uint64_t size; // Size of input in bytes
|
||||
uint32_t buffer[4]; // Current accumulation of hash
|
||||
uint8_t input[64]; // Input to be used in the next step
|
||||
uint8_t digest[16]; // Result of algorithm
|
||||
}MD5Context;
|
||||
|
||||
void md5Init(MD5Context *ctx);
|
||||
void md5Update(MD5Context *ctx, uint8_t *input, size_t input_len);
|
||||
void md5Finalize(MD5Context *ctx);
|
||||
void md5Step(uint32_t *buffer, uint32_t *input);
|
||||
|
||||
void md5String(char *input, uint8_t *result);
|
||||
// void md5File(FILE *file, uint8_t *result);
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,17 @@
|
||||
/*---------------------------------------------------------------------------*/
|
||||
// Author : hiyohiyo
|
||||
// Mail : hiyohiyo@crystalmark.info
|
||||
// Web : https://crystalmark.info/
|
||||
// License : MIT License
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "stdafx.h"
|
||||
#define STBI_ONLY_PNG
|
||||
#define STBI_NO_STDIO
|
||||
#define STBI_NO_HDR
|
||||
#define STBI_NO_LINEAR
|
||||
#define STBI_NO_FAILURE_STRINGS
|
||||
#define STBI_ASSERT(x)
|
||||
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#include "stb_image.h"
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,13 @@
|
||||
/*---------------------------------------------------------------------------*/
|
||||
// Author : hiyohiyo
|
||||
// Mail : hiyohiyo@crystalmark.info
|
||||
// Web : https://crystalmark.info/
|
||||
// License : MIT License
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "stdafx.h"
|
||||
#define STBI_NO_STDIO
|
||||
#define STBI_WRITE_NO_STDIO
|
||||
#define STB_IMAGE_WRITE_IMPLEMENTATION
|
||||
#include "stb_image_write.h"
|
||||
|
||||
Reference in New Issue
Block a user