各位英雄,我实在解决不了这个问题了!

Linux2001 2003-03-04 10:58:33
现在我可以使用Canvas.RoundRect画一个圆角矩形,我需要可以画完以后选中这个圆角矩形并且更改他的大小,如何写代码啊,我只能画出他来,不知道如何选中和修改大小啊。英雄们,帮我一下吧
...全文
26 23 打赏 收藏 转发到动态 举报
写回复
用AI写文章
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
Linux2001 2003-03-06
  • 打赏
  • 举报
回复
要求不高啊。
tongdings 2003-03-06
  • 打赏
  • 举报
回复
这样会晕死人的.
还是算了
proman 2003-03-06
  • 打赏
  • 举报
回复
你的要求太高了吧.
myling 2003-03-06
  • 打赏
  • 举报
回复
晕,这么复杂,

up吧
Linux2001 2003-03-06
  • 打赏
  • 举报
回复
哪位英雄行行好,我现在已经可以生成一个矩形(圆角),并且给矩形四个角上增加四个小矩形用于拖拉。我现在只需要英雄们给我一个可以拖拉这些小矩形的代码并且根据拖拉小矩形的方向改变圆角矩形圆角的弧度就可以了。谢谢了
Linux2001 2003-03-06
  • 打赏
  • 举报
回复
jackyshenno1@163.com
各位不要发垃圾邮件给我阿,谢谢 taxi(游少爷)
taxi 2003-03-06
  • 打赏
  • 举报
回复
不过没有改变圆角大小的功能。
taxi 2003-03-06
  • 打赏
  • 举报
回复
留下油箱,给你一个例子。
qiume 2003-03-06
  • 打赏
  • 举报
回复
帮你UP
Linux2001 2003-03-05
  • 打赏
  • 举报
回复
楼上的大哥,我把你的代码复制到新工程中,为什么没有反应啊
jeff 2003-03-05
  • 打赏
  • 举报
回复
也省心不到那里去。如果你有两个线是重合的,都是红色,但是隶属不同的图形,你异或一把,肯定要麻烦。
jeff 2003-03-05
  • 打赏
  • 举报
回复
哦,忘记了,使用异或要多少省心一点。
jeff 2003-03-05
  • 打赏
  • 举报
回复
靠,这么麻烦的问题!!!
你以为你随便写一写就能实现这么麻烦的功能吗?如果仅仅是画一个小小的矩形,然后再使用鼠标拖动,改变大小的话,写写代码就可以实现,你做的东西总不至于是仅仅在Canvas上画一个矩形吧,你怎么也要考虑可以画圆,画矩形,画椭圆,画线,然后拖动,更改大小,删除,随随便便的写一些代码,会死人的。
你首先需要申请一块内存,内存中存储各个图形的性质,比如图形类型,中心位置,长度,宽度等等等等。然后在鼠标移动的时候,马上去内存中找,是否鼠标在一个图形的框上,如果在的话,立马更改图标,然后等待用户按下鼠标。
在用户按下鼠标的时候还需要有一个状态,标记当前是否选择了图形,并判断用户的操作(你还需要在上面放上一堆的快捷按钮,表示是移动,更改大小等)。
在判断用户的操作后,你才开始完成画新图形的功能,就是说,首先将原来的图形擦除(使用背景色重新画原来图形),然后再在新位置画新的图形。每次鼠标移动都要擦除和画。一直到用户鼠标放开为止。这样就完成了修改大小的功能。
但是,这些就够了吗?错,如果Canvas上有很多其他的图形,由于你擦除的时候是使用Canvas在上面画背景色的圆图形,如果要画的图形和别的图形有交叉,你在画背景色图形(擦除)的时候就把原来的图形擦除了。因此在擦除后你还需要判断是否有交叉的图形。如果有你还要画其他的图形。
图形移动也是这样的原理,相对简单一些。不过如果你想做的好,同样需要考虑这些问题。
另外,你还要考虑算法的问题。如果上面有10000个图形,且有些是交叉的,这样你在重新画的时候又要擦除,又要画新的,还要画旧的,你看看你的算法是否在用户忍受的时间中完成。
然后总体的思路就出来了:首先申请两个内存,一个存储当前的界面上有多少个图形,并给出图形的Rect范围(判断是否交叉),一个存储各个图形的参数。然后在鼠标移动的时候(如果键没有按下)判断是否移动到某一个图形的边界,或者如果用户选择移动的话判断用户选择的是哪一个图形(靠,更麻烦,因为如果图形交叉的话,你怎么判断?是否还要设置哪个图形在前面,哪个图形在后面?),并更改鼠标的样式。如果按键有按下,判断是否是更改大小或者移动位置。然后对鼠标的移动写程序(画旧的,画新的,画原来的)。
当然你还要考虑一个问题,就是Form.Canvas属性是不具有Paint功能的,就是说你在Form.Canvas上画一个图形,然后使用其他的界面覆盖该Form,然后在显示该Form,图形就没有了,因此你还有考虑Form的Repaint的时候该怎么办。
干脆你把需求给我详细描述一下,我帮你写一个框架算了。
proman 2003-03-05
  • 打赏
  • 举报
