2011-11-04 112 views
0

我創建了兩個Fred Acker's CHoverButtonEx類的實例,稍作修改以包含禁用狀態。自定義控制圖 - 焦點狀態

這些按鈕上包含以下屬性模態對話框存在:

IDD_MY_DIALOG DIALOGEX 0, 0, 162, 27 
STYLE DS_SETFONT | WS_POPUP 
EXSTYLE WS_EX_TOPMOST | WS_EX_TOOLWINDOW 
FONT 9, "Arial", 400, 0, 0x0 
BEGIN 
    CONTROL   146,IDC_STATIC_BKGND,"Static",SS_BITMAP,0,0,162,27 
    LTEXT   "",IDC_STATIC_1,6,4,101,9,SS_WORDELLIPSIS 
    LTEXT   "",IDC_STATIC_2,6,15,101,9 
    CONTROL   "",IDC_BUTTON_1,"Button",BS_OWNERDRAW | WS_TABSTOP,108,4,24,19 
    CONTROL   "",IDC_BUTTON_2,"Button",BS_OWNERDRAW | WS_TABSTOP,134,4,24,19 
END 

一切都與不同之處在於按鍵運作良好,現在我需要實現聚焦狀態,但行爲很奇怪和意外。

在我DRAWITEM消息處理程序,我有以下的代碼,其功能幾乎完全一樣的原始減去一些東西,我清理了這是沒有必要:

void CHoverButtonEx::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) 
{ 
// Do other stuff above and now find the state and draw the bitmap 

if(lpDrawItemStruct->itemState & ODS_SELECTED) 
{ 
    //mydc->BitBlt(0,0,m_ButtonSize.cx,m_ButtonSize.cy,pMemDC,m_ButtonSize.cx,0,SRCCOPY); 
    mydc->StretchBlt(0,0, lpDrawItemStruct->rcItem.right-lpDrawItemStruct->rcItem.left, 
     lpDrawItemStruct->rcItem.bottom-lpDrawItemStruct->rcItem.top, 
     pMemDC,m_ButtonSize.cx,0, m_ButtonSize.cx,m_ButtonSize.cy, SRCCOPY); 
} 
else 
{ 
    if(m_bHover) 
    { 
     //mydc->BitBlt(0,0,m_ButtonSize.cx,m_ButtonSize.cy,pMemDC,m_ButtonSize.cx*2,0,SRCCOPY); 
     mydc->StretchBlt(0,0, lpDrawItemStruct->rcItem.right-lpDrawItemStruct->rcItem.left, 
      lpDrawItemStruct->rcItem.bottom-lpDrawItemStruct->rcItem.top, 
      pMemDC,m_ButtonSize.cx*2,0, m_ButtonSize.cx,m_ButtonSize.cy, SRCCOPY); 
    } 
    else 
    { 
     if (IsWindowEnabled()) 
     { 
      //mydc->BitBlt(0,0,m_ButtonSize.cx,m_ButtonSize.cy,pMemDC,0,0,SRCCOPY); 
      mydc->StretchBlt(0,0, lpDrawItemStruct->rcItem.right-lpDrawItemStruct->rcItem.left, 
       lpDrawItemStruct->rcItem.bottom-lpDrawItemStruct->rcItem.top, 
       pMemDC,0,0, m_ButtonSize.cx,m_ButtonSize.cy, SRCCOPY); 
     } 
     else 
     { 
      //mydc->BitBlt(0,0,m_ButtonSize.cx,m_ButtonSize.cy,pMemDC,m_ButtonSize.cx*3,0,SRCCOPY); 
      mydc->StretchBlt(0,0, lpDrawItemStruct->rcItem.right-lpDrawItemStruct->rcItem.left, 
       lpDrawItemStruct->rcItem.bottom-lpDrawItemStruct->rcItem.top, 
       pMemDC,m_ButtonSize.cx*3,0, m_ButtonSize.cx,m_ButtonSize.cy, SRCCOPY); 
     } 
    } 
} 

if (lpDrawItemStruct->itemAction & ODA_FOCUS) 
{ 
    RECT rcFocus; 
    int iChange = 3; 
    rcFocus.top = lpDrawItemStruct->rcItem.top + iChange; 
    rcFocus.left = lpDrawItemStruct->rcItem.left + iChange; 
    rcFocus.right = lpDrawItemStruct->rcItem.right - iChange; 
    rcFocus.bottom = lpDrawItemStruct->rcItem.bottom - iChange; 
    pMemDC->DrawFocusRect(&rcFocus); 
} 

// clean up 
pMemDC -> SelectObject(pOldBitmap); 
delete pMemDC; 
} 

