윈도우 앱개발을 향하여

블로그 이미지
윈도우 10 스토어에 앱을 개발해 올리는 것을 목표로 하고 있습니다. 비전공자가 독학으로 시도하는 일이어서 얼마나 걸릴지 모르겠지만... 아무튼 목표는 그렇습니다!!
by 코딩하는 경제학도
  • Total hit
  • Today hit
  • Yesterday hit

'MSDN/Shell Programming'에 해당되는 글 4건

  1. 2017.02.22
    Getting Information About the Contents of a Folder
  2. 2017.02.22
    Getting a Folder's ID
  3. 2017.02.22
    Understanding Shell Namespace Extensions
  4. 2017.02.22
    Common Explorer Concepts (== Introduction to the Shell Namespace)

Getting Information About the Contents of a Folder (MSDN 번역)


지난 Getting a Folder's ID에서는 namespace object의 PIDL(pointer to an item identifier list)를 구하는 두 가지 접근방법(approaches)을 알아보았다. 그렇다면 PIDL을 얻은 뒤 이것으로 무엇을 할 수 있을까? A related question is: What if neither approach works, or is suitable for your application? The answer to both questions requires taking a closer look at how the namespace is implemented. The key is the IShellFolder interface.


목차

Using the IShellFolder Interface 

Enumerating the Contents of a Folder

Determining Display Names and Other Properties 

Getting a Pointer to a Subfolder's IShellFolder Interface  

Determining an Object's Parent Folder



- Using the IShellFolder Interface


이전 설명에서 namespace 폴더들을 object로 언급했다. 맞는 말이다, namespace 폴더는 COM(Component Object Model) object로 대표되기 때문이다. 각 folder object는 다양한 업무에 사용되는 많은 인터페이스를 노출시킨다(expose). 어떤 인터페이스는 선택가능해서 모든 폴더들이 노출시키지는 않지만, 모든 폴더는 반드시 IShellFolder라는 fundamental한 인터페이스를 노출시켜야만 한다(따라서 언제나 접근가능하다). 


Folder object를 사용하기 위한 첫 단계는 해당 폴더 object의 IShellFolder 인터페이스의 포인터를 얻는 것이다. Object의 다른 인터페이스를 제공하는 함수들을(methods) IShellFolder가 가지고 있다. 그 중 몇가지는 여기서 소개될 것이다.


IShellFolder 인터페이스의 포인터를 얻기 위해선 반드시 SHGetDesktopFolder함수를 호출해야한다. 이 함수는 namespace root(Desktop)의 IShellFolder 인터페이스를 가리키는 포인터를 반환한다. 일단 Desktop의 IShellFolder 인터페이스를 얻으면 그 다음부터는 다양한 방법으로 진행할 수 있다.


만약 관심있는 폴더의 PIDL을 이미 가지고 있다면(SHGetFolderLocation함수를 호출해서 얻었다던가..), 그 폴더의 IShellFolder 인터페이스를 Desktop의 IShellFolder::BindToObject method를 호출하여 얻을 수 있다.

만약 관심있는 폴더가 파일 시스템 object이고 그 경로를 알고 있다면 Desktop의 IShellFolder::ParseDisplayName method를 호출하여 해당 폴더의 PIDL을 얻을 수도 있다. 

만약 위의 두 가지 방법을 모두 사용할 수 없다면 다른 IShellFolder method로 해당 namespace를 탐색할 수도 있다. (Navigating the Namespace 참조)



- Enumerating the Contents of a Folder


관심있는 폴더에 무엇이 포함되어 있는지 보기 위해서는 해당 폴더의 IShelFolder::EnumObjects method를 호출해야만 한다. 그러면 해당 폴더는 standard OLE enumeration object를 만들고 그것의 IEnumIDList 인터페이스를 반환한다. IEnumIDList 인터페이스는 Clone, Next, Reset, Skip 이라는 네 개의 인터페이스를 노출시키며 관심 폴더의 내용물을 열거하는데 사용된다. 그 과정은 다음과 같다.

  1. 해당 폴더의 IShellFolder::EnumObjects method를 호출하여 a pointer to an enumeration object's IEnumIDList interface를 얻는다.
  2. IEnumIDList::Next에 unallocated PIDL를 넘긴다. IEnumIDList::Next가 PIDL의 메모리를 할당한다. 그리고 IEnumIDList::Next가 반환하면 PIDL는 object's item ID와 terminating NULL characters를 담고있다(single-level PIDL, relative to the folder, not a fully qualified PIDL).
  3. IEnumIDList::Next가 내용물이 모두 열거되었음을 알리는 S_FALSE를 반환할 때까지 2단계를 반복한다.
  4. IEnumIDList::Release를 호출하여 enumeration object를 해제한다.
Note  It is important to keep track of whether you are working with a full or relative PIDL. Some functions and methods will accept either, but others will only take one or the other.


나머지 세 개의 IEnumIDList method(Reset, Skip, Clone)도 폴더의 내용물을 반복해서 열거할 때 유용하다. (They allow you to reset the enumeration, skip one or more objects, and make a copy of the enumeration object to preserve its state.)



- Determining Display Names and Other Properties


일단 폴더에 포함된 모든 PIDLs를 열거했다면 그것들이 어떤 종류의 object인지 알아낼 수도 있다. IShellFolder 인터페이스는 쓸모있는 메소드들을 많이 포함하고 있으며 그 중 몇가지를 여기서 소개한다.


One of the most useful properties is the object's display name. 해당 object의 PIDL를 IShellFolder::GetDisplayNameOf에 넘기면 object의 display name을 얻을 수 있다. 해당 object가 namespace의 부모폴더에 포함되어 있기 때문에 해당 object의 PIDL은 반드시 부모폴더와 연관되어 있다.


In addition to its display name, an object can have a number of attributes, such as whether it is a folder or whether it can be moved. You can retrieve an object's attributes by passing its PIDL to IShellFolder::GetAttributesOf. The complete list of attributes is quite large, so you should see the reference for details. Note that the PIDL that you pass to GetAttributesOf must be single-level. In particular, IShellFolder::GetAttributesOf will accept the PIDLs returned by IEnumIDList::Next. You can pass in an array of PIDLs, and GetAttributesOf will return those attributes that all objects in the array have in common.

If you have an object's fully qualified path or PIDL, SHGetFileInfo provides a simple way to retrieve information about an object that is sufficient for many purposes. SHGetFileInfo takes a fully qualified path or PIDL, and returns a variety of information about the object including:

  • The object's display name
  • The object's attributes
  • Handles to the object's icons
  • A handle to the system image list
  • The path of the file containing the object's icon


- Getting a Pointer to a Subfolder's IShellFolder Interface

You can determine whether your folder contains any subfolders by calling IShellFolder::GetAttributesOf and checking to see if the SFGAO_FOLDER flag is set. If an object is a folder, you can bind to it, which provides you with a pointer to its IShellFolder interface.

To bind to a subfolder, call the parent folder's IShellFolder::BindToObject method. This method takes the subfolder's PIDL and returns a pointer to its IShellFolder interface. Once you have this pointer, you can use the IShellFolder methods to enumerate the subfolders contents, determine their properties, and so on.


- Determining an Object's Parent Folder

If you have an object's PIDL, you may need a handle to one of the interfaces exposed by its parent folder. For example, if you want to determine the display name associated with a PIDL by using IShellFolder::GetDisplayNameOf, you must first retrieve the IShellFolder interface of the object's parent. It is possible to do this with the techniques discussed in the previous sections. However, a much simpler approach is to use the Shell function, SHBindToParent. This function takes the fully qualified PIDL of an object and returns a specified interface pointer on the parent folder. Optionally, it also returns the item's single-level PIDL for use in methods such as IShellFolder::GetAttributesOf.

The following sample console application retrieves the PIDL of the System special folder and returns its display name.


#include <shlobj.h>

#include <shlwapi.h>

#include <iostream.h>

#include <objbase.h>


int main()

