头文件:
//用户索引: 假使桌面有N个图标, 则桌面从左到右,从上到下,分配从0到N-1的索引。
//系统索引: 桌面的N个图标,对应着桌面的listview控件中的N个ITEM,该索引用于控制该控件中的ITEM
#ifndef __SETICONPOS_H__
#define __SETICONPOS_H__
#include <map>
#include <list>
#include <string>
#include <tchar.h>
#include <Windows.h>
class CSetIconPath
{
public:
CSetIconPath();
virtual ~CSetIconPath();
private:
CSetIconPath(const CSetIconPath&);
void operator=(const CSetIconPath&);
private:
//获取桌面listview控件的句柄
HWND GetDesktopListView();
//获取桌面排列方式
void GetDesktopArrangeMode();
//获取系统索引与图标的映射和图标列表
void GetSysIndexMap(HWND hwndSysListView32,
std::map<DWORD,std::pair<std::wstring,POINT>*>& SysIndexMapIcon);
//获取用户索引与图标的映射、用户索引跟系统索引的映射、图标列表
void GetUserIndexMap(const std::map<DWORD,std::pair<std::wstring,POINT>*> &SysIndexMapIcon,
std::map<DWORD,std::pair<std::wstring,POINT>*> &UserIndexMapIcon,
std::map<DWORD,DWORD> &UserIndexMapSysIndex,
std::list<std::pair<std::wstring,POINT>*> &IconList);
//根据用户索引图标映射,判断图标要移动的目标位置
UINT32 GetDesUserIndex(const std::map<DWORD,std::pair<std::wstring,POINT>*> &UserIndexMapIcon);
//用于m_iconList的排序,由此而获得UserIndex
static bool UserIndexSort(std::pair<std::wstring,POINT>* &p1, std::pair<std::wstring,POINT>* &p2);
enum MOVE_MODE{
MOVE_UP_1_PIX, //移动到目标位置向上一个像素
MOVE_EXACT, //移动到目标位置上
MOVE_DOWN_1_PIX//移动到目标位置向下一个像素点
};
//移动SRC用户索引图标到DES用户索引图标的位置上
void MoveSetp(UINT32 SrcUserIndex,UINT32 DesUserIndex, MOVE_MODE mode=MOVE_EXACT);
void Shell_MoveStep(UINT32 SrcUserIndex,UINT32 DesUserIndex, MOVE_MODE mode=MOVE_EXACT);
//实现移动图标的具体操作
void MoveIconPos(UINT32 SrcUserIndex,UINT32 DesUserIndex);
private:
//要移动的图标的用户索引
UINT32 m_nSelfUserIndex;
//要移动的目标位置的用户索引
UINT32 m_nDesUserIndex;
//桌面listview控件的句柄
HWND m_hwndSysListView32;
//用户索引跟系统索引的映射
std::map<DWORD,DWORD> m_UserIndexMapSysIndex;
//桌面图标列表
std::list<std::pair<std::wstring,POINT>*> m_iconList;
//用户索引与桌面图标的映射
std::map<DWORD,std::pair<std::wstring,POINT>*> m_UserIndexMapIcon;
//系统索引与桌面图标的映射
std::map<DWORD,std::pair<std::wstring,POINT>*> m_SysIndexMapIcon;
//是否自动排列图标;
bool m_bAutoArrange;
//是否对其到网格
bool m_bSnapToGrid;
};
#endif
cpp文件:
#include "SetIconPos.h"
#include <CommCtrl.h>
CSetIconPath::CSetIconPath():
m_nSelfUserIndex(-1),
m_nDesUserIndex(-1),
m_hwndSysListView32(NULL),
m_bSnapToGrid(false),
m_bAutoArrange(false)
{};
CSetIconPath::~CSetIconPath()
{
for (std::list<std::pair<std::wstring,POINT>*>::iterator iter = m_iconList.begin();
iter!=m_iconList.end();
++iter)
{
delete (std::pair<std::wstring,POINT>*)(*iter);
}
}
UINT32 CSetIconPath::GetDesUserIndex(const std::map<DWORD,std::pair<std::wstring,POINT>*> &UserIndexMapIcon)
{
return 2;
}
bool CSetIconPath::UserIndexSort(std::pair<std::wstring,POINT>* &p1, std::pair<std::wstring,POINT>* &p2)
{
if (p1->second.x<p2->second.x)
{
return true;
}
else if (p1->second.x==p2->second.x)
{
return p1->second.y<p2->second.y;
}
else
{
return false;
}
}
void CSetIconPath::GetUserIndexMap(const std::map<DWORD,std::pair<std::wstring,POINT>*> &SysIndexMapIcon,
std::map<DWORD,std::pair<std::wstring,POINT>*> &UserIndexMapIcon,
std::map<DWORD,DWORD> &UserIndexMapSysIndex,
std::list<std::pair<std::wstring,POINT>*> &IconList)
{
UserIndexMapIcon.clear();
UserIndexMapSysIndex.clear();
IconList.clear();
std::map<std::pair<std::wstring,POINT>*,DWORD> IconMapSysIndex;
for (std::map<DWORD,std::pair<std::wstring,POINT>*>::const_iterator citer = SysIndexMapIcon.begin();
citer!=SysIndexMapIcon.end();
++citer)
{
IconList.push_back(citer->second);
IconMapSysIndex[citer->second] = citer->first;
}
IconList.sort(CSetIconPath::UserIndexSort);
DWORD dwUserIndex = -1;
for (std::list<std::pair<std::wstring,POINT>*>::const_iterator citer=IconList.begin();
citer!=IconList.end();
++citer)
{
UserIndexMapIcon[++dwUserIndex] = *citer;
UserIndexMapSysIndex[dwUserIndex] = IconMapSysIndex[*citer];
}
};
HWND CSetIconPath::GetDesktopListView()
{
HWND hwndParent = NULL;
HWND hwndSHELLDLL_DefView = NULL;
HWND hwndSysListView32 = NULL;
hwndParent = ::FindWindowEx(NULL, hwndParent, _T("progman"), _T("program manager"));
if (!(hwndSHELLDLL_DefView = ::FindWindowEx(hwndParent,hwndSHELLDLL_DefView, _T("shelldll_defview"), NULL ))||\
!(hwndSysListView32 = ::FindWindowEx( hwndSHELLDLL_DefView, NULL, _T("syslistview32"), _T("folderview") )))
{
hwndParent = ::FindWindowEx(NULL, NULL, _T("workerw"), NULL );
hwndSHELLDLL_DefView = NULL;
hwndSysListView32 = NULL;
do
{
hwndSHELLDLL_DefView = ::FindWindowEx(hwndParent,hwndSHELLDLL_DefView, _T( "shelldll_defview"), NULL );
if (!hwndSHELLDLL_DefView)
continue;
hwndSysListView32 = ::FindWindowEx( hwndSHELLDLL_DefView, NULL, _T("syslistview32"), _T("folderview") );
if (!hwndSysListView32)
continue;
else
break;
}while(hwndParent=::FindWindowEx(NULL, hwndParent, _T("workerw"), NULL ));
}
return hwndSysListView32;
}
void CSetIconPath::GetSysIndexMap(HWND hwndSysListView32,
std::map<DWORD,std::pair<std::wstring,POINT>*>& SysIndexMapIcon)
{
SysIndexMapIcon.clear();
DWORD dwPid = 0;
GetWindowThreadProcessId(hwndSysListView32,&dwPid);
HANDLE hProcess=OpenProcess(PROCESS_VM_READ|PROCESS_VM_OPERATION|PROCESS_VM_WRITE,false,dwPid);
if (hProcess==INVALID_HANDLE_VALUE)
{
return ;
}
DWORD dwIconCount = ListView_GetItemCount(hwndSysListView32);
LVITEM *plvitem=(LVITEM*)VirtualAllocEx(hProcess, NULL, sizeof(LVITEM),MEM_COMMIT, PAGE_READWRITE);
TCHAR *pszName=(TCHAR*)VirtualAllocEx(hProcess, NULL, MAX_PATH*sizeof(TCHAR),MEM_COMMIT, PAGE_READWRITE);
POINT *ppt=(POINT*)VirtualAllocEx(hProcess, NULL, sizeof(POINT),MEM_COMMIT, PAGE_READWRITE);
LVITEM lv={0};
lv.cchTextMax=MAX_PATH*sizeof(TCHAR);
lv.pszText=pszName;
WriteProcessMemory(hProcess,plvitem,&lv,sizeof(LVITEM),NULL);
TCHAR szName[MAX_PATH];
POINT pt={0};
for (DWORD dwIndex=0;dwIndex<dwIconCount;++dwIndex)
{
SendMessage(hwndSysListView32,LVM_GETITEMTEXT,dwIndex,(LPARAM)plvitem);
ReadProcessMemory(hProcess,pszName,szName,sizeof(szName),NULL);
SendMessage(hwndSysListView32,LVM_GETITEMPOSITION,dwIndex,(LPARAM)ppt);
ReadProcessMemory(hProcess,ppt,&pt,sizeof(POINT),NULL);
SysIndexMapIcon[dwIndex] = new std::pair<std::wstring,POINT>(std::make_pair(std::wstring(szName),pt));;
}
VirtualFreeEx(hProcess, plvitem, 0, MEM_RELEASE);
VirtualFreeEx(hProcess, pszName, 0, MEM_RELEASE);
VirtualFreeEx(hProcess, ppt, 0, MEM_RELEASE);
CloseHandle(hProcess);
}
void CSetIconPath::MoveSetp(UINT32 SrcUserIndex,UINT32 DesUserIndex, MOVE_MODE mode)
{
std::map<DWORD,DWORD>::iterator iter1 = m_UserIndexMapSysIndex.find(SrcUserIndex);
std::map<DWORD,std::pair<std::wstring,POINT>*>::iterator iter2 = m_UserIndexMapIcon.find(DesUserIndex);
if (iter1==m_UserIndexMapSysIndex.end()||
iter2==m_UserIndexMapIcon.end())
{
return ;
}
UINT32 nSrcSysIndex = iter1->second;
POINT pt = iter2->second->second;
if (mode==MOVE_UP_1_PIX)
{
pt.y-=1;
}
else if (mode==MOVE_DOWN_1_PIX)
{
pt.y+=1;
}
ListView_SetItemPosition(m_hwndSysListView32,nSrcSysIndex,pt.x,pt.y);
}
//void CSetIconPath::Shell_MoveStep(UINT32 SrcUserIndex,UINT32 DesUserIndex, MOVE_MODE mode)
//{
// std::map<DWORD,std::pair<std::wstring,POINT>*>::iterator iterSrc = m_UserIndexMapIcon.find(SrcUserIndex);
// std::map<DWORD,std::pair<std::wstring,POINT>*>::iterator iterDes = m_UserIndexMapIcon.find(DesUserIndex);
// if (iterSrc==m_UserIndexMapIcon.end()||
// iterDes==m_UserIndexMapIcon.end())
// {
// return ;
// }
//}
void CSetIconPath::GetDesktopArrangeMode()
{
#ifndef LVS_EX_SNAPTOGRID
#define LVS_EX_SNAPTOGRID 0x00080000
#endif
DWORD dwIconCount = ListView_GetItemCount(m_hwndSysListView32);
DWORD dwStyle = GetWindowLong(m_hwndSysListView32,GWL_STYLE);
DWORD dwExStyle = ListView_GetExtendedListViewStyle(m_hwndSysListView32);
m_bAutoArrange = ((dwStyle&LVS_AUTOARRANGE)==LVS_AUTOARRANGE);
m_bSnapToGrid = ((dwExStyle&LVS_EX_SNAPTOGRID)==LVS_EX_SNAPTOGRID);
}
void CSetIconPath::MoveIconPos(UINT32 SrcUserIndex,UINT32 DesUserIndex)
{
SendMessage(m_hwndSysListView32, WM_SETREDRAW, FALSE, 0);
if (m_nSelfUserIndex<m_nDesUserIndex) //move backward
{
//1.move (nSelf+1)~nPos forward
//2.move self to des
UINT32 nStart = 0;
if (m_bSnapToGrid)
{
nStart = m_nSelfUserIndex+1;
for (;nStart<=m_nDesUserIndex;++nStart)
{
MoveSetp(nStart,nStart-1,MOVE_UP_1_PIX);
if (nStart==m_nDesUserIndex)
{
break;
}
}
MoveSetp(m_nSelfUserIndex,m_nDesUserIndex,MOVE_EXACT);
}
else
{
nStart = m_nSelfUserIndex+1;
for (;nStart<=m_nDesUserIndex;++nStart)
{
MoveSetp(nStart,nStart-1,MOVE_EXACT);
if (nStart==m_nDesUserIndex)
{
break;
}
}
MoveSetp(m_nSelfUserIndex,m_nDesUserIndex,MOVE_EXACT);
}
}
else if (m_nSelfUserIndex>m_nDesUserIndex) //move forward
{
//1. move self to the destination
//2. move (nSelfPos-1)~nPos backward
UINT32 nStart = 0;
if (m_bSnapToGrid)
{
MoveSetp(m_nSelfUserIndex,m_nDesUserIndex,MOVE_UP_1_PIX);
//if need keep origin layout
nStart = m_nSelfUserIndex-1;
for (;nStart>=m_nDesUserIndex;--nStart)
{
MoveSetp(nStart,nStart+1,MOVE_EXACT);
if (nStart==m_nDesUserIndex)
{
break;
}
}
}
else
{
MoveSetp(m_nSelfUserIndex,m_nDesUserIndex,MOVE_EXACT);
nStart = m_nSelfUserIndex-1;
for (;nStart>=m_nDesUserIndex;--nStart)
{
MoveSetp(nStart,nStart+1,MOVE_EXACT);
if (nStart==m_nDesUserIndex)
{
break;
}
}
}
}
SendMessage(m_hwndSysListView32, WM_SETREDRAW, TRUE, 0) ;
::UpdateWindow(m_hwndSysListView32);
}
main文件
#include "SetIconPos.h"
int _tmain(int argc, TCHAR **argv)
{
DWORD dw1 = GetTickCount();
CSetIconPath * p = new CSetIconPath;
while(true)
{
p->MoveIconPos(0,8);
//Sleep(100);
}
_tprintf(_T("use %d ms\n"),GetTickCount()-dw1);
return 0;
}