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

MFC 窗口被覆蓋後按鈕圖標消失:自繪按鈕與嵌套 Tab 控件通信

     編輯:程式設計綜合問答

MFC 開發中,窗口被其他窗口遮擋後恢復,按鈕上的圖標消失,需滑過才顯示;且嵌套 Tab 控件間通信困擾開發者。本文分析自繪按鈕重繪機制,並提供 Tab 控件跨頁面數據交互的標準做法。

問題一:按鈕圖標消失

現象

  • 使用 CButton::SetIcon 設置圖標
  • 窗口被覆蓋後恢復,圖標不見
  • 鼠標懸停時重新顯示

原因分析

若按鈕設置了 BS_OWNERDRAW 風格(自繪),系統不再自動繪製圖標,開發者必須重寫 DrawItem 虛函數手動繪製。被覆蓋後收到 WM_PAINT,若 DrawItem 未正確繪製圖標,則顯示空白。

解決方案


void CMyButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) {
    CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
    CRect rect = lpDrawItemStruct->rcItem;
    UINT state = lpDrawItemStruct->itemState;

    // 繪製背景
    pDC->FillSolidRect(rect, GetSysColor(COLOR_BTNFACE));

    // 繪製圖標
    if (m_hIcon) {
        CSize size(32, 32); // 圖標尺寸
        CPoint pt((rect.Width() - size.cx) / 2, (rect.Height() - size.cy) / 2);
        ::DrawIconEx(pDC->GetSafeHdc(), pt.x, pt.y, m_hIcon, size.cx, size.cy, 0, NULL, DI_NORMAL);
    }

    // 繪製焦點矩形
    if (state & ODS_FOCUS) {
        pDC->DrawFocusRect(rect);
    }
}

確保按鈕類繼承 CButton 並聲明 virtual void DrawItem(LPDRAWITEMSTRUCT)。

問題二:嵌套 Tab 控件跨頁通信

場景

  • Tab1(父)包含 Tab2(子)
  • Tab1 第 1 頁按鈕點擊 → 修改 Tab2 第 2 頁 Edit 控件值

標準做法:指針傳遞

  1. 在 Tab2 構造函數接收父窗口指針:CTab2(CWnd* pParentTab1)
  2. Tab1 創建 Tab2 時傳遞 this:m_tab2 = new CTab2(this)
  3. Tab2 保存指針:m_pParentTab1 = pParentTab1
  4. Tab2 中調用父窗口公共方法:m_pParentTab1->UpdateTab2Edit(value)
  5. Tab1 實現公共方法,內部調用 m_tab2.GetDlgItem(IDC_EDIT)->SetWindowText(...)

代碼示例


// Tab1.h
class CTab1 : public CTabCtrl {
public:
    CTab2* m_pTab2;
    void UpdateTab2Edit(CString str); // 公共接口
};

// Tab1.cpp
void CTab1::OnButtonClick() {
    if (m_pTab2) m_pTab2->SetEditValue(_T("新值"));
    // 或調用自身公共方法
    UpdateTab2Edit(_T("新值"));
}

void CTab1::UpdateTab2Edit(CString str) {
    if (m_pTab2) {
        CWnd* pEdit = m_pTab2->GetDlgItem(IDC_EDIT2);
        if (pEdit) pEdit->SetWindowText(str);
    }
}

// Tab2 創建時
m_pTab2 = new CTab2(this); // 傳遞 this

替代方案:消息機制

  • 自定義消息 WM_USER_UPDATE_EDIT
  • Tab1 發送:GetParent()->SendMessage(WM_USER_UPDATE_EDIT, 0, (LPARAM)str)
  • Tab2 接收:在消息映射中處理
  • 優點:解耦,Tab2 不依賴 Tab1 類定義
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved