ホームに戻る 初歩のVC++Programming Tipsに戻る

初歩のVC++Programming Tips Win32SDK篇

アプリケーションへのファイルのDropを実現する方法


次のようにします。

1.ウィンドウへのファイルのDropを許可する

DragAcceptFiles(hWnd,TRUE);

でウインドウハンドルhWndが示すウインドウへのファイルのDropが許可されます。これ以降ファイルがDropされると、WindowプロシージャにWM_DROPFILESが送られます。ウインドウプロシージャ側ではこのメッセージを受け取ったときの処理が必要です。

2.ウインドウプロシージャでWM_DROPFILESメッセージを受け取る

WM_DROPFILESメッセージを受け取ったら

UINT DragQueryFile(

    HDROP hDrop, //DroppedFiles構造体のハンドル(Windowプロシージャの引数wParamから渡される)
    UINT iFile, //Doropされたファイル達のインデックス(0から) -1を指定すると戻り値としてDropされたファイルの総数が返る
    LPTSTR lpszFile, //受け取るファイル名を格納するバッファ
    UINT cch  //同バッファのサイズ
   );

で、ドロップされたファイルのフルパスまたは、ファイルの総数を取得できます。

3.Drag&Dropのためのメモリを解放する。[1998/11/9 加筆]

DragFinish(hDroppedFiles);

ドロップされたファイルを取得し終えたら、この関数でhDroppedFilesを解放します。

4.ウインドウへのファイルのDropを禁止する

DragAcceptFiles(hWnd,FALSE);

で禁止できます。

サンプルプログラム

実行してみたらこんな感じ

以下、サンプルプログラムの全ソースリストです。「ダイアログベースアプリの作り方」のソースを元に作りました。

resource.h

//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by Script1.rc
//
#define IDD_DIALOG1                     101
#define IDC_STATIC1                     1001
#define IDC_LIST1                       1003

// Next default values for new objects
// 
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NO_MFC                     1
#define _APS_NEXT_RESOURCE_VALUE        102
#define _APS_NEXT_COMMAND_VALUE         40001
#define _APS_NEXT_CONTROL_VALUE         1004
#define _APS_NEXT_SYMED_VALUE           101
#endif
#endif

tips13.c

/******************************************************************************
title    : tips13 - ウインドウへのファイルのドロップ  for win95/98/NT4.0
compiler : VC++ 5.0
******************************************************************************/
#include<windows.h>
#include<commctrl.h>
#include"resource.h"

/* グローバル変数 */
const char  szClassName[]="Tips13Class";
const char  szAppName[]="Tips13";
const char  szAppVer[]="1.0";
HWND        hDlg;           //メインダイアログハンドル
HINSTANCE   hInst;          //インスタンスハンドル


/*-----------------------------------------------------------------------------
  メインダイアログプロシージャ
-----------------------------------------------------------------------------*/
LRESULT CALLBACK mainDlgProc(HWND hWnd,UINT uMessage,WPARAM wParam,LPARAM lParam)
{
    char szTmp[MAX_PATH+1];

    switch(uMessage){
    //ウインドウ作成時の処理
    case WM_INITDIALOG:
        DragAcceptFiles(hWnd,TRUE);//Drag&Drop on
        break;
    
    //ユーザーメッセージ処理
    case WM_COMMAND:
        switch(LOWORD(wParam)){
        //終了
        case IDOK:
        case IDCANCEL:
            DragAcceptFiles(hWnd,FALSE);//Drag&Drop off
            DestroyWindow(hWnd);
            break;
        
        default:
            return DefWindowProc(hWnd,uMessage,wParam,lParam);
        }
        break;
    
    //ファイルがドロップされたときの処理
    case WM_DROPFILES:
    {
        UINT    iFileNum;
        UINT    iCount;
        HDC     hDc;
        int     iSave;
        HFONT   hFont;
        UINT    iMaxNum=0;
        UINT    iMaxColumn=0;
        UINT    iListWidth=0;
        SIZE    size;
        
        //ドロップされたファイル数
        iFileNum=DragQueryFile((HDROP )wParam,-1,NULL,0);
        SetDlgItemInt(hWnd,IDC_STATIC1,iFileNum,FALSE);
        
        //リストボックスにドロップされたファイルの一覧を表示する
        for(iCount=0; iCount<iFileNum; iCount++)
        {
            DragQueryFile((HDROP )wParam,iCount,szTmp,MAX_PATH);
            SendMessage(GetDlgItem(hWnd,IDC_LIST1),LB_ADDSTRING,0,(LPARAM )(LPCTSTR )szTmp);
            //一番長い文字列を保存
            if(lstrlen(szTmp)>(int )iMaxColumn)
            {
                iMaxColumn=lstrlen(szTmp);
                iMaxNum=iCount;
            }
        }
        
        //必要なら水平スクロールバーを表示する
        DragQueryFile((HDROP )wParam,iMaxNum,szTmp,MAX_PATH);
        DragFinish((HDROP )wParam);
        hDc=GetDC(GetDlgItem(hWnd,IDC_LIST1));
        iSave=SaveDC(hDc);
        hFont=(HFONT )SendMessage(GetDlgItem(hWnd,IDC_LIST1),WM_GETFONT,0,0);
        if(hFont != NULL)
        {
            SelectObject(hDc,hFont);
        }
        GetTextExtentPoint32(hDc,szTmp,lstrlen(szTmp),&size);
        iListWidth=size.cx+GetSystemMetrics(SM_CXVSCROLL);
        SendMessage(GetDlgItem(hWnd,IDC_LIST1),LB_SETHORIZONTALEXTENT,(WPARAM )iListWidth,0L);
        RestoreDC(hDc,iSave);
        ReleaseDC(GetDlgItem(hWnd,IDC_LIST1),hDc);
        break;
    }
    
    //[X]ボタン
    case WM_CLOSE:
        PostMessage(hWnd,WM_COMMAND,IDCANCEL,0);
        break;
    
    //プログラム終了時のウインドウ破棄
    case WM_DESTROY:
        PostQuitMessage(0);
        break;

    default:
        return DefWindowProc(hWnd,uMessage,wParam,lParam);
    }//switch end
    
    return 0;
}


/*=============================================================================
  WinMain
=============================================================================*/
int APIENTRY WinMain(HINSTANCE hInstCurrent, HINSTANCE hinstPrevious, LPSTR lpszCmdLine, int nCmdShow)
{
    MSG             msg;
    WNDCLASS        wndclass;
    
    hInst=hInstCurrent;

    //メインウインドウクラスの登録
    wndclass.style         = 0;
    wndclass.lpfnWndProc   = mainDlgProc;
    wndclass.cbClsExtra    = 0;
    wndclass.cbWndExtra    = DLGWINDOWEXTRA;
    wndclass.hInstance     = hInst;
    wndclass.hIcon         = LoadIcon(NULL,IDI_APPLICATION);
    wndclass.hCursor       = LoadCursor(NULL,IDC_ARROW);
    wndclass.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1);
    wndclass.lpszMenuName  = NULL;
    wndclass.lpszClassName = szClassName;
    if(RegisterClass(&wndclass) == 0)
    {
        MessageBox(NULL,"ウインドウクラスを登録できませんでした",
                szAppName,MB_APPLMODAL | MB_ICONSTOP);
        return FALSE;
    }
    
    //メインウインドウの生成
    if((hDlg=CreateDialog(hInst,MAKEINTRESOURCE(IDD_DIALOG1),0,mainDlgProc)) == NULL)
    {
        MessageBox(NULL,"メインウインドウを作成できませんでした",
                szAppName,MB_APPLMODAL | MB_ICONSTOP);
        return FALSE;
    }
    
    //メインウインドウの表示
    ShowWindow(hDlg, nCmdShow);
    UpdateWindow(hDlg);

    //メッセージループ
    while(GetMessage(&msg, NULL, 0, 0))
    {
        if(IsDialogMessage(hDlg,&msg) == FALSE)
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

    return msg.wParam;
}

Script1.rc

//Microsoft Developer Studio generated resource script.
//
#include "resource.h"

#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"

/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS

/////////////////////////////////////////////////////////////////////////////
// 日本語 resources

#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_JPN)
#ifdef _WIN32
LANGUAGE LANG_JAPANESE, SUBLANG_DEFAULT
#pragma code_page(932)
#endif //_WIN32

/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//

IDD_DIALOG1 DIALOG DISCARDABLE  0, 0, 187, 93
STYLE WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Tips13"
CLASS "Tips13Class"
FONT 9, "MS Pゴシック"
BEGIN
    PUSHBUTTON      "閉じる",IDCANCEL,130,72,50,14
    LTEXT           "",IDC_STATIC1,109,19,71,14,SS_SUNKEN
    LTEXT           "ドロップされたファイル数",IDC_STATIC,109,7,71,8
    LISTBOX         IDC_LIST1,7,7,99,79,LBS_NOINTEGRALHEIGHT | LBS_NOSEL | 
                    WS_VSCROLL | WS_HSCROLL | WS_TABSTOP
END


/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//

#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO DISCARDABLE 
BEGIN
    IDD_DIALOG1, DIALOG
    BEGIN
        LEFTMARGIN, 7
        RIGHTMARGIN, 180
        TOPMARGIN, 7
        BOTTOMMARGIN, 86
    END
END
#endif    // APSTUDIO_INVOKED


#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//

1 TEXTINCLUDE DISCARDABLE 
BEGIN
    "resource.h\0"
END

2 TEXTINCLUDE DISCARDABLE 
BEGIN
    "#include ""afxres.h""\r\n"
    "\0"
END

3 TEXTINCLUDE DISCARDABLE 
BEGIN
    "\r\n"
    "\0"
END

#endif    // APSTUDIO_INVOKED

#endif    // 日本語 resources
/////////////////////////////////////////////////////////////////////////////



#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//


/////////////////////////////////////////////////////////////////////////////
#endif    // not APSTUDIO_INVOKED

copyright (c) 1998-2000 by T-Matsuo
ホームに戻る 初歩のVC++Programming Tipsに戻る