Condividi tramite


Ottimizzare il disegno del controllo

Quando un controllo viene richiesto di disegnarsi in un contesto di dispositivo contenitore-fornito, in genere seleziona gli oggetti GDI (come penne, pennelli e i tipi di carattere) nel contesto di dispositivo, esegue le operazioni di disegno e ripristina gli oggetti GDI precedenti.Se il contenitore ha più controlli che devono essere trascinati lo stesso contesto di dispositivo e ogni controllo seleziona gli oggetti GDI che richiede, il tempo può essere salvato se i controlli non modalità i singoli oggetti precedentemente selezionati.Dopo che tutti i controlli sono stati disegnati, il contenitore vengono automaticamente ripristinare gli oggetti originali.

per rilevare se un contenitore supporta questa tecnica, un controllo può chiamare la funzione membro di COleControl::IsOptimizedDraw .Se questa funzione restituisce TRUE, il controllo può ignorare il passaggio normale di ripristino degli oggetti precedentemente selezionati.

Si consideri un controllo con la seguente funzione non ottimizzata () di OnDraw :

void OnDraw(CDC* pdc, const CRect& rcBounds, const CRect& /*rcInvalid*/)
{
   CPen pen(PS_SOLID, 0, TranslateColor(GetForeColor()));
   CBrush brush(TranslateColor(GetBackColor()));
   CPen* pPenSave = pdc->SelectObject(&pen);
   CBrush* pBrushSave = pdc->SelectObject(&brush);
   pdc->Rectangle(rcBounds);
   pdc->SelectObject(pPenSave);
   pdc->SelectObject(pBrushSave);
}

La penna e il pennello in questo esempio sono variabili locali e pertanto, che i distruttori vengono chiamati quando escono dall'ambito (quando la funzione di OnDraw termina).i distruttori tenteranno di eliminare gli oggetti GDI corrispondenti.Ma non devono essere eliminati se si intende allinearli selezionati nel contesto di dispositivo restituito da OnDraw.

Per impedire agli oggetti di CBrush e di CPen da eliminati quando OnDraw completa, poterli memorizzare in variabili membro anziché le variabili locali.Nella dichiarazione della classe del controllo, aggiungere le dichiarazioni per due nuovi variabili membro:

class CMyAxOptCtrl : public COleControl
{


...


   CPen m_pen;
   CBrush m_brush;
};

Quindi, la funzione di OnDraw può essere riscritta come segue:

void OnDraw(CDC* pdc, const CRect& rcBounds, const CRect& /*rcInvalid*/)
{
   CPen pen(PS_SOLID, 0, TranslateColor(GetForeColor()));
   CBrush brush(TranslateColor(GetBackColor()));
   CPen* pPenSave = pdc->SelectObject(&pen);
   CBrush* pBrushSave = pdc->SelectObject(&brush);
   pdc->Rectangle(rcBounds);
   pdc->SelectObject(pPenSave);
   pdc->SelectObject(pBrushSave);
}

In questo modo si evitano la creazione della penna e del pennello ogni volta che OnDraw viene chiamato.Il miglioramento della velocità del costo di gestione dei dati aggiuntivi dell'istanza.

Se le modifiche delle proprietà BackColor o di ForeColor, la penna o il pennello deve essere ancora creata.A tale scopo, eseguire l'override delle funzioni membro di OnBackColorChanged e di OnForeColorChanged :

void CMyAxOptCtrl::OnForeColorChanged()
{
   m_pen.DeleteObject();
}

void CMyAxOptCtrl::OnBackColorChanged()
{
   m_brush.DeleteObject();
}

Infine, eliminare le chiamate non necessari di SelectObject , modificare OnDraw come segue:

void CMyAxOptCtrl::OnDraw(CDC* pdc, const CRect& rcBounds, const CRect& /*rcInvalid*/)
{
   if (m_pen.m_hObject == NULL)
      m_pen.CreatePen(PS_SOLID, 0, TranslateColor(GetForeColor()));
   if (m_brush.m_hObject == NULL)
      m_brush.CreateSolidBrush(TranslateColor(GetBackColor()));
   CPen* pPenSave = pdc->SelectObject(&m_pen);
   CBrush* pBrushSave = pdc->SelectObject(&m_brush);
   pdc->Rectangle(rcBounds);
   if (! IsOptimizedDraw())
   {
      pdc->SelectObject(pPenSave);
      pdc->SelectObject(pBrushSave);
   }
}

Vedere anche

Riferimenti

Classe COleControl

Creazione guidata controllo ActiveX MFC

Concetti

Controlli ActiveX MFC: ottimizzazione

Controlli ActiveX MFC

Controlli ActiveX MFC

Controlli ActiveX MFC: Disegno del controllo ActiveX