使用:Delphi XE2 Update 4.1,32位VCL应用程序,Windows 8
如果将DragMode设置为dmAutomatic,则调用OnStartDrag事件;但是,如果将DragMode设置为dmManual,则会绕过OnStartDrag事件。
这是设计的吗?如何确保调用OnStartDrag事件?
编辑:代码根据要求发布。有问题的事件是TTableDesigner.LblStartDrag,它在调用BeginDrag之后没有被执行(在TTableDesigner.LblOnMouseDown中)。
unit uTableDesigner;
interface
uses
System.SysUtils, System.Classes, Vcl.Controls, Graphics, JvCaptionPanel,
StdCtrls, ExtCtrls;
type
TMyTable = record
TableName: String;
TableFields: TStrings;
TableObject: Pointer;
end;
PMyTable = ^TMyTable;
TTableDesigner = class(TCustomControl)
procedure CreateWnd; override;
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure LblOnMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
procedure LblDragDrop(Sender, Source: TObject; X, Y: Integer);
procedure LblDragOver(Sender, Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean);
procedure LblEndDrag(Sender, Target: TObject; X, Y: Integer);
procedure LblStartDrag(Sender: TObject; var DragObject: TDragObject);
// procedure Paint; override;
private
{ Private declarations }
FTableList: TList;
FCaptionPanelList: TList;
FPanelSlot_Left: Integer;
FPanelSlot_Top: Integer;
FStartDragPnl: TJvCaptionPanel;
FDragHoverPnl: TJvCaptionPanel;
FEndDragPnl: TJvCaptionPanel;
procedure HighlightPanelLabel(ALabel: TLabel);
protected
{ Protected declarations }
public
{ Public declarations }
procedure AddTable(const ATableName: String; const AFields: TStrings);
procedure DeleteTable(const ATableName: String);
procedure DeleteAllTables;
published
{ Published declarations }
property Align;
property Visible;
property Color;
end;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents('Samples', [TTableDesigner]);
end;
constructor TTableDesigner.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FTableList := TList.Create;
FCaptionPanelList := TList.Create;
FPanelSlot_Left := 40;
FPanelSlot_Top := 40;
end;
destructor TTableDesigner.Destroy;
begin
DeleteAllTables;
FTableList.Free;
FCaptionPanelList.Free;
inherited;
end;
procedure TTableDesigner.CreateWnd;
begin
inherited;
end;
procedure TTableDesigner.AddTable(const ATableName: String; const AFields: TStrings);
var
pnl: TJvCaptionPanel;
c, h, j: Integer;
lbl: TLabel;
MyTable: PMyTable;
begin
pnl := TJvCaptionPanel.Create(Self);
pnl.Parent := Self;
pnl.Color := clWhite;
pnl.Caption := ATableName;
pnl.CaptionPosition := dpTop;
pnl.Left := FPanelSlot_Left;
pnl.Top := FPanelSlot_Top;
// FPanelSlot_Left := FPanelSlot_Left + pnl.Width + 40;
// if FPanelSlot_Left > ClientWidth - 100 then
// begin
// FPanelSlot_Left := 40;
//
// j := 0;
// for c := 0 to FTableList.Count - 1 do
// if j < TJvCaptionPanel(TMyTable(FTableList.Items[c]^).TableObject).Height then
// j := TJvCaptionPanel(TMyTable(FTableList.Items[c]^).TableObject).Height;
//
// FPanelSlot_Top := FPanelSlot_Top + j + 40;
// end;
h := 0;
for c := 0 to AFields.Count - 1 do
begin
lbl := TLabel.Create(pnl);
lbl.Parent := pnl;
lbl.Align := alTop;
lbl.Caption := AFields[c];
lbl.Transparent := False;
lbl.ParentColor := False;
lbl.DragKind := dkDrag;
lbl.OnMouseDown := LblOnMouseDown;
lbl.OnDragDrop := LblDragDrop;
lbl.OnDragOver := LblDragOver;
lbl.OnEndDrag := LblEndDrag;
lbl.OnStartDrag := LblStartDrag;
// lbl.DragMode := dmAutomatic;
h := h + lbl.Height + 4;
end;
pnl.ClientHeight := pnl.CaptionHeight + h;
MyTable := AllocMem(SizeOf(TMyTable));
Initialize(MyTable^);
MyTable.TableName := ATableName;
MyTable.TableFields := TStringList.Create;
MyTable.TableFields.Assign(AFields);
MyTable.TableObject := pnl;
FTableList.Add(MyTable);
end;
procedure TTableDesigner.DeleteTable(const ATableName: String);
var
c: Integer;
begin
for c := 0 to FTableList.Count - 1 do
if TMyTable(FTableList.Items[c]^).TableName = ATableName then
begin
TJvCaptionPanel(TMyTable(FTableList.Items[c]^).TableObject).Free;
TMyTable(FTableList.Items[c]^).TableFields.Free;
Finalize(TMyTable(FTableList.Items[c]^));
FreeMem(FTableList.Items[c]);
FTableList.Delete(c);
Break;
end;
end;
procedure TTableDesigner.DeleteAllTables;
var
c: Integer;
begin
for c := FTableList.Count - 1 downto 0 do
begin
TJvCaptionPanel(TMyTable(FTableList.Items[c]^).TableObject).Free;
TMyTable(FTableList.Items[c]^).TableFields.Free;
Finalize(TMyTable(FTableList.Items[c]^));
FreeMem(FTableList.Items[c]);
FTableList.Delete(c);
end;
end;
procedure TTableDesigner.HighlightPanelLabel(ALabel: TLabel);
var
pnl: TJvCaptionPanel;
c: Integer;
begin
pnl := TJvCaptionPanel(ALabel.Parent);
for c := 0 to pnl.ControlCount - 1 do
if pnl.Controls[c] = ALabel then
TLabel(pnl.Controls[c]).Color := clHighlight
else
TLabel(pnl.Controls[c]).Color := pnl.Color;
end;
procedure TTableDesigner.LblOnMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
HighlightPanelLabel(TLabel(Sender));
BeginDrag(False, 4);
end;
procedure TTableDesigner.LblDragDrop(Sender, Source: TObject; X, Y: Integer);
begin
FEndDragPnl := TJvCaptionPanel(TLabel(Sender).Parent);
FEndDragPnl.Color := clWhite;
end;
procedure TTableDesigner.LblDragOver(Sender, Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean);
begin
FDragHoverPnl := TJvCaptionPanel(TLabel(Sender).Parent);
FDragHoverPnl.Color := clGreen;
Accept := True;
end;
procedure TTableDesigner.LblEndDrag(Sender, Target: TObject; X, Y: Integer);
begin
TJvCaptionPanel(TLabel(Sender).Parent).Color := clPurple;
end;
procedure TTableDesigner.LblStartDrag(Sender: TObject; var DragObject: TDragObject);
begin
FStartDragPnl := TJvCaptionPanel(TLabel(Sender).Parent);
FStartDragPnl.Color := clRed;
end;
// procedure TTableDesigner.Paint;
// var
// c: Integer;
// begin
// inherited;
//
// // Canvas.Pen.Mode := pmBlack;
// // Canvas.Pen.Color := clBlack;
// // Canvas.Pen.Style := psSolid;
// // Canvas.Pen.Width := 1;
// // Canvas.MoveTo(50, 50);
// // Canvas.LineTo(500, 500);
//
// end;
end.
答案 0 :(得分:4)
如果你没有对方法进行限定,那么你就是'TTableDesigner'的方法。隐含了“自我”。因此'BeginDrag'调用适用于TableDesigner对象。
你宁愿叫'TLabel(发件人).BeginDrag(..'。