List View の設定と Drag & Drop

Tree View, List View にフォルダーを表示して、Drag&Drop と Double Click での起動をサポートします。

前田稔(Maeda Minoru)の超初心者のプログラム入門

Main.cpp の説明

  1. プロジェクトのフォルダーに下記のファイルを格納して下さい。
    Main.cpp ソースプログラムファイル
    Main.rc リソースファイル
    Resource.h リソースのヘッダーファイル
    SuperED.cpp Super Editor Object Class ソースファイル
    SuperED.h Super Editor Object Class ヘッダファイル
    DragDrop.cpp Drag & Drop ソースファイル
    DragDrop.h Drag & Drop ヘッダファイル
    Shell.c Shell Object ソースファイル
    Shell.h Shell Object ヘッダファイル
    Tool.bmp Tool Bar のアイコン画像ファイル
    SEdit.ico Super Editor アイコンファイル
    Fhand.dat Double Click 起動設定ファイル
  2. DragDrop.cpp と DragDrop.h は Drag&Drop を行うソースプログラムとヘッダファイルです。
    詳細は C++ API で File List を Drag&Drop する を参照して下さい。
  3. Shell.cpp と Shell.h は MyComputer や DeskTop の表示を行うソースプログラムとヘッダファイルです。
    詳細は Desk Top を List View に表示する を参照して下さい。
  4. Fhand.dat は Double で起動するプログラムを設定するファイルです。
    詳細は ダブルクリックやメニューからプログラムを起動 を参照して下さい。
  5. Main.cpp のソースコードです。
    SuperED *App は SuperED Object Class の定義です。
    DRAGDROP* DragDrop は Drag&Drop Object Class の定義です。
    Tool Bar とインスタンスの Handle を定義します。
    exp[32] は編集対象とするファイル拡張子のテーブルで、DialogBox から設定/変更を行います。
    TBBUTTON tbb[] と TIPS[] に Tool Bar の仮の設定を定義しています。
        /****************************************/
        /*★ Super Editor  Program    前田 稔 ★*/
        /****************************************/
        // case WM_DROP: でファイルが Drop されたことを知らされます。
        #define     NAME    "Super Editor"
        #include    <SHLOBJ.H>
        #include    "SuperED.h"
        #include    "DragDrop.h"
        #include    "resource.h"
        #pragma     comment(lib,"comctl32.lib")
    
        // Defines, constants, and global variables
        #define     ID_TREE         100
        #define     ID_LIST         101
        #define     ID_TOOLBAR      103
        #define     ID_STATUS       104
        #define     WM_DROP         (WM_APP + 1)
    
        SuperED         *App= NULL;         //Super Edit Class
        HWND            g_hToolBar;         //Tool Bar Handle
        HINSTANCE       g_hInst;            //Instance Handle
        LPCSTR          dir= "c:\\Program Files\\Microsoft Visual Studio\\";
        char            exp[32]= ".txt.htm.html.cpp.c.h";
    
        // Drag&Drop Object
        DRAGDROP*   DragDrop;
        int         ItemCnt;                    //選択されている ITEM の数
        char        FileName[50][MAX_PATH];     //選択された ITEM Text(File Name)
    
        TBBUTTON tbb[]=
        {   {0,  ID_PARENT, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0},
            {1,  ID_CHILD,  TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0},
            {2,  ID_LTVIEW, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0},
                      :
        };
    
        LPCTSTR  TIPS[]=
        {   "親のフォルダーに移動",
            "子のフォルダーに移動",
            "List View に表示",
                  :
        };
        
  6. WinMain() はいつもと同じです。
    WM_CREATE: の処理です。
    new DRAGDROP(hWnd); で Drog&Drop の設定を行います。
    Tree View と List View と ToolBar と Status Bar を生成します。
    new SuperED() で Object をインスタンス化します。
    App->TRView() と App->LTView() で Tree View と List View にフォルダーを表示します。
    App->SetExp(exp) で、編集対象とするファイルの拡張子を設定します。
        //★ Call Back Procedure
        LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
        {   static  LPTOOLTIPTEXT   lptip;
            HWND            hTree;
            HWND            hList;
            HWND            hStatus;
            LV_DISPINFO     *lvinfo;
            NM_LISTVIEW     *pNMLV;
            HTREEITEM       hItem;
            WORD            w,h,i;
            int             id;
    
            switch (msg)
            {   case WM_CREATE:
                    OleInitialize(NULL);
                    DragDrop = new DRAGDROP(hWnd);
                    if (DragDrop==NULL)  return -1;
                    DragDrop->OnCreate();
                    InitCommonControls();
                    hTree= CreateWindowEx(0, WC_TREEVIEW, "",
                        WS_CHILD | WS_BORDER | WS_VISIBLE | TVS_HASLINES |
                        TVS_HASBUTTONS | TVS_LINESATROOT | TVS_EDITLABELS,
                        0, 0, 0, 0, hWnd,(HMENU)ID_TREE,g_hInst,NULL);
                    hList= CreateWindowEx(0, WC_LISTVIEW, "",
                        WS_CHILD | WS_VISIBLE | WS_DLGFRAME | LVS_EDITLABELS |
                        LVS_REPORT | LVS_SHAREIMAGELISTS,
                        0, 0, 0, 0, hWnd, (HMENU)ID_LIST, g_hInst, NULL);
                    g_hToolBar= CreateToolbarEx(hWnd, WS_CHILD | WS_VISIBLE | TBSTYLE_TOOLTIPS,
                        ID_TOOLBAR, 10, g_hInst, ID_BMP, tbb,
                        10, 0, 0, 16, 16, sizeof(TBBUTTON));
                    SendMessage(g_hToolBar,TB_AUTOSIZE,0,0);
                    hStatus = CreateWindowEx(0, STATUSCLASSNAME, NULL,
                        WS_CHILD|SBARS_SIZEGRIP|CCS_BOTTOM|WS_VISIBLE,
                        0, 0, 0, 0, hWnd, (HMENU)ID_STATUS, g_hInst, NULL);
                    SendMessage(hStatus,SB_SIMPLE,TRUE,0L);
                    App= new SuperED(hTree,hList,hStatus,dir);
                    App->TRView();
                    App->LTView();
                    App->SetExp(exp);
                    break;
        
  7. WM_DROP: にファイルが Drop されたときの処理を記述します。
            case WM_DROP:                       //ファイルが Drop された
                MessageBox(hWnd,"ファイルが Drop されました","WM_DROPFILES",MB_OK);
                for(i=0; i_Text[i],"File Name",MB_OK);
                App->CopyTable(DragDrop->_Text,App->folder,wp);
                App->LTView();
                break;
        
  8. WM_COMMAND の処理です。
    ID_PARENT: で Tree View の親フォルダーに設定します。
    ID_CHILD: で Tree View の子フォルダーに設定します。
    ID_LTVIEW: で Tree View で選択されたフォルダーを List View に展開します。
            case WM_COMMAND:
                switch(LOWORD(wp))
                {   case IDHELP:
                        MessageBox(hWnd,"Program by Maeda Minoru  Ver 1.0","Super Editor", MB_OK); 
                        break;
                    case ID_PARENT:             //TreeView の表示を親に設定
                        App->Parent();
                        break;
                    case ID_CHILD:              //TreeView の表示を子に設定
                        hItem= TreeView_GetSelection(App->hTree);
                        App->Child(hItem);
                        break;
                    case ID_LTVIEW:             //ListView に表示
                        hItem= TreeView_GetSelection(App->hTree);
            //pBuf= App->GetText(hItem);
            //DMsg(pBuf,-1);
                        App->LTView(hItem); 
                        break;
                    default:
                        return DefWindowProc(hWnd, msg, wp, lp);
                }
                break;
        
  9. WM_NOTIFY: の処理です。
    TTN_NEEDTEXT のとき Tool Chip を表示します。
    LVN_COLUMNCLICK: で List View のソートを行います。
    LVN_BEGINDRAG: で List View の Drag を処理します。
            case WM_NOTIFY:
                if (((LPNMHDR)lp)->code==TTN_NEEDTEXT)
                {   lptip = (LPTOOLTIPTEXT)lp;
                    lptip->hinst = g_hInst;
                    switch(lptip->hdr.idFrom)
                    {   case ID_PARENT: id= 0;  break;
                        case ID_CHILD:  id= 1;  break;
                        case ID_LTVIEW: id= 2;  break;
                        case IDHELP:    id= 3;  break;
                        default:        id= -1;
                    }
                    if (id>=0)  lptip->lpszText= (char*)TIPS[id];
                    break;
                }
                if (LOWORD(wp)==ID_LIST)
                {   lvinfo = (LV_DISPINFO *)lp;
                    pNMLV  = (NM_LISTVIEW *)lp;
                    switch(lvinfo->hdr.code)
                    {
                        case LVN_COLUMNCLICK:       //カラムクリック
                            App->Col= pNMLV->iSubItem;
                            App->SortItems(App->Col);
                            break;
                        case LVN_BEGINDRAG:
                            SetFileName(hWnd);
                            return DragDrop->OnLButtonDown(wp,lp);
                    }
                    return 0L;
                }
                break;
        
  10. WM_DESTROY: で Object の開放と後始末を行います。
            case WM_DESTROY:
                DragDrop->OnDestroy();
                delete DragDrop;
                SAFE_DELETE(App);
                OleUninitialize();
                PostQuitMessage(0);
                break;
        
  11. Drag されたファイル名を取得して Drag&Drop Object に渡す関数です。
        //★ 選択されたファイル名を取り出して FileName[] に格納する
        //   char    *_FileList[50];    //Drag File List
        int SetFileName(HWND hwnd)
        {   int         nItem;
            LV_ITEM     lvitem;
            char        buf[64];
    
            if (ListView_GetSelectedCount(App->hList)==0)
            {   MessageBox(hwnd,"Selct File Error","Drag&Drop", MB_OK);
                return FALSE;
            }
            ItemCnt=0;
            nItem= -1;
            while(ItemCnt<50)
            {   nItem = ListView_GetNextItem(App->hList,nItem,LVNI_ALL|LVNI_SELECTED);
                if (nItem == -1)    break;
                lvitem.mask= LVIF_PARAM;
                lvitem.iItem= nItem;
                lvitem.iSubItem= 0;
                if (!ListView_GetItem(App->hList,&lvitem))  continue;
                ListView_GetItemText(App->hList,nItem,0,buf,64);
                strcpy(FileName[ItemCnt],App->folder);
                strcat(FileName[ItemCnt],buf);
                DragDrop->_FileList[ItemCnt]= FileName[ItemCnt];
                ItemCnt++;
            }
            DragDrop->_FileCnt= ItemCnt;
            return TRUE;
        }
        


SuperED.h の説明

  1. SuperED.h のソースコードです。
    Set_TVdata() は再起でフォルダーを Tree View に展開する関数です。
    StaticMyCompProc() と MyCompProc() は List View のソートから参照される CALLBACK 関数です。
    TRView() は Tree View をリセットして Set_TVdata() を使って Tree View にアイテムを登録します。
    GetText() は Tree View に表示されている TEXT を取得する関数です。
    Parent() は親の Directry を TRView() を使って Tree View に展開する関数です。
    Child() は子の Directry を TRView() を使って Tree View に展開する関数です。
    LTView() は List View にアイテムを表示する関数です。
    SortItems() は List View をソートする関数です。
    SetExp() は編集対象となるファイルの拡張子を設定する関数です。
    CopyTable() は Table[] の n 個のファイル(フォルダー)を DDir のフォルダーに更新日付でコピーする関数です。
    OneCopy() は SDir から DDir に buf のファイルを一個コピーする関数です。
    CopyZ() はフォルダーごと再帰的にコピーする関数です。
    DateChk() はファイルの更新日付を比較する関数です。
        //★ Super Edit Object Class Header   前田 稔
        #include    <windows.h>
        #include    <commctrl.h>
        #define     SAFE_DELETE(p)  { if (p) { delete (p);     (p)=NULL; } }
        #define     SAFE_RELEASE(p) { if (p) { (p)->Release(); (p)=NULL; } }
        #define     UP      1
        #define     DOWN    2
        extern  "C" /* Assume C declarations for C++ */
        {       LRESULT     ViewMyLV(HWND hList);
                LRESULT     ViewMyTV(HWND hTree);
        }
    
        class SuperED
        { //★非公開部分
          protected:
            HIMAGELIST      hSmall;                 //Small Icon
            TV_INSERTSTRUCT tv;                     //Tree View Insert
            TV_ITEM         tvItem;
            int             sortno[3];
            char            Exp_T[50][8];           //ファイル拡張子
            int             Exp_N;                  //Exp の個数
    
            int             Set_TVdata(HTREEITEM par, int n);
            static int      CALLBACK    StaticMyCompProc(LPARAM, LPARAM, LPARAM);
            int             CALLBACK    MyCompProc(LPARAM, LPARAM, LPARAM);
    
          //★公開部分
          public:
            HWND            hTree;                  //Tree View Handle
            HWND            hList;                  //List View Handle
            HWND            hStatus;                //Status Bar Handle
            char            path[MAX_PATH];         //Tree View Directry Path
            char            folder[MAX_PATH];       //List View Path
            char            buf[MAX_PATH];
            int             Col;                    //Sort Key Column
    
            SuperED(HWND, HWND, HWND, LPCSTR);  //Constructor
            ~SuperED();                         //Destructor
            LRESULT         TRView(char *dir);
            LRESULT         TRView()    {  return TRView(path);  }	
            char*           GetText(HTREEITEM hitem);
            void            Parent();
            void            Child(char *str);
            void            Child(HTREEITEM hitem);
            LRESULT         LTView(char *dir);
            LRESULT         LTView()    {  return LTView(folder);  }
            LRESULT         LTView(HTREEITEM hitem);
            void            SortItems(int col);
            int             SetExp(char *str);
            LRESULT         CopyTable(char Table[][MAX_PATH], char DDir[], WORD n);
            LRESULT         OneCopy(char SDir[], char DDir[], char buf[], int flag);
            LRESULT         CopyZ(char SDir[], char DDir[], BOOL flag);
            LRESULT         DateChk(char SDir[], char DDir[]);
        };
        


SuperED.cpp の説明

  1. SuperED.cpp のプロトタイプ宣言とデータの定義と Constructor です。
    ViewMyLV() は List View に MyComputer を表示する関数です。
    ViewMyTV() は Tree View に MyComputer を表示する関数です。
    Constructor ではハンドルとフォルダーを Object に格納して、イメージリストを設定します。
        //★ Super Edit Object Class    2004-01-26  前田 稔
        #include    <windows.h>
        #include    <commctrl.h>
        #include    "SuperED.h"
        extern  "C" /* Assume C declarations for C++ */
        {       LRESULT     ViewMyLV(HWND hList);
                LRESULT     ViewMyTV(HWND hTree);
        }
    
        SuperED*    g_pApp = NULL;
        char        HEAD[][16]= {  "名前", "サイズ", "更新日付"  };
        int         CX[]=       {  300, 80, 120 };
    
        //★ Constructor
        SuperED::SuperED(HWND Tree, HWND List, HWND Status, LPCSTR dir)
        {   LV_COLUMN   lvcol;
            SHFILEINFO  sfi;
            int         i;
    
            hTree= Tree;
            hList= List;
            hStatus= Status;
            strcpy(path, dir);
            strcpy(folder, dir);
            sortno[0]=sortno[1]=sortno[2]= UP;
            Col= 0;
            //イメージリストのハンドルを得る
            hSmall = (HIMAGELIST)SHGetFileInfo((LPCSTR)"C:\\",0,&sfi,sizeof(SHFILEINFO),
                                 SHGFI_SYSICONINDEX | SHGFI_SMALLICON);
            if (hSmall)
            {   TreeView_SetImageList(hTree,hSmall,0);
                ListView_SetImageList(hList,hSmall,LVSIL_SMALL);
            }
            g_pApp = this;
            sortno[0]=sortno[1]=sortno[2]= UP;
            // Column の項目設定
            lvcol.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
            lvcol.fmt = LVCFMT_LEFT;
            for(i=0; i<3; i++)
            {   lvcol.cx = CX[i];
                lvcol.pszText = HEAD[i];
                lvcol.iSubItem = i;
                ListView_InsertColumn(hList, i, &lvcol);
            }
        }
        

[Previous Chapter ↑] Super Editor のフレームワークを作成する

超初心者のプログラム入門(Win32API C++)