9
votes

Comment pouvez-vous modifier la couleur de la police d'un contrôle activé par thème?

Oui, c'est encore une fois cette question:

Comment puis-je modifier la couleur de la police d'une boîte TCHeckBox (ou de tout contrôle manipulé) avec DelphI7-> Delphi2007 sur une application activée par thèmes?

Après avoir beaucoup lu sur Internet et sur ce site, j'ai trouvé 4 types de réponse:

  1. et la plupart des populaires (même de QC): vous ne pouvez pas, il est conçu comme celui de Microsoft.
  2. Créez un composant qui vous permet de le dessiner comme vous le souhaitez.
  3. Achetez un ensemble de composants coûteux qui attire comme vous le souhaitez.
  4. Ne pas utiliser de thèmes.

    OK, mais je suis toujours malheureux de cela.

    Donner des commentaires colorés par l'utilisateur pour l'état d'une propriété / des données qu'il a sur un formulaire, me semble légitime.

    Puis je viens d'installer l'édition Express MSVC # 2008 et quelle surprise, ils peuvent changer la couleur de la police (prévisorif de propriété de la case à cocher), alors quoi?

    Il ne semble pas être un "Il est conçu comme ça, par Microsoft". alors maintenant la question:

    Comment puis-je modifier la couleur de la police d'une boîte de police (ou d'une commande manipulée) avec Delphi 7 via Delphi 2007 sur une application activée sur le thème?


2 commentaires

Qu'est-ce qui vous fait penser que les développeurs de Visual Studio n'ont tout simplement pas utilisé l'option 2?


Eh bien, je n'avais pas besoin, tout en essayant de reproduire que "c'est conçu comme ça, par Microsoft". sur c #. J'ai défini le préviseur en rouge et obtenez une légende rouge pour ma case à cocher.


5 Réponses :


0
votes

Option 5. Utilisez le contrôle TYOU comme comme une option de base et remplacez tous les messages de peinture du contrôle (oui, vous pouvez appeler un composant mais le contrôle est le nom des composants visibles afin que vous puissiez plutôt utiliser cela). Tout simplement attraper le WM_Paint, éventuellement le WM_NCPAINT, vous pouvez dessiner le contrôle dans votre propre style. Au moins, vous pouvez réutiliser toute la fonctionnalité du contrôle. Tant que vous ne changez pas la disposition, seules les couleurs que vous n'aurez pas besoin de changer les Hittsts Mousedowns. up mouvements, etc.

Remarque: j'ai l'expérience avec le remplacement de TCustomedit pour permettre à toutes sortes de couleurs, de texte de fond, de boutons supplémentaires, etc. Il a fallu assez de temps pour le faire correctement et lire tous les documents de MSDN et Ko pour vous assurer que le contrôle a fait ce que je voulais que ça fasse.


6 commentaires

Je comprends que pas comme option 5, mais comme option 2a et mon option 2 comme option 2b; ^)! Mais pourquoi C # n'a pas besoin de remplacer la méthode WM_Paint pour changer la couleur de la couleur de la police d'une composante à cocher?


@Edouard. Ce qui est dans un nom .. À propos de la C # n'en a pas besoin: C # a sa propre couche de contrôle (Microsoft en invente une nouvelle pour l'environnement .NET chaque tant d'années), Delphi utilise les mêmes commandes qui existe depuis Windows 95. plus de stabilité mais parfois vous payez pour que quelque chose de simple devienne plus difficile; GDI est vieux mais je pense que dans 10 ans, GDI est toujours là et que devriez-vous faire avec votre application WinForms? Pensez à ça!


Je sais que le GDI est assez vieux, j'ai commencé à travailler avec elle, quand j'ai fait ma première étape sur Borland Object Pascal sur "Windows 2" quelque chose comme 1988. Ce que vous dites est: C # peut faire cela, car ils utilisent un totalement différent des contrôles que celui utilisé par Delphi tandis que les thèmes sont activés? Comme la chose à thème est responsable de dessiner les nouvelles choses, je suppose que Delphi utilise les mêmes composants (ORT au moins une bibliothèque) que c # utilisation.


À propos, j'ai maintenant également testé que sur Access2003: Créer un formulaire, ajoutez une case à cocher, puis définissez le prévisueur au rouge, et ici aussi ses éléments de travail (composants thématiques + cases de couleur) !!! Et je suis sûr que Access2003 est conçu pour utiliser GDI plus âgé que Delphi2007.