{

    IShellFolder *psfParent = NULL;

    LPITEMIDLIST pidlSystem = NULL;

    LPCITEMIDLIST pidlRelative = NULL;

    STRRET strDispName;

    TCHAR szDisplayName[MAX_PATH];

    HRESULT hr;


    hr = SHGetFolderLocation(NULL, CSIDL_SYSTEM, NULL, NULL, &pidlSystem);


    hr = SHBindToParent(pidlSystem, IID_IShellFolder, (void **) &psfParent, &pidlRelative);


    if(SUCCEEDED(hr))

    {

        hr = psfParent->GetDisplayNameOf(pidlRelative, SHGDN_NORMAL, &strDispName);

        hr = StrRetToBuf(&strDispName, pidlSystem, szDisplayName, sizeof(szDisplayName));

        cout << "SHGDN_NORMAL - " <<szDisplayName << '\n';

    }


    psfParent->Release();

    CoTaskMemFree(pidlSystem);


    return 0;

}


The application first uses SHGetFolderLocation to retrieve the System folder's PIDL. It then calls SHBindToParent, which returns a pointer to the parent folder's IShellFolder interface, and the System folder's PIDL relative to its parent. It then uses the parent folder's IShellFolder::GetDisplayNameOf method to retrieve the display name of the System folder. Because GetDisplayNameOf returns a STRRET structure, StrRetToBuf is used to convert the display name into a normal string. After displaying the display name, the interface pointers are released and the System PIDL freed. Note that you must not free the relative PIDL returned by SHBindToParent.





AND

Getting a Folder's ID  (MSDN 번역)


Namespace object를 사용하기에 앞서 PIDL(pointer to an item identifier list) 또는 (file system object인 경우만) path(경로)를 얻어 object들을 구별할 수 있어야 한다. 여기서는 object ID들을 얻는 두가지 간단한 방법을 소개한다.


모든 폴더에 대해 적용되는 강력한 접근방법은 IShellFolder interface를 이용하는 것이다(Getting Information About the Contents of a Folder 참조 - 다음 챕터에 소개).


목차

The OpenFiles Dialog Box

The SHBrowseForFolder Dialog Box

Special Folders and CSIDLs

A Simple Example of How to Use CSIDLs and SHBrowseForFolder



- The OpenFiles Dialog Box


사용자가 namespace를 탐색하고 폴더를 선택할 수 있도록 하기 위해서는 당신의 application이 IFileDialog interface를 사용해야 한다. 이 인터페이스를 FOS_PICKFOLDERS flag와 함께 호출하면 the Open Files common dialog box가 "pick folders" mode로 실행된다. (WIndow Vista이후 폴더 선택방식으로 권장되는 방법)



- The SHBrowseForFolder Dialog Box


사용자가 namespace를 탐색하고 폴더를 선택할 수 있도록 하기 위해서는 당신의 application이 단순히 SHBrowseForFolder를 호출하여 Open or Save As common dialog boxes방식으로 작동하는 UI를 가진 dialog box를 실행시키면 됩니다.


사용자가 폴더를 선택하면 SHBrowseForFolder는 폴더의 fully qualified PIDL을 반환하고 그것의 이름을 표시합니다. 만약 그 폴더가 파일 시스템에 포함되는 것이라면 application은 SHGetPathFromIDList함수를 호출하여 PIDL을 경로로 변환할 수 있습니다. Application은 특정 root folder만 선택적으로 보임으로써 사용자의 폴더 선택을 제한할 수 있습니다.

(SHBrowseForFolder Function 참조)



- Special Folders and CSIDLs


사용되는 폴더들 중 상당수는 시스템에 의해 특별히 설계된 것이다. 이 특수 목적 폴더들은 거의 모든 시스템에 포함되어 있거나 설령 없더라도 그 폴더의 이름과 위치가 정의되어 있어 언제든 추가될 수 있다. 이 특수 폴더들은 모든 시스템의 표준 가상 폴더들(standard virtual folders; Printer, My Documents, Network Neighborhood 등)이거나 표준 파일 시스템 폴더들(standard file system folders; Program files, System 등) 이다.


모든 시스템에 포함되어 있기는 하지만 시스템 상황에 따라 그 폴더의 위치는 다를 수 있다(For example, the System directory is C:\Winnt\System32 on some systems and C:\Windows\System32 on others.). 이런 차이가 있는 환경변수를 피하기 위해 쉘은  CSIDLs라는 특수 폴더를 구별하는 방법을 제공한다.


