[Delphi version] Logitech Infinite Spirit Sable, Driver Patch - Implementing a Real Multimedia Player! Attached QQ icon camouflage program
██████████████ QQ Icon Camouflage Program
Turn "Chat with So-and-so" in the title bar of the QQ chat window into "My Document So-and-so", and the icon in the chat window becomes the icon of Word document, and the icon in the tray also becomes other icons in different states. : For example, online = network drive, leave = floppy disk drive, stealth = hard disk drive, offline = disconnect network drive.
Change icons do not require programming, just modify the QQRes.Dll file of QQ2004.
████████████ Logitech Infinite Spirit Sable, Driver Patch – Realize a Real Multimedia Player
Logitech Infinite Spirit Mink is a multifunctional wireless mouse launched by Logitech. It is called "Logitech Media Player" in the English name, as the name implies - a multimedia remote control.
The biggest feature of this mouse is that it has many function keys embedded, and in addition to the scroll wheel, there are 8 keys. The two keys on the side are equipped with Logitech's many mid-to-high-end mice, and the functions are mainly to browse up and down; the six keys on the top form a multimedia keypad, including: "Media, Play/Pause, Forward, Backward, +, -" . In addition, the scroll wheel can perform cross navigation, which means there is an additional left and right browsing function.
But in actual use, the functions of the multimedia key are really limited. By my standards, it cannot play the role of the remote control at all! Why do you say so?
The media player I like to use is MPC (MS Windows Media Player Classic). It is short and concise, fast startup, small resources, rich shortcut keys, and is very simple to operate with a mouse and keyboard.
The following is a question about MPC’s shortcomings:
Just play/pause and click the left button or Space, and the left button is on the mouse, so the Play/Pause button is redundant;
Click PgUp/PgDown on the next/previous one. Although the corresponding mouse is Forward/Backward, how many opportunities do we have to watch the previous or next file in the middle when we watch a movie or video clip? Even if you are looking for video files that are more than 10 minutes, it is not a big problem to manually click on the next file after watching one, so these two keys are unnecessary.
Logitech's latest drivers do not provide customization functions for the above three keys, so in order to make full use of the many function keys on the mouse, I had to add new code to the QQ icon program to implement these three keys. Customization function, and it can also enable the same mouse button to implement different customization functions in different applications.
Use the official driver setup program to set up:
The function of the Media key is the key combination: Ctrl+F4, and the function of the zoom is to close the program (very efficient).
The subsequent program can implement the following functions (mainly key combination):
◎MPC
Browse up: Go forward for 10 seconds; Browse down: Go back for 10 seconds.
◎ACDSee
Play/Pause: Ctrl+Del; Forward: Alt+C; Backward: Alt+M.
◎ACD FotoCanvas
Play/Pause: Ctrl+S; Forward: Shift+A; Backward: Shift+S.
◎NetCaptor
Play/Pause: Ctrl+Shift+S; Foward: F3; Backward: F2.
◎UltraEdit
Play/Pause: Ctrl+S; Foward: Ctrl+Shift+F6; Backward: Ctrl+F6.
Finally, I want to despise the developers of Logitech Infinite Spirit Mink drivers!
The core function of mouse driver lies in the conversion and processing of displacement signals transmitted from the mouse, as well as problems such as the definition of various keys and the processing of acceleration, but these are just small problems compared to the processing and analysis of mobile signals. There are no functional technical difficulties in programming in this aspect. Since you have made so many mid-to-high-end mice, especially this Lingsie I bought for RMB 360, why don’t you type more codes and add a few keys in the multimedia keypad to customize them. After all, computers are not TVs, recorders, VCD machines, DVD machines, combined audio... Multimedia functions are only part of the functions of computers. Most people still need to use them to do many other swimming things, if they can be used in more application software. Each key implements custom functions, so with its current price of less than 400 yuan and a large number of mouse buttons, it is definitely a great value mouse!
The code of ██████████ Delphi is as follows, among which only MPC uses hooks, because in media playback software, the messages generated by the multimedia keypad and the two side keys are abducted by Logitech's driver hooks. So I have to make a global hook myself to stop the news in advance so that Logitech's hook cannot hook the information I need.
//▓▓▓▓▓▓▓▓▓▓▓▓ ReTitle.dPR
program ReTitle;
uses
Forms,
SysUtils,
Windows,
Unit1 in 'Unit1.pas' {f},
DlgDebug_U in 'DlgDebug_U.pas' {dlgDebug};
{$R *.res}
Begin
application.Initialize;
//Debug status
dbg := findCmdLineSwitch('debug', ['/', '-'], true);
if dbg then with dlgDebug do begin
dlgDebug := TDlgDebug.Create(Application); Show;
Left := GetSystemMetrics(SM_CXSCREEN)-Width;
Top := GetSystemMetrics(SM_CYSCREEN)-Height-60;
end;
Application.CreateForm(Tf, f);
Application.Run;
end.
//▓▓▓▓▓▓▓▓▓ Unit1.pas
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls, DlgDebug_U;
type
Tf = class(TForm)
Tmr: TTimer;
procedure FormCreate(Sender: TObject);
procedure TmrTimer(Sender: TObject);
procedure WndProc(var Message: TMessage); override;
Private
{ Private declarations }
hFocus: HWND;
Buf: array[0..1024] of Char;
sTitle: string;
procedure GetMousePosHwndAndClassName(Sender: TPoint);
function replacing(s,source,target:string):string;
//Logichi Infinite Spiritual Sable
procedure Down(VK: byte);
procedure UP (VK: byte);
procedure Key1(VK1: byte);
procedure Key2(VK1, VK2 : byte);
procedure Key3(VK1, VK2, VK3: byte);
public
{ Public declarations }
end;
var
f: Tf;
const
LOGITECH = $0319;
PLAY_PAUSE = $E0000;
PLAY_LEFT = $C0000;
PLAY_RIGHT = $B0000;
Implementation
procedure EnableWheelHook ; stdcall; external 'HookPrj.dll';
procedure DisableWheelHook; stdcall; external 'HookPrj.dll';
{$R *.dfm}
procedure Tf.FormCreate(Sender: TObject);//██████████████████████████████ Interface Initialization
Begin
FormStyle := fsStayOnTop;
Height:=0;
Width:=0;
Hide;
Tmr.Interval := 50;
ShowWindow(Application.Handle, SW_HIDE);
SetWindowLong(Application.Handle, GWL_EXSTYLE,
GetWindowLong(Application.handle, GWL_EXSTYLE) or WS_EX_TOOLWINDOW AND NOT WS_EX_APPWINDOW);
EnableWheelHook;//Lotech Lingmian Blue Side Key, WM_MouseWheel Message Hook
end;
procedure Tf.GetMousePosHwndAndClassName(Sender: TPoint);//████ Camouflage title bar
var hWnd: THandle;
aTitle: array [0..255] of char;
str:string;
Begin
hWnd := WindowFromPoint(Sender);
if boolean(GetWindowText(hWnd, aTitle, 256)) then begin
str := string(aTitle);
if ((pos('and',str)>0) and (pos('Chat',str)>0)) then begin
str:=replacing(str, ' Chat', '');
str:=replacing(str, 'and', 'my documentation');
SetWindowText(hWnd,pchar(str));
end;
if ((pos('group-',str)>0) or (pos('advanced group-',str)>0)) then begin
str:=replacing(str, 'group-', 'my letter');
str:=replacing(str, 'advanced', '');
SetWindowText(hWnd,pchar(str));
end;
//Chat room
if pos('QQ Chat Room', str)>0 then begin
str := 'Microsoft Visual C++ 6.2';
SetWindowText(hWnd,pchar(str));
end;
//MSN
if pos(' - dialogue', str)>0 then begin
str := replacing(str, ' - dialogue', 'working document');
SetWindowText(hWnd,pchar(str));
end;
end;
end;
procedure Tf.TmrTimer(Sender: TObject);//███████████████████████████████████████████████████████████████████████████████
var rPos: TPoint;
Begin
if boolean(GetCursorPos(rPos)) then GetMousePosHwndAndClassName(rPos);
end;
function Tf.replacing(s,source,target:string):string;//██████ Replace string
var site, strlen: integer;
Begin
site:=pos(source,s);
strlen:=length(source);
delete(s, site,strlen);
insert(target,s,site);
result:=s;
end;
procedure Tf.WndProc(var Message: TMessage);////█████████▌Logytech Infinite Spirit Mink
begin with Message do begin
inherited;
//If the three keys on the center and right of the multimedia keypad are not pressed, exit
IF NOT( (Msg=LOGITECH) and ((lParam=PLAY_PAUSE)or(lParam=PLAY_LEFT)or(lParam=PLAY_RIGHT)) ) THEN exit;
hFocus := GetForegroundWindow;
GetWindowText(hFocus, buf, 1024);
sTitle := string(buf);
deb(sTitle);
//ACDSee
if (pos('ACDSee', sTitle)>0) and (pos('5.0', sTitle)>0) and (Msg=LOGITECH) then case lParam of
PLAY_PAUSE: Key2(VK_Control, VK_Delete);//Ctrl+Del
PLAY_LEFT : Key2(VK_Menu, ord('M') );//Alt+M
PLAY_RIGHT: Key2(VK_Menu, Ord('C'));//Alt+C
end;
if (pos('ACD', sTitle)>0) and (pos('FotoCanvas', sTitle)>0) and (Msg=LOGITECH) then case lParam of
PLAY_PAUSE: Key2(VK_Control, ord('S'));//Ctrl+S
PLAY_LEFT : Key2(VK_Shift , ord('S'));//Shift+S
PLAY_RIGHT: Key2(VK_Shift , Ord('A'));//Shift+A
end;
//NetCaptor
if (pos('NetCaptor', sTitle)>0) and (Msg=LOGITECH) then case lParam of
PLAY_PAUSE: Key3(VK_Control, VK_Shift, ord('S'));//Ctrl+Shift+S
PLAY_LEFT : Key1(VK_F2);
PLAY_RIGHT: Key1(VK_F3);
end;
//UltraEdit
if (pos('UltraEdit-32', sTitle)>0) and (Msg=LOGITECH) then case lParam of
PLAY_PAUSE: Key2(VK_Control, ord('S'));//Ctrl+S
PLAY_LEFT : Key2(VK_Control, VK_F6 );//Ctrl+F6
PLAY_RIGHT: Key3(VK_Control, VK_Shift, VK_F6);//Ctrl+Shift+F6
end;
end; end;
procedure Tf.Down(VK: byte); begin keybd_event(VK, MapVirtualKey(VK, 0), 0, 0); end;
procedure Tf.UP (VK: byte); begin keybd_event(VK, MapVirtualKey(VK, 0), KEYEVENTF_KEYUp, 0); end;
procedure Tf.Key1(VK1: byte); begin
Down(VK1);
Up (VK1);
end;
procedure Tf.Key2(VK1, VK2: byte); begin
Down(VK1);
Down(VK2);
Up (VK2);
Up (VK1);
end;
procedure Tf.Key3(VK1, VK2, VK3: byte); begin
Down(VK1);
Down(VK2);
Down(VK3);
Up (VK3);
Up (VK2);
Up (VK1);
end;
end.
//▓▓▓▓▓▓▓▓▓▓▓▓ DlgDebug_U.pas
{********************************************************* ************************************
Non-modal dialog box used in the program to display debugging information
2005/02
********************************************************* ************************************************
unit DlgDebug_U; interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ComCtrls;
procedure deb(theMsg: string); overload;//Debug information
procedure deb(theMsg: integer);overload;
procedure deb(const theStr: string; const Args: array of const); overload;
type
TdlgDebug = class(TForm)
re: TRichEdit;
procedure mmKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
procedure FormCreate(Sender: TObject);
Private
{ Private declarations }
public
{ Public declarations }
indent: byte;
selColor: TColor;
procedure TimeLine;
end;
var dlgDebug: TdlgDebug;
dbg: Boolean;
Implementation
{$R *.dfm}
procedure TdlgDebug.mmKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
Begin
if Key=VK_SPACE then begin
re.Tag := integer( not boolean(re.Tag) );
//mm.Tag := integer( not boolean(mm.Tag) );
//if boolean(mm.Tag) then Red.Suspend
//else Red.Resume;
end;
end;
procedure deb(theMsg: string); begin
if not dbg then exit;
with dlgDebug do begin//Debug information
TimeLine;
re.SelAttributes.Color := selColor;
re.paragraph.FirstIndent := indent;
re.Lines.Add(theMsg);
//mm.Lines.Add(theMsg);
end;
end;
procedure deb(theMsg: integer);
Begin
if not dbg then exit;
with dlgDebug do begin//Debug information
TimeLine;
re.SelAttributes.Color := selColor;
re.paragraph.FirstIndent := indent;
re.Lines.Add(intToStr(theMsg));
//mm.Lines.Add(intToStr(theMsg));
end;
end;
procedure deb(const theStr: string; const Args: array of const); overload;
Begin
if not dbg then exit;
with dlgDebug do begin//Debug information
TimeLine;
re.SelAttributes.Color := selColor;
re.paragraph.FirstIndent := indent;
re.Lines.Add(format(theStr, Args));
//mm.Lines.Add(format(theStr, Args));
end;
end;
procedure TdlgDebug.TimeLine;
begin with re do begin
paragraph.FirstIndent := 0;
SelAttributes.Color := clRed;
lines.Add(formatDateTime(LongTimeFormat, now));
end; end;
procedure TdlgDebug.FormCreate(Sender: TObject);
Begin
indent := 10;
selColor := clYellow;
end;
end.
//▓▓▓▓▓▓▓▓▓▓▓▓ HookPrj.dpr
library HookPrj;
uses
SysUtils,
Classes,
Hook_U in 'Hook_U.pas';
exports
EnableWheelHook,
DisableWheelHook;
Begin
end.
//▓▓▓▓▓▓▓▓▓ Hook_U.pas
unit Hook_U; interface
uses Windows,Messages, SysUtils, dialogs;
var HK: HHOOK;//Hook handle value
hFocus: HWnd;
buf: array [0..1024] of char;
sTitle: string;
iC: byte;
zDelta: short;
function WheelHookProc(Code: Integer; WParam: Longint; Msg: Longint): LRESULT; stdcall;
function EnableWheelHook : Boolean; stdcall; export;
function DisableWheelHook: Boolean; stdcall; export;
Implementation
//█████████████████████████████████████████�
function WheelHookProc(Code: Integer; WParam: Longint;Msg:Longint): LRESULT; stdcall;
Begin
zDelta := short(HiWord(PMsg(Msg)^.wParam));
if (Code=HC_ACTION) and (PMsg(Msg)^.Message=WM_MOUSEWHEEL) and (abs(zDelta)>200) then begin
hFocus := GetForegroundWindow;
GetWindowText(hFocus, buf, 1024);
sTitle := string(buf);
if ( pos('mplayerc', sTitle)>0 )or( pos('Media Player Classic', sTitle)>0 ) then begin
inc(iC);
// Press the blue side key once to generate two messages. If the two-in-one processing is equivalent to fast forwarding once, that is, 5 seconds.
//If all processed, it is equivalent to fast forwarding twice, that is, 10 seconds
//if (iC mod 2)=0 then begin
keybd_event(VK_Control, MapVirtualKey(VK_Control, 0), 0, 0); //CTRL Down
if zDelta>200 then begin
keybd_event(VK_Right, MapVirtualKey(VK_Right, 0), 0, 0); //RIGHT Down
keybd_event(VK_Right, MapVirtualKey(VK_Right, 0), KEYEVENTF_KEYUP, 0);//RIGHT Up
end else begin
keybd_event(VK_Left , MapVirtualKey(VK_Left , 0), 0, 0); //LEFT Down
keybd_event(VK_Left , MapVirtualKey(VK_Left , 0), KEYEVENTF_KEYUP, 0);//LEFT Up
end;
keybd_event(VK_Control, MapVirtualKey(VK_Control, 0), KEYEVENTF_KEYUP, 0);//CTRL Up
//end;
PMsg(Msg)^.Message := 0;//Because the side key message has been processed locally, it does not have to be handed over to other threads for processing
end else Result := CallNextHookEx(HK, Code, WParam, Longint(@Msg));//If it is not MPC, pass down
end else Result := CallNextHookEx(HK, Code, WParam, Longint(@Msg));//If it is not two blue side keys, pass it down
end;
function EnableWheelHook: Boolean; stdcall; export;//██████████████████████████████████�
Begin
if HK=0 then begin
HK := SetWindowsHookEx(WH_GETMESSAGE, @WheelHookProc, Hinstance, 0);
Result := True;
end else Result := False;
end;
function DisableWheelHook: Boolean; stdcall; export;//█████████████████████▌Unload hook
Begin
if HK<>0 then begin
UnHookWindowsHookEx(HK);
HK := 0;
Result := True;
end else Result := False;
end;
end.
QQ: 7995.7944 (Shensi Road)
E-Mail: [email protected]