셸 확장 처리기 초기화
Shell 확장 처리기 개체 구현의 대부분은 해당 형식에 따라 결정됩니다. 그러나 몇 가지 일반적인 요소가 있습니다. 이 항목에서는 모든 Shell 확장 처리기에서 공유하는 구현의 이러한 측면에 대해 설명합니다.
모든 셸 확장 처리기는 COM(In-process Component Object Model) 개체입니다. GUID를 할당하고 셸 확장 처리기 등록에 설명된 대로 등록해야 합니다. DLL로 구현되며 다음 표준 함수를 내보내야 합니다.
- DllMain. DLL에 대한 표준 진입점입니다.
- DllGetClassObject. 개체의 클래스 팩터리를 노출합니다.
- DllCanUnloadNow. COM은 이 함수를 호출하여 개체가 클라이언트에 서비스를 제공하는지 여부를 확인합니다. 그렇지 않은 경우 시스템에서 DLL을 언로드하고 연결된 메모리를 해제할 수 있습니다.
모든 COM 개체와 마찬가지로 셸 확장 처리기는 IUnknown 인터페이스 및 클래스 팩터리를 구현해야 합니다. 또한 대부분은 Windows XP 또는 이전 버전에서 IPersistFile 또는 IShellExtInit 인터페이스를 구현해야 합니다. 이러한 항목은 Windows Vista의 IInitializeWithStream, IInitializeWithItem 및 IInitializeWithFile 로 대체되었습니다. 셸은 이러한 인터페이스를 사용하여 처리기를 초기화합니다.
IPersistFile 인터페이스는 다음을 통해 구현해야 합니다.
- 아이콘 처리기
- 데이터 처리기
- 드롭 처리기
IShellExtInit 인터페이스는 다음을 통해 구현해야 합니다.
- 바로 가기 메뉴 처리기
- 끌어서 놓기 처리기
- 속성 시트 처리기
이 항목의 나머지 부분에서는 다음 주제에 대해 설명합니다.
IPersistFile 구현
IPersistFile 인터페이스는 개체를 디스크 파일에서 로드하거나 디스크 파일에 저장할 수 있도록 설계되었습니다. IUnknown 외에도 6개의 메서드, 5개의 자체 메서드 및 IPersist에서 상속하는 GetClassID 메서드가 있습니다. 셸 확장을 사용하면 IPersist 는 Shell 확장 처리기 개체를 초기화하는 데만 사용됩니다. 일반적으로 디스크에서 읽거나 쓸 필요가 없으므로 GetClassID 및 Load 메서드만 토큰이 아닌 구현이 필요합니다.
Shell은 GetClassID 를 먼저 호출하고 함수는 확장 처리기 개체의 CLSID(클래스 식별자)를 반환합니다. 그런 다음 셸은 Load 를 호출하고 두 값을 전달합니다. 첫 번째 pszFile은 Shell이 작동하려고 하는 파일 또는 폴더의 이름을 가진 유니코드 문자열입니다. 두 번째는 파일 액세스 모드를 나타내는 dwMode입니다. 일반적으로 파일에 액세스할 필요가 없으므로 dwMode 는 일반적으로 0입니다. 메서드는 나중에 참조하기 위해 필요에 따라 이러한 값을 저장합니다.
다음 코드 조각에서는 일반적인 Shell 확장 처리기가 GetClassID 및 Load 메서드를 구현하는 방법을 보여 줍니다. ANSI 또는 유니코드를 처리하도록 설계되었습니다. CLSID_SampleExtHandler 확장 처리기 개체의 GUID이고 CSampleShellExtension은 인터페이스를 구현하는 데 사용되는 클래스의 이름입니다. m_szFileName 및 m_dwMode 변수는 파일의 이름 및 액세스 플래그를 저장하는 데 사용되는 프라이빗 변수입니다.
class CSampleShellExtension : public IPersistFile
{
// Method declarations not included
private:
WCHAR m_szFileName[MAX_PATH]; // The file name
DWORD m_dwMode; // The file access mode
}
IFACEMETHODIMP CSampleShellExtension::GetClassID(__out CLSID *pCLSID)
{
*pCLSID = CLSID_SampleExtHandler;
}
IFACEMETHODIMP CSampleShellExtension::Load(PCWSTR pszFile, DWORD dwMode)
{
m_dwMode = dwMode;
return StringCchCopy(m_szFileName, ARRAYSIZE(m_szFileName), pszFile);
}
// The implementation sample is continued in the next section.
IShellExtInit 구현
IShellExtInit 인터페이스에는 IUnknown 외에도 IShellExtInit::Initialize라는 메서드가 하나만 있습니다. 메서드에는 Shell이 다양한 유형의 정보를 전달하는 데 사용할 수 있는 세 가지 매개 변수가 있습니다. 전달된 값은 처리기 유형에 따라 달라지고 일부는 NULL로 설정할 수 있습니다.
- pidlFolder 는 PIDL(항목 식별자 목록)에 대한 폴더의 포인터를 보유합니다. 이는 절대 PIDL입니다. 속성 시트 확장의 경우 이 값은 NULL입니다. 바로 가기 메뉴 확장의 경우 바로 가기 메뉴가 표시되는 항목이 포함된 폴더의 PIDL입니다. 기본이 아닌 끌어서 놓기 처리기의 경우 대상 폴더의 PIDL입니다.
- pDataObject 는 데이터 개체의 IDataObject 인터페이스에 대한 포인터를 보유합니다. 데이터 개체는 CF_HDROP 형식으로 하나 이상의 파일 이름을 보유합니다.
- hRegKey 는 파일 개체 또는 폴더 형식에 대한 레지스트리 키를 보유합니다.
IShellExtInit::Initialize 메서드는 나중에 사용하기 위해 필요에 따라 파일 이름, IDataObject 포인터 및 레지스트리 키를 저장합니다. 다음 코드 조각은 IShellExtInit::Initialize의 구현을 보여 줍니다. 간단히 하기 위해 이 예제에서는 데이터 개체에 단일 파일만 포함되어 있다고 가정합니다. 일반적으로 데이터 개체에는 여러 파일이 포함될 수 있으며, 각 파일은 추출해야 합니다.
// This code continues the CSampleShellExtension sample shown in the
// "Implementing IPersistFile" section above.
class CSampleShellExtension : public IShellExtInit
{
// Method declarations not included
private:
// IDList of the folder for extensions invoked on the folder, such as
// background context menu handlers or nondefault drag-and-drop handlers.
PIDLIST_ABSOLUTE m_pidlFolder;
// The data object contains an expression of the items that the handler is
// being initialized for. Use SHCreateShellItemArrayFromDataObject to
// convert this object to an array of items. Use SHGetItemFromObject if you
// are only interested in a single Shell item. If you need a file system
// path, use IShellItem::GetDisplayName(SIGDN_FILESYSPATH, ...).
IDataObject *m_pdtobj;
// For context menu handlers, the registry key provides access to verb
// instance data that might be stored there. This is a rare feature to use
// so most extensions do not need this variable.
HKEY m_hRegKey;
}
// This method must be very efficient. Do not do any unnecessary work here.
// Use Initialize to acquire resources that will be used later.
IFACEMETHODIMP CSampleShellExtension::Initialize(__in_opt PCIDLIST_ABSOLUTE pidlFolder,
__in_opt IDataObject *pDataObject,
__in_opt HKEY hRegKey)
{
// In some cases, handlers are initialized multiple times. Therefore,
// clear any previous state here.
CoTaskMemFree(m_pidlFolder);
m_pidlFolder = NULL;
if (m_pdtobj)
{
m_pdtobj->Release();
}
if (m_hRegKey)
{
RegCloseKey(m_hRegKey);
m_hRegKey = NULL;
}
// Capture the inputs for use later.
HRESULT hr = S_OK;
if (pidlFolder)
{
m_pidlFolder = ILClone(pidlFolder); // Make a copy to use later.
hr = m_pidlFolder ? S_OK : E_OUTOFMEMORY;
}
if (SUCCEEDED(hr))
{
// If a data object pointer was passed into the method, save it and
// extract the file name.
if (pDataObject)
{
m_pdtobj = pDataObject;
m_pdtobj->AddRef();
}
// It is uncommon to use the registry handle, but if you need it,
// duplicate it now.
if (hRegKey)
{
LSTATUS const result = RegOpenKeyEx(hRegKey, NULL, 0, KEY_READ, &m_hRegKey);
hr = HRESULT_FROM_WIN32(result);
}
}
return hr;
}
Infotip 사용자 지정
인포 설명을 사용자 지정하는 방법에는 두 가지가 있습니다. 한 가지 방법은 IQueryInfo 를 지원하는 개체를 구현한 다음 레지스트리의 적절한 하위 키 아래에 개체를 등록하는 것입니다(아래 참조). 또는 표시할 고정 문자열 또는 특정 파일 속성 목록을 지정할 수 있습니다.
네임스페이스 확장의 고정 문자열을 표시하려면 네임스페이스 확장의 CLSID 키 아래에 InfoTip 이라는 하위 키를 만듭니다. 해당 하위 키의 데이터를 표시할 문자열로 설정합니다.
HKEY_CLASSES_ROOT
CLSID
{CLSID}
InfoTip = InfoTip string for your namespace extension
파일 형식에 대한 고정 문자열을 표시하려면 infotip을 제공하려는 파일 형식의 ProgID 키 아래에 InfoTip이라는 하위 키를 만듭니다. 해당 하위 키의 데이터를 표시할 문자열로 설정합니다.
HKEY_CLASSES_ROOT
ProgID
InfoTip = InfoTip string for all files of this type
셸이 특정 파일 형식에 대한 정보 설명에 특정 파일 속성을 표시하려면 해당 파일 형식의 ProgID 키 아래에 InfoTip이라는 하위 키를 만듭니다. 해당 하위 키의 데이터를 정식 속성 이름 또는 {fmtid}의 세미콜론으로 구분된 목록으로 설정하고, propname 이 정식 속성 이름이고 {fmtid},pid 가 FMTID/PID 쌍인 pid 쌍으로 설정합니다.
HKEY_CLASSES_ROOT
ProgID
InfoTip = propname;propname;{fmtid},pid;{fmtid},pid
다음 속성 이름을 사용할 수 있습니다.
속성 이름 | 설명 | 에서 검색됨 |
---|---|---|
작성자 | 문서 작성자 | PIDSI_AUTHOR |
제목 | 문서의 제목 | PIDSI_TITLE |
제목 | 제목 요약 | PIDSI_SUBJECT |
의견 | 문서 주석 | PIDSI_COMMENT 또는 폴더/드라이브 속성 |
PageCount | 페이지 수 | PIDSI_PAGECOUNT |
Name | 이름 | 표준 폴더 보기 |
OriginalLocation | 원본 파일의 위치 | 서류 가방 폴더 및 휴지통 폴더 |
DateDeleted | 날짜 파일이 삭제되었습니다. | 휴지통 폴더 |
형식 | 파일 형식 | 표준 폴더 세부 정보 보기 |
크기 | 파일 크기 | 표준 폴더 세부 정보 보기 |
SyncCopyIn | OriginalLocation과 동일 | OriginalLocation과 동일 |
수정자 | 마지막으로 수정한 날짜 | 표준 폴더 세부 정보 보기 |
생성일 | 만든 날짜 | 표준 폴더 세부 정보 보기 |
액세스함 | 마지막으로 액세스한 날짜 | 표준 폴더 세부 정보 보기 |
InFolder | 파일이 포함된 디렉터리 | 문서 검색 결과 |
순위 | 검색 일치 품질 | 문서 검색 결과 |
FreeSpace | 사용 가능한 스토리지 공간 | 디스크 드라이브 |
NumberOfVisits | 방문 횟수 | 즐겨찾기 폴더 |
특성 | 파일 특성 | 표준 폴더 세부 정보 보기 |
회사 | 회사 이름 | PIDDSI_COMPANY |
범주 | 문서 범주 | PIDDSI_CATEGORY |
Copyright | 미디어 저작권 | PIDMSI_COPYRIGHT |
HTMLInfoTipFile | HTML InfoTip 파일 | 폴더에 대한 파일 Desktop.ini |
관련 항목