|
Tutorial 3. Working with vector objects Next | Previous
|
|
Creating non-rectangular windows
|
|
In this example we will use vector objects to vectorize some image regions. Then we will use the regions obtained to create non-standard windows by using the SetWindowRgn API function.
First, we create a new project with two forms: Form1 and Form2. Then we remove Form2 from the auto-creation list (use the Project/Options menu, Forms tab, ‘>>’ button).
We next drop TZBitmapLink, TZImageBox and TZMarkerLayer (PixeLook palette page) onto Form1 and set the following properties in the Object Inspector (see Tutorial 1 for details of the TZBitmapLink component):
|
ZBitmapLink1.MappingMode =mmDisk ZBitmapLink1.Active = true ZImageBox1.Align = alClient ZImageBox1.BitmapLink = ZBitmapLink1 ZMarkerLayer1.Parent = ZImageBox1, this attaches the layer to ZImageBox1 ZMarkerLayer1.Active = true, this activates the layer, so that it can accept mouse messages
|
|
As we will outline image regions, we need only closed vector objects. So we set the following elements of the ZMarkerLayer1.ObjectTypes property:
|
otPoint = false otLine = false otPolygon = false otRect = true otVector = false otCircle = true otEllipse = true
|
|
Then we create the Form1.OnCreate event handler, where the second form is created:
|
procedure TForm1.FormCreate(Sender: TObject); begin Form2:=TForm2.Create(Self); Form2.Show; // place your own image here ZBitmapLink1.FileName:='c:/padlock.bmp'; end;
|
|
We now drop the standard TImage component onto Form2, and set the following properties in the Object Inspector:
|
|
|
|
With these properties, Form2 will look like just an image (no caption or borders).
Using the Object Inspector we load the 'c:/padlock.bmp' image to the Form2.Image1.Picture object.
We then create the second piece of code (ZMarkerLayer1.OnMouseUp event handler) where the shape of Form2 is changed according to vector objects:
|
procedure TForm1.ZMarkerLayer1MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Double); var P:array of TPoint; Num:array of integer; Point:TDPoint; N,i,j:integer; R:HRGN; begin with ZMarkerLayer1 do begin //Count a number of points in all vector objects N:=0; for i:=0 to Objects.Count-1 do inc(N,Objects[i].SplineCount); //Allocate an array for all points SetLength(P,N); // Allocate an array of integers, each of which specifies the number of points in one of the polygons SetLength(Num,Objects.Count); // Copy all points of vector objects to the array N:=0; for i:=0 to Objects.Count-1 do //iterate over all objects begin Num[i]:=Objects[i].SplineCount; for j:=0 to Objects[i].SplineCount-1 do //iterate over all object's points begin Point:=Objects[i].Spline[j]; // get next point P[N].X:=round(Point.X); P[N].Y:=round(Point.Y); inc(N); end; end; // Create a Windows region from all vector objects R:=CreatePolyPolygonRgn(P[0],Num[0],Objects.Count,ALTERNATE); end; //Change shape of Form2 according to new region SetWindowRgn(Form2.Handle,R,true); end;
|
|
Now you can run the program and put a few vector objects onto the Form1. You will see that Form2 changes its shape according to the vector objects. You can select rectangles, circles, ellipses or polygons. A polygon can be smoothed using the context menu or the toolbar buttons. The following picture shows an example, where the region consists of 2 ellipses, 2 rectangles and 3 polygons:
|
|
|