移动桌面图标位置

本文介绍了一个用于Windows桌面图标移动的算法实现,通过获取桌面图标的位置信息,并利用特定的数据结构进行索引映射,实现了图标之间的精确移动。文章详细阐述了如何获取桌面listview控件的句柄、排列方式及图标位置等关键步骤。
摘要由CSDN通过智能技术生成

头文件:

 

//用户索引: 假使桌面有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;
}


 

 


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值