Title: Drawing on the screen, outside the form
Question: How I can draw anything outside the form.
Answer:
You can draw outside a form (or window) by using device context obtained through GetDC(0) function. See functions below for details.
procedure TForm1.Button1Click(Sender: TObject);
var
DC, memDC: HDC; //TwinControl
x, y: Integer;
bmp: HbitMap;
begin
x:=Left; y:=Top - 40;
DC:=GetDC(0);
memDC:= CreateCompatibleDC(DC);
bmp:=CreateCompatibleBitMap(DC, 20, 20);
try
SelectObject(memDC, bmp);
BitBlt(memDC, 0, 0, diameter, diameter, DC, x, y, SRCCOPY);
while x BitBlt(DC, x, y, 20, 20, memDC, 0, 0, SRCCOPY);
Inc(x, 5);
BitBlt(memDC, 0, 0, 20, 20, DC, x, y, SRCCOPY);
Ellipse(DC, x, y, x+20, y+20);
Sleep(50);
end;
BitBlt(DC, x, y, 20, 20, memDC, 0, 0, SRCCOPY);
finally
DeleteDC(memDC);
DeleteObject(bmp);
ReleaseDC(0, DC);
end;
end;
or more sophisticated:
procedure TForm1.Button1Click(Sender: TObject); //Start drawing
var
DC, memDC: HDC;
begin
if FStart then exit;
x:=Left - offset - diameter; y:=Top - offset - diameter;
DC:=GetDC(0);
memDC:= CreateCompatibleDC(DC);
bmp:=CreateCompatibleBitMap(DC, diameter, diameter);
try
SelectObject(memDC, bmp);
BitBlt(memDC, 0, 0, diameter, diameter, DC, x, y, SRCCOPY);
finally
DeleteDC(memDC);
ReleaseDC(0, DC);
end;
FStart:=true;
end;
procedure TForm1.Button2Click(Sender: TObject); //Stop drawing
var
DC, memDC: HDC; //TWinControl
begin
if not FStart then exit;
FStart:=false;
DC:=GetDC(0);
memDC:= CreateCompatibleDC(DC);
try
SelectObject(memDC, bmp);
BitBlt(DC, x, y, diameter, diameter, memDC, 0, 0, SRCCOPY);
finally
DeleteDC(memDC);
ReleaseDC(0, DC);
end;
DeleteObject(bmp);
end;
procedure TForm1.Timer1Timer(Sender: TObject);
var
DC, memDC: HDC; //TWinControl
begin
if not FStart then exit;
DC:=GetDC(0);
memDC:= CreateCompatibleDC(DC);
try
SelectObject(memDC, bmp);
BitBlt(DC, x, y, diameter, diameter, memDC, 0, 0, SRCCOPY);
if x=Left-offset-diameter then begin
if y=Top-offset-diameter then Inc(x, Step)
else Dec(y, Step)
end else if x=Left+Width+offset then begin
if y=Top+Height+offset then Dec(x, Step)
else Inc(y, Step);
end else if y Inc(x, Step);
end else begin
Dec(x, Step)
end;
if x if xLeft+Width+offset then x:=Left+Width+offset;
if y if yTop+Height+offset then y:=Top+Height+offset;
BitBlt(memDC, 0, 0, diameter, diameter, DC, x, y, SRCCOPY);
Ellipse(DC, x, y, x+diameter, y+diameter);
finally
DeleteDC(memDC);
ReleaseDC(0, DC);
end;
end;
This code contains many restrictions and you can improve it.
You must remember two things:
- InvalidateRect(0, nil, false) enables you redraw all window
- Then the function retrieve image from a memory buffer you can get wrong picture on your screen. This error occurs then background window those surface was stored into the buffer change its contents and later our function restore old (already wrong) picture.