Super Editor のフレームワークを作成する

Tree View, List View, Tool Box, Status Bar を配置して、Tree View にフォルダーを展開します。

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

Main.cpp の説明

  1. 空の新規プロジェクト(Main)を作成します。
    プロジェクトのフォルダーに下記のファイルを作成して下さい。
    Main.cpp ソースプログラムファイル
    Main.rc リソースファイル
    Resource.h リソースのヘッダーファイル
    SuperED.cpp Super Editor Object Class ソースファイル
    SuperED.h Super Editor Object Class ヘッダファイル
    Tool.bmp Tool Bar のアイコン画像ファイル
  2. Tool.bmp は Tool Bar に表示するアイコン用の画像ファイルです。
    一個のアイコンは 16*16 ピクセルで 256 色モードで作成しています。
    黒色は 0,0,0 にしないで 8,8,8 ぐらいに設定して下さい。
    私は黒色のつもりで 0,0,0 に設定したのですが、色が透き通ってしまいました。
  3. リソースは VC++ の機能を使って作成しました。
    今回リソースに登録するのは Help Menu と Tool Bar のアイコンだけです。
  4. Main.cpp のソースコードです。
    主要なヘッダファイルは SuperED.h の中で取り込んでいます。
    Shell Object を使うので comctl32.lib をリンクして下さい。
    Tree View と List View と Status Bar の ID を定義します。
    SuperED *App は SuperED Object Class の定義です。
    Tool Bar とインスタンスの Handle を定義します。
    dir は Tree View に展開する仮のフォルダーです。
    TBBUTTON tbb[] に Tool Bar の仮の設定を定義しています。
        /****************************************/
        /*★ Super Editor  Program    前田 稔 ★*/
        /****************************************/
        #define     NAME    "Super Editor"
        #include    "SuperED.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
        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\\";
        TBBUTTON tbb[]=
        {   {0,  IDHELP,  TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0},
                   :
            {9,  IDHELP,  TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0},
        };
        
  5. WinMain() はいつもと同じです。
    WM_CREATE: の処理です。
    Tree View と List View と ToolBar と Status Bar を生成します。
    new SuperED() で Object をインスタンス化して App->TRView() で Tree View にフォルダーを展開します。
        //★ Call Back Procedure
        LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
        {   HWND            hTree;
            HWND            hList;
            HWND            hStatus;
            NM_TREEVIEW     *pNM;
            TV_DISPINFO     *tvinfo;
            char            *pBuf;
            HTREEITEM       hItem;
            int             w,h;
    
            switch (msg)
            {   case WM_CREATE:
                    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();
                    break;
        
  6. WM_SIZE で Tree View と List View と Tool Bar と Status Bar のサイズを調整します。
    WM_COMMAND で処理するのは、今回は Help だけです。
            case WM_SIZE:
                w= LOWORD(lp);
                h= HIWORD(lp);
                MoveWindow(App->hTree,2,30,(w-6)/3,h-50,TRUE);
                MoveWindow(App->hList,(w)/3,30,(w)/3*2,h-50,TRUE);
                SendMessage(g_hToolBar,TB_AUTOSIZE,0,0);
                SendMessage(App->hStatus,WM_SIZE,wp,lp);
                break;
            case WM_COMMAND:
                switch(LOWORD(wp))
                {   case IDHELP:
                        MessageBox(hWnd,"Program by Maeda Minoru  Ver 1.0","Super Editor", MB_OK); 
                        break;
                    default:
                        return DefWindowProc(hWnd, msg, wp, lp);
                }
                break;
        
  7. Tree View のダブルクリックでフォルダーを移動します。
    Tree View には3レベル分のフォルダーを展開していて、上位のフォルダーが選択されたときに親を、 下位のフォルダーが選択されたときに1レベル子のフォルダーを展開します。
            case WM_NOTIFY:
                if (LOWORD(wp)==ID_TREE)
                {   tvinfo= (TV_DISPINFO *)lp;
                    pNM   = (NM_TREEVIEW *)lp;
                    switch(tvinfo->hdr.code)
                    {   case NM_DBLCLK:
                            hItem= TreeView_GetSelection(App->hTree);
                            pBuf= App->GetText(hItem);
                //DMsg(pBuf,1);
                            hItem= TreeView_GetParent(App->hTree,hItem);
                            if (hItem==NULL)
                            {   //親のフォルダーに移動
                                App->Parent();
                                break;
                            }
                            hItem= TreeView_GetParent(App->hTree,hItem);
                            if (hItem==NULL)    break;
                            pBuf= App->GetText(hItem);
                //DMsg(pBuf,2);
                            //子のフォルダーに移動
                            App->Child(pBuf);
                            break;
                    }
                    return 0L;
                }
                break;
            case WM_DESTROY:
                SAFE_DELETE(App);
                PostQuitMessage(0);
                break;
        


SuperED.h の説明

  1. SuperED.h のソースコードです。
    Set_TVdata() は再起でフォルダーを Tree View に展開する関数です。
    TRView() は Tree View をリセットして Set_TVdata() を使って Tree View にアイテムを登録します。
    GetText() は Tree View に表示されている TEXT を取得する関数です。
    Parent() は親の Directry を TRView() を使って Tree View に展開する関数です。
    Child() は子の Directry を TRView() を使って Tree View に展開する関数です。
        //★ 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; } }
    
        class SuperED
        { //★非公開部分
          protected:
            HIMAGELIST      hSmall;             //Small Icon
            TV_INSERTSTRUCT tv;                 //Tree View Insert
            TV_ITEM         tvItem;
    
            int     Set_TVdata(HTREEITEM par, int n);
    
          //★公開部分
          public:
            HWND            hTree;              //Tree View Handle
            HWND            hList;              //List View Handle
            HWND            hStatus;            //Status Bar Handle
            char            path[MAX_PATH];     //Directry Path
            char            buf[MAX_PATH];
    
            SuperED(HWND, HWND, HWND, LPCSTR);  //Constructor
            ~SuperED();                         //Destructor
            void    TRView();
            char*   GetText(HTREEITEM hitem);
            void    Parent();
            void    Child(char *str);
         };
        


SuperED.cpp の説明

  1. SuperED.cpp のソースコードです。
    Constructor ではハンドルとフォルダーを Object に格納して、イメージリストを設定します。
        //★ Super Edit Object Class    前田 稔
        #include    "SuperED.h"
    
        //★ Constructor
        SuperED::SuperED(HWND Tree, HWND List, HWND Status, LPCSTR dir)
        {   SHFILEINFO  sfi;
            hTree= Tree;
            hList= List;
            hStatus= Status;
            strcpy(path, dir);
            //イメージリストのハンドルを得る
            hSmall = (HIMAGELIST)SHGetFileInfo((LPCSTR)"C:\\",0,&sfi,sizeof(SHFILEINFO),
                                 SHGFI_SYSICONINDEX | SHGFI_SMALLICON);
            if (hSmall)  TreeView_SetImageList(hTree,hSmall,0);
        }
    
        //★ Destructor
        SuperED::~SuperED()
        {
        }
        
  2. Tree View をリセットして Tree View にアイテムを登録します。
    レベル0の登録は TVI_ROOT を親に設定して 0 で Set_TVdata() をコールします。
    登録したフォルダー名を Status Bar に表示します。
        //★ Tree View をリセットして Item を表示する
        void  SuperED::TRView()
        {   memset((char *)&tv,0,sizeof(TV_INSERTSTRUCT));
            tv.hInsertAfter= TVI_LAST;
            tv.item.mask= TVIF_TEXT | TVIF_IMAGE;
            if (SetCurrentDirectory(path)==0)
            {   MessageBox(NULL,path,"First Directory Error",MB_OK);
                return;
            }
            TreeView_DeleteAllItems(hTree);
            Set_TVdata(TVI_ROOT,0);
            SendMessage(hStatus,SB_SETTEXT,255 | 0,(WPARAM)path);
        }
        
  3. 再起でフォルダーを Tree View に展開する関数です。
    フォルダーの中を全て Tree View に展開するのは、時間もかかるし現実的で無いので3レベルまで展開しています。
    それでも沢山のファイルが格納されている Windows のフォルダーなどでは、多少時間がかかります。
        //★ 再起で Tree View に登録
        int  SuperED::Set_TVdata(HTREEITEM par, int n)
        {   WIN32_FIND_DATA fd;
            HTREEITEM       hParent;
            SHFILEINFO      sfi; 
            HANDLE          hFind;
            BOOL            bRet= TRUE;
            int             i;
    
            if (n>2)    return -1;
            tv.hParent= par;
            hFind= FindFirstFile("*.*",&fd);
            for(i=0; hFind!=INVALID_HANDLE_VALUE && bRet; i++)
            {
                if (!(fd.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY))    goto next;  //!Directry 
                if (fd.dwFileAttributes&FILE_ATTRIBUTE_SYSTEM)          goto next;  //System
                if (fd.dwFileAttributes&FILE_ATTRIBUTE_HIDDEN)          goto next;  //隠しファイル
                if (fd.cFileName[0]=='.')                               goto next;  //.[..]
                tv.item.pszText = fd.cFileName;
                SHGetFileInfo(fd.cFileName,0,&sfi,sizeof(SHFILEINFO),
                              SHGFI_SYSICONINDEX | SHGFI_SMALLICON | SHGFI_TYPENAME);
                tv.item.iImage= sfi.iIcon;
                hParent= TreeView_InsertItem(hTree,&tv);
                //☆Sub Directry を再起検索
                if (n<2)
                {   if (SetCurrentDirectory(fd.cFileName))
                    {   Set_TVdata(hParent,n+1);
                        SetCurrentDirectory("..");
                    }
                    else    MessageBox(NULL,fd.cFileName,"Next Directory Error",MB_OK);
                }
                tv.hParent= par;
            next:
                bRet= FindNextFile(hFind,&fd);
            }
            TreeView_SortChildren(hTree,par,0);
            return(n);
        }
        
  4. hitem で指示された Item の TEXT を取得する関数です。
    取得した TEXT は buf の領域に格納してリターンされます。
        //★ Tree View の TEXT を取得する
        char*  SuperED::GetText(HTREEITEM hitem)
        {   memset((char *)&tvItem,0,sizeof(TV_ITEM));
            tvItem.hItem= hitem;
            tvItem.mask= TVIF_TEXT;
            tvItem.pszText= buf;
            tvItem.cchTextMax= MAX_PATH;
            if (TreeView_GetItem(hTree,&tvItem)==FALSE)
            {   MessageBox(NULL,"GetText Error","TRView Object Class",MB_OK);
                return NULL;
            }
            return buf;
        }
        
  5. path の領域には、現在表示中のフルパスが格納されています。
    path を1レベル親に設定して Tree View に展開します。
        //★ 親の Directry に移動する
        void  SuperED::Parent()
        {   int i;
            for(i=strlen(path)-2; i>0 && path[i]!='\\'; i--);
        //DMsg(path,9);
            if (i>0)
            {   path[i+1]= '\0';
                TRView();
            }
        }
        
  6. path の領域には、現在表示中のフルパスが格納されています。
    path に str を連結したフォルダーを Tree View に展開します。
        //★ 子の Directry に移動する
        void  SuperED::Child(char *str)
        {   strcat(path,str);
            strcat(path,"\\");
        //DMsg(path,9);
            TRView();
        }
        

[Next Chapter ↓] List View の設定と Drag & Drop
[Previous Chapter ↑] Super Editor を作成する

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