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

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

編輯:關於.NET

Windows 7介紹了一種庫的新概念,用戶數據的新的入口點。用戶可以輕松的以集合數據 的方式,找到並且管理他們的數據,而且這些數據可能是在計算機中的多個不同的位置。這 個庫代替了早期Windows版本中的固有文件夾(比如,我的文檔,圖片,音樂),並且把它 們都放入了主“storage”。Shell庫的 API,提供給應用程序一種簡單的方法來對該庫進行 交互操作。應用程序可以創建,交互並且像他們的環境中的一級元素一樣支持該庫。

在Windows 7中,Shell庫的概念就是,通過允許他們對其文檔庫文件夾結構的全部控制 權限,試圖去解決用戶在他們的PC上,到處存放數據的問題。換而言之,在 Windows 7中, 用戶可以在文檔庫中來定義哪個文件夾用來存放。我們也可以說,Shell庫是一種用戶自定 義的,合理的代表用戶數據的文件夾集合。在庫中所包含的文件夾,其實就是用戶告訴了 Windows,他的或者她的重要數據在哪裡存放。那麼系統將為這些文件夾進行索引,來更快 的查詢檢索、在基於文件屬性和元數據的Windows Explorer中具有更豐富的視圖展示能力。

在早期的Windows版本中,每一個應用程序都有其屬於自己的屬性庫。比如,Windows Media Player與iTunes相比,擁有不同的作用域集合,並且兩者都不是與Music文件夾一致 的。使用Shell庫的API,應用程序就可以定義並且共同使用用戶自定義的那個區域。

Shell庫中同樣也可以包含網絡文件夾。這個功能將給用戶無論是在家還是在單位,都有 一個很好的用戶體驗。無論何時用戶打開一個文件對話框,他就能獲得所有可用的庫的指向 的集合視圖。

注意 :了解更多信息,請參看Inside Windows 7: Introducing Libraries,和 Windows 7 Programming Guide - Libraries

目標

在本次動手實驗中,你將 了解到如何用編程的方式管理庫,包括如何:

• 創建新的庫

• 打開現有的庫

• 在庫中進行添加和刪除 文件夾

• 獲取和解析庫文件夾列表

• 刪除庫

• 重命 名庫

• 為庫設置一個默認保存文件夾

• 設置庫的屬性,比如文件 夾類型,圖標,鎖定到導航欄的狀態等

• 顯示"manage user interface"對話 框

系統需求

完成本實驗,你需要有以下組件:

• Microsoft Visual Studio 2008 SP1

• Windows 7

• Windows 7 SDK

練習: 開發 SLUtil

Shell庫實用工具(SLUtil)是一個用 來管理在默認的庫目錄下的庫的命令行工具。

SLUtil 命令:

命令提示

SLUtil ? [CommandName]
SLUtil Create LibraryName
SLUtil AddFolder LibraryName FolderPath
SLUtil RemoveFolder  LibraryName FolderPath
SLUtil Delete LibraryName
SLUtil Rename  OldName NewName
SLUtil SaveFolder LibraryName [FolderPath]
SLUtil  NavPanePinnedState LibraryName [TRUE|FALSE]
SLUtil Icon LibraryName  [Icon]
SLUtil FolderType LibraryName  [Documents|Pictures|Music|Videos|Generic]
SLUtil ListFolders  LibraryName
SLUtil ManageUI LibraryName [Title] [Instruction] 

任務 1 – 創建 SLUtil 項目

1.開啟 Visual Studio 2008 並且選擇 C++ Win32 控制台應用程序。

a.輸入SLUtil作為新項目的名稱。

b.保持默認配置。

2.添加CommandLineInterpreter.h和CommandLineInterpreter.cpp文件。你可以在 Starter文件夾中找到這兩個文件。你需要使用Command宏,向命令行解釋器中添加命令。

3.使用Starter文件夾中包含必要的#include代碼的stdafx.h文件來替換現有項目中的 stdafx.h文件。

4.為了支持Windows 7 API,請將targetver.h文件中的_WIN32_WINNT更改為0x0601。

5.如果要使用命令行解釋器,直接在SLUtil.cpp文件中的#include "stdafx.h"下,添加 #include "CommandLineInterpreter.h"。

6.更改主方法來調用命令行解釋器的執行函數。你同樣需要初始化COM:

注意 :命令行解釋器是一個實用工具類,它知道如何翻譯命令行和其已經注冊了的 Command宏的執行函數

C++ (SLUtil.cpp)

#include "stdafx.h"
#include "CommandLineInterpreter.h"

int _tmain(int argc, _TCHAR* argv[])
{
                 //Initiate COM
                 CoInitialize(NULL);
                 CCommandLineInterpreter::Execute(argc,  argv);
                 CoUninitialize();
                 return 0;
}

7.編譯該程序。

8.想要測試當前應用程序的狀態,在項目屬性中的調試框中,添加命令行變量。

9.執行該應用程序。你應該能得到下面的輸出結果:

注意 :

SLUtil ? [CommandName]

Press any key to continue ...

任務 2 –添加創建命令

對Shell庫進行編程,我們不但需要使用IshellLibrary接口,而且還需要比如 IShelItem, IShelItem2, 和 IshellItemArray之類的其他Shell接口。他們都在shobjidl.h 的頭文件中定義好了。這個頭文件同樣包含了一些Shell庫幫助方法,當有一些普通的Shell 庫操作,比如創建Shell庫COM對象或者讀取Shell庫時,這些方法將保存一些代碼。舉例說 明,下面的代碼就是 shobjidl.h文件中的一個片段:

C++ (from shobjidl.h)

__inline HRESULT SHCreateLibrary(__in REFIID riid, __deref_out  void **ppv)
{
     return CoCreateInstance(CLSID_ShellLibrary, NULL,  CLSCTX_INPROC_SERVER,
                                                                                                                                                                       riid, ppv);
}

1.向SLUtil.cpp文件中添加下面的代碼:

C++ (SlUtil.cpp)

//Create a new shell library
void CreateLibrary(const CCommand &command, const  vector<PCWSTR> &arguments)
{
   IShellLibrary *shellLibrary = NULL;
   IShellItem *savedTo = NULL;

   //Create the shell library COM object
   HRESULT hr = SHCreateLibrary(IID_PPV_ARGS(&shellLibrary));
   if (FAILED(hr))
   {
     wcerr << L"Create: Can't create Shell Library COM  object." << endl;
     exit(4);
   }

   //Save the new library under the user's Libraries folder.
   //If a library with the same name is already exists, add a  number to the
   //name to create unique name
   hr = shellLibrary->SaveInKnownFolder(FOLDERID_UsersLibraries,  arguments[0],
                                                  LSF_MAKEUNIQUENAME, &savedTo);
   if (FAILED(hr))
   {
     wcerr << L"Create: Can't create Shell Library." <<  endl;
     exit(5);
   }

   if (shellLibrary != NULL)
     shellLibrary->Release();

   if (savedTo != NULL)
     savedTo->Release();
}
COMMAND(L"Create", L"SLUtil Create LibraryName", L"Create a new  library",
                                   L"SLUtil  Create MyLib", 1, CreateLibrary);

2.編譯並執行。

3.將命令行變量更改為:Create MyLib。

4.運行該應用程序,並且檢查驗證你創建的新的庫。

任務 3 –添加AddFolder 和RemoveFolder 命令

在一個存在的庫中,添加或刪除一個文件夾,我們需要重新打開這個庫。許多命令都需 要重新打開庫,所以我們需要創建兩個幫助方法(注意:在本次動手實驗中,我們只涉及用 戶庫的位置)。

1.向SLUtil.cpp文件中添加下面的代碼:

C++ (SLUtil.cpp)

// Get the library COM object and the full path of a  library.
// If shellLibrary is NULL, don't return it.
// If libraryFullPath is NULL, don't return it.
// Call relese on the shellLibrary object.Call CoTaskMemFree on  the
// libraryFullPath
HRESULT GetLibraryFromLibrariesFolder(PCWSTR libraryName, IShellLibrary  **shellLibrary, bool openRead = true, PWSTR *libraryFullPath = NULL)
{
                 //Create the real library file name
                 wstring realLibraryName(libraryName);
                 realLibraryName += L".library-ms";

                 IShellItem2 *shellItem = NULL;

                 //Get the shell item that represent the  library
                 HRESULT hr = SHCreateItemInKnownFolder (FOLDERID_UsersLibraries,
                                 KF_FLAG_DEFAULT_PATH|KF_FLAG_NO_ALIAS , realLibraryName.c_str(),
                                 IID_PPV_ARGS (&shellItem));
                 if (FAILED(hr))
                 {
                                 return  hr;
                 }

                 //In case a file-system full path is  needed
                 //extract the information from the Shell  Item ParsingPath property
                 if (libraryFullPath != NULL)
                 {
                                 hr =  shellItem->GetString(PKEY_ParsingPath, libraryFullPath); 
                 }

                 //Get the shellLibrary object from the  shell item with a read/write
                 //permitions
                 if (shellLibrary != NULL)
                 {
                                 hr =  SHLoadLibraryFromItem(shellItem, openRead ? 
                                                  STGM_READ : STGM_READWRITE, IID_PPV_ARGS (shellLibrary));
                 }

                 if (shellItem != NULL)
                                 shellItem- >Release();
                 return hr;
}

//Open an existing library
IShellLibrary *OpenLibrary(PCWSTR commandName, PCWSTR libraryName,
                                                                                                                                    bool openRead = true)
{
                 IShellLibrary *shellLibrary =  NULL;

                 HRESULT hr =  GetLibraryFromLibrariesFolder(libraryName, &shellLibrary,
                                                                                                                                                                        openRead);
                 if (FAILED(hr))
                 {
                                 wcerr  << commandName << L": Can't load library." <<  endl;
                                 exit(4);
                 }
                 return shellLibrary;
}

2.現在,我們來添加AddFolder 和 RemoveFolder命令。向SLUtil.cpp文件中添加下面的 代碼:

C++ (SLUtil.cpp)

//Add a folder to a library
void AddFolder(const CCommand &command, const vector<PCWSTR>  &arguments)
{
                 IShellLibrary *shellLibrary = OpenLibrary (L"AddFolder", arguments[0],
                                                                                                                                                                          false);

                 HRESULT hr = SHAddFolderPathToLibrary (shellLibrary, arguments[1]);
                 if (FAILED(hr))
                 {
                                 wcerr  << L"AddFolder: Can't add folder to the library." <<  endl;
                                 exit(6);
                 }

                 //Commit the library changes
                 shellLibrary->Commit();

                 if (shellLibrary != NULL)
                                                  shellLibrary->Release();
}
COMMAND(L"AddFolder", L"SLUtil AddFolder LibraryName FolderPath",
         L"Add a folder to a library", L"SLUtil AddFolder  Documents C:\\Docs",
                                                                                                                                                         2,  AddFolder);

//Remove a folder from a library
void RemoveFolder(const CCommand &command, const vector<PCWSTR>  &arguments)
{
                 IShellLibrary *shellLibrary = OpenLibrary (L"RemoveFolder",
                                                                                                                                    arguments[0], false);

                 HRESULT hr =  SHRemoveFolderPathFromLibrary(shellLibrary, arguments[1]);
                 if (FAILED(hr))
                 {
                                 wcerr  << L"RemoveFolder: Can't remove folder from the library."
                                                                                                                                                                         << endl;
                                 exit(5);
                 }

                 //Commit the library changes
                 shellLibrary->Commit();

                 if (shellLibrary != NULL)
                                 shellLibrary ->Release();
}
COMMAND(L"RemoveFolder", L"SLUtil RemoveFolder LibraryName  FolderPath",
  L"Remove a folder from a library", L"SLUtil RemoveFolder Documents  C:\\Docs",
                                                                                                                                                      2,  RemoveFolder);

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