View Full Version : Dite che è possibile?
dico subito che io penso di si e passo ad esporre
supponiamo che da un vostro programma vogliate pilotare IE (il vostro Browser) in questo senso
conndizione iniziale: IE non è in esecuzione
lanciate il vostro programma e cliccando su di un Button eseguite le seguenti funzioni:
a) aprite Internet Explorer
b) attivate il menu File
c) attivate la voce di menu Apri
d) gli fornite il percorso di un'immagine
e) rispondete attraverso il vostro programma di caricare l'immagine
f) l'immagine viene mostrata si IE aperto dal vostro programma
io penso che con gli Hook di windows sia possibile ma non conosco questa tecnica di programmazione:)
Credo che basti inviare i messaggi giusti alle varie finestre...
Spiegami però cosa vuoi fare di preciso perchè ci potrebbero essere soluzioni alternative...
bravo, infatti ho trovato la SendMessage()
in breve cosa desider ottenere
ho un programma costituito da diverse schermate, ad ogno schermata corrispodono ben definiti campi e per arrivare ad una schermata particolare devi cliccare e selezionare molti controlli
il mio programma, dovrebbe fungere da menu semplificato el senso che, se dico all'utente di visualizzare una determinata schermata è sufficiente che clicchi su di un pulsante della mia applicazione
non so se sono stato chiaro
vedi esempio sopra di IE dove per visualizzare un'immagine nella sua finestra devi compiere un certo numero di operazioni; supponi di aver scritto un programma dove su di una form vi sia un pulsante con scritto "mostra immagine in IE" e cliccandovi sopra il tutto avviene automaticamente
in pratica, fornire istruzioni ad IE attraverso un tuo programma:)
Non ti basta passare il link da aprire quando lanci IE ?
o, quello di IE è solo un banale esempio; supponi che vuoi dire a word di salvare tutti i documenti aperti e chiudersi
SendMessage(HWND, UINT, WPARAM, LPARAM)
almeno, penso sia questa l'API da usare
solo per darti un'idea :
LPCTSTR lpClassName = NULL;
HWND hWnd = FindWindow( lpClassName,
"Test.cpp - WordPad");
SetWindowPos(
hWnd,
HWND_TOP,
0,
0,
800,
600,
SWP_SHOWWINDOW
);
dico a windows di ingrandire la finestra di WordPad a 800x600 pixel
supponi che gli voglia dire, attraverso il mio programma, di aprire in WordPad la finestra "Visualizza->opzioni"
Devi vedere che messaggio viene inviato all'applicazione per aprire quell'opzione del menù...
Ti serve un programma tipo Spy++ del Visual Studio...
e qui entrano in gioco gli hook di windows, penso
Spy, dal nome mi fa pensare a qualcosa di poco pulito
l'applicazione che intendo scrivere io invece, è pulitissima
sarebbe comoda ad esempio per far compiere alle più svariate applicazioni i compiti più ripetitivi:)
Spy++ è completamente legale...serve per monitorare i msg che vengono inviate all'applicazione... In ogni caso ci dovrebbe essere un DDE server in Internet Exploder :)
mi sto convincendo che scrivere u programma che catturi i messagi di un programma esterno non sia poi così complesso in quanto tutto windows è basato su essi: spero di non essere troppo facilone:)
il problema è trovare documentazione valida
ho provato a spedire ed a ricevere messaggi tra 2 miei programmi ed il tutto sembra funzionare ma, diverso è "strapparli" da un programma esterno ed ignoto:)
leggo male o qui si dice che la GetMessage() non ritorna messaggi di un'applizazione esterna?
The GetMessage function retrieves a message from the calling thread's message queue and places it in the specified structure. This function can retrieve both messages associated with a specified window and thread messages posted via the PostThreadMessage function. The function retrieves messages that lie within a specified range of message values. GetMessage does not retrieve messages for windows that belong to other threads or applications.
Sì...infatti la tua affermazione mi sembrava un po' troppo affrettata ;)
infatti ho una gran fretta:)
se trovi documentazione in merito, grazie
temo che si debbano usare gli hook ma, se esiste già qualcosa di pronto non lo disdegno, una sorta di registratore di messaggi ed eventi di questo tipo:
supponi di voler stampare un libro di 20 capitoli, e supponiamo che sia scritto in word, e supponiamo anche che dello script editor interno non ti importi nulla: lanci il programma che chameremo "recorder", gli dici quale programma monitorare, e da quel momento memorizza tutto ciò che selezioni o clicchi in word
in questo modo, anche i programmi nei quali non è prevista questa funzionalità divengono più produttivi
tornando a word, supponi che "recorder" momorizzi:
a) apertura del primo capitolo
b) inserimento numeri di pagina
c) creazione del sommario
d) stampa
poi
apertura del secondo capitolo etc....
la prossima volta che ti serve stampare è sufficiente cliccare su un pulsante di recorder e word esegue fedelmente quanto comandato:)
se ti capita qualcosa di simile;)
Comunque quasi tutti i programmi della Microsoft hanno un server DDE interno... Informati su questa tecnologia...
Comunque SetWindowsHookEx...
Esiste una versione freeware di Spy++ ??:)
stò provando ad usare PostMessage()
Non lo so mi dispiace...
Comunque Spy++ non fa altro che settare un hook per la cattura dei messaggi sul processo che scegli...
l'ho trovato ma, come fai a disctricarti in quella marea di messaggi?
un pò troppi per i miei gusti
Li puoi filtrare...ad esempio elimina quelli del mouse...
cmq, è un massacro, spedendo ad esempio a Notepad i medesimi messaggi non funziona nulla
mah.....
Gli devi spedire anche gli stessi valori in wParam e lParam...attenzione...
già fatto ma non cambia nulla:(
un esempio:
000007F0 S WM_NCACTIVATE fActive:True [wParam:00000001 lParam:00000000]
000007F0 P message:0x0624 [User-defined:WM_USER+548] wParam:00000000 lParam:00000000
000007F0 S WM_NCHITTEST xPos:732 yPos:44 [wParam:00000000 lParam:002C02DC]
000007F0 P WM_NCMOUSEMOVE nHittest:HTBORDER xPos:732 yPos:44 [wParam:00000012 lParam:002C02DC]
000007F0 S WM_NCHITTEST xPos:731 yPos:42 [wParam:00000000 lParam:002A02DB]
000007F0 P WM_NCMOUSEMOVE nHittest:HTMENU xPos:731 yPos:42 [wParam:00000005 lParam:002A02DB]
000007F0 S WM_NCHITTEST xPos:731 yPos:41 [wParam:00000000 lParam:002902DB]
000007F0 P WM_NCMOUSEMOVE nHittest:HTMENU xPos:731 yPos:41 [wParam:00000005 lParam:002902DB]
000007F0 S WM_NCHITTEST xPos:730 yPos:39 [wParam:00000000 lParam:002702DA]
000007F0 P WM_NCMOUSEMOVE nHittest:HTMENU xPos:730 yPos:39 [wParam:00000005 lParam:002702DA]
000007F0 S WM_NCHITTEST xPos:730 yPos:38 [wParam:00000000 lParam:002602DA]
000007F0 P WM_NCMOUSEMOVE nHittest:HTMENU xPos:730 yPos:38 [wParam:00000005 lParam:002602DA]
000007F0 P message:0x0118 [Unknown] wParam:0000FFF6 lParam:178F7DBA
000007F0 S WM_NCHITTEST xPos:730 yPos:38 [wParam:00000000 lParam:002602DA]
000007F0 P WM_NCLBUTTONDOWN nHittest:HTMENU xPos:730 yPos:38 [wParam:00000005 lParam:002602DA]
000007F0 S WM_NCCALCSIZE fCalcValidRects:True lpncsp:00B6E87E [wParam:00000001 lParam:00B6E87E]
000007F0 S WM_NCPAINT hrgn:0000077C [wParam:0000077C lParam:00000000]
000007F0 S message:0x0125 [Unknown] wParam:0000020C lParam:00000000
000007F0 S WM_NCACTIVATE fActive:False [wParam:00000000 lParam:00000F8C]
000007F0 S WM_NCACTIVATE fActive:True [wParam:00000001 lParam:00000F8C]
000007F0 S WM_NCCALCSIZE fCalcValidRects:True lpncsp:00B6E272 [wParam:00000001 lParam:00B6E272]
000007F0 S WM_NCPAINT hrgn:00000E90 [wParam:00000E90 lParam:00000000]
000007F0 S WM_NCCALCSIZE fCalcValidRects:True lpncsp:00B6E272 [wParam:00000001 lParam:00B6E272]
000007F0 S WM_NCPAINT hrgn:00000F94 [wParam:00000F94 lParam:00000000]
000007F0 S WM_NCCALCSIZE fCalcValidRects:True lpncsp:00B6EEE2 [wParam:00000001 lParam:00B6EEE2]
000007F0 S WM_NCPAINT hrgn:000006C8 [wParam:000006C8 lParam:00000000]
000007F0 S WM_NCACTIVATE fActive:False [wParam:00000000 lParam:00000000]
dovrebbe semplicemente aprire un nuovo documento
No...togli WM_NC*... Sono relativi ala posizione del puntatore del mouse sullo schermo...basta spostare l'applicazione od averla in background che non funziona più niente !!!
Interessanti maari sono i tre [unknown]...prova a mandare solo l'ultimo...
questo è quello che invio
PostMessage(hWnd, WM_COMMAND, 0x201,0);
No...dicevo scegliere di non vedere tutti i messaggi WM_NC*...
Prova ad inviare l'ultimo messaggio di topo [unknown]...
PostMessage(hWnd, 0x0125, 0x0000020C, 0);
non accade nulla ma in compenso
PostMessage(hWnd, WM_COMMAND, 0x08, 0x0);
apre la finestra Trova di Notepad
mah....
PostMessage(hWnd, WM_COMMAND, 0x09, 0x0);
questo attiva il menu nuovo documento
Prova quelli da 1 a 7 e guarda cosa fanno ;)
Probabilmente quei comandi sono associati ai tasti di shortcut...
cmq, ho capito l'uso di spy++: tanta pazienza
meno male che i parametri (wParam/lParam) da PC a PC non cambiano: giusto?
ma sono parte dell'aplicazione
penso che l'inconveniente stia se lo utilizzi in versioni differenti dello stesso prodotto come ad esempio:
becchi i comandi per la versione 5.0 di Notepad ma non è detto che funzionino poi sulla versione 6.0:)
Giusto...
Alcuni parametri possono essere definiti dal programma...ed anche alcuni messaggi possono essere registrati dal programma stesso...
In toeria l'interpretazione che un programma fa dei messaggi è completamente a discrezione del programmatore...
Quindi anche da versione a versione possono cambiare...
ma una volta compilato un programma i parametri dovrebbero rimanere sempre tali: giusto?
dimmi se ti sembra un inizio per agganciarsi ad un programma esterno:
HOOKPROC hkprcShell;
static HINSTANCE hinstDLL;
static HHOOK hhookShell;
hinstDLL = LoadLibrary((LPCTSTR) "<your DLL>");
hkprcSysMsg = (HOOKPROC)GetProcAddress(hinstDLL, "ShellProc");
hhookSysMsg = SetWindowsHookEx(WH_SHELL,hkprcSysMsg,hinstDLL,0);
int ShellProc(int nCode, WPARAM wparam, LPARAM lparam)
{
if (nCode == HSHELL_WINDOWCREATED)
{
HWND hwndApp = (HWND)wparam;
PostMessage(hwndApp, WM_CLOSE);
}
return 0;
}
ovviamente, in luogo della LoadLibrary() avevo in mente di passargli una FindWindow()
chissà perchè mi sembra di essere fuori strada:(
Da quello che ne so, in VC++ si può mettere un hook solo da una DLL... Non so perchè...però mi sembra di aver capito che sia così...
Ti conviene cercare un esempio...io se vuoi ho l'esempio in VC++ di un keylogger...
ne ho trovati a quintalate di esempi ma, anche sin troppo approfonditi; manco uno che si accontenti di spiegare come monitorare un singolo messaggio; trovi esempi chilometrici
giuro che se capisco il funzionamento spendo un pò di tempo per spiegarli in modo facile, banale, step by step e comprensibili da chiunque: sempre che prima ci riesca;)
Anzichè FindWindow() forse si deve usare:
1 - GetModuleHandle();
2 - GetProcAddress();
3 - SetWindowsHookEx();
Non credo...
SetWindowsHookEx va chiamato dall'interno di una DLL...altrimenti non funziona...
Nel DLLMain ti viene passato l'HINSTANCE della DLL...
Te lo metti in una variabile globale alla DLL... (che chiamo hMod)
Fai nella DLL una funzione che setta il threadID dell'istanza di IE...e mette l'hook...
Ad esempio :
void SetHook(DWORD threadID)
{
hook = SetWindowsHookEx(WH_GETMESSAGE,
GetMsgProc,
(HINSTANCE)hmod,
threadID);
};
hook è una variaible globale alla DLL di tipo HHOOK...
Per ottenere il threadID di IE devi usare ShellExecuteEx (con le giuste opzioni in fMask) per ottenere l'HANDLE al processo... Purtroppo poi non so da dove passare...
grazie cionci, sto quasi per perdere la pazienza con questi benedetti hook
addirittura uno mi ha detto che se installo un loop all'interno di una mia applicazione, posso uscirne semplicemente passando o ricevendo un messaggio attraverso gli hook
da quanto ho visto in giro per la rete, servono un pò per fare di tutto, ovviamente tutte le info sono in inglese
ma in italiano?
dove sono i programmatori italiani?
mah
dal win32.hlp si evince che:
A hook is a point in the Microsoft® Windows® message-handling mechanism where an application can install a subroutine to monitor the message traffic in the system and process certain types of messages before they reach the target window procedure.
e fino a qui si è ben capito ma, proseguendo nella lettura ti sparano un bell'esempio chilometrico; tanto per confonderti le idee e magari vedere di che pasta sei fatto
ma un banale esempio che intercetta un banalissmo click su di un pulsante?
figurati; troppo semplice
ma tengo duro:)
Provo a farlo io domani e te lo posto :)
Originariamente inviato da misterx
[B]in bocca al lupo;)
:mad: :mad: :mad: Mi ha funzionato una volta e poi ha smesso :mad: :mad: :mad:
dai che ci dai, mi sa che li ho capiti; ancora qualche esperimento poi ti dico: non vorrei aver preso un abbaglio
cmq, sto provando a monitorare i messaggi del mouse e funziona:)
uhm, riesco a spedire e ricevere messaggi dalla medesima applicazione ma, ricevere messaggi da un'applicazione esterna mi è ancora impossibile: santa pazienza, non riesco ad agganciarmi:
tu, cionci, con che metodo avevi provato?:)
Con una DLL esterna che installava un hook di sistema...per ora avevo provato a registrare la pressione dei tasti... Però come ho già detto...mi ha funzioanto una volta e poi non sono più riuscito a farlo andare... Mah...
azz. si sta rivelando un argomento alquanto ostico ma ci sono quasi; non ho capito la distinzione tra hook locali ed hook globali
nel mio caso, penso che di dover definire un hook globale ed è per questo motivo che devo creare und DLL con le mie procedure; poi richiamarla attraverso un mio programma: ma non ho scoperto i motivi di un tale metodo
mah....sto windows:)
Può darsi che è sia locale quando si attacca allo stesso thread in cui viene richiamata la SetWindowsHookEx (e quindi riceve solamente le comunicazioni per quel thread)...mentre è globale se non viene attaccata ad un thread in particolare e quindi riceve le comunicazioni per tutti i sistemi...
allora, ho creato la mia bella DLL con all'interno la procedura; problema: cotinua "luppare":D (che brutto termine) e non esce più
scusa se è in versione BCB ma so ch in ogni caso capisci
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "winbase.h"
//---------------------------------------------------------------------------
//extern "C" __declspec (dllexport) void __stdcall HelloWorld(void)
static HHOOK MioHook = NULL ;
char szBuf[128];
HINSTANCE HInst;
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void*)
{
HInst=hinst;
return 1;
}
//---------------------------------------------------------------------------
extern "C" __declspec (dllexport) LRESULT CALLBACK __stdcall MouseProc (int nCode,
WPARAM wParam, LPARAM lParam)
{
if (nCode < 0)
return CallNextHookEx(MioHook, nCode, wParam, lParam);
wsprintf(szBuf, "WH_MOUSE - nCode: %d, wP: %d, lP: %d", nCode, wParam, lParam);
MessageBox(0, szBuf, "ok, messagio ricevuto", MB_OK);
return CallNextHookEx(MioHook, nCode, wParam, lParam);
}
//---------------------------------------------------------------------------
extern "C" __declspec (dllexport) void __stdcall Inizia(HWND hWnd)
{
MioHook = SetWindowsHookEx(
(int)WH_MOUSE,
(HOOKPROC)MouseProc ,
(HINSTANCE)HInst,
0
);
}
//---------------------------------------------------------------------------
extern "C" __declspec (dllexport) void __stdcall Fine()
{
UnhookWindowsHookEx(MioHook);
}
//---------------------------------------------------------------------------
qui: MessageBox(0, szBuf, "bla bla bla", MB_OK);
la DLL non aspetta neanche a morire l'OK dell'utente, fa apparire centinaia di MessageBox:(
Originariamente inviato da misterx
[B]qui: MessageBox(0, szBuf, "vadavia al xxxx", MB_OK);
la DLL non aspetta neanche a morire l'OK dell'utente, fa apparire centinaia di MessageBox:(
Chiaro...è un call back...ongi volta che hai l'evento lui richiama la funzione...
Comunque è identica spiccicata alla mia...
cionci, edita il tuo post; la parola estranea "ehm ehm..." non era voluta nè diretta a te; sob: chiedo venia ma sono stupidate da programmatori:)
chi è senza peccato scagli la prima pietra;)
Pensa che non ci avevo nemmeno fatto caso :) :D
Originariamente inviato da cionci
[B]Pensa che non ci avevo nemmeno fatto caso :) :D
meglio così;)
per fare in modo che il chiamante della DLL non venga messo da parte; pulsanti del chiamante congelati è sufficiente inserire nella DLL un bel:
PostMessage(miohWnd, WH_MOUSE, 0, 0);
dove miohWnd=handle del chiamante
dai che ci dai ci sono arrivato; ecco un banale risultato che rileva i click del mouse di un'altra applicazione: ora, è quel 512 (decimale che mi frega), sarà possibile far apparire in luogo di esso quale pulsante è stato premuto?
penso che lP = 6945778 non abbia qui alcun significato
WH_MOUSE - nCode: 0, wP: 512, lP: 6942830
WH_MOUSE - nCode: 0, wP: 512, lP: 6942830
WH_MOUSE - nCode: 0, wP: 514, lP: 6942830
WH_MOUSE - nCode: 0, wP: 160, lP: 6945778
WH_MOUSE - nCode: 0, wP: 160, lP: 6945778
WH_MOUSE - nCode: 0, wP: 160, lP: 6945778
WH_MOUSE - nCode: 0, wP: 512, lP: 6945778
WH_MOUSE - nCode: 0, wP: 512, lP: 6945778
Parameters
nCode
[in] Specifies a code the hook procedure uses to determine how to process the message. This parameter can be one of the following values. Value Meaning
HC_ACTION The wParam and lParam parameters contain information about a mouse message.
HC_NOREMOVE The wParam and lParam parameters contain information about a mouse message, and the mouse message has not been removed from the message queue. (An application called the PeekMessage function, specifying the PM_NOREMOVE flag.)
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
[in] Specifies the identifier of the mouse message.
lParam
[in] Pointer to a MOUSEHOOKSTRUCT structure.
Mi attacchi il codice della DLL funzionante così ci do un'occhiata...
non c'è problema: basta che ignori le mie stranezze nel codice:D
come puoi vedere da te, spedisco il tutto su di un file; se trovi qualche errore, comunicamelo
:)
Originariamente inviato da misterx
[B]spedisco il tutto su di un file;
Come avevo fatto io :)
Domani lo guardo un po'...
pazzokramaz
06-11-2002, 22:52
Comunque Spy++ non fa altro che settare un hook per la cattura dei messaggi sul processo che scegli...
coosaaaaaa:eek:
cosa centra caputano uncino di peter pan?:eek:
hook lasciamolo sul galleone:D
Originariamente inviato da pazzokramaz
[B]coosaaaaaa:eek:
cosa centra caputano uncino di peter pan?:eek:
hook lasciamolo sul galleone:D
Mah...:rolleyes: :rolleyes: :rolleyes:
cmq, se nella DLL inserisci
PostMessage(tipo di messaggio,NULL,NULL)
e nel programma "chiamante"
MSG msg;
char miobuf[255];
GetMessage(&msg, hWnd, NULL,NULL );
wsprintf(miobuf,"%s",msg.message);
ottieni il medesimo effetto della
fprintf()........... inserita nella DLL
almeno, a me si comporta così:)
pazzokramaz
07-11-2002, 15:55
non ci capisco nulla:rolleyes: :D almeno uncino lo potresti schiappare tra qualche lettera;) attento però il poco.. xchè poi ti denunciano x i diritti su peter pan:D
pensavo che il prcedimento non funzionasse poi, sbirciando nel mio HD, d essendomi agganciato ad una normale finestra di esplora risorse, mi son ritrovato files da 60Mb: che dire; funziona
la stranezza è che il file viene creato: non nella cartella dell'applicazione ma nella cartella che in quel momento avevi agganciato
devo aver pasticciato un pò con i temini ma penso che tu abbia capito
mah.... la storia continua:)
A me non funziona ancora...nemmeno il tuo...
Tu come le chiami le funzioni delle DLL ? Con dllimport o con il .lib e il .h ?
uso la LoadLibrary in questo modo:
typedef VOID (*MYPROC)(HWND hWnd);
MYPROC InitHook;
HINSTANCE hinstDLL = LoadLibrary((LPCTSTR) "miaDLL.dll");
InitHook= (MYPROC)GetProcAddress(hinstDLL, "InitHook");
FARPROC EndHook= GetProcAddress(hinstDLL, "EndHook");
pazzokramaz
08-11-2002, 22:43
virus èehhhh:D
fai prima ad unire un bat e una jpg
okkio il bat sai come scriverlo.. gli levi di mezzo qualke dll e command.com ;)
Ma che virus :rolleyes: :p :D
Originariamente inviato da pazzokramaz
[B]virus èehhhh:D
fai prima ad unire un bat e una jpg
okkio il bat sai come scriverlo.. gli levi di mezzo qualke dll e command.com ;)
cosa c'entra il virus?????
ah, tu pensi che il codice sopra serva a scrivere un virus:D :D :D
sei completamente fuori strada;)
pazzokramaz
09-11-2002, 13:34
lo so stavo scherzando:cool:
cmq il c++ e compani... con quel tipo di scrittura non me gustano tanto....:rolleyes: quello che si vuole fare viene stilizzato troppo.. secondo me..... poi i gusti cambiano ..;)
cmq, quello che mi lascia perplesso è che devo passare alla SetWindowsHookEx l'istanza della DLL e non l'handle della finestra da me catturato
extern "C" __declspec (dllexport) void __stdcall Inizia(HWND hWnd)
{
MioHook = SetWindowsHookEx(
(int)WH_MOUSE,
(HOOKPROC)MouseProc ,
(HINSTANCE)HInst, 0 );
}
se provo così, si blocca tutto
extern "C" __declspec (dllexport) void __stdcall Inizia(HWND hWnd)
{
MioHook = SetWindowsHookEx(
(int)WH_MOUSE,
(HOOKPROC)MouseProc ,
(HINSTANCE)hWnd, 0 );
}
in quanto la SetWindowsHookEx si aspetta una HINSTANCE e non un handle: e forse ha ragione proprio lei
ho idea che passando l'istanza della DLL alla SetWindowsHookEx, questa agganci l'handle della finestra desiderata, ma il meccanismo mi è ancora oscuro; però, tutti gli esempi che ho trovato in giro sparpagliati per la rete utilizzanno questo metodo; mah.....mistero
qui (http://archive.devx.com/free/mgznarch/vcdj/1999/aug99/hooks1.asp) c'è un articolo in inglese che spiega gli hook:)
Magari bisogna passargli l'utlimo parametro...che è un threadID...
nel link che tio ho postato c'era questo esempio non male:
typedef struct
{
WPARAM wParam;
LPARAM lParam;
DWORD dwExtraData;
} CLIENTMSGDATA;
CLIENTMSGDATA MsgData;
COPYDATASTRUCT gcds = { 0, sizeof(CLIENTMSGDATA), &MsgData };
LRESULT CALLBACK GetMsgProc(int nCode, WPARAM wParam, LPARAM lParam )
{
MSG *pMsg = (MSG*)lParam;
HWND hWnd = pMsg->hwnd;
HWND hwndClient = FindWindow(CLIENTWINDOWCLASS, CLIENTWINDOWNAME);
if (nCode < 0 || hwndClient == NULL)
return CallNextHookEx(NULL, hc, wParam, lParam);
if (nCode == HC_ACTION)
{
MsgData.wParam = wParam;
MsgData.lParam = lParam;
gcds.dwData = uiMessage;
SendMessage(hwndClient, WM_COPYDATA, (WPARAM)hwnd, (LPARAM)&gcds);
return 1;
}
return 0;
}
poi, l'autore, ha cominciato ad andare per la sua strada, parlando d'altro, e non si è capito più nulla: è un gran peccato
cmq, sembrerebbe che vi siano innumerevoli metodi per ottenere il risultato da me sperato; il problema è che continuando a leggere diverse implementazioni, ti confondono le idee:(
prova questo:)
// Codice per la DLL:
SECTIONS
HOOK_SHARED CLASS 'HOOK_SHARED' SHARED
// The CPP file for the DLL:
#pragma option -zRHOOK_SHARED
#pragma option -zSHOOK_SHARED
#pragma option -zTHOOK_SHARED
#define STRICT
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
HHOOK HookHandle = 0;
HWND hwnd = 0;
//------------------------------------------------------------------------------------------------------------
extern "C" void __stdcall _export SetHookHandle ( HHOOK HookHandle_ )
{
HookHandle = HookHandle_;
}
//------------------------------------------------------------------------------------------------------------
extern "C" void __stdcall _export SetWindowHandle ( HWND hwnd_ )
{
hwnd = hwnd_;
}
//------------------------------------------------------------------------------------------------------------
extern "C" LRESULT CALLBACK _export KBProc ( int nCode, WPARAM wParam, LPARAM lParam )
{
if ( nCode == HC_ACTION && lParam & 0x80000000 && hwnd )
PostMessage ( hwnd, WM_APP, wParam, 0 );
return CallNextHookEx ( HookHandle, nCode, wParam, lParam );
}
//------------------------------------------------------------------------------------------------------------
BOOL WINAPI DllEntryPoint ( HINSTANCE, DWORD, LPVOID )
{
return TRUE;
}
//------------------------------------------------------------------------------------------------------------
// Codice per l'applicazione:
#define STRICT
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
LRESULT CALLBACK WndProc ( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
static const int BufferSize = 0x400;
static char buffer [ BufferSize ];
static int BufferIndex = 0;
if ( uMsg == WM_APP )
{
char c = static_cast < char > ( MapVirtualKey ( wParam, 2 ) );
if ( isprint ( c ) && BufferIndex < BufferSize )
buffer [ BufferIndex ++ ] = c;
return 0;
}
else if ( uMsg == WM_DESTROY )
{
HANDLE FileHandle = CreateFile ( "KbHist.txt", GENERIC_WRITE, 0, 0,
OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0 );
DWORD BytesWritten;
WriteFile ( FileHandle, buffer, BufferIndex, & BytesWritten, 0 );
CloseHandle ( FileHandle );
PostQuitMessage ( 0 );
return 0;
} return DefWindowProc ( hwnd, uMsg, wParam, lParam );
}
//------------------------------------------------------------------------------------------------------------
bool RegisterWindowClass ( HINSTANCE hInstance )
{
WNDCLASSEX WindowClass;
WindowClass . cbSize = sizeof ( WNDCLASSEX );
WindowClass . style = 0;
WindowClass . lpfnWndProc = WndProc;
WindowClass . cbClsExtra = 0;
WindowClass . cbWndExtra = 0;
WindowClass . hInstance = hInstance;
WindowClass . hIcon = LoadIcon ( 0, IDI_APPLICATION );
WindowClass . hIconSm = LoadIcon ( 0, IDI_APPLICATION );
WindowClass . hCursor = LoadCursor ( 0, IDC_ARROW );
WindowClass . hbrBackground = ( HBRUSH ) GetStockObject ( GRAY_BRUSH );
WindowClass . lpszMenuName = 0;
WindowClass . lpszClassName = "Hook Window Class";
return RegisterClassEx ( & WindowClass );
}
//------------------------------------------------------------------------------------------------------------
int WINAPI WinMain ( HINSTANCE instance, HINSTANCE, LPSTR, int )
{
RegisterWindowClass ( instance );
HWND hwndMain = CreateWindow ( "Hook Window Class",
"Hook Application",
WS_OVERLAPPED | WS_SYSMENU,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
( HWND ) 0, ( HMENU ) 0,
instance, ( LPVOID ) 0 );
ShowWindow ( hwndMain, SW_SHOW );
UpdateWindow ( hwndMain );
HINSTANCE DllInstance= LoadLibrary ( "hook.dll" );
HOOKPROC TheKBProc = ( HOOKPROC ) GetProcAddress ( DllInstance, "KBProc" );
HHOOK TheHook = SetWindowsHookEx ( WH_KEYBOARD, TheKBProc , DllInstance, 0 );
typedef void ( __stdcall * HHookSetter ) ( HHOOK );
HHookSetter SetHookHandle= ( HHookSetter ) GetProcAddress ( DllInstance, "SetHookHandle" );
SetHookHandle( TheHook );
typedef void ( __stdcall * HWNDSetter ) ( HWND );
HWNDSetter SetWindowHandle= ( HWNDSetter ) GetProcAddress ( DllInstance, "SetWindowHandle" );
SetWindowHandle( hwndMain );
MSG msg;
while ( GetMessage ( & msg, 0, 0, 0 ) )
{
TranslateMessage ( & msg );
DispatchMessage ( & msg );
}
UnhookWindowsHookEx ( TheHook );
FreeLibrary ( DllInstance );
return msg . wParam;
}
Non va...mi da un errore di accesso alla memoria... Comunque ora non ho tempo di fare il debug...
non c'è problema; non mi metto fretta neppure io:)
forse ho capito dov'è il problema; sempre che riesca a capire cosa significano queste dichiarazioni:
//-------------cpp----------------
#pragma option -zRSHARED_SEG
#pragma option -zSSHARED_GROUP
#pragma option -zTDATA
//--------------------------------
;-------------def----------------
SECTIONS
SHARED_SEG CLASS 'DATA' SHARED
;--------------------------------
a quanto pare devo creare delle variabili di tipo SHARED ma non ho capito come utilizzare quanto sopra e soprattutto dove inserirlo
ho capito solo che dicono al compilatore di fare qualcosa ma non cosa:(
continuo in questo post visto che a me sembra un argomento collegato
domanda:
come si fa in C++ a ritornare l'ID di un pulsante situato in un'altro programma?
so che dovrebbe esistere un'API a tal proposito ma non la trovo
grazie 1000
ehi, mi avete abbandonato?
cmq, la storia degli hook è andata a lieto fine:)
Mezzetti0903
26-11-2002, 21:05
Ehi misterx non pensi sia ora di postare il codice funzionante??
:D :D :D
giusto il tempo di dargli un paio di limatine; non vorrei per la fretta fare una brutta figuraccia;)
:D
Originariamente inviato da misterx
[B]continuo in questo post visto che a me sembra un argomento collegato
domanda:
come si fa in C++ a ritornare l'ID di un pulsante situato in un'altro programma?
so che dovrebbe esistere un'API a tal proposito ma non la trovo
grazie 1000
l'ho scoperto da me
grazie lo stesso:)
un attimo di pazienza, devo approfondire ancora alcuni aspetti
Cionci, hai presente in IE la nutrita serie di pulsanti posti in alto?
stampa/pagina iniziale/avanti/indietro etc....
sai se sono posti su una ToolBar?
Sì sono una toolbar all'interno di una ReBar (si vede con Spy++)...
lo supponevo; il problema è che non si riesce a ritornare l'handle di ogni singolo pulsante presente su essa
nemmeno spy++ ritorna l'handle del singolo pulsante
un problema:
HWND hPointWnd = FindWindow(0,"Calcolatrice");
SetCapture(
hPointWnd );
::SetCursorPos(0,0);
questo codice dovrebbe ricavare l'handle della calcolatrice di windows e posizionare il cursore del mouse alle coordinate (0,0) relative alla finestra della calcolatrice
ma al contrario, posiziona il cursore rispetto allo schermo di windows
sai se esiste un'altra funzione in modo che prenda come riferimento la windows della calcolatrice in luogo dello schermo?
per informare window di usare un riferimento diverso dallo screen non trovo nulla; sto usando questo
RECT r;
::GetWindowRect(hPointWnd, &r );
::SetCursorPos( r.left + x_desiderata , r.top + y_desiderata );
Direi che va bene così...
Riguardo ai child della ToolBar purtroppo non credo che si possano ottenere... e non so nemmeno se sono window...
però ho lavorato per nulla in quanto non serve al mio scopo
se provi a giocare con il seguente codice ti accorgerai che cliccando su di una toolbar, viene nascosta completamente; occhio che ha il potere di nascondere ogni cosa: in pratica ti ritrovi il desktop completamente vuoto
se noti, anche se clicchi su un pulsante della toolbar, viene preso come riferimeto non l'handle del pulsante ma di tutta la toolbar; difatti, muovendosi col cursore sui vari pulsanti l'handle non cambia mai
// qui ti ricavi l'handle dell'oggetto desiderato
HWND hPointWnd ;
while(quello che vuoi)
{
GetCursorPos (&pt);
hPointWnd = WindowFromPoint(pt);
}
// e qui lo nascondi
ShowWindow(hPointWnd,SW_HIDE);
il medesimo metodo ti permette di ritornare gli handle, di qualsiasi oggetto che si trova sotto al cursore del mouse, praticamente in stile spy++
in pratica, ho scoperto dopo un pò di esperimenti che la funzione:
WindowFromPoint(pt)
tratta tutti i controlli come fossero delle finestre e quindi ti ritorna l'handle corretto di qualsiasi cosa
lo puoi constatare usando la ShowWindow(hPointWnd,SW_HIDE);
spero di non averti annoiato troppo:)
leggi qua
In Windows tutta l'interfaccia utente e' composta da finestre. Sono finestre quelle contenenti i menu, le finestre di dialogo, i pulsanti, i menu a tendina ecc. Le finestre ricevono l'input dall'utente sottoforma di messaggi, e comunicano tra loro sempre nello stesso modo. Ad esempio quando l'utente ridimensiona una fiestra, Windows invia un messaggio al programma descrivente l'azione in corso, e permette al programma di reagire di conseguenza. L'invio di un messaggio corrisponde ad una chiamata di funzione, cioe' quando Windows deve inviare un certo messaggio ad un programma non fa altro che chiamare una certa funzione di quel programma. La funzione in oggetto e' detta window procedure, ed il messaggio e' stabilito dal suo argomento.
In Windows tutta l'interfaccia utente e' composta da finestre
ed io aggiungo, o trattate come tali
Originariamente inviato da misterx
[B]spero di non averti annoiato troppo:)
Figurati...anzi :)
Sì sono tutte Windows...ma le toolbar sono un componente monolitico...purtroppo...
Mi spieghi qual era lo scopo iniziale della tua investigazione ?
Originariamente inviato da cionci
[B]
Figurati...anzi :)
Sì sono tutte Windows...ma le toolbar sono un componente monolitico...purtroppo...
Mi spieghi qual era lo scopo iniziale della tua investigazione ?
devo scrivere della documentazione relativa ad un programma non scrito da me; nella documentazione, ho la necessità di rendere agevole all'utente l'uso del programma stesso
il programma per il quale genero la documentazione è costituito da numerosissime videate; in alcune di queste videate sono presenti molti campi che l'utente deve compilare per ottenere determinati risultati
il mio programma quindi, funzionerà da client; il programma che riceverà i miei messaggi da server
la comunicazione tra client->server avviene attraverso link presenti nella mia documentazione; detti link, invieranno attraverso il client dei messaggi al server che a sua volta mi mostrerà la videata interessata
insomma, è come se devi spiegare il funzionamento di IE con una pagina HTML e nella spiegazione, quando ti serve mostrare una particolare videata, anzichè mettere una banale bitmap metti un link che ti fa apparire la finestra: Strumenti->Opzioni
cmq, sono riuscito a catturare l'ID di un pulsante presente su di una toolbar facendo uso di SendMessage:)
ho notato anche una cosa ma non so se è un caso; se catturi l'indirizzo di una finestra e ne prendi nota; poi catturi l'indirizzo di un pulsante sempre prendendone nota
chiudi il programma per il quale hai catturato gli indirizzi
lo rilanci ed ovviamente l'indirizzo base cambia
poi, ricatturi i due indirizzi come sopra, se fai la differenza la distanza non cambia
è un caso?
prima prova
---------------
window = &H344 (dec = 836)
pulsante = &H3B0 (dec = 944)
seconda prova
------------------
window = &H558 (dec = 1368)
pulsante = &H5C4 (dec = 1476)
1368-836 = 532 ytes
1476-944 = 532 bytes
in entrambi i casi la distanza è uguale
E' abbastanza normale... Credo dipenda dall'ordine in cui vengono creati gli handle... Se non ci sono "interferenze" l'ordine è lo stesso...
mi è venuto il dubbio pensando alla deframmentazione della memoria
se il tutto si ripete, basta tracciare il primo handle (indirizzo) ed i gioco è fatto
ehi, non avrai mica iniziato a pensare che stessi diventando un hackers:)
anche se ho imparato numerose cosette su windows che non intendo certo postare in questo luogo, per ovvi motivi;)
E' interessante quella cosa che vuoi fare...
Riguardo agli ID...
Magari gli hHandle vengono dichiarati in base all'handle della finestra princpale più l'ID che li rappresenta (come sai ogni window ha il suo ID)... Può benissimo essere....anche se questo implica che il processo di creazione di una finestra (almeno fino al punto in cui vengono riservati gli handle) sia un processo atomico (che non interrompibile dallo scheduler)...
Può anche essere... E' una implementazione molto veloce soprattutto per il dispatching dei messaggi...
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.