[Delphi]罗技无限灵貂,驱动程序扩展补丁-Logz V3.0 (所有四向滚轮鼠标、应用窗体对话框均能通用)

 
摘要:利用Delphi6自己开发的后台程序,在官方提供的SetPoint V2.40驱动程序以及笔者自行编写的扩展补丁V1.0、V2.0的基础上,再一次自定义扩展了鼠标上的众多功能键,连滚轮的功能也扩展了。并且使用了配置文件,更加通用。关键字:Delphi、Windows API、消息、钩子、四向(横向)滚轮、灵貂(多媒体)、LX5、罗技Logz、热键、剪贴板、配置文件。
 
██████████ 注意
 
    请使用Fixedsys、Courier New等“中英文等间距”的字体浏览本文!
 
██████████ 前传
 
    [Delphi]罗技无限灵貂Logz,驱动程序补丁─实现真正的多媒体遥控器!附QQ图标,标题栏伪装程序(Patch2)
    http://blog.csdn.net/ACDSeeQ/archive/2005/12.aspx
 
██████████ 前言
 
    05年8月买完灵貂,并且自定义扩展了鼠标功能键的功能后,使用到现在,用着真TMD爽。而且不少网友买完灵貂后纷纷向我索要扩展补丁,令我十分欣喜,可以和别人共同分享我的“小聪明”,呵呵。但新的问题又有了,于是又开始有了新的需求。
   
    公司除了为我们软件部每人配台Notebook之外,在办公室每人又配了台PC,而且显示器是17"液晶的。平常我在办公室更喜欢用PC,写了一个映射驱动器的批处理文件,一点击之后,就可以把Notebook当成服务器用了,充分发挥17"液晶的价值。因此灵貂就要在不停地在两台电脑之间切换,有的时候笔记本用灵貂的时候,PC也要临时用下鼠标,只好插上一个小光电鼠标对付一下,但用着很不爽。突然想起了白云大妈的一句名言——程序员对自己下手就要狠一点!于是痛下决心,再去买一个Logz无线鼠标。
   
    本来05年初的时候买过一个Logz无线鼠标——旋貂极光版(我的第一个无线鼠标,从此拉开了我的‘无线&伸缩’时代,呵呵),可到了8月突然坏了(后文交代处理结果)。已经用惯了无线,并且打算升级,因此也就懒得去修理,直接买的灵貂。这次就不用再买个灵貂了,太TMD贵了!主要是为了PC临时用的,所以买个便宜点的就够了,上网又收集了一下资料并且打电话到上一次的教化专卖店,最终以190的价格又捧回了一个LX5,虽然没有灵貂那么多的多媒体功能键,但滚轮是四向的,可以横向滚动,就是下按的时候手感有些硬,不过用胜于无么。(比较了一下,LX5的中键手感不如罗技的其它产品,旋貂都比它强!不推荐大家买LX5,我是买了就没办法了。)
   
    拿回来用以后,无论是在PC上临时用,还是在笔记本上临时用,少了很多灵貂的扩展功能,觉得相当不习惯。于是琢磨着,怎么把灵貂的扩展功能做的更通用一些,让LX5也能用上呢?LX5除了左右键,有三个可以自定义的功能键——中键(即滚轮下按)、左滚右滚(横向滚轮)。仔细一想,其实横向滚轮用的机会不是很多,真要是有用到的时候,多费点事,左键按住滚动条滚动就可以了。打个比方,汽车都会把喇叭、转向指示灯和方向盘做在一起,决不会把调整收音机的音量、播放CD这些东西放在方向盘上,放上了也是鸡肋,除了显得技术含量高,实用价值不大(但有些中高档车的确已经做到了)。于是决定埫横滚作为两个鼠标共享扩展功能的接口。又经过在官方程序中可以利用的功能中的一番挑选,并考虑到笔者本人编程实力有限,决定为横滚指定快捷键(即组合键、热键)来作为共享扩展功能的接口。如此一来,天下所有滚轮可以四向滚动的鼠标都可以使用我的驱动补丁了,只要鼠标自带的驱动可以为横滚指定按键组合。——此为v2.0
   
    此外,在同事的强烈建议之下,决定将扩展功能写到配置文件中,这样一来,可以更加通用,不会仅仅局限在笔者本人最常使用的软件的范围内,让每个横向滚轮鼠标的用户都能发挥他们手中的鼠标的强大功能!欲使新的配置生效,只需重新注销、登录(如果是灵貂,只需按Shift+Alt+PP *^-^* )。——此为v3.0
 
██████████ 术语约定
 
 官方驱动:SetPoint V2.40
 扩展补丁、自定义补丁:Logz V3.0
 
 普通鼠标——
    中键:滚轮下按
 四向鼠标——
    左滚:滚轮向左掰
    右滚:滚轮向右掰
    横滚:左滚or右滚
 灵貂——
    UU:向上浏览
    DD:向下浏览
    PP:Play/Pause >||
    FF:Forward    >>
    BB:Backward   <<
 
██████████ 笔者的 SetPoint 设置
 
 版本——
    2.40 2.47 2.60 不好使,鸡肋)
 灵貂、LX5——
    中键:Close
    左滚[LogzHotKey0]:Shift+Alt+0 (先按0,再按Shift+Alt)
    右滚[LogzHotKey1]:Shift+Alt+1 (这两个按键组合不要被系统中已有的应用软件占用)
 灵貂——
    Media:Ctrl+F4
    UU:向上浏览(缺省)
    DD:向下浏览(缺省)
 
██████████ 驱动补丁嵌入的扩展功能明细
 
 
◎◎◎◎ 关闭补丁程序=Ctrl+Shift+Alt+PP
 
 
◎◎◎◎ 重新加载配置=Shift+Alt+PP(for 灵貂 only)
 
 
◎◎◎ ACD SYSTEMS
 
  ⊙⊙ ACDSee 5.0 Viewer
 
    左滚:* (缩小至全屏查看)
    右滚:/ (放大至实际大小)
    (看起图片来,真TMD方便!)
 
  ⊙⊙ ACD FotoCanvas
 
    ⊙ Resize
 
    左滚:36% (缩小图片至36%并回车确定,为了和FotoCanvas的左滚保持一致)
    右滚:[待定]
 
    ⊙ Edit Description
 
    左滚:Alt+A、回车
    右滚:[待定]
 
 
◎◎◎ Delphi6
 
    左滚:Ctrl+F9 (编译)
    右滚:F9      (编译并运行)
    PP:F12 (查看窗体)
    FF:Ctrl+F2 (终止编译程序的运行)
    BB:F11 (对象观察器)
    Ctrl+PP:Ctrl+F12 (查看单元)
    Ctrl+BB:Ctrl+F11 (打开工程)
 
 
◎◎◎ MPC
 
    UU:前进10秒
    DD:倒退10秒
 
 
