请问高手关于取桌面图标的坐标的问题
我想得到桌面图标的位置,程序如下,可是运行总是说内存不能写入,非法访问,请问是怎么回事?
//得到桌面的HWND
HWND hDeskTop;
hDeskTop = FindWindow( "progman", NULL );
hDeskTop = FindWindowEx( hDeskTop, 0, "shelldll_defview", NULL );
hDeskTop = FindWindowEx( hDeskTop, 0, "syslistview32", NULL );
HANDLE hfmap = CreateFileMapping( (HANDLE)(-1),
NULL,
PAGE_READWRITE,
0,
sizeof( POINT ),
"MyMapping" );
POINT *ppt = 0;
ppt = (POINT*)MapViewOfFile( hfmap, FILE_MAP_ALL_ACCESS, 0, 0, 0 );
//取第一个图标的位置
ListView_GetItemPosition( hDeskTop, 1, ppt);
问题点数:100、回复次数:15Top
1 楼wormie4evr(虫虫不爱我...)回复于 2003-01-07 19:07:35 得分 20
我这里运行很正常啊. 你加点判错码看看 MapViewOfFile 有没成功.Top
2 楼In355Hz(好象一条狗)回复于 2003-01-07 19:30:03 得分 0
// ppt = (POINT*)MapViewOfFile( hfmap, FILE_MAP_ALL_ACCESS, 0, 0, 0 );
我记得只有 Win9x 才能用这种方式分配共享内存吧,因为 Win9x 用于内存映射文件的 MMF 区是共享的。Top
3 楼wormie4evr(虫虫不爱我...)回复于 2003-01-07 19:36:15 得分 0
我记得只有 Win9x 才能用这种方式分配共享内存吧,因为 Win9x 用于内存映射文件的 MMF 区是共享的。
--------------------------
他这里又没有共享 mmf, 只是分配块内存.
不过不懂楼主为啥要 mmf ... 直接堆栈上留个 POINT 结构不是方便很多吗.Top
4 楼wjun2000(阿三)回复于 2003-01-07 19:46:43 得分 0
在堆栈上不行吧,因为是让桌面的进程修改我的进程里的数据(就是那个POINT结构)
to wormie4vr:
你用的是98还是2000,我用的是win2000
to ln355Hz:
那你知道win2000里该怎么办吗,please tell me, thank you.Top
5 楼wormie4evr(虫虫不爱我...)回复于 2003-01-07 19:53:16 得分 0
我用的是 win2k (no sp). ListView_GetItemPosition 这个宏就是 SendMessage, 而不同进程间 SendMessage 时, 会在目标进程的堆上建一 buffer (长度同POINT), 窗口函数返回前把结果写入此 buffer, 最后把这个 buffer 复制(WriteProcessMemory)回堆栈上的 pt 变量.
还不相信的话, 可以想象一下给别的进程的窗口发WM_GETTEXT. 不需mmf, 否则2000不是完了.Top
6 楼wjun2000(阿三)回复于 2003-01-07 20:05:52 得分 0
你的意思是不是这样:
//得到桌面的HWND
HWND hDeskTop;
hDeskTop = FindWindow( "progman", NULL );
hDeskTop = FindWindowEx( hDeskTop, 0, "shelldll_defview", NULL );
hDeskTop = FindWindowEx( hDeskTop, 0, "syslistview32", NULL );
POINT *ppt = 0;
//取第一个图标的位置
ListView_GetItemPosition( hDeskTop, 1, ppt);
不好用,还是说内存不能writtenTop
7 楼ArCoolGG(ArCoolGG)回复于 2003-01-07 20:16:41 得分 10
可以这样试试,
自己写一个DLL,然后用hook把它挂到explorer.exe的进程上,在钩子函数里给这个listview发消息,得到坐标后将数据传回你的进程。不过这里又有一个进程间数据访问的问题。要注意。Top
8 楼wormie4evr(虫虫不爱我...)回复于 2003-01-07 20:34:19 得分 0
不是那样, 是
POINT pt;
ListView_GetItemPosition( hDeskTop, 1, &pt);
ArCoolGG 不要那么麻烦.Top
9 楼vc_mira(www.kibase.com (知、信,天下))回复于 2003-01-07 20:53:58 得分 0
哈哈哈,我猜wjun2000(无名小卒) 的机子里运行着一个带bug的程序。Top
10 楼wjun2000(阿三)回复于 2003-01-08 12:23:49 得分 0
to wormie4evr(虫虫不爱我...)
你用vc试了吗,我这样做了,不管用Top
11 楼In355Hz(好象一条狗)回复于 2003-01-08 15:59:34 得分 60
// 我认为这个代码保险一点,尽管需要较高的权限。
DWORD dwProcessId;
GetWindowThreadProcessId(hDeskTop, &dwProcessId);
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
LPVOID lpvPt = VirtualAllocEx(hProcess, NULL, sizeof(POINT), MEM_COMMIT, PAGE_READWRITE);
POINT pt;
ListView_GetItemPosition( hDeskTop, 1, lpvPt);
ReadProcessMemory(hProcess, lpvPt, &pt, sizeof(POINT), NULL);
// 如果还要调用 ListView_GetItemPosition 则不必马上释放 lpvPt 和 hProcess
VirtualFreeEx(hProcess, lpvPt, 0, MEM_RELEASE);
CloseHandle(hProcess);
// pt 里保存了 Item 的位置。Top
12 楼In355Hz(好象一条狗)回复于 2003-01-08 16:04:11 得分 0
补充:
HANDLE hProcess = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_READ, FALSE, dwProcessId);Top
13 楼wormie4evr(虫虫不爱我...)回复于 2003-01-08 16:38:00 得分 0
In355Hz 是对的.
LVM_ 是 common control 消息, 系统不会像我前面说的那样建一中转 buffer.Top
14 楼NowCan(城市浪人)回复于 2003-01-08 17:30:06 得分 10
我记得《Windows核心编程》里有这个例子。不过他好像用的是hook。Top
15 楼wjun2000(阿三)回复于 2003-01-08 18:34:16 得分 0
In355Hz的方法很好用,谢谢啦,也谢谢各位的参与,我要给分拉Top




