Hey! It's hard to have a little easier. Now I have time to send the QQ chat recorder made in the previous day and share it with everyone. Do this program is to see the latest online software called QQAUTOREORDER. It The implementation is to record QQ chat records. The technique used is: hook the QQ dialog. It does not record the QQ message that the user has not clicked. (I think if you want to record QQ messages, Meaning It is an unequal QQ message box to record the message of QQ. I can only go to block the QQ data package. I spent a day above this, but the final conclusion is '太 无 力 力' ^ _ _ ^ It seems that the QQ data package is not so easy to get L)
Reason returning: This article uses a method for hook the QQ message box (which is easier to implement, two is also a general way to most such programs.) For the simplified program: I divide this procedure into two implementations (all in QQ2004 Realize, to the last version compatible with QQ2003):
I. Capture someone else giving yourself:
Since it is a message box of QQ, naturally, it is natural to find a very reasonable and most convenient. It is easy to think about what you use to view QQ messages. Generally lead to a QQ message window The generation of body. It will produce a CREATE event. From this point, it is wise to use a wh_shell hook.
The description of the WH_SHELL is: monitor the Windows shell notification message, such as the release of the creation of the top-level window. We must care about the creation message of the window.
Because there is a case where multiple QQ message windows appear once, I use global hooks here: and define the following data structure:
HookType.Pas unit
Unit hooktype;
Interface
Uses
Windows, Messages;
Const
WM_USERCMD = WM_APP 1; // User Customize Application Level Message
UC_Wincreate = WM_APP 2; // QQ message window creation
UC_Windestroy = WM_APP 3; // Send QQ message
Buffer_size = 16 * 1024;
Hook_mem_filename = 'MEM_FILE';
Type
Tshared = Record
Keyhook: hhook; // Keyboard hook
Shellhook: hhook;
Callhook: hHOOK;
Mainwnd: thandle; // Handle (non-Application.handle)
Moudle: Thandle; // DLL
END;
Pshared = ^ Tshared;
IMPLEMENTATION
End.
DLL unit code
VAR
Memfile: thandle;
Shared: pshared;
Function shellProc (icode: integer; wparam: wparam; lparam: lparam): LRESULT; stdcall;
Begin
Case icode of
Hshell_windowcreated:
// Send yourself to the demo to define the message WM_USERCMD. WPARAMR parameter description
// wparam specifies the handle of the window being created or destroyed, respective.
Postmessage (Shared ^ .mainWnd, WM_USERCMD, UC_WINCREATE, WPARAM);
END;
Result: = CallnexthooKex (Shared ^ .shellhook, iCode, WPARAM, LPARAM);
END;
Function Installhook: boolean;
Begin
Shared ^ .moudle: = getModuleHandle (Pchar ('QQHOOK')); // qqhook is my DLL file name.
Shared ^ .Shellhook: = setWindowshookex (wh_shell, @ shellproc,
Shared ^ .moudle,
0);
if Shared ^ .ShellHook = 0 THEN
Begin
Result: = FALSE;
EXIT;
END;
RESULT: = TRUE;
END;
{Undo hook filter function}
Function uninstallhook: boolean;
Begin
Freelibrary (Shared ^ .moudle);
Result: = UnHookWindowsHookex (Shared ^ .shellhook);
UnmapViewoffile (Shared);
CloseHandle (Memfile);
END;
Procedure DLlentry (dwreason: integer);
Begin
Case dwreason
DLL_PROCESS_ATTACH:
Begin
Memfile: = OpenFilemapping (file_map_write, false, hook_mem_filename);
if Memfile = 0 THEN
Memfile: = CREATEFILEMAPPING ($ fffffff, nil,
Page_readwrite,
0,
Sizeof (tshared),
Hook_mem_filename);
Shared: = MapViewOffile (Memfile,
FILE_MAP_WRITE,
0,
0,
0);
END;
DLL_PROCESS_DETACH:
Begin
// uninstallhook;
END;
Else;
END;
END;
Exports
INSTALLHOOK;
Begin
DllProc: = @dllentry;
DLLENTRY (DLL_PROCESS_ATTACH);
End.
// The above code does not have a more manner to unload the hook, which is not discussed in this range.
Demo program code
Procedure TFORM1.BUTTON1CLICK (Sender: TOBJECT);
Begin
INSTALLHOOK;
END;
Procedure TFORM1.FormCreate (Sender: TOBJECT);
Begin
Memfile: = OpenFilemapping (file_map_write, false, hook_mem_filename);
if Memfile = 0 THEN
Memfile: = CREATEFILEMAPPING ($ fffffff, nil,
Page_readwrite,
0,
Sizeof (tshared),
Hook_mem_filename);
Shared: = MapViewOffile (Memfile,
FILE_MAP_WRITE,
0,
0,
0);
Shared ^ .mainWnd: = handle; // Save Form Handle
END;
// Window message processing process
Procedure TFORM1.WNDPROC (VAR Msg: TMESSAGE);
Begin
With msg do
Begin
IF msg = wm_usercmd life // DLL sent custom message
Begin
Case wparam of
UC_Wincreate: // QQ message box creation
Begin
GetText (FindHWD (HWnd (LPARAM))); // Get the text in the QQ message box
END;
END;
END;
END;
inherited;
END;
/ / Find the QQ window handle via the wPARAM parameter
Function TFORM1.FINDHWD (PARENT: HWND): hwnd; var
HWD, HBTN, HMEMO: HWND;
Begin
Result: = 0;
HWD: = FindWindowEx (PARENT, 0, '# 32770', nil); // qq secondary window handle QQ2003 and previous versions do not have this.
IF (hwd <> 0) THEN
Begin
HBTN: = FindWindowEx (hwd, 0, nil, 'back message (& r)'); // can be proved to be a received QQ message box.
IF (HBTN <> 0) THEN
Begin
HMEMO: = Getdlgitem (HWD, $ 00000380); // Richedit handle, QQ message exists here.
IF (HMEMO <> 0) THEN
Result: = HMEMO;
END;
END;
END;
/ / Get the text in the specified handle control.
Procedure TFORM1.Gettext (hwd: hwnd);
VAR
RET: longint;
QQText: pchar;
BUF: Integer;
Begin
GetMem (QQTEXT, 1024);
IF (hwd <> 0) THEN
Begin
Try
RET: = SendMessage (HWD, WM_GettextLength, 0, 0) 1;
BUF: = longint (QQText);
SendMessage (HWD, WM_Gettext, Min (RET, 1024), BUF);
Memo1.Lines.Add (QQText); // Display text in MEMO
Finally
FreeMem (QQText, 1024);
END;
END;
END;
The above is the code I test, just for the convenience of classification, I will come out. Maybe there is some unreasonable place. If there is anything out of this, the following will provide full code download.
Hottey on the 2005-6-2 website:
http://asp.itdrp.com/hottey