如果这个简单的问题都搞不定的话,以后我还来不来呢?我真的急!(200分)

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

luket

Unregistered / Unconfirmed
GUEST, unregistred user!
在TWebBrowser里选择文本后,拖动至我的另一个控件中,并接受TWebBrowser选择的文本,请问怎么实现?
 
一条代码也不用的办法:
把你的那个控件做成RICHEDIT。
 
是啊,这不就是简单的文本拖放吗?
 
简单的文本拖放,也不是那么简单的,这里有个 memo 作为 drag & drop
Target 的例子,作为 Source 自己找找吧。

From undu 9809
//=== SIMPLE TEXT DROP ONTO A MEMO EXAMPLE =====================================
//
// This is a simple demonstration of a Form with a TMemo that you can drop
// text onto. The Memo will only accept simple text, cannot link to the
// source of the text, but does permit both Copy and Move (in which case
// the text is deleted from the source).
//
// Try typing some text into wordpad, highlight a block, the drag the block
// across to the memo and drop. Press Ctrl to Copy; no key to Move.
//
// Watch for the insertion point being highlighted by means of a thin grey caret.
// Move the mouse near to an edge of the memo's text area to scroll the memo in
// that direction.
//
// Grahame Marsh 18/ 8/98 Freeware for UNDU Tested under Delphi 4.00 only
// 7/ 9/98 Resource leak corrected, autoscrolling and user
// feedback (grey caret) added
//
//==============================================================================

unit EditDrop1;

{$ASSERTIONS ON} // for debugging
{$OPTIMIZATION OFF} // for debugging and single stepping only

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ExtCtrls, ActiveX;
type
TDropEditForm = class(TForm)
Panel1: TPanel;
DropMemo: TMemo;
procedure FormCreate(Sender: TObject);
private
public
end;

var
DropEditForm: TDropEditForm;

implementation

{$R *.DFM}

//--- UTILITIES ----------------------------------------------------------------
// Drop effects as Delphi style constants (originals in ActiveX)
const
deNone = DROPEFFECT_NONE;
deMove = DROPEFFECT_MOVE;
deCopy = DROPEFFECT_COPY;
deLink = DROPEFFECT_LINK;
deScroll = longint(DROPEFFECT_SCROLL);

//Default drag constants as Delphi style (originals in ActiveX)
const
ddScrollInset = DD_DEFSCROLLINSET; // = 11
ddScrollDelay = DD_DEFSCROLLDELAY; // = 50
ddScrollInterval = DD_DEFSCROLLINTERVAL; // = 50
ddDragDelay = DD_DEFDRAGDELAY; // = 200
ddDragMinDist = DD_DEFDRAGMINDIST; // = 2

//Inset region codes for scroll operations
const
inNone = 0; // not in an inset regions
inLeft = 1; // left edge
inRight = 2; // right edge - left and right are exclusive
inTop = 4; // top edge
inBottom = 8; // bottom edge - top and bottom are exclusive


// Data transfer direction during data type enumeration (original in ActiveX)
// as Delphi style constants
const
ddGet = DATADIR_GET;
ddSet = DATADIR_SET;

// Type of storage medium for data formats (original in ActiveX)
// as Delphi style constants
const
tsGlobal = TYMED_HGLOBAL; // handle to global memory clock
tsFile = TYMED_FILE; // file
tsStream = TYMED_ISTREAM; // stream interface
tsStorage = TYMED_ISTORAGE; // storage interface
tsGDI = TYMED_GDI; // gdi object
tsMetafilePict = TYMED_MFPICT; // metafilepict structure
tsEnhMetafile = TYMED_ENHMF; // enhanced metafile
tsNull = TYMED_NULL; // no storage

// View Aspect
const
dvaContent = DVASPECT_CONTENT;
dvaThumbnail = DVASPECT_THUMBNAIL;
dvaIcon = DVASPECT_ICON;
dvaDocPrint = DVASPECT_DOCPRINT;

//--- returns the normal response for a wanted effect:
// no keys = "move"
// control only = "copy"
// control/shift = "link" - ignored in this case
function StandardEffect (Keys : TShiftState) : integer;
begin
Result := deMove;
if ssCtrl in Keys then
Result := deCopy
end;

//=== ENUMERATE FORMATS ========================================================
// This is a simple format enumerator for an IDataObject interface. It has
// been written to be expanded but this version can only respond to an
// IDataObject that contains a CF_TEXT format.

type
TEnumFormats = class
private
FDataObject : IDataObject;
FEnumerator : IEnumFormatEtc;
FFormatEtc : TFormatEtc;
FMediumValid,
FValid : boolean;
FCount : integer;
FMedium : TStgMedium;
procedure SetDataObject (Value : IDataObject);
function SomeText (Format : TClipFormat) : string;
public
constructor Create (DataObject : IDataObject);
destructor Destroy; override;
// frees memory associated with the storage medium
procedure FreeMedium;
// reset to the start of the enum list
function Reset : boolean;
// returns next formatetc or first if reset just called
function Next : boolean;
// returns true if a given format is available
function HasFormat (ClipFormat : TClipFormat) : boolean;
// returns the handle to a given type of medium required
function Handle (Tymed : integer): hGlobal;
// Global handle from a tsGlobal type of medium
function GlobalHandle : hGlobal;
// Text available?
function HasText : boolean;
function Text : string;
// number of formats available
property Count : integer read FCount;
// the dataobject interface for which enum is required
property DataObject : IDataObject read FDataObject write SetDataObject;
// true if formatetc stuff is valid
property Valid : boolean read FValid;
// information held by current formatetc if valid
property FormatEtc : TFormatEtc read FFormatEtc;
property Aspect : integer read FFormatEtc.dwAspect write FFormatEtc.dwAspect;
property Format : TClipFormat read FFormatEtc.cfFormat write FFormatEtc.cfFormat;
property Index : integer read FFormatEtc.lIndex write FFormatEtc.lIndex;
property Medium : integer read FFormatEtc.Tymed write FFormatEtc.Tymed;
end;

// Create the enumerator and set the dataobject
constructor TEnumFormats.Create (DataObject : IDataObject);
begin
inherited Create;
SetDataObject (DataObject)
end;

// Destroy the dataobject copy and the enumerator
destructor TEnumFormats.Destroy;
begin
FreeMedium;
SetDataObject (nil);
inherited Destroy
end;

//--- free the memory associated with the storage medium record FMedium

procedure TEnumFormats.FreeMedium;
begin
if FMediumValid then
ReleaseStgMedium (FMedium);
FMediumValid := false
end;

//--- function to obtain the next Format supported by the DataObject, or the
// first if Reset has just been called, returns true on success
function TEnumFormats.Next : boolean;
var
Returned : integer;
begin
inc (FCount);
FValid := FEnumerator.Next (1, FFormatEtc, @Returned) = S_OK;
Result := FValid
end;

//--- Reset the Enumerator interface back to the beginning of the list,
// returns true on success
function TEnumFormats.Reset : boolean;
begin
FValid := false;
FCount := 0;
Result := Succeeded (FEnumerator.Reset)
end;

//--- Enumerate the data object for a specific format, returns true if
// found, then the FFormatEtc record will be valid
function TEnumFormats.HasFormat (ClipFormat : TClipFormat) : boolean;
begin
Result := false;
if Reset then
while (not Result) and Next do
Result := ClipFormat = Format
end;

procedure TEnumFormats.SetDataObject (Value : IDataObject);
var
Result : integer;
begin
// clear current values and free
FDataObject := nil;

// new interfaces
FDataObject := Value;
if Assigned (FDataObject) then
begin
Result := FDataObject.EnumFormatEtc (ddGet, FEnumerator);
Assert (Succeeded (Result), 'Cannot get the format enumerator');
Reset
end
end;

