코딩캣: 코딩하는 고양이.
Windows 쉘 익스텐션 개발 가이드 - (8) 자세히 모드 (1/2)
API/COM
2021. 2. 10. 11:46

입문자를 위한 Windows Shell Extension 개발 가이드

본 게시물은 ‘codeproject.com’에 게시된 “The Complete Idiot's Guide to Writing Shell Extensions” 시리즈를 우리말로 번역한 것입니다.

원문의 주소는 “https://www.codeproject.com/script/Articles/MemberArticles.aspx?amid=152”입니다. 원문은 2000년에 작성되었지만 네이티브 수준에서 Windows 운영체제가 근본적으로 바뀌지 않는 이상 현재에도 여전히 유효한 내용입니다. 다만 소스코드가 Visual C++ 6.0을 기준으로 작성되었기 때문에 현재 버전의 Visual Studio에서 자동으로 생성해주는 코드의 형태와는 다소 차이가 있을 수 있음을 감안하시기 바랍니다.

또한 본 게시물은 원문을 최대한 직역하는 것을 지향하고 있으나, 우리말로 읽었을 때 보다 매끄럽게 하기 위하여 부득이 의역, 어순 조정 및 어휘 조정이 있음을 양해 바랍니다.

 

  1. 목차
  2. 쉘 익스텐션(Shell Extension)을 작성하기 위한 단계별 튜토리얼
    1. 파트 1
    2. 파트 2
  3. 여러 개의 파일에 대해 한번에 작동하는 쉘 익스텐션(Shell Extension)
    1. 파트 1
    2. 파트 2
  4. 파일에 대해 ‘팝업(Popup)’ 설명을 보여주는 쉘 익스텐션(Shell Extension)
  5. 사용자 정의 ‘드래그 앤 드롭(Drag and Drop)’ 기능을 제공하는 쉘 익스텐션(Shell Extension)
  6. 파일에 대한 ‘등록 정보’(또는 ‘속성’) 다이얼로그에 페이지를 추가하는 쉘 익스텐션(Shell Extension)
    1. 파트 1
    2. 파트 2
  7. ‘보내기(Send To)’ 메뉴에서 사용될 수 있는 쉘 익스텐션(Shell Extension)
  8. 컨텍스트 메뉴에 그림 출력하는 쉘 익스텐션(Shell Extension)
    및 디렉토리의 빈 공간에서 마우스 오른쪽 클릭에 응답하는 컨텍스트 메뉴 익스텐션(Shell Extension)
    1. 파트 1
    2. 파트 2
    3. 파트 3
  9. Windows 탐색기에서 “자세히” 보기 모드를 선택할 때 나타나는 열 항목을 추가하는 쉘 익스텐션(Shell Extension)
    1. 파트 1
    2. 파트 2
  10. 특정 형식의 파일에 대해 아이콘을 사용자화 하는 쉘 익스텐션(Shell Extension)

 

8 단계. Windows 탐색기에서 “자세히” 보기 모드를 선택할 때 나타나는 열 항목을 추가하는 쉘 익스텐션(Shell Extension)

실습 프로젝트 다운로드

ShellExtGuide8_demo.zip
51.2 kB

 

들어가기에 앞서......

많은 독자 여러분께서 본 “입문자를 위한 가이드” 시리즈가 계속 되기를 원하십니다. 이번 단계에서 필자는 Windows Me 및 2000 이상의 운영체제에 대해 Windows 탐색기의 “자세히” 보기 화면에 표시되는 열을 추가하는 방법에 대해 다루어 보겠습니다. 이러한 유형의 쉘 익스텐션은 Windows NT 4.0, Windows 95 및 Windows 98에서는 지원되지 않습니다. 때문에 본 예제 프로젝트를 가지고 실습하고자 하실 경우 최신 버전의 운영체제를 사용해야만 합니다.

Visual C++ 7.0 또는 8.0 사용자는 이전과 같이 1 단계의 본 시리즈에 들어가며......를 참고하여 컴파일하기 전 몇 가지 설정을 변경해야 함을 기억하시기 바랍니다.

Windows Me와 2000는 “자세히”보기 모드에서 Windows 탐색기를 사용자화 할 수 있는 다양한 옵션들이 추가되었습니다. Windows 2000의 경우 여러분이 활성화시킬 수 있는 37가지의 새로운 열(column)들이 있습니다. 여러분은 두 가지 방법으로 이들 열(column)들을 나타나게 하고, 사라지게 할 수 있습니다. 먼저 열 헤더(column header)에 대해 마우스 오른쪽 버튼을 클릭하면 추가 및 제거할 수 있는 열의 종류가 컨텍스트 메뉴 형태로 몇 가지 나타납니다.

 

