程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> Windows 7開發:Shell 庫 - 本機(動手實驗)(下)

Windows 7開發:Shell 庫 - 本機(動手實驗)(下)

編輯:關於.NET

2.編譯並測試:

a.打開一個命令行窗口,並且將目錄(cd)切換到SLUtil.exe所在的位置。

b.打開緊鄰命令行窗口的庫Shell文件夾,你將會看到你使用SLUtil工具所做的變 化.

c.在命令行窗口中,測試SLUtil命令。

d.試著為你的MyLib庫使用一個與Pictures庫相同的圖標。

e.試著將你的庫在文件管理面板中鎖定和解鎖。

f.改變庫的默認存儲位置,將這個位置移到文件系統中另外的位置,並且測試默認的存 儲位置是否解決了這個變化。

任務 6 –添加FolderType 命令

每個庫都有一個文件夾模板類型。這個類型定義了Shell庫窗口的樣子和感覺,例如,圖 片和音樂就有不同的模板。IShellLibrary SetFolderType()方法則使用GUID的方式來表示 文件夾的類型id。GetFolderType()方法則能返回當前文件夾的id。默認情況,用戶創建的 庫,都是一般文件夾類型。

為了讓用戶使用文本類型而不是使用GUID,我們需要使用一個幫助類。 CfolderTypeIdNameConverter這個類知道如何將Pictures, Music, Documents, Videos, 和 Generic轉換成相應的FOLDERTYPEID_*,同樣,反之亦然。同時,這個方法還知道取名稱的 一部分,比如vid 就是 Videos。這些都將使設置庫文件夾的類型變得簡單:SLUtil FolderType MyLib doc

1.向項目中添加FolderTypeIdNameConverter.h 和 FolderTypeIdNameConverter.cpp文 件。你可以從Starter文件夾中找到它們。

2.添加 #include "FolderTypeIdNameConverter.h"

3.添加下面的代碼片段,來實現FolderType命令:

C++ (SLUtil.cpp)

//Set or get the library's folder template
void FolderType(const CCommand &command, const vector<PCWSTR>  &arguments)
{
                 IShellLibrary *shellLibrary = NULL;
                 HRESULT hr = S_OK;
                 FOLDERTYPEID folderTypeId;

                 CFolderTypeIdNameConverter  converter;

                 //Show current folder type
                 if (arguments.size() == 1)
                 {
                                 //Open  library with read permissions
                                 IShellLibrary  *shellLibrary =
                                                                                   OpenLibrary(L"FolderType", arguments[0]);

                                 hr =  shellLibrary->GetFolderType(&folderTypeId);
                                 if (FAILED (hr))
                                 {
                                                  wcerr <<
                                                     L"FolderType: Can't get the library's folder  template."
                                                                                                                                                                          << endl;
                                                  exit(5);
                                 }
                                 wcout  << L"Library " << arguments[0] << L": Folder template  is: "                                                 << converter.GetFolderTypeIdName(folderTypeId)  << endl;
                 }
                 else //Set the current folder type
                 {
                                 //Open  library with read/write permissions
                                 IShellLibrary  *shellLibrary =
                                                    OpenLibrary(L"FolderType", arguments[0],  false);

                                 hr =  converter.GetFolderTypeIdFromName(arguments[1],
                                                                                                                                                    &folderTypeId);
                                 if (FAILED (hr))
                                 {
                                                  wcerr << L"FolderType: Invalida folder template  name." <<
                                                                                                                                                                                     endl;
                                                  exit(6);
                                 }

                                 hr =  shellLibrary->SetFolderType(folderTypeId);
                                 if (FAILED (hr))
                                 {
                                                  wcerr <<
                                                     L"FolderType: Can't set the library's folder  template,"
                                                                                                                                                                          << endl;
                                                  exit(7);
                                 }
                                 //Commit the  library changes
                                 shellLibrary ->Commit();
                 }
                 if (shellLibrary != NULL)
                                 shellLibrary ->Release();
}
COMMAND(L"FolderType", 
    L"SLUtil FolderType LibraryName  [Documents|Pictures|Music|Videos|Generic]",
    L"Set or get the library's folder template", L"SLUtil MyLib  Documents", 1,
    FolderType);

4.編譯和測試:

a.打開一個命令行窗口,並且將目錄(cd)切換到SLUtil.exe所在的位置。

b.打開緊鄰命令行窗口的庫Shell文件夾,你將會看到你使用SLUtil工具所做的變 化.

c.在命令行窗口中,測試SLUtil命令。

d.嘗試將Pictures庫的文件夾類型,賦給你的MyLib庫。

任務 7 –添加ListFolders 命令

GetFolders() 方法將一個文件夾的數組返回到COM對象中,這個對象用來實現 IShellItemArray。IShellItemArray有一個 GetCount()方法,這個方法能夠返回數組的長 度,GetItemAt()返回一個實現IShellItem並且代表一個Shell文件夾的COM 對象。應用程序 可以使用Shell文件夾的ParsingPath屬性來獲取文件夾的路徑。它能夠通過IShellItem2接 口的 GetString()方法來讀取基於字符串的屬性。這就是為什麼我們需要將從 IShellItemArray獲取到的IShellItem接口,轉換成 IShellItem2接口。另外一個復雜的問 題是,我們不得不注意我們所處理的是否被重命名,移動或者刪除了。我們需要使用 ResolveFolder()方法來解決這些問題。

