怎么样获取桌面图标句柄,并用VC完成随意移动桌面图标地位置?

源地址:

http://www.qqgb.com/Program/VC/VCJC/Program_251616.html

桌面图标是放在 SysListView32这个列表中,下面得到了它的句柄,如何遍历它得到各各桌面图标的句柄?
如果桌面上有文件夹,文件什么的怎么分辨?以下三句得到列表的句柄,哪个能告诉我下面该怎么做,我的目标是通过
MoveWindow函数来任意改变桌面上所有图标的位置。。。
HWND  hwndParent = ::FindWindow(L"Progman",L"Program Manager");
HWND  hwndSHELLDLL_DefView = ::FindWindowEx(hwndParent,NULL,L"SHELLDLL_DefView", NULL);
HWND  hwndSysListView32 = ::FindWindowEx(hwndSHELLDLL_DefView,NULL,L"SysListView32",L"FolderView");


这个问题第1个回答:

C/C++ code
  
  void C***::OnSetDeskIcon() 
{    
    HWND  hwndParent = ::FindWindow( "Progman", "Program Manager" ); 
HWND hwndSHELLDLL_DefView = ::FindWindowEx( hwndParent, NULL, "SHELLDLL_DefView", NULL );
HWND hwndSysListView32 = ::FindWindowEx( hwndSHELLDLL_DefView, NULL, "SysListView32", "FolderView" );
int Nm = ListView_GetItemCount( hwndSysListView32 );
int sNm = 0;
if( Nm >= 10 )
{ sNm = 10;
}
else
{ sNm = Nm;
}
for( int i = 0; i < sNm; i++ )
{ int x = 400 + 150*cos( i*36*3.1415926/180 );
int y = 400 + 150*sin( i*36*3.1415926/180 );
::SendMessage( hwndSysListView32, LVM_SETITEMPOSITION, i, MAKELPARAM( x,y));
}
ListView_RedrawItems(hwndSysListView32, 0, ListView_GetItemCount(hwndSysListView32) - 1);
::UpdateWindow(hwndSysListView32);
}


上面的代码 实现把桌面前10图标排成一个圆 楼主去查ListView_RedrawItems这类函数的用法


这个问题第2个回答:
楼上的很经典...


这个问题第3个回答:

