I. Création d'une fenêtre non rectangulaire▲
Pour cela nous allons créer un nouveau projet avec une Form (Form1) avec la propriété BorderStyle à bsDialog.
Sur les événements OnCreate et OnPaint de Form1 :
void
__fastcall TForm1::
FormCreate(TObject *
Sender)
{
HRGN Region;
HRGN SubRgn;
Region =
CreateRectRgn(0
,0
,Width,Height);
SubRgn =
CreateRectRgn(Width/
2
-
100
,Height/
2
-
100
,
Width/
2
+
300
,Height/
2
+
300
);
CombineRgn(Region,Region,SubRgn,RGN_DIFF);
SetWindowRgn(Handle,Region,true
);
DeleteObject(SubRgn);
}
void
__fastcall TForm1::
FormPaint(TObject *
Sender)
{
int
bordx, bordy;
HDC dc;
RECT Rectangl;
bordx =
GetSystemMetrics(SM_CXEDGE);
bordy =
GetSystemMetrics(SM_CYEDGE);
dc =
GetWindowDC(Handle);
Rectangl.left =
Width/
2
-
100
-
bordx;
Rectangl.top =
Height/
2
-
100
-
bordy;
Rectangl.right =
Width/
2
+
300
+
bordx;
Rectangl.bottom =
Height/
2
+
300
+
bordy;
DrawEdge(dc, &
Rectangl, EDGE_SUNKEN, BF_RECT);
ReleaseDC(Handle,dc);
}
Explication
• Vous créez une région avec la fonction CreateRectRgn qui représente la surface de la Form :
Region =
CreateRectRgn(0
,0
,Width,Height);
• Vous créez une seconde région que vous allez combiner avec la première, ici une ronde :
SubRegion =
CreateEllipticRgn(24
, 11
, 281
, 268
);
• Puis vous les combinez ensemble avec la fonction CombineRgn
CombineRgn(Region,Region,SubRegion,RGN_DIFF);
prototype : CombineRgn(HRGN destination, HRGN source1, HRGN source2, int
Mode);
Mode et le mode de combinaison valeurs possibles : RGN_AND, RGN_COPY, RGN_DIFF, RGN_OR, RGN_XOR.
• Puis vous affectez la région à la Form avec : SetWindowRgn(Handle,Region,true
);
• Vous supprimez la 2e région qui ne sert plus. DeleteObject(SubRegion);
• Le mieux est de faire quelques essais avec différentes dimensions et modes de combinaisons des deux régions (vous pouvez même combiner avec une 3e région…).
• Voir aide sur les API Windows CombineRgn, SetWindowRgn, CreateRectRgn, CreateRoundRectRgn, CreateEllipticRgn, CreatePolygonRgn…
• La partie du code qui est dans FormPaint ne sert que pour tracer la bordure, elle n'est pas nécessaire pour la forme de la fenêtre.
Pour ceux qui ont la chance d'avoir BCB6 et Windows 2000 ou XP, on peut faire cela beaucoup plus simplement. Il suffit de mettre la propriété TransparentColor de la Form à true, de poser un TShape ou mieux un TImage sur la Form et d'affecter la couleur du TShape ou l'une des couleurs du Bitmap du TImage à la propriété TransparentColorValue de la Form.