1.添加下面的代碼片段:

C++ (SLUtil.cpp)

//List all library folders
void ListFolders(const CCommand &command, const vector<PCWSTR>  &arguments)
{
                 IShellLibrary *shellLibrary = OpenLibrary (L"ListFolders", arguments[0]);
                 HRESULT hr = S_OK;
                 IShellItemArray *shellItemArray =  NULL;

                 shellLibrary->GetFolders(LFF_ALLITEMS,  IID_PPV_ARGS(&shellItemArray));

                 if (FAILED(hr))
                 {
                                 wcerr  << L"ListFolders: Can't get the library's folder list."  <<
                                                                                                                                                                                     endl;
                                 exit(5);
                 }

                 wcout << L"Folder list of "  << arguments[0] << L" library:" << endl;
                 DWORD count;
                 shellItemArray->GetCount (&count);

                 //Iterate through all library folders
                 for (DWORD i = 0; i < count; ++i)
                 {
                                 IShellItem  *shellItem;
                                 IShellItem2  *shellItem2;

                                 hr =  shellItemArray->GetItemAt(i, &shellItem);
                                 if (FAILED (hr))
                                                  continue;
                                 //Convert  IShellItem to IShellItem2
                                 shellItem- >QueryInterface(IID_PPV_ARGS(&shellItem2));
                                 shellItem- >Release();

                                 IShellItem2  *shellItemResolvedFolder = NULL;
                                 //Fix folder  path changes
                                 hr =  shellLibrary->ResolveFolder(shellItem2, 5000,
                                                                                   IID_PPV_ARGS(&shellItemResolvedFolder));
                                 if  (SUCCEEDED(hr))
                                 {
                                                  //Point to the fixed folder
                                                  shellItem2->Release();
                                                  shellItem2 = shellItemResolvedFolder;
                                 }
                                 //else we  will show the unfixed folder

                                 PWSTR  folderPath;
                                 hr =  shellItem2->GetString(PKEY_ParsingPath, &folderPath);
                                 if  (SUCCEEDED(hr))
                                 {
                                                  wcout << folderPath << endl;
                                 }
                                 CoTaskMemFree(folderPath);
                                 shellItem2- >Release();
                 }
                 shellItemArray->Release();
                 shellLibrary->Release();
}
COMMAND(L"ListFolders", L"SLUtil ListFolders LibraryName", L"List all  library folders.", L"SLUtil ListFolders Documents", 1,  ListFolders);

2.編譯並且測試:

a.打開一個命令行窗口,並且將目錄(cd)切換到SLUtil.exe所在的位置。

b.打開緊鄰命令行窗口的庫Shell文件夾,你將會看到你使用SLUtil工具所做的變 化.

c.在命令行窗口中,測試SLUtil命令。

d.列出庫中的內容。

e.嘗試去重命名,移動或刪除文件夾,並且看一看庫是如何來解決這些問題的。

任務 8 – 添加ManageUI 命令

最後,完成SLUtil的最終命令是ManageUI命令。這個命令將會顯示一個Shell庫的管理窗 口:

SHShowManageLibraryUI()API將獲取一個能夠代表Shell庫的Shell元素,並且展示一個 庫管理對話框。你只需要提供父窗體的句柄,標題的文本和說明。你同時也可以決定是否允 許添加一個可能會降低庫操作速度、不能索引的網絡文件夾。

1.添加下面的代碼:

C++ (SLUtil.cpp)

//Show the Shell Library management UI
void ManageUI(const CCommand &command, const vector<PCWSTR>  &arguments)
{
                 PWSTR libraryFullPath = NULL;
                 HRESULT hr =  GetLibraryFromLibrariesFolder(arguments[0], NULL, false,
                                                                                                                                                     &libraryFullPath);
                 if (FAILED(hr))
                 {
                                 wcerr  << L"ManageUI: Can't get library." << endl;
                                 exit(4);
                 }

                 IShellItem *shellItem = NULL;
                 hr = SHCreateItemFromParsingName (libraryFullPath, 0,
                                                                                                                   IID_PPV_ARGS (&shellItem));
                 if (FAILED(hr))
                 {
                                 wcerr  << L"ManageUI: Can't create COM object." << endl;
                                 exit(5);
                 }

                 PCWSTR title = arguments[0];
                 PCWSTR instruction = L"Manage Library  folders and settings";

                 if (arguments.size() > 1)
                                 title =  arguments[1];

                 if (arguments.size() > 2)
                                 instruction  = arguments[2];

                 SHShowManageLibraryUI(shellItem, NULL,  title, instruction,
                                                                                    LMD_ALLOWUNINDEXABLENETWORKLOCATIONS);

                 shellItem->Release();
                 CoTaskMemFree(libraryFullPath);
}
COMMAND(L"ManageUI", L"SLUtil ManageUI LibraryName [Title]  [Instruction]", L"Show the Shell Library management UI", L"SLUtil  ManageUI Documents", 1, ManageUI);

2.編譯並測試:

a.SLUtil ManageUI Pictures "Manage Picture Library" "Add or Remove folders from the Pictures Library"

你可以在最終的解決方案文件夾中找到該實驗的最終版。干得漂亮!

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved