歪
歪就歪
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,技术却不怎么样。
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,技术却不怎么样。