高手请给个思路:关于图像控制(例如选择、拖动等)(100分)

  • 主题发起人 主题发起人 lovebbs
  • 开始时间 开始时间
L

lovebbs

Unregistered / Unconfirmed
GUEST, unregistred user!
请您花一点时间阅读一下:

实例:是平板车的装载问题:火车中一节节向连的平板车上要装载各种类型的车辆,如车辆小
则一节平板车可以装几辆车,有的一节平板车只能装一辆,如车长则两节平板车才能装下
(称为跨装);
现在需在程序里用简单的示意图模拟,平板车可用小长方条代替,车辆
用示意图表示(宽度按比例)。
要求:可以用鼠标选择车辆,并进行拖动,当放到某个空的平板车上时,要能够判断
该车能否被放下。
关于图形图象部分,我不知该如何解决,用位图好还是用矢量图好,以及如何实现对
图形的操作,请高手给个思路!!! 分不是问题.
 
关于图形图象,当然是矢量图好,它只需检索出一个个图元,最好的优点是
操作起来速度快,而且不失真;位图也可以,它的操作相对简单,但是速度和
保真方面有问题.
 
图形操作???
给你举个小例子,相当于图形的移动了 :

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;

type
TForm1 = class(TForm)
procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
OX,OY :Integer;
First :Boolean;

implementation

{$R *.DFM}

procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
if not First then Canvas.Ellipse(ox,oy,ox+150,oy+150);
Canvas.Ellipse(X,Y,X+150,Y+150);
OX :=X;
OY :=Y;
First :=False;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
with Canvas do
Begin
Pen.mode :=pmNotXor;
Pen.color :=clBlack;
pen.Style :=psDot;
Brush.Style :=bsClear;
end;
First:=True;
end;

end.
 
可是你的例子不是很实用,无法实现对图形对象的选择,
 
有个控件CADODRAW也许能帮上忙。
 
以下的代码 有点拖放的意思:

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ExtCtrls;

type
TForm1 = class(TForm)
CarImage: TImage;
Image1: TImage;
procedure CarImageDragOver(Sender, Source: TObject; X, Y: Integer;
State: TDragState; var Accept: Boolean);
procedure Image1DragOver(Sender, Source: TObject; X, Y: Integer;
State: TDragState; var Accept: Boolean);
procedure Image1DragDrop(Sender, Source: TObject; X, Y: Integer);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.CarImageDragOver(Sender, Source: TObject; X, Y: Integer;
State: TDragState; var Accept: Boolean);
begin
Accept := Source is TImage;
end;

procedure TForm1.Image1DragOver(Sender, Source: TObject; X, Y: Integer;
State: TDragState; var Accept: Boolean);
begin
Accept := Source is TImage;
end;

procedure TForm1.Image1DragDrop(Sender, Source: TObject; X, Y: Integer);
var t :TImage;
begin
if Source is TImage then
begin
t := Source as TImage;
Image1.Canvas.Draw(x,y,t.Picture.Bitmap);
end;
end;

end.
 
先对数据进行氏量取存储
然后在鼠标按下时进行判断是否选中图形(判断点在线上,点在多边形内等)
在鼠标移动时判断是否选中图形,如选中则根据新位置重新画
你的图形很简单,应该可以实时显示变化;而不用像delphi设计期拖动控件时画矩形框
 
我给个思路吧,可能并不十分好。

对每部车创建一个TShape,用一个大的TImage绘上背景图(平板车),

然后就只管处理Shape的拖放事件吧。
 
可以参考JohnsonGuo的意见,但是建议从TShape继承出两个新类分别代表平板车和汽车,其中平
板车组件中包含管理汽车组件实例的属性和方法,然后在程序里处理拖放和停放的事件就可以了。

 
这个可以用图层来解决。这样的控件有LayerBitmap.
 
同意LanFairy的意见,我的一个程序就是这样写的。
只要图形不复杂,速度就很快。
 