正在發生的事情是,當該對話框是活動窗口,我按一下標籤,焦點框跳到第二個按鈕,即使我可以通過按鈕的點擊處理程序確認第一個按鈕具有真正的焦點。然後當我再次按下標籤時,焦點框跳轉到包括兩個按鈕。然後另一個標籤按鈕將焦點框移動到另一個按鈕,最後另一個標籤按鈕完全移除焦點框。這個序列不斷髮生。即使按住Shift鍵也不會影響它。

我用spy ++嗅探了Windows消息,它看起來很正常。我得到了兩個按鈕控件的WM_DRAWITEM消息,並且它們被成功處理。

我會提到最後一件事;在我的對話框代碼中,當我初始化按鈕時,我不得不將按鈕放置在z順序的底部,否則IDC_STATIC_BKGND會畫出按鈕。這對我來說看起來並不正常,因爲它們應該已經在z順序的底部了。 (只要添加它,以防它是我的問題的一部分原因)。

m_button1.SetHorizontal(true); 
m_button1.SetMoveable(FALSE); 
m_button1.LoadBitmap(IDB_BUTTON_1); 
m_button1.SetToolTipText(_T("Some Text1")); 
// Draws the button after the background is drawn 
m_button1.SetWindowPos(&CWnd::wndBottom, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); 

m_button2.SetHorizontal(true); 
m_button2.SetMoveable(FALSE); 
m_button2.LoadBitmap(IDB_BUTTON_2); 
m_button2.SetToolTipText(_T("Some Text2")); 
// Draws the button after the background is drawn 
m_button2.SetWindowPos(&CWnd::wndBottom, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); 

有誰知道如何正確地爲我的情況添加一個焦點框?

謝謝。

更新: 試圖BrendanMcK的建議,並沒有解決問題後,我挖了一些間諜++捕捉消息,發現的東西,似乎是古怪的行爲。以下消息表示對話框中的單個選項卡按下。

<00283> 00870794 R WM_CTLCOLORBTN hBrush:01900015 
<00284> 00870794 S WM_DRAWITEM idCtl:112 lpdis:002AEF2C 
<00285> 00870794 R WM_DRAWITEM fProcessed:True 
<00286> 00870794 S DM_GETDEFID 
<00287> 00870794 R DM_GETDEFID wHasDef:DC_HASDEFID wDefID:0001 
<00288> 00870794 S WM_CTLCOLORBTN hdcButton:110114A7 hwndButton:01090502 
<00289> 00870794 R WM_CTLCOLORBTN hBrush:01900015 
<00290> 00870794 S WM_DRAWITEM idCtl:113 lpdis:002AF2A0 
<00291> 00870794 R WM_DRAWITEM fProcessed:True 

顯然有兩個單獨的WM_DRAWITEM消息傳遞。每個消息的細節是:

消息#284:行動= ODA_FOCUS,狀態= 0x0110(ODS_FOCUS = 0×0010)

消息#290:行動= ODA_DRAWENTIRE,狀態= ODS_NOACCEL

我本來期望在消息#290中,該動作將再次成爲ODA_FOCUS以允許另一個按鈕「取消」對焦框。

我不確定爲什麼我使用Win7時甚至會收到ODS_NOACCEL狀態。有什麼我忘記禁用?

回答

0

MSDN on DRAWITEMSTATE

ODA_FOCUS 控制失去或得到鍵盤焦點。應檢查itemState成員以確定控件是否具有焦點。

由於您正在重繪控件,因此如果itemState指示控件具有焦點,則應該只繪製焦點矩形。相反,你在所有情況下繪製它,關注是否控制收益或失去的重點。添加一個檢查項目狀態& ODS_FOCUS,你應該很好。

+0

感謝您的建議,但沒有運氣。我在主帖中添加了更新。 – sna14