0

我使用 miscrosoft SDK 示例通过 shell 命名空间扩展创建了一个虚拟文件夹: 在此处输入图像描述

在这个虚拟文件夹中,它有几个文件夹。其中一个文件夹是空的。我想更改空文件夹的文件夹视图的背景,例如: 在此处输入图像描述

所以对于包含文件的文件夹,显示文件,但对于空文件夹,显示“此文件夹中没有文件”。有没有办法做到这一点?我在想也许我可以 PS 一张包含文本的照片并将照片显示为空文件夹的背景照片。但是怎么做呢?在 SDK 示例代码中,他们只是使用默认的文件夹视图:

class CFolderViewCB : public IShellFolderViewCB,
public IFolderViewSettings
{
public:
CFolderViewCB() : _cRef(1) { }

// IUnknown
IFACEMETHODIMP QueryInterface(REFIID riid, void **ppv)
{
    static const QITAB qit[] =
    {
        QITABENT(CFolderViewCB, IShellFolderViewCB),
        QITABENT(CFolderViewCB, IFolderViewSettings),
        { 0 },
    };
    return QISearch(this, qit, riid, ppv);
}

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

// IShellFolderViewCB
IFACEMETHODIMP MessageSFVCB(UINT /* uMsg */, WPARAM /* wParam */, LPARAM /* lParam */)
{   
        return E_NOTIMPL;   
}

// IFolderViewSettings
IFACEMETHODIMP GetColumnPropertyList(REFIID /* riid */, void **ppv)
{
    *ppv = NULL; return E_NOTIMPL;
}
IFACEMETHODIMP GetGroupByProperty(PROPERTYKEY * /* pkey */, BOOL * /* pfGroupAscending */)
{
    return E_NOTIMPL;
}
IFACEMETHODIMP GetViewMode(FOLDERLOGICALVIEWMODE * /* plvm */)
{
    return E_NOTIMPL;
}
IFACEMETHODIMP GetIconSize(UINT * /* puIconSize */)
{
    return E_NOTIMPL;
}

IFACEMETHODIMP GetFolderFlags(FOLDERFLAGS *pfolderMask, FOLDERFLAGS *pfolderFlags);

IFACEMETHODIMP GetSortColumns(SORTCOLUMN * /* rgSortColumns */, UINT /* cColumnsIn */, UINT * /* pcColumnsOut */)
{
    return E_NOTIMPL;
}
IFACEMETHODIMP GetGroupSubsetCount(UINT * /* pcVisibleRows */)
{
    return E_NOTIMPL;
}

private:
~CFolderViewCB() { };
long _cRef;
};

// IFolderViewSettings
IFACEMETHODIMP CFolderViewCB::GetFolderFlags(FOLDERFLAGS *pfolderMask, 
FOLDERFLAGS *pfolderFlags)
{
if (pfolderMask)
{
    *pfolderMask = FWF_USESEARCHFOLDER;
}

if (pfolderFlags)
{
    *pfolderFlags = FWF_USESEARCHFOLDER;
}

return S_OK;
}

HRESULT CFolderViewCB_CreateInstance(REFIID riid, void **ppv)
{
*ppv = NULL;

HRESULT hr = E_OUTOFMEMORY;
CFolderViewCB *pfvcb = new (std::nothrow) CFolderViewCB();
if (pfvcb)
{
    hr = pfvcb->QueryInterface(riid, ppv);
    pfvcb->Release();
}
return hr;
}

- - - - - - - - - - - - - -更新 - - - - - - - - - - - --------

IFACEMETHODIMP MessageSFVCB(UINT  uMsg , WPARAM  wParam , LPARAM  lParam )
{

    std::basic_string<TCHAR> test = L"no items";

    if (uMsg == 54)
    {
        lParam = LPARAM(test.c_str());
    }

    wParam = 10;

    return S_OK;
}

根据@DenisAnisimov 的评论,当我将函数修改为上述代码时。但它不起作用。当我单击该文件夹时,Windows 资源管理器没有响应然后崩溃。------------------------------------更新第二次------------ --------

//test is a global variable of string, std::string test = "no items";
 IFACEMETHODIMP MessageSFVCB(UINT  uMsg , WPARAM  wParam , LPARAM  lParam )
 {
    if (uMsg == 54)
    {
        lParam = reinterpret_cast<LPARAM>(&test);

        wParam = sizeof(test);

        return S_OK;
    }
    return E_NOTIMPL; 
}

或者

// test is char test[9] = "no items";
IFACEMETHODIMP MessageSFVCB(UINT  uMsg , WPARAM  wParam , LPARAM  lParam )
{
    if (uMsg == 54)
    {
        lParam = reinterpret_cast<LPARAM>(&test);

        wParam = strlen(test);
        return S_OK;
    }
    return E_NOTIMPL; 
}

或者

// test is char test[9] = "no items"; 
IFACEMETHODIMP MessageSFVCB(UINT  uMsg , WPARAM  wParam , LPARAM  lParam )
{
    if (uMsg == 54)
    {
        lParam = LPARAM(test);

        wParam = strlen(test);

        return S_OK;
    }
    return E_NOTIMPL; 
}

或者

// test is char test[9] = "no items";
IFACEMETHODIMP MessageSFVCB(UINT  uMsg , WPARAM  wParam , LPARAM  lParam )
{
    test[8] = '\0';

    if (uMsg == 54)
    {
        lParam = LPARAM(test);

        wParam = strlen(test);

        return S_OK;
    }
    return E_NOTIMPL; 
}

这次空文件夹仍然没有显示任何内容,没有任何字符串作为背景。------------------------------更新第三次--------

IFACEMETHODIMP MessageSFVCB(UINT  uMsg , WPARAM  /*wParam*/ , LPARAM  lParam )
{
    char a[9] = "no items";
    a[8] = '\0';
    if (uMsg == 54)
    {
        char* s = (char*)lParam;

        memcpy(s, a, strlen(a));

        char* tt = (char*)lParam;

        s = tt;

        return S_OK;
    }
    return E_NOTIMPL; 
}

或者

IFACEMETHODIMP MessageSFVCB(UINT  uMsg , WPARAM  /*wParam*/ , LPARAM  lParam )
{
    char* a = (char*)malloc(sizeof(char) * 10);

    memset(a, 0, sizeof(char) * 10);

    a = "no items";


    if (uMsg == 54)
    {
        char* s = (char*)lParam;

        memcpy(s, a, strlen(a));

        char* tt = (char*)lParam;

        s = tt;

        return S_OK;
    }
    return E_NOTIMPL; 
}

这次我通过添加断点来调试它char* tt = (char*)lParam;tt确实变成了“无项目”。但它在后台显示错误的字符串:

在此处输入图像描述

---------------------------------------最终更新------这次成功了!

//wchar_t test[9] = L"no items";
IFACEMETHODIMP MessageSFVCB(UINT  uMsg , WPARAM  /*wParam*/ , LPARAM  lParam )
{

    if (uMsg == 54)
    {
        wchar_t* s = (wchar_t*)lParam;

        memcpy(s, test, 18);
        return S_OK;
    }
    return E_NOTIMPL; 
}
4

1 回答 1

0

当您为 IID_IShellView调用IShellFolder::CreateViewObject时,您可以返回一个自定义的IShellView实现(您还必须实现IOleWindow),而不是默认的(通常来自调用 SHCreateShellFolderView 函数)。

您的自定义实现只需要实现CreateViewWindow, DestroyViewWindow, 和 IOleWindow 的GetWindow方法即可(对于其他方法,您可以返回 E_NOTIMPL)

于 2018-02-20T07:07:35.120 回答