2013-02-06 11 views
6

Ho un componente pulsante personalizzato che ho derivato da TCustomButton.Modifica di CreateParams in modo dinamico?

Per rendere ownerdrawn ho overrided le CreateParams in questo modo:

procedure TMyButton.CreateParams(var Params: TCreateParams); 
begin 
    inherited CreateParams(Params); 
    with Params do 
    begin 
    Style := Style or BS_OWNERDRAW; 
    end; 
end; 

mio pulsante funziona bene con la mia pittura, ecc, ma quello che vorrei fare è fornire una proprietà booleana in Inspector, che può essere usato per dire al mio pulsante se dovrebbe essere proprietario o meno.

Ad esempio, se la proprietà è abilitata, il pulsante dipinge con le mie routine di pittura come pulsante proprietario, se la proprietà viene disattivata, deve dipingere come lo stile di pulsante di Windows a tema (come un normale pulsante).

CreateParams dice al mio pulsante che dovrebbe essere ownerdawn, ma voglio fornire un'opzione per dire al pulsante se dovrebbe essere ownerdrawn o meno. Modificando la proprietà in fase di progettazione o tramite codice in fase di runtime, voglio dire al mio pulsante se ritirare o meno.

E 'possibile farlo e se sì, come?

risposta

10

Aggiungere la proprietà e rendere CreateParams comportarsi di conseguenza non è il problema, suppongo. Prendendo la nuova impostazione in vigore immediatamente lo è probabilmente.

Chiama RecreateWnd quando la proprietà è attivata. Ciò porterà a eliminare l'attuale handle di Windows e a ricrearlo, includendo l'uso della tua routine sovrascritta CreateParams.

Tutto sommato:

type 
    TMyButton = class(TButtonControl) 
    private 
    FOwnerDraw: Boolean; 
    procedure SetOwnerDraw(Value: Boolean); 
    protected 
    procedure CreateParams(var Params: TCreateParams); override; 
    published 
    property OwnerDraw: Boolean read FOwnerDraw write SetOwnerDraw 
     default False; 
    end; 

procedure TMyButton.CreateParams(var Params: TCreateParams); 
const 
    OwnerDraws: array[Boolean] of DWORD = (0, BS_OWNERDRAW); 
begin 
    inherited CreateParams(Params); 
    Params.Style := Params.Style or OwnerDraws[FOwnerDraw]; 
end; 

procedure TMyButton.SetOwnerDraw(Value: Boolean); 
begin 
    if FOwnerDraw <> Value then 
    begin 
    FOwnerDraw := Value; 
    RecreateWnd; 
    end; 
end; 
+0

RecreateWnd era la parola magica che ora conosco :) –

5

si può fare in questo modo:

  1. Fai proprietà OwnerDraw.
  2. Verificare questa proprietà in CreateParams e cambiare comportamento di conseguenza.
  3. Chiama il numero RecreateWnd ogni volta che la proprietà cambia.

Invece dell'articolo 3, è possibile modificare semplicemente lo stile della finestra con una chiamata a SetWindowLong. Assicurati di testare HandleAllocated prima di provare a farlo. Nessun punto costringendo la finestra a essere creata inutilmente. Tuttavia, probabilmente dovresti anche forzare un ciclo di pittura ogni volta che ciò accade.

Personalmente, penso che sarei incline a forzare la ricreazione di finestre.

+0

Con "forzare un ciclo di verniciatura" si intende inviare un controllo invalido al controllo? Per quello che vale la tua risposta e NGLN's era esattamente quello che dovevo sapere, RecreateWnd chiama CreateParams e lo modifica nello stile nativo con un semplice controllo per testare lo stato della proprietà. –

+1

'Invalidate' imporrà un ciclo di verniciatura. Si noti che 'RecreateWnd' non chiama' CreateParams'. Semplicemente distrugge la finestra. Quando il controllo richiede un handle di finestra, verrà creato e quindi viene chiamato 'CreateParams'. Le maniglie delle finestre vengono create su richiesta. –

+0

Vedo grazie per averlo chiarito, sembra che ho imparato un'altra parola chiave oggi in 'RecreateWnd' :) –

Problemi correlati