delphi - 使用对话框时无法使 DragAcceptFiles 工作

标签 delphi winapi drag-and-drop dialog

我正在使用 Delphi 编写一个简单的应用程序,该应用程序需要接受拖放到其上的目录名称。虽然我使用的是 Delphi,但这个程序是直接的 Windows API(没有 VCL,没有面向对象的东西),就像在纯 C 中一样。

我有一些代码已经可以使用普通窗口(由 CreateWindowEx 创建)运行。当我将该代码转换为使用对话框时,拖放功能损坏了,我无法弄清楚原因。

这是我工作正常的代码(部分):


function WndProc (Wnd : hWnd; Msg, wParam, lParam : DWORD) : DWORD; stdcall;
  { main application/window handler function                                  }
const
  DROPPED_FILE_COUNT  = -1;

var
  FileCnt     : integer;                            { number of files dropped }

  Filename    : packed array[0..MAX_PATH] of char;  { filename buffer         }
  DropInfo    : HDROP absolute wParam;              { wParam points to Drop...}

  I           : integer;                            { for loop                }

begin
  WndProc := 0;

  { let the Windows default handler take care of everything                   }

  case msg of
    WM_CREATE:
       begin
         InitCommonControls;

         if CreateWindowEx(WS_EX_CLIENTEDGE or WS_EX_RIGHTSCROLLBAR,
                           'LISTBOX',
                           nil,
                           WS_CHILD        or WS_HSCROLL      or WS_VSCROLL or
                           WS_CLIPSIBLINGS or WS_CLIPCHILDREN or
                           WS_VISIBLE      or LBS_NOINTEGRALHEIGHT,
                           0,
                           0,
                           0,
                           0,
                           Wnd,
                           IDC_LISTBOX,
                           hInstance,
                           nil) = 0 then
         begin
           MessageBox(Wnd,
                      'Couldn''t create the listbox', 'Main Window', MB_OK);

           WndProc := -1;
         end;

         { let Windows know that we accept files being dragged over our client}
         { area.                                                              }

         DragAcceptFiles(Wnd, TRUE);

         { tell the listbox to use a nice font                                }

         SendMessage(GetDlgItem(Wnd, IDC_LISTBOX),
                     WM_SETFONT, GetStockObject(DEFAULT_GUI_FONT), 0);

         exit;
       end; { WM_CREATE }

    WM_DROPFILES:
       begin
         { one or more files have been dropped on us!                         }

         FileCnt := DragQueryFile(DropInfo, DROPPED_FILE_COUNT, nil, 0);

         for I := 0 to FileCnt - 1 do
           begin
             { get the dropped files names and add them to the listbox        }

             DragQueryFile(DropInfo, I, Filename, sizeof(Filename));

             ListBox_AddString(GetDlgItem(Wnd, IDC_LISTBOX), Filename);
           end;

         { tell Windows that we are done grabbing the dropped files           }

         DragFinish(DropInfo);

         exit;
       end; { WM_DROPFILES }

    ... followed by other stuff that has nothing to do with drag and drop ... 

我将其转换为:


procedure ExecWM_INITDIALOG(wnd : hWnd);
begin
  { ensure that the listbox isn't accepting dropped files }

  DragAcceptFiles(GetDlgItem(Wnd, IDC_DIRECTORIES), FALSE);

  { ensure the main dialog window accept dropped files }

  DragAcceptFiles(Wnd, TRUE);

  { load the current values in the registry                                   }

  LoadRegistrySettings(RegistryKey, RegistrySettings, RegistrySettingsCount)
end;

procedure ExecWM_DROPFILES(Wnd : hWnd; wParam : word; lParam : longint);
const
  DROPPED_FILE_COUNT  = -1;

var
  FileCnt     : integer;                            { number of files dropped }

  Filename    : packed array[0..MAX_PATH] of char;  { filename buffer         }
  DropInfo    : HDROP absolute wParam;              { wParam points to Drop...}

  I           : integer;                            { for loop                }
begin
  { one or more files have been dropped on us!                         }

  { -->>> The problem seems to show up at this statement:              }
  {        the DropInfo (wParam) has a value that seems too low ($20)  }
  {        when using the code that works the value is much larger     }

  FileCnt := DragQueryFile(DropInfo, DROPPED_FILE_COUNT, nil, 0);

  for I := 0 to FileCnt - 1 do
    begin
      { get the dropped files names and add them to the listbox        }

      DragQueryFile(DropInfo, I, Filename, sizeof(Filename));

      ListBox_AddString(GetDlgItem(Wnd, IDC_DIRECTORIES), Filename);
    end;

  { tell Windows that we are done grabbing the dropped files           }

  DragFinish(DropInfo);
end;

function BackupConfigProc(wnd      : hWnd;
                          msg      : word;
                          wParam   : word;
                          lParam   : longint) : bool; stdcall;
begin
  BackupConfigProc := FALSE;            { default return value                }

  case msg of
    WM_COMMAND:
    begin
      ExecWM_COMMAND (wnd, wParam, lParam);
      BackupConfigProc := TRUE;
    end;

    WM_DROPFILES:
    begin
      ExecWM_DROPFILES(Wnd, wParam, lParam);
      //BackupConfigProc := TRUE;    { this was a shot in the dark }
    end;

    WM_INITDIALOG:
       begin
         ExecWM_INITDIALOG (wnd);
         BackupConfigProc := TRUE;
       end;

    WM_CLOSE:
       begin
         EndDialog(wnd, 0);     { and return the default FALSE                }
       end;
  end;
end;

begin
  DialogBox(hInstance, 'BackupConfigDlg', 0, @BackupConfigProc);
end.

看起来对话框接收到的 DropInfo (wParam) 值无效(因为它的值比有效的非对话框代码接收到的值低得多)。

我将感谢所有能够阐明为什么 Dialog 版本不起作用以及需要采取哪些措施才能使其起作用的人。

谢谢,

约翰。

最佳答案

procedure ExecWM_DROPFILES(Wnd : hWnd; wParam : word; lParam : longint);

wParam 不应输入 word,而应输入 Windows.WPARAM,它实际上是一个 long int(在 Win32 上)。

关于delphi - 使用对话框时无法使 DragAcceptFiles 工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5790164/

相关文章:

c - Windows 和 Linux 上的内存页面写入检测

javascript - 基于拖放项目的 jquery 验证

delphi - 接口(interface) DLL 表单应用程序崩溃

java - Delphi 中的 "Word"是否与 Java 中的 "Char"等效?

delphi - BDE和斯洛伐克语。有驱动程序吗?

c# - 捕获事件窗口更改事件时出现问题

winapi - FS在Win32中注册

javascript - 如何使用jQuery的drop事件上传从桌面拖拽的文件?

javascript - Vue JS 在使用 v-for 渲染的单个项目上切换类

delphi - 音乐符号 UI VCL 组件。它存在吗?