CSIDLs는 특수 폴더의 위치를 이름이나 위치, 시스템과 관계없이 분별하는 공통의 방법을 제공한다. 환경변수와 달리 CSIDLs는 파일 시스템 폴더뿐 아니라 가상 폴더들에도 적용된다. 각 특수 폴더들은 고유의 CSIDL을 배정받는다. (For example, the Program Files file system folder has a CSIDL of CSIDL_PROGRAM_FILES, and the Network Neighborhood virtual folder has a CSIDL of CSIDL_NETWORK)


CSIDL은 몇몇 Shell function들과 함께 특수 폴더의 PIDL 또는 special file system folder의 경로를 얻어내는데 쓰인다. 만약 해당 폴더가 시스템에 존재하지 않는다면 CSIDL_FLAG_CREATE flag를 추가하여 해당 폴더를 만들 수도 있다. 

SHGetFolderLocation함수는 특수 폴더의 PIDL를 구하고, SHGetFolderPath함수는 파일시스템의 특수 폴더 경로를 구한다.

(SHGetSpecialFolderLocation/Path함수들은 Shell 5.0 버전 이후 위 두 함수의 래퍼함수에 불과하게 되었다. 대체되는 중)


- A Simple Example of How to Use CSIDLs and SHBrowseForFolder


LPITEMIDLIST PidlBrowse(HWND hwnd, int nCSIDL, LPSTR pszDisplayName)

{

    LPITEMIDLIST pidlRoot = NULL;

    LPITEMIDLIST pidlSelected = NULL;

    BROWSEINFO bi = {0};


    if(nCSIDL)

    {

        SHGetFolderLocation(hwnd, nCSIDL, NULL, NULL, &pidlRoot);

    }


    else

    {

        pidlRoot = NULL;

    }


    bi.hwndOwner = hwnd;

    bi.pidlRoot = pidlRoot;

    bi.pszDisplayName = pszDisplayName;

    bi.lpszTitle = "Choose a folder";

    bi.ulFlags = 0;

    bi.lpfn = NULL;

    bi.lParam = 0;


    pidlSelected = SHBrowseForFolder(&bi);


    if(pidlRoot)

    {

        CoTaskMemFree(pidlRoot);

    }


    return pidlSelected;

}


위 함수를 호출한 application은 SHBrowseForFolder함수가 필요로 하는 윈도우 핸들과 목표로 하는 특수 폴더의 CSIDL을 넘겨 검색할 root folder로 지정한다(그 목적은 검색 제한). 또한 pszDisplayName으로 문자열 버퍼를 넘겨 PidlBrowse가 반환될 때 선택된 폴더의 이름을 저장한다. 마지막에는 CoTaskMemFree함수로 사용한 IDList의 메모리를 해제해준다.




Getting a Folder's ID  (MSDN 번역)

AND

Understanding Shell Namespace Extensions (MSDN 번역)


윈도우 탐색기는 사용자가 Shell Object에 접근할 수 있게 도와주는 도구와 결합된 Shell namespace의 graphical representation이다. With a namespace extension, you can take any body of data and have Windows Explorer present it to the user as a virtual folder. When a user browses into this folder, your data는 tree-structured 계층의 폴더들과 파일들로 표현되어 보여집니다, much like the rest of the Shell namespace. 사용자와 application들은 다른 namespace object들과 비슷한 방법으로 가상 폴더(virtual folder)의 내용물을 사용할 수 있습니다. 이 문서는namespace extension을 생성하는 방법을 다룹니다.


목차

How a Namespace Extension Works

The Default System Folder View Object(DefView)

How Windows Explorer Interacts with a Namespace Extension

TreeView

Folder View

Menu Bar and Toolbars

Status Bar


- How a Namespace Extension Works

윈도우 탐색기가 보여주는 모든 폴더들은 내부적으로 folder object라 불리는 COM(Component Object Model) Object로 대표됩니다(represented). 사용자가 폴더 또는 폴더의 내용물을 건드릴 때마다 쉘은 standard interface들 중 하나를 통하여 해당 folder object와 소통합니다. Folder object는 사용자의 행동에 맞춰 필요한 반응을 하고, 쉘은 윈도우 탐색기로 그 변화를 출력합니다.

