怎麼樣獲取桌面圖標句柄,並用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個回答:

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 );
}
我這裏試驗通過了。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章