Delphi 中 鼠标的移动消息

Delphi 中 鼠标的移动消息,第1张

核心方法是调用API——SendInput,简单举例如下:

var

rInput : TInput;

FillChar( rInput, SizeOf( rInput ), 0 );

rInputItype := INPUT_MOUSE; // 鼠标消息

rInputmidx := 0; // 指针横坐标

rInputmidy := 0; // 指针纵坐标

rInputmidwFlags := MOUSEEVENTF_MOVE; // 移动指针

SendInput( 1, @rInput, SizeOf( rInput ) ); // 发送消息(鼠标)

FillChar( rInput, SizeOf( rInput ), 0 );

rInputItype := INPUT_KEYBOARD; // 键盘消息

rInputkiwVk := VK_LEFT; // 左箭头的键码

rInputkidwFlags := KEYEVENTF_KEYUP; // 指示键被抬起,如没有本行,则表示按下

SendInput( 1, @rInput, SizeOf( rInput ) ); // 发送消息(左箭头)

更详细的例子不大好弄,和具体意图十分相关,还是看看MSDN关于SendInput、MOUSEINPUT、KEYBDINPUT的说明吧。

需要注意的是发送鼠标消息时,指针坐标是虚拟坐标系——[ 0, 0 ]~[ 65535, 65535 ],而不是显卡、屏幕分辨率数值范围,因此,需要类似如下方法进行转换。

procedure ClientToVirtual( const H : HWND; const PMI : PMouseInput );

const

{ 鼠标指针坐标采用虚拟坐标系:[ 0, 0 ] ~ [ 65535, 65535 ] }

{ 参见API函数SendInput }

C_n_VirtualWidth = 65536;

C_n_VirtualHeight = 65536;

var

P : TPoint;

begin

PX := PMIdx;

PY := PMIdy;

ClientToScreen( H, P );

PMIdx := PX C_n_VirtualWidth div ScreenWidth;

PMIdy := PY C_n_VirtualHeight div ScreenHeight;

end;

该函数涉及到一个窗口句柄,它的获得可以通过调用EnumWindow枚举、调用FindWindow查找,也可以设为通过其它方法了解到的立即数(如Spy++等),一般来说,发送消息是要指定向谁发送的,但SendInput接口中没有HWND参数,就需要调用SetForegroundWindow把期望的窗口提升到顶层

综上,弄这个还是需要掌握不少相关知识的,没有什么捷径,看MSDN实乃正解。

最简单的办法可以在控件的onContextPopup事件中写。

例如可以在button1的onContextPopup事件中写

Button1Click(nil);

这样在button1上点右键的时候就实现了点击左键的效果

复杂一点的可以利用消息机制,获取消息

以下代码实现在ContentEdit(文本编辑器)中三击鼠标选中一整行的功能。

先定义4个全局变量

FIsThreeClicking: Boolean; //三击事件(是否)进行中

FCurMouseX: Integer;

FCurMouseY: Integer; //三击时的坐标校验

FStartTime: Double; //用于实现鼠标三击事件

事件FormCreate 中初始化变量

procedure TFormMDIChildFormCreate(Sender: TObject);

begin

FIsThreeClicking := False;

FStartTime := 0;

end;

控件的KeyDown事件中

procedure TFormMDIChildContentEditKeyDown(Sender: TObject; var Key: Word;

Shift: TShiftState);

begin

if FIsThreeClicking then //正处于三击事件时,屏蔽掉按键

begin

Key := 0;

Exit;

end;

end;

控件的MouseUp事件中

procedure TFormMDIChildContentEditMouseUp(Sender: TObject;

Button: TMouseButton; Shift: TShiftState; X, Y: Integer);

var

pointBB, pointBE: TPoint;

bSelectFromTop: Boolean;

begin

if FIsThreeClicking then

begin

FIsThreeClicking := False; //三击事件结束

FStartTime := 0;

with ContentEdit do

begin

//恢复为正常选择模式,并选中指定块

if SelectionMode = smLine then

begin

SelectionMode := smNormal;

//if SelAvail then

begin

if (BlockBeginy > BlockEndy)

or ((BlockBeginy = BlockEndy)

and (BlockBeginx > BlockEndx)) then

begin

pointBB := BlockEnd;

pointBE := BlockBegin;

end //如果块是从下往上选择

else begin

pointBB := BlockBegin;

pointBE := BlockEnd;

end; //否则正常

if CaretY = pointBEy then

bSelectFromTop := True

else

bSelectFromTop := False;

pointBBx := 1;

if pointBEy < LinesCount then

begin

pointBEx := 1;

pointBEy := pointBEy + 1;

end

else begin

pointBEx := Length(Lines[pointBEy-1]) + 1;

pointBEy := pointBEy;

end;

BlockBegin := pointBB;

