首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

VS2008 MFC 專案使用 Skin++ 換膚後按鈕不同步?手動重繪控件解決

     編輯:程式設計綜合問答

現象描述

在 VS2008 MFC 專案中引入 Skin++ 庫實現動態換膚時,主視窗與大部分控件外觀更新正常,但按鈕等部分控件未即時刷新,必須將滑鼠游標移至按鈕上方觸發 WM_PAINT 才會套用新皮膚。

根本原因

Skin++ 套用新皮膚後,僅對主視窗發送重繪訊息,子控件(如 CButton)未主動使其客戶區失效,導致舊外觀殘留。

解決方案:遍歷控件強制重繪

在換膚完成後,手動枚舉視窗所有子控件,呼叫 InvalidateRgn 與 UpdateWindow 強制立即重繪:

// 範例碼:在換膚函式結束處加入
void CMyDialog::OnSkinChanged()
{
    // ... 原換膚邏輯 ...

    // 遞迴或迴圈取得所有子視窗句柄
    HWND hWndChild = ::GetWindow(m_hWnd, GW_CHILD);
    while (hWndChild)
    {
        // 使整個客戶區失效
        ::InvalidateRgn(hWndChild, NULL, TRUE);
        // 立即處理 WM_PAINT
        ::UpdateWindow(hWndChild);
        hWndChild = ::GetWindow(hWndChild, GW_HWNDNEXT);
    }
}

關鍵點說明

  • InvalidateRgn(hwnd, NULL, TRUE):將整個客戶區標記為需重繪,TRUE 表示同時清除背景。
  • UpdateWindow(hwnd):繞過訊息佇列,直接發送 WM_PAINT,確保即時見效。
  • 若專案使用自訂控件類別,建議在基類中封裝 RefreshSkin() 方法,統一管理。

總結

第三方換膚庫常忽略子控件同步更新,開發者需在換膚流程末端補上全控件 InvalidateRgn + UpdateWindow,即可徹底解決按鈕、編輯框等控件「滑鼠經過才變色」的尷尬。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved