如能仔细看一下我的问题,给些建议,小弟不胜感激背景是:现在要做一个图形控件Tshapex,继承自TgraphicControl,要处理在运行期控制这个控件的对象,比如拖动,改变大小等操作,所以动态创建一个panel,希望可以在panel的paint函数中把控件画到panel上,这样利用panel的一些move,resize函数,拖动panel的时候,实现拖动控件的效果。
问题是:如何把这个tshapex的对象画到panel的canvas上去。
注:1.继承自Twincontrol的控件,有个Twincontrl(Fcontrol).paintto(canvas.handle,x,y),就可以把控件画到panel.canvas上去了。Tgraphiccontrol没有paintto方法。
2.有个canvas.draw(x,y,Graphic)方法,在canvas上画Graphic对象,如果用这个方法的话,我的控件继承TGraphic行不行?能做成可视化的控件么?
3.canvas有个copyrect的方法,可以把指定区域的图形copy到panel的canvas上,这样的话需要先在窗体上画出一个图形,供copy,这样的话,为了实现对控件的操作,需要先在窗体上画一个控件。用这样的方法可以让这个参考的控件不显示出来了么?
问题是:如何把这个tshapex的对象画到panel的canvas上去。
注:1.继承自Twincontrol的控件,有个Twincontrl(Fcontrol).paintto(canvas.handle,x,y),就可以把控件画到panel.canvas上去了。Tgraphiccontrol没有paintto方法。
2.有个canvas.draw(x,y,Graphic)方法,在canvas上画Graphic对象,如果用这个方法的话,我的控件继承TGraphic行不行?能做成可视化的控件么?
3.canvas有个copyrect的方法,可以把指定区域的图形copy到panel的canvas上,这样的话需要先在窗体上画出一个图形,供copy,这样的话,为了实现对控件的操作,需要先在窗体上画一个控件。用这样的方法可以让这个参考的控件不显示出来了么?
解决方案 »
- TVirtualStringTree 的一个问题???
- 如何获取所有本地连接名?
- 看见这么多人卖书,我说:我不敢卖书。我奉劝大家也不要卖书。
- 怎样修改SYSTEM字体,或者点阵字体也行
- 大家做delphi程序都用什么按装程序!
- 如何去当前日期和时间?
- 很菜的一个报表问题,不过分多
- TADOQuery型的控件,其中有个属性connection,这个属性是做什么用的,该怎么用,我看过帮助了,没看懂:(
- 编写ASP组件时,怎样才能在一个方法之下包含另一个方法或者属性
- 如果得到OS的类型啊?用什么API函数啊?
- 编辑器:请问有没有直接将字符转换为16进制的函数可用(WIN32),可否举例呢
- 帮我把这个解密算法改成加密的,谢谢
我觉得他们是把一些对象(直线)画在一个panel上,拖动的这个panel。
可以从 TgraphicControl继承,通过判断鼠标位置来确定是拖动还是改变大小不.
在拖支的时候 是先按下然后鼠标移动,在弹起. 在这个过程中通过控件 left top 来实现移动在控件的周围绘制8个小方块,通过鼠标位置来确定是否是改变大小.但如果你是想做一个绘图程序,不建议你将绘制的每个元素都控件化.
作画时的宽高就是TshapexTPanel中放入Tshapex对象,Tshapex.align属性为alcient,调整大小时需要使Tshapex重画。
unit DdhSizerExU;interfaceuses
Classes,SysUtils, Windows, Messages, Controls, StdCtrls,typinfo,Dialogs;const
sc_DragMove: Longint = $F012;type
TDdhSizerControlEx = class (TCustomControl)
private
FOnChange: TNotifyEvent;
FOnSelected: TNotifyEvent;
FControl: TControl;
FOldControl: TControl;
FRectList: array [1..8] of TRect;
FPosList: array [1..8] of Integer;
procedure KeyUp(var Key: Word; Shift: TShiftState); override;
procedure SetControl(const Value: TControl);
procedure SetOnChange(const Value: TNotifyEvent);
procedure DoEventChange;
procedure SetOnSelected(const Value: TNotifyEvent);
protected
procedure CreateParams (var Params: TCreateParams); override;
procedure CreateHandle; override;
procedure WmNcHitTest (var Msg: TWmNcHitTest); message WM_NcHitTest;
procedure WmSize (var Msg: TWmSize); message WM_Size;
procedure WmLButtonDown (var Msg: TWmLButtonDown); message WM_LButtonDown;
procedure WmMove (var Msg: TWmMove); message WM_Move;
procedure Paint; override;
procedure SizerControlExit(Sender: TObject);
public
constructor Create(AOwner: TComponent);
destructor Destroy; override;
procedure DeleteControl;
procedure SetValue(sName: String;Value: Integer);overload;
procedure SetValue(sName: String;Value: String); overload;
property Control: TControl read FControl write SetControl;
property OnChange: TNotifyEvent read FOnChange write SetOnChange;
property OnSelected: TNotifyEvent read FOnSelected write SetOnSelected; class procedure SizerControlEnter(Sender: TObject);
end; function DdhSizerControlEx: TDdhSizerControlEx;
procedure FreeDdhSizerControlEx;implementationuses
Graphics;
var
ADdh: TDdhSizerControlEx = nil;
// TDdhSizerControl methods function DdhSizerControlEx: TDdhSizerControlEx;
begin
if not Assigned(ADdh) then
ADdh := TDdhSizerControlEx.Create(nil);
Result := ADdh;
end;
procedure FreeDdhSizerControlEx;
begin
if Assigned(ADdh) then
ADdh.Free;
ADdh := nil;
end;
constructor TDdhSizerControlEx.Create (AOwner: TComponent);
begin
inherited Create (AOwner);
end;procedure TDdhSizerControlEx.CreateHandle;
begin
inherited CreateHandle;
end;procedure TDdhSizerControlEx.CreateParams (var Params: TCreateParams);
begin
inherited CreateParams(Params);
Params.ExStyle := Params.ExStyle + WS_EX_TRANSPARENT;
end;procedure TDdhSizerControlEx.Paint;
var
I: Integer;
begin
if Focused then
begin
Canvas.Brush.Color := clBlack;
for I := 1 to 8 do
Canvas.Rectangle (FRectList [I].Left, FRectList [I].Top,
FRectList [I].Right, FRectList [I].Bottom);
end
end;procedure TDdhSizerControlEx.WmNcHitTest(var Msg: TWmNcHitTest);
var
Pt: TPoint;
I: Integer;
begin
Pt := Point (Msg.XPos, Msg.YPos);
Pt := ScreenToClient (Pt);
Msg.Result := 0;
for I := 1 to 8 do
if PtInRect (FRectList [I], Pt) then
Msg.Result := FPosList [I];
// if the return value was not set
if Msg.Result = 0 then
inherited;
if FOldControl <> FControl then
begin
FOldControl := FControl;
//ShowMessage(FControl.Name);
if Assigned(FOnSelected) then
FOnSelected(FControl);
end;
end;procedure TDdhSizerControlEx.WmSize (var Msg: TWmSize);
var
R: TRect;
begin
R := BoundsRect;
InflateRect (R, -2, -2);
FControl.BoundsRect := R;
// setup data structures
FRectList [1] := Rect (0, 0, 5, 5);
FRectList [2] := Rect (Width div 2 - 3, 0, Width div 2 + 2, 5);
FRectList [3] := Rect (Width - 5, 0, Width, 5);
FRectList [4] := Rect (Width - 5, Height div 2 - 3, Width, Height div 2 + 2);
FRectList [5] := Rect (Width - 5, Height - 5,Width, Height);
FRectList [6] := Rect (Width div 2 - 3, Height - 5,Width div 2 + 2, Height);
FRectList [7] := Rect (0, Height - 5, 5, Height);
FRectList [8] := Rect (0, Height div 2 - 3, 5, Height div 2 + 2);
DoEventChange;
end;procedure TDdhSizerControlEx.SizerControlExit (Sender: TObject);
begin
Hide;
end;procedure TDdhSizerControlEx.WmLButtonDown (var Msg: TWmLButtonDown);
begin
Perform(wm_SysCommand, sc_DragMove, 0);
end;procedure TDdhSizerControlEx.WmMove (var Msg: TWmMove);
var
R: TRect;
begin
R := BoundsRect;
InflateRect (R, -2, -2);
FControl.Invalidate; // repaint entire surface
FControl.BoundsRect := R;
DoEventChange;
end;
class procedure TDdhSizerControlEx.SizerControlEnter(Sender: TObject);
begin
if (Sender as TControl).Parent.Tag = 832 then
DdhSizerControlEx.Control := Sender as TControl;
end;procedure TDdhSizerControlEx.KeyUp(var Key: Word; Shift: TShiftState);
begin
if (Key = VK_DELETE) then
begin
DeleteControl;
end;
end;destructor TDdhSizerControlEx.Destroy;
begin
FControl := nil;
inherited;
end;procedure TDdhSizerControlEx.SetControl(const Value: TControl);
var
R: TRect;
begin
if Assigned(Value) then
begin
FControl := Value;
// install the new handler
// set the size and position
R := FControl.BoundsRect;
InflateRect (R, 2, 2);
BoundsRect := R;
// set the parent
Parent := FControl.Parent;
// create the list of positions
FPosList [1] := htTopLeft;
FPosList [2] := htTop;
FPosList [3] := htTopRight;
FPosList [4] := htRight;
FPosList [5] := htBottomRight;
FPosList [6] := htBottom;
FPosList [7] := htBottomLeft;
FPosList [8] := htLeft; Visible := True;
BringWindowToTop((FControl as TWinControl).Handle);
BringWindowToTop(Self.Handle);
if GetAsyncKeyState(VK_LButton) <> 0 then
begin
Perform(wm_SysCommand, sc_DragMove, 0);
end
else
begin
end;
SetFocus;
Paint;
end;
end;procedure TDdhSizerControlEx.SetOnChange(const Value: TNotifyEvent);
begin
FOnChange := Value;
end;procedure TDdhSizerControlEx.DoEventChange;
begin
if Assigned(FOnChange) then
try
FOnChange(Self);
except
end;
end;procedure TDdhSizerControlEx.DeleteControl;
begin
Hide;
if Assigned(FControl) then
begin
(FControl as TWinControl).Visible := False;
(FControl as TWinControl).Destroy;
FControl := nil;
DoEventChange;
end;
end;procedure TDdhSizerControlEx.SetValue(sName: String; Value: Integer);
begin
if Assigned(FControl) then
begin
if GetPropInfo(FControl,sName) <> nil then
SetOrdProp(FControl,sName,Value); SetControl(FControl);
end;
end;procedure TDdhSizerControlEx.SetValue(sName, Value: String);
var
pinfo: PPropInfo;
iValue: Integer;
begin
if Assigned(FControl) then
begin
pinfo := GetPropInfo(FControl,sName);
if pinfo <> nil then
if pinfo^.PropType^^.Kind in [tkInteger] then
begin
Value := '0' + Value;
try
iValue := StrToInt(Value);
SetOrdProp(FControl,sName,iValue);
finally
end;
end
else
SetStrProp(FControl,sName,Value); SetControl(FControl);
end;
end;procedure TDdhSizerControlEx.SetOnSelected(const Value: TNotifyEvent);
begin
FOnSelected := Value;
end;end.
我用了你的控件,非常好用。有一个小问题在粘帖一个控件的时候,弹出错误 “class TWincontrol not found”,不知道什么原因?