If then else matters! - I5 12600KF, Asus Tuf GT501, Asus Tuf OC 3080, 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, Asus Tuf OC 3080, 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, Asus Tuf OC 3080, 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, Asus Tuf OC 3080, 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, Asus Tuf OC 3080, 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, Asus Tuf OC 3080, 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, Asus Tuf OC 3080, 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, Asus Tuf OC 3080, 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, Asus Tuf OC 3080, 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, Asus Tuf OC 3080, 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, Asus Tuf OC 3080, 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, Asus Tuf OC 3080, 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, Asus Tuf OC 3080, 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, Asus Tuf OC 3080, 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, Asus Tuf OC 3080, 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, Asus Tuf OC 3080, 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, Asus Tuf OC 3080, 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.