사용자가 사용하는 대부분의 폴더들과 파일들은 file system 또는 system virtual folder(휴지통 같은)에 속합니다. 이런 standard folders들의 기능을 레지스터를 수정하거나 Shell extension handler를 implementing함으로써 확장할 수 있습니다(Creating Shell Extension handlers 참조). 하지만 쉘을 확장하는 것은 당신의 정보가 빠르게 normal file system의 파일이나 폴더로 packaged될 수 있을 때 유용합니다.

파일 시스템의 파일이나 폴더로 정보를 저장하는 것이 권장되지 않거나 심지어는 불가능한 경우도 존재합니다. 
(A collection of items that is most effectively packaged in a single file, such as a database. A collection of items stored on a remote computer that does not have a standard Windows file system. An example of such data is the information stored on a personal digital assistant (PDA) or digital camera. A collection of items that does not represent stored data. An example of such data is the printer links contained by the standard Printers folder.)


One way to present this kind of data to a user is to write an application to allow users to view and interact with the various items. However, if your data can be presented as a folder/file hierarchy, much of the functionality you will need to implement might be user interface services that are already provided by Windows Explorer. A much more efficient approach could be to write a namespace extension and let Windows Explorer become your GUI.

To implement a namespace extension, your information must be organized as a tree-structured namespace. Your namespace root is presented as a virtual folder in the Shell namespace. The root folder, and all its subfolders and data items, becomes part of the Shell namespace, and Windows Explorer becomes your user interface. You can thus present your information to the user in a familiar and readily accessible way with much less UI programming than would be required for a custom application.

A namespace extension consists of two basic components:

  • A data manager
  • An interface between the data manager and Windows Explorer

The first component on the list is entirely up to you. You can store and manage your data in whatever way is most effective. The second component is the code needed to package your data as folder objects and handle the interaction with Windows Explorer. Windows Explorer can then call these objects to allow users to view and interact with your data as if it were a collection of folders and files. Your namespace extension's folder objects must interact with Windows Explorer as if they were normal folders. Before attempting to implement a namespace extension, you must first understand how Windows Explorer handles a folder object.

- The Default System Folder View Object (DefView)

The Shell provides a default implementation of the folder view, colloquially known as DefView, so that you can avoid much of the work of implementing your own namespace extension. Because some view features cannot be achieved through custom views, it is often recommended that the default system folder view object is used in place of a custom view. For more information, see SHCreateShellFolderView.

- How Windows Explorer Interacts with a Namespace Extension

Windows Explorer provides users with a GUI that allows them to do a variety of tasks, including:

  • Navigating the namespace hierarchy and viewing the contents of folders.
  • Managing the contents of the namespace by moving, deleting, and copying objects.
  • Retrieving a variety of information about objects.
  • Launching applications.

The Windows Explorer GUI has five basic components. The following illustration names the components and shows where they are typically displayed within Windows Explorer.


When a user displays a folder that belongs to a namespace extension in Windows Explorer, the folder object has at least partial control over the contents of all five areas.

- Tree View

The tree view provides a high-level view of the namespace. This area hosts a tree view control that can display every namespace folder and the folder's position in the namespace hierarchy. A user can perform several operations with the tree view area, including:

  • Displaying or hiding the next level in the namespace.
  • Copying, moving, or deleting folders.
  • Right-clicking a folder to display a shortcut menu.
  • Selecting a folder and viewing its contents in the folder view.

The tree view communicates with folder objects primarily through their IShellFolder interface. For example, when a user clicks the plus sign (+) next to the folder's icon, Windows Explorer expands the display to show the folder's subfolders. To obtain the information needed to update the tree view, the Shell makes several calls to the folder object's IShellFolder interface to:

  • Request the folder's attributes.
  • Enumerate the contents of the folder.
  • Request display names for each subfolder.
  • Request an icon to display next to each folder.

