谁能告诉我,Image怎么知道被单击?

lance 2002-10-20 07:18:09
如果是个 button我就很明白,Image就搞不懂了.
...全文
43 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
findcsdn 2002-11-04
  • 打赏
  • 举报
回复
windows只能把消息投递到用CreateWindow函数创建的窗口内,在delphi中就是从twincontrol派生的各种控件。 timage不是从twincontrol派生显然不能接受消息,所以只能是他的父窗口在接到系统鼠标消息后转发的。vcl中有他自己的一套消息机制。
knock 2002-11-03
  • 打赏
  • 举报
回复
image 默认的没有onclick事件,但可以用一个bool变量来模拟吧,在mousedown和mouseup里分别设置此bool变量的值,不过mouseup里判断后再处理,不就和click事件差不多了吗?
lance 2002-11-01
  • 打赏
  • 举报
回复
>区域捕捉
什么意思?
wanglight 2002-11-01
  • 打赏
  • 举报
回复
这人问题我也遇到过.
1.当然可以在image 的click中写代码;
2.若是用Canvas画出的,则可用区域捕捉来进行!
pdbird 2002-10-26
  • 打赏
  • 举报
回复
高手就是高手!
goodloop 2002-10-26
  • 打赏
  • 举报
回复
哇,受益匪浅
ColdWolf 2002-10-25
  • 打赏
  • 举报
回复
TImage、TSpeedButton等等,这些控件都是TGraphicControl继承的,他们不是能获取焦点,但是它们的父容器,在接受到事件的时候,总是先检测该事件是否发生在这些控件所在区域,如果是的话,就会将消息交给这些控件来处理
xzgyb 2002-10-25
  • 打赏
  • 举报
回复
boy2002()
在Project/option/compiler
选上Use Debug Dcus,以跟踪到源代码

Controls单元的6199行设置断点
也就是
IsControlMouseMsg函数里
这样就可得到
lance 2002-10-25
  • 打赏
  • 举报
回复
呵呵,你为什么要重复一遍.
理想 2002-10-24
  • 打赏
  • 举报
回复
响应 OnClick 事件就行了。
DelUser 2002-10-24
  • 打赏
  • 举报
回复
up
boy2002 2002-10-24
  • 打赏
  • 举报
回复
to xygyb
你是如何知道产生了WM_MOUSEMOVE,WM_LBUTTONDOWN,WM_LBUTTONUP
在WM_MOUSEFIRST和WM_MOUSELAST这几个事件,在那里设断点
xzgyb 2002-10-22
  • 打赏
  • 举报
回复
lance:
对,我说了一堆,就是这意思
lance 2002-10-22
  • 打赏
  • 举报
回复
to halfdream(哈欠) :
确实,我应该问,image没有窗口句柄,如何得到消息?
其实,有焦点和有窗口句柄是等价的.不知道我说的对不对.
lance 2002-10-22
  • 打赏
  • 举报
回复
高手终于出现了!!!
Image能得到消息么?(我是说windows的标准消息)
能,但不是直接得到!!!什么意思呢?
让我们回想一下,我们要把Image放到一个容器里才行.或者是form或者是panel
什么的.你能把一个Image放到一个shape里么?不能.你想过为什么吗?

得到消息的是容器而不是Image.只有TWinControl才可以得到消息,他的父类TControl是得不到消息的.

现在明白了.当我们单击Image时,容器得到一个消息"我被单击了一下",然后容器就
判断被单击的地方有没有control啊,如果有就让这个control自己处理好了.

关键:区域点击测试.
这是偶看一本图形学的书的时候,突然想到的.


xzgyb 2002-10-21
  • 打赏
  • 举报
回复
前些天也在考虑,略微弄懂了些。先写一下吧。

