紧急求解,非高手勿言。怎样在image 中用鼠标选中图形的一部分,并对该部分用鼠标拖动、剪切、拷贝,粘贴等。(100分)

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

learningguy

Unregistered / Unconfirmed
GUEST, unregistred user!
大虾们,怎样在image 中用鼠标选中图形的一部分,并对该部分用鼠标拖动、剪切、拷贝,粘贴等。最好提供源代码。谢谢。
 
太简单了吧,你可以自己看看TCanvas的属性,如CopyRect;加上TCliperborad的帮助
 
放置一个Image(TImage),其Align为alClient,放ClipImg(TImage),
其Align先设为alClient,然后改回alNone。
设计一下菜单有CutCmd, CopyCmd, PasteCmd
写代码如下:
...
private
...
StartX,StartY,EndX,EndY:Integer;
MouseDown:Boolean;
...
procedure TMainFrm.ImageMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin //开始选择
if not MouseDown then begin
if ClipImg.Visible then RestoreImage;
MouseDown:=True;
StartX:=X;
StartY:=Y;
EndX:=X;
EndY:=Y;
DrawFrame;
end;
end;

procedure TMainFrm.ImageMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin //选择过程
if MouseDown then begin
DrawFrame;
EndX:=X;
EndY:=Y;
DrawFrame;
end;
end;

procedure TMainFrm.ImageMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin //结束选择
if MouseDown then begin
MouseDown:=False;
if (StartX=EndX) and (StartY=EndY) then begin
DrawFrame;
ClipImg.Visible:=False;
end else begin
with ClipImg,Canvas do begin
Width:=EndX-StartX;
Height:=EndY-StartY;
CopyRect(Rect(0,0,Width,Height),
Image.Canvas,
Rect(StartX,StartY,EndX,EndY));
Visible:=True;
Left:=StartX;
Top:=StartY;
end;
with Image.Canvas do begin
Brush.Color:=clWhite;
Brush.Style:=bsSolid;
FillRect(Rect(StartX,StartY,EndX,EndY));
end;
end;
end;
end;

procedure TMainFrm.FormCreate(Sender: TObject);
var
Bmp:TBitmap;
begin
ClipImg.Visible:=False;
with Image,Canvas do begin
Brush.Color:=clWhite;
FillRect(ClientRect);
end;
end;

procedure TMainFrm.DrawFrame;
begin //在Image上画一个选择框
with Image.Canvas do begin
Brush.Style:=bsClear;
Pen.Color:=clAqua;
Pen.Mode:=pmXor;
Rectangle(StartX,StartY,EndX,EndY);
end;
end;

procedure TMainFrm.CopyCmdClick(Sender: TObject);
var
Bmp:TBitmap;
begin //复制图片
Bmp:=TBitmap.Create;
try
DrawClipFrame;
Bmp.Width:=ClipImg.Width;
Bmp.Height:=ClipImg.Height;
Bmp.Canvas.Draw(0,0,ClipImg.Picture.Bitmap);
ClipBoard.Assign(Bmp);
DrawClipFrame;
finally
Bmp.Free;
end;
end;

procedure TMainFrm.CutCmdClick(Sender: TObject);
begin //剪切图片
CopyCmdClick(Sender);
ClipImg.Visible:=False;
end;

procedure TMainFrm.PasteCmdClick(Sender: TObject);
var
Bmp:TBitmap;
begin //粘贴图片
if ClipBoard.HasFormat(CF_BITMAP) then begin
if ClipImg.Visible then RestoreImage;
Bmp:=TBitmap.Create;
try
Bmp.Assign(ClipBoard);
with ClipImg do begin
Width:=Bmp.Width;
Height:=Bmp.Height;
Canvas.Draw(0,0,Bmp);
Visible:=True;
Left:=0;
Top:=0;
end;
DrawClipFrame;
finally
Bmp.Free;
end;
end;
end;