是否能给个例子,画一条直线,编辑时可移动他,可查看他的属性,如坐标角度等?
谢谢
 
TCAD
http://www.codeidea.com
可以做到这一点
 
我也很希望能得到个例子,画一条直线,编辑时可移动他,可查看他的属性,非常感谢!
 
http://delphi.mychangshu.com/dispdoc.asp?id=556
 
我写了一段代码,有些欠考虑的,还有些我还没想出来怎么解决,不过好歹也能演示一下
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ExtCtrls, ImgList, ComCtrls;

type
TDrawingTool = (dtLine, dtRectangle, dtEllipse, dtRoundRect);
TNode = Record
rectx1 : integer;
rectx2 : integer;
recty1 : integer;
recty2 : integer;
name : string;
pic : tpicture;
//rect : trect;
end;

TLine =record
StartPt,EndPt :TPoint;
end;

TForm1 = class(TForm)
ScrollBox1: TScrollBox;
Image1: TImage;
TreeView1: TTreeView;
ImageList1: TImageList;
procedure Image1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure FormCreate(Sender: TObject);
procedure Image1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure TreeView1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure Image1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
private
{ Private declarations }
pic : tpicture;
name : string;
drawing,moving,Lining : Boolean;
picnode : array of TNode;
ArrLine :array of TLine;
nodecount,nodeselectNo : integer;
LineCount,LineSelectNo :integer;
origin, movept :TPoint;
DrawingTool: TDrawingTool;
procedure DrawShape(TopLeft, BottomRight: TPoint; AMode: TPenMode);
procedure RefreshImage;
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.RefreshImage;
var i :integer;
begin

end;

procedure TForm1.Image1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var
i : integer;
tmprect : trect;
begin
if button = mbleft then
begin
if drawing then
begin
image1.Canvas.Draw(x,y,pic.Graphic);
setlength(picNode,nodeCount+1);
picnode[nodecount].rectx1 := x;
picnode[nodecount].recty1 := y;
picnode[nodecount].rectx2 := x + pic.Width;
picnode[nodecount].recty2 := y + pic.Height;
picnode[nodecount].name := name;
picnode[nodecount].pic := tpicture.Create;
picnode[nodecount].pic := pic;
image1.Canvas.TextOut(picnode[nodecount].rectx1,picnode[nodecount].recty2,picnode[nodecount].name);
nodecount := nodecount + 1;
drawing := False;
end
else
begin
for i := 0 to nodecount do
begin
tmprect := rect(picnode.rectx1,picnode.recty1,picnode.rectx2,picnode.recty2);
if ptinrect(tmprect,point(x,y)) then
begin
moving := true;
nodeselectNo := i;
break;
end;
end;
end;
end else if Button =mbRight then
begin
for i := 0 to nodecount do
begin
tmprect := rect(picnode.rectx1,picnode.recty1,picnode.rectx2,picnode.recty2);
if ptinrect(tmprect,point(x,y)) then
begin
//moving := true;
nodeselectNo := i;
DrawingTool :=dtLine;
lining :=true;
Origin :=point(x,y);
MovePt := Origin;
break;
end;
end;
end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
nodecount := 0;
LineCount :=0;
setlength(picnode,30);
drawing := false;
moving := false;
Lining :=false;
end;

