{Par bestiol, bestiol@club-internet.fr

Voici une application montrant comment dessiner sans utiliser de canvas, et
aussi comment dessiner sur un composant qui ne possède pas de Canvas

Tous les commentaires sont permis, exceptés les injures et le fait que j'ai
choisis des assemblages de couleurs immondes !!

Bestiol.}

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ImgList, commctrl;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    Button4: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button4Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
Var DC: HDC; //DC: Device Context. Le DC remplace le canvas (TCanvas.Handle est
             //de type HDC
    Brush: HBRUSH;
    Pen: HPEN;
begin

  DC := GetDC(Memo1.Handle); //On crée un Device Context pour le Memo

  Brush := CreateSolidBrush(clFuchsia);
  SelectObject(DC, Brush);
  //Il faut indiquer à Windows quel "matériel" utiliser et pour
  //quel DC... On crée donc un objet Brush de couleur Fuchsia qu'on assigne au
  //DC du mémo

  Pen := CreatePen(PS_SOLID, 2, clBlack);
  SelectObject(DC, Pen);
  //Idem pour le pinceau (contour du rectangle)

  Rectangle(DC, 20, 20, Memo1.Width - 20, Memo1.Height - 20);
  //Appel de l'API permettant de dessiner un rectangle tout comme avec le Canvas,
  //le DC en plus

  DeleteObject(Brush);
  DeleteObject(Pen);          //On supprime ici la mémoire allouée pour nos
  ReleaseDC(Memo1.Handle, DC);//objets et le DC;

end;

procedure TForm1.Button4Click(Sender: TObject);
Var DC: HDC; //Toujours notre Device Context;
    Brush: HBRUSH;
    Pen: HPEN;
begin

  DC := GetDC(Memo1.Handle); //On crée un Device Context pour le Memo

  Brush := CreateSolidBrush(clLime);
  SelectObject(DC, Brush);
  //Mêmes opérations que pour le rectangle

  Pen := CreatePen(PS_SOLID, 2, clBlue);
  SelectObject(DC, Pen);
  //Idem ;)

  Ellipse(DC, 20, 20, Memo1.Width - 20, Memo1.Height - 20);
  //C'est toujours comme le rectangle, mais c'est une ellipse !

  DeleteObject(Brush);
  DeleteObject(Pen);          //On supprime ici la mémoire allouée pour nos
  ReleaseDC(Memo1.Handle, DC);//objets et le DC;

end;

procedure TForm1.Button2Click(Sender: TObject);
Var DC: HDC;
    Fonte: HFONT;
begin

  DC := GetDC(Memo1.Handle); //On crée un Device Context pour le Memo

  SetBkMode(DC, TRANSPARENT);//Le Fond du texte sera transparent, ce qui évite
                             //un joli rectangle blanc autour du texte.

  Fonte := CreateFont(0, 0, 0, 0, FW_NORMAL, 0, 0, 0,
                      DEFAULT_CHARSET, 0, CLIP_DEFAULT_PRECIS,
                      DEFAULT_QUALITY, DEFAULT_PITCH or FF_DONTCARE,
                      PChar('Arial'));
  //Création de la fonte. Y a beaucoup de paramètres, mais les plus intéressants
  //sont l'orientation (3eme et 4eme), les 4 suivants pour déterminer "l'épaisseur"
  //du texte et s'il est en italique, souligné, barré et le dernier permettant de
  //choisir la fonte.

  SelectObject(DC, Fonte);
  //Création de la fonte et son assignation au DC

  TextOut(DC, Memo1.Width div 2,
          Memo1.Height div 2 - 9, PChar('Bestiol'), Length('Bestiol'));
  //Même fonction qu'avec le canvas. Il faut juste rajouter, outre le DC, la
  //taille du texte à écrire.

  DeleteObject(Fonte);        //On supprime ici la mémoire allouée pour nos
  ReleaseDC(Memo1.Handle, DC);//objets et le DC;

end;

procedure TForm1.Button3Click(Sender: TObject);
Var DC: HDC;             //encore et toujours le même !
    ImgLst: HIMAGELIST;  //Une "ImageList"
    Bmp, Masque: TBitmap;//L'image à dessiner, son masque (pour la transparence)
    PosX, PosY: Integer; //et les variables pour les coordonnées de l'image.
begin

  DC := GetDC(Memo1.Handle); //On récupère le DC

  Bmp := TBitmap.Create;      //Création d'un bitmap et
  Bmp.LoadFromFile('Ol.bmp'); //chargement de l'image à dessiner

  Masque := TBitmap.Create;         //Création d'un bitmap pour
  Masque.LoadFromFile('Masque.bmp');//recevoir le masque de transparence

  ImgLst := ImageList_Create(32, 32, ILC_COLOR24 or ILC_MASK, 0, 1);
  //On crée une ImageList acceptant des images de 32 par 32 en 16 millions de
  //couleurs (24 bits) et un masque de transparence pour chaque image...

  ImageList_Add(ImgLst, Bmp.Handle, Masque.Handle);
  //On ajoute à cette liste le bitmap créé précédemment
  //en lui assignant le masque créé...

  PosX := Memo1.Width div 2 - Bmp.Width div 2 - 20;
  PosY := Memo1.Height div 2 - Bmp.Height div 2;

  ImageList_Draw(ImgLst, 0, DC, PosX, PosY, ILD_TRANSPARENT);
  //Et on dessine cette image, avec transparence.

  ReleaseDC(Memo1.Handle, DC); //on libère le DC,
  ImageList_Destroy(ImgLst);   //l'ImageList
  Bmp.Free;                    //et le bitmap

end;

end.
