Dit is geen vraag, maar een antwoord op de vraag van MisterE in [topic=460128].
In het kort komt het erop neer dat je in een dll een library-defined hook maakt, die kijkt welke messages er naar alle windows worden gestuurd.
Ergens heb ik het gevoel dat deze code een beetje overkill is, dus als je wat beters weet, hoor ik het graag.
Dll Code:
Applicatie:
Mijn code is eigenlijk opgefleurde code van gajits; Note dat de opmerkingen mbt Set8087CW, niet meer gelden voor Delphi 5 en later.yep, maar prob. is eigenlijk dat ik wil 'intercepten' wanneer de iconen veranderd worden.
ik ben namelijk een wallpaper manager aan het maken, en ik wil er voor zorgen dat de iconen de goede kleur blijven behouden.
In het kort komt het erop neer dat je in een dll een library-defined hook maakt, die kijkt welke messages er naar alle windows worden gestuurd.
Ergens heb ik het gevoel dat deze code een beetje overkill is, dus als je wat beters weet, hoor ik het graag.
Dll Code:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
| library Capture;
uses
SysUtils,
Classes,
Windows,
CommCtrl,
Messages;
{$R *.RES}
type
PHookRec = ^THookRec;
THookRec = record
MainWindow: THandle;
SysView32: THandle;
HookID: HHOOK;
end;
const
CM_IconTextChanged = WM_USER + 1;
const
HookRecPtr: PHookRec = nil;
MappingHandle: THandle = 0;
procedure SetMainHandle(Handle: HWnd);
begin
HookRecPtr.MainWindow := Handle;
end;
procedure SetSysView32(Handle: HWnd);
begin
HookRecPtr.SysView32 := Handle;
end;
function HookProc(Code: Integer; WParam: Longint; var Msg: TCWPStruct): Longint;
stdcall;
begin
{ We monitoren alleen messsages die naar de desktop SysView32
worden gestuurd }
if (Msg.HWnd = HookRecPtr.SysView32) then
case Msg.Message of
{ Hier kunnen meerdere messages, die je
wilt monitoren, toegevoegd worden }
LVM_SETTEXTCOLOR, LVM_SETTEXTBKCOLOR:
PostMessage(HookRecPtr.MainWindow, CM_IconTextChanged, Msg.Message, 0);
end;
Result := CallNextHookEx(HookRecPtr.HookID, Code, WParam, Longint(@Msg))
end;
procedure SetHook;
begin
HookRecPtr.HookID := SetWindowsHookEx(WH_CALLWNDPROC, @HookProc, HInstance,
0);
end;
procedure UnSetHook;
begin
UnHookWindowsHookEx(HookRecPtr.HookID);
end;
exports
SetHook,
UnSetHook,
SetMainHandle,
SetSysView32;
procedure EntryPointProc(Reason: Integer);
begin
case reason of
DLL_PROCESS_ATTACH:
begin
MappingHandle := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE, 0,
SizeOf(THookRec), 'CaptureDesktopEvents');
HookRecPtr := MapViewOfFile(MappingHandle, FILE_MAP_WRITE, 0, 0, 0);
end;
DLL_PROCESS_DETACH:
begin
try
if HookRecPtr <> nil then
UnMapViewOfFile(HookRecPtr);
if MappingHandle <> 0 then
CloseHandle(MappingHandle);
except
end;
end;
end;
end;
begin
DllProc := @EntryPointProc;
EntryPointProc(DLL_PROCESS_ATTACH);
end. |
Applicatie:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
| unit Capture02;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;
{ Beetje lelijk om 2x dezelfde constante te definieren }
const
CM_IconTextChanged = WM_USER + 1;
type
TForm2 = class(TForm)
Button1: TButton;
Button2: TButton;
ListBox1: TListBox;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
protected
procedure CMIconTextChanged(var Message: TMessage); message
CM_IconTextChanged;
end;
var
Form2: TForm2;
implementation
uses
CommCtrl;
{$R *.DFM}
procedure SetHook; external 'capture.dll';
procedure UnSetHook; external 'capture.dll';
procedure SetMainHandle(Handle: HWnd); external 'capture.dll';
procedure SetSysView32(Handle: HWnd); external 'capture.dll';
function GetSysView32: THandle;
var
ProgMan, Shell: THandle;
begin
ProgMan := FindWindowEx(GetDesktopWindow, 0, 'ProgMan', nil);
Shell := FindWindowEx(ProgMan, 0, 'SHELLDLL_DefView', nil);
Result := FindWindowEx(Shell, 0, 'SysListView32', nil);
end;
procedure TForm2.Button1Click(Sender: TObject);
begin
SetSysView32(GetSysView32);
SetMainHandle(Handle);
SetHook;
end;
procedure TForm2.Button2Click(Sender: TObject);
begin
UnSetHook;
end;
procedure TForm2.CMIconTextChanged(var Message: TMessage);
begin
case Message.WParam of
LVM_SETTEXTCOLOR:
ListBox1.Items.Add('LVM_SETTEXTCOLOR');
LVM_SETTEXTBKCOLOR:
ListBox1.Items.Add('LVM_SETTEXTBKCOLOR');
else
ListBox1.Items.Add('Unknown');
end;
end;
end. |