在我的delphi项目中拖放不起作用

这个话题显然在这里一遍又一遍地被打了,但是现在我从我的观点来看只是没有办法。

操作系统: Windows XP SP3

所以,这里是我在我的应用程序中使用的RichEdit的拖放示例

procedure TForm1.AcceptFiles( var msg : TMessage ); // or TWMDROPFILES const cnMaxFileNameLen = 255; var i, nCount : integer; acFileName : array [0..cnMaxFileNameLen] of char; begin // find out how many files we're accepting nCount := DragQueryFile( msg.WParam, // or msg.Drop $FFFFFFFF, acFileName, cnMaxFileNameLen ); // query Windows one at a time for the file name for i := 0 to nCount-1 do begin DragQueryFile( msg.WParam, { or msg.Drop} i, acFileName, cnMaxFileNameLen ); // do your thing with the acFileName MessageBox( Handle, acFileName, '', MB_OK ); end; // let Windows know that you're done DragFinish( msg.WParam ); // or msg.Drop end; 

问题是,经过一些最近的变化(unforutinetly我不使用任何SVN,所以我不能跟踪哪个承诺引入这个问题)拖放不再工作。

在每个可能与某种相关的事件(所谓的)相关的事件中,我都运行了断点而没有成功:

 RichEditMouseOver; RichEditChange; FormClick; 

我的应用程序正在处理这些WM的:

 procedure WMDropFiles(var Msg: TWMDROPFILES); message WM_DROPFILES; procedure WMSysCommand(var Msg: TWMSysCommand); message WM_SYSCOMMAND; procedure WMCopyData(var Msg: TWMCopyData); message WM_COPYDATA; procedure WMGetMinMaxInfo(var AMsg: TWMGetMinMaxInfo); message WM_GETMINMAXINFO; procedure CMDialogKey(var Msg: TCMDialogKey ); message CM_DIALOGKEY; 

在窗体上使用TRichEdit的空白项目 – 一切正常。

也尝试改变DragAcceptFiles() Form1.Handle RichEdit.Handle – 仍然没有运气。

当echo'ing nCountacFileName参数,acFileName没有文件path的拖动文件…为什么?

目前我只是不知道是什么使acFileName参数丢失拖动文件path。 你能提出隐藏问题的地方吗?

恐怕我不是如何拖放文件实际工作的专家。 所以我不能通过你的代码找出什么是错的。

我能做的是给你我使用的代码。 它适用于我现在在XP,Vista和Windows 7的德尔福2009年。它也适用于我以前在Windows 98和Windows XP上使用Delphi 4。

也许你可以用你的代码来弄清楚你的代码有什么问题,或者你可能想尝试使用或修改这段代码。 它最初来自于“Delphi 3 – 用户界面设计”一书,第169-171页。

如果我忽略了一个重要的例程,请在评论中告诉我,我将编辑我的答案以包含它。

 type TMainForm = class(TForm) procedure WMDropFiles(var WinMsg: TMessage); message wm_DropFiles; procedure AppMessageHandler(var Msg: TMsg; var Handled: Boolean); procedure TMainForm.FormShow(Sender: TObject); begin DragAcceptFiles(Handle, true); Application.OnMessage := AppMessageHandler; end; procedure TLogoAppForm.WMDropFiles(var WinMsg: TMessage); const BufSize = 255; var TempStr : array[0..BufSize] of Char; NumDroppedFiles, I: integer; Filenames: TStringList; begin NumDroppedFiles := DragQueryFile(TWMDropFiles(WinMsg).Drop, $ffffffff, nil, 0); if NumDroppedFiles >= 1 then begin Filenames := TStringList.Create; for I := 0 to NumDroppedFiles - 1 do begin DragQueryFile(TWMDropFiles(WinMsg).Drop, I, TempStr, BufSize); Filenames.Add(TempStr); end; OpenFiles(Filenames, ''); Filenames.Free; end; DragFinish(TWMDropFiles(WinMsg).Drop); WinMsg.Result := 0; end; procedure TLogoAppForm.AppMessageHandler(var Msg: TMsg; var Handled: Boolean); begin if (Msg.Message = WM_DropFiles) and IsIconic(Application.Handle) then begin Perform(Msg.Message, Msg.Wparam, Msg.lParam); Handled := true; end end; 

从官方Microsoft支持论坛提取:

无法将文件拖放到应用程序的可能原因可能是UAC完整性级别(IL)。 在Vista或Win7中启用UAC的情况下,默认情况下不允许从低IL进程到高IL进程进行拖放。 发生问题时,请检查您的应用程序是否升级(以管理员身份运行)。

如果您不想禁用UAC,则可以尝试仅禁用UIPI(用户界面特权隔离)。

打开注册表并转到:HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Windows \ CurrentVersion \ Policies \ System

添加一个名为EnableUIPI的新DWORD(32位)值,并将其设置为0。

重新启动机器,看它是否按照您的要求运行。

我要在这里刺探心理调试; 你说它“不再有效”,暗示它在某个时刻起作用。 虽然你没有提到你使用的是哪个操作系统,但是我也会推测你使用的是Windows Vista或者Windows 7(或者相关的服务器版本)。

我怀疑发生的事情是您的应用程序作为不同于shell的用户或权限级别运行。 Windows不允许拖动(特别是文件拖动)数据从一个特权级别的应用程序转移到另一个特权级别。 如果您是从IDE运行此程序,并且IDE以管理员身份运行,那么衍生的进程也在该级别运行。

检查以确保您的应用程序实际上以登录用户身份运行。 我已经被这个次数咬了很多次,而且非常微妙,以至于不知道发生了什么。