怎么在画布上画虚框?
http://www5.eastgame.net/attachment/154/jpg/485336_4384156.jpg
(一般都是用来做选择框的)
如何实现在画布上画一个虚框呢
thx
问题点数:30、回复次数:17Top
1 楼drift1981(delphi coder)回复于 2004-08-21 15:22:51 得分 3
把画笔风格换成虚线就行了
canvas.pen.style:=psdashTop
2 楼setdefault(山转水也转)回复于 2004-08-21 15:26:38 得分 3
Canvas->Pen->Mode = pmXor;
Canvas->Pen->Style =psDashDot ;
Canvas->Pen->Color = clYellow;
Canvas->Brush->Style =bsClear;
onmousedown时记录Point和标志Bool mousedowned=true
OnMouseMove if (mousedowned) Canvas->Rectangle(...);
OnMouseUpBool mousedowned=fasle
Top
3 楼drift1981(delphi coder)回复于 2004-08-21 15:29:57 得分 3
procedure TForm1.BitBtn1Click(Sender: TObject);
begin
canvas.Pen.Style := psdash;
canvas.Pen.Color := clblue;
canvas.MoveTo(50,50);
canvas.LineTo(50,300);
canvas.LineTo(300,300);
canvas.LineTo(300,50);
canvas.LineTo(50,50);
end;
Top
4 楼imfzp(阿良)回复于 2004-08-21 23:36:55 得分 0
看样子我没说清楚,我要的虚框就是比如你要复制区域图片
拖动鼠标框住选择区域,此时显示的虚框
是可以消失的那种,不是在画布上直接画Top
5 楼miky(miky)回复于 2004-08-22 01:09:12 得分 3
是在画布上直接画的,不然画哪呢?
想偷懒有个API.Windows.DrawFocusRect,他也用的XOR方式,画一次是画上去,再画一次就变成删除了.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs;
type
TForm1 = class(TForm)
procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
StartPoint:TPoint;
ARect: TRect;
implementation
{$R *.dfm}
procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
StartPoint.X := X;
StartPoint.Y := y;
end;
procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
//这只是个简单演示,具体坐标还要计算一下.
if ssLeft in Shift then
begin
Windows.DrawFocusRect(Canvas.Handle,ARect);
Arect.TopLeft := StartPoint;
Arect.Bottom := y;
ARect.Right := x;
Windows.DrawFocusRect(Canvas.Handle,ARect);
end;
end;
end.
Top
6 楼ehom(?!)回复于 2004-08-22 07:57:58 得分 1
Canvas.DrawFocusRectTop
7 楼ehom(?!)回复于 2004-08-22 07:59:41 得分 1
同样坐标再调用一次消失,没必要直接调GDI,TCanvas封装了~~~下次喷到类似问题自己先试试,猜也能猜出来啊Top
8 楼whitetiger8(键盘未敲坏,基本功未练成)回复于 2004-08-22 08:31:38 得分 1
canvas.pen.style:=psdash
Top
9 楼exu(大脸猫)回复于 2004-08-22 21:15:35 得分 1
最简单的办法就是DrawFocusRectTop
10 楼beigua111(冷月葬诗魂)回复于 2004-08-22 21:40:13 得分 3
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Label1: TLabel;
procedure Label1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure FormCreate(Sender: TObject);
procedure Label1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
procedure Label1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
private
{ Private declarations }
draw: Boolean;
sx,sy,tx,ty: Integer;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Label1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
draw := true;
sx := x;
sy := y;
tx := x;
ty := y;
label1.Canvas.Pen.Color := clblack;
label1.Canvas.Pen.Style := psdot;
label1.Canvas.Pen.Mode := pmnotxor;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
draw := false;
end;
procedure TForm1.Label1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
if draw then
begin
label1.Canvas.Rectangle(sx,sy,tx,ty);
label1.Canvas.Rectangle(sx,sy,x,y);
tx := x;
ty := y;
end;
end;
procedure TForm1.Label1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if draw then
begin
label1.Canvas.Rectangle(sx,sy,tx,ty);
label1.Canvas.Rectangle(sx,sy,x,y);
draw := false;
end;
end;
end.
Top
11 楼beigua111(冷月葬诗魂)回复于 2004-08-22 21:42:52 得分 2
如果要最后mouseup的时候虚线也取消的话
那么把label1.Canvas.Rectangle(sx,sy,x,y);注释就可以了 mouseup函数中的Top
12 楼miky(miky)回复于 2004-08-23 22:01:30 得分 2
Canvas.DrawFocusRect有问题,不好用,而且他也是调用windows.DrawFocusRect,直接使用更经济。Top
13 楼ehom(?!)回复于 2004-08-24 17:27:01 得分 1
有问题?什么问题?
直接使用更经济?那不如回到面向过程时代写程序,肯定执行效率更高.我认为这种时候100%的考虑设计优先.一共还没几个时钟周期的差别.Top
14 楼miky(miky)回复于 2004-08-24 19:49:14 得分 1
看这里,我很久以前提问的,不过没有得到满意的答案。
http://community.csdn.net/Expert/topic/2630/2630124.xml?temp=.5432093
设计优先,应该体现在大方面,至于细节,各人有各人的实现方式。VCL对API的支持是非常好的。如果熟悉API,我觉得完全可以大方去用,效率高点有什么不好呢?
Top
15 楼ehom(?!)回复于 2004-08-24 20:29:05 得分 3
注意,是说程序设计,不是软件设计~~~重视大方面,不等于完全忽视细节.各人是有个人的方法,但有必要学习比较好的方法,放弃自己不好的做法
合格的Windows程序都熟悉API,但不等于会在这种情况下去调不经过封装的API.
可以根据具体需要封装自己的多线程类,自己的WinSock类,自己的DC类~~~其实这也可以理解是"直接"调用API,就像MFC自己的CDC封装的很浅,你完全可以自己封装过.
你在一个事件直接调用API有时候是可以,也很方便,但注意这里调用的不是一个独立性很强的API,这里还用到了Canvas.Handle,就是非常不好的做法,这造成了和Canvas对象的耦合.为产生问题埋下了隐患
至于你的帖,没看出两种做法会产生任何效果上的差异Top
16 楼yourlin(信我者必得救)回复于 2004-08-25 00:10:35 得分 1
哇
楼上的分析的好透彻PF PF
路过学习Top
17 楼beigua111(冷月葬诗魂)回复于 2004-08-27 18:02:56 得分 1
搞糊涂了
不是很简单的吗?
怎么大家都说的那么复杂啊?
是不是我理解错了
我的方法可以做吗?Top





