15 мая 2023 года "Исходники.РУ" отмечают своё 23-летие!
Поздравляем всех причастных и неравнодушных с этим событием!
И огромное спасибо всем, кто был и остаётся с нами все эти годы!

Главная Форум Журнал Wiki DRKB Discuz!ML Помощь проекту


Focus Rectangle in Owner Draw List Box on Property Sheet pag

Tina Buch -- tbuch@Onramp.NET
Friday, February 09, 1996

VC++ 1.52c

I have an owner draw list box (I need to bypass the 64K limit of listboxes
and draw bit maps) on a page of a Property Sheet.  When a user selects an
item, a bit map is drawn to indicate item selection. A focus rectangle moves
up and down the listbox indicating the current item.

The listbox has LBS_MULTIPLESEL | LBS_OWNERDRAWVARIABLE | 
WS_VSCROLL | WS_TABSTOP   styles.


The problem I'm having is with the focus rectangle.

The DrawItem() code below works great when I select the page containing the
listbox and the initial focus is NOT on the listbox (Set to a Radio button
instead).  If I tab to the listbox, my focus rectangle gets drawn and 
each  down arrow (scroll, etc) moves my focus rectangle appropriately.

However, if I tab to the page and the initial focus is ON the listbox, the
focus rectangle does not get displayed and gets displayed when the focus
either leaves the listbox or moves to another item in the listbox. (I get
two focus rectangles, one for the new item selected and one incorrectly on
the old item.)  

This same problem occurs if you ALT-TAB to another app when the focus is in
the listbox and come back. 

The code in DrawItem() is being processed one too many or one too few times. 
I probably need to change some of the code below around, but am stumped as to
what checks I need to make.


                Any help will be appreciated!

                        Thanks, Tina


void CAirpListBox::DrawItem(LPDRAWITEMSTRUCT lpDIS)
     {
       CDC* pDC = CDC::FromHandle(lpDIS->hDC);  
        ......
       pDC->DrawText(...);                     //Draw the Item  
        
       if ((lpDIS->itemState & ODS_SELECTED) &&
            (lpDIS->itemAction & (ODA_SELECT | ODA_DRAWENTIRE)))
            {
            ...
            pDC->BitBlt(...)       //Draw Bit Map to Indicate item Selected
            ...
            }
   if (!(lpDIS->itemState & ODS_SELECTED) &&
        (lpDIS->itemAction & ODA_SELECT))
            {
            ....
            COLORREF deHilite = RGB(255,       //Draw  over Bit Map to Indicate 
                        255, 255);             // not selected     
            CBrush br(deHilite);
            .....    
            pDC->FillRect(..., &br);           //draws only over bit map

            }
      aTmpRec = (CRect)lpDIS->rcItem;
      if(lpDIS->itemAction & ODA_DRAWENTIRE)       //Draw/Undraw Focus Rectangle
            {                                      //to indicate current active 
            if(lpDIS->itemState & ODS_FOCUS)       //item.   
               pDC->DrawFocusRect(aTmpRec);        // If focus rect already
}                                     // drawn, undraws     
      else
            {
            if(lpDIS->itemAction & ODA_FOCUS)      //Draw/Undraw Focus Rect
              pDC->DrawFocusRect(aTmpRec);
           }

    } 






Gerry Sweeney -- gerry@hornbill.demon.co.uk
Monday, February 12, 1996


Tina,

This is the OnDrawItem member on my owner draw list box(s). I normally start 
with this and add what ever bits i need, like drawing bitmaps etc. This is 
from my 16bit apps so I am only assuming it will work under Win32.

David,

I hope this helps. I am sure I got this from the MSDN but I have not been 
able to find it again. I will look again later to try and find it for you.


Gerry
gerry@hornbil.demon.co.uk



void CListDialog::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT pDI)
{
     CListBox *lb = (CListBox *)GetDlgItem(nIDCtl);

    CRect rcText = pDI->rcItem;
    CString text;
     switch (pDI->itemAction)
          {
         case ODA_DRAWENTIRE:
               {
               lb->GetText(pDI->itemID, text);
             // Set up the font we want to use.
             rcText = pDI->rcItem;
             // Erase the entire area.
             ::ExtTextOut(pDI->hDC, rcText.left, rcText.top, ETO_OPAQUE, 
&rcText, "", 0, NULL);

             // Move the text over to just beyond the bitmap.
             ::DrawText(pDI->hDC, text, -1, &rcText, DT_LEFT | DT_VCENTER | 
DT_NOPREFIX);

             // Check if we need to show selection state.
             if (pDI->itemState & ODS_SELECTED) ::InvertRect(pDI->hDC, 
&(pDI->rcItem));

             // Check if we need to show focus state.
             if (pDI->itemState & ODS_FOCUS) ::DrawFocusRect(pDI->hDC, 
&(pDI->rcItem));
         break;
            }

    case ODA_FOCUS:
        // Toggle the focus state.
        ::DrawFocusRect(pDI->hDC, &(pDI->rcItem));
        break;

    case ODA_SELECT:
        // Toggle the selection state.
        ::InvertRect(pDI->hDC, &(pDI->rcItem));
        break;
    default:
        break;
    }
}




| Вернуться в корень Архива |