這段代碼有點奇怪,特別是因爲你不給我們任何上下文。什麼是dc
,設備上下文?此代碼是否在OnPaint
消息處理函數中?不管怎樣,你爲什麼要手動繪製圖標而不是讓按鈕控件自動執行它?
的更簡單的方法是通過監聽通過OnEnable
成員函數WM_ENABLE
消息,並調用SetIcon
成員函數來更新按鈕的圖標來監視控制的啓用狀態。這樣,按鈕控件就會跟蹤圖標,因此不需要將其保存在成員變量中(m_hIcon
)。刪除圖標與將其設置爲顯示空圖標一樣簡單。沒有必要或所有這些醜陋的黑客,如使用第二個透明圖標,或用純色矩形在圖標上繪圖。
示例代碼,其中CMyButton
擴展CButton
:
void CMyButton::OnEnable(BOOL bEnable)
{
CButton::OnEnable(bEnable); // call the base class
if (bEnable)
{
// The button was enabled, so load and set the icon.
const HICON hIcon = AfxGetApp()->LoadIcon(IDI_ICON1);
this->SetIcon(hIcon);
}
else
{
// The button was disabled.
// First, retrieve the current icon from the button.
const HICON hIcon = this->GetIcon();
// Then, remove the icon from the button by setting a null icon.
this->SetIcon(NULL);
// Finally, delete the original icon to prevent memory leaks.
::DestroyIcon(hIcon);
}
}
這是當然的,可能你說的辦了OnPaint
功能裏面,如果你絕對必須(雖然這是設計不良)。訣竅是,只有在繪製代碼的代碼被執行時纔會繪製圖標。否則,不會繪製圖標。基類不會繪製圖標。
因此,所有你需要的是:
void CMyWindow::OnPaint()
{
CPaintDC dc(this);
const CWnd* pBtn = GetDlgItem(IDC_BUTTON1);
if (pBtn->IsWindowEnabled())
{
m_hIcon = AfxGetApp()->LoadIcon(IDI_ICON1);
dc.DrawIcon(DT_CENTER, DT_CENTER, m_hIcon);
// make sure that you delete m_hIcon when the window is destroyed!
}
else
{
// Do not draw the icon here!
// But write whatever other code you want, like...
dc.SetTextColor(RGB(192,192,192));
}
}
顯然,如果你的代碼是OnPaint
函數內這種戰術只會工作,但畢竟是你應該做你的繪圖所有。否則,只要窗口被重新繪製,它就會丟失。對於演示,只需嘗試最小化窗口或將其從屏幕上移出即可。通過調用CWnd::Invalidate
,然後CWnd::UpdateWindow
(或者`CWnd :: RedrawWindow)強制重繪。