procedure TMainFrm.DrawClipFrame;
begin //在ClipImg上画一个选择框
with ClipImg,Canvas do begin
Brush.Style:=bsClear;
Pen.Color:=clAqua;
Pen.Mode:=pmXor;
Rectangle(ClientRect);
end;
end;

procedure TMainFrm.RestoreImage;
begin //恢复图像
DrawClipFrame;
with ClipImg do
Image.Canvas.CopyRect(
Rect(Left,Top,Left+Width,Top+Height),
ClipImg.Canvas,
Rect(0,0,Width,Height));
end;

procedure TMainFrm.ClipImgMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin //开始移动选择部分
if not MouseDown then begin
MouseDown:=True;
StartX:=X;
StartY:=Y;
end;
end;

procedure TMainFrm.ClipImgMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin //移动选择部分过程
if MouseDown then begin
ClipImg.Left:=ClipImg.Left+X-StartX;
ClipImg.Top:=ClipImg.Top+Y-StartY;
end;
end;

procedure TMainFrm.ClipImgMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin //结束移动选择部分
if MouseDown then MouseDown:=False;
end;
...

 
to JohnsonGuo:
多谢老兄。只是在image里拖动图形时背景闪烁得厉害。请问如何解决。再谢。
 
响应WM_ERASEBKGND
private
...
procedure WMEraseBkGnd(var Msg:TWMEraseBkGnd); message WM_ERASEBKGND;
end;
...

procedure TForm1.WMEraseBkGnd(var Msg:TWMEraseBkGnd);
begin
Msg.Result:=-1;
end;
 
编译时报错:Undeclared identifier:'ClipBoard',怎办?
 
没有加载ClipBrd单元,当然会报错。
 
O,象ClipBoard这种工具栏上没有的东东以后去哪得知呢?

 
把光标移到ClipBoard上,然后按F1就知道它属于哪一个单元了。
 
to JohnsonGuo :
抱歉,这两天一直在调程序。没有及时向你老兄致谢。
程序作了些修改,已基本调通了。只是还有一点小问题想请教
-- 我在Form上加了coolbar和工具条,这样一来客户区将工具条也算进去了。图象拖动时能进入到
工具条的下面,影响了图象恢复。把image放到panel上,拖动时图象就闪烁不止。(我已捕
获了刷新背景的消息)请问有什么两全的方法。
-- 窗体中捕获刷新背景的消息后,image中位图没填到的地方就露出了背后的其他窗体,
有没有解决方法。
多谢 !
 
1 在图例拖动时限制其拖动即可。

2 响应Form.OnPaint手动重画窗体。
 
恩,我的意思是说工具栏里没有的东东,怎知道还有哪些呢?(凭经验吗)
 
to JohnsonGuo :
再问一个问题 -- 有没有办法做一个透明的panel(不要问为什么)。
我查过以往问题,没有找到现成的。
 
不好意思。问题提得多了些。
 
未曾试过。
 
那么如何用鼠标选中不规则图形呢??
 
非常简单,这些底层的玩意儿自己写太累了,用ImageEN控件就可以搞定了,

安装后在FORM上放一个ImageEN控件,用LOADFROMFILE方法装入图片
(这个控件在设计期无法装入,大概因为它是用OBJ文件链接的原因吧),
然后用它的的MouseInteract属性,miSelectPolygon表示选定多边形,miSelect表
示选定矩形,还可以选定成圆形,要实现拖动就把MouseInteract中的miScroll设为
TRUE就OK了,还可以放大缩小

在把选定的内容复制把剪贴板就这SelCopytoClip,
SelCutToClip是什么意思你该明白吧?

最后,我想说,一个优秀DELPHI程序员应该善于利用第三方控件。下载:
http://www.net-wing.net/kangwei/
 
- 有没有办法做一个透明的panel.我查过以往问题,没有找到现成的。
 

Similar threads

D
回复
0
查看
2K
DelphiTeacher的专栏
D
D
回复
0
查看
1K
DelphiTeacher的专栏
D
D
回复
0
查看
1K
DelphiTeacher的专栏
D
S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
后退
顶部