BlockEnd := pointBE;

if bSelectFromTop then

CaretXY := pointBE

else

CaretXY := pointBB;

end;

end; //三击后恢复选择模式

if [eoNoCaret] Options = [eoNoCaret] then

begin

Options := Options - [eoNoCaret];

end; //三击后恢复光标(不是鼠标)

end;

end;

end;

procedure TFormMDIChildContentEditMouseDown(Sender: TObject;

Button: TMouseButton; Shift: TShiftState; X, Y: Integer);

begin

if Button = mbLeft then

begin

with ContentEdit do

begin

if (GetTickCount - FStartTime < GetDoubleClickTime)

{如果当前时间 - 双击时的时间 < 系统的双击间隔时间——即当前动作为三击}

and (PixelsToRowColumn(Point(FCurMouseX, FCurMouseY))x = PixelsToRowColumn(Point(X, Y))x)

and (PixelsToRowColumn(Point(FCurMouseX, FCurMouseY))y = PixelsToRowColumn(Point(X, Y))y)

{当前坐标 = 双击时的坐标}

then begin

Options := Options - [eoDragDropEditing]; //不允许拖动(MouseDown 事件中处理中用到)

PostMessage(SelfHandle, WM_THREECLICK, 0, 0); //发送消息到消息队列

end //因为 MouseDown 后 SynEdit 要进行一些处理,而这些处理与三击事件的处理

//代码在顺序上有冲突,故通过消息队列来安排事件处理顺序

else begin

FCurMouseX := X;

FCurMouseY := Y; //保存当前 Mouse X,Y

end;

end;

end;

end;

procedure WmContentEditThreeClick(var Message: TMessage); message WM_THREECLICK; //处理鼠标三击事件

procedure TFormMDIChildWmContentEditThreeClick(var Message: TMessage);

{三击时选中全行}

var

pointCaretXY: TPoint;

begin

FIsThreeClicking := True; //三击事件进行中

with ContentEdit do

begin

Options := Options + [eoDragDropEditing]; //恢复拖动

SelectionMode := smLine; //改为双击选中行模式

pointCaretXYx := 1;

pointCaretXYy := CaretXYy;

BlockBegin := pointCaretXY;

pointCaretXYx := Length(LineText) + 1;

BlockEnd := pointCaretXY; //选中全行

if [eoNoCaret] Options <> [eoNoCaret] then

begin

Options := Options + [eoNoCaret]; //隐藏光标

end;

end;

end;