// returns a handle to the current formatetc given the
// type of medium required
function TEnumFormats.Handle (Tymed : integer): hGlobal;
var
FormatEtc : TFormatEtc;
begin
FreeMedium;
Result := 0;
if FValid and (FFormatEtc.tymed and Tymed = Tymed) then
begin
FormatEtc := FFormatEtc;
FormatEtc.tymed := FormatEtc.tymed and Tymed; // use only the requested type
if Succeeded (FDataObject.GetData (FormatEtc, FMedium)) then
begin
FMediumValid := true;
Result := FMedium.hGlobal
end
end
end;

// Get a global data handle (eg for CF_TEXT)
function TEnumFormats.GlobalHandle : hGlobal;
begin
Result := Handle (tsGlobal)
end;

//--- function to return a string, used by CF_TEXT
function TEnumFormats.SomeText (Format : TClipFormat) : string;
var
H : hGlobal;
P : PChar;
begin
Result := '';
if HasFormat (Format) then // check that text is available *AND* position
begin // the enumerator on the text data
H := GlobalHandle; // get the global handle to the data
if FMediumValid then
try
if H <> 0 then
begin
P := GlobalLock (H); // it's a pointer to a null terminated string
try
Result := P // get our copy
finally
GlobalUnLock (H) // let it go
end
end
finally
FreeMedium // free the storage medium
end
end
end;

//--- TEXT ---
// Returns a text item or empty if not present
function TEnumFormats.Text : string;
begin
Result := SomeText (CF_TEXT)
end;

// Returns true if some text is available
function TEnumFormats.HasText : boolean;
begin
Result := HasFormat (CF_TEXT)
end;

//--- Drop Target Interface ----------------------------------------------------
// This is the IDropTarget interface implemented using TInterfacedObject
// that will respond to some text being dropped on a TMemo control

type
TDropTarget = class (TInterfacedObject, IDropTarget)
function DragEnter (const DataObj: IDataObject; grfKeyState: Longint; pt: TPoint; var dwEffect: Longint): HResult; stdcall;
function DragOver (grfKeyState: Longint; pt: TPoint; var dwEffect: Longint): HResult; stdcall;
function DragLeave : HResult; stdcall;
function Drop (const DataObj: IDataObject; grfKeyState: Longint; pt: TPoint; var dwEffect: Longint): HResult; stdcall;
private
FInsertPos : TPoint;
FOk : boolean;
FMemo : TMemo;
FScrollTick,
FTextHt : integer;
public
constructor Create (AMemo : TMemo);
end;

constructor TDropTarget.Create (AMemo : TMemo);
begin
inherited Create;
FMemo := AMemo
end;

function TDropTarget.DragEnter (const DataObj: IDataObject; grfKeyState: Longint; pt: TPoint; var dwEffect: Longint): HResult;
var
DC : hDC;
TM : TTextMetric;
begin
// Determine if text is available and set the Ok flag accordingly
with TEnumFormats.Create (DataObj) do
try
FOk := HasText
finally
Free
end;

if FOk then
begin
// set tick counter to zero to indicate not in an inset region initially
FScrollTick := 0;

// get memo text height
DC := GetDC (FMemo.Handle);
try
SelectObject (DC, FMemo.Font.Handle);
GetTextMetrics (DC, TM)
finally
ReleaseDC (FMemo.Handle, DC)
end;
FTextHt := TM.tmHeight;

// create a thin grey caret to give user feedback
CreateCaret (FMemo.Handle, 1, 1, FTextHt);
ShowCaret (FMemo.Handle);

// set the cursor display effect according to keys
dwEffect := StandardEffect (KeysToShiftState (grfKeyState))
end else
dwEffect := deNone;
Result := NOERROR;
end;

