PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : C++ WindowMessages abfangen


BofD
2004-06-27, 13:49:02
Hallo,
gibt es in C++ die Möglichkeit WindowMessages von anderen Programmen abzufangen und späten wieder zu diesen Programmen zurückzusenden? Sozusagen ein "externer Messagehandler". Ich will ein Programm schreiben, dass systemweit alle Messages aufzeichnet.

Also ich hab mir mal folgendes überlegt:
Grundsätzlich braucht man ja erstmal ein normalen MessageLoop. Etwa so:
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow )
{
MSG msg;
while (GetMessage(..))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
Normalerweise würde man ja statt GetMessage(..) einfach GetMessage(&msg, (HWND)NULL, 0, 0) schreiben. Ich will aber ja nicht nur von meiner eigenen Anwendung die Messages, sondern von allen.
Gibt es eine Funktion, die alle Messages auf einmal abfängt?
Eine andere Möglichkeit wäre von jedem Fenster einzeln die Messages nacheinander abzufangen. Nur wie kann ich ein Array von Handles erzeugen, die auf jeweils ein anderes Fenster zeigen?
Oder Geht das ganze auch einfacher indem man direkt auf den MessageQueue zugreifen kann?

Metal Maniac
2004-06-27, 18:05:30
Vielleicht mit 'ner Hook probieren? Ich hab' mich vor einiger Zeit mal damit gespielt, um für Windows bestimmte Tastatureingaben zu filtern (z.B. Deaktivieren von Systemtasten etc.). Mit globalen Hooks kann man alle möglichen Messages vom System abfangen und verarbeiten. Hab' mich allerdings nicht weiter damit beschäftigt...

Infos zu Hooks:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/WinUI/WindowsUserInterface/Windowing/Hooks/AboutHooks.asp

zeckensack
2004-06-28, 07:48:05
Aktuell erfolgreich im Einsatz:LRESULT CALLBACK
message_filter(HWND window,UINT message,WPARAM wp,LPARAM lp)
{

switch(message)
{
default:
LOG_P("Passing on a 0x%X message\n",message);
return(CallWindowProc(fstate.client_window_proc,window,message,wp,lp));
case(WM_CAPTURECHANGED):
case(WM_DISPLAYCHANGE):
case(WM_DEVMODECHANGE):
case(WM_SIZE):
case(WM_SIZING):
case(WM_MOVE):
case(WM_MOVING):
case(WM_WINDOWPOSCHANGING):
case(WM_WINDOWPOSCHANGED):
// case(WM_PAINT):
// case(WM_NCPAINT):
// case(WM_ERASEBKGND):
LOG_P("filtered a 0x%X message\n",message);
return(0);
break;
}
}

void
install_message_filter(HWND window)
{
if ((!fstate.message_filter_installed)&&(window!=NULL))
{
fstate.client_window_proc=(WNDPROC)GetWindowLong(window,GWL_WNDPROC);
SetWindowLong(window,GWL_WNDPROC,(LONG)message_filter);
fstate.message_filter_installed=true;
LOG_P("message filter installed on window 0x%X\n",window);
LOG_P("-old window proc was 0x%X, ",fstate.client_window_proc);
LOG_P("filter proc is 0x%X\n",(uint)message_filter);
}
}

void
remove_message_filter(HWND window)
{
if (fstate.message_filter_installed)
{
if (GetWindowLong(window,GWL_WNDPROC)==(LONG)message_filter)
{
SetWindowLong(window,GWL_WNDPROC,(LONG)fstate.client_window_proc);
LOG_P("message filter removed from window 0x%X\n",window);
LOG_P("-window proc has been restored to 0x%X\n",(uint)fstate.client_window_proc);
}
else
{
LOG_P("message filter could not be removed from window 0x%X\n",window);
LOG("-window proc was changed by client\n");
}
fstate.message_filter_installed=false;
}
}

D-Swat
2004-06-28, 21:15:20
@zeckensack
Subclassing von Windows funktioniert aber nicht über Prozessgrenzen hinweg. ( jedenfalls laut msdn )
Funktioniert also nur innerhalt der eigenen Applikation.