关于若干历史问题的回顾--对Desktop的操作(0分)

  • 主题发起人 主题发起人 歪就歪
  • 开始时间 开始时间

歪就歪

Unregistered / Unconfirmed
GUEST, unregistred user!
一口气问了三个几乎重复的问题:
http://www.gislab.ecnu.edu.cn/delphibbs/DispQ.asp?LID=174922
http://www.gislab.ecnu.edu.cn/delphibbs/DispQ.asp?LID=174924
http://www.gislab.ecnu.edu.cn/delphibbs/DispQ.asp?LID=173802
都是关于对DESKTOP上ICON的,涉及的问题是:
凭着DESKTOP的HANDEL:
一、得到一个DESKTOP上某ICON的坐标。
二、设定Desktop上的AutoArrange
要实现这两问题的目的,不过就是想在目前项目中,在运行时,生成
一个ICON,然后,这ICON飞到程序的载入窗口而已。
起初,Hubdog和Keyes都说对了,要用一个Dll Hook以便能和Desktop
共享内存,当然,就为一个ICON做个HOOK似乎不值得,更何况要实现
用HOOK对DESKTOP操作也不容易。
后来发现,不用HOOK,只要简单的通过ListView_SetItemPosition
就能改变ICON的位置。于是,又有了不用HOOK的新希望,但随后发现
在ListView_XXXXXX的调用中,有一些成功,有些不成功,比如:
ListView_GetItemPosition就不行。
实际上,还是内存问题。
以下是Experter-Exchange的回答,清晰明了,希望和我水平一样低
的、以及竟然比我还低的,从中受益:
The problem is that the desktop's listview is in the context of
another process, so it's in another memory context, too. And
THATdo
es mean, that pointers that are valid in YOUR process are not
valid in the explorer's process. So the explorer gets a pointer to a
string that is valid only in YOUR process. In the explorer's process
this pchar pointer points to "wild" memory.
function ListView_SetItemPosition(hWnd: HWND;
i, x, y: Integer):Bool;
begin

Result := Bool( SendMessage(hWnd, LVM_SETITEMPOSITION, i,MakeLong(x, y)) );
end;

It is nothing but a simple message. You can transport two 32bit
values with SendMessage (wParam and lParam). As long as you
transport two cardinals or two integers, that is ORDINALS, you have
no problem. That's why SetItemPosition and GetItemCountdo
work,
because there are no pointer involved.
As soon as a listView message needs pointers, you come into
problems. And the caption of the list item you want to finddo
esn't
fit into two 32bit values. One of those 32bit values takes the pointer
to that find string. And there we have the POINTER - so there we
have the problems...
关键在于:有一半以上ListView_XXXX的参数中用了指针,这些指针不会
正确的指向Desktop的内存区内。凡是参数中没有用到指针传递的,才有
可能有效。
到此为止,完全明白了。
最后解决的办法,其实也很简单,用个透明FORM,上面放个IMAGE,做
的和DESKTOP上的ICON一样,然后,让它在屏幕上飞起来……哈哈,又
简单又牢靠!还和真正的ICON飞起来一样!只是,在心里上不是很满
足:做出来的东西,看着COOL,技术却不怎么样。

 
好样的,歪大侠开创了整理问题回答的先河,值得鼓励。
建议以后的大侠也如法炮制,说不定一个大富翁精华版就这么出来了。
 
y9y: 能不能帮我把上面的e文翻译一下,我看的半懂的,想好好研究一下.
 
感谢歪大虾!可以放在编程手记中
 
欺负我,你水平那么高,就算英文欠一些,猜也猜的差不多了。因为我在国内没
做过计算机,所以,很多中文词汇不太清楚,基本的词汇都是和你们学的,可能
有不准的地方。
译文如下:
===========
问题的关键在于,桌面的ListView是在另一个程序,亦即:它在另一个独立的地
址空间。那就意味着,你程序里的指针不能指向正确的地方,也就是Explore程
序的地址空间中的那个地址。当Explore接到你程序提供的指针时,这个在你程
序内有效的指针到了Explore中成为指向“乱七八糟”的指针。
function ListView_SetItemPosition(hWnd: HWND;
i, x, y: Integer):Bool;
begin

Result := Bool( SendMessage(hWnd, LVM_SETITEMPOSITION, i,MakeLong(x, y)) );
end;


上文的FUNCTION仅仅是发送了一个消息,在这消息中,你所传送的是32BIT的
值(wParam和lparam)只要你传送的是2个Cardinal,或整数,亦即:都是
Ordinal,你就不会遇到问题,这就是为什么SetItemPosition 和
GetItemCount能工作的原因:在参数传送中,没有传送指针。
只要参数中需要传送指针的时候,你就会遇到这问题。当你想用ICON的CAPTION
找到相应桌面的ICON的Index值时,你要传送的Caption不在是32bit参数(应该
是:不再是Ordinal了),而是指向一个字串的指针。于是,指针--我们就遇
到这问题了!
==============
不好意思,翻译得怪不通的,如果你看着费劲,我再解释一下:
说白了,就是Desktop和你的程序在不同的地址空间内,如果你想在EXE程序中
用ListView_XXX的API调用,以便对Desktop的ICON进行操作,那么,只有:没
有以指针为参数的API调用才能成功,比如:ListView_SetItemPosition。
否则,如果参数中有指针的,比如:ListView_GetItemPosition就会乱七八糟
了(Explore可能CRASH)
相信这么解释,对cAKK是多余的了。
 
感谢!
我理解的意思也差不多,只是不太肯定....现在肯定了.
那么如果有指针参数就没戏了吗? 一点办法也没有?
 
cAkk:
我想,那恐怕就有hook可以了吧。而且,做个什么样的Hook,在hook中该
如何实现,我却是一点儿底儿都没有。Keyes给了我一个C的程序,据说是
实现这功能的,但我看了两天,没弄明白它说了些什么。
更何况,就为了搬动一下桌面的ICON,做个Hook值得么?
Hooker在英文中就是妓女的意思。最好离她远点,麻烦多多。
 
接受答案了.
 
后退
顶部