#include "stdafx.h"
|
#include "CBaseDlg.h"
|
#include "GridCtrl.h"
|
|
// È«¾ÖÖ÷Ìâ¶ÔÏó
|
Theme g_lightTheme = { RGB(255, 255, 255), RGB(0, 0, 0), RGB(240, 240, 240), RGB(200, 200, 200) };
|
Theme g_darkTheme = { RGB(40, 40, 40), RGB(255, 255, 255), RGB(60, 60, 60), RGB(80, 80, 80) };
|
|
CFont g_defaultFont;
|
Theme* g_currentTheme = &g_lightTheme;
|
|
// È«¾Ö×ÊÔ´¾ä±ú
|
HINSTANCE g_hCurrentResource = NULL;
|
|
IMPLEMENT_DYNAMIC(CBaseDlg, CDialogEx)
|
|
CBaseDlg::CBaseDlg(UINT nID, CWnd* pPage) : CDialogEx(nID, pPage), m_bResizing(false)
|
{
|
m_nID = nID;
|
m_pParent = pPage;
|
m_nInitialWidth = 0;
|
m_nInitialHeight = 0;
|
}
|
|
CBaseDlg::~CBaseDlg()
|
{
|
// shared_ptr»á×Ô¶¯ÇåÀíÄڴ棬²»ÐèÒªÊÖ¶¯É¾³ý
|
m_mapFonts.clear();
|
m_mapCtrlLayouts.clear();
|
m_mapControls.clear();
|
}
|
|
void CBaseDlg::SwitchTheme(ThemeType enThemeType)
|
{
|
// ʹÓà map À´¸ù¾Ý themeType ²éÕÒÖ÷Ìâ
|
static const std::unordered_map<ThemeType, Theme*> themeMap = {
|
{ ThemeType::Light, &g_lightTheme },
|
{ ThemeType::Dark, &g_darkTheme }
|
};
|
|
// ÉèÖõ±Ç°Ö÷Ìâ
|
auto it = themeMap.find(enThemeType);
|
if (it != themeMap.end()) {
|
g_currentTheme = it->second;
|
}
|
else {
|
g_currentTheme = &g_lightTheme;
|
}
|
|
// ¸üпؼþµÄÍâ¹Û
|
CWnd* pWnd = GetWindow(GW_CHILD);
|
while (pWnd) {
|
pWnd->Invalidate();
|
pWnd = pWnd->GetNextWindow();
|
}
|
|
// ¸üжԻ°¿ò±³¾°ÑÕÉ«
|
SetBackgroundColor(g_currentTheme->backgroundColor);
|
}
|
|
void CBaseDlg::LoadResourceLibrary(const CString& strLanguage)
|
{
|
// Ð¶ÔØÖ®Ç°¼ÓÔØµÄ×ÊÔ´¿â
|
UnloadResourceLibrary();
|
|
// ¼ÓÔØÐµÄ×ÊÔ´¿â
|
g_hCurrentResource = AfxLoadLibrary(strLanguage);
|
|
// ÉèÖÃеÄ×ÊÔ´¾ä±ú
|
if (g_hCurrentResource != NULL) {
|
AfxSetResourceHandle(g_hCurrentResource);
|
}
|
}
|
|
void CBaseDlg::UnloadResourceLibrary()
|
{
|
// Ð¶ÔØÖ®Ç°¼ÓÔØµÄ×ÊÔ´¿â
|
if (g_hCurrentResource != NULL) {
|
FreeLibrary(g_hCurrentResource); // Êͷŵ±Ç°×ÊÔ´¿â
|
g_hCurrentResource = NULL; // Çå¿Õ×ÊÔ´¾ä±ú
|
}
|
}
|
|
CFont* CBaseDlg::GetOrCreateFont(int nFontSize)
|
{
|
auto it = m_mapFonts.find(nFontSize);
|
if (it != m_mapFonts.end()) {
|
return it->second.get();
|
}
|
|
// ʹÓà shared_ptr À´¹ÜÀí×ÖÌå¶ÔÏó
|
auto font = std::make_shared<CFont>();
|
LOGFONT logFont = { 0 };
|
_tcscpy_s(logFont.lfFaceName, _T("Segoe UI"));
|
logFont.lfHeight = -nFontSize;
|
logFont.lfQuality = CLEARTYPE_QUALITY;
|
font->CreateFontIndirect(&logFont);
|
m_mapFonts[nFontSize] = font;
|
|
return font.get();
|
}
|
|
void CBaseDlg::SetDefaultFont()
|
{
|
CFont* defaultFont = GetOrCreateFont(12);
|
|
CWnd* pWnd = GetWindow(GW_CHILD);
|
while (pWnd) {
|
TCHAR szClassName[256];
|
GetClassName(pWnd->m_hWnd, szClassName, sizeof(szClassName));
|
if (_tcsicmp(szClassName, _T("MFCGridCtrl")) == 0) {
|
pWnd = pWnd->GetNextWindow();
|
continue;
|
}
|
|
pWnd->SetFont(defaultFont, TRUE);
|
pWnd = pWnd->GetNextWindow();
|
}
|
}
|
|
BOOL CBaseDlg::AddControl(UINT nCtrlID, CWnd* pControl)
|
{
|
// È·±£¿Ø¼þ²»Öظ´Ìí¼Ó
|
if (m_mapControls.find(nCtrlID) != m_mapControls.end()) {
|
return FALSE; // ¿Ø¼þÒѾ´æÔÚ
|
}
|
|
m_mapControls[nCtrlID] = std::unique_ptr<CWnd>(pControl);
|
return TRUE;
|
}
|
|
BOOL CBaseDlg::RemoveControl(UINT nCtrlID)
|
{
|
auto it = m_mapControls.find(nCtrlID);
|
if (it != m_mapControls.end()) {
|
m_mapControls.erase(it);
|
return TRUE;
|
}
|
return FALSE;
|
}
|
|
BOOL CBaseDlg::UpdateControlText(UINT nCtrlID, const CString& strText)
|
{
|
auto it = m_mapControls.find(nCtrlID);
|
if (it != m_mapControls.end()) {
|
CWnd* pWnd = it->second.get();
|
if (pWnd->GetSafeHwnd() != nullptr)
|
{
|
pWnd->SetWindowText(strText);
|
return TRUE;
|
}
|
}
|
return FALSE;
|
}
|
|
CWnd* CBaseDlg::GetControl(UINT nCtrlID)
|
{
|
auto it = m_mapControls.find(nCtrlID);
|
if (it != m_mapControls.end()) {
|
return it->second.get();
|
}
|
return nullptr;
|
}
|
|
void CBaseDlg::AdjustControls(float dScaleX, float dScaleY)
|
{
|
if (m_bResizing) return; // ·ÀÖ¹ÔÚµ÷Õû¹ý³ÌÖÐÖØ¸´µ÷Õû
|
|
m_bResizing = true;
|
CWnd* pWnd = GetWindow(GW_CHILD);
|
while (pWnd) {
|
int nCtrlID = pWnd->GetDlgCtrlID();
|
if (nCtrlID != -1 && m_mapCtrlLayouts.find(nCtrlID) != m_mapCtrlLayouts.end()) {
|
CRect originalRect = m_mapCtrlLayouts[nCtrlID];
|
CRect newRect(
|
static_cast<int>(originalRect.left * dScaleX),
|
static_cast<int>(originalRect.top * dScaleY),
|
static_cast<int>(originalRect.right * dScaleX),
|
static_cast<int>(originalRect.bottom * dScaleY));
|
|
TCHAR szClassName[256];
|
GetClassName(pWnd->m_hWnd, szClassName, sizeof(szClassName));
|
|
if (_tcsicmp(szClassName, _T("ComboBox")) == 0) {
|
CComboBox* pComboBox = (CComboBox*)pWnd;
|
pComboBox->SetItemHeight(-1, newRect.Height()); // -1 ±íʾËùÓÐÏîµÄ¸ß¶È
|
}
|
|
if (_tcsicmp(szClassName, _T("MFCGridCtrl")) == 0) {
|
CGridCtrl* pGridCtrl = (CGridCtrl*)pWnd;
|
pGridCtrl->SetDefCellHeight(newRect.Height() / 21);
|
pGridCtrl->ExpandColumnsToFit(TRUE);
|
pGridCtrl->ExpandLastColumn();
|
pGridCtrl->Invalidate();
|
pGridCtrl->UpdateWindow();
|
}
|
|
pWnd->MoveWindow(&newRect);
|
AdjustControlFont(pWnd, newRect.Width(), newRect.Height());
|
}
|
pWnd = pWnd->GetNextWindow();
|
}
|
m_bResizing = false;
|
}
|
|
void CBaseDlg::AdjustControlFont(CWnd* pWnd, int nWidth, int nHeight)
|
{
|
TCHAR szClassName[256];
|
GetClassName(pWnd->m_hWnd, szClassName, sizeof(szClassName));
|
|
if (_tcsicmp(szClassName, _T("MFCGridCtrl")) == 0) {
|
return;
|
}
|
|
int fontSize = nHeight / 2;
|
if (fontSize < 8) fontSize = 8;
|
if (fontSize > 32) fontSize = 32;
|
|
CFont* pFont = GetOrCreateFont(fontSize);
|
|
pWnd->SetFont(pFont);
|
pWnd->Invalidate(); // ˢпؼþÏÔʾ
|
}
|
|
BEGIN_MESSAGE_MAP(CBaseDlg, CDialogEx)
|
ON_WM_SIZE()
|
ON_WM_GETMINMAXINFO()
|
ON_WM_CTLCOLOR()
|
END_MESSAGE_MAP()
|
|
BOOL CBaseDlg::OnInitDialog()
|
{
|
CDialogEx::OnInitDialog();
|
|
// »ñÈ¡µ±Ç°ÓïÑÔ
|
LANGID langId = GetUserDefaultLangID();
|
if (langId == LANG_CHINESE) {
|
// ¼ÓÔØÖÐÎÄ×ÊÔ´
|
}
|
else {
|
// ¼ÓÔØÓ¢ÎÄ×ÊÔ´
|
}
|
|
// »ñÈ¡¶Ô»°¿òµÄ¹¤×÷Çø£¨ÆÁÄ»¿ÉÓÃÇøÓò£©
|
CRect screenRect, dlgRect, clientRect;
|
SystemParametersInfo(SPI_GETWORKAREA, 0, &screenRect, 0);
|
GetClientRect(&clientRect);
|
m_nInitialWidth = clientRect.Width();
|
m_nInitialHeight = clientRect.Height();
|
|
// ÉèÖÃĬÈÏ×ÖÌå
|
CFont* pDefaultFont = GetOrCreateFont(12);
|
|
// ±éÀú×Ó´°¿Ú£¨¿Ø¼þ£©
|
CWnd* pWnd = GetWindow(GW_CHILD);
|
while (pWnd) {
|
int nCtrlID = pWnd->GetDlgCtrlID();
|
if (nCtrlID != -1) {
|
// ±£´æ¿Ø¼þµÄ³õʼ²¼¾Ö
|
CRect ctrlRect;
|
pWnd->GetWindowRect(&ctrlRect);
|
ScreenToClient(&ctrlRect);
|
m_mapCtrlLayouts[nCtrlID] = ctrlRect;
|
|
// Åųý²»ÐèÒª²Ù×÷µÄ¿Ø¼þ£¨Èç×Ô¶¨Òå¿Ø¼þ GridCtrl£©
|
TCHAR szClassName[256];
|
GetClassName(pWnd->m_hWnd, szClassName, sizeof(szClassName));
|
if (_tcsicmp(szClassName, _T("MFCGridCtrl")) == 0) {
|
pWnd = pWnd->GetNextWindow();
|
continue;
|
}
|
|
// ÉèÖÿؼþµÄĬÈÏ×ÖÌå
|
pWnd->SetFont(pDefaultFont);
|
}
|
pWnd = pWnd->GetNextWindow();
|
}
|
|
// ½«¶Ô»°¿ò¾ÓÖÐ
|
GetWindowRect(&dlgRect);
|
int dlgWidth = dlgRect.Width() * 2;
|
int dlgHeight = dlgRect.Height() * 2;
|
|
if (dlgWidth > screenRect.Width()) {
|
dlgWidth = screenRect.Width();
|
}
|
if (dlgHeight > screenRect.Height()) {
|
dlgHeight = screenRect.Height();
|
}
|
|
int centerX = screenRect.left + (screenRect.Width() - dlgWidth) / 2;
|
int centerY = screenRect.top + (screenRect.Height() - dlgHeight) / 2;
|
MoveWindow(centerX, centerY, dlgWidth, dlgHeight);
|
|
return TRUE;
|
}
|
|
void CBaseDlg::OnSize(UINT nType, int cx, int cy)
|
{
|
CDialogEx::OnSize(nType, cx, cy);
|
|
if (nType == SIZE_MINIMIZED || m_mapCtrlLayouts.empty()) {
|
return;
|
}
|
|
// ¼ì²é³ß´ç±ä»¯ÊÇ·ñ×ã¹»´ó£¬±ÜÃâÆµ·±µ÷Õû
|
//static int lastWidth = 0, lastHeight = 0;
|
//if (abs(cx - lastWidth) < 10 && abs(cy - lastHeight) < 10) {
|
// return;
|
//}
|
|
//lastWidth = cx;
|
//lastHeight = cy;
|
|
// ¼ÆËã±ÈÀý²¢µ÷Õû²¼¾Ö
|
float dScaleX = static_cast<float>(cx) / m_nInitialWidth;
|
float dScaleY = static_cast<float>(cy) / m_nInitialHeight;
|
|
AdjustControls(dScaleX, dScaleY);
|
}
|
|
void CBaseDlg::OnGetMinMaxInfo(MINMAXINFO* lpMMI)
|
{
|
lpMMI->ptMinTrackSize.x = 400;
|
lpMMI->ptMinTrackSize.y = 300;
|
|
CDialogEx::OnGetMinMaxInfo(lpMMI);
|
}
|
|
HBRUSH CBaseDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
|
{
|
if (g_currentTheme) {
|
pDC->SetBkColor(g_currentTheme->backgroundColor);
|
pDC->SetTextColor(g_currentTheme->textColor);
|
|
// ·µ»Ø±³¾°»Ë¢
|
return CreateSolidBrush(g_currentTheme->backgroundColor);
|
}
|
|
return CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor);
|
}
|