引用 1 楼 Tinary3v0 的回复:
C/C++ codevoid C***::OnSetDeskIcon()
{   
    HWND  hwndParent = ::FindWindow( "Progman", "Program Manager" );
    HWND  hwndSHELLDLL_DefView = ::FindWindowEx( hwndParent, NULL, "SHELLDLL_DefView", NULL );
    HWND  hwndSysListView32 = ::FindWindowEx( hwndSHELLDLL_DefView, NULL, "SysListView32", "FolderView" );

    int Nm = ListView_GetItemCount( hwndSysListView32 );

    int sNm = …


经典


这个问题第4个回答:

引用 1 楼 Tinary3v0 的回复:
C/C++ codevoid C***::OnSetDeskIcon()
{   
    HWND  hwndParent = ::FindWindow( "Progman", "Program Manager" );
    HWND  hwndSHELLDLL_DefView = ::FindWindowEx( hwndParent, NULL, "SHELLDLL_DefView", NULL );


谢谢,我还有一个问题,希望你帮我解答一下,答完就结贴给分。
    HWND hDestTop;
    hDestTop = ::FindWindow("progman", NULL);
    hDestTop = ::FindWindowEx(hDestTop, 0, "shelldll_defview", NULL);
    hDestTop = ::FindWindowEx(hDestTop, 0, "syslistview32", NULL);
   
    DWORD dwProcessId;
    GetWindowThreadProcessId(hDestTop, &dwProcessId);
    HANDLE hProcess = OpenProcess(PROCESS_VM_READ | PROCESS_VM_OPERATION, false, dwProcessId);
   
    PVOID rc = VirtualAllocEx(hProcess, NULL, sizeof(RECT), MEM_COMMIT, PAGE_READWRITE);
    m_iconCount = ListView_GetItemCount(hDestTop);
    RECT iRect;
    char szText[200];
    CString rcStr;
    m_iconInfoCtrl.DeleteAllItems();
    for (int i = 0; i < m_iconCount; i++)
    {
        ListView_GetItemText(hDestTop, i, 5, szText, 200); //在这我想得到如“我的电脑”等图标的文本
                                                          //但不知道如何得,随便写的一个。
        ListView_GetItemRect(hDestTop, i, rc, LVIR_ICON); //出错处,想得到图标大小
        ReadProcessMemory(hProcess,  rc,  &iRect,  sizeof(RECT), NULL);
        rcStr.Format("(%d,%d,%d,%d)", iRect.left, iRect.top, iRect.right, iRect.bottom);
        m_iconInfoCtrl.InsertItem(i, szText);
        m_iconInfoCtrl.SetItemText(i, 1, rcStr);
    }
    VirtualFreeEx(hProcess, rc, 0, MEM_RELEASE);
    CloseHandle(hProcess);
    UpdateData(false);
用上面的方法我是想把桌面上的图标数量和图标的大小显示出来,结果在上面标红的地方出错,如果我不在explorer进程中开空间的话,读出来的大小是不对的,结果都是1,和一个很小的负数。。要得到大小和图标上的文本应该如何写?


这个问题第5个回答:
mark


这个问题第6个回答:
下面这个函数纯属抄袭了:http://www.codeproject.com/KB/threads/int64_memsteal.aspx
在上面增加了取得 Rect的部分
C/C++ code

 
 void C***::OnSetDeskIcon()
{ HWND hDestTop;
hDestTop = ::FindWindow("progman", NULL);
hDestTop = ::FindWindowEx(hDestTop, 0, "shelldll_defview", NULL);
hDestTop = ::FindWindowEx(hDestTop, 0, "syslistview32", NULL);
int count=(int)::SendMessage( hDestTop, LVM_GETITEMCOUNT, 0, 0);
LVITEM lvi, *_lvi;
char item[512], subitem[512];
char *_item, *_subitem;
unsigned long pid;
HANDLE process;
GetWindowThreadProcessId( hDestTop, &pid);
process=OpenProcess(PROCESS_VM_OPERATION|PROCESS_VM_READ|PROCESS_VM_WRITE|PROCESS_QUERY_INFORMATION, FALSE, pid);
_lvi=(LVITEM*)VirtualAllocEx(process, NULL, sizeof(LVITEM), MEM_COMMIT, PAGE_READWRITE);
_item=(char*)VirtualAllocEx(process, NULL, 512, MEM_COMMIT, PAGE_READWRITE);
_subitem=(char*)VirtualAllocEx(process, NULL, 512, MEM_COMMIT, PAGE_READWRITE);
RECT rc;
rc.left = LVIR_ICON; //这个一定要设定 可以去看MSDN关于LVM_GETITEMRECT的说明
RECT* _rc =(RECT*)VirtualAllocEx( process, NULL, sizeof(RECT), MEM_COMMIT, PAGE_READWRITE);
lvi.cchTextMax=512;
for( int i=0; i< 10; i++) {
lvi.iSubItem=0;
lvi.pszText=_item;
WriteProcessMemory(process, _lvi, &lvi, sizeof(LVITEM), NULL);
::SendMessage( hDestTop, LVM_GETITEMTEXT, (WPARAM)i, (LPARAM)_lvi);
lvi.iSubItem=1;
lvi.pszText=_subitem;
WriteProcessMemory(process, _lvi, &lvi, sizeof(LVITEM), NULL);
::SendMessage( hDestTop, LVM_GETITEMTEXT, (WPARAM)i, (LPARAM)_lvi);
::WriteProcessMemory( process, _rc, &rc, sizeof(rc), NULL);
::SendMessage( hDestTop, LVM_GETITEMRECT, (WPARAM)i, (LPARAM)_rc);
ReadProcessMemory(process, _item, item, 512, NULL);
ReadProcessMemory(process, _subitem, subitem, 512, NULL);
ReadProcessMemory(process, _rc, &rc, sizeof(rc), NULL);
CString str;
str.Format("LF:%d TP:%d RT:%d BT:%d", rc.left,rc.top,rc.right,rc.bottom);
AfxMessageBox(str);
str.Format("%s - %s/n", item, subitem);
AfxMessageBox( str );
}
VirtualFreeEx(process, _lvi, 0, MEM_RELEASE);
VirtualFreeEx(process, _item, 0, MEM_RELEASE);
VirtualFreeEx(process, _subitem, 0, MEM_RELEASE);
VirtualFreeEx(process, _rc, 0, MEM_RELEASE);
CloseHandle( process );
}
我这里试验通过了。
  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值