Я использовал пример miscrosoft SDK для создания виртуальной папки по расширению пространства имен оболочки:
В этой виртуальной папке есть несколько папок. Одна из папок пуста.
Я хочу изменить фон для представления папки пустой папки, например:
Поэтому для папок, которые содержат файлы, отобразите файлы, а для пустой папки — «Нет файлов в этой папке».
Есть ли способ сделать это?
Я думаю, может быть, я могу 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 Explorer не отвечает, а затем происходит сбой.
———————— 2-е обновление ———————— ——-
//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;
}
На этот раз пустая папка по-прежнему ничего не показывает, никаких строк в качестве фона.
—————————— обновление 3-е ——————
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;
}
Когда тебя зовут IShellFolder :: CreateViewObject для IID_IShellView вы можете вернуть пользовательский IShellView реализация (вы также должны реализовать IOleWindow) вместо значения по умолчанию (обычно получаемого при вызове функции SHCreateShellFolderView).
Ваша пользовательская реализация должна только реализовать CreateViewWindow
, DestroyViewWindow
и IOleWindow’s GetWindow
методы для начала (для других методов вы можете вернуть E_NOTIMPL)
Других решений пока нет …