If then else matters! - I5 12600KF, Asus Tuf GT501, Gigabyte Gaming OC 16G 5080 RTX, Asus Tuf Gaming H670 Pro, 48GB, Corsair RM850X PSU, SN850 1TB, Arctic Liquid Freezer 280, ASUS RT-AX1800U router
Ik kom er echt niet uit en ik heb het wel nodig.
If then else matters! - I5 12600KF, Asus Tuf GT501, Gigabyte Gaming OC 16G 5080 RTX, Asus Tuf Gaming H670 Pro, 48GB, Corsair RM850X PSU, SN850 1TB, Arctic Liquid Freezer 280, ASUS RT-AX1800U router
Verwijderd
[edit]
Werkt
Forget your fears...
...and want to know more...
Werkt dat??
Hoe?
If then else matters! - I5 12600KF, Asus Tuf GT501, Gigabyte Gaming OC 16G 5080 RTX, Asus Tuf Gaming H670 Pro, 48GB, Corsair RM850X PSU, SN850 1TB, Arctic Liquid Freezer 280, ASUS RT-AX1800U router
Forget your fears...
...and want to know more...
Verwijderd
Misschien kun je wel proberen om het Notepad window een childform van jouw app te maken en de close-button disablen?
Verwijderd
of WH_GETMESSAGE, en dan wm_close en wm_quit eruit filteren.Op maandag 13 mei 2002 23:08 schreef DiFool het volgende:
Volgens mij moet dit kunnen met SetWindowsHookEx met hook id WH_CBT. Zal er 's naar kijken.
[edit]
Werkt
Kan je dat misschien een heel klein beetje .. voordoen?Op dinsdag 14 mei 2002 10:12 schreef deur het volgende:
[..]
of WH_GETMESSAGE, en dan wm_close en wm_quit eruit filteren.
If then else matters! - I5 12600KF, Asus Tuf GT501, Gigabyte Gaming OC 16G 5080 RTX, Asus Tuf Gaming H670 Pro, 48GB, Corsair RM850X PSU, SN850 1TB, Arctic Liquid Freezer 280, ASUS RT-AX1800U router
Verwijderd
Ik zal vanavond een voorbeeld posten, maar je kunt vast kijken naar [topic=462493], lijkt er veel op.
If then else matters! - I5 12600KF, Asus Tuf GT501, Gigabyte Gaming OC 16G 5080 RTX, Asus Tuf Gaming H670 Pro, 48GB, Corsair RM850X PSU, SN850 1TB, Arctic Liquid Freezer 280, ASUS RT-AX1800U router
Deze doet hier precies het verkeerdeOp maandag 13 mei 2002 23:08 schreef DiFool het volgende:
Volgens mij moet dit kunnen met SetWindowsHookEx met hook id WH_CBT. Zal er 's naar kijken.
[edit]
Werkt
Hmm in de help staat dit
Die moet ik hebben, maar hoe gebruik ik die?LRESULT CALLBACK CBTProc(
int nCode,// hook code
WPARAM wParam,// depends on hook code
LPARAM lParam // depends on hook code
);
Parameters
nCode
Specifies a code that the hook procedure uses to determine how to process the message. This parameter can be one of the following values:
ValueMeaning
HCBT_DESTROYWND
A window is about to be destroyed.
If nCode is less than zero, the hook procedure must pass the message to the CallNextHookEx function without further processing and should return the value returned by CallNextHookEx.
wParam
Depends on the nCode parameter. For details, see the following Remarks section.
lParam
Depends on the nCode parameter. For details, see the following Remarks section.
[edit2]
Hmmm `t begint haast avond te worden
[edit3]
Belangrijk ff
Ik moet WH_SHELL gebruiken, met HSHELL_WINDOWDESTROYED.
Maar als ik
1
2
3
4
5
6
7
8
9
10
11
12
13
| Private
procedure WMHCBTBeforeDistroyWnd(var Msg: TMessage); message WH_SHELL;
Var Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.WMHCBTBeforeDistroyWnd(var Msg: TMessage);
Begin
ShowMessage(IntToStr(HCBT_DESTROYWND));
End; |
Dan doet ie nix...
If then else matters! - I5 12600KF, Asus Tuf GT501, Gigabyte Gaming OC 16G 5080 RTX, Asus Tuf Gaming H670 Pro, 48GB, Corsair RM850X PSU, SN850 1TB, Arctic Liquid Freezer 280, ASUS RT-AX1800U router
Dat editen is dan ook niet alles...
If then else matters! - I5 12600KF, Asus Tuf GT501, Gigabyte Gaming OC 16G 5080 RTX, Asus Tuf Gaming H670 Pro, 48GB, Corsair RM850X PSU, SN850 1TB, Arctic Liquid Freezer 280, ASUS RT-AX1800U router
Application
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
| unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, Constants;
type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
private
FMappedFileHandle: THandle;
procedure WMBeforeDistroyWnd(var Msg: TMessage); message WE_CloseWindow;
public
property MappedFileHandle: THandle read FMappedFileHandle write FMappedFileHandle;
protected
end;
procedure HookCBT; stdcall; external 'WindowEvents.dll' index 1;
procedure UnHookCBT; stdcall; external 'WindowEvents.dll' index 2;
var
Form1: TForm1;
implementation
{$R *.DFM}
Procedure TForm1.WMBeforeDistroyWnd(var Msg : TMessage);
Begin
ShowMessage('s');
End;
procedure TForm1.FormCreate(Sender: TObject);
var
HookData: PCBTHookData;
begin
MappedFileHandle := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE, 0,
SizeOf(TCBTHookData), HookName);
HookData := MapViewOfFile(MappedFileHandle, FILE_MAP_ALL_ACCESS, 0, 0, 0);
if Assigned(HookData) then
begin
FillChar(HookData^, SizeOf(TCBTHookData), #0);
HookData^.AppHandle := Handle;
HookCBT;
end;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
UnHookCBT;
CloseHandle(MappedFileHandle);
end;
end. |
En de DLL
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
| library WindowEvents;
uses
Messages,
Constants,
Windows;
{$R *.RES}
function ShellProc(Code: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT stdcall;
var
Msg: Integer;
MappedMemoryHandle: THandle;
HookData: PCBTHookData;
begin
Result := 0;
MappedMemoryHandle := OpenFileMapping(FILE_MAP_ALL_ACCESS, False, HookName);
if MappedMemoryHandle <> 0 then
begin
HookData := MapViewOfFile(MappedMemoryHandle, FILE_MAP_ALL_ACCESS, 0, 0, 0);
if Assigned(HookData) then
begin
Msg := -1;
if Code = HSHELL_WINDOWDESTROYED Then Msg := WE_CloseWindow;
if Msg > -1 then PostMessage(HookData^.AppHandle, Msg, wParam, lParam);
if HookData^.HookHandle <> 0 then
Result := CallNextHookEx(HookData^.HookHandle, Code, wParam, lParam);
UnMapViewOfFile(HookData);
end;
CloseHandle(MappedMemoryHandle);
end
end;
procedure HookCBT; stdcall;
var
MappedMemoryHandle: THandle;
HookData: PCBTHookData;
begin
MappedMemoryHandle := OpenFileMapping(FILE_MAP_ALL_ACCESS, False, HookName);
if MappedMemoryHandle <> 0 then
begin
HookData := MapViewOfFile(MappedMemoryHandle, FILE_MAP_ALL_ACCESS, 0, 0, 0);
if Assigned(HookData) then
begin
{ Store the returned Handle in the Memory Mapped File so all instances }
{ of the DLL hook can retrieve it to pass it the CallNextHookEx }
HookData^.HookHandle := SetWindowsHookEx(WH_CBT, ShellProc, hInstance, 0);
UnmapViewOfFile(HookData);
end;
CloseHandle(MappedMemoryHandle);
end
end;
procedure UnHookCBT; stdcall;
var
MappedMemoryHandle: THandle;
HookData: PCBTHookData;
begin
MappedMemoryHandle := OpenFileMapping(FILE_MAP_ALL_ACCESS, False, HookName);
if MappedMemoryHandle <> 0 then
begin
HookData := MapViewOfFile(MappedMemoryHandle, FILE_MAP_ALL_ACCESS, 0, 0, 0);
if Assigned(HookData) then
begin
UnHookWindowsHookEx(HookData^.HookHandle);
HookData^.HookHandle := 0;
UnmapViewOfFile(HookData);
end;
CloseHandle(MappedMemoryHandle);
end
end;
exports HookCBT Index 1;
exports UnHookCBT Index 2;
begin
end. |
If then else matters! - I5 12600KF, Asus Tuf GT501, Gigabyte Gaming OC 16G 5080 RTX, Asus Tuf Gaming H670 Pro, 48GB, Corsair RM850X PSU, SN850 1TB, Arctic Liquid Freezer 280, ASUS RT-AX1800U router
Verwijderd
Ik moet wel zeggen dat ik gisteren iets te enthousiast was, want na wat verder testen blijkt het niet te werken bij alle programma's.
Wel doet bv:
- Notepad
- Winamp
- IrfanView
- Opera
- Calculator
- Explorer [niet zo gek]
- Delphi programma's [zal wel weer door Application Window <> Main Window komen]
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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
| unit Capture02;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;
const
CM_DestroyWnd = WM_USER + 1;
type
TForm2 = class(TForm)
Button1: TButton;
Button2: TButton;
ListBox1: TListBox;
Edit1: TEdit;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
protected
procedure CMDestroyWnd(var Message: TMessage); message
CM_DestroyWnd;
end;
var
Form2: TForm2;
implementation
uses
CommCtrl;
{$R *.DFM}
var
GWindowHandleList: TList;
procedure SetHook; external 'Capture.dll';
procedure UnSetHook; external 'Capture.dll';
procedure SetObserver(Handle: HWnd); external 'Capture.dll';
procedure SetObservableWindow(Handle: HWnd; Item: Integer); external
'Capture.dll';
function IsMainAppWindow(Wnd: HWND): Boolean;
var
ParentWnd: HWND;
ExStyle: DWORD;
begin
if IsWindowVisible(Wnd) then
begin
ParentWnd := GetWindowLong(Wnd, GWL_HWNDPARENT);
ExStyle := GetWindowLong(Wnd, GWL_EXSTYLE);
Result := ((ParentWnd = 0) or (ParentWnd = GetDesktopWindow)) and
((ExStyle and WS_EX_TOOLWINDOW = 0) or (ExStyle and WS_EX_APPWINDOW <>
0));
end
else
Result := False;
end;
procedure CleanUp(AList: TList);
var
i: Integer;
begin
for i := AList.Count - 1 downto 0 do
if not IsMainAppWindow(HWND(AList[i])) then
AList.Delete(i);
end;
procedure TForm2.Button2Click(Sender: TObject);
begin
UnSetHook;
end;
procedure TForm2.CMDestroyWnd(var Message: TMessage);
begin
if GWindowHandleList.IndexOf(Pointer(Message.WParam)) >= 0 then
begin
ListBox1.Items.Add(Format('HCBT_DESTROYWND: %s',
[IntToHex(Message.WParam, 8)]));
end
else
ListBox1.Items.Add('Onbekend');
end;
function ExecuteProg(FileName: string; Visibility: Integer; var ProcessID:
DWORD): Boolean;
var
zAppName: array[0..512] of Char;
zCurDir: array[0..255] of Char;
WorkDir: string;
StartupInfo: TStartupInfo;
ProcessInfo: TProcessInformation;
begin
StrPCopy(zAppName, FileName);
GetDir(0, WorkDir);
StrPCopy(zCurDir, WorkDir);
FillChar(StartupInfo, SizeOf(StartupInfo), #0);
StartupInfo.cb := SizeOf(StartupInfo);
StartupInfo.dwFlags := STARTF_USESHOWWINDOW;
StartupInfo.wShowWindow := Visibility;
Result := CreateProcess(nil, zAppName, nil, nil, False, Create_NEW_CONSOLE or
NORMAL_PRIORITY_CLASS, nil, nil, StartupInfo, ProcessInfo);
if Result then
begin
ProcessID := ProcessInfo.dwProcessId;
WaitForInputIdle(ProcessInfo.hProcess, 5000);
end;
end;
procedure TForm2.Button1Click(Sender: TObject);
function EnumWindowsProc(Wnd: HWND; ProcessID: DWORD): Boolean; stdcall;
var
PID: DWORD;
begin
GetWindowThreadProcessId(Wnd, @PID);
if (ProcessID = PID) then
GWindowHandleList.Add(Pointer(Wnd));
Result := True;
end;
var
ProcessID: DWORD;
i: Integer;
begin
if ExecuteProg(Edit1.Text, SW_SHOW, ProcessID) then
begin
GWindowHandleList.Clear;
repeat
EnumWindows(@EnumWindowsProc, LPARAM(ProcessID));
Sleep(100);
until GWindowHandleList.Count > 0;
for i := 0 to GWindowHandleList.Count - 1 do
ListBox1.Items.Add(Format('WindowHandle = %s',
[IntToHex(Integer(GWindowHandleList[i]), 8)]));
{ Dit kun je eventueel weghalen }
CleanUp(GWindowHandleList);
for i := 0 to GWindowHandleList.Count - 1 do
ListBox1.Items.Add(Format('Observe %s',
[IntToHex(Integer(GWindowHandleList[i]), 8)]));
with GWindowHandleList do
if Count <> 0 then
begin
while Count < 6 do
Add(nil);
SetObserver(Handle);
for i := 0 to 5 do
SetObservableWindow(HWND(Items[i]), i);
SetHook;
end;
end;
end;
initialization
GWindowHandleList := TList.Create;
finalization
GWindowHandleList.Free;
end. |
Dll:
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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
| library Capture;
uses
Windows,
CommCtrl,
Messages;
{$R *.RES}
type
PHookRec = ^THookRec;
THookRec = record
Observer: THandle;
ObservableWindow0: THandle;
ObservableWindow1: THandle;
ObservableWindow2: THandle;
ObservableWindow3: THandle;
ObservableWindow4: THandle;
ObservableWindow5: THandle;
HookID: HHOOK;
end;
const
CM_DestroyWnd = WM_USER + 1;
const
HookRecPtr: PHookRec = nil;
procedure SetObserver(Handle: HWnd);
begin
HookRecPtr.Observer := Handle;
end;
procedure SetObservableWindow(Handle: HWnd; Item: Integer);
begin
case Item of
0: HookRecPtr.ObservableWindow0 := Handle;
1: HookRecPtr.ObservableWindow1 := Handle;
2: HookRecPtr.ObservableWindow2 := Handle;
3: HookRecPtr.ObservableWindow3 := Handle;
4: HookRecPtr.ObservableWindow4 := Handle;
5: HookRecPtr.ObservableWindow5 := Handle;
end;
end;
function HookProc(Code: Integer; WParam, LParam: Longint): Longint;
stdcall;
begin
if (Code = HCBT_DESTROYWND) and
((WParam = HookRecPtr.ObservableWindow0) or
(WParam = HookRecPtr.ObservableWindow1) or
(WParam = HookRecPtr.ObservableWindow2) or
(WParam = HookRecPtr.ObservableWindow3) or
(WParam = HookRecPtr.ObservableWindow4) or
(WParam = HookRecPtr.ObservableWindow5)) then
begin
PostMessage(HookRecPtr.Observer, CM_DestroyWnd, WParam, LParam);
//CallNextHookEx(HookRecPtr.HookID, Code, WParam, LParam);
Result := 1;
end
else
Result := CallNextHookEx(HookRecPtr.HookID, Code, WParam, LParam)
end;
procedure SetHook;
begin
HookRecPtr.HookID := SetWindowsHookEx(WH_CBT, @HookProc, HInstance,
0);
end;
procedure UnSetHook;
begin
UnHookWindowsHookEx(HookRecPtr.HookID);
end;
exports
SetHook,
UnSetHook,
SetObserver,
SetObservableWindow;
procedure EntryPointProc(Reason: Integer);
const
hMapObject: THandle = 0;
begin
case reason of
DLL_PROCESS_ATTACH:
begin
hMapObject := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE, 0,
SizeOf(THookRec), 'CaptureDesktopEvents');
HookRecPtr := MapViewOfFile(hMapObject, FILE_MAP_WRITE, 0, 0, 0);
end;
DLL_PROCESS_DETACH:
begin
try
if HookRecPtr <> nil then
UnMapViewOfFile(HookRecPtr);
if hMapObject <> 0 then
CloseHandle(hMapObject);
except
end;
end;
end;
end;
begin
DllProc := @EntryPointProc;
EntryPointProc(DLL_PROCESS_ATTACH);
end. |
WErkt lekker, alleen IExplorer.exe dus niet, en daar gaat het juist om... hoe zou dat kunnen?
Is dit misschien wat kan helpen?Basically the notifications HCBT_CREATEWND and HCBT_DESTROYWND are called whenever a window is created or destroyed in the system. This type of behavior is exactly what I thought was required. I realized soon that WH_CBT and HCBT_CREATEWND and HCBT_DESTROYWND were too much. This hook will notify you for practically every window created in the system, with few exceptions. It meant I had to identify which windows were top level, non-child and visible. Since when an application starts several windows are created, this proved to be too much and not reliable enough.
After a more in-depth look at the documentation, I realized WH_SHELL might be just what I needed. It has several useful notifications: HSHELL_ACCESSIBILITYSTATE, HSHELL_ACTIVATESHELLWINDOW, HSHELL_GETMINRECT, HSHELL_LANGUAGE, HSHELL_REDRAW, HSHELL_TASKMAN, HSHELL_WINDOWACTIVATED, HSHELL_WINDOWCREATED, HSHELL_WINDOWDESTROYED. This hook notifies you only of actions happening to top level windows (for example, the main application window, which is what we have to deal with). WH_SHELL is easier to deal with and, unlike WH_CBT, our code doesn't require overly complex logic to get the functionality we specified. It just feels better when the code is not cluttered with special cases. WH_SHELL is a listen-only hook. We cannot modify its behavior, mainly because it notifies the filter process after the default behavior has taken place.
[edit1]
En wat is die observer eigelijks?
[edit2]
Hmmm bij calc.exe en die anderen die het niet doen gaat ie hier
1
2
3
| for i := AList.Count - 1 downto 0 do
if not IsMainAppWindow(HWND(AList[i])) then
AList.Delete(i); |
altijd die AList.Delete(i) doen.
En dat moet niet.
Dus die IsMainAppWindow is niet 100% ok.
FF zoeken
[edit3]
En wel, IsWindowVisible(Wnd) doet het niet goed
[edit4]
Hmm zelfs als je die if IsWindowVisible(Wnd) then weg laat, dus dat ie die IsMainAppWindow altijd true geeft, doet ie t nOg niet...
[edit5]
Notepad heeft 1, en calc heeft 2 handles......dat is het zekers?
[edit6]
En ditte
for i := 0 to 5 do
SetObservableWindow(HWND(Items[i]), i);
SetHook;
Moet ie die SetHook niet voor elke For actie doen?
[edit7]
Ik hoop dat je zo verder komt?
Ik kom er echt niet uit...
If then else matters! - I5 12600KF, Asus Tuf GT501, Gigabyte Gaming OC 16G 5080 RTX, Asus Tuf Gaming H670 Pro, 48GB, Corsair RM850X PSU, SN850 1TB, Arctic Liquid Freezer 280, ASUS RT-AX1800U router
Verwijderd
Ik dacht dat het de bedoeling was, om ervoor te zorgen dat een app niet afgesloten werd?WH_SHELL is a listen-only hook. We cannot modify its behavior, mainly because it notifies the filter process after the default behavior has taken place.
Als je deze functie toevoegd, kun je kijken wat de caption van de window is.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
| function GetWindowCaption(Wnd: HWND): string;
const
BufferAllocStep = 256;
var
Buffer: PChar;
Size, TextLen: Integer;
begin
Result := '';
Buffer := nil;
try
Size := GetWindowTextLength(Wnd) + 2 - BufferAllocStep;
repeat
Inc(Size, BufferAllocStep);
ReallocMem(Buffer, Size);
TextLen := GetWindowText(Wnd, Buffer, Size);
until TextLen < Size - 1;
if TextLen > 0 then
Result := Buffer;
finally
FreeMem(Buffer);
end;
end; |
Dan zul je zien dat bij de calculator de windows 'Rekenmachine' en 'CalcMsgPumpWnd' [?] gemaakt worden. Het programma identificeert Rekenmachine als de main window [dat klopt dus] en als de calculator afgesloten wordt, wordt ook een bericht verstuurd. Meest waarschijnlijke waarom het programma toch wordt afgesloten is dat het niet op een standaard manier geprogrammeerd is.
Bij explorer wordt geen window gevonden door EnumWindowsProc, die past bij de ProcessID. Ik weet niet precies wat dit betekent, maar dit zal er mee te maken hebben dat explorer ingebed zit in Windows.
Met een ander programma dat ik heb, kun je wel zien dat er verschillende windows worden gecreeerd. Dus misschien is er wel een truk hiervoor te verzinnen.
Je zult je denk ik wel moeten afvragen, of je de goeie weg ingeslagen bent. Zijn denk is simpelere manieren om te doen wat jij wilt - zover ik kan inschatten wat jij wilt.
NB. functies GetWindowCaption & IsMainAppWindow komen uit de JCL.
En weet je dan ook ongeveer welke manieren er nogmeer zijn?Zijn denk is simpelere manieren om te doen wat jij wilt - zover ik kan inschatten wat jij wilt
Anders weet ik het ook niet meer.
In iedergeval alvast heel erg bedankt voor de moeite DiFool
`t Hoeft trouwens alleen maar te werken voor Internet Explorer
If then else matters! - I5 12600KF, Asus Tuf GT501, Gigabyte Gaming OC 16G 5080 RTX, Asus Tuf Gaming H670 Pro, 48GB, Corsair RM850X PSU, SN850 1TB, Arctic Liquid Freezer 280, ASUS RT-AX1800U router
Verwijderd
Dmv subclassing vd Explorer window in de dll kun je WM_SYSCOMMAND etc afvangen.
Zal vanavond weer code posten [zit nu op werk]. Kan wel laat worden, want ik was van plan veel tv te kijken vandaag.
Ik wacht weer met smart
[edit]
Ik wacht nog steeds
If then else matters! - I5 12600KF, Asus Tuf GT501, Gigabyte Gaming OC 16G 5080 RTX, Asus Tuf Gaming H670 Pro, 48GB, Corsair RM850X PSU, SN850 1TB, Arctic Liquid Freezer 280, ASUS RT-AX1800U router
Verwijderd
Probleem is: hoe weet je welke window je moet subclassen? Het is vrij moeilijk om de window te achterhalen in de aanroepende applicatie; daarom laat ik het de dll bepalen.
Ik geef aan de dll het process id door van de window. De dll ziet welke windows er gecreerd worden en bepaald dan aan de hand van het process id en de classname van de window [moet 'ieframe' zijn] wat de internet explorer is.
Applicatie:
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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
| unit Capture02;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;
const
{ Dit bericht kan de dll sturen.. }
CM_NotifyObserver = WM_USER + 1;
{ ..met de volgende submessages }
NO_BeginSubClassed = 0;
NO_EndSubClassed = 1;
NO_ProcessIDFound = 2;
NO_ClosePrevented = 3;
type
TForm2 = class(TForm)
ListBox1: TListBox;
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
private
FSubClassedCount: Integer; // Aantal windows dat gesubclassed zijn
FHooking: Boolean; // Zijn we gestart met hooken?
FWantStopHooking: Boolean; // Willen we stoppen met hooken?
FWantClose: Boolean; // Willen we afsluiten?
protected
procedure CMNotifyObserver(var Message: TMessage); message
CM_NotifyObserver;
procedure StartHooking;
procedure StopSubClassing;
procedure StopHooking;
end;
var
Form2: TForm2;
implementation
{$R *.DFM}
procedure SetHook; external 'Capture.dll';
procedure UnSetHook; external 'Capture.dll';
procedure SetObserver(Handle: HWnd); external 'Capture.dll';
procedure SetWantProcessID(AProcessID: HWnd); external 'Capture.dll';
function GetClassNameWnd(Wnd: HWND): string;
begin
SetLength(Result, 80);
SetLength(Result, GetClassName(Wnd, PChar(Result), Length(Result)));
end;
function ExecuteProg(FileName: string; Visibility: Integer; var ProcessID:
DWORD): Boolean;
var
zAppName: array[0..512] of Char;
zCurDir: array[0..255] of Char;
WorkDir: string;
StartupInfo: TStartupInfo;
ProcessInfo: TProcessInformation;
begin
StrPCopy(zAppName, FileName);
GetDir(0, WorkDir);
StrPCopy(zCurDir, WorkDir);
FillChar(StartupInfo, SizeOf(StartupInfo), #0);
StartupInfo.cb := SizeOf(StartupInfo);
StartupInfo.dwFlags := STARTF_USESHOWWINDOW;
StartupInfo.wShowWindow := Visibility;
Result := CreateProcess(nil, zAppName, nil, nil, False, Create_NEW_CONSOLE or
NORMAL_PRIORITY_CLASS, nil, nil, StartupInfo, ProcessInfo);
if Result then
begin
ProcessID := ProcessInfo.dwProcessId;
WaitForInputIdle(ProcessInfo.hProcess, 5000);
end;
end;
procedure TForm2.Button1Click(Sender: TObject);
begin
StartHooking;
end;
procedure TForm2.Button2Click(Sender: TObject);
begin
StopHooking;
end;
procedure TForm2.CMNotifyObserver(var Message: TMessage);
begin
{ Berichten van de dll weergeven }
with ListBox1.Items do
case Message.WParam of
NO_BeginSubClassed:
begin
Inc(FSubClassedCount);
Add(Format('Subclassing %s started', [IntToHex(Message.LParam, 8)]));
end;
NO_EndSubClassed:
begin
Add(Format('Subclassing %s stopped', [IntToHex(Message.LParam, 8)]));
Dec(FSubClassedCount);
if FSubClassedCount = 0 then
begin
if FWantStopHooking then
StopHooking;
if FWantClose then
Close;
end;
end;
NO_ProcessIDFound:
Add(Format('ProcessID found in %s', [IntToHex(Message.LParam, 8)]));
NO_ClosePrevented:
Add(Format('Close prevented: %s', [IntToHex(Message.LParam, 8)]));
else
Add('Unknown message');
end;
end;
procedure TForm2.StartHooking;
var
ProcessID: DWORD;
begin
if FWantClose or FWantStopHooking or (FSubClassedCount > 0) then
Exit;
SetObserver(Handle);
SetHook;
{ Start IE }
if ExecuteProg('C:\Program Files\Internet explorer\iexplore.exe', SW_SHOW,
ProcessID) then
begin
{ Geef het process id door aan de dll }
SetWantProcessID(ProcessID);
ListBox1.Items.Add(Format('Started hooking, ProcessID = %d', [ProcessID]));
FHooking := True;
end
else
UnSetHook;
end;
procedure TForm2.StopHooking;
begin
if FSubClassedCount > 0 then
begin
{ Eerst stoppen met subclassing }
StopSubClassing;
FWantStopHooking := True;
Exit;
end;
UnSetHook;
ListBox1.Items.Add('Stopped hooking');
FHooking := False;
FWantStopHooking := False;
end;
procedure TForm2.StopSubClassing;
function EnumWindowsProc(Wnd: HWND; ProcessID: DWORD): Boolean; stdcall;
begin
if CompareText(GetClassNameWnd(Wnd), 'ieframe') = 0 then
{ Geef aan alle IE windows een stop bericht, de gesubclasste [?]
windows zullen hierop stoppen met subclassen. }
PostMessage(Wnd, WM_NULL, $15, $15);
Result := True;
end;
begin
EnumWindows(@EnumWindowsProc, 0);
end;
procedure TForm2.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
CanClose := not FHooking;
if FHooking then
begin
FWantClose := True;
StopHooking;
end;
end;
end. |
Dll
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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
| library Capture;
uses
Windows,
CommCtrl,
Messages,
SysUtils;
{$R *.RES}
type
PHookRec = ^THookRec;
THookRec = record
{ De window waarnaar we notification berichten sturen: }
Observer: THandle;
OldWndProc: Pointer;
{ Handle naar de IE window die we moeten subclassen, als deze 0 is
weten we het nog niet, maar kunnen we al windows gesubclassed hebben }
ObservedWindow: THandle;
HookID: HHOOK;
{ Process id van de IE window die we zouden moeten subclassen }
WantProcessID: DWORD;
end;
const
CM_NotifyObserver = WM_USER + 1;
NO_BeginSubClassed = 0;
NO_EndSubClassed = 1;
NO_ProcessIDFound = 2;
NO_ClosePrevented = 3;
const
HookRecPtr: PHookRec = nil;
{ Hulpfunctie om berichten naar de observer te sturen }
procedure NotifyObserver(Msg, SubMsg: Integer);
begin
PostMessage(HookRecPtr.Observer, CM_NotifyObserver, Msg, SubMsg);
end;
procedure UnSubClass(Handle: HWnd);
begin
SetWindowLong(Handle, GWL_WNDPROC, Longint(HookRecPtr.OldWndProc));
NotifyObserver(NO_EndSubClassed, LongInt(Handle));
end;
function WndProc(Wnd: HWND; Msg, WParam, LParam: Longint): Longint; stdcall;
var
PID: DWORD;
begin
{ Als ObservedWindow 0 is [dus we weten nog niet welke window
we zouden moeten subclassen], en het process ID is bekend, dan.. }
if (HookRecPtr.ObservedWindow = 0) and (HookRecPtr.ObservedWindow <> Wnd) and
(HookRecPtr.WantProcessID > 0) then
begin
{ ..bepaal het process id van deze window }
GetWindowThreadProcessId(Wnd, @PID);
if PID <> HookRecPtr.WantProcessID then
begin
{ We willen niet deze window gesubclassed hebben.. }
Result := CallWindowProc(HookRecPtr.OldWndProc, Wnd, Msg, WParam, LParam);
UnSubClass(Wnd);
Exit;
end
else
begin
{ We willen wel deze window gesubclassed hebben.. }
HookRecPtr.ObservedWindow := Wnd;
NotifyObserver(NO_ProcessIDFound, LongInt(Wnd));
end;
end;
if (Msg = WM_NULL) and (WParam = $15) and (LParam = $15) then
begin
{ Speciaal bericht van de observer, om te stoppen met subclassen }
UnSubClass(Wnd);
Result := 0;
end
else if ((Msg = WM_SYSCOMMAND) and (WParam = SC_CLOSE)) or
((Msg = WM_COMMAND) and (WParam = 40993)) then
begin
{ WM_SYSCOMMAND -> via window menu
WM_COMMAND -> via File|Sluiten }
NotifyObserver(NO_ClosePrevented, LongInt(Msg));
Result := 0
end
else
Result := CallWindowProc(HookRecPtr.OldWndProc, Wnd, Msg, WParam,
LParam);
end;
procedure SubClass(Handle: Hwnd);
begin
HookRecPtr.OldWndProc := Pointer(GetWindowLong(Handle, GWL_WNDPROC));
SetWindowLong(Handle, GWL_WNDPROC, Longint(@WndProc));
NotifyObserver(NO_BeginSubClassed, LongInt(Handle));
end;
procedure SetObserver(Handle: HWnd);
begin
HookRecPtr.Observer := Handle;
end;
function GetClassNameWnd(Wnd: HWND): string;
begin
SetLength(Result, 80);
SetLength(Result, GetClassName(Wnd, PChar(Result), Length(Result)));
end;
function HookProc(Code: Integer; WParam, LParam: Longint): Longint;
stdcall;
var
ExStyle: LongInt;
begin
{ Als we nog niet weten welke window we moeten subclassen
[ObservedWindow = 0], dan subclass deze window.. }
if (Code = HCBT_CREATEWND) and (HookRecPtr.ObservedWindow = 0) then
begin
{ ..tenminste als het een IE window is }
ExStyle := GetWindowLong(WParam, GWL_EXSTYLE);
if (ExStyle = 256) and (CompareText(GetClassNameWnd(WParam), 'ieframe') = 0)
then
SubClass(WParam);
end;
Result := CallNextHookEx(HookRecPtr.HookID, Code, WParam, LParam)
end;
procedure SetWantProcessID(AProcessID: DWORD);
begin
HookRecPtr.WantProcessID := AProcessID;
end;
procedure SetHook;
begin
HookRecPtr.WantProcessID := 0;
HookRecPtr.ObservedWindow := 0;
HookRecPtr.HookID := SetWindowsHookEx(WH_CBT, @HookProc, HInstance, 0);
end;
procedure UnSetHook;
begin
UnHookWindowsHookEx(HookRecPtr.HookID);
end;
exports
SetHook,
UnSetHook,
SetObserver,
SetWantProcessID;
procedure EntryPointProc(Reason: Integer);
const
hMapObject: THandle = 0;
begin
case reason of
DLL_PROCESS_ATTACH:
begin
hMapObject := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE, 0,
SizeOf(THookRec), 'CaptureDesktopEvents');
HookRecPtr := MapViewOfFile(hMapObject, FILE_MAP_WRITE, 0, 0, 0);
end;
DLL_PROCESS_DETACH:
begin
try
if HookRecPtr <> nil then
UnMapViewOfFile(HookRecPtr);
if hMapObject <> 0 then
CloseHandle(hMapObject);
except
end;
end;
end;
end;
begin
DllProc := @EntryPointProc;
EntryPointProc(DLL_PROCESS_ATTACH);
end. |
Heb je dat echt allemaal zelf gemaakt??
Jemig, wat knap.
Nou ik zal vanavond testen of het werkt
Tnx man! Tnx
Wat een boel he
Van 80% snap ik nix, maarja
If then else matters! - I5 12600KF, Asus Tuf GT501, Gigabyte Gaming OC 16G 5080 RTX, Asus Tuf Gaming H670 Pro, 48GB, Corsair RM850X PSU, SN850 1TB, Arctic Liquid Freezer 280, ASUS RT-AX1800U router
En dubbelklik linksbovenin...
If then else matters! - I5 12600KF, Asus Tuf GT501, Gigabyte Gaming OC 16G 5080 RTX, Asus Tuf Gaming H670 Pro, 48GB, Corsair RM850X PSU, SN850 1TB, Arctic Liquid Freezer 280, ASUS RT-AX1800U router
Verwijderd
1
2
3
4
5
6
7
8
| else if ((Msg = WM_SYSCOMMAND) and ((WParam = SC_CLOSE) or (WParam = 61539)))
or
((Msg = WM_COMMAND) and ((WParam = 40993) or (WParam = 106529)))
then
begin
NotifyObserver(NO_ClosePrevented, LongInt(Msg));
Result := 0
end |
CTRL + W: Msg = WM_SYSCOMMAND; WParam = 61539
Dubbelklik: Msg = WM_COMMAND; WParam = 106529
D'r zitten nog wel fouten in het programma, zoals: Caption van IE klopt niet; dll kan maar 1 oude WndProc onthouden, gaat dus fout als 2 of meer windows gesubclassed worden; gaat iets fout bij meerdere keren hooken van windows zonder dat de IE window afgesloten wordt.
Ik hoef maar 1 IE venster te openen, dus dat andere is geen probleem meer
If then else matters! - I5 12600KF, Asus Tuf GT501, Gigabyte Gaming OC 16G 5080 RTX, Asus Tuf Gaming H670 Pro, 48GB, Corsair RM850X PSU, SN850 1TB, Arctic Liquid Freezer 280, ASUS RT-AX1800U router
In iedergeval hartstikke bedankt voor je hulp!
If then else matters! - I5 12600KF, Asus Tuf GT501, Gigabyte Gaming OC 16G 5080 RTX, Asus Tuf Gaming H670 Pro, 48GB, Corsair RM850X PSU, SN850 1TB, Arctic Liquid Freezer 280, ASUS RT-AX1800U router
Verwijderd
Caption probleem, kwam doordat ik de ANSI api's aanriep GetWindowLong, CallWindowProc etc. terwijl IE [in XP, 2000?] unicode is. Dit los je dan op door GetWindowLongW en CallWindowProcW aan te roepen.
Ik heb het niet getest in windows 98/95, dan moet je denk ik wel GetWindowLong, CallWindowProc aanroepen. Dit kun je oplossen door de api IsWindowUnicode aan te roepen voor het subclassen, en 2 WndProc te implementeren: 1 ansi [die dus gemaakt wordt met GetWindowLong en CallWindowProc aanroept] en 1 unicode [die gemaakt wordt met GetWindowLongW en CallWindowProcW aanroept]; maar dat heb ik niet gedaan, mag jij doen
Foutmelding bij 2 of meer gesubclasste IE kwam doordat als je een gesubclasste IE afsloot, alle dll's gedetached worden. Oplossing is bij het detachen van een dll, de window te unsubclassen.
Code dll:
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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
| library Capture;
uses
Windows,
CommCtrl,
Messages,
SysUtils;
{$R *.RES}
type
PHookRec = ^THookRec;
THookRec = record
RObserver: THandle;
RObservedWindow: THandle;
RHookID: HHOOK;
RWantProcessID: DWORD;
end;
const
CM_NotifyObserver = WM_USER + 1;
CM_NotifyObserverMsg = WM_USER + 2;
NO_BeginSubClassed = 0;
NO_EndSubClassed = 1;
NO_ProcessIDFound = 2;
NO_ClosePrevented = 3;
NO_StartProcess = 4;
NO_EndProcess = 5;
var
{ Alle instanties van de dll die geinjecteerd worden in een window
krijgen eigen instanties van de volgende vars: }
{ Pointer naar de data die alle dll instanties delen }
GHookRecPtr: PHookRec = nil;
{ Handle naar de filemapping object }
GMapObject: THandle = 0;
{ Pointer naar oude wndproc }
GOldWndProc: Pointer = nil;
{ Handle naar Window die gesubclassed is }
GHandle: THandle = 0;
procedure NotifyObserver(Msg, SubMsg: Integer);
begin
PostMessage(GHookRecPtr.RObserver, CM_NotifyObserver, Msg, SubMsg);
end;
procedure UnSubClass {(Handle: HWnd)};
begin
if (GOldWndProc <> nil) and (GHandle > 0) then
begin
SetWindowLongW(GHandle, GWL_WNDPROC, Longint(GOldWndProc));
NotifyObserver(NO_EndSubClassed, LongInt(GHandle));
GOldWndProc := nil;
GHandle := 0;
end;
end;
function WndProc(Wnd: HWND; Msg, WParam, LParam: Longint): Longint; stdcall;
var
PID: DWORD;
begin
with GHookRecPtr^ do
begin
if (RObservedWindow = 0) and (RWantProcessID > 0) then
begin
GetWindowThreadProcessId(Wnd, @PID);
if PID <> RWantProcessID then
begin
Result := CallWindowProcW(GOldWndProc, Wnd, Msg, WParam, LParam);
UnSubClass {(Wnd)};
Exit;
end
else
begin
RObservedWindow := Wnd;
NotifyObserver(NO_ProcessIDFound, LongInt(Wnd));
end;
end;
case Msg of
WM_NULL:
if (WParam = $15) and (LParam = $15) then
begin
UnSubClass;
Result := 0;
Exit;
end;
WM_SYSCOMMAND:
if (WParam = SC_CLOSE) or (WParam = 61539) then
begin
NotifyObserver(NO_ClosePrevented, LongInt(Msg));
Result := 0;
Exit;
end;
WM_COMMAND:
if (WParam = 40993) or (WParam = 106529) then
begin
NotifyObserver(NO_ClosePrevented, LongInt(Msg));
Result := 0;
Exit;
end;
end;
Result := CallWindowProcW(GOldWndProc, Wnd, Msg, WParam, LParam);
end;
end;
procedure SubClass(Handle: Hwnd);
begin
GHandle := Handle;
GOldWndProc := Pointer(GetWindowLong(Handle, GWL_WNDPROC));
SetWindowLongW(Handle, GWL_WNDPROC, Longint(@WndProc));
NotifyObserver(NO_BeginSubClassed, LongInt(Handle));
end;
procedure SetObserver(Handle: HWnd);
begin
GHookRecPtr.RObserver := Handle;
end;
function GetClassNameWnd(Wnd: HWND): string;
begin
SetLength(Result, 80);
SetLength(Result, GetClassName(Wnd, PChar(Result), Length(Result)));
end;
function HookProc(Code: Integer; WParam, LParam: Longint): Longint;
stdcall;
var
ExStyle: LongInt;
begin
if (Code = HCBT_CREATEWND) and (GHookRecPtr.RObservedWindow = 0) then
begin
ExStyle := GetWindowLong(WParam, GWL_EXSTYLE);
if (ExStyle = 256) and (CompareText(GetClassNameWnd(WParam), 'ieframe') = 0)
then
SubClass(WParam);
end;
Result := CallNextHookEx(GHookRecPtr.RHookID, Code, WParam, LParam)
end;
procedure SetWantProcessID(AProcessID: DWORD);
begin
GHookRecPtr.RWantProcessID := AProcessID;
end;
procedure SetHook;
begin
with GHookRecPtr^ do
begin
RWantProcessID := 0;
RObservedWindow := 0;
RHookID := SetWindowsHookEx(WH_CBT, @HookProc, HInstance, 0);
end;
end;
procedure UnSetHook;
begin
UnHookWindowsHookEx(GHookRecPtr.RHookID);
end;
exports
SetHook,
UnSetHook,
SetObserver,
SetWantProcessID;
procedure EntryPointProc(Reason: Integer);
begin
case reason of
DLL_PROCESS_ATTACH:
begin
GMapObject := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE, 0,
SizeOf(THookRec), 'CaptureDesktopEvents');
GHookRecPtr := MapViewOfFile(GMapObject, FILE_MAP_WRITE, 0, 0, 0);
NotifyObserver(NO_StartProcess, 0);
end;
DLL_PROCESS_DETACH:
begin
UnSubClass;
NotifyObserver(NO_EndProcess, 0);
try
if GHookRecPtr <> nil then
UnMapViewOfFile(GHookRecPtr);
if GMapObject <> 0 then
CloseHandle(GMapObject);
except
end;
end;
end;
end;
begin
DllProc := @EntryPointProc;
EntryPointProc(DLL_PROCESS_ATTACH);
end. |
Harstikke bedankt! Hoe weet jij dat allemaal ??
Het werkt nu prima!
Nu nog implementeren.
Dat is erg lastig, aangezien ik al hooks heb voor minimalizeren, en dat combineren wil nog niet echt lukken
[edit]
Pfff volgens mij is het gelukt
If then else matters! - I5 12600KF, Asus Tuf GT501, Gigabyte Gaming OC 16G 5080 RTX, Asus Tuf Gaming H670 Pro, 48GB, Corsair RM850X PSU, SN850 1TB, Arctic Liquid Freezer 280, ASUS RT-AX1800U router
Nog only 1 thing...
Kan ik ook zorgen dan dat hij niet visible is op de taskbar, maar wel gewoon zichtbaar is op je buroblad zeg maar?
If then else matters! - I5 12600KF, Asus Tuf GT501, Gigabyte Gaming OC 16G 5080 RTX, Asus Tuf Gaming H670 Pro, 48GB, Corsair RM850X PSU, SN850 1TB, Arctic Liquid Freezer 280, ASUS RT-AX1800U router
Verwijderd
[edit]
Wellicht de unicode versie dus SetWindowLongW.