function TDropTarget.DragOver (grfKeyState: Longint; pt: TPoint; var dwEffect: Longint): HResult;
var
Caret,
Offset,
Point : TPoint;
Tick,
Loop,
Inset : integer;
Text : string;
DC : hDC;
Size : TSize;
begin
if FOk then
begin
// convert Screen mouse position to Memo relative
Point := FMemo.ScreenToClient (Pt);

//=== DISALLOW DROP ON SCROLL BARS

if (Point.X >= FMemo.ClientWidth) or
(Point.Y >= FMemo.ClientHeight) then
begin
SetCaretPos (-1, -1);
dwEffect := deNone;
FInsertPos.X := -1;
FInsertPos.Y := -1
end else begin

//=== PROVIDE USER FEEDBACK

// get the current scroll bar positions to offset mouse position
Offset.X := GetScrollPos (FMemo.Handle, SB_HORZ);
Offset.Y := GetScrollPos (FMemo.Handle, SB_VERT);

// calculate line number that mouse is on, get the text for that line
Caret.Y := (Point.Y div FTextHt) + Offset.Y;
Text := FMemo.Lines [Caret.Y];
// round mouse position to calculate caret Y position
Caret.Y := Caret.Y * FTextHt;
// get X position by locating text character just to the left of the
// mouse position, or end of the line if mouse is beyond
DC := GetDC (FMemo.Handle);
try
SelectObject (DC, FMemo.Font.Handle);
GetTextExtentPoint32 (DC, PChar (Text), length (Text), Size);
inc (Size.cx, 3);
if Point.X + Offset.X < Size.cx then
for Loop := length (Text) - 1 downto 0 do
begin
GetTextExtentPoint32 (DC, PChar (Text), Loop, Size);
inc (Size.cx, 3);
if Size.cx < Point.X + Offset.X then
break
end
finally
ReleaseDC (FMemo.Handle, DC)
end;
// calculate the caret X, Y position in the scrolled memo area
Caret.X := Size.cx - Offset.X;
Caret.Y := Caret.Y - Offset.Y * FTextHt;
// position caret
SetCaretPos (Caret.X, Caret.Y);
// remember this position as the insert position if the user
// should drop the text here
FInsertPos.X := Caret.X;
FInsertPos.Y := Caret.Y + FTextHt;

//=== SCROLL MEMO

Inset := inNone;
// check left and right bounds
if Point.X <= ddScrollInset then
Inset := Inset or inLeft
else
if FMemo.ClientWidth - Point.X < ddScrollInset then
Inset := Inset or inRight;

// check top and bottom bounds
if Point.Y <= ddScrollInset then
Inset := Inset or inTop
else
if FMemo.ClientHeight - Point.Y < ddScrollInset then
Inset := Inset or inBottom;

// get standard key combinations
dwEffect := StandardEffect (KeysToShiftState (grfKeyState));

// check for scrolling inset region
if Inset <> inNone then
begin
// set scrolling flag in dwEffect
dwEffect := dwEffect or deScroll;
// check if only first call, if so get tick counter at which scrolling will occur

Tick := GetTickCount;
if FScrollTick = 0 then
FScrollTick := Tick + ddScrollDelay
else
// check if delay or interval timer expired
if Tick - FScrollTick > 0 then
begin
// scroll up or down?
if Inset and inTop <> 0 then
FMemo.Perform (WM_VSCROLL, SB_LINEUP, 0)
else
if Inset and inBottom <> 0 then
FMemo.Perform (WM_VSCROLL, SB_LINEDOWN, 0);
// scroll left or right?
if Inset and inLeft <> 0 then
FMemo.Perform (WM_HSCROLL, SB_LINELEFT, 0)
else
if Inset and inRight <> 0 then
FMemo.Perform (WM_HSCROLL, SB_LINERIGHT, 0);

// set tick counter for delay until next scroll
FScrollTick := Tick + ddScrollInterval
end
end
end
end else
dwEffect := deNone;
Result := NOERROR
end;

function TDropTarget.DragLeave: HResult;
begin
if FOk then
DestroyCaret;
Result := NOERROR
end;