◎◎◎ 影音传送带
 
  ⊙⊙ 主界面
 
    ⊙ 选择要下载的URL
 
    UU、DD:只勾择 .JPG 文件,并模拟点击‘确定’
 
    ⊙ 添加新的下载任务
   
    UU:勾选‘手工开始’单选框,并模拟点击‘确定’
    DD:勾选‘立即开始’单选框,并模拟点击‘确定’
    Ctrl+UU:如果操作系统剪贴板的内容是一段文字,将其填补到‘目录’编辑框中,勾选‘手工开始’单选框,并模拟点击‘确定’
    Ctrl+DD:如果操作系统剪贴板的内容是一段文字,将其填补到‘目录’编辑框中,勾选‘立即开始’单选框,并模拟点击‘确定’
 
 
██████████ 后话
 
    那个后买的LX5,由于中键手感不如我的灵貂和另两个同事的罗技鼠标,拿到代理那儿去换,换了之后还是一个德行,本想算了。不过给我拿出来的新LX5颜色和我的灵貂差不多,于是强词夺理地又要求换了,哈哈。
   
    新版补丁把大量扩展操作转移到了横滚上,因此对罗技无线鼠标的滚轮的机械品质绝对是个考验,希望罗技的制作工艺不会令我失望。
   
    刚买第一个LX5的时候,他们给我的名片上又多了罗技维修处的地址和电话,我一瞧,和我单位离得很近,于是有天午饭后把那个坏了的旋貂拿去了。维修处真TM破呀,和废品收购站差不多。初步断定是接收器坏了,由于旋貂已经停产了,可能会给我换个新的。过了不到十天,我打电话询问进展,说让我过去拿换的新的。去了以后,给我换了个工包的(把一套键鼠套装中的无线旋貂换给我了)。
   
    后来有人告诉我网上罗技最新的驱动是2.47、2.60……等等,于是我升级了驱动,但并未发现有何新颖的创新,界面稍有些改观。不过我的补丁程序不好使了,最后只好把新的驱动卸载,重新安装了2.40版的驱动,补丁又重新好使了,并且继续发挥强大的功能了。看来2.40应该是罗技最稳定的驱动了,hoho。
   
    本人酷爱数码摄影,每次用松下FZ30拍回来的图片,利用ACDSee FotoCanvas 2.0对图片进行PS。如果没有旋转、裁剪这些操作,在驱动补丁的辅助下,PS一张原始的数码图片,连5秒钟都用不了,对于我来说,那-真-是--相当方便了!
   
    我个人在很多自己经常使用的对话框中,将左滚设定为回车键,现在,左滚基本上就相当于半个回车键了,快捷方便!
 