@Edouard: Access utilise sa propre bibliothèque de contrôle personnalisée (option 2.) RE C #: Cela dépend de la bibliothèque dont vous parlez (Winforms, WPF, ...?) Mais si c'est des winforms, il enveloppe et s'étend probablement (option 2 !) La Windows intégrée contrôle. Si c'est quelque chose comme WPF, il s'agit d'une bibliothèque de contrôle complètement différente.


Pourquoi n'aimes-tu pas les réponses que tu as déjà eues? Les options que vous listez sont précises et valides - vous ne pouvez pas simplement dire "Je ne les aime pas, alors je vais demander à nouveau."



2
votes

Oh, mais vous pouvez!

Placez cela avant em> la déclaration de votre formulaire: p> xxx pré>

cette nouvelle déclaration de TCHECKBOX est maintenant utilisé au moment de l'exécution comme le type diffusant du DFM de votre formulaire. Maintenant, implémentez le message comme celui-ci: p>

procedure TCheckBox.CNCtlColorStatic(var Message: TWMCtlColorStatic);
begin
  SetTextColor(Message.ChildDC, ColorToRGB(clRed)); // or RGB(255,0,0));
  SetBkMode(Message.ChildDC, TRANSPARENT);
  Message.Result := GetStockObject(NULL_BRUSH);
end;


0 commentaires

2
votes

Voici comment j'ai résolu cela dans mon application:

  1. Retirez la légende de la case à cocher et rendu plus petit - juste assez gros pour afficher la case à cocher sans la légende.
  2. Mettez un TLABEL à côté de la case à cocher pour agir en tant que légende.
  3. Dans l'événement OnClick de l'étiquette, bascule l'état de la case à cocher.
  4. Si l'étiquette dispose d'un accélérateur de clavier ALT + Lettre, faites le formulaire Gérer le message CM_DialogChar. Copiez le gestionnaire de messages du code source TLABEL et ajoutez une ligne pour basculer l'état de la case à cocher.

    Ce n'est pas une vraie case, et c'est un peu plus de travail que je le souhaite, mais cela fonctionne assez bien dans mon application (qui n'a qu'une seule case ayant besoin de ce traitement).


0 commentaires

4
votes

Ceci nécessite une solution parfaite pour être une solution parfaite mais a fonctionné pour moi:

Ajoutez 2 méthode à votre case Box composant xxx

et mettre en œuvre de cette façon: xxx


1 commentaires

Je crois que cela devrait être marqué comme réponse, bon travail!



0
votes

Ce code est un code amélioré de @Flicker que le support bidimode code> et la position correcte du texte:

interface
  TMSCheckBox = class(TCheckBox)
  private
    FOriginalCaption: string;
    _MySetCap: Boolean;
    procedure WMPaint (var Message: TWMPaint); message WM_PAINT;
    procedure CMTextChanged(var Message: TMessage); message CM_TEXTCHANGED;
  end;

implementation

procedure TMSCheckBox.CMTextChanged(var Message: TMessage);
begin
  inherited;
  if _MySetCap then Exit;
  FOriginalCaption := Caption;
end;

procedure TMSCheckBox.WMPaint(var Message: TWMPaint);
const
  SPACE   :Integer = 2;
var
  txtW, txtH, txtX,
  BtnWidth: Integer;
  canv: TControlCanvas;
begin
  BtnWidth := GetSystemMetrics(SM_CXMENUCHECK);

  _MySetCap := True;
  if not (csDesigning in ComponentState) then
    Caption := '';
  _MySetCap := False;
  inherited;
  canv := TControlCanvas.Create;
  try
    canv.Control := Self;
    canv.Font := Font;
    txtW:= canv.TextWidth(FOriginalCaption);
    txtH:= canv.TextHeight(FOriginalCaption);
    if BiDiMode in [bdRightToLeft, bdRightToLeftReadingOnly] then
      txtX:= Width - BtnWidth - SPACE - txtW
    else
      txtX:= BtnWidth + SPACE;
    SetBkMode(canv.Handle, Ord(TRANSPARENT));
    canv.TextOut(txtX, (Height - txtH) div 2 + 1, FOriginalCaption);
  finally
    canv.Free;
  end;
end;


0 commentaires