Windows Explorer then updates the tree view to show the selected folder's subfolders. If the subfolders have subfolders, a '+' character is displayed next to their folder icon. There are a number of more sophisticated tasks that a user can also perform with the tree view, including:

  • Using the Clipboard to cut or copy a folder and paste it into another folder.
  • Using drag-and-drop to cut or copy a folder and drop it on another folder.
  • Using a search engine to search for items in a folder or its subfolders.
  • Modifying the folder's properties.

For a more detailed discussion of how a namespace extension handles these user actions, see Implementing the Basic Folder Object Interfaces.

- Folder View

When a user selects a folder, the contents of the folder are displayed in the folder view. To some extent, the normal functionality of the folder view overlaps with the tree view. Users can move or copy folders, change folder properties, view the contents of a subfolder, display a shortcut menu for a folder, and so on. However, there are some distinct differences between tree view and folder view:

  • Folder view displays only the contents of a single folder, not part or all of the namespace hierarchy.
  • Folder view displays file objects as well as folder objects.
  • Folder view can display much more information about objects than tree view.
  • Folder view allows namespace extensions to have almost complete control over what information is displayed and how. Only minor aspects of the tree view, such as folder icons, can be modified.

Unlike the tree view, Windows Explorer does not directly control the contents of the folder view. The folder view is an area that Windows Explorer provides to folder objects. Displaying and managing the contents of a folder in the folder view are the responsibility of the folder object. Although most folder views follow a fairly standard format, there are actually few limitations on what can be displayed or how. An extreme case is the Internet folder, which is a full-featured browser.

When a user selects a folder that belongs to your namespace extension, you create a window and pass its handle to Windows Explorer. This window becomes a child of the folder view window. Windows Explorer provides the dimensions of the folder view window but places no restrictions on the content of your child window. You can then use the child window to display the folder's folder view.

Namespace extensions use one of two approaches for creating a folder view:

  • Use your child window to host a list view control. This control allows you to display the contents of a folder in much the same way as the Windows Explorer classic view.
  • Use your child window to host a WebBrowser control and use a Dynamic HTML (DHTML) document to display the contents of the folder.

Both approaches display a folder view that looks very much like that displayed for system folders. However, if you want to use a different display scheme, you are free to do so.

- Menu Bar and Toolbars

Like most Windows applications, Windows Explorer provides the user with a collection of tools. A complete selection of tools is available through the menu bar. The more commonly used tools are also represented by buttons or edit boxes on a toolbar. Unlike many Windows applications, the Windows Explorer menu bar is actually a toolbar control that has been customized to behave like a conventional menu. Both the menu bar and the toolbar are incorporated into a rebar control to allow users to organize the individual controls to suit their needs.

By default, Windows Explorer supports a standard set of buttons and menu items, such as Copy and Properties. Your namespace extension can customize the menu bar and toolbars by deleting standard tools and adding custom tools. When your folder view object is initialized, Windows Explorer passes a pointer to its IShellBrowser interface. This interface supports several methods that you can call to customize the menu bar and toolbar. When the user selects one of your custom menu items or toolbar buttons, Windows Explorer forwards WM_COMMAND messages for custom menu and toolbar items to your child window's window procedure.

- Status Bar

The Windows Explorer status bar displays information about the currently selected object. Your namespace extension can use the status bar to display status information, such as a text string. You can customize the status bar by calling IShellBrowser.



AND

Common Explorer Concepts 

( == Introduction to the Shell Namespace) (MSDN 번역)


The Shell namespace는 쉘에 의해 관리되는 file system과 other Object들을 single tree-structured 계층으로 organizes한다. (Shell namespace는 file system보다 큰 개념이다.)


목차

Introduction

Identifying Namespace Object

Item IDs

Item ID Lists

PIDLs

Allocating PIDLs



- Introduction


쉘(Shell)의 주요 업무 중 하나는 file system을 구성하는 다양하고 방대한 object(디스크 드라이브를 차지하는 폴더들과 파일들이 대표적)들에 대한 접근을 제공 및 관리하는 것이다. 하지만 쉘은 파일시스템에 포함되지 않은 것들과 virtual object들도 관리한다. (Network Printers, Other Networked computers, Control Panel applications, The Recycle Bin 같은 것들)