██████████ 图片及下载
 
    如果您手中的鼠标也带有横向滚轮,或者恰巧是罗技的产品,甚至就是罗技无限灵貂,而且对该补丁感兴趣,可以致信作者。
   
    另外,补丁程序将Delphi IDE中的很多资源设为动态链接,因此产生了一个优点和一个缺点。
   
    优点是:文件体积非常小。所有文件加在一起连200k都不到,其中嵌入到程序中的两个美观的图标就占了50k,哈哈。
   
    缺点是:在没有安装Delphi开发环境的计算机中使用,可能会报错说某些文件找不到,那么用户可以自行到网上下载或者给笔者来信索要。目前得到的信息是,这些缺失的文件应当包括——
       
        Name                              Size              Date
        ---------------------------   --------   ---------------
        adortl60.bpl                    146 KB   2002-2-15 14:02
        dbrtl60.bpl                     249 KB   2002-2-15 14:02
        indy60.bpl                      502 KB   2001-5-22 14:00
        qtintf.dll                    4,046 KB   2002-2-15 14:02
        rtl60.bpl                       669 KB    2003-3-20 6:04
        vcl60.bpl                     1,295 KB   2002-2-15 14:02
        visualclx60.bpl               1,035 KB   2002-2-15 14:02
 
    笔者的鼠标实物、官方驱动、自定义补丁的设置放在了163相册里(
http://photo.163.com/photos/logzmouse/),仅供参考。
   
    如要应用补丁,官方驱动的版本以及设置务必与笔者保持一致!
 
██████████ 作者联系方式
 
    如果您有什么改进的建议或者不解的疑问,或是提供更好的编程技巧,或是索要补丁程序,欢迎与作者联系。
 
                                                                ╱╲
╔═══════════════╦══════════════╱㊣╱
║Logz                         ║                    V3.0  ╱  ╱
╟───────────────╫────────────╱  ╱╢
║      木 小 折                ║                        ◣╱  ║
╟───────────────╫───────────────╢
║      子 兀 口                ║    LogzMouse        ║
╟───────────────╫───────────────╢
║            Erngy  Lee    ║            @163.com  ║
╟───────────────╫───────────────╢
║                       2006年║5月                          ║
╚═══════════════╩═══════════════╝
 
 
██████████ URL
 
http://blog.csdn.net/ACDSeeQ/
 
 
██████████ Delphi Source Dode
 
 
//▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ Logz.dpr
 
 
{ 罗技无限灵貂Logz,驱动程序扩展补丁
  V3.0
  且适用于所有罗技四向滚轮鼠标
  作者:Lgz
  日期:2006年5月

┏━━┳━━━━━━┳━━━━┳━━━━━━┓
┃罗技┃     P/N    ┃   M/N  ┃ S/N or PID ┃
┣━━╋━━━━━━╋━━━━╋━━━━━━┫
┃灵貂┃852213-0000 ┃M-RAM99 ┃LZB50154923 ┃
┣━━╋━━━━━━╋━━━━╋━━━━━━┫
┃LX5 ┃831192-3000 ┃C-BN4   ┃LZ547AU     ┃
┗━━┻━━━━━━┻━━━━┻━━━━━━┛
}
program Logz;

uses
  Forms,
  SysUtils,
  Windows,
  DlgDebug_U,
  FrmMediaPlayer_U in 'FrmMediaPlayer_U.pas' {frmMediaPlayer},
  Shared_U in '../../../Delphi/[Public]/Shared_U.pas';

{$R *.res}

begin
  Application.Initialize;

//启动调试
SD_Debug_Show(findCmdLineSwitch('debug', ['/', '-'], true));

  Application.ShowMainForm := False;      //隐藏
  Application.CreateForm(TfrmMediaPlayer, frmMediaPlayer);
  ShowWindow(Application.Handle, SW_HIDE);//隐藏

  Application.Run;
end.
 
 
//▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ FrmMediaPlayer_U.pas
 
 
{ 主界面(后台隐形运行)
  主要利用WndProc以及热键(WMHotKey)捕捉消息并进行处理
  2006年5月
}
//▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
unit FrmMediaPlayer_U; interface
uses Windows, Messages, Forms, CommCtrl, Classes, Controls, StdCtrls, IniFiles,
    ExtCtrls, SysUtils, Dialogs, DlgDebug_U, Clipbrd, Shared_U, Qt, Const_U,
    StrUtils;
//▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
const
    LOGITECH   = $0319;//利用VC的Spy捕捉到的
    PLAY_PAUSE = $E0000;
    PLAY_LEFT  = $C0000;
    PLAY_RIGHT = $B0000;
    LOGZHOTKEYWORD0= 'LogzHotKeyword0';
    LOGZHOTKEYWORD1= 'LogzHotKeyword1';
    ItemNo     = 36;
//▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
type
  TLogzItem = record
  //欲应用补丁的窗体(对话框)的信息,在本程序中,定义为“项目”。详情请参考配置文件
    Onn: Boolean;
    ItemIndex,//[Item01]
    ExecSQL,
    Description,
    Keywords,
    HotGun0,
    HotGun1,
    UU,
    DD,
    PP,
    BB,
    FF,
    Ctrl_HotGun0,
    Ctrl_HotGun1,
    Alt_PP,
    Alt_BB,
    Alt_FF,
    Ctrl_PP,
    Ctrl_BB,
    Ctrl_FF,
    Shift_PP,
    Shift_BB,
    Shift_FF
    : string;
    end;

  TfrmMediaPlayer = class(TForm)
    le: TLabeledEdit;
    Nemo: TMemo;
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure WndProc(var Mssg: TMessage); override;
  private
    { Private declarations }
    hwLogz: HWND;//Window
    tlLogz, clsName: string;//Title, Class
    Buf: array[0..1024] of Char;
    dwnCtrl, dwnShift, dwnAlt: Boolean;//Down
    LogzHotID : array [0..1] of Integer;//热键标识ID
    LogzHotKey: array [0..1] of Boolean;//触发了哪个热键
    Items: array [1..ItemNo] of TLogzItem;//窗体(对话框)信息
    ExecKeys: array [0..2] of byte;//转换后的组合键

    procedure WMLogzHotKey   (var Mssg: TWMHotKey); message WM_HotKey       ;
    procedure WMDrawClipBoard(var Mssg: TMessage ); message WM_DRAWCLIPBOARD;

    procedure LoadConfiguration;
    procedure GetForeWindowInfo;

    function TitleKeyword(theKeyword: string): Boolean;
    function ClassKeyword(theKeyword: string): Boolean;
    function TitleIS(theKeyword: string): Boolean;
    function ClassIS(theKeyword: string): Boolean;
    function KeywordsMatchTitle(const theKeywords: string): Boolean;

    procedure ExecuseMe(theExecSQL: string);
  public
    { Public declarations }
    NextClipHwnd: HWND;//剪贴板观察链中下一个窗口句柄
  end;
//▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
var frmMediaPlayer: TfrmMediaPlayer;

implementation
uses MisCtrls_U;
//▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
//罗技无限灵貂
procedure EnableWheelHook ; stdcall; external 'LogzHook.dll';
procedure DisableWheelHook; stdcall; external 'LogzHook.dll';
procedure Key1(VK1          : byte); external 'LogzHook.dll';
procedure Key2(VK1, VK2     : byte); external 'LogzHook.dll';
procedure Key3(VK1, VK2, VK3: byte); external 'LogzHook.dll';
procedure KeyStr(const theStr: string);external 'LogzHook.dll';
procedure Down(VK: byte);            external 'LogzHook.dll';
procedure UP  (VK: byte);            external 'LogzHook.dll';
function StrToVK(theKeyStr: string): byte; external 'LogzHook.dll';
function VKToStr(theVisKey: byte): string; external 'LogzHook.dll';
procedure LoadVisualKeys;                  external 'LogzHook.dll';
{$R *.dfm}
//▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
procedure TfrmMediaPlayer.FormCreate(Sender: TObject);
//界面初始化
var i: integer;
begin
    FormStyle := fsStayOnTop;

    //复制粘贴要用的
    le.Width := 50000;
    Nemo.Width := le.Width;

    EnableWheelHook;//罗技灵貂蓝色侧键,WM_MouseWheel 消息钩子

    Lgf := 'LogzClip.txt';//剪贴板要用的
    NextClipHwnd:=SetClipBoardViewer(Handle);//获得观察链中下一个窗口句柄

    //配置文件
    Cnf := './Logz.conf';
    Conf:= TIniFile.Create(cnf);
    LoadConfiguration;

    LoadVisualKeys;

    //注册全局热键 Shift+Alt+0/1
    if (GlobalFindAtom(LOGZHOTKEYWORD0)=0)and(GlobalFindAtom(LOGZHOTKEYWORD1)=0) then begin
        LogzHotID[0] := GlobalAddAtom(LOGZHOTKEYWORD0);
        LogzHotID[1] := GlobalAddAtom(LOGZHOTKEYWORD1);
        RegisterHotKey(Handle, LogzHotID[0], MOD_SHIFT or MOD_Alt, Key_0);
        RegisterHotKey(Handle, LogzHotID[1], MOD_SHIFT or MOD_Alt, Key_1);
    end else halt;
end;
//▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
procedure TfrmMediaPlayer.FormClose(Sender: TObject; var Action: TCloseAction);
//程序退出
begin
    //从观察链中删除本观察窗口
    ChangeClipboardChain(Handle, NextClipHwnd);
    //将WM_DRAWCLIPBOARD消息传递到下一个观察链中的窗口
    SendMessage(NextClipHwnd, WM_CHANGECBCHAIN, Handle, NextClipHwnd);

    UnRegisterHotKey(Handle, LogzHotID[0]);  GlobalDeleteAtom(LogzHotID[0]);
    UnRegisterHotKey(Handle, LogzHotID[1]);  GlobalDeleteAtom(LogzHotID[1]);

    DisableWheelHook;
end;
//▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
procedure TfrmMediaPlayer.WndProc(var Mssg: TMessage);
//无限灵貂中右侧三个键
var i: integer;
begin with Mssg do begin
    inherited;

    //如果不是多媒体键区的中右侧三个键按下,则退出
    IF NOT(  (Msg=LOGITECH) AND ((lParam=PLAY_PAUSE)OR(lParam=PLAY_LEFT)OR(lParam=PLAY_RIGHT))  ) THEN exit;
    GetForeWindowInfo;

    //是否刷新配置
    if dwnShift and dwnAlt and (lParam=PLAY_PAUSE) then LoadConfiguration;

    //Close
    if dwnShift and dwnAlt and (lParam=PLAY_PAUSE) and dwnCtrl then Close;

    //以下是一些嵌入代码:为个人定制

    //ACDSee5
    if TitleKeyword('ACDSee') and TitleKeyword('5.0') then begin
        if dwnCtrl then begin//按下了Ctrl键
            Up(VK_Control);
            case lParam of
            PLAY_PAUSE: ;//enumChildWindows(hwLogz, @EnumAseChildWndProc_Less10K, 0);
            end;
        end else if dwnAlt then begin//按下了Alt键
            Up(VK_Menu);
            case lParam of
            //PLAY_PAUSE: enumChildWindows(hwLogz, @EnumAseChildWndProc_Less10K, 0);
            PLAY_LEFT : begin  Key2(VK_Menu, VK_Left);  Key1(VK_F3);  Key2(VK_Menu, ord('S'));  end;
            //PLAY_RIGHT: Key1(VK_DIVIDE );// /
            end;
        end;

        //exit;//不能exit,配置文件里还有ACDSee的信息
    end;

    //Delphi6
    if pos('T', clsName)=1 then begin
        if dwnCtrl then begin
            Up(VK_Control);
            case lParam of
            PLAY_PAUSE: Key2(VK_Control, VK_F12);//Ctrl+F12
            PLAY_LEFT : Key2(VK_Control, VK_F11);//Ctrl+F11, Open Project
            end;
        end else begin
            case lParam of
            PLAY_PAUSE: Key1(VK_F12);//F12
            PLAY_LEFT : Key1(VK_F11);//F11
            PLAY_RIGHT: Key2(VK_Control, VK_F2);//Ctrl+F2
            end;
        end;

        exit;
    end;

    //根据配置文件轮循处理:为大众通用

    for i := 1 to ItemNo do begin
        if not Items[i].Onn then continue;
        if not KeywordsMatchTitle(Items[i].Keywords) then continue;

        if dwnAlt then begin
            Up(VK_Menu);
            case lParam of
            PLAY_PAUSE: Items[i].ExecSQL := Items[i].Alt_PP;
            PLAY_LEFT : Items[i].ExecSQL := Items[i].Alt_BB;
            PLAY_RIGHT: Items[i].ExecSQL := Items[i].Alt_FF;
            end;
        end else if dwnCtrl then begin
            Up(VK_Control);
            case lParam of
            PLAY_PAUSE: Items[i].ExecSQL := Items[i].Ctrl_PP;
            PLAY_LEFT : Items[i].ExecSQL := Items[i].Ctrl_BB;
            PLAY_RIGHT: Items[i].ExecSQL := Items[i].Ctrl_FF;
            end;
        end else if dwnShift then begin
            Up(VK_Shift);
            case lParam of
            PLAY_PAUSE: Items[i].ExecSQL := Items[i].Shift_PP;
            PLAY_LEFT : Items[i].ExecSQL := Items[i].Shift_BB;
            PLAY_RIGHT: Items[i].ExecSQL := Items[i].Shift_FF;
            end;
        end else begin
            case lParam of
            PLAY_PAUSE: Items[i].ExecSQL := Items[i].PP;
            PLAY_LEFT : Items[i].ExecSQL := Items[i].BB;
            PLAY_RIGHT: Items[i].ExecSQL := Items[i].FF;
            end;
        end;

        ExecuseMe(Items[i].ExecSQL);
        break;
    end;
end; end;
//▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
procedure TfrmMediaPlayer.WMDrawClipBoard(var Mssg: TMessage);
//监视剪贴板
begin
    //将WM_DRAWCLIPBOARD消息传递到下一个观察链中的窗口
    SendMessage(NextClipHwnd, Mssg.Msg, Mssg.WParam, Mssg.LParam);

    //查询剪贴板中特定格式的数据内容
    if (Clipboard.HasFormat(CF_TEXT) or Clipboard.HasFormat(CF_OEMTEXT))
    and(pos('Outlook Express', tlLogz)>0) and(pos(
'@', ClipBoard.AsText)>0) then begin
        //处理剪贴板中内容
        sLg_(Lgf, trim(Clipboard.AsText));
        Clipboard.Clear;
    end;
end;
//▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
procedure TfrmMediaPlayer.WMLogzHotKey(var Mssg: TWMHotKey);
//捕获并处理横滚触发的热键
var i, j: integer;
begin
    if (Mssg.HotKey<>LogzHotID[0])and(Mssg.HotKey<>LogzHotID[1]) then exit;
    LogzHotKey[0] := Mssg.HotKey=LogzHotID[0];
    LogzHotKey[1] := Mssg.HotKey=LogzHotID[1];

    UP(VK_Shift);  UP(VK_Menu);  UP(Key_0);  UP(Key_1);
    GetForeWindowInfo;
    //deb(tlLogz);

    //以下是一些嵌入代码:为个人定制

    //ACDSee5
    if ClassIS('ImageViewWndClass')
    or (ClassIS('Afx:400000:8')and TitleKeyword('ACDSee')and TitleKeyword('5.0')) then begin
        if LogzHotKey[0] then Key1(VK_MULTIPLY) else Key1(VK_DIVIDE );// * or /
        Key1(VK_F5);

        exit;
    end;

    if (ClassIS('Afx:400000:0')and TitleKeyword('ACDSee')and TitleKeyword('5.0')) then begin
        if LogzHotKey[0] then Key2(VK_Control, ord('E')) else Key1(VK_F4);
        //exit;//这里不能用exit,否则如果在配置文件中为LogzHotKey0指定了按键组合,就会失效
    end;

    if TitleIS('Resize') then begin//For Panasonic-FZ30 only
        if LogzHotKey[0] then
        begin  Key1(VK_NumPad3);  Key1(VK_NumPad6);  Key1(VK_Return);  end;//36(%)+Return

        exit;
    end;

    if TitleIS('Edit Description') then begin
        if LogzHotKey[0] then
        begin  Key2(VK_Menu, ord('A'));  Key1(VK_Return);  end;

        exit;
    end;

    //Delphi6
    if (pos('T', clsName)=1) then begin
        if LogzHotKey[0] then Key2(VK_Control, VK_F9)//Ctrl+F9 , Compile
        else Key1(VK_F9);//F9=Run

        exit;
    end;

    //影音传送带
    if TitleIS('选择要下载的URL') then begin
        PostMessage(hwLogz, WM_MouseWheel, $03C00000, $007E0104);//照着SPY程序写的

        exit;
    end else if TitleIS('添加新的下载任务') then begin
        if dwnCtrl then begin
            Up(VK_CONTROL);
            Key2(VK_Menu, ord('D'));  Key1(VK_End);  Key2(VK_CONTROL, ord('V'));
        end;

        if LogzHotKey[0] then Key2(VK_Menu, ord('M')) else Key2(VK_Menu, ord('I'));//手工or立即
        Key2(VK_Menu, ord('D'));
        Key1(VK_Return);

        exit;
    end;

    //根据配置文件轮循处理:为大众通用

    for i := 1 to ItemNo do begin
        if not Items[i].Onn then continue;

        //[为pcAnywhere定制:for 孙总 only
        if (pos('pcAnywhere', Items[i].Description)>0)and TitleIS(Items[i].Keywords) then begin
            j := pos('^', Items[i].HotGun0);

            if TitleIS('Credentials') then begin
                Key2(VK_Menu, ord('D'));//&Domain/UserName
                KeyStr(copy(Items[i].HotGun0, 1, j-1));
                Key2(VK_Menu, ord('P'));//&Password
                KeyStr(copy(Items[i].HotGun0, j+1, length(Items[i].HotGun0)-j));
                Key1(VK_Return);
            end;

            if TitleIS('Symantec pcAnywhere - Host Login') then begin
                Key2(VK_Menu, ord('U'));//&User Name
                KeyStr(copy(Items[i].HotGun0, 1, j-1));
                Key2(VK_Menu, ord('P'));//&Password
                KeyStr(copy(Items[i].HotGun0, j+1, length(Items[i].HotGun0)-j));
                Key1(VK_Return);
            end;

            break;
        end;
        //为pcAnywhere定制]

        if not KeywordsMatchTitle(Items[i].Keywords) then continue;

        if dwnCtrl then begin
            Up(VK_Control);
            if LogzHotKey[0] then Items[i].ExecSQL := Items[i].Ctrl_HotGun0
            else Items[i].ExecSQL := Items[i].Ctrl_HotGun1;
        end else begin
            if LogzHotKey[0] then Items[i].ExecSQL := Items[i].HotGun0
            else Items[i].ExecSQL := Items[i].HotGun1;
        end;

        ExecuseMe(Items[i].ExecSQL);
        break;
    end;
end;
//▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
procedure TfrmMediaPlayer.GetForeWindowInfo;
//得到顶层窗体(对话框)的信息
begin
    hwLogz := GetForegroundWindow;
    GetWindowText(hwLogz, buf, 1024);  tlLogz  := string(buf);
    GetClassName (hwLogz, buf, 1024);  clsName := string(buf);

    dwnCtrl := GetKeyState(VK_Control)<0;
    dwnShift:= GetKeyState(VK_Shift  )<0;
    dwnAlt  := GetKeyState(VK_Menu   )<0;
end;
//▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
function TfrmMediaPlayer.TitleKeyword(theKeyword: string): Boolean;
begin  Result := pos(theKeyword, tlLogz)>0  end;
function TfrmMediaPlayer.ClassKeyword(theKeyword: string): Boolean;
begin  Result := pos(theKeyword, clsName)>0  end;

function TfrmMediaPlayer.TitleIS(theKeyword: string): Boolean;
begin  Result := theKeyword=tlLogz;  end;
function TfrmMediaPlayer.ClassIS(theKeyword: string): Boolean;
begin  Result := theKeyword=clsName;  end;
//▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
function TfrmMediaPlayer.KeywordsMatchTitle(const theKeywords: string): Boolean;
//判断顶层窗体(对话框)的标题栏是否与关键字组合相吻合
var j: byte;
    sKw: string;
begin
    sKw := theKeywords;
    if isEmpty(theKeywords) then begin  Result := false;  exit;  end
    else Result := true;

    repeat begin
        j := pos('^', sKw);
        if j=0 then begin
            Result := Result and (pos(sKw, tlLogz)>0);
            sKw := '';
        end else begin
            Result := Result and (pos(leftStr(sKw, j-1), tlLogz)>0);
            sKw := rightStr(sKw, length(sKw)-j);
        end;
    end until not (Result and notEmpty(sKw));
end;
//▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
procedure TfrmMediaPlayer.ExecuseMe(theExecSQL: string);
//执行指定的按键组合
var i, j: integer;
    s: string;
begin
    i := 1;
    j := pos('^', theExecSQL);

    if j>0 then begin
        inc(i);
        ExecKeys[0] := strToVK(leftStr(theExecSQL, j-1));
        s := rightStr(theExecSQL, length(theExecSQL)-j);

        j := pos('^', s);
        if j>0 then begin
            inc(i);
            ExecKeys[1] := strToVK(leftStr(s, j-1));
            s := rightStr(s, length(s)-j);
            ExecKeys[2] := strToVK(s);
        end else ExecKeys[1] := strToVK(s);
       
    end else begin
        ExecKeys[0] := strToVK(theExecSQL);
    end;

    case i of
    1: Key1(ExecKeys[0]);
    2: Key2(ExecKeys[0], ExecKeys[1]);
    3: Key3(ExecKeys[0], ExecKeys[1], ExecKeys[2]);
    end;
end;
//▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
procedure TfrmMediaPlayer.LoadConfiguration;
//读入配置文件信息内容
var i: byte;
begin with Conf do  for i := 1 to ItemNo do begin
    fmtStr(Items[i].ItemIndex, 'Item%s', [intToStr0(i, 2)]);
    Items[i].Onn := ReadBool(Items[i].ItemIndex, 'On', false);
    Items[i].Description := ReadString(Items[i].ItemIndex, 'Description','');
    Items[i].Keywords:= ReadString(Items[i].ItemIndex, 'Keywords','');
    Items[i].HotGun0 := ReadString(Items[i].ItemIndex, 'HotGun0', '');
    Items[i].HotGun1 := ReadString(Items[i].ItemIndex, 'HotGun1', '');
    Items[i].UU := ReadString(Items[i].ItemIndex, 'UU', '');
    Items[i].DD := ReadString(Items[i].ItemIndex, 'DD', '');
    Items[i].PP := ReadString(Items[i].ItemIndex, 'PP', '');
    Items[i].BB := ReadString(Items[i].ItemIndex, 'BB', '');
    Items[i].FF := ReadString(Items[i].ItemIndex, 'FF', '');
    Items[i].Ctrl_HotGun0 := ReadString(Items[i].ItemIndex, 'Ctrl_HotGun0', '');
    Items[i].Ctrl_HotGun1 := ReadString(Items[i].ItemIndex, 'Ctrl_HotGun1', '');
    Items[i].Alt_PP := ReadString(Items[i].ItemIndex, 'Alt_PP', '');
    Items[i].Alt_BB := ReadString(Items[i].ItemIndex, 'Alt_BB', '');
    Items[i].Alt_FF := ReadString(Items[i].ItemIndex, 'Alt_FF', '');
    Items[i].Ctrl_PP := ReadString(Items[i].ItemIndex, 'Ctrl_PP', '');
    Items[i].Ctrl_BB := ReadString(Items[i].ItemIndex, 'Ctrl_BB', '');
    Items[i].Ctrl_FF := ReadString(Items[i].ItemIndex, 'Ctrl_FF', '');
    Items[i].Shift_PP := ReadString(Items[i].ItemIndex, 'Shift_PP', '');
    Items[i].Shift_BB := ReadString(Items[i].ItemIndex, 'Shift_BB', '');
    Items[i].Shift_FF := ReadString(Items[i].ItemIndex, 'Shift_FF', '');
end; end;

end.
 
 
//▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ LogzHook.dpr
 
 
{ 罗技无限灵貂Logz,驱动程序扩展补丁
  V3.0
  作者:Lgz
  日期:2006年5月
  捕捉灵貂‘向上浏览、向下浏览’键发出的消息
}
//▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
library LogzHook;
//▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
uses
  SysUtils,
  Classes,
  LogzHook_U in 'LogzHook_U.pas';
//▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
exports
    EnableWheelHook, DisableWheelHook,
    Key1, Key2, Key3, KeyStr, Down, Up,
    StrToVK, VKToStr, LoadVisualKeys;
//▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
begin
    hkLogzWheel := 0;
    hkQQChat    := 0;
end.
 
 
//▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ LogzHook_U.pas
 
 
{ 主要利用WheelHookProc以及TitleHookProc处理捕捉到的灵貂‘向上、下浏览’键发出的
  消息,并修改QQ聊天窗口的标题。
  此外,放入一些主窗体程序用到的一些过程和函数。
}
//▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
unit LogzHook_U; interface
uses Windows, Messages, Classes, SysUtils, Dialogs, CommCtrl, MisCtrls_U;
//▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
var hkLogzWheel, hkQQChat: HHOOK;//钩子的句柄值
    hwLogzWheel, hwQQChat: HWnd ;
    tlLogzWheel, tlQQChat: string;
    dwnCtrl, dwnShift, dwnAlt: Boolean;//Down
    clsName: string;
    buf: array [0..1024] of char;
    iC: byte;
    zDelta: short;//上下浏览的速度
    rc: TRect;//QQ聊天窗口的特征信息
    wid, hei: integer;
    VisualKeys: TStringList;
//▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
const
    csQQ  = '#32770';//利用VC的Spy捕捉到的
    csRoom= 'Afx:400000:b:0:';
    csMSN = 'IMWindowClass';
//▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
function WheelHookProc(Code: Integer; WParam, Msg: Longint): LRESULT; stdcall;
function TitleHookProc(Code: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
function EnumWindowsTitleFunc(Handle: THandle; lParam: LPARAM): boolean ; stdcall;
function EnableWheelHook : Boolean; stdcall; export;
function DisableWheelHook: Boolean; stdcall; export;
procedure Down(VK: byte);
procedure UP  (VK: byte);
procedure Key1(VK1          : byte);
procedure Key2(VK1, VK2     : byte);
procedure Key3(VK1, VK2, VK3: byte);
procedure KeyStr(const theStr: string);
function TitleKeyword(theKeyword: string): Boolean;
function ClassKeyword(theKeyword: string): Boolean;
function TitleIS(theKeyword: string): Boolean;
function ClassIS(theKeyword: string): Boolean;
procedure GetForeWindowInfo;
procedure LoadVisualKeys;
function StrToVK(theKeyStr: string): byte;
function VKToStr(theVisKey: byte): string;
//▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
implementation
//▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
function EnumNtChildWndProc_JPEG(AhWnd: LongInt; AlParam: lParam): Boolean; StdCall;
//令影音传送带专门下载 .JPG
var WndClassName, WndCaption, pszText1, pszText2: array[0..254] of Char;
    pszStr1: string;
    i: integer;
begin
    GetClassName (AhWnd, wndClassName, 254);
    GetWindowText(AhWnd, WndCaption  , 254);

    //所有的链接,只选中JPG文件,其它的全勾掉
    if (wndClassName='SysListView32') and (WndCaption='List1') then
    for i := 0 to ListView_GetItemCount(AhWnd)-1 do begin
        ListView_GetItemText(AhWnd, i, 1, pszText1, 100);
        ListView_GetItemText(AhWnd, i, 2, pszText2, 100);
        pszStr1 := lowerCase(string(pszText1));

        //正常情况下
        ListView_SetCheckState(AhWnd, i,
                (   (  (pszStr1='.jpg')or(pszStr1='.jpeg')or(pszStr1='.bmp')  )
                and ( pos('small', pszText2)=0 )
                and ( pos('xinsiludcfs', pszText2)=0 )
                and ( pos('bannerr02', pszText2)=0 )
                and ( pos('www.beautyleg.com', pszText2)=0 )
                )
            or
                (   ( pos('http://www.beautyleg.com/', pszText2)>0 )
                and ( pos('attachment', pszText2)>0 )
                )
            );
    end;

    //因为‘取消’是最后一个控件,这个时候再模拟点击‘确定’,否则先点‘确定’关闭对话框
    //也许代码找不到下一个控件了
    if (wndClassName='Button') and (pos('取消', WndCaption)>0) then
        Key2(VK_Menu, ord('O'));

    result:=true;
end;
//▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
function WheelHookProc(Code: Integer; WParam, Msg:Longint): LRESULT; stdcall;
//处理无限灵貂上下浏览键的Wheel钩子
begin
    zDelta := short(HiWord(PMsg(Msg)^.wParam));

    if  (Code=HC_ACTION) and (PMsg(Msg)^.Message=WM_MOUSEWHEEL) and (abs(zDelta)>200) then begin
        GetForeWindowInfo;

        if TitleKeyword('mplayerc')or TitleKeyword('Media Player Classic') then begin
            inc(iC);

            //按一次蓝色侧键产生两条消息,二合一处理的话相当于快进1次,即5秒,
            //都处理的话相当于快进2次,即10秒
            //if (iC mod 2)=0 then begin
                Down(VK_Control);
                if zDelta>200 then Key1(VK_Right) else Key1(VK_Left);
                Up(VK_Control);//CTRL Up
            //end;

            PMsg(Msg)^.Message := 0;//因为侧键消息已经本地处理过了,不必再交给其它线程处理

        end else if TitleIS('选择要下载的URL') then begin//影音传送带
            enumChildWindows(hwLogzWheel, @EnumNtChildWndProc_JPEG, 0);
        end

        else Result := CallNextHookEx(hkLogzWheel, Code, WParam, Longint(@Msg));//如果不是MPC或者影音传送带,则向下传递

    end else Result := CallNextHookEx(hkLogzWheel, Code, WParam, Longint(@Msg));//如果不是两个蓝色侧键则向下传递
end;
//▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
function TitleHookProc(Code: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
//处理QQ聊天对话框的Title钩子
begin
    Result := 0;
   
    if Code<0 then begin
        Result := CallNextHookEx(hkQQChat, Code, wParam, lParam);
        Exit;
    end else if Code=HCBT_ACTIVATE then begin
        hwQQChat := HWND(wParam);

        GetClassName(hwQQChat, buf, 1024);
        clsName := string(buf);

        if clsName=csQQ then begin//QQ聊天对话框
            GetWindowRect(hwQQChat, rc);
            with rc do begin
                wid := right -left;
                hei := bottom-top ;
            end;

            //478,323 or 470,467
            if (wid>400)and(hei>300) then begin
                //inc(ic);

                //if (ic mod 2)=0 then begin
                    EnumWindows(@EnumWindowsTitleFunc, hwQQChat);
                //end;
            end;
        end else if (pos(csRoom, clsName)>0)or(clsName=csMSN) then begin//QQ聊天室orMSN
            EnumWindows(@EnumWindowsTitleFunc, hwQQChat);
        end;
    end;
end;
//▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
function EnumWindowsTitleFunc(Handle: THandle; lParam: LPARAM): boolean ; stdcall;
//伪装聊天窗口的标题栏
begin
    Result := false;

    if (Handle=lParam) and boolean(GetWindowText(Handle, buf, 256)) then begin
        tlQQChat := string(buf);

        //QQ
        if ((pos('与', tlQQChat)>0) and (pos('聊天中', tlQQChat)>0)) then begin
            tlQQChat := StringReplace(tlQQChat, '与'    , '我的文档', []);
            tlQQChat := StringReplace(tlQQChat, '聊天中', ''        , []);
            SetWindowText(Handle, pchar(tlQQChat));
            Result := true;
            exit;
        end;

        if ((pos('群 -', tlQQChat)>0) or (pos('高级群 -', tlQQChat)>0)) then begin
            tlQQChat := StringReplace(tlQQChat, '群 -', '我的信件', []);
            tlQQChat := StringReplace(tlQQChat, '高级' , ''        , []);
            SetWindowText(Handle, pchar(tlQQChat));
            Result := true;
            exit;
        end;

        //聊天室
        if pos('QQ 聊天室', tlQQChat)>0 then begin
            tlQQChat := 'Microsoft Visual C++ 6.2';
            SetWindowText(Handle, pchar(tlQQChat));
            Result := true;
            exit;
        end;

        //MSN
        if pos(' - 对话', tlQQChat)>0 then begin
            tlQQChat := replacing(tlQQChat, ' - 对话' , '工作文档');
            SetWindowText(Handle, pchar(tlQQChat));
            Result := true;
            exit;
        end;
    end;

    Result := true;
end;
//▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
function EnableWheelHook: Boolean; stdcall; export;
//加载钩子
begin
    //罗技鼠标
    if hkLogzWheel=0 then begin
        hkLogzWheel := SetWindowsHookEx(WH_GETMESSAGE, @WheelHookProc, Hinstance, 0);
        Result := True;
    end else Result := False;

    //QQ聊天对话框
    if hkQQChat=0 then begin
        hkQQChat := SetWindowsHookEx(WH_CBT, @TitleHookProc, Hinstance, 0);
        Result := True;
    end else Result := False;
end;
//▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
function DisableWheelHook: Boolean; stdcall; export;
//卸载钩子
begin
    //罗技鼠标
    if hkLogzWheel<>0 then begin
        UnHookWindowsHookEx(hkLogzWheel);
        hkLogzWheel := 0;
        Result := True;
    end else Result := False;

    //QQ聊天对话框
    if hkQQChat<>0 then begin
        UnHookWindowsHookEx(hkQQChat);
        hkQQChat := 0;
        Result := True;
    end else Result := False;
end;
//▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
//模拟按键
procedure Down(VK: byte); begin keybd_event(VK, MapVirtualKey(VK, 0), 0, 0); end;
procedure UP  (VK: byte); begin keybd_event(VK, MapVirtualKey(VK, 0), KEYEVENTF_KEYUp, 0); end;

procedure Key1(VK1: byte); begin
    Down(VK1);
    Up  (VK1);
end;

procedure Key2(VK1, VK2: byte); begin
    Down(VK1);
    Down(VK2);
    Up  (VK2);
    Up  (VK1);
end;

procedure Key3(VK1, VK2, VK3: byte); begin
    Down(VK1);
    Down(VK2);
    Down(VK3);
    Up  (VK3);
    Up  (VK2);
    Up  (VK1);
end;

procedure KeyStr(const theStr: string);
var i: byte;
begin
    for i := 1 to length(theStr) do Key1(StrToVK(UpperCase('VK_'+theStr[i])));
end;
//▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
procedure GetForeWindowInfo;
//得到顶层窗体(对话框)的信息
begin
    hwLogzWheel := GetForegroundWindow;
    GetWindowText(hwLogzWheel, buf, 1024);  tlLogzWheel  := string(buf);
    GetClassName (hwLogzWheel, buf, 1024);  clsName := string(buf);

    dwnCtrl := GetKeyState(VK_Control)<0;
    dwnShift:= GetKeyState(VK_Shift  )<0;
    dwnAlt  := GetKeyState(VK_Menu   )<0;
end;
//▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
function TitleKeyword(theKeyword: string): Boolean;
begin  Result := pos(theKeyword, tlLogzWheel)>0  end;
function ClassKeyword(theKeyword: string): Boolean;
begin  Result := pos(theKeyword, clsName)>0  end;

function TitleIS(theKeyword: string): Boolean;
begin  Result := theKeyword=tlLogzWheel;  end;
function ClassIS(theKeyword: string): Boolean;
begin  Result := theKeyword=clsName;  end;
//▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
function StrToVK(theKeyStr: string): byte;
begin
    if isEmpty(theKeyStr) then begin  Result := 0;  exit;  end;
    Result := VisualKeys.IndexOf(theKeyStr);
end;

function VKToStr(theVisKey: byte): string;
begin
    Result := VisualKeys[theVisKey];
end;

procedure LoadVisualKeys;
    procedure AddEmptyVK; overload;
    begin
        VisualKeys.Add('VK_CANCEL');
    end;
    procedure AddEmptyVK(a, b: byte); overload;
    var i: byte;
    begin
        for i := a to b do VisualKeys.Add('VK_CANCEL');
    end;
var i: byte;
begin
    VisualKeys := TStringList.Create;

    VisualKeys.Add('VK_CANCEL');   //0
    VisualKeys.Add('VK_LBUTTON');  //1
    VisualKeys.Add('VK_RBUTTON');  //2
    VisualKeys.Add('VK_CANCEL');   //3
    VisualKeys.Add('VK_MBUTTON');  //4
    AddEmptyVK(5, 7);   //=====
    VisualKeys.Add('VK_BACK');     //8
    VisualKeys.Add('VK_TAB');      //9
    AddEmptyVK(10, 11); //=====
    VisualKeys.Add('VK_CLEAR');    //12
    VisualKeys.Add('VK_RETURN');   //13
    AddEmptyVK(14, 15); //=====
    VisualKeys.Add('VK_SHIFT');    //$10
    VisualKeys.Add('VK_CONTROL');  //17
    VisualKeys.Add('VK_MENU');     //18
    VisualKeys.Add('VK_PAUSE');    //19
    VisualKeys.Add('VK_CAPITAL');  //20
    VisualKeys.Add('VK_KANA');     //21 or VK_HANGUL = 21 too
    VisualKeys.Add('VK_HANGUL');   //21 or VK_HANGUL = 21 too
    VisualKeys.Add('VK_JUNJA');    //23
    VisualKeys.Add('VK_FINAL');    //24
    VisualKeys.Add('VK_HANJA');    //25 or VK_KANJI = 25 too
    VisualKeys.Add('VK_KANJI');    //25 or VK_KANJI = 25 too
    VisualKeys.Add('VK_ESCAPE');   //27
    VisualKeys.Add('VK_CONVERT');  //28
    VisualKeys.Add('VK_NONCONVERT');//29
    VisualKeys.Add('VK_ACCEPT');   //30
    VisualKeys.Add('VK_MODECHANGE');//31
    VisualKeys.Add('VK_SPACE');    //$20
    VisualKeys.Add('VK_PRIOR');    //33
    VisualKeys.Add('VK_NEXT');     //34
    VisualKeys.Add('VK_END');      //35
    VisualKeys.Add('VK_HOME');     //36
    VisualKeys.Add('VK_LEFT');     //37
    VisualKeys.Add('VK_UP');       //38
    VisualKeys.Add('VK_RIGHT');    //39
    VisualKeys.Add('VK_DOWN');     //40
    VisualKeys.Add('VK_SELECT');   //41
    VisualKeys.Add('VK_PRINT');    //42
    VisualKeys.Add('VK_EXECUTE');  //43
    VisualKeys.Add('VK_SNAPSHOT'); //44
    VisualKeys.Add('VK_INSERT');   //45
    VisualKeys.Add('VK_DELETE');   //46
    VisualKeys.Add('VK_HELP');     //47
    VisualKeys.Add('VK_0');        //$30
    VisualKeys.Add('VK_1');        //$31
    VisualKeys.Add('VK_2');        //$32
    VisualKeys.Add('VK_3');        //$33
    VisualKeys.Add('VK_4');        //$34
    VisualKeys.Add('VK_5');        //$35
    VisualKeys.Add('VK_6');        //$36
    VisualKeys.Add('VK_7');        //$37
    VisualKeys.Add('VK_8');        //$38
    VisualKeys.Add('VK_9');        //$39
    AddEmptyVK($3A,$40);//=====
    VisualKeys.Add('VK_A');        //$41
    VisualKeys.Add('VK_B');        //$42
    VisualKeys.Add('VK_C');        //$43
    VisualKeys.Add('VK_D');        //$44
    VisualKeys.Add('VK_E');        //$45
    VisualKeys.Add('VK_F');        //$46
    VisualKeys.Add('VK_G');        //$47
    VisualKeys.Add('VK_H');        //$48
    VisualKeys.Add('VK_I');        //$49
    VisualKeys.Add('VK_J');        //$4A
    VisualKeys.Add('VK_K');        //$4B
    VisualKeys.Add('VK_L');        //$4C
    VisualKeys.Add('VK_M');        //$4D
    VisualKeys.Add('VK_N');        //$4E
    VisualKeys.Add('VK_O');        //$4F
    VisualKeys.Add('VK_P');        //$50
    VisualKeys.Add('VK_Q');        //$51
    VisualKeys.Add('VK_R');        //$52
    VisualKeys.Add('VK_S');        //$53
    VisualKeys.Add('VK_T');        //$54
    VisualKeys.Add('VK_U');        //$55
    VisualKeys.Add('VK_V');        //$56
    VisualKeys.Add('VK_W');        //$57
    VisualKeys.Add('VK_X');        //$58
    VisualKeys.Add('VK_Y');        //$59
    VisualKeys.Add('VK_Z');        //$5A
    VisualKeys.Add('VK_LWIN');     //91
    VisualKeys.Add('VK_RWIN');     //92
    VisualKeys.Add('VK_APPS');     //93
    AddEmptyVK(94, 95); //=====
    VisualKeys.Add('VK_NUMPAD0');  //96
    VisualKeys.Add('VK_NUMPAD1');  //97
    VisualKeys.Add('VK_NUMPAD2');  //98
    VisualKeys.Add('VK_NUMPAD3');  //99
    VisualKeys.Add('VK_NUMPAD4');  //100
    VisualKeys.Add('VK_NUMPAD5');  //101
    VisualKeys.Add('VK_NUMPAD6');  //102
    VisualKeys.Add('VK_NUMPAD7');  //103
    VisualKeys.Add('VK_NUMPAD8');  //104
    VisualKeys.Add('VK_NUMPAD9');  //105
    VisualKeys.Add('VK_MULTIPLY'); //106
    VisualKeys.Add('VK_VisualKeys.Add');      //107
    VisualKeys.Add('VK_SEPARATOR');//108
    VisualKeys.Add('VK_SUBTRACT'); //109
    VisualKeys.Add('VK_DECIMAL');  //110
    VisualKeys.Add('VK_DIVIDE');   //111
    VisualKeys.Add('VK_F1');       //112
    VisualKeys.Add('VK_F2');       //113
    VisualKeys.Add('VK_F3');       //114
    VisualKeys.Add('VK_F4');       //115
    VisualKeys.Add('VK_F5');       //116
    VisualKeys.Add('VK_F6');       //117
    VisualKeys.Add('VK_F7');       //118
    VisualKeys.Add('VK_F8');       //119
    VisualKeys.Add('VK_F9');       //120
    VisualKeys.Add('VK_F10');      //121
    VisualKeys.Add('VK_F11');      //122
    VisualKeys.Add('VK_F12');      //123
    VisualKeys.Add('VK_F13');      //124
    VisualKeys.Add('VK_F14');      //125
    VisualKeys.Add('VK_F15');      //126
    VisualKeys.Add('VK_F16');      //127
    VisualKeys.Add('VK_F17');      //128
    VisualKeys.Add('VK_F18');      //129
    VisualKeys.Add('VK_F19');      //130
    VisualKeys.Add('VK_F20');      //131
    VisualKeys.Add('VK_F21');      //132
    VisualKeys.Add('VK_F22');      //133
    VisualKeys.Add('VK_F23');      //134
    VisualKeys.Add('VK_F24');      //135
    AddEmptyVK(136,143);//=====
    VisualKeys.Add('VK_NUMLOCK');  //144
    VisualKeys.Add('VK_SCROLL');   //145
    AddEmptyVK(146,159);//=====
    VisualKeys.Add('VK_LSHIFT');   //160
    VisualKeys.Add('VK_RSHIFT');   //161
    VisualKeys.Add('VK_LCONTROL'); //162
    VisualKeys.Add('VK_RCONTROL'); //163
    VisualKeys.Add('VK_LMENU');    //164
    VisualKeys.Add('VK_RMENU');    //165
    AddEmptyVK(166,228);//=====
    VisualKeys.Add('VK_PROCESSKEY');//229
    AddEmptyVK(230,245);//=====
    VisualKeys.Add('VK_ATTN');     //246
    VisualKeys.Add('VK_CRSEL');    //247
    VisualKeys.Add('VK_EXSEL');    //248
    VisualKeys.Add('VK_EREOF');    //249
    VisualKeys.Add('VK_PLAY');     //250
    VisualKeys.Add('VK_ZOOM');     //251
    VisualKeys.Add('VK_NONAME');   //252
    VisualKeys.Add('VK_PA1');      //253
    VisualKeys.Add('VK_OEM_CLEAR');//254
end;

end.

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值