Condividi tramite


Controlli ActiveX MFC: disegno di un controllo ActiveX

In questo articolo viene descritto il processo di creazione del controllo ActiveX e come è possibile modificare il codice di disegno per ottimizzare il processo. (Vedere Ottimizzazione del disegno del controllo per le tecniche su come ottimizzare il disegno non disponendo di controlli che ripristinano singolarmente gli oggetti GDI selezionati in precedenza. Dopo che tutti i controlli sono stati disegnati, il contenitore può ripristinare automaticamente gli oggetti originali.

Importante

ActiveX è una tecnologia legacy che non deve essere usata per il nuovo sviluppo. Per altre informazioni sulle tecnologie moderne che sostituisce ActiveX, vedere Controlli ActiveX.

Gli esempi in questo articolo hanno origine da un controllo creato dalla Creazione guidata controllo ActiveX MFC con le impostazioni predefinite. Per altre informazioni sulla creazione di un'applicazione di controllo scheletro tramite la Creazione guidata controllo ActiveX MFC, vedere l'articolo Creazione guidata controllo ActiveX MFC.

Vengono trattati i seguenti argomenti:

Processo di disegno di un controllo ActiveX

Quando i controlli ActiveX vengono inizialmente visualizzati o vengono ridisegnati, seguono un processo di disegno simile alle altre applicazioni sviluppate tramite MFC, con un'importante distinzione: i controlli ActiveX possono trovarsi in uno stato attivo o in uno stato inattivo.

Un controllo attivo viene rappresentato in un contenitore di controlli ActiveX da una finestra figlio. Come altre finestre, è responsabile della pittura stessa quando viene ricevuto un messaggio di WM_PAINT. La classe base del controllo, COleControl, gestisce questo messaggio nella relativa OnPaint funzione. Questa implementazione predefinita chiama la funzione OnDraw del controllo.

Un controllo inattivo viene disegnato in modo diverso. Quando il controllo è inattivo, la finestra è invisibile o inesistente, pertanto non può ricevere un messaggio di disegno. Invece, il contenitore del controllo chiama direttamente la funzione OnDraw del controllo. Questo processo à diverso dal processo di disegno di un controllo attivo per il fatto che la funzione membro OnPaint non viene mai chiamata.

Come discusso nei paragrafi precedenti, la modalità di aggiornamento di un controllo ActiveX dipende dallo stato del controllo. Tuttavia, poiché il framework chiama la funzione membro OnDraw in entrambi i casi, la maggior parte del codice di disegno deve essere aggiunta in questa funzione membro.

La funzione membro OnDraw gestisce il disegno del controllo. Quando un controllo è inattivo, il contenitore di controlli chiama OnDraw, passando il contesto di dispositivo del contenitore del controllo e le coordinate dell'area rettangolare occupata dal controllo.

Il rettangolo passato dal framework alla funzione membro OnDraw contiene l'area occupata dal controllo. Se il controllo è attivo, l'angolo superiore sinistro è (0, 0) e il contesto del dispositivo passato è per la finestra figlio che contiene il controllo. Se il controllo è inattivo, la coordinata superiore sinistra non è necessariamente (0, 0) e il contesto di dispositivo passato è per il contenitore del controllo che contiene il controllo.

Nota

È importante che le modifiche apportate a OnDraw non dipendono dal punto superiore sinistro del rettangolo uguale a (0, 0) e che si disegna solo all'interno del rettangolo passato a OnDraw. Si potrebbero ottenere risultati imprevisti se si disegna oltre l'area del rettangolo.

L'implementazione predefinita fornita dalla Creazione guidata controllo ActiveX MFC nel file di implementazione del controllo (.CPP), illustrato di seguito, disegna il rettangolo con un pennello bianco e riempie l'ellisse del colore di sfondo corrente.

void CMyAxUICtrl::OnDraw(CDC* pdc, const CRect& rcBounds, const CRect& /*rcInvalid*/)
{
   if (!pdc)
      return;

   // TODO: Replace the following code with your own drawing code.
   pdc->FillRect(rcBounds, CBrush::FromHandle((HBRUSH)GetStockObject(WHITE_BRUSH)));
   pdc->Ellipse(rcBounds);
}

Nota

Quando si disegna un controllo, non è consigliabile fare ipotesi sullo stato del contesto di dispositivo passato come parametro pdc alla OnDraw funzione. Talvolta il contesto di dispositivo viene fornito dall'applicazione contenitore e non necessariamente verrà inizializzato allo stato predefinito. In particolare, selezionare esplicitamente penne, pennelli, colori, tipi di carattere e altre risorse da cui dipende il codice di disegno.

Ottimizzazione del codice paint

Una volta disegnato il controllo, è necessario ottimizzare la funzione OnDraw.

L'implementazione predefinita del disegno del controllo ActiveX disegna l'intera area di controllo. Tale soluzione è sufficiente per i controlli semplici, ma in molti casi ridisegnare il controllo risulta più veloce se solo la parte che è necessario aggiornare viene ridisegnata, anziché l'intero controllo.

La OnDraw funzione fornisce un metodo semplice di ottimizzazione passando rcInvalid, l'area rettangolare del controllo che deve essere ridisegnato. Utilizzare quest'area, in genere più piccola dell'intera area di controllo, per velocizzare il processo di disegno.

Disegnare il controllo usando i metafile

Nella maggior parte dei casi il parametro pdc della OnDraw funzione punta a un contesto di dispositivo dello schermo . Tuttavia, quando vengono stampate immagini del controllo o durante una sessione di anteprima di stampa, il contesto di dispositivo ricevuto per il rendering è un tipo speciale denominato "contesto di dispositivo metafile". A differenza di un contesto di dispositivo di uno schermo, che gestisce subito le richieste che riceve, un contesto di dispositivo metafile archivia le richieste per riprodurle in un secondo momento. Alcune applicazioni contenitore possono inoltre scegliere di eseguire il rendering dell'immagine del controllo utilizzando un contesto di dispositivo metafile in modalità di progettazione.

Le richieste di disegno metafile possono essere effettuate dal contenitore tramite due funzioni di interfaccia: IViewObject::Draw (questa funzione può anche essere chiamata per il disegno non metafile) e IDataObject::GetData. Quando un controller di dominio metafile viene passato come uno dei parametri, il framework MFC effettua una chiamata a COleControl::OnDrawMetafile. Poiché si tratta di una funzione membro virtuale, eseguire l'override della funzione nella classe del controllo per effettuare qualunque l'elaborazione speciale. Il comportamento predefinito chiama COleControl::OnDraw.

Per assicurarsi che il controllo possa essere disegnato sia su schermo che in contesti di dispositivo metafile, è necessario utilizzare solo funzioni membro che siano supportate sia nel contesto di dispositivo su schermo che nel contesto di dispositivo metafile. Tenere presente che l'unità di misura del sistema di coordinate potrebbe non essere il pixel.

Poiché l'implementazione predefinita di OnDrawMetafile chiama la funzione OnDraw del controllo, utilizzare solo le funzioni membro che sono adatte sia per un contesto di dispositivo metafile che per un contesto di dispositivo dello schermo, a meno che non si esegua l'override di OnDrawMetafile. Di seguito è elencato il sottoinsieme delle funzioni membro CDC che possono essere utilizzate in entrambi i contesti di dispositivo. Per altre informazioni su queste funzioni, vedere classe CDC nella Guida di riferimento per MFC.

Arc BibBlt Chord
Ellipse Escape ExcludeClipRect
ExtTextOut FloodFill IntersectClipRect
LineTo MoveTo OffsetClipRgn
OffsetViewportOrg OffsetWindowOrg PatBlt
Pie Polygon Polyline
PolyPolygon RealizePalette RestoreDC
RoundRect SaveDC ScaleViewportExt
ScaleWindowExt SelectClipRgn SelectObject
SelectPalette SetBkColor SetBkMode
SetMapMode SetMapperFlags SetPixel
SetPolyFillMode SetROP2 SetStretchBltMode
SetTextColor SetTextJustification SetViewportExt
SetViewportOrg SetWindowExt SetWindowORg
StretchBlt TextOut

Oltre alle funzioni membro CDC, esistono diverse altre funzioni che sono compatibili in un contesto di dispositivo metafile. Questi includono CPalette::AnimatePalette, CFont::CreateFontIndirect e tre funzioni membro di CBrush: CreateBrushIndirect, CreateDIBPatternBrush e CreatePatternBrush.

Le funzioni non registrate in un metafile sono DrawFocusRect, DrawIcon, DrawText, ExcludeUpdateRgn, FillRect, FrameRect, GrayString, InvertRect, ScrollDC e TabbedTextOut. Poiché un contesto di dispositivo metafile in realtà non è associato a un dispositivo, non è possibile utilizzare SetDIBits, GetDIBits e CreateDIBitmap con questo tipo di contesto. È possibile utilizzare SetDIBitsToDevice e StretchDIBits con un contesto di dispositivo metafile come destinazione. CreateCompatibleDC, CreateCompatibleBitmap e CreateDiscardableBitmap non sono significativi con un controller di dominio metafile.

Un altro punto da considerare quando si utilizza un contesto di dispositivo metafile è che il sistema di coordinate potrebbe non essere misurato in pixel. Per questo motivo, tutto il codice di disegno deve essere regolato in modo da adattarlo al rettangolo passato al OnDraw parametro rcBounds . Ciò impedisce il disegno accidentale all'esterno del controllo perché rcBounds rappresenta le dimensioni della finestra del controllo.

Dopo avere implementato il rendering del metafile per il controllo, utilizzare Test Container per eseguire i test sul metafile. Per informazioni su come accedere al Test Container, vedere Test di proprietà ed eventi con Test Container .

Per eseguire i test sul metafile del controllo utilizzando Test Container

  1. Scegliere Inserisci nuovo controllo dal menu Modifica contenitore di test.

  2. Nella casella Inserisci nuovo controllo selezionare il controllo e fare clic su OK.

    Il controllo verrà visualizzato in Test Container.

  3. Scegliere Disegna metafile dal menu Controllo.

    Verrà visualizzata una finestra separata, nella quale sarà visualizzato il metafile. È possibile modificare le dimensioni di questa finestra per vedere in che modo il ridimensionamento influisce sui metafile del controllo. È possibile chiudere questa finestra in qualsiasi momento.

Vedi anche

Controlli ActiveX MFC