模仿 Visual Studio 屬性視窗標題列的「釘子」按鈕:點擊切換釘入/釘出狀態,圖片翻轉,並同步設定父視窗 `WS_EX_TOPMOST` 置頂/取消置頂。
void CSButton::PreSubclassWindow() {
m_pinned = FALSE;
m_bmpUp.LoadBitmap(IDB_PIN_UP);
m_bmpDown.LoadBitmap(IDB_PIN_DOWN);
CDC* pDC = GetDC();
m_memUp.CreateCompatibleDC(pDC); m_memUp.SelectObject(&m_bmpUp);
m_memDown.CreateCompatibleDC(pDC); m_memDown.SelectObject(&m_bmpDown);
ReleaseDC(pDC);
CButton::PreSubclassWindow();
ModifyStyle(0, BS_OWNERDRAW); // 必須設為 OwnerDraw
}
void CSButton::DrawItem(LPDRAWITEMSTRUCT lpDIS) {
CRect rc = lpDIS->rcItem;
CDC* pDC = CDC::FromHandle(lpDIS->hDC);
// 背景
CBrush br(::GetSysColor(COLOR_BTNFACE));
pDC->FillRect(rc, &br);
// 依狀態畫位圖
CDC* pSrc = m_pinned ? &m_memDown : &m_memUp;
pDC->StretchBlt(rc.left, rc.top, rc.Width(), rc.Height(),
pSrc, 0, 0, 24, 21, SRCCOPY); // 24x21 為原圖尺寸
// 同步父視窗置頂狀態
GetParent()->SetWindowPos(m_pinned ? &CWnd::wndTopMost : &CWnd::wndNoTopMost,
0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
}
void CSButton::OnLButtonDown(UINT nFlags, CPoint point) {
m_pinned = !m_pinned;
Invalidate(); // 觸發重繪
CButton::OnLButtonDown(nFlags, point);
}