📄 pidlmgr.cpp
字号:
/******************************************************************
*
* Project.....: Windows View (Namespace Extension)
*
* Application.: WINVIEW.dll
* Module......: PidlMgr.cpp
* Description.: PIDL implementation
*
* Compiler....: MS Visual C++
* Written by..: D. Esposito
*
* Environment.: Windows 9x/NT
*
*******************************/
#include "PidlMgr.h"
#include "ShlFldr.h"
#include "resource.h"
/*---------------------------------------------------------------*/
// Constructor and destructor
/*---------------------------------------------------------------*/
CPidlMgr::CPidlMgr()
{
if( FAILED(SHGetMalloc(&m_pMalloc)) )
delete this;
g_DllRefCount++;
}
CPidlMgr::~CPidlMgr()
{
if( m_pMalloc )
m_pMalloc->Release();
g_DllRefCount--;
}
/*
Our PIDL are simply given by the HWND.
*/
/*---------------------------------------------------------------*/
// CPidlMgr::Create( HWND )
// Create a new PIDL using the HWND
/*---------------------------------------------------------------*/
LPITEMIDLIST CPidlMgr::Create(HWND hwnd)
{
// Global size of the PIDL, including SHITEMID
USHORT uSize = sizeof(ITEMIDLIST) + sizeof(PIDLDATA);
// Also allocate memory for the final, null, ITEMIDLIST
// Note that we must use IMalloc to get new memory
LPITEMIDLIST pidlOut = reinterpret_cast<LPITEMIDLIST>(
m_pMalloc->Alloc(uSize + sizeof(ITEMIDLIST)));
if(pidlOut)
{
LPITEMIDLIST pidlTemp = pidlOut;
// Prepares the PIDL to be filled with actual data
pidlTemp->mkid.cb = uSize;
LPPIDLDATA pData = reinterpret_cast<LPPIDLDATA>(pidlTemp->mkid.abID);
// Fill the PIDL
pData->hwnd = hwnd;
//
// Add more fields here if required...
//
// A PIDL of size 0 means the end of the chain
pidlTemp = GetNextItem(pidlTemp);
pidlTemp->mkid.cb = 0;
pidlTemp->mkid.abID[0] = 0;
}
return pidlOut;
}
/*---------------------------------------------------------------*/
// CPidlMgr::Delete( LPITEMIDLIST )
// Delete a PIDL
/*---------------------------------------------------------------*/
void CPidlMgr::Delete(LPITEMIDLIST pidl)
{
m_pMalloc->Free(pidl);
}
/*---------------------------------------------------------------*/
// CPidlMgr::GetNextItem( LPCITEMIDLIST )
// Retrieves the next element in a ITEMIDLIST
/*---------------------------------------------------------------*/
LPITEMIDLIST CPidlMgr::GetNextItem(LPCITEMIDLIST pidl)
{
if(pidl)
return reinterpret_cast<LPITEMIDLIST>(
(reinterpret_cast<LPBYTE>(const_cast<LPITEMIDLIST>(pidl))) + pidl->mkid.cb);
else
return NULL;
}
/*---------------------------------------------------------------*/
// CPidlMgr::GetLastItem( LPCITEMIDLIST )
// Retrieves the last element in a ITEMIDLIST
/*---------------------------------------------------------------*/
LPITEMIDLIST CPidlMgr::GetLastItem(LPCITEMIDLIST pidl)
{
LPITEMIDLIST pidlLast = NULL;
// Get the PIDL of the last item in the list
if(pidl)
{
while(pidl->mkid.cb)
{
pidlLast = const_cast<LPITEMIDLIST>(pidl);
pidl = GetNextItem(pidl);
}
}
return pidlLast;
}
/*---------------------------------------------------------------*/
// CPidlMgr::GetSize( LPITEMIDLIST )
// Retrieves the size of item list
/*---------------------------------------------------------------*/
UINT CPidlMgr::GetSize(LPCITEMIDLIST pidl)
{
UINT cbTotal = 0;
LPITEMIDLIST pidlTemp = (LPITEMIDLIST) pidl;
if( pidlTemp )
{
while(pidlTemp->mkid.cb)
{
cbTotal += pidlTemp->mkid.cb;
pidlTemp = GetNextItem(pidlTemp);
}
// add the size of the NULL terminating ITEMIDLIST
cbTotal += sizeof(ITEMIDLIST);
}
return cbTotal;
}
/*---------------------------------------------------------------*/
// CPidlMgr::GetData(LPCITEMIDLIST)
// Retrieves the HWND of a given PIDL (last element)
/*---------------------------------------------------------------*/
HWND CPidlMgr::GetData(LPCITEMIDLIST pidl)
{
if(!pidl)
return NULL;
// Get the last item of the PIDL to make sure we get the right HWND
// in case of multiple nesting levels
LPITEMIDLIST p = GetLastItem(pidl);
LPPIDLDATA pData = reinterpret_cast<LPPIDLDATA>(p->mkid.abID);
return pData->hwnd;
}
/*---------------------------------------------------------------*/
// CPidlMgr::Copy( LPITEMIDLIST )
// Duplicates a PIDL
/*---------------------------------------------------------------*/
LPITEMIDLIST CPidlMgr::Copy( LPCITEMIDLIST pidlSource )
{
LPITEMIDLIST pidlTarget = NULL;
UINT cbSource = 0;
if( NULL==pidlSource )
return NULL;
// allocate memory for the new PIDL
cbSource = GetSize( pidlSource );
pidlTarget = (LPITEMIDLIST)m_pMalloc->Alloc( cbSource );
if( !pidlTarget )
return NULL;
// source to target
CopyMemory( pidlTarget, pidlSource, cbSource );
return pidlTarget;
}
/*---------------------------------------------------------------*/
// CPidlMgr::HasChildren( HWND )
// Verifies whether a given window has children
/*---------------------------------------------------------------*/
BOOL CPidlMgr::HasChildren( HWND hWnd )
{
// Determine whether a window has children
HWND h = GetWindow( hWnd, GW_CHILD );
return (h != NULL);
}
/*---------------------------------------------------------------*/
// CPidlMgr::HasChildrenOfChildren( HWND )
// Verifies whether a given window has children
/*---------------------------------------------------------------*/
BOOL CPidlMgr::HasChildrenOfChildren(HWND hWnd)
{
// Determine whether a window has children
BOOL b = FALSE;
// Enumerating windows is a process that scans all the windows that
// belong to the sub-tree whose root is hWnd. We need to stop the
// process when the first grandchild is found.
// For this reason, we need a return value from the enumeration function,
// and because this return value depends upon what the callback finds,
// we can't use the standard retval. That's why I'm passing a pointer.
EnumChildWindows(hWnd, WindowHasChildren, reinterpret_cast<LPARAM>(&b));
return b;
}
/*---------------------------------------------------------------*/
// CPidlMgr::GetDataPointer( LPCITEMIDLIST )
// Internal routine that returns the HWND from a PIDL
/*---------------------------------------------------------------*/
HWND CPidlMgr::GetDataPointer(LPCITEMIDLIST pidl)
{
if(!pidl)
return NULL;
LPPIDLDATA pData;
pData = (LPPIDLDATA)(pidl->mkid.abID);
return pData->hwnd;
}
/*---------------------------------------------------------------*/
// CPidlMgr::GetPidlPath( LPITEMIDLIST, LPTSTR)
// Sets the text to be returned to identify the item
/*---------------------------------------------------------------*/
DWORD CPidlMgr::GetPidlPath(LPCITEMIDLIST pidl, LPTSTR lpszOut)
{
HWND hwnd = GetData(pidl);
TCHAR szClass[100], szTitle[100];
GetWindowText(hwnd, szTitle, 100);
GetClassName(hwnd, szClass, 100);
// Add a description to the desktop window (of class "#32769")
if(!lstrcmpi(szClass, __TEXT("#32769")))
lstrcpy(szClass, __TEXT("Desktop"));
// Return a string in the form "title [class]"
if(lstrlen(szTitle))
wsprintf(lpszOut, __TEXT("%s [%s]"), szTitle, szClass);
else
wsprintf(lpszOut, __TEXT("[%s]"), szClass);
// Return the size of the string
return lstrlen(lpszOut);
}
/*---------------------------------------------------------------*/
// CPidlMgr::WindowHasChildren( HWND,LPARAM )
// Verifies whether the window has children
/*---------------------------------------------------------------*/
BOOL CPidlMgr::WindowHasChildren(HWND hwnd, LPARAM lParam)
{
BOOL* pB = reinterpret_cast<BOOL*>(lParam);
// If the window is a child window then the returned HWND isn't NULL
HWND h = GetWindow(hwnd, GW_CHILD);
*pB = (h != NULL); // TRUE if at least one grandchild exists
return(h == NULL); // Needs to return FALSE to stop enumeration
}
/* End of file: PidlMgr.cpp */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -