Controlli ActiveX MFC: creazione di una sottoclasse per un controllo Windows

In questo articolo viene descritto il processo per la creazione di una sottoclasse di un controllo Windows comune per creare un controllo ActiveX. La creazione di una sottoclasse di un controllo Windows esistente è un modo rapido per sviluppare un controllo ActiveX. Il nuovo controllo disporrà delle funzionalità dei controlli Windows sottoclassati, come il disegno e la risposta ai clic del mouse. L'esempio di controlli ActiveX MFC BUTTON è un esempio di sottoclasse di un controllo Windows.

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.

Per creare una sottoclasse di un controllo Windows, completare le seguenti attività:

Override di IsSubclassedControl e PreCreateWindow

Per eseguire l'override PreCreateWindow di e IsSubclassedControl, aggiungere le righe di codice seguenti alla protected sezione della dichiarazione della classe di controllo:

virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
BOOL IsSubclassedControl();

Nel file di implementazione del controllo (.CPP), aggiungere le seguenti righe di codice per implementare le due funzioni sottoposte a override:

// CMyAxSubCtrl::PreCreateWindow - Modify parameters for CreateWindowEx

BOOL CMyAxSubCtrl::PreCreateWindow(CREATESTRUCT& cs)
{
   cs.lpszClass = _T("BUTTON");
   return COleControl::PreCreateWindow(cs);
}

// CMyAxSubCtrl::IsSubclassedControl - This is a subclassed control

BOOL CMyAxSubCtrl::IsSubclassedControl()
{
   return TRUE;
}

Notare che, in questo esempio, il controllo pulsante Windows viene specificato in PreCreateWindow. Tuttavia, tutti i controlli Windows standard possono essere sottoclassati. Per altre informazioni sui controlli Windows standard, vedere Controlli.

Quando si sottoclassa un controllo Windows, è possibile specificare uno stile di finestra specifico (WS_) o flag di finestra estesa (WS_EX_) da utilizzare per la creazione della finestra del controllo. È possibile impostare i valori per questi parametri nella PreCreateWindow funzione membro modificando i cs.style campi della struttura e cs.dwExStyle . È necessario apportare modifiche a questi campi usando un'operazione OR per mantenere i flag predefiniti impostati dalla classe COleControl. Ad esempio, se il controllo crea una sottoclasse del controllo BUTTON e si desidera che il controllo venga visualizzato come casella di controllo, inserire la seguente riga di codice nell'implementazione di CSampleCtrl::PreCreateWindow, prima dell'istruzione return:

cs.style |= BS_CHECKBOX;

Questa operazione aggiunge il flag di stile BS_CHECKBOX, lasciando intatto il flag di COleControl stile predefinito (WS_CHILD).

Modifica della funzione membro OnDraw

Se si desidera che il controllo sottoclassato mantenga lo stesso aspetto del controllo Windows corrispondente, la funzione membro OnDraw per il controllo deve contenere solo una chiamata alla funzione membro DoSuperclassPaint, come mostrato nel seguente esempio:

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

   DoSuperclassPaint(pdc, rcBounds);
}

La funzione membro DoSuperclassPaint, implementata da COleControl, utilizza la procedura della finestra del controllo Windows per disegnare il controllo nel contesto di dispositivo specificato, all'interno del rettangolo di delimitazione. In questo modo il controllo è visibile anche quando non è attivo.

Nota

La DoSuperclassPaint funzione membro funzionerà solo con i tipi di controllo che consentono di passare un contesto di dispositivo come wParam di un messaggio di WM_PAINT. Sono inclusi alcuni dei controlli Windows standard, ad esempio SCROLLBAR e BUTTON, e tutti i controlli comuni. Per i controlli che non supportano questo comportamento, è necessario fornire il proprio codice per visualizzare correttamente un controllo inattivo.

Gestione dei messaggi finestra riflessa

I controlli Windows in genere inviano determinati messaggi finestra alla rispettiva finestra padre. Alcuni di questi messaggi, ad esempio WM_COMMAND, forniscono una notifica di un'azione da parte dell'utente. Altri, ad esempio WM_CTLCOLOR, vengono usati per ottenere informazioni dalla finestra padre. Un controllo ActiveX in genere comunica con la finestra padre in altri modi. Le notifiche vengono passate generando eventi (inviando notifiche di eventi) e le informazioni sul contenitore del controllo vengono ottenute accedendo alle proprietà di ambiente del contenitore. Grazie a queste tecniche di comunicazione, i contenitori di controlli ActiveX non prevedono l'elaborazione dei messaggi finestra inviati dal controllo.

Per impedire al contenitore di ricevere dei messaggi finestra inviati da un controllo Windows sottoclassato, COleControl crea una finestra aggiuntiva che serve da padre del controllo. Questa finestra aggiuntiva, denominata "riflettore", viene creata solo per un controllo ActiveX che crea la sottoclasse di un controllo Windows e dispone delle stesse dimensioni e posizione della finestra del controllo. La finestra riflettore intercetta determinati messaggi della finestra e li invia al controllo. Il controllo, nella routine della finestra, può quindi elaborare questi messaggi riflessi intraprendendo le opportune azioni per un controllo ActiveX (ad esempio, generando un evento). Vedi ID messaggio finestra riflessa per un elenco di messaggi di Windows intercettati e i relativi messaggi riflessi.

Un contenitore di controlli ActiveX può essere progettato per eseguire la reflection dei messaggi, evitando a COleControl la necessità di creare la finestra riflettore e riducendo il sovraccarico di runtime per un controllo Windows sottoclassato. COleControl rileva se il contenitore supporta questa funzionalità controllando la presenza di una proprietà di ambiente MessageReflect con un valore TRUE.

Per gestire un messaggio della finestra riflesso, aggiungere una voce alla mappa messaggi del controllo e implementare una funzione del gestore. Poiché i messaggi riflessi non fanno parte del set di messaggi standard definiti da Windows, Visualizzazione classi non supporta l'aggiunta di tali gestori di messaggi. Tuttavia, non è difficile aggiungere un gestore manualmente.

Per aggiungere manualmente un gestore messaggi per un messaggio della finestra riflesso, effettuare le operazioni seguenti:

  • Nel file .H della classe del controllo, dichiarare una funzione del gestore. La funzione deve avere un tipo restituito di LRESULT e due parametri, rispettivamente con i tipi WPARAM e LPARAM. Ad esempio:

    class CMyAxSubCtrl : public COleControl
    {
    
    protected:
       LRESULT OnOcmCommand(WPARAM wParam, LPARAM lParam);
    };
    
  • Nella classe del controllo . File CPP, aggiungere una voce ON_MESSAGE alla mappa dei messaggi. I parametri di questa voce devono essere l'identificatore del messaggio e il nome della funzione del gestore. Ad esempio:

    BEGIN_MESSAGE_MAP(CMyAxSubCtrl, COleControl)
       ON_MESSAGE(OCM_COMMAND, &CMyAxSubCtrl::OnOcmCommand)
    END_MESSAGE_MAP()
    
  • Anche in . File CPP, implementare la OnOcmCommand funzione membro per elaborare il messaggio riflesso. I parametri wParam e lParam sono uguali a quelli del messaggio della finestra originale.

Per un esempio di come vengono elaborati i messaggi riflessi, fare riferimento all'esempio BUTTON dei controlli ActiveX MFC. Illustra un OnOcmCommand gestore che rileva il codice di notifica BN_CLICKED e risponde attivando (inviando) un Click evento.

Vedi anche

Controlli ActiveX MFC