回复
啊,写了一大段都丢了,总之代码不多啦, 主要是控制鼠标的状态了和采用异或模式画图。http://gimis.8800.org/Download.shtml
到这里下个编辑平台,增加一点感性认识,很快就会了。
Borlandor 2003-03-05
  • 打赏
  • 举报
回复
给你个橡皮条先,你拖动任何对象时,总得给出一个虚框吧:

unit TrackerBand;

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);
procedure FormMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}
type
TDrawFlag = (dfToDraw,dfDrawing,dfDrawn);
var
TrackerBrush: TBrush = Nil;
TrackerPen: TPen = Nil;
HalfToneBrush:TBrush = Nil;
OldDragRect: TRect = (Left:0;Top:0;Right:0;Bottom:0);


procedure InitHalfToneBrush;
var grayPattern:array[0..7] of WORD;
grayBitmap:HBITMAP;
I:Integer;
begin
if HalfToneBrush = Nil then
begin
HalfToneBrush := TBrush.Create;
for I := 0 to 7 do
grayPattern[i] := WORD(($5555 shl (I and 1)));
grayBitmap := Windows.CreateBitmap(8, 8, 1, 1, @grayPattern);
if (grayBitmap <> 0) then
begin
HalftoneBrush.Handle := Windows.CreatePatternBrush(grayBitmap);
Windows.DeleteObject(grayBitmap);
end;
end;
end;

procedure DrawDragRect(DC:HDC;NewRect:TRect;DragFlag:TDrawFlag;BandWidth:Integer = 3);
var rgnNew,rgnOld,rgnTemp:HRGN;
SaveIndex: Integer;
TempRect: TRect;
begin
SaveIndex := Windows.SaveDC(DC);
try
{ Get the region which is the old border }
if DragFlag = dfToDraw then rgnOld := 0
else begin
TempRect := OldDragRect;
rgnTemp := Windows.CreateRectRgnIndirect(TempRect);
Windows.InflateRect(TempRect,BandWidth,BandWidth);
rgnOld := Windows.CreateRectRgnIndirect(TempRect);
Windows.CombineRgn(rgnOld,rgnOld,rgnTemp,RGN_XOR);
Windows.DeleteObject(HRGN(rgnTemp));
end;

{ Get the region which is the new border }
if DragFlag = dfDrawn then rgnNew := 0
else begin
TempRect := NewRect;
//RectNormalize(TempRect);
OldDragRect := TempRect;
rgnTemp := Windows.CreateRectRgnIndirect(TempRect);
Windows.InflateRect(TempRect,BandWidth,BandWidth);
rgnNew := Windows.CreateRectRgnIndirect(TempRect);
Windows.CombineRgn(rgnNew,rgnNew,rgnTemp,RGN_XOR);
Windows.DeleteObject(HRGN(rgnTemp));
end;

{ Get the different region between new and old }
if rgnNew = 0 then rgnNew := Windows.CreateRectRgn(0,0,0,0);
Windows.CombineRgn(rgnNew,rgnNew,rgnOld,RGN_XOR);

{ Draw into the border region which need to be updated }
Windows.SelectClipRgn(DC,rgnNew);
Windows.GetClipBox(DC,TempRect);
Windows.SelectObject(DC,HalfToneBrush.Handle);
with TempRect do
Windows.PatBlt(DC,Left,Top,Right-Left,Bottom-Top,PATINVERT);

if rgnOld <> 0 then Windows.DeleteObject(HRGN(rgnOld));
if rgnNew <> 0 then Windows.DeleteObject(HRGN(rgnNew));

{ Remove the clip region }
Windows.SelectClipRgn(DC,0);
finally
Windows.RestoreDC(DC,SaveIndex);
end;
end;


