Я использую 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 не работает и что нужно сделать, чтобы она работала.
Спасибо,
Джон.