我在窗体Form1放了个TImage控件Image1
TGraphicControl控件的一些事件是依靠它的父控件TWinControl来产生的
在这里Image1的Parent为TForm1;
当点击Image1时,我跟踪了下,是这样的,我只说主要的
TWinControl的WndProc中的(Controls单元的6226行)
WM_MOUSEFIRST..WM_MOUSELAST:
if IsControlMouseMsg(TWMMouse(Message)) then
begin
{ Check HandleAllocated because IsControlMouseMsg might have freed the
window if user code executed something like Parent := nil. }
if (Message.Result = 0) and HandleAllocated then
DefWindowProc(Handle, Message.Msg, Message.wParam, Message.lParam);
Exit;
end;

当我把鼠标移到Image1并单击了一下,产生了WM_MOUSEMOVE,WM_LBUTTONDOWN,WM_LBUTTONUP
在WM_MOUSEFIRST和WM_MOUSELAST范围内,
调用IsControlMouseMsg(TWMMouse(Message));
源码如下
function TWinControl.IsControlMouseMsg(var Message: TWMMouse): Boolean;
var
Control: TControl;
P: TPoint;
begin
if GetCapture = Handle then
begin
Control := nil;
if (CaptureControl <> nil) and (CaptureControl.Parent = Self) then
Control := CaptureControl;
end else
Control := ControlAtPos(SmallPointToPoint(Message.Pos), False);
Result := False;
if Control <> nil then
begin
P.X := Message.XPos - Control.Left;
P.Y := Message.YPos - Control.Top;
Message.Result := Control.Perform(Message.Msg, Message.Keys, Longint(PointToSmallPoint(P)));
Result := True;
end;
end;
WM_MOUSEMOE被通过ControlAtPos所确定的Image1控件Perform出去了,先不说了。
WM_LBUTTONDOWN过来了
然后调用Perform,Perform调用TControl的WindowProc
TControl的WndProc又对这个消息做了些处理
else if (Message.Msg >= WM_MOUSEFIRST) and (Message.Msg <= WM_MOUSELAST) then
begin
if not (csDoubleClicks in ControlStyle) then
case Message.Msg of
WM_LBUTTONDBLCLK, WM_RBUTTONDBLCLK, WM_MBUTTONDBLCLK:
Dec(Message.Msg, WM_LBUTTONDBLCLK - WM_LBUTTONDOWN);
end;
case Message.Msg of
WM_MOUSEMOVE: Application.HintMouseMessage(Self, Message);
WM_LBUTTONDOWN, WM_LBUTTONDBLCLK:
begin
if FDragMode = dmAutomatic then
begin
BeginAutoDrag;
Exit;
end;
Include(FControlState, csLButtonDown);
end;
然后TControl的WndProc把WM_LBUTTONDOWN消息Dispatch出去
调用TControl.WMLBUTTONDOWN

procedure TControl.WMLButtonDown(var Message: TWMLButtonDown);
begin
SendCancelMode(Self);
inherited;
if csCaptureMouse in ControlStyle then MouseCapture := True;
if csClickEvents in ControlStyle then Include(FControlState, csClicked);
DoMouseDown(Message, mbLeft, []);
end;

同样WM_LBUTTONUP也是这样当调用到TControl.WMLButtonUp时
procedure TControl.WMLButtonUp(var Message: TWMLButtonUp);
begin
inherited;
if csCaptureMouse in ControlStyle then MouseCapture := False;
if csClicked in ControlState then
begin
Exclude(FControlState, csClicked);
if PtInRect(ClientRect, SmallPointToPoint(Message.Pos)) then Click;
end;
DoMouseUp(Message, mbLeft);
end;
这个Click事件就产生了
代码贴了一大堆,不好意思。
说的也乱七八糟,唉,跟我做人的风格也一样
呵呵




halfdream 2002-10-21
  • 打赏
  • 举报
回复
我想你有一点有点混淆,就是认为没有焦点不能得到消息。
有没有焦点同有没有窗口句柄倒可以联系的。
lance 2002-10-20
  • 打赏
  • 举报
回复
道理很不一样.
Image没有焦点.如何得到消息?
  • 打赏
  • 举报
回复
我的天,现成的
procedure TForm1.Image1Click(Sender: TObject);
begin

end;

祝:身体健康!
tolimit 2002-10-20
  • 打赏
  • 举报
回复
这个有什么不明白的啊,道理是一样的啊

5,388

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