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

Hex*_*0bx 3 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版本不起作用以及需要做些什么来使其工作的人.

谢谢,

约翰.

Fre*_*man 5

procedure ExecWM_DROPFILES(Wnd : hWnd; wParam : word; lParam : longint);
Run Code Online (Sandbox Code Playgroud)

不应该键入wParam wordWindows.WPARAM实际上是一个long int(在Win32上).