2011-04-26 54 views
3

我正在使用Delphi編寫一個簡單的應用程序,該應用程序需要接受已刪除的目錄名稱。雖然我使用的是Delphi,但這個程序是直接Windows API(沒有VCL,沒有面向對象的東西),就像它在普通的C中一樣。使用對話框時,無法使DragAcceptFiles正常工作

我有一些代碼已經在使用普通窗口工作了(由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版本爲什麼不起作用以及需要做什麼才能使其工作的人員。

謝謝,

約翰。

回答

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

wParam中不應該鍵入wordWindows.WPARAM這實際上是一個長整型(在Win32)。

+0

你是我的極度尷尬,絕對正確!我剛剛意識到,我複製的一些代碼來自我在Windows 3.1時代編寫的程序。適當調整參數後,它工作得很好。謝謝你,我對這個愚蠢的錯誤表示歉意。 – Hex440bx 2011-04-26 12:30:57