
核心方法是调用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 如何实现三击鼠标事件等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)