Delphi 如何在使用Melander';斯德拉格德罗普套房酒店
我正在尝试Melander套件的Delphi 如何在使用Melander';斯德拉格德罗普套房酒店,delphi,exception,drag-and-drop,Delphi,Exception,Drag And Drop,我正在尝试Melander套件的TDropFileTarget组件。目标是在拖放文件后执行某些任务。此外,如果在处理过程中出现问题,我希望收到例外情况 似乎OnDrop事件处理程序中引发的异常被吞没了。但是,即使我将raise语句放入组件的源代码中,我仍然无法接收异常。你能帮忙评论一下吗 示例dfm文件。 示例pas文件。 TCustomDropTarget.Drop的原始代码。 您不能在Drop()中引发异常并在应用程序的代码中捕获它。Ander的原始评论明确指出: // We must no
TDropFileTarget
组件。目标是在拖放文件后执行某些任务。此外,如果在处理过程中出现问题,我希望收到例外情况
似乎OnDrop
事件处理程序中引发的异常被吞没了。但是,即使我将raise
语句放入组件的源代码中,我仍然无法接收异常。你能帮忙评论一下吗
示例dfm文件。
示例pas文件。
TCustomDropTarget.Drop的原始代码。
您不能在Drop()
中引发异常并在应用程序的代码中捕获它。Ander的原始评论明确指出:
// We must not allow exceptions to escape from any of the COM methods since
// COM doesn't support exceptions.
Drop()
是TCustomDropTarget
对IDropTarget.Drop()接口方法的实现IDropTarget
方法在DoDragDrop()
函数中调用,该函数由启动拖动的应用程序调用Drop()
在应用程序的进程内运行,但应用程序不会调用它。因此,即使可以安全地引发异常(事实并非如此),您也没有任何地方可以放置try/except
块来捕获异常,因为COM会检测到异常并将其作为故障传回启动应用程序,而不是您的应用程序。您唯一的选择是在不引发异常的情况下处理OnDrop
事件处理程序中的错误。您不能在Drop()
中引发异常并在应用程序的代码中捕获它。Ander的原始评论明确指出:
// We must not allow exceptions to escape from any of the COM methods since
// COM doesn't support exceptions.
Drop()
是TCustomDropTarget
对IDropTarget.Drop()接口方法的实现IDropTarget
方法在DoDragDrop()
函数中调用,该函数由启动拖动的应用程序调用Drop()
在应用程序的进程内运行,但应用程序不会调用它。因此,即使可以安全地引发异常(事实并非如此),您也没有任何地方可以放置try/except
块来捕获异常,因为COM会检测到异常并将其作为故障传回启动应用程序,而不是您的应用程序。您唯一的选择是在不引发异常的情况下处理OnDrop
事件处理程序中的错误。另一个选择是在OnDrop事件中,只需收集所需的数据(即丢弃的文件)并将其存储在应用程序中的TStringList中,然后将一条消息发布到表单的消息队列中,以通知它已删除
这样,删除文件的实际处理将在程序的正常上下文中进行,因此您可以以正常方式处理异常。另一个选项是在OnDrop事件中,只需收集所需的数据(即删除的文件),并将其存储在应用程序中的TStringList中,然后将一条消息发布到表单的消息队列中,以通知它已删除
这样,删除文件的实际处理将在程序的正常上下文中进行,因此您可以以正常方式处理异常。非常感谢您的宝贵意见!你能帮我推荐一些我可以进一步了解你所说内容的材料吗?非常感谢你富有见识的评论!你能帮我推荐一些材料,让我进一步了解你说的话吗?
function TCustomDropTarget.Drop(const dataObj: IDataObject; grfKeyState: Longint;
pt: TPoint; var dwEffect: Longint): HResult;
var
ShiftState: TShiftState;
ClientPt: TPoint;
begin
FScrollTimer.Enabled := False;
// Protect resources against exceptions in OnDrop event handler.
try
// Refuse drop if we have lost the data object somehow.
// This can happen if the drop is rejected in one of the other IDropTarget
// methods (e.g. DragOver).
if (not Enabled) or (FDataObject = nil) then
begin
dwEffect := DROPEFFECT_NONE;
Result := E_UNEXPECTED;
end else
begin
ShiftState := KeysToShiftStatePlus(grfKeyState);
// Create a default drop effect based on the shift state and allowed
// drop effects (or an OnGetDropEffect event if implemented).
if (FTarget <> nil) then
ClientPt := FTarget.ScreenToClient(pt)
else
ClientPt := pt;
dwEffect := GetValidDropEffect(ShiftState, ClientPt, dwEffect);
// Get data from source and generate an OnDrop event unless we failed to
// get data.
try
if (FGetDataOnEnter or GetData(dwEffect)) then
begin
if (not AsyncTransfer) then
DoDrop(ShiftState, ClientPt, dwEffect);
end else
dwEffect := DROPEFFECT_NONE;
Result := S_OK;
except
// We must not allow exceptions to escape from any of the COM methods since
// COM doesn't support exceptions.
dwEffect := DROPEFFECT_NONE;
Result := E_UNEXPECTED;
end;
end;
if (DropTargetHelper <> nil) then
DropTargetHelper.Drop(DataObj, pt, dwEffect)
else
if (FDragImageHandle <> 0) and (FTarget <> nil) then
ImageList_DragLeave(FTarget.Handle);
finally
// clean up!
if (not AsyncTransfer) then
begin
ClearData;
FDataObject := nil;
FTarget := nil;
end;
FDropTargetHelper := nil;
end;
end;
function TCustomDropTarget.Drop(const dataObj: IDataObject; grfKeyState: Longint;
pt: TPoint; var dwEffect: Longint): HResult;
var
ShiftState: TShiftState;
ClientPt: TPoint;
begin
FScrollTimer.Enabled := False;
try
// Protect resources against exceptions in OnDrop event handler.
try
// Refuse drop if we have lost the data object somehow.
// This can happen if the drop is rejected in one of the other IDropTarget
// methods (e.g. DragOver).
if (not Enabled) or (FDataObject = nil) then
begin
dwEffect := DROPEFFECT_NONE;
Result := E_UNEXPECTED;
end else
begin
ShiftState := KeysToShiftStatePlus(grfKeyState);
// Create a default drop effect based on the shift state and allowed
// drop effects (or an OnGetDropEffect event if implemented).
if (FTarget <> nil) then
ClientPt := FTarget.ScreenToClient(pt)
else
ClientPt := pt;
dwEffect := GetValidDropEffect(ShiftState, ClientPt, dwEffect);
// Get data from source and generate an OnDrop event unless we failed to
// get data.
try
if (FGetDataOnEnter or GetData(dwEffect)) then
begin
if (not AsyncTransfer) then
DoDrop(ShiftState, ClientPt, dwEffect);
end else
dwEffect := DROPEFFECT_NONE;
Result := S_OK;
except
// We must not allow exceptions to escape from any of the COM methods since
// COM doesn't support exceptions.
dwEffect := DROPEFFECT_NONE;
Result := E_UNEXPECTED;
raise; // <--- Why can't I get the exception
end;
end;
if (DropTargetHelper <> nil) then
DropTargetHelper.Drop(DataObj, pt, dwEffect)
else
if (FDragImageHandle <> 0) and (FTarget <> nil) then
ImageList_DragLeave(FTarget.Handle);
finally
// clean up!
if (not AsyncTransfer) then
begin
ClearData;
FDataObject := nil;
FTarget := nil;
end;
FDropTargetHelper := nil;
end;
except
raise; // <--- Why can't I get the exception
end;
end;
// We must not allow exceptions to escape from any of the COM methods since
// COM doesn't support exceptions.