어떤 virtual object들은 물리적인 storage를 가지지 않기도 한다. 

(예를 들어 The printer object  contains a collection of links to networked printers. Other virtual objects, such as the Recycle Bin, may contain data that is stored on a disk drive, but needs to be handled differently than normal files. For example, a virtual object can be used to represent data stored in a database. In terms of the namespace, the various items in the database could appear in the Windows Explorer as separate objects, even though they are all stored in a single disk file.)


Virtual object들은 심지어 다른 컴퓨터에 위치할 수도 있다.

(예를 들어 to facilitate roaming, a user's document files might be stored on a server. To give users access to their files from multiple desktop PCs, the My Documents folder on the desktop PC they are currently using will point to the server, not the hard disk of the desktop PC. Its path will include either a mapped network drive or a UNC path name.)


Namespace도 file system과 마찬가지로 폴더와 파일이라는 두개의 기본적인 타입의 object들을 포함한다. 폴더 objects는 tree의 nodes로써 다른 폴더와 파일 object들의 컨테이너다.  파일 object들은 tree의 leaves로써 평범한 디스크 파일이거나 virtual objects이다.  파일 시스템의 일부가 아닌 폴더들은 virtual folders라고도 불린다.


파일 시스템 폴더들과 마찬가지로 가상 폴더(virtual folder)들도 시스템 환경에 따라 다르다. 가상 폴더들의 세 가지 classes는...

  • Standard virtual folders, such as the Recycle Bin, that are found on all systems.
  • Optional virtual folders that have standard names and functionality, but may not be present on all systems.
  • Non-standard folders that are installed by the user.
파일 시스템 폴더들과 달리 사용자는 가상 폴더들을 새롭게 만들 수 없고 단지 non-Microsoft 개발자가 만든 것을 설치할 수 밖에 없으므로 가상 폴더들은 파일 시스템 폴더들 보다 훨씬 적다. (가상 폴더 확장과 관련한 내용은 Namespace Extensions를 참조)


namespace 계층의 최상위에는 Desktop이 있고 그 바로 밑에는 My computer(내컴퓨터)와 휴지통 등과 같은 가상 폴더들이 있다. (윈도우 탐색기에서 바로 확인이 가능하다.)


다양한 디스크 드라이브들의 파일시스템들은 더 큰 namespace 계층의 일부로 보인다. 

(The roots of these file systems are subfolders of the My Computer folder. My Computer also includes the roots of any mapped network drives. Other nodes in the tree, such as My Documents, are virtual folders.)



- Identifying Namespace Objects


Namespace Object를 쓰기에 앞서 이것들을 구별하는 방법을 알아야 한다. 파일시스템의 object는 MyFile.htm과 같은 이름을 가지고 있을 수 있다. 하지만 동일한 이름의 파일이 시스템 내에 또 있을 수 있으므로 완전경로(Fully Qualified Path)("C:\MyDocs\MyFile.htm" 같은)를 요구한다. 이런 경로들은 기본적으로 파일시스템의 root인 C드라이브로부터 시작되는 모든 폴더명의 연속된 계층을 나열하고 마지막에 파일의 이름을 쓴 것이다.


하지만 완전경로는 파일시스템에 포함되있는 object들의 위치를 구별하는 데에는 유용하지만 virtual objects들에게 적용할 수 없다. 그래서 쉘은 모든 namespace object가 이용가능한 방법을 지원한다.


- Item IDs


Within a folder, each object는 item ID(which is the functional equivalent of a file or folder name)를 갖는다. Item ID는 실제로는 SHITEMID 구조체이다.


typedef struct _SHITEMID { 

USHORT cb; 

BYTE   abID[1]; 

} SHITEMID, * LPSHITEMID;


abID 멤버가 object의 구별자(identifier)이다. abID의 길이는 정해지지 않았고 그 값은 object를 포함하고 있는 폴더에 의해 결정된다. abID의 값이 폴더에 의해 결정되는 표준화된 방법이 없기 때문에 그 값들은 단지 해당 폴더 object와 함께할 때만 의미를 갖는다. Applications는 그 값들을 특정 폴더 내의 object들을 구별하는 토큰으로 취급하면 된다. Because the length of abID varies, the cb member holds the size of the SHITEMID structure, in bytes.


item ID가 display 목적으로 유용하지 않기 때문에 보통 해당 object를 포함하는 폴더가 object에게 display name을 배정한다. This is the name that is used by Windows Explorer when it displays the contents of a folder. (display names이 다루어지는 방법은 Getting Information From a Folder를 참조)


- Item ID Lists


Item ID가 그 자체로 쓰이는 경우는 별로 없고 보통은 item ID list의 일부로써 파일시스템의 경로와 동일한 목적으로 이용된다. 경로는 문자열로 이루어졌지만 item ID list는 ITEMIDLIST 구조체로 되어있다. 이 구조체는 item ID들의 연속으로 이루어지고 two-byte NULL로 끝이 난다. 


My Computer    C;/         MyDocs    MyFile.htm

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

|  cb  | abID   | cb | abID | cb | abID | cb | abID  | 2-byte NULL

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ


item ID list안의 각 item ID는 namespace object와 일치한다. 그것들의 순서는 파일시스템의 경로처럼 namespace 내의 경로를 정의한다.



- PIDLs


쉘 API에서 namespace object들은 보통 ITEMIDLIST 구조체의 포인터(==Pointer to an item IDentifier List; PIDL)로 구별된다.


위 그림을 full(또는 absolute) PIDL이라고도 부를 수 있다. Full PIDL은 데스크탑부터 시작해서 중도에 있는 폴더들의 item ID를 포함하며 마지막에는 해당 object의 item ID와 two-byte NULL로 끝이 난다. Full PIDL은 완전경로와 비슷하고 Shell namespace내 object의 식별자 역활을 수행한다.


많은 함수들에서는 Full PIDL보다는 relative PIDL을 사용된다. relative PIDL의 root는 Desktop이 아닌 폴더이다. As with relative paths, the series of item IDs that make up the structure define a path in the namespace between two objects. Although they do not uniquely identify the object, they are usually smaller than a full PIDL and sufficient for many purposes.


The most commonly used relative PIDLs, single-level PIDLs, are relative to the object's parent folder. They contain only the object's item ID and a terminating NULL. Multi-level PIDLs are also used for many purposes. They contain two or more item IDs and typically define a path from a parent folder to an object through a series of one or more subfolders. Note that a single-level PIDL can still be a fully qualified PIDL. In particular, desktop objects are children of the desktop, so their fully qualified PIDLs contain only one item ID.


쉘 API는 object의 PIDL을 얻는 다양한 방법을 제공하는데 (그 방법은 Getting a Folder's ID 참조) 우리는 어떤 object의 PIDL을 다른 object의 PIDL과 구별하는 용도로 사용할 뿐 다른 용도로 이용하는 경우는 드물다. 따라서 PIDL의 내부는 공개되지 않았다.


- Allocationg PIDLs


PIDL들이 경로와 비슷하지만 그것의 사용방법은 다소 다르다. 특히 PIDL을 위한 메모리 할당과 해제가 그렇다. 경로가 문자열을 사용하는 것과 마찬가지로 PIDL도 반드시 메모리가 할당되어 사용된다(ITEMIDLIST 구조체를 위한 충분한 메모리 할당이 필수적). 대부분의 경우 쉘이 PIDL을 만들고 메모리 할당도 함께 한다. 그리고 보통 application에게 그 메모리를 해제할 책임이 있다. 이런 PIDL의 할당과 해제에는 CoTaskMemAlloc함수와 CoTaskMemFree함수가 쓰인다.





Common Explorer Concepts 

( == Introduction to the Shell Namespace) (MSDN 번역)

'MSDN > Shell Programming' 카테고리의 다른 글

Getting Information About the Contents of a Folder  (0) 2017.02.22
Getting a Folder's ID  (0) 2017.02.22
Understanding Shell Namespace Extensions  (0) 2017.02.22
AND

ARTICLE CATEGORY

분류 전체보기 (56)
Programming (45)
MSDN (4)
Shell Programmin.. (4)
개발노트 (2)
reference (5)

RECENT ARTICLE

RECENT COMMENT

CALENDAR

«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31

ARCHIVE