◇[DELPHI]网络邻居复制文件uses shellapi;copyfile(pchar( newfile txt ) pchar( //putername/direction/targer txt ) false);◇[DELPHI]产生鼠标拖动效果通过MouseMove事件 DragOver事件 EndDrag事件实现 例如在PANEL上的LABEL var xpanel ypanel xlabel ylabel:integer;PANEL的MouseMove事件 xpanel:=x;ypanel:=y;PANEL的DragOver事件 xpanel:=x;ypanel:=y;LABEL的MouseMove事件 xlabel:=x;ylabel:=y;LABEL的EndDrag事件 label left:=xpanel xlabel;label top:=ypanel ylabel;◇[DELPHI]取得WINDOWS目录uses shellapi;var windir:array[ ] of char;geindowsdirectory(windir sizeof(windir));或者从注册表中读取 位置 HKEY_LOCAL_MACHINE\Sofare\Microsoft\Windows\CurrentVersionSystemRoot键 取得如 C:\WINDOWS◇[DELPHI]在form或其他容器上画线var x y:array [ ] of integer;lor:=clred;canvas pen style:=psDash;form canvas moveto(trunc(x[i]) trunc(y[i]));form canvas lineto(trunc(x[j]) trunc(y[j]));◇[DELPHI]字符串列表使用var tips:tstringlist;tips:=tstringlist create;tips loadfromfile( filename txt );edit text:=tips[ ];tips add( last line addition string );tips insert( insert string at NO line );tips savetofile( newfile txt );tips free;◇[DELPHI]简单的剪贴板 *** 作richedit selectall;pytoclipboard;richedit cuttoclipboard;edit pastefromclipboard;◇[DELPHI]关于文件 目录 *** 作Chdir( c:\abcdir );转到目录Mkdir( dirname );建立目录Rmdir( dirname );删除目录GetCurrentDir;//取当前目录名 无 \ Getdir( s);//取工作目录名s:= c:\abcdir ;Deletfile( abc txt );//删除文件Renamefile( old txt new txt );//文件更名ExtractFilename(filelistbox filename);//取文件名ExtractFileExt(filelistbox filename);//取文件后缀◇[DELPHI]处理文件属性attr:=filegetattr(filelistbox filename);if (attr and faReadonly)=faReadonly then //只读if (attr and faSysfile)=faSysfile then //系统if (attr and faArchive)=faArchive then //存档if (attr and faHidden)=faHidden then //隐藏◇[DELPHI]执行程序外文件WINEXEC//调用可执行文件winexec( /c copy c:\ SW_Normal);winexec( start abc txt );ShellExecute或ShellExecuteEx//启动文件关联程序function executefile(const filename params defaultDir:string;showCmd:integer):THandle;ExecuteFile( C:\abc\a txt x abc c:\abc\ );ExecuteFile( );ExecuteFile( mailto: );◇[DELPHI]取得系统运行的进程名var hCurrentWindow:HWnd;szText:array[ ] of char;beginhCurrentWindow:=Geindow(handle GW_HWndFrist);while hCurrentWindow <> dobeginif Geindowtext(hcurrneindow @sztext )> then ems add(strpas(@sztext));hCurrentWindow:=Geindow(hCurrenindow GW_HWndNext);end;end;◇[DELPHI]关于汇编的嵌入A End;可以任意修改EAX ECX EDX 不能修改ESI EDI ESP EBP EBX ◇[DELPHI]关于类型转换函数FloatToStr//浮点转字符串FloatToStrF//带格式的浮点转字符串IntToHex//整数转 进制TimeToStrDateToStrDateTimeToStrFmtStr//按指定格式输出字符串formatDateTime( YYYY MM DD hh mm ss DATE);◇[DELPHI]字符串的过程和函数Insert(obj target pos);//字符串target插入在pos的位置 如插入结果大于target最大长度 多出字符将被截掉 如Pos在 以外 会产生运行错 例如 st:= Brian 则Insert( OK st )会使st变为 BrOKian Delete(st pos Num);//从st串中的pos(整型)位置开始删去个数为Num(整型)个字符的子字串 例如 st:= Brian 则Delete(st )将变为Brn Str(value st);//将数值value(整型或实型)转换成字符串放在st中 例如 a= E 时 则str(a: st)将使st的值为 Val(st var code);//把字符串表达式st转换为对应整型或实型数值 存放在var中 St必须是一个表示数值的字符串 并符合数值常数的规则 在转换过程中 如果没有检测出错误 变量code置为 否则置为第一个出错字符的位置 例如 st:= E x是一个实型变量 则val(st x code)将使X值为 code值为 Copy(st pos num);//返回st串中一个位置pos(整型)处开始的 含有num(整型)个字符的子串 如果pos大于st字符串的长度 那就会返回一个空串 如果pos在 以外 会引起运行错误 例如 st:= Brian 则Copy(st )返回 ri Concat(st st st …… stn);//把所有自变量表示出的字符串按所给出的顺序连接起来 并返回连接后的值 如果结果的长度 将产生运行错误 例如 st := Brian st := st := Wilfred 则Concat(st st st )返回 Brian Wilfred Length(st);//返回字符串表达式st的长度 例如 st:= Brian 则Length(st)返回值为 Pos(obj target);//返回字符串obj在目标字符串target的第一次出现的位置 如果target没有匹配的串 Pos函数的返回值为 例如 target:= Brian Wilfred 则Pos( Wil target)的返回值是 Pos( hurbet target)的返回值是 ◇[DELPHI]关于处理注册表uses Registry;var reg:Tregistry;reg:=Tregistry create;reg rootkey:= HKey_Current_User ;reg openkey( Control Panel\Desktop false);reg WriteString( Title Wallpaper );reg writeString( Wallpaper filelistbox filename);reg closereg;reg free;◇[DELPHI]关于键盘常量名VK_BACK/VK_TAB/VK_RETURN/VK_SHIFT/VK_CONTROL/VK_MENU/VK_PAUSE/VK_ESCAPE/VK_SPACE/VK_LEFT/VK_RIGHT/VK_UP/VK_DOWNF F $ ( ) $ B( )A Z $ ( ) $ A( ) $ ( ) $ ( )◇[DELPHI]初步判断程序母语DELPHI软件的DOS提示 This Program Must Be Run Under Win VC++软件的DOS提示 This Program Cannot Be Run In DOS Mode ◇[DELPHI] *** 作Cookieokies( name ) domain:= ;with okies add dobeginname:= username ;value:= username ;end◇[DELPHI]增加到文档菜单连接uses shellapi shlOBJ;shAddToRecentDocs(shArd_path pchar(filepath));//增加连接shAddToRecentDocs(shArd_path nil);//清空◇[杂类]备份智能ABC输入法词库windows\system\user remwindows\system\tmmr rem◇[DELPHI]判断鼠标按键if GetAsyncKeyState(VK_LButton)<> then //左键if GetAsyncKeyState(VK_MButton)<> then //中键if GetAsyncKeyState(VK_RButton)<> then //右键◇[DELPHI]设置窗体的最大显示onformCreate事件self width:=screen width;self height:=screen height;◇[DELPHI]按键接受消息OnCreate事件中处理 Application OnMessage:=MyOnMessage;procedure Tform MyOnMessage(var MSG:TMSG;var Handle:Boolean);beginif ssage= then //ANY键if ssage= then //F if ssage= then //F end;◇[杂类]隐藏共享文件夹共享效果 可访问 但不可见(在资源管理 网络邻居中)取共享名为 direction$访问 //puter/dirction/◇[Java Script]Java Script网页常用效果网页 秒定时关闭关闭窗口关闭定时转URL设为首页设为首页收藏本站收藏本站加入频道加入频道◇[DELPHI]随机产生文本色randomize;//随机种子lor:=rgb(random( ) random( ) random( ));◇[DELPHI]DELPHI UPDATE升级补丁序列号 X fx ◇[DELPHI]文件名的非法字符过滤for i:= to length(s) doif s[i] in [ \ / : < > | ] then◇[DELPHI]转换函数的定义及说明datetimetofiledate (datetime:Tdate lishixinzhi/Article/program/Delphi/201311/8427

以下是我编写的示例代码,完成这个示例,需要三个文件:

1 dll工程文件, testdll:

library testDll;

uses

SysUtils,

Classes,

Forms,

FormDll in 'FormDllpas' {frmDll};

{$R RES}

function GetDllForm: TForm; stdcall; export;

begin

Result := frmDll;

end;

exports

GetDllForm;

begin

end

2 dll中包含的窗体,窗体有一个按钮,FormDllpas:

unit FormDll;

interface

uses

Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

Dialogs, StdCtrls;

type

TfrmDll = class(TForm)

Button1: TButton;

procedure Button1Click(Sender: TObject);

private

{ Private declarations }

public

{ Public declarations }

end;

var

frmDll: TfrmDll;

implementation

{$R dfm}

procedure TfrmDllButton1Click(Sender: TObject);

begin

MessageDlg('你已经成功使用了DLL窗体。',  mtInformation, [mbOK], 0);

end;

initialization

begin

frmDll := TfrmDllCreate(Application);

end;

finalization

begin

frmDllFree;

end;

end

3 调用dll窗体的文件,testdllpas:

unit testdll;

interface

uses

Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

Dialogs, StdCtrls;

type

TForm2 = class(TForm)

Button1: TButton;

procedure Button1Click(Sender: TObject);

private

{ Private declarations }

public

{ Public declarations }

end;

var

Form2: TForm2;

function GetDllForm: TForm;

implementation

{$R dfm}

function GetDllForm: TForm; external 'testdlldll';

procedure TForm2Button1Click(Sender: TObject);

var

AForm: TForm;

begin

AForm := GetDLLForm;

AFormShow;

end;

end

4 显示结果:

您可以这样写:(D7下已经通过了)

procedure TForm1FormMouseMove(Sender: TObject; Shift: TShiftState; X,

Y: Integer);

var

strpos:string; //定义整形变量

begin

strpos:=format('X=%3d, Y=%3d',[x,y]); //获取鼠标指针的当前坐标

statusbar1panels[0]text:=strpos; //输出鼠标指针的当前坐标

Edit1Text := intToStr(x);

Edit2Text := intToStr(y);

end;

窗体unit1全部源码为:

unit Unit1;

interface

uses

Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

Dialogs, StdCtrls, ComCtrls;

type

TForm1 = class(TForm)

Edit1: TEdit;

StatusBar1: TStatusBar;

Edit2: TEdit;

Label1: TLabel;

Label2: TLabel;

procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X,

Y: Integer);

private

public

end;

var

Form1: TForm1;

implementation

procedure TForm1FormMouseMove(Sender: TObject; Shift: TShiftState; X,

Y: Integer);

var

strpos:string; //定义整形变量

begin

strpos:=format('X=%3d, Y=%3d',[x,y]); //获取鼠标指针的当前坐标

statusbar1panels[0]text:=strpos; //输出鼠标指针的当前坐标

Edit1Text := intToStr(x);

Edit2Text := intToStr(y);

end;

end

------------------------------------------------

窗体上定义2个Edit组件,分别叫edit1和edit2,有定义一个statusbar组件叫statusbar1,对statusbar1进行编辑,起码有一个元素panels[0],其width=150,这些是基本条件,你早就知道了。

按照以上做法就可以在 edit1上显示x值,edit2上显示y值,在状态条上显示x和y值

-----------------------------------------------

以上就是关于Delphi 中 鼠标的移动消息全部的内容,包括:Delphi 中 鼠标的移动消息、delphi如何实现鼠标右键事件变为鼠标左键事件,、delphi 如何实现三击鼠标事件等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/9690425.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-01
下一篇2023-05-01

发表评论

登录后才能评论

评论列表(0条)

    保存