본문 바로가기
WinAPI

IFIleDialog사용하여 탐색기 보기 모드 설정 아이콘으로하기

by juheeL 2022. 12. 20.

간단 결론 :

IFileDialogEvents::OnFolderChange에 보기설정을 아이콘으로 하면 된다.

(SetCurrentViewMode - FVM_ICON)

(크기설정까지 SetViewModeAndIconSize)

 

간단 코드 : 

OnFolderChange 정의

IFACEMETHODIMP CDialogEventHandler::OnFolderChanging(IFileDialog *, IShellItem *) 
{
	IServiceProvider *psp = nullptr;
    IFolderView *pfv = nullptr;
    
    HRESULT hr = pfd->QueryInterface(IID_PPV_ARGS(&psp));
    do
    {
    	if(FAILED(hr)) break;
        hr = psp->QueryService(SID_SFolderView, &pfv);
        if(FAILED(hr)) break;
        pfv->SerCurrentViewMode(FVM_ICON); // 아이콘 보기 설정
        
        // 더 자세하게 크기 설정을 하고 싶으면,
        IFolderView2 *pfv2 = nullptr;
        pfv->QueryInterface(*pfv2);
        pfv2->SetViewModeAndIconSize(FVM_ICON, 48);
    }while(flase);
    
    if(nullptr != pfv) pfv->Release();
    if(nullptr != psp)psp->Release();
	return hr;
}

 

OnFolderChange 선언

 

class CDialogEventHandler : public IFileDialogEvents,
{
public:
    // IUnknown methods
    IFACEMETHODIMP QueryInterface(REFIID riid, void** ppv)
    {
        static const QITAB qit[] = {
            QITABENT(CDialogEventHandler, IFileDialogEvents),
            { 0 },
#pragma warning(suppress:4838)
        };
        return QISearch(this, qit, riid, ppv);
    }

    IFACEMETHODIMP_(ULONG) AddRef()
    {
        return InterlockedIncrement(&_cRef);
    }

    IFACEMETHODIMP_(ULONG) Release()
    {
        long cRef = InterlockedDecrement(&_cRef);
        if (!cRef)
            delete this;
        return cRef;
    }

    // IFileDialogEvents methods
    IFACEMETHODIMP OnFileOk(IFileDialog *) { return S_OK; };
    IFACEMETHODIMP OnFolderChange(IFileDialog *) { return S_OK; };
    IFACEMETHODIMP OnFolderChanging(IFileDialog *, IShellItem *) { return S_OK; };
    IFACEMETHODIMP OnHelp(IFileDialog *) { return S_OK; };
    IFACEMETHODIMP OnSelectionChange(IFileDialog *) { return S_OK; };
    IFACEMETHODIMP OnShareViolation(IFileDialog *, IShellItem *, FDE_SHAREVIOLATION_RESPONSE *) { return S_OK; };
    IFACEMETHODIMP OnTypeChange(IFileDialog *pfd);
    IFACEMETHODIMP OnOverwrite(IFileDialog *, IShellItem *, FDE_OVERWRITE_RESPONSE *) { return S_OK; };
    
    CDialogEventHandler() : _cRef(1) { };
private:
    ~CDialogEventHandler() { };
    long _cRef;
};

 

실제 사용 코드 전체

class CDialogEventHandler : public IFileDialogEvents,
{
public:
    // IUnknown methods
    IFACEMETHODIMP QueryInterface(REFIID riid, void** ppv)
    {
        static const QITAB qit[] = {
            QITABENT(CDialogEventHandler, IFileDialogEvents),
            { 0 },
#pragma warning(suppress:4838)
        };
        return QISearch(this, qit, riid, ppv);
    }

    IFACEMETHODIMP_(ULONG) AddRef()
    {
        return InterlockedIncrement(&_cRef);
    }

    IFACEMETHODIMP_(ULONG) Release()
    {
        long cRef = InterlockedDecrement(&_cRef);
        if (!cRef)
            delete this;
        return cRef;
    }

    // IFileDialogEvents methods
    IFACEMETHODIMP OnFolderChanging(IFileDialog *, IShellItem *);
    IFACEMETHODIMP OnFileOk(IFileDialog *) { return S_OK; };
    IFACEMETHODIMP OnFolderChange(IFileDialog *) { return S_OK; };
    IFACEMETHODIMP OnHelp(IFileDialog *) { return S_OK; };
    IFACEMETHODIMP OnSelectionChange(IFileDialog *) { return S_OK; };
    IFACEMETHODIMP OnShareViolation(IFileDialog *, IShellItem *, FDE_SHAREVIOLATION_RESPONSE *) { return S_OK; };
    IFACEMETHODIMP OnTypeChange(IFileDialog *pfd);
    IFACEMETHODIMP OnOverwrite(IFileDialog *, IShellItem *, FDE_OVERWRITE_RESPONSE *) { return S_OK; };

    CDialogEventHandler() : _cRef(1) { };
private:
    ~CDialogEventHandler() { };
    long _cRef;
};

IFACEMETHODIMP CDialogEventHandler::OnFolderChanging(IFileDialog *, IShellItem *) 
{
	IServiceProvider *psp = nullptr;
    IFolderView *pfv = nullptr;
    
    HRESULT hr = pfd->QueryInterface(IID_PPV_ARGS(&psp));
    do
    {
    	if(FAILED(hr)) break;
        hr = psp->QueryService(SID_SFolderView, &pfv);
        if(FAILED(hr)) break;
        pfv->SerCurrentViewMode(FVM_ICON);
    }while(flase);
    
    if(nullptr != pfv) pfv->Release();
    if(nullptr != psp)psp->Release();
	return hr;
}

HRESULT CDialogEventHandler_CreateInstance(REFIID riid, void **ppv)
{
    *ppv = NULL;
    CDialogEventHandler *pDialogEventHandler = new (std::nothrow) CDialogEventHandler();
    HRESULT hr = pDialogEventHandler ? S_OK : E_OUTOFMEMORY;
    if (SUCCEEDED(hr))
    {
        hr = pDialogEventHandler->QueryInterface(riid, ppv);
        pDialogEventHandler->Release();
    }
    return hr;
}

HRESULT BasicFileOpen()
{
    // CoCreate the File Open Dialog object.
    IFileDialog *pfd = NULL;
    HRESULT hr = CoCreateInstance(CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pfd));
    if (SUCCEEDED(hr))
    {
        // Create an event handling object, and hook it up to the dialog.
        IFileDialogEvents *pfde = NULL;
        hr = CDialogEventHandler_CreateInstance(IID_PPV_ARGS(&pfde));
        if (SUCCEEDED(hr))
        {
            // Hook up the event handler.
            DWORD dwCookie;
            hr = pfd->Advise(pfde, &dwCookie);
            
        	//이후 파일 오픈 작업 하면 됨

 

아래 링크가 정말 큰 도움이 됐다.

영어때문에 스킵했다가 결국 다 해석하고 힌트 얻어서 해결했네... 영어공부합시다.

https://social.msdn.microsoft.com/Forums/sqlserver/en-US/a4746d64-12c9-4bd3-a8b2-de6478e550f4/initialize-view-context-in-filedialog?forum=windowsgeneraldevelopmentissues 

 

위 링크랑

아래  msdn에서 코드 예시로 올려준거 보고 참고해서 해결.

https://github.com/microsoft/Windows-classic-samples/blob/main/Samples/Win7Samples/winui/shell/appplatform/commonfiledialog/CommonFileDialogApp.cpp

 

그 외 참고 링크들

IFIleDialog
일반 항목 대화 상자
https://learn.microsoft.com/ko-kr/windows/win32/shell/common-file-dialog
IFIleDialog
인터페이스
https://learn.microsoft.com/ko-kr/windows/win32/api/shobjidl_core/nn-shobjidl_core-ifiledialog
IFIleDialogEvent
인터페이스
https://learn.microsoft.com/ko-kr/windows/win32/api/shobjidl_core/nn-shobjidl_core-ifiledialogevents
IFolderView2
인터페이스
https://learn.microsoft.com/ko-kr/windows/win32/api/shobjidl_core/nn-shobjidl_core-ifolderview2

 

 

 

결국

위 IFileDialogEvents::OnFolderChange 함수를 IFIleDialog에 설정해두고,

OnFolderChange에서 SetViewModeAndIconSize함수를 사용하거나, SetCurrentViewMode를 사용하면 가능하다.

 

'WinAPI' 카테고리의 다른 글

pow()  (0) 2022.09.19
GetLocaleInfo 함수  (0) 2017.07.12