Всем доброго времени суток!!! Кто нибудь может подсказать как програмно отключить упорядочивание элементов рабочего стола (ярлыков) ?
Я пишу простую программу-шутку на С++, которая будет создавать дрожь ярлыков на рабочем столе, а затем обрушивать их в случайном порядке вниз за область экрана. При этом я сталкнулся с проблемой и прошу у вас помощи в её решении. Суть проблеммы в том, что если я в меню Вид-> Выравнивать автоматически ставлю галочку, то программа вообще не работает. И если я выбираю пункт Выравнять по сетке, то ярлыки двигаются рывками. Как мне устранить данные траблы?
Первую проблему с автоматическим выравниванием решил с помощью SetWindowLong(DesktopHandle,GWL_STYLE,WS_CHILDWINDOW|WS_VISIBLE|WS_CLIPSIBLINGS|WS_CLIPCHILDREN|LVS_ICON|LVS_SHAREIMAGELISTS|LVS_EDITLABELS|LVS_ALIGNLEFT|LVS_OWNERDATA|LVS_NOSCROLL); Что делать со второй не знаю, если включено выравнивание по сетке ярлыки движутся рывками.
Может пройдет прикол с выключением и включением видимости этих значков? Выкл и включаем видимость значков. "Шутили" когда то под Win2000, так что осторожно. Чтобы не перезагружать explorer Код (Text): #include "windows.h" #include "commctrl.h" #include "stdio.h" int main(int argc, char* argv[]) { HWND hwnd; hwnd=FindWindowEx(GetDesktopWindow(),NULL,"Progman",NULL); hwnd=FindWindowEx(hwnd,NULL,"SHELLDLL_DefView",NULL); hwnd=FindWindowEx(hwnd,NULL,"SysListView32",NULL); LONG lo=GetWindowLong(hwnd,GWL_STYLE); lo=lo^LVS_REPORT^WS_VSCROLL; SetWindowLong(hwnd,GWL_STYLE,lo); InvalidateRect(hwnd,NULL,FALSE); return 0; } Первый раз запусти - все пропадет, второй - проявится.
Прости помочь явно не могу, но точно это делал. Сорец на другом компе. Кури LVS_* (Двигал значки попиксельно) Может быть: LVS_AUTOARRANGE http://msdn.microsoft.com/en-us/library/bb774739(v=VS.85).aspx PS
SetWindowLong(DesktopHandle,GWL_STYLE,WS_CHILDWINDOW|WS_VISIBLE|WS_CLIPSIBLINGS|WS_CLIPCHILDREN|LVS_ICON|LVS_SHAREIMAGELISTS|LVS_EDITLABELS|LVS_ALIGNLEFT|LVS_OWNERDATA|LVS_NOSCROLL);-Чушь! Сначало gwl=GetWindowLong, потом SetWindowLong(gwl || LVS_style);
punxer Почему чушь? Просто устанавливаем стили которые нам нужны, а не берем старые и добовляем к ним новые. Таким же способом я решил и вторую проблемму с 'выравниванием по сетке'. ListView_SetExtendedListViewStyleEx (DesktopHandle, 0,LVS_EX_HEADERDRAGDROP|LVS_EX_FULLROWSELECT|LVS_EX_INFOTIP|LVS_EX_UNDERLINEHOT|LVS_EX_LABELTIP|LVS_EX_DOUBLEBUFFER); Теперь ярлык перемещается плавно, без рывков.
А как мне получить координаты ярлыка?ListView_GetItemPosition(DesktopHandle, i, &xy); не работает. Пробовал SendMessage(DesktopHandle, LVM_GETITEMPOSITION, i,(LONG)&xy); тоже не выходит :-(
вобщем 'написал' (вернее и чеснее скопировал и слегка модифицировал код) программу, которая трясет ярлычками на рабочем столе. Вот код: #include "stdafx.h" #include <windows.h> #include <commctrl.h> //#include <iostream> #define LVM_FIRST 0x1000 #define LVM_SETITEMPOSITION (LVM_FIRST+15) #define LVM_GETITEMPOSITION (LVM_FIRST+16) #define LVM_UPDATE (LVM_FIRST+42) #define LVS_ICON 0x0000 #define LVS_SHAREIMAGELISTS 0x0040 #define LVS_EDITLABELS 0x0200 #define LVS_ALIGNLEFT 0x800 #define LVS_OWNERDATA 0x1000 #define LVS_NOSCROLL 0x2000 #define LVS_EX_HEADERDRAGDROP 0x00000010 #define LVS_EX_FULLROWSELECT 0x00000020 #define LVS_EX_INFOTIP 0x00000400 #define LVS_EX_UNDERLINEHOT 0x00000800 #define LVS_EX_LABELTIP 0x00004000 #define LVS_EX_DOUBLEBUFFER 0x00010000 #define LVS_EX_SNAPTOGRID 0x00080000 int x,y; HWND FindListView() throw(...) { HWND progman_wnd = 0; HWND desktopview_wnd = NULL; HWND listview_wnd = NULL; progman_wnd = FindWindowA(NULL, "Program Manager"); if(progman_wnd == NULL) throw(GetLastError()); desktopview_wnd = FindWindowExA(progman_wnd, NULL, "SHELLDLL_DefView", NULL); if(desktopview_wnd == NULL) throw(GetLastError()); listview_wnd = FindWindowExA(desktopview_wnd, NULL,"SysListView32", NULL); if(listview_wnd == NULL) throw(GetLastError()); return listview_wnd; } HANDLE FindExlorerProcess(HWND slave_wnd) throw(...) { // Thanks to mr_williams@rave.ch who pointed me to GetWindowThreadProcessId(), that makes this function waaaaaaaaaaaaay shorter. HANDLE proc; DWORD explorer_pid; // Get the PID based on a HWND. This is the good stuff. You wouldn't believe the long and difficult function I had to write before I heard of this simple API call. GetWindowThreadProcessId(slave_wnd, &explorer_pid); // Get a process handle which we need for the shared memory functions. proc = OpenProcess(PROCESS_VM_OPERATION|PROCESS_VM_READ|PROCESS_VM_WRITE|PROCESS_QUERY_INFORMATION, FALSE, explorer_pid); if(proc == NULL) throw(GetLastError()); else return proc; } void* AllocMemInForeignProcess(HANDLE process, unsigned long size) throw(...) { void *ptr = VirtualAllocEx(process, NULL, size, MEM_COMMIT, PAGE_READWRITE); if(ptr == NULL) throw(GetLastError()); else return ptr; } void ReadFromForeignProcessMemory(HANDLE process, void* ptr, void* target, unsigned long size) throw(...) { if(ReadProcessMemory(process, ptr, target, size, NULL) == 0) throw(GetLastError()); } void FreeMemInForeignProcess(HANDLE process, void* ptr) throw(...) { if(VirtualFreeEx(process, ptr, 0, MEM_RELEASE) == 0) throw(GetLastError()); } int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { void* ipc_iconpos = 0; LRESULT msg_result = 0; HANDLE explorer = 0; POINT iconpos; HWND listview_wnd = FindListView(); ListView_SetExtendedListViewStyleEx (listview_wnd, 0,LVS_EX_HEADERDRAGDROP|LVS_EX_FULLROWSELECT|LVS_EX_INFOTIP|LVS_EX_UNDERLINEHOT|LVS_EX_LABELTIP|LVS_EX_DOUBLEBUFFER); SetWindowLong(listview_wnd,GWL_STYLE,WS_CHILDWINDOW|WS_VISIBLE|WS_CLIPSIBLINGS|WS_CLIPCHILDREN|LVS_ICON|LVS_SHAREIMAGELISTS|LVS_EDITLABELS|LVS_ALIGNLEFT|LVS_OWNERDATA|LVS_NOSCROLL); InvalidateRect(listview_wnd,NULL,FALSE); unsigned long iconcount = static_cast<unsigned long>(SendMessage(listview_wnd, LVM_GETITEMCOUNT, 0, 0)); // Get the PID of the process that houses the listview, i.e.: Explorer.exe explorer = FindExlorerProcess(listview_wnd); // Here we allocate the shared memory buffers to use in our little IPC. ipc_iconpos = AllocMemInForeignProcess(explorer, sizeof(POINT)); for (int z = 0; z < 10000; ++z) { for(int i = 0; i < iconcount ; ++i) { msg_result = SendMessage(listview_wnd, LVM_GETITEMPOSITION, i, reinterpret_cast<LPARAM>(ipc_iconpos)); ReadFromForeignProcessMemory(explorer, ipc_iconpos, &iconpos, sizeof(POINT)); for (int t=0; t<2;++t) { x=iconpos.x+t; y=iconpos.y+t; ListView_SetItemPosition(listview_wnd, i, x, y); } } for(int i = 0; i < iconcount ; ++i) { msg_result = SendMessage(listview_wnd, LVM_GETITEMPOSITION, i, reinterpret_cast<LPARAM>(ipc_iconpos)); ReadFromForeignProcessMemory(explorer, ipc_iconpos, &iconpos, sizeof(POINT)); for (int s=0; s<2;++s) { x=iconpos.x-s; y=iconpos.y-s; ListView_SetItemPosition(listview_wnd, i, x, y); } } } FreeMemInForeignProcess(explorer, ipc_iconpos); CloseHandle(explorer); system("PAUSE"); return EXIT_SUCCESS; } Я плохо знаю С++ и Win32 API и не понял как происходит выделение памяти в пространстве explorer'a. При работе программы explorer загружает процессор, это как то устранимо? И еще в Висте работает нормально, а в ХР пропадают обои. Может быть это связанно с тем о чем мне говорил punxer Или в чем причина?
pashe4ka13 Выложи архив с exe-хой и сорцом. на файлообменник (на http://webfile.ru/ например). Может люди посмотрят по тестят.