function TDropTarget.Drop (const DataObj: IDataObject; grfKeyState: Longint; pt: TPoint; var dwEffect: Longint): HResult;
var
P : TSmallPoint;
begin
if FOk then
begin
DestroyCaret;
// Check if drop has occured onto a scrollbar
if (FInsertPos.X = -1) and (FInsertPos.Y = -1) then
dwEffect := deNone
else begin

// Convert drop point from screen coords to memo coords and to TSmallPoint
// to pass as an integer parameter to position the caret in the memo
P := PointToSmallPoint (FInsertPos);
// Do a down click
FMemo.Perform (WM_LBUTTONDOWN, 0, integer (P));
// Do an up click
FMemo.Perform (WM_LBUTTONUP, 0, integer (P));
// The memo's input caret is now nicely poised,
// Insert the drop text into the memo
with TEnumFormats.Create (DataObj) do
try
FMemo.SelText := Text
finally
Free
end;
// tell the drop source to delete the text if necessary
dwEffect := StandardEffect (KeysToShiftState (grfKeyState))
end
end else
dwEffect := deNone;

Result := NOERROR
end;

//=== FORM STUFF ===============================================================

procedure TDropEditForm.FormCreate(Sender: TObject);
var
Result : integer;
begin
Result := RegisterDragDrop (DropMemo.Handle, TDropTarget.Create (DropMemo));
Assert (Succeeded (Result), Format ('RegisterDragDrop failed ($%x)', [Result]))
end;

//=== INITIALIZATION ===========================================================

procedure Initialize;
var
Result : HRESULT;
begin
Result := OleInitialize (nil);
Assert (Result in [S_OK, S_FALSE], Format ('OleInitialize failed ($%x)', [Result]))
end;

initialization
Initialize
finalization
OleUninitialize
end.

 
哇!这么复杂的代码,佩服!佩服!
不过还是看情形吧。如果要求没那么高弄一个简单的就可以了。
 
TO SuperMMX:
谢谢你的资料!

TO wint:
我的接受控件只能是TTREEVIEW。

不过由于TWEBBROWSER显示的是网页内容,故同普通的TMEMO中拖动不同。
我的思路是这样:
在Twebbrowser的Onstartdrag中调用TWEBBROWSER的EXECWB(COPY)命令,使选中内容复制至剪贴板,然后在TTREEVIEW中接受拖动动作。但由于TWEBBROWSER的特殊性,把直接把ACCEPT:=TRUE都不能接受。

请高手们给我解决!

 
不是有接收文件拖放的例子吗? 不知参考过没有? 我想是类似的吧。
 
有没有人来回答?这个问题看似简单,其实很怪!

请高手们帮我试一下!这个问题困扰我一个月了!我提了几次问题了!

人死光了吗?!!!

 
》》人死光了吗?!!!

就冲你这句话,没人肯帮你。
 
我收回我上一句不礼貌的话,深表歉意!对不起!
主要是我太急的缘故。
如果你们真的不肯帮忙,那就算了!
 
呵呵,不用急嘛!!!再等等!
 
我没别的意思,不是不肯帮忙,实在是。。

有可能,
1,大虾没来,
2,大虾没看到,
3,看到的都不会

这一方面很难的,只能用代码来说明。

关于 drag & drop 我那里有一个系列文章,英文的,
我正在看,要吗?不过不知道是不适应 TWebBrower,
我的 email: SuperMMX@263.net
可能要迟几天。
 
首先纠正大家一个概念性的错误

Delphi中的所有组件的Drag&Drop的相关操作都是伪造的,
Delphi在controls.pas单元中定义了一个自定义消息,如下:
...
const
CM_BASE = $B000;
...
<font color=red>CM_DRAG = CM_BASE + 47;</font>
...

在controls.pas单元中可以看到,Delphi在这里完整的模拟了一套Drag&Drop体系,
基本上大多数的Drag&Drop相关操作都在这里实现了,
少部分的如TreeView和ListView的在ComCtrls.pas中实现

整个体系简单地说分成两部分
1、判断鼠标的动作,并解释为等价的Drag&Drop消息
2、组件接收CMDrag消息,判断参数含义,作出相应的动作,触发相应的事件

其中1可以参见controls.pas中的TDragObject.MouseMsg方法
2则可以参见各控件的CMDrag方法,这个方法被定义为响应CM_Drag消息


到此可以基本得出结论:
Delphi中的Drag&Drop的相关操作都是伪造的,
因此如果我们使用Delphi自身提供的Drag&Drop的相关操作,
则只有Drag&Drop在同一个应用程序中发生,而且所有相关控件都是Delphi控件时才可能正确运行。

这里luket提出的问题是要从TWebBrowser中选择文本然后Drop到TreeView中,
但是这里TWebBrowser不是Delphi组件,Delphi只是引用了系统中注册的COM对象,并封装为Delphi类而已
因此TWebBrowser显然不会与Delphi组件那样运行,因而TreeView的全部Drag&Drop相关事件都根本不会发生

大家请注意看上面SuperMMX贴的那段代码,其实也在不断的计算鼠标位置、判断鼠标状态,
很明显也是在伪造Drag&Drop操作!
 
好啦,按照我的观点得到的结论必然是直接使用Delphi的相关事件是绝对行不通的,
只好用Windows标准的方法了,按照Win32 Help的说法,
要编程控制控件的Drag&Drop动作,必须按照以下步骤:
(a)对于Drag&Drop动作的Target控件: (对于本问就是TreeView)
1、实现一个IDropTarget接口
2、调用RegisterDragDrop将一个控件与一个IDropTarget接口实例关联起来
3、调用RevokeDragDrop取消2中的关联

(b)对于Drag&Drop动作的Source控件: (对于本问就是TWebBrowser)
1、实现一个IDropSource接口,控制Drag&Drop动作的Source控件
2、实现一个IDataObject接口,控制被Drag&Drop的数据
2、调用DoDragDrop方法,开始Drag&Drop动作

(其中RegisterDragDrop、RevokeDragDrop、DoDragDrop都是API,
Delphi中的接口定义在....../Source/Rtl/Win/Ole2.pas中)

在本问中TWebBrowser不需要我们负责,因此(b)不在讨论之列,我们主要讨论(a)
a.2调用RegisterDragDrop将一个控件与一个IDropTarget接口实例关联起来
程序如下:
type
TfmMain = class(TForm)
private
DropTarget: IDropTarget;
...
end;

procedure TfmMain.FormCreate(Sender: TObject);
begin
DropTarget := ITreeViewDropTarget.Create(TreeView);
RegisterDragDrop(TreeView.Handle, DropTarget);
end;

a.3、调用RevokeDragDrop取消2中的关联
程序如下:
procedure TfmMain.FormDestroy(Sender: TObject);
begin
RevokeDragDrop(TreeView.Handle);
DropTarget.Free;
end;

好了,上面的代码很简单,不用多说,再来重点看如何实现一个符合我们要求的IDropTarget:
a.1实现一个IDropTarget接口:
首先要作一些和本问不太相关的工作,实现IUnknow中的抽象方法(abstract method),如下:
type
ITreeViewDropTarget = class(IDropTarget)
private
FRefCount: LongInt;
protected
TreeView: TTreeView;
public
constructor Create(ATreeView: TTreeView);

function QueryInterface(const iid: TIID; var obj): HResult; override; stdcall;
function AddRef: Longint; override; stdcall;
function Release: Longint; override; stdcall;
...
property RefCount: LongInt read FRefCount;
end;

// 因为要和TreeView绑定
// 所以增加了一个TreeView,保存目标TreeView的引用
constructor ITreeViewDropTarget.Create(ATreeView: TTreeView);
begin
Inherited Create;
FRefCount := 0;
TreeView := ATreeView;
end;