procedure TForm1.Image1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var
tmprect : trect;
i :integer;
CanLine :Boolean;
begin
CanLine :=False;
if button = mbleft then
begin
if moving then
begin
tmprect := rect(picnode[nodeselectno].rectx1,picnode[nodeselectno].recty1,picnode[nodeselectno].rectx2,picnode[nodeselectno].recty2);
image1.Canvas.FillRect(tmpRect);
image1.Canvas.Brush.Color := clWhite;
image1.Canvas.TextOut(picnode[nodeselectno].rectx1,picnode[nodeselectno].recty2,' ');
image1.Canvas.Draw(x,y,picnode[nodeselectno].pic.Graphic);
picnode[nodeselectno].rectx1 := x;
picnode[nodeselectno].recty1 := y;
picnode[nodeselectno].rectx2 := x + picnode[nodeselectno].pic.Width;
picnode[nodeselectno].recty2 := y + picnode[nodeselectno].pic.Height;
image1.Canvas.TextOut(picnode[nodeselectno].rectx1,picnode[nodeselectno].recty2,picnode[nodeselectno].name);
for i :=0 to Length(ArrLine)-1 do
begin
if ptInRect(tmpRect,ArrLine.StartPt) then
begin
DrawShape(Point(x,y),ArrLine.EndPt,PmCopy);
DrawShape(ArrLine.StartPt,ArrLine.EndPt,pmNotXor);
ArrLine.StartPt :=Point(x,y);
end else if ptInRect(tmpRect,ArrLine.EndPt) then
begin
DrawShape(ArrLine.StartPt,Point(x,y),PmCopy);
DrawShape(ArrLine.StartPt,ArrLine.EndPt,pmNotXor);
ArrLine.EndPt :=Point(x,y);
end;
end;
image1.Refresh;
moving := false;
end;
end else if button =mbRight then
begin
if lining then
begin
for i := 0 to nodecount do
begin
tmprect := rect(picnode.rectx1,picnode.recty1,picnode.rectx2,picnode.recty2);
if ptinrect(tmprect,point(x,y)) then
begin
CanLine :=True;
break;
end;
end;
if CanLine then
begin
DrawShape(Origin, Point(X, Y), pmCopy);
inc(LineCount);
setlength(ArrLine,LineCount);
ArrLine[LineCount-1].StartPt :=Origin;
ArrLine[LineCount-1].EndPt :=Point(x,y);
lining :=false;
end else
begin
DrawShape(Origin,Point(x,y),pmNotXor);
lining :=false;
end;
end;
end;
end;

procedure TForm1.TreeView1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var
i : integer;
bmp : tbitmap;
begin
for i := 0 to Treeview1.Items.Count - 1 do
begin
if Treeview1.Items.Selected then
begin
pic := TPicture.Create;
bmp :=TBitmap.Create;
ImageList1.GetBitmap(Treeview1.Items.ImageIndex,bmp);
//SelectIndex := i;
pic.Assign(bmp);
Drawing :=True;
name :=TreeView1.Items.Text;
bmp.Free;
end;
end;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
var
i : integer;
begin
pic.Free;
for i := 0 to nodecount-1 do
picnode[nodecount].pic.Free;
end;

procedure TForm1.Image1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
if lining then
begin
DrawShape(Origin, MovePt, pmNotXor);
MovePt := Point(X, Y);
DrawShape(Origin, MovePt, pmNotXor);
end;
end;

procedure TForm1.DrawShape(TopLeft, BottomRight: TPoint; AMode: TPenMode);
begin
with Image1.Canvas do
begin
Pen.Mode := AMode;
case DrawingTool of
dtLine:
begin
Image1.Canvas.MoveTo(TopLeft.X, TopLeft.Y);
Image1.Canvas.LineTo(BottomRight.X, BottomRight.Y);
end;
dtRectangle: Image1.Canvas.Rectangle(TopLeft.X, TopLeft.Y, BottomRight.X,
BottomRight.Y);
dtEllipse: Image1.Canvas.Ellipse(Topleft.X, TopLeft.Y, BottomRight.X,
BottomRight.Y);
dtRoundRect: Image1.Canvas.RoundRect(TopLeft.X, TopLeft.Y, BottomRight.X,
BottomRight.Y, (TopLeft.X - BottomRight.X) div 2,
(TopLeft.Y - BottomRight.Y) div 2);
end;
end;
end;

end.
 
to JohnsonGuo,SeaHawk:
是不是也可以用Dock事件?拖放事件与Dock事件哪个好控制?
 
后退
顶部