‘자세히’ 보기 모드에서 열 헤더 부분을 마우스 오른쪽 클릭해본다.

 

여러분이 [자세히...] 항목을 클릭한다면, Windows 탐색기는 사용 가능한 모든 열 항목들을 다이얼로그를 통해 보여줄 것이고, 이 중에서 선택할 수 있습니다.

 

‘열 설정’ 대화상자에서 표시할 열의 종류를 설정할 수 있다.

 

또한 Windows 탐색기는 이들 열 목록 속에 우리가 직접 정의한 것을 추가할 수 있도록 컬럼 핸들러 익스텐션(column handler extension)을 제공합니다.

이번 단계의 예제 프로젝트는 MP3 파일에 대한 컬럼 핸들러로서, .mp3 파일에 저장되는 ID3 태그(버전 1에 한함)로부터 다양한 필드를 읽어서 Windows 탐색기를 통해 사용자에게 보여줄 것입니다.

 

인터페이스 구현하기

여러분은 이미 프로젝트를 생성하는 과정에 대해 익숙해지셨을 것이므로 필자는 Visual C++ 마법사에 대한 내용은 생략하겠습니다. 새로운 ATL COM 프로젝트를 생성하고 그 이름을 MP3TagView로 정합니다. 또한 CMP3ColExt라는 이름의 C++ 구현 클래스를 생성합니다.

컬럼 핸들러는 단 하나의 인터페이스만 구현하면 됩니다. 바로 IColumnProvider입니다. 다른 쉘 익스텐션처럼 IShellExtInitIPersistFile을 통해 별도의 초기화 과정을 밟을 필요가 없습니다. 왜냐하면 컬럼 핸들러는 폴더에 대한 확장이고, 현재 선택된 파일에 대해서 어떤 작업을 할 필요가 없기 때문입니다. 물론 소정의 초기화 작업이 필요하기는 하지만, 이들은 IColumnProvider의 메소드를 통해 수행됩니다.

우리가 개발할 COM 개체에 IColumnProvider를 추가하기 위하여 MP3ColExt.h를 열고 아래 표시된 부분과 같이 내용을 추가합니다.

 

#include <comdef.h> // 새로 추가
#include <shlobj.h> // 새로 추가
#include <shlguid.h> // 새로 추가
 
/////////////////////////////////////////////////////////////////////////////
// CMP3ColExt
 
class CMP3ColExt :
    public CComObjectRootEx<CComSingleThreadModel>,
    public CComCoClass<CMP3ColExt, &CLSID_MP3ColExt>,
    public IColumnProvider { // 새로 추가
    BEGIN_COM_MAP(CMP3ColExt)
        // 새로 추가
        COM_INTERFACE_ENTRY_IID(IID_IColumnProvider, IColumnProvider)
    END_COM_MAP()
    
    public:
        // 이 이하부터 모두 새로 추가
        // IColumnProvider 
        STDMETHODIMP Initialize(LPCSHCOLUMNINIT psci) { return S_OK; }
        STDMETHODIMP GetColumnInfo(DWORD dwIndex, SHCOLUMNINFO * psci);
        STDMETHODIMP GetItemData(LPCSHCOLUMNID pscid, LPCSHCOLUMNDATA pscd, VARIANT * pvarData);
};

 

인터페이스 맵 부분에 COM_INTERFACE_ENTRY_IID라는 매크로가 적혀있는 것을 주목하시기 바랍니다. 이전까지 작성했던 쉘 익스텐션에서 COM_INTERFACE_ENTRY 매크로를 사용해 왔습니다. 이 때는 인터페이스가 __declspec(uuid) 구문으로 선언된 GUID를 가지고 있어야 합니다. 그러나 comdef.h의 경우 IColumnProvider에 대한 GUID를 선언하고 있지 않습니다. 그래서 우리는 이 인터페이스를 COM_INTERFACE_ENTRY를 써서 구현할 수 없습니다.

이 때 필요한 것이 COM_INTERFACE_ENTRY_IID입니다. 인터페이스의 이름과 이에 대한 IID를 명시적으로 지정해주기만 하면 됩니다. 이 방법 대신 클래스 선언 바로 직전에 다음과 같이 내용을 추가하면 기존처럼 COM_INTERFACE_ENTRY를 사용할 수도 있습니다.

 

struct __declspec(uuid("E8025004-1C42-11d2-BE2C-00A0C9A83DA1")) IColumnProvider;

 

우리는 또한 stdafx.h에서 몇 가지 설정을 바꾸어야 합니다. 우리는 Windows 2000의 기능들을 사용하고자 하므로 각종 선언과 원형들을 활성화시키기 위하여 다음과 같이 매크로 상수를 구성합니다.

#define WINVER       0x0500    // Windows 2000, 98 기능 사용
#define _WIN32_WINNT 0x0500    // Windows 2000 기능 사용
#define _WIN32_IE    0x0500    // Internet Explorer 5.0 이상의 기능 사용

 

위 매크로 상수들은 #include보다 먼저 등장해야 합니다.

 

초기화

IColumnProvider는 세 가지 메소드를 갖습니다. 그 중 하나는 Initialize로서 다음과 같은 원형을 갖습니다.

 

HRESULT IColumnProvider::Initialize(LPCSHCOLUMNINIT psci);

 

쉘(shell)은 우리에게 SHCOLUMNINIT 구조체를 전달해줄 것입니다. 이것은 Windows 탐색기에서 보여주고 있는 현재 폴더의 전체 경로를 포함하고 있습니다. 본 단계에서 구현할 예제에서는 필요한 정보가 아니므로 본 Initialize 메소드에서는 단순히 S_OK만 반환할 것입니다.

 

새로운 열(column)을 열거하기

우리가 만든 컬럼 핸들러가 등록되었음을 Windows 탐색기가 발견하였을 때, Windows 탐색기는 우리에게 어떤 열(column)들을 구현하고 있는지 물어보게 됩니다. 이 과정은 다음과 같은 원형을 가진 GetColumnInfo에서 처리됩니다.

 

HRESULT IColumnProvider::GetColumnInfo(DWORD dwIndex, SHCOLUMNINFO * psci);

 

dwIndex0부터 세는 카운터 값으로서, Windows 탐색기가 몇 번째 열에 대해 알고 싶어 하는지를 의미합니다.

psciSHCOLUMNINFO 형 구조체로서 열(column)에 대한 매개 변수(parameter)들로 우리가 내용을 채워야 하는 구조체입니다.

SHCOLUMNINFO의 첫 번째 멤버 변수는 또 다른 구조체인 SHCOLUMNID입니다. SHCOLUMNIDGUIDDWORD의 한 쌍으로 구성되어 있습니다. GUID의 경우 “포맷 아이디(format ID)”라고 부리고, DWORD의 경우 “프로퍼티 아이디(property ID)”라고 부릅니다. 이 한 쌍의 값은 한 시스템에서 특정 열(column)을 유일하게 식별할 수 있습니다. 예를 들어 저자(Author)와 같이 이미 존재하는 열(column)이라 해도 포맷 아이디와 프로퍼티 아이디가 미리 정의된 값으로 설정되어있다면 재사용할 수 있습니다.

쉘 익스텐션이 새로운 열(column)을 추가할 때, 유일한 것으로 보장되는 우리의 CLSID를 포맷 아이디로 지정한다면, 프로퍼티 아이디는 간단한 숫자로 지정할 수 있습니다.

본 단계에서 구현할 쉘 익스텐션은 두 가지 방법을 모두 사용해 볼 것입니다.

우리는 먼저 제작자(Author), 제목(Author) 및 주석(Comment) 열을 재사용할 것이고, MP3 앨범명(MP3 Album), MP3 연도(MP3 Year) 및 MP3 장르(MP3 Genre)라는 열을 새롭게 추가할 것입니다. 본 단계의 예제 프로젝트에서 GetColumnInfo는 다음과 같이 시작합니다.

 

STDMETHODIMP CMP3ColExt::GetColumnInfo(DWORD dwIndex, SHCOLUMNINFO * psci) {
    // 우리는 최대 6개의 열을 제공할 것이기 때문에
    // dwIndex가 6 이상이면 우리가 제공할 열을 모두 열거했음을 알리기 위해
    // S_FALSE를 반환합니다.
    if (dwIndex >= 6)
        return S_FALSE;
    
    // ...

 

dwIndex6 이상의 값이 전달되면 우리는 Windows 탐색기가 열에 대한 열거를 끝낼 수 있도록 S_FALSE를 반환합니다. 그렇지 않은 경우 우리는 SHCOLUMNINFO 구조체의 내용을 채워야 합니다. dwIndex의 값이 0, 1, 2인 경우 우리는 우리가 새롭게 추가할 열(column)에 대한 데이터를 반환할 것입니다. dwIndex의 값이 3, 4, 5인 경우 우리는 재사용하고자 하는 운영체제 내장 열(column)을 반환할 것입니다.

우리의 첫 번째 커스텀 열(custom column)인, ID3 태그에서 앨범 이름을 보여주는 열을 구성하는 예는 다음과 같습니다.

 

    // ...
    
    switch (dwIndex) {
    case 0: // MP3 Album - separate column
        psci->scid.fmtid = CLSID_MP3ColExt; // 포맷 ID로서 우리의 CLSID를 지정.
        psci->scid.pid   = 0; // 프로퍼티 ID로서 0번을 지정.
        psci->vt         = VT_LPSTR; // 이 열(column)의 데이터는 문자열임을 지정.
        psci->fmt        = LVCFMT_LEFT; // 문자열은 왼쪽 정렬로 출력되어야 함.
        psci->csFlags    = SHCOLSTATE_TYPE_STR; // 데이터는 문자열로 저장되어야 함.
        psci->cChars     = 32; // 기본 열 너비(단위: 문자)
        
        wcsncpy(psci->wszTitle, L"MP3 Album", MAX_COLUMN_NAME_LEN);
        wcsncpy(psci->wszDescription, L"Album name of an MP3", MAX_COLUMN_DESC_LEN);
        
        break;
        
        // ...

 

중요

이 글의 이전 버전에서는 csid.fmtid 멤버에 _Module.pguidVer라는 값을 저장하도록 작성했었는데 이는 근본적으로 틀린 내용이었습니다. 왜냐하면 GUID는 같은 버전의 ATL에서 빌드된 모든 바이너리에서 항상 똑같기 때문입니다. _Module.pguidVer를 사용하면서 같은 프로퍼티 아이디를 사용하는 서로 다른 두 개의 쉘 익스텐션이 있다면, 각 열 사이에 서로 엄청난 충돌이 발생할 것입니다.

 

우리는 포맷 아이디로서 본 단계에서 다루는 쉘 익스텐션의 GUID를 지정했고, 프로퍼티 아이디에는 열(column)의 번호를 지정했습니다. SHCOLUMNINIT 구조체의 vt 멤버는 우리가 Windows 탐색기에 반환할 데이터의 타입을 나타냅니다. VT_LPSTR은 C 언어 스타일의 문자열을 의미합니다.

 

fmt 멤버는 LVCFMT_로 시작하는 상수들 중 하나가 될 수 있으며 그 열(column)에서 문자열 정렬 방향을 지정합니다. 이 경우는 왼쪽 정렬로 하겠습니다.

 

csFlags 멤버는 열(column)에 대한 몇 가지 옵션입니다. 그러나 쉘(shell)은 모든 옵션들을 구현해 놓지는 않은 것으로 보입니다. 다음은 각 플래그(flag)에 대한 설명입니다.

 

SHCOLSTATE_TYPE_STR, SHCOLSTATE_TYPE_INTSHCOLSTATE_TYPE_DATE

Windows 탐색기가 열을 기준으로 정렬할 때 해당 열의 데이터를 어떻게 처리해야 하는지를 지정합니다. 문자열, 정수 및 날짜/시각 중 하나가 될 수 있습니다.

SHCOLSTATE_ONBYDEFAULT

마이크로소프트 개발 지원 관계자인 Dave Anderson에 따르면 다음과 같은 용도를 갖습니다.

이 작동은 여러분의 쉘 탐색기(shell browser)의 설정에 따라 달라집니다. 여러분이 폴더 옵션에서 “각 폴더의 보기 옵션 기억”을 지정하였다면, 특정한 몇몇 쉘(shell)에서 열(column)이 보여지는 상태는 레지스트리로부터 가져오게 될 것입니다. 이 때는 SHCOLSTATE_ONBYDEFAULT 플래그가 아무 효과가 없습니다.

모든 폴더의 보기 설정을 리셋하는 것은, 여러분의 열도 기본 상태로 돌아가게 할 수 있습니다. 여러분은 이 설정을 Windows 탐색기 또는 제어판의 폴더 옵션 대화상자에서 할 수 있습니다.

SHCOLSTATE_SLOW

개발 문서에 따르면 이 옵션을 포함하는 것은 각 열의 데이터를 읽어오는데 시간이 걸림을 뜻합니다. 이 때 Windows 탐색기는 쉘(shell) 익스텐션을 하나 이상의 백그라운드 스레드에서 호출하여, Windows 탐색기 창 그 자체는 사용자로부터 원활하게 응답할 수 있도록 조치합니다. 필자가 테스트해 본 바, 이 옵션의 존재 여부에 따른 차이를 발견하지 못했습니다.

Windows 2000에서 Windows 탐색기는 쉘 익스텐션이 제공하는 열에 대한 데이터를 불러오는 데 하나의 스레드만을 사용할 뿐이었습니다.

Windows XP에서 Windows 탐색기는 몇 개의 서로 다른 스레드를 통해 작업하기는 하였으나, SHCOLSTATE_SLOW 옵션의 존재 여부에 따라 돌아가는 스레드의 개수의 차이는 발견하지 못했습니다.

SHCOLSTATE_SECONDARYUI

개발 문서에 따르면 이 옵션을 전달하는 것은 열(column)이 헤더 컨트롤의 컨텍스트 메뉴에 나타나는 것을 방지해준다고 합니다. 여러분이 이 옵션을 추가해주지 않는다면, 각 열의 제목에 대해 마우스 오른쪽 버튼을 클릭하여 나타나는 컨텍스트 메뉴에서 여러분이 추가하고 있는 열이 나타난다는 뜻입니다. 이 옵션이 포함되면, 컨텍스트 메뉴에는 곧바로 나타나지 않고 [자세히...] 버튼을 누른 후 대화상자를 통해서만 나타납니다.

SHCOLSTATE_HIDDEN
이 옵션을 전달하면 “열 설정(Column Settings)” 대화상자에서 열(column)이 나타나지 않습니다. 숨겨진 열을 활성화하는 방법은 없기 때문에 이 것은 열(column)을 사용할 수 없게 만듭니다.

 

cChars 멤버는 열(column) 이본 너비를 문자 수 단위로 지정합니다. 이 값을 열(column) 이름 길이의 최대치 및 여러분이 이 열을 통해 나타날 것으로 예상하는 가장 긴 문자열만큼 설정하시기 바랍니다. 또한 여러분은 전체 문자열을 충분하게 보여주도록 2, 3문자의 여유를 더 추가하여야 합니다. 이 여유분을 넣지 않으면 열의 기본 너비는 충분히 넓지 않을 수 있고 일부 텍스트가 잘려서 표시될 수 있습니다.

 

마지막 두 멤버는 헤더 컨트롤(header control)에서 보여질 열의 이름을 보관하는 유니코드 문자열 및 열에 대한 설명을 보관하는 유니코드 문자열입니다. 현재는 이 열을 설명하는 문자열이 사용되지 않기 때문에 사용자는 이를 보는 일이 없습니다.

 

제1열과 제2열도 비슷합니다. 그러나 제1열은 데이터 타입과 정렬 방법에서 차이가 있습니다. 이 열은 연도를 나타내기 때문인데, 어떻게 정의되는지는 아래의 코드에서 확인 가능합니다.

 

    // ...
    
    case 1:     // MP3 year - separate column
        psci->scid.fmtid = CLSID_MP3ColExt;
        psci->scid.pid   = 1;
        psci->vt         = VT_LPSTR; // 문자열의 형태로 데이터를 반환할 것입니다.
        psci->fmt        = LVCFMT_RIGHT; // 문자열은 오른쪽 정렬로 나타날 것입니다.
        psci->csFlags    = SHCOLSTATE_TYPE_INT; // 정수 형태로 저장되어야 합니다.
        psci->cChars     = 6; // 열의 기본 폭을 지정합니다.
        
        wcsncpy(psci->wszTitle, L"MP3 Year", MAX_COLUMN_NAME_LEN);
        wcsncpy(psci->wszDescription, L"Year of an MP3", MAX_COLUMN_DESC_LEN);
        break;
    // ...

 

vt 멤버 변수가 VT_LPSTR로 되어 있음에 주목하시기 바랍니다. 이것은 우리가 Windows 탐색기에게 문자열을 전달할 것임을 의미합니다. 하지만 csFlags 멤버 변수는 SHCOLSTATE_TYPE_INT로 되어 있습니다. 이것은 Windows 탐색기가 우리가 전달한 데이터들을 정렬할 때 가나다 순이 아니라, 숫자로서 크기 비교를 하라는 뜻입니다. 물론 처음부터 우리가 Windows 탐색기에 문자열이 아닌 정수 형식으로 데이터를 전달할 수도 있습니다. 그러나 .mp3 파일의 ID3 태그가 발행 연도 항목을 정수가 아닌 문자열 형식으로 보관하고 있기 때문에, 위와 같이 열 정의를 하면 우리가 직접 문자열을 정수로 변환하지 않아도 됩니다.

 

dwIndex3, 4, 5일 때 우리는 재사용하고자 하는 운영체제 내장 열(column)을 반환합니다. 제3열은 저작자(Author) 열(column)로서 ID3의 아티스트(Artist) 정보를 보여줄 것입니다.

 

    // ...
    
    case 3: // MP3 artist - reusing the built-in Author column
        psci->scid.fmtid = FMTID_SummaryInformation; // 미리 정의된 FMTID
        psci->scid.pid   = 4; // 미리 정의된 author 열
        psci->vt         = VT_LPSTR; // 데이터를 문자열 형태로 반환할 것입니다.
        psci->fmt        = LVCFMT_LEFT; // 문자열은 왼쪽 정렬될 것입니다.
        psci->csFlags    = SHCOLSTATE_TYPE_STR; // 데이터는 문자열로서 정렬됩니다.
        psci->cChars     = 32;  // 열의 기본 너비(단위: 문자)
        break;
    // ...

 

FMTID_SummaryInformation은 미리 정의된 기호입니다. 저자(author) 필드는 MSDN 문서에 따르면 4번으로 등록되어 있습니다. 전체 목록은 “The Summary Information Property Set”을 참고하시기 바랍니다. 운영체제에서 미리 정의해 놓은 열을 재사용하고자 할 때, 우리는 열의 제목이나 설명을 반환하지 않습니다. 왜냐하면 쉘(shell)이 이미 이것을 다룰 것이기 때문입니다.

마지막으로 switch 구문의 끝나고 우리는 SHCOLUMNINFO 구조체를 모두 채웠음을 알리기 위하여 S_OK를 반환합니다.

 

열에 데이터 출력하기

IColumnProvider의 마지막 메소드는 GetItemData입니다. 이것은 파일에 대한 데이터를 얻어서 출력하기 위해 Windows 탐색기에 의해 호출되는 메소드입니다. 이 메소드의 원형은 다음과 같습니다.

 

HRESULT IColumnProvider::GetItemData(LPCSHCOLUMNID pscid, LPCSHCOLUMNDATA pscd, VARIANT * pvarData);

 

SHCOLUMNID 구조체는 Windows 탐색기가 어떤 열의 데이터를 필요로 하는지를 알려줍니다. 또한 이 구조체는 우리가 GetColumnInfo 메소드를 통해 Windows 탐색기에게 전달해 준 정보도 포함하고 있습니다.

SHCOLUMNDATA 구조체는 파일이나 디렉토리에 대한 자세한 정보를 경로와 함께 포함하고 있습니다. 우리는 이 정보를 해당 파일 또는 디렉토리에 대한 데이터를 제공할 것인지 여부를 결정하기 위해 사용할 수 있습니다.

pvarDataVARIANT 구조체에 대한 포인터로서, Windows 탐색기를 통해 우리가 보여주고자 하는 실질적인 데이터를 보관할 것입니다. VARIANT라는 자료형은 Visual Basic과 같은 스크립트 언어들이 갖는 loosely-typed 변수의 C 언어 버전입니다. 이 구조체는 두 가지 부분으로 구성되어 있는데, 하나는 타입이고 하나는 데이터입니다. ATL은 VARIANT를 초기화하고 값을 설정하는 것과 관련해 편리하게 다룰 수 있는 CComVariant라는 클래스를 제공하고 있습니다.

 

계속 읽기

이전 게시글: Windows 쉘 익스텐션 개발 가이드 - (7) 비트맵 및 폴더 메뉴 (3/3)

다음 게시글: Windows 쉘 익스텐션 개발 가이드 - (8) 자세히 모드 (2/2)

 

'API/COM' 카테고리의 다른 글
더 보기...
태그 : 
댓글