function ITreeViewDropTarget.QueryInterface(const iid: TIID; var obj): HResult;
begin
IUnknown(Obj) := Nil;
Result := S_OK;
end;

function ITreeViewDropTarget.AddRef: Longint;
begin
Inc(FRefCount);
Result := RefCount;
end;

function ITreeViewDropTarget.Release: Longint;
begin
Dec(FRefCount);
Result := RefCount;
end;


各位,下面就是最重要的工作了,实现IDropTarget的四个方法:
如下:
type
ITreeViewDropTarget = class(IDropTarget)
public
...
function DragEnter(dataObj: IDataObject; grfKeyState: Longint;
pt: TPoint; var dwEffect: Longint): HResult; override; stdcall;
function DragOver(grfKeyState: Longint; pt: TPoint;
var dwEffect: Longint): HResult; override; stdcall;
function DragLeave: HResult; override; stdcall;
function Drop(dataObj: IDataObject; grfKeyState: Longint; pt: TPoint;
var dwEffect: Longint): HResult; override; stdcall;
...
end;
这四个方法的作用请大家去看Win32 Help,写得很详细,我就不翻译了,
实现的代码如下:(这里只是说明原理,因此一切从简)
function ITreeViewDropTarget.DragEnter(dataObj: IDataObject; grfKeyState: Longint;
pt: TPoint; var dwEffect: Longint): HResult;
begin
dwEffect := DropEffect_Copy;
Result := S_OK;
end;

function ITreeViewDropTarget.DragOver(grfKeyState: Longint; pt: TPoint;
var dwEffect: Longint): HResult;
begin
dwEffect := DropEffect_Copy;
Result := S_OK;
end;

function ITreeViewDropTarget.DragLeave: HResult;
begin
Result := S_OK;
end;

function ITreeViewDropTarget.Drop(dataObj: IDataObject; grfKeyState: Longint; pt: TPoint;
var dwEffect: Longint): HResult;
begin
dwEffect := DropEffect_Copy;
Result := S_OK;
end;


现在我们可以修改上面四个方法,详细地控制Drag&Drop操作,
我懒得作了,luket同志自己搞定吧

最后剩余的问题就是在ITreeViewDropTarget.Drop方法中应该对Drop过来的数据进行处理
数据全部在DataObj: IDataObject中,具体如何使用luket同志自己去看Win32 Help吧,
有很详细的说明,我没仔细看,想来应该不难


好啦,我就到此为止了,
各位有兴趣的同志继续研究一下,根据luket把上面四个方法写完吧!
 
李颖:
久闻你的大名,今天总算心服口服了!
 我先试一下,如果能成功,你有兴趣要我的源代码吗?(是个飞鹰浏览器)
 我学DELPHI虽有一年,工作有二年,但我基础太差(19岁),ENGLISH又不好,因此学起东西来总是不可以太深奥。看到你们在中华大地四处闯荡,大作拳脚,很羡慕!!希望我也有成功的一天。
 谢谢!

Supermmx:
你有兴趣我也可以发给你。

 但是不能侵权哦!


 
哈哈, 又见到李颖大虾了,
不过您说错了,我贴的实现了 IDragDrop,
您说的判断鼠标只是为了能 scroll 而已。


to liket,
好呀,多大,谢谢了。
 
难道你们还没收到?为什么不给我回个信?
 
2 SuperMMX:
>> 不过您说错了,我贴的实现了 IDragDrop,
>> 您说的判断鼠标只是为了能 scroll 而已。
是吗?代码太长,没仔细看,抱歉

2 luket:
收到了,不过所有的dbf都缺索引文件打不开,
而且有个Feditsite.dfm缺.pas文件
请你把这些文件补上

ps:现在有很多人要过来我这里玩,恐怕没时间看,
大概要到5.1之后再说了,抱歉!
 
有个控件 Drag&Drop
感兴趣我发给你.lxgcn@elong.com
 
后退
顶部