procedure InitGlobalObjects;
var
HatchPattern: Array[0..7] of WORD;
WPattern: WORD;
I: Integer;
HatchBitmap:HBITMAP;
begin
WPattern := $1111;
if TrackerBrush = Nil then
begin
TrackerBrush := TBrush.Create;
{Create the hatch pattern + bitmap}
for I := 0 to 3 do
begin
HatchPattern[i] := WPattern;
HatchPattern[i+4] := WPattern;
WPattern := WPattern shl 1;
end;

HatchBitmap := Windows.CreateBitmap(8, 8, 1, 1, @HatchPattern);
if HatchBitmap <> 0 then
begin
{ Create black hatched brush }
TrackerBrush.Handle := Windows.CreatePatternBrush(HatchBitmap);
Windows.DeleteObject(HatchBitmap);
end;

if TrackerPen = Nil then
begin
TrackerPen := TPen.Create;
{create black dotted pen}
TrackerPen.Handle := CreatePen(PS_DOT, 0, RGB(0, 0, 0));
end;
end;

InitHalfToneBrush;
OldDragRect := Rect(0,0,0,0);
end;

procedure ReleaseGlobalObjects;
begin
if HalfToneBrush <> Nil then HalfToneBrush.Free;
if TrackerBrush <> Nil then TrackerBrush.Free;
if TrackerPen <> Nil then TrackerPen.Free;
end;



procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
DrawDragRect(Canvas.Handle,Rect(X,Y,X,Y),dfToDraw,4);
end;

procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
if ssLeft in Shift then
DrawDragRect(Canvas.Handle,Rect(OldDragRect.Left,OldDragRect.Top,X,Y),dfDrawing,4);
end;

procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
DrawDragRect(Canvas.Handle,Rect(OldDragRect.Left,OldDragRect.Top,X,Y),dfDrawn,4);
end;

Initialization
InitGlobalObjects;
finalization
ReleaseGlobalObjects;

end.
proman 2003-03-05
  • 打赏
  • 举报
回复
补充: 你需要Panit事件中进行画图操作,这样才不会被别的东西擦掉.
proman 2003-03-05
  • 打赏
  • 举报
回复
是啊,我一开始写了,可是网页出错全丢了,你先看看我推荐你下的画图的平台,增加一点感性认识.
针对你的要求
1.你需要在内存中有一个变量能够保存你当前画的矩形的参数.这一点想必你是有的.
2.当鼠标触发了MouseDown事件时,你需要根据鼠标的位置进行选中操作.针对你目前的要求,也就是调用一下PointInRect函数而已.
3.如果选中,则你的作法是在矩形的四个角再把四个小符号标记出来,对吧.但是你要有个变量记住,当前处于选中状态.
4.当你的鼠标再次触发MouseDown时,你需要判断当前是否处于选中状态,如果处于选中状态,你则需进一步判断是当前的鼠标位置是否又选中了你的矩形的四个角.如果选中则需要把这个状态记下来,或都说你的操作当前的状态的变化由一开始的图形选中,到编辑点的选中进入了编辑状态.
5.当你的鼠标处于编辑状态时,鼠标在移动的时候最好能够画出当前的图形的样子,这需要使用异或模式作图.
6异或模式的基本思路是,当你进入编辑状态以后,就需要把画笔设为异或模式.
然后在每次移动时用你鼠标选中点的对角点和鼠标的当前点画一个矩形,但是注意需要画两次,就是说你需要记住上一次MouseMove事件中的点的位置,首先用上一个位置画一次,由于是异或模式,因此刚好是把上一次画的图去除,再在新的位置上画一次.
7.你需要处理MouseUp事件,在MouseUp事件中,再把前面的图擦掉,最好把画笔改成原来的模式画出新的矩形.
8.简单的图形编辑就是这样了.
当然如果你需要处理大量的图形就不是这样简单了.
如果你确实需要处理大量的图形,建议你寻找专业的组件.我上面说的那个就不错.
Linux2001 2003-03-05
  • 打赏
  • 举报
回复
帖子又看不见了
Linux2001 2003-03-05
  • 打赏
  • 举报
回复
还有人吗
Linux2001 2003-03-05
  • 打赏
  • 举报
回复
我仅仅是需要创建一个圆角矩形并且可以选中它,在选中它的时候,圆角矩形四周生成四个可以拖拉的点,这些点的拖拉可以改变圆角矩形的大小和圆角的弧度!
加载更多回复(3)

5,388

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