本人最近在写一个自定义控件,其中有一功能是:在捕获鼠标左键按下消息的同时检测ctrl键的状态,按下和没按的处理不一样。我写了一个鼠标左键按下的处理过程,希望在此过程内获取ctrl键的状态
procedure WM_Click(var Msg: TWMLButtonDown); message WM_LBUTTONDOWN;//鼠标单击通过查找资料,得知有个api函数GetKeyState可以实现,但是由于这段时间正在学习vcl,想看看vcl是怎么实现的,结果发现其不是使用该函数,且很多细节看不太懂,现罗列出来,望高人指点:----------------------------------------------------------------------------------------
以下代码截自tctrol,众所周知,OnMouseDown的事件处理大致如下WMLButtonDown->DoMouseDown->MouseDownWMLButtonDown(var Message: TWMLButtonDown);
DoMouseDown(var Message: TWMMouse; Button: TMouseButton; Shift: TShiftState);
MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);这三个过程的参数是逐渐增加,=======我的问题就是这个增加的参数是怎么来的?=======请看疑问注释:--------------------------------------------------------------------------------
procedure TControl.MouseDown(Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if Assigned(FOnMouseDown) then FOnMouseDown(Self, Button, Shift, X, Y);
end;procedure TControl.DoMouseDown(var Message: TWMMouse; Button: TMouseButton;
Shift: TShiftState);
begin
if not (csNoStdEvents in ControlStyle) then
with Message do
if (Width > 32768) or (Height > 32768) then
with CalcCursorPos do
MouseDown(Button, KeysToShiftState(Keys) + Shift, X, Y) {
KeysToShiftState(Keys)函数原型在后面[功能就是取得哪些功能键被按下吧,shift参数的实际内容就是在这增加的],+shift,从调用它的DoMouseDown(Message, mbLeft, [])语句来看,实参在此已经是空集了,还加上有何用意? 它的keys参数是哪里来的,找遍整个单元也没见哪里有声明过, X,Y也是,不知从何而来?
} else
MouseDown(Button, KeysToShiftState(Keys) + Shift, Message.XPos, Message.YPos);
end;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;
-------------------------------------------------------------------------
function KeysToShiftState(Keys: Word): TShiftState;
begin
Result := [];
if Keys and MK_SHIFT <> 0 then Include(Result, ssShift);
if Keys and MK_CONTROL <> 0 then Include(Result, ssCtrl);
if Keys and MK_LBUTTON <> 0 then Include(Result, ssLeft);
if Keys and MK_RBUTTON <> 0 then Include(Result, ssRight);
if Keys and MK_MBUTTON <> 0 then Include(Result, ssMiddle);
if GetKeyState(VK_MENU) < 0 then Include(Result, ssAlt);
end;
procedure WM_Click(var Msg: TWMLButtonDown); message WM_LBUTTONDOWN;//鼠标单击通过查找资料,得知有个api函数GetKeyState可以实现,但是由于这段时间正在学习vcl,想看看vcl是怎么实现的,结果发现其不是使用该函数,且很多细节看不太懂,现罗列出来,望高人指点:----------------------------------------------------------------------------------------
以下代码截自tctrol,众所周知,OnMouseDown的事件处理大致如下WMLButtonDown->DoMouseDown->MouseDownWMLButtonDown(var Message: TWMLButtonDown);
DoMouseDown(var Message: TWMMouse; Button: TMouseButton; Shift: TShiftState);
MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);这三个过程的参数是逐渐增加,=======我的问题就是这个增加的参数是怎么来的?=======请看疑问注释:--------------------------------------------------------------------------------
procedure TControl.MouseDown(Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if Assigned(FOnMouseDown) then FOnMouseDown(Self, Button, Shift, X, Y);
end;procedure TControl.DoMouseDown(var Message: TWMMouse; Button: TMouseButton;
Shift: TShiftState);
begin
if not (csNoStdEvents in ControlStyle) then
with Message do
if (Width > 32768) or (Height > 32768) then
with CalcCursorPos do
MouseDown(Button, KeysToShiftState(Keys) + Shift, X, Y) {
KeysToShiftState(Keys)函数原型在后面[功能就是取得哪些功能键被按下吧,shift参数的实际内容就是在这增加的],+shift,从调用它的DoMouseDown(Message, mbLeft, [])语句来看,实参在此已经是空集了,还加上有何用意? 它的keys参数是哪里来的,找遍整个单元也没见哪里有声明过, X,Y也是,不知从何而来?
} else
MouseDown(Button, KeysToShiftState(Keys) + Shift, Message.XPos, Message.YPos);
end;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;
-------------------------------------------------------------------------
function KeysToShiftState(Keys: Word): TShiftState;
begin
Result := [];
if Keys and MK_SHIFT <> 0 then Include(Result, ssShift);
if Keys and MK_CONTROL <> 0 then Include(Result, ssCtrl);
if Keys and MK_LBUTTON <> 0 then Include(Result, ssLeft);
if Keys and MK_RBUTTON <> 0 then Include(Result, ssRight);
if Keys and MK_MBUTTON <> 0 then Include(Result, ssMiddle);
if GetKeyState(VK_MENU) < 0 then Include(Result, ssAlt);
end;
解决方案 »
- Clientdataset.filter的问题请救?
- Delphi中怎么把内容生成WORD文档?
- 小问题:你如何把数据发送到在服务器背后的某台客户端(用在WAN上)?
- Delphi中SQL查询问题,有点难(在线等待)
- 一个关于CreateOleObject的问题
- 一个简单的DELPHI问题
- 我快疯了,有关报表的一个简单的问题,帮帮忙!
- 哪里可以下载ADO安装程序(delphi)
- 在下正在学PHP4.0,可是 Apache+php4.0在我的机子上配置不起来,能否指教一下具体的 配置方法吗?甚望!多谢了!
- delphi中如何判断一个文件夹是否存在?谢谢!
- 急急急~~~~~~~!请各位高手们帮帮我这个菜鸟!~~~
- 有哪位给ehlib DBgridEH加了“分组显示”的工能了吗?
Shift: TShiftState; X, Y: Integer) of object; //声明property OnMouseDown: TMouseEvent read FOnMouseDown write FOnMouseDown;FOnMouseDown: TMouseEvent; 定义
procedure TControl.MouseDown(Button: TMouseButton;
Shift: TShiftState; X, Y: Integer); //调用
begin
if Assigned(FOnMouseDown) then FOnMouseDown(Self, Button, Shift, X, Y); //对应上
end;procedure TControl.DoMouseDown(var Message: TWMMouse; Button: TMouseButton;
Shift: TShiftState);
begin
if not (csNoStdEvents in ControlStyle) then
with Message do
if (Width > 32768) or (Height > 32768) then
with CalcCursorPos do
MouseDown(Button, KeysToShiftState(Keys) + Shift, X, Y)
else
MouseDown(Button, KeysToShiftState(Keys) + Shift, Message.XPos, Message.YPos);
//调用MouseDown
end; procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
//处理消息
end;
当MouseDown按下了后,系统告诉程序鼠标按下
TControl.DoMouseDown->调用MouseDown->调用FOnMouseDown->TMouseEvent-> 找到代码FormMouseDown
开始执行你的代码
KeysToShiftState(Keys)函数原型在后面[功能就是取得哪些功能键被按下吧,shift参数的实际内容就是在这增加的],+shift,从调用它的DoMouseDown(Message, mbLeft, [])语句来看,实参在此已经是空集了,还加上有何用意? 它的keys参数是哪里来的,找遍整个单元也没见哪里有声明过, X,Y也是,不知从何而来?
}
---------------------------------------------------------------
昨天又看到了 TControl.WndProc(var Message: TMessage)过程的代码,其实它就是用GetKeyState来获取功能键状态的。
begin
SendCancelMode(Self);
inherited;
if csCaptureMouse in ControlStyle then MouseCapture := True;
if csClickEvents in ControlStyle then Include(FControlState, csClicked);
DoMouseDown(Message, mbLeft, []);//mbLeft
end;procedure TControl.WMLButtonDblClk(var Message: TWMLButtonDblClk);
begin
SendCancelMode(Self);
inherited;
if csCaptureMouse in ControlStyle then MouseCapture := True;
if csClickEvents in ControlStyle then DblClick;
DoMouseDown(Message, mbLeft, [ssDouble]); //不空吧
end;procedure TControl.DoMouseDown(var Message: TWMMouse; Button: TMouseButton;
Shift: TShiftState);
begin
if not (csNoStdEvents in ControlStyle) then
with Message do
if (Width > 32768) or (Height > 32768) then
with CalcCursorPos do
MouseDown(Button, KeysToShiftState(Keys) + Shift, X, Y)
else
MouseDown(Button, KeysToShiftState(Keys) + Shift, Message.XPos, Message.YPos);
end;MouseDown(Button, KeysToShiftState(Keys) + Shift, Message.XPos, Message.YPos); //不就有x,y了
放分,谢谢几位关注。