[VB6] Window Messages van andere applicate opvangen

Pagina: 1
Acties:

  • BestTested!
  • Registratie: Oktober 2003
  • Laatst online: 07:32
Hi allemaal,

Ik ben bezig met een soort van Multimedia shell (a la meedio) maar dan wat lichter. Binnen deze shell mag er maar een beperk aantal andere programma's gestart worden. (vooraf gedefineerd welke). Deze andere applicaties draaien 'binnen' mijn shell.

Dit heb ik nu allemaal werkend, maar ik wil ook dat sommige applicaties NIET afgesloten kunnen worden. Ik ben daarmee aan de slag gegaan en heb de volgende 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
Private Const GWL_WNDPROC = (-4) 
Private Const WM_CLOSE As Long = &H10

Private lngOldProc As Long

Public Function getWindowHandler(title As String) As Long
getWindowHandler = FindWindow(vbNullString, title)
End Function

Public Function WindowProc(ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
       
If Msg = WM_CLOSE Then
    MsgBox "Closure"
Else
    WindowProc = CallWindowProc(lngOldProc, hwnd, Msg, wParam, lParam)
End If

End Function

Public Function setHook(handler As Long)
lngOldProc = SetWindowLongA(handler, GWL_WNDPROC, AddressOf WindowProc)
End Function

Public Function closeApp(handler As Long)
SendMessage handler, WM_CLOSE, 0, 0&
End Function

en
code:
1
2
3
4
Dim handler As Long
handler = getWindowHandler(" *** Applicatie *** ")
setHook (handler)
closeApp (handler)


Het lijkt echter wel alsof de setHook niet goed werkt. Het oude adres (de return value) is altijd 0. Weet iemand waar mijn fout zit. Wanneer ik als applicatie zichzelf gebruik werkt het wel. Kan ik soms geen WindowProc van een andere applicatie overschrijven?

Tot zover ben ik gekomen met debuggen, en op internet vind ik ook enkel voorbeelden waar de eigen WindowProc wordt gewijzigd en niet die van een andere applicatie.

NB. Dit hele Messaging systeem is voor mij redelijk nieuw, ben hier nog maar pas mee begonnen.

Verwijderd

Als je msdn bekijkt zie je dat SetWindowLong een 0 returned als hij failed, met GetLastError zie je wat er fout.

Zou eens kijken of je handle die FindWindow terug geeft wel valid is.

[ Voor 25% gewijzigd door Verwijderd op 09-04-2005 16:02 ]


  • BestTested!
  • Registratie: Oktober 2003
  • Laatst online: 07:32
Ik neem aan dat ik gewoon GetLastError() direct na de SetWindowLong aanroep? In dat geval krijg ik error 5 terug, oftewel: ERROR_ACCESS_DENIED.

Is er misschien een work-around om dit toch te kunnen realiseren?

  • Gerco
  • Registratie: Mei 2000
  • Laatst online: 08-05 18:46

Gerco

Professional Newbie

Het lijkt me logisch dat je geen wndProc van een ander proces kan opvangen. Binnen Windows heeft elk proces ten eerste al zijn eigen address space en een adres binnen dat proces betekent dus helemaal niets voor het jouwe, je zou de oude wndProc bijv niet meer kunnen aanroepen.

Wat je wel kunt doen is een zelfde techniek als ook voor global keyloggers gebruikt wordt, je maakt een dll die in alle processen wordt ingeladen en gaat op die manier de boel afvangen. Via 1 of ander IPC mechanisme kun je dan de boel besturen.

Kijk hier voor een voorbeeldje van zo'n dll. Ik heb 'em zelf niet gemaakt, maar alleen gewrapped, dus de vb code is niet interessant in dit voorbeeld.

Het gaat dan vooral om de SetWindowsHookEx() call, daarmee kun je een global message hook (of keyboard of muis) installeren. Het IPC mechanisme in dit geval is window messages. De dll kan ook geen functie in jouw proces direct aanroepen vanwege dat address space issue.

[ Voor 36% gewijzigd door Gerco op 09-04-2005 16:35 ]

- "Als ik zou willen dat je het begreep, legde ik het wel beter uit!" | All number systems are base 10!