• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            隨筆-341  評(píng)論-2670  文章-0  trackbacks-0
                GacUI的ListView支持Windows 7資源管理器的六種View,并且在默認(rèn)的皮膚下表現(xiàn)的跟資源管理器十分類似。這個(gè)Demo也使用了一些Shell API來獲得資源管理器使用的文件的圖標(biāo)、文件類型的字符串等等。完整的代碼可以在http://www.gaclib.net/Demos/Controls.ListView.ViewSwitching/Demo.html看到。在這里先上圖:

            Information:


            Tile:


            Detail:


            List:


            SmallIcon:


            BigIcon:


                想必這么一個(gè)簡(jiǎn)單的兩個(gè)控件的排版大家都已經(jīng)知道怎么寫了。首先創(chuàng)建一個(gè)2行1列的表格,其次直接放兩個(gè)控件進(jìn)去。代碼如下:

            #include "..\..\Public\Source\GacUI.h"
            #include 
            <ShlObj.h>

            using namespace vl::collections;

            int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int CmdShow)
            {
                
            return SetupWindowsDirect2DRenderer();
            }

            extern void FillData(GuiListView* listView);

            /***********************************************************************
            ViewSwitchingWindow
            **********************************************************************
            */

            class ViewSwitchingWindow : public GuiWindow
            {
            private:
                GuiListView
            *                    listView;
                GuiComboBoxListControl
            *            comboView;

                
            void comboView_SelectedIndexChanged(GuiGraphicsComposition* sender, GuiEventArgs& arguments)
                {
                    
            switch(comboView->GetSelectedIndex())
                    {
                    
            case 0:
                        listView
            ->ChangeItemStyle(new list::ListViewBigIconContentProvider);
                        
            break;
                    
            case 1:
                        listView
            ->ChangeItemStyle(new list::ListViewSmallIconContentProvider);
                        
            break;
                    
            case 2:
                        listView
            ->ChangeItemStyle(new list::ListViewListContentProvider);
                        
            break;
                    
            case 3:
                        listView
            ->ChangeItemStyle(new list::ListViewDetailContentProvider);
                        
            break;
                    
            case 4:
                        listView
            ->ChangeItemStyle(new list::ListViewTileContentProvider);
                        
            break;
                    
            case 5:
                        listView
            ->ChangeItemStyle(new list::ListViewInformationContentProvider);
                        
            break;
                    }
                }
            public:
                ViewSwitchingWindow()
                    :GuiWindow(GetCurrentTheme()
            ->CreateWindowStyle())
                {
                    
            this->SetText(L"Controls.ListView.ViewSwitching");

                    GuiTableComposition
            * table=new GuiTableComposition;
                    table
            ->SetCellPadding(4);
                    table
            ->SetAlignmentToParent(Margin(0000));
                    table
            ->SetRowsAndColumns(21);
                    table
            ->SetRowOption(0, GuiCellOption::MinSizeOption());
                    table
            ->SetRowOption(1, GuiCellOption::PercentageOption(1.0));
                    table
            ->SetColumnOption(0, GuiCellOption::PercentageOption(1.0));
                    {
                        GuiCellComposition
            * cell=new GuiCellComposition;
                        table
            ->AddChild(cell);
                        cell
            ->SetSite(0011);

                        GuiTextList
            * comboSource=g::NewTextList();
                        comboSource
            ->GetItems().Add(L"Big Icon");
                        comboSource
            ->GetItems().Add(L"Small Icon");
                        comboSource
            ->GetItems().Add(L"List");
                        comboSource
            ->GetItems().Add(L"Detail");
                        comboSource
            ->GetItems().Add(L"Tile");
                        comboSource
            ->GetItems().Add(L"Information");
                        comboSource
            ->SetHorizontalAlwaysVisible(false);

                        comboView
            =g::NewComboBox(comboSource);
                        comboView
            ->SetSelectedIndex(0);
                        comboView
            ->GetBoundsComposition()->SetAlignmentToParent(Margin(00-10));
                        comboView
            ->GetBoundsComposition()->SetPreferredMinSize(Size(1600));
                        comboView
            ->SelectedIndexChanged.AttachMethod(this&ViewSwitchingWindow::comboView_SelectedIndexChanged);
                        cell
            ->AddChild(comboView->GetBoundsComposition());
                    }
                    {
                        GuiCellComposition
            * cell=new GuiCellComposition;
                        table
            ->AddChild(cell);
                        cell
            ->SetSite(1011);

                        listView
            =g::NewListViewBigIcon();
                        listView
            ->GetBoundsComposition()->SetAlignmentToParent(Margin(0000));
                        listView
            ->SetHorizontalAlwaysVisible(false);
                        listView
            ->SetVerticalAlwaysVisible(false);
                        listView
            ->SetMultiSelect(true);
                        cell
            ->AddChild(listView->GetBoundsComposition());
                    }
                    
            this->GetBoundsComposition()->AddChild(table);
                    FillData(listView);

                    
            // set the preferred minimum client size
                    this->GetBoundsComposition()->SetPreferredMinSize(Size(640480));
                    
            // call this to calculate the size immediately if any indirect content in the table changes
                    
            // so that the window can calcaulte its correct size before calling the MoveToScreenCenter()
                    this->ForceCalculateSizeImmediately();
                    
            // move to the screen center
                    this->MoveToScreenCenter();
                }
            };

                在非虛擬模式下的ListView控件可以使用listView->ChangeItem(list::ListView*ContentProvider)來切換外觀。整個(gè)控件的設(shè)計(jì)是開放的,如果程序員有特別的要求的話,也可以實(shí)現(xiàn)一個(gè)類似的ContentProvider來控制每一個(gè)item的外觀。ContentProvider可以控制的地方有列表項(xiàng)的排版、坐標(biāo)系和每一個(gè)列表項(xiàng)的皮膚等等。排版和坐標(biāo)系都已經(jīng)有很多預(yù)定義的類(實(shí)現(xiàn))可以使用。值得一提的是,在Detail模式下的ColumnHeader是列表項(xiàng)的排版組件放進(jìn)去的。如果沒有特別復(fù)雜的要求,單純要顯示數(shù)據(jù)的話,使用起來很簡(jiǎn)單。上面的代碼有一個(gè)關(guān)鍵的FillData函數(shù),用于讀取Windows目錄(通常是C:\Windows)的文件內(nèi)容然后顯示上去。代碼如下:

            /***********************************************************************
            FillData
            **********************************************************************
            */

            void FillList(GuiListView* listView, const WString& path, List<WString>& files)
            {
                
            // Fill all information about a directory or a file.
                FOREACH(WString, file, files.Wrap())
                {
                    Ptr
            <list::ListViewItem> item=new list::ListViewItem;
                    WString fullPath
            =path+L"\\"+file;

                    
            // Get large icon.
                    item->largeImage=GetFileIcon(fullPath, SHGFI_LARGEICON | SHGFI_ICON);
                    
            // Get small icon.
                    item->smallImage=GetFileIcon(fullPath, SHGFI_SMALLICON | SHGFI_ICON);
                    
            // Get display name
                    item->text=GetFileDisplayName(fullPath);
                    
            // Get type name
                    item->subItems.Add(GetFileTypeName(fullPath));
                    
            // Get last write time
                    item->subItems.Add(GetFileLastWriteTime(fullPath));
                    
            // Get file size
                    item->subItems.Add(GetFileSize(fullPath));

                    listView
            ->GetItems().Add(item);
                }
            }

            void FillData(GuiListView* listView)
            {
                
            // Get the Windows directory, normally L"C:\Windows".
                wchar_t folderPath[MAX_PATH]={0};
                HRESULT hr
            =SHGetFolderPath(NULL, CSIDL_WINDOWS, NULL, 0, folderPath);
                
            if(FAILED(hr)) return;

                
            // Enumerate all directories and files in the Windows directory.
                List<WString> directories;
                List
            <WString> files;
                SearchDirectoriesAndFiles(folderPath, directories, files);

                
            // Set all columns. The first column is the primary column. All others are sub columns.
                listView->GetItems().GetColumns().Add(new list::ListViewColumn(L"Name"230));
                listView
            ->GetItems().GetColumns().Add(new list::ListViewColumn(L"Type"120));
                listView
            ->GetItems().GetColumns().Add(new list::ListViewColumn(L"Date"120));
                listView
            ->GetItems().GetColumns().Add(new list::ListViewColumn(L"Size"120));

                
            // Set all data columns (important sub solumns). The first sub item is 0. The primary column is not counted in.
                listView->GetItems().GetDataColumns().Add(0);    // Type
                listView->GetItems().GetDataColumns().Add(1);    // Data

                
            // Fill all directories and files into the list view
                FillList(listView, folderPath, directories);
                FillList(listView, folderPath, files);
            }

            /***********************************************************************
            GuiMain
            **********************************************************************
            */

            void GuiMain()
            {
                GuiWindow
            * window=new ViewSwitchingWindow;
                GetApplication()
            ->Run(window);
                delete window;
            }

                跟很多GUI類庫(kù)類似,為了在ListView上面顯示內(nèi)容,簡(jiǎn)單的new一下ListViewItem和ListViewColumn,把數(shù)據(jù)都放進(jìn)去就可以了。這里的DataColumn主要是為了在Tile和Information模式下面顯示附加數(shù)據(jù)而制作的。剩下的內(nèi)容就不是重點(diǎn)了,不過有些人可能很關(guān)心一些具體的操作,譬如怎樣獲取文件圖標(biāo)啦,怎樣獲取文件的各種屬性等等。值得一提的是Windows有很多類似GetDateFormatEx這樣的函數(shù),用來把幾乎所有需要在GUI上顯示的數(shù)據(jù),轉(zhuǎn)成一個(gè)跟用戶當(dāng)前的區(qū)域設(shè)置(locale)相關(guān)的字符串。這種事情就應(yīng)該讓操作系統(tǒng)來做啊。剩下的代碼包含了很多操作Windows API獲取文件屬性的代碼:

            /***********************************************************************
            File System Operations
            **********************************************************************
            */

            void SearchDirectoriesAndFiles(const WString& path, List<WString>& directories, List<WString>& files)
            {
                
            // Use FindFirstFile, FindNextFile and FindClose to enumerate all directories and files
                WIN32_FIND_DATA findData;
                HANDLE findHandle
            =INVALID_HANDLE_VALUE;

                
            while(true)
                {
                    
            if(findHandle==INVALID_HANDLE_VALUE)
                    {
                        WString searchPath
            =path+L"\\*";
                        findHandle
            =FindFirstFile(searchPath.Buffer(), &findData);
                        
            if(findHandle==INVALID_HANDLE_VALUE)
                        {
                            
            break;
                        }
                    }
                    
            else
                    {
                        BOOL result
            =FindNextFile(findHandle, &findData);
                        
            if(result==0)
                        {
                            FindClose(findHandle);
                            
            break;
                        }
                    }

                    
            if(findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
                    {
                        
            if(wcscmp(findData.cFileName, L".")!=0 && wcscmp(findData.cFileName, L"..")!=0)
                        {
                            directories.Add(findData.cFileName);
                        }
                    }
                    
            else
                    {
                        files.Add(findData.cFileName);
                    }
                }

                Func
            <vint(WString a, WString b)> comparer=[](WString a, WString b){return _wcsicmp(a.Buffer(), b.Buffer());};
                CopyFrom(directories.Wrap(), directories.Wrap()
            >>OrderBy(comparer));
                CopyFrom(files.Wrap(), files.Wrap()
            >>OrderBy(comparer));
            }

            Ptr
            <GuiImageData> GetFileIcon(const WString& fullPath, UINT uFlags)
            {
                
            // Use SHGetFileInfo to get the correct icons for the specified directory or file.
                SHFILEINFO info;
                DWORD result
            =SHGetFileInfo(fullPath.Buffer(), 0&info, sizeof(SHFILEINFO), uFlags);
                Ptr
            <GuiImageData> imageData;
                
            if(result)
                {
                    Ptr
            <INativeImage> image=windows::CreateImageFromHICON(info.hIcon);
                    
            if(image)
                    {
                        imageData
            =new GuiImageData(image, 0);
                    }
                    DestroyIcon(info.hIcon);
                }
                
            return imageData;
            }

            WString GetFileDisplayName(
            const WString& fullPath)
            {
                SHFILEINFO info;
                DWORD result
            =SHGetFileInfo(fullPath.Buffer(), 0&info, sizeof(SHFILEINFO), SHGFI_DISPLAYNAME);
                
            return result?info.szDisplayName:L"";
            }

            WString GetFileTypeName(
            const WString& fullPath)
            {
                SHFILEINFO info;
                DWORD result
            =SHGetFileInfo(fullPath.Buffer(), 0&info, sizeof(SHFILEINFO), SHGFI_TYPENAME);
                
            return result?info.szTypeName:L"";
            }

            WString GetFileLastWriteTime(
            const WString& fullPath)
            {
                
            // Get file attributes.
                WIN32_FILE_ATTRIBUTE_DATA info;
                BOOL result
            =GetFileAttributesEx(fullPath.Buffer(), GetFileExInfoStandard, &info);

                
            // Get the localized string for the file last write date.
                FILETIME localFileTime;
                SYSTEMTIME localSystemTime;
                FileTimeToLocalFileTime(
            &info.ftLastWriteTime, &localFileTime);
                FileTimeToSystemTime(
            &localFileTime, &localSystemTime);

                
            // Get the correct locale
                wchar_t localeName[LOCALE_NAME_MAX_LENGTH]={0};
                GetSystemDefaultLocaleName(localeName, 
            sizeof(localeName)/sizeof(*localeName));

                
            // Get the localized date string
                wchar_t dateString[100]={0};
                GetDateFormatEx(localeName, DATE_SHORTDATE, 
            &localSystemTime, NULL, dateString, sizeof(dateString)/sizeof(*dateString), NULL);

                
            // Get the localized time string
                wchar_t timeString[100]={0};
                GetTimeFormatEx(localeName, TIME_FORCE24HOURFORMAT 
            | TIME_NOSECONDS, &localSystemTime, NULL, timeString, sizeof(timeString)/sizeof(*timeString));

                
            return dateString+WString(L" ")+timeString;
            }

            WString GetFileSize(
            const WString& fullPath)
            {
                
            // Get file attributes.
                WIN32_FILE_ATTRIBUTE_DATA info;
                BOOL result
            =GetFileAttributesEx(fullPath.Buffer(), GetFileExInfoStandard, &info);

                
            // Get the string for file size
                LARGE_INTEGER li;
                li.HighPart
            =info.nFileSizeHigh;
                li.LowPart
            =info.nFileSizeLow;

                WString unit;
                
            double size=0;
                
            if(li.QuadPart>=1024*1024*1024)
                {
                    unit
            =L" GB";
                    size
            =(double)li.QuadPart/(1024*1024*1024);
                }
                
            else if(li.QuadPart>=1024*1024)
                {
                    unit
            =L" MB";
                    size
            =(double)li.QuadPart/(1024*1024);
                }
                
            else if(li.QuadPart>=1024)
                {
                    unit
            =L" KB";
                    size
            =(double)li.QuadPart/1024;
                }
                
            else
                {
                    unit
            =L" Bytes";
                    size
            =(double)li.QuadPart;
                }

                WString sizeString
            =ftow(size);
                
            const wchar_t* reading=sizeString.Buffer();
                
            const wchar_t* point=wcschr(sizeString.Buffer(), L'.');
                
            if(point)
                {
                    
            const wchar_t* max=reading+sizeString.Length();
                    point
            +=4;
                    
            if(point>max) point=max;
                    sizeString
            =sizeString.Left(point-reading);
                }

                
            return sizeString+unit;
            }

                在這里需要特別說明一下。這個(gè)Demo沒有使用GacUIIncludes.h,而是用GacUI.h,是因?yàn)镚acUI.h包含了一些跟Windows操作系統(tǒng)直接相關(guān)的東西,譬如說把一個(gè)HICON類型轉(zhuǎn)成INativeImage類型的方法:windows::GetImageFromHICON。類似的操作在開發(fā)跟Windows系統(tǒng)本身交互比較密切的函數(shù)是很有用的。下一個(gè)Demo還沒有寫,但是基本上會(huì)選擇一個(gè)小場(chǎng)景來描述如何使用ListView的虛擬模式。GacUI里面所有的列表控件都有虛擬模式,包括GuiVirtualTextList、GuiVirtualListView和GuiTreeView(TreeView的虛擬模式和非虛擬模式是同一個(gè)類型)等。敬請(qǐng)期待。
            posted on 2012-06-04 09:15 陳梓瀚(vczh) 閱讀(7738) 評(píng)論(8)  編輯 收藏 引用 所屬分類: GacUI

            評(píng)論:
            # re: GacUI Demo:模擬Windows7資源管理器 2012-06-04 17:37 | SunRise_at
            大神,一點(diǎn)還不睡覺,很傷身體的。。。  回復(fù)  更多評(píng)論
              
            # re: GacUI Demo:模擬Windows7資源管理器 2012-06-05 22:48 | 邱震鈺(zblc)
            # re: GacUI Demo:模擬Windows7資源管理器 2012-06-19 08:17 | 龍哥
            無法支持vc2005  回復(fù)  更多評(píng)論
              
            # re: GacUI Demo:模擬Windows7資源管理器 2012-06-19 08:20 | 龍哥
            還有就是必須安裝dx sdk,感覺不用也要安裝還是不方便。  回復(fù)  更多評(píng)論
              
            # re: GacUI Demo:模擬Windows7資源管理器 2012-06-19 08:31 | 陳梓瀚(vczh)
            @龍哥
            Direct2D不能裝進(jìn)XP,所以XP只能用GDI,不需要裝dxsdk。
            vista以后的版本自帶至少DX10,有Direct2D,所以windows sdk已經(jīng)有DX10了,所以也不需要安裝dxsdk。用戶不需要sdk,dx10的runtime已經(jīng)存在了,所以可以直接運(yùn)行。

            結(jié)論:不需要你特別去安裝dxsdk。  回復(fù)  更多評(píng)論
              
            # re: GacUI Demo:模擬Windows7資源管理器 2012-06-19 08:31 | 陳梓瀚(vczh)
            @龍哥
            vc2005我猜是windows sdk版本的問題  回復(fù)  更多評(píng)論
              
            # re: GacUI Demo:模擬Windows7資源管理器 2012-06-19 11:11 | 龍哥
            @陳梓瀚(vczh)
            但不安裝dxsdk會(huì)提示缺少D2D1.h DWrite.h,不知道注釋掉是否可以。我用的是xp系統(tǒng)。
            vc2005提示缺少wincodec.h這個(gè)文件,搜索sdk目錄的確也不存在這個(gè)文件。
              回復(fù)  更多評(píng)論
              
            # re: GacUI Demo:模擬Windows7資源管理器 2012-06-20 04:15 | 陳梓瀚(vczh)
            @龍哥
            哦,我知道你的問題了。我有計(jì)劃要給一個(gè)宏,當(dāng)你開發(fā)和目標(biāo)系統(tǒng)都只能是XP的時(shí)候,通過打開這個(gè)宏來關(guān)掉所有D2D的部分。不過想來因?yàn)樾碌腣S連XP都只支持到SP3并且隨時(shí)要干掉了,所以就降低了他的優(yōu)先級(jí)。對(duì)我來說支持win8更重要一點(diǎn),啊哈哈哈。  回復(fù)  更多評(píng)論
              
            久久久久人妻一区精品色| 香蕉久久夜色精品国产2020| 久久久久久久97| 久久国产乱子伦精品免费强| 国产91久久综合| 国产精品久久新婚兰兰| 亚洲AV无码久久| 久久久久国产一级毛片高清版| 2021国产成人精品久久| 亚洲国产成人久久综合碰| 亚洲狠狠婷婷综合久久久久| 久久久久久久99精品免费观看| 久久嫩草影院免费看夜色| 亚洲精品美女久久777777| 韩国无遮挡三级久久| 一个色综合久久| www.久久热.com| 国内精品久久国产| 97久久精品人妻人人搡人人玩| 久久国产精品一区| 人妻无码久久一区二区三区免费| 91精品国产高清久久久久久国产嫩草| 欧美精品丝袜久久久中文字幕 | 精品久久久久久成人AV| 久久精品无码一区二区三区免费 | 久久精品中文騷妇女内射| 精品欧美一区二区三区久久久 | 亚洲国产精品综合久久网络| MM131亚洲国产美女久久| 久久成人小视频| 国内精品久久久久影院网站| 久久久久亚洲av无码专区导航| 国内精品久久久久久久影视麻豆| 久久久久免费看成人影片| 模特私拍国产精品久久| 久久高潮一级毛片免费| 成人国内精品久久久久一区| 久久久久久国产精品美女| 久久久久无码中| 国产L精品国产亚洲区久久| 国产亚洲精品美女久久久|