개발시 네임 스페이스 확장이 있는데 확장 프로그램 내에서 프로그래밍 방식으로 폴더를 추가하지 못했습니다. 툴바 버튼을 클릭하면 파일 경로가 선택되고 그 파일은 가상 폴더 및 파일이 생성 된 데이터 소스입니다.네임 스페이스 확장 내에서 탐색기보기에 가상 폴더 (IShellFolder)를 추가하려면 어떻게합니까?
툴바의로드 파일 버튼이 네임 스페이스 확장 루트 내에 있으므로 새로운 가상 폴더가 자동으로 나타나기를 원합니다. 폴더를 표시하려면 트리보기를 클릭하거나 루트에서 나가서 다시 들어 와야합니다. 그러면 폴더가 나타납니다.
이 문제를 조사한 결과 일반적으로 사람들이 SHChangeNotify를 사용하고있을 때이를 조사했습니다. 아래 예제와 같이 경로 또는 pidl을 네임 스페이스 확장 루트에서 제공하는 등의 다양한 조합을 사용했습니다. 아래 예제에서는 해당 경로의 pidl을 사용하여 (SHChangeNotify에서 적절한 플래그로) 새 폴더를 포함하고 여전히 주사위가 없습니다. 또한 xxx는 모든 플래그를 알리는 SHCNE_xxx를 시도했습니다. SHChangeNotify (SHCNE_UPDATEDIR, SHCNF_IDLIST, retPidl, 0);
보기 창을 마우스 오른쪽 버튼으로 클릭하고 새로 고침을 선택해도 표시 할 폴더를 호출하지 않습니다.
폴더의 경로를 가져 오는 코드에서 내 폴더의 BindToObject를 호출 한 다음 EnumObjects 및 다음으로 중단 점에 도달하지 않았습니다. 트리보기를 클릭하거나 폴더 위로 이동하여 다시 중단하면 모든 중단 점이 나타납니다. SHChangeNotify는 중단 점을 호출하지 않습니다. ShellVolderView 클래스의
if (IID_IShellView == riid) {
SFV_CREATE csfv = {0};
csfv.cbSize = sizeof(SFV_CREATE);
hr = QueryInterface(IID_PPV_ARGS(&csfv.pshf));
if (SUCCEEDED(hr)) {
hr = CShellFolderView_CreateInstance(IID_PPV_ARGS(&csfv.psfvcb));
if (SUCCEEDED(hr)) {
hr = SHCreateShellFolderView(&csfv, (IShellView**)ppv);
csfv.psfvcb->Release();
m_hWnd = hwndOwner;
}
csfv.pshf->Release();
}
}
, 나는 알림 플래그에 BP를 설정하고 그들이 공격하지 :
뷰는과 같이 CreateViewObject에 SHCreateShellFolderView을 사용하여 만들어집니다. S_OK를 반환하는 것은 SFVM_UPDATEOBJECT에 필요하므로 추가했습니다.
IFACEMETHODIMP CShellFolderView::MessageSFVCB(UINT uMsg, WPARAM wParam, LPARAM lParam) {
HRESULT hr = E_NOTIMPL;
switch(uMsg) {
case SFVM_GETSORTDEFAULTS:
wParam = (WPARAM)(int*)-1;
lParam = (LPARAM)(int*)Col::Size;
hr = S_OK;
break;
case SFVM_GETNOTIFY:
*((LONG*)lParam) = SHCNE_ALLEVENTS;
hr = S_OK;
break;
}
return hr;
}
* 편집 : 용의자 기능을 추가. * ppidl이 NULL이면 E_INVALIDARG가 반환됩니다.
STDMETHODIMP CShellFolder::ParseDisplayName(HWND hwnd, IBindCtx *pbc, LPWSTR pszDisplayName, ULONG *pchEaten, PIDLIST_RELATIVE *ppidl, ULONG *pdwAttributes) {
HRESULT hr = E_INVALIDARG;
if (pszDisplayName && *ppidl) {
WCHAR szNameComponent[MAX_SIZE] = {};
PWSTR pszNext = PathFindNextComponent(pszDisplayName);
if (pszNext && *pszNext) {
// unsure of max length, can't use StringCchLength for this
size_t len = lstrlen(pszDisplayName);
size_t nextLen = 0;
StringCchLength(pszNext, MAX_SIZE, &nextLen);
hr = StringCchCopyN(szNameComponent, MAX_SIZE, pszDisplayName, len - nextLen);
}
else {
hr = StringCchCopy(szNameComponent, MAX_SIZE, pszDisplayName);
}
if (SUCCEEDED(hr)) {
PathRemoveBackslash(szNameComponent);
PIDLIST_RELATIVE pidlCurrent = NULL;
LPPIDLDATA child = m_pPidlMgr->GetSubItemFromPidl((LPCITEMIDLIST)ppidl);
hr = m_pPidlMgr->Create(&pidlCurrent, child);
if (SUCCEEDED(hr)) {
if (pszNext && *pszNext) {
IShellFolder *psf;
hr = BindToObject(pidlCurrent, pbc, IID_PPV_ARGS(&psf));
if (SUCCEEDED(hr)) {
PIDLIST_RELATIVE pidlNext = NULL;
hr = psf->ParseDisplayName(hwnd, pbc, pszNext, pchEaten, &pidlNext, pdwAttributes);
if (SUCCEEDED(hr)) {
*ppidl = ILCombine(pidlCurrent, pidlNext);
ILFree(pidlNext);
}
psf->Release();
}
ILFree(pidlCurrent);
}
else {
*ppidl = pidlCurrent;
}
}
}
}
return hr;
}
폴더를 프로그래밍 방식으로 표시하려면 어떤 단계를 수행해야합니까?
SHCNE_UDPATEDIR가 말한다 그러나 존재하지 않기 때문에'thenewfoldername '을 아무도보고 있지 않습니다. 설명서에 "폴더를 만들거나 삭제하거나 이름을 변경 한 경우 SHCNE_MKDIR, SHCNE_RMDIR 또는 SHCNE_RENAMEFOLDER를 각각 사용하십시오." –
네임 스페이스 확장 데이터 소스는 SHITEMIDLIST와는 별도의 트리 구조입니다. 루트에서 다른 분기를 추가하고 SHChangeNotify를 올바르게 (감사합니다) 호출하도록 데이터 소스 트리를 업데이트 한 후 Shell을 호출하여 IShellFolder2 :: EnumObjects()를 호출하도록 다른 단계를 수행해야합니까? –
만들어진 각 디렉터리에 대해 하나의 SHCNE_MKDIR을 발생시킵니다. 하위 서브 디렉토리를 만든 경우, 첫 번째 레벨 디렉토리에 대해 한 번, 두 번째 레벨 디렉토리에 대해 한 번 두 번 올리는 것입니다. –