[Win32] Message sturen naar andere app *

Pagina: 1
Acties:

  • MidnightMotion
  • Registratie: April 2002
  • Laatst online: 03-04-2022
Ik probeer via SendMessage() een message te versturen die door een ander programma weer opgevangen moet worden. Dit werkt zolang van het andere programma het window actief is (= op de voorgrond staat). Ik wil echter dat het programma de message altijd opvangt....

Weet iemand hoe dit moet?Ik krijg het niet voor elkaar!

Eigenaar van domoticavergelijken.info


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

Als het programma de msg niet krijgt als ie not active is weigert ie 'm zelf, want Focus heeft geen invloed op messaging.

Verder hoor je PostMessage te gebruiken naar andere programma's, SendMessage is heel ranzig buiten je eigen zandbak.

edit:
Delphi en C++ uit je topictitel geschrapt, beide zijn irrelevant :P verder denk ik bij 'Global Messaging' aan broadcasts, dat ook even verduidelijkt :)

[ Voor 27% gewijzigd door curry684 op 13-09-2003 16:23 ]

Professionele website nodig?


  • MidnightMotion
  • Registratie: April 2002
  • Laatst online: 03-04-2022
curry684 schreef op 13 September 2003 @ 16:22:
Als het programma de msg niet krijgt als ie not active is weigert ie 'm zelf, want Focus heeft geen invloed op messaging.

Verder hoor je PostMessage te gebruiken naar andere programma's, SendMessage is heel ranzig buiten je eigen zandbak.

edit:
Delphi en C++ uit je topictitel geschrapt, beide zijn irrelevant :P verder denk ik bij 'Global Messaging' aan broadcasts, dat ook even verduidelijkt :)
PostMessage heb ik ook geprobeerd, het maakt op zich niet uit hoe ranzig het is als het maar werkt maar het kan dus niet volgens jou? Het is toch mogelijkop de 1 of andere manier messages tussen niet actieve programma's te versturen?

[ Voor 4% gewijzigd door MidnightMotion op 13-09-2003 16:32 ]

Eigenaar van domoticavergelijken.info


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

Ja hoor perfect mogelijk. Maar als het wel werkt als die andere app actief is en niet als hij niet actief is weigert hij expliciet de message te parsen die je stuurt.

Welke msg verstuur je uberhaupt?

Professionele website nodig?


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 04:06

.oisyn

Moderator Devschuur®

Demotivational Speaker

curry684 schreef op 13 September 2003 @ 16:22:
Verder hoor je PostMessage te gebruiken naar andere programma's, SendMessage is heel ranzig buiten je eigen zandbak.
ik vraag me dus af in hoeverre dat waar is. In de MSDN staat niets over dat je SendMessage () beter niet kunt gebruiken voor andere apps. Sterker nog, er staat zelfs dat windows marshalling doet voor system messages (0 tot WM_USER), en dat gaat alleen op als er een message wordt gestuurd naar een andere applicatie.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

Met SendMessage neem je prioriteit boven alles wat er op dat moment in de queue van de ontvangende applicatie staat, en je kunt daarmee dus bijv. een WM_CLOSE forcen terwijl de recipient queue nog volstaat met WM_SIZE et al voor dat window. Grote kans dat je het programma daarmee opblaast...

Want ja, Windows slikt het probleemloos, maar door gewoon netjes de queue te respecteren doe je de stabiliteit van de programma's veel goed.

Professionele website nodig?


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 04:06

.oisyn

Moderator Devschuur®

Demotivational Speaker

Ja ok, je bypassed de queue, maar dat is nou eenmaal precies wat SendMessage () doet, of het nou naar een andere app is of voor jezelf. Maar een SendMessage () naar een andere app is niet per definitie vies, dat hangt een beetje van de message af die je verstuurd :)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

SendMessage moet je gewoon per definitie alleen gebruiken als het antwoord van de message je boeit :)

Professionele website nodig?


  • MidnightMotion
  • Registratie: April 2002
  • Laatst online: 03-04-2022
Ik zal het 1 en ander wat verduidelijken:

Ik heb een DLL met een procedure om een KeyHook aan te maken, deze procedure roep ik aan vanuit een ander programma.

Ik wil in plaats van in de DLL de toetsenbord aanslagen af te handelen dit in een andere app doen (code in de betreffende procedure binnen de DLL moet altijd zo min mogelijk zijn vanwege performance)

[ Voor 5% gewijzigd door MidnightMotion op 13-09-2003 16:53 ]

Eigenaar van domoticavergelijken.info


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

Dat werkt perfect hoor via messages...

* curry684 heeft een compleet remote desktop systeem op die manier geschreven :)

Professionele website nodig?


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 04:06

.oisyn

Moderator Devschuur®

Demotivational Speaker

curry684 schreef op 13 September 2003 @ 16:49:
SendMessage moet je gewoon per definitie alleen gebruiken als het antwoord van de message je boeit :)
Tenzij er pointers in de message parameters komen te staan, want die worden dus alleen gemarshalled bij SendMessage (ik praat hier natuurlijk over een message naar een andere app). Als je bijvoorbeeld de window caption wilt wijzigen, dan is een SendMessage je enige keuze.

Maar goed, het wordt hoog tijd dat de topicstarter eens gaat vertellen wat voor message hij nou wilt versturen :Y)
ah :)

[ Voor 23% gewijzigd door .oisyn op 13-09-2003 16:56 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 04:06

.oisyn

Moderator Devschuur®

Demotivational Speaker

MidnightMotion schreef op 13 September 2003 @ 16:52:
Ik wil in plaats van in de DLL de toetsenbord aanslagen af te handelen dit in een andere app doen (code in de betreffende procedure binnen de DLL moet altijd zo min mogelijk zijn vanwege performance)
Begrijp ik het dan goed dat je dan een message verstuurd naar een andere app mvb SendMessage in de procedure in de DLL? Dan heeft het weinig zin, want SendMessage wacht tot de andere app de message geprocessed heeft, dus of je het dan zelf doet of de andere app laat doen, de wachttijd is net zo lang

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • MidnightMotion
  • Registratie: April 2002
  • Laatst online: 03-04-2022
.oisyn schreef op 13 September 2003 @ 16:59:
[...]


Begrijp ik het dan goed dat je dan een message verstuurd naar een andere app mvb SendMessage in de procedure in de DLL? Dan heeft het weinig zin, want SendMessage wacht tot de andere app de message geprocessed heeft, dus of je het dan zelf doet of de andere app laat doen, de wachttijd is net zo lang
Gebruik PostMessage al, die wacht niet op antwoord.

Eigenaar van domoticavergelijken.info


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

Maar leg het nu eens goed uit: jij schrijft dus zelf de recipient-applicatie? Jij schrijft daar zelf de WindowProc? Jij hebt daar zelf al een breakpoint in de WindowProc gezet zodat je kunt zien of je messages aankomen?

Professionele website nodig?


  • MidnightMotion
  • Registratie: April 2002
  • Laatst online: 03-04-2022
curry684 schreef op 13 september 2003 @ 17:04:
Maar leg het nu eens goed uit: jij schrijft dus zelf de recipient-applicatie? Jij schrijft daar zelf de WindowProc? Jij hebt daar zelf al een breakpoint in de WindowProc gezet zodat je kunt zien of je messages aankomen?
Ja en die komen niet aan, ik kom er trouwens net achter dat de keyhook niet eens werkt als de applicatie niet actief is???? (MessageBox() gezet in de hook procedure) Dit werkte eerst nog wel! :'(

Eigenaar van domoticavergelijken.info


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

Hoe wil je keyloggen in een applicatie zonder focus? :?

Professionele website nodig?


  • MidnightMotion
  • Registratie: April 2002
  • Laatst online: 03-04-2022
curry684 schreef op 13 September 2003 @ 17:20:
Hoe wil je keyloggen in een applicatie zonder focus? :?
Ik wil alle toetsaanslagen binnen Windows afvangen.

Eigenaar van domoticavergelijken.info


Verwijderd

curry684 schreef op 13 September 2003 @ 17:20:
Hoe wil je keyloggen in een applicatie zonder focus? :?
Ik heb eens zoiets gemaakt met
Private Declare Sub keybd_event Lib "user32" (ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Long, ByVal dwExtraInfo As Long)

geloof ik.

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 04:06

.oisyn

Moderator Devschuur®

Demotivational Speaker

MidnightMotion schreef op 13 September 2003 @ 17:23:

Ik wil alle toetsaanslagen binnen Windows afvangen.
Wat jij wilt is een GLOBAL hook, niet een hook op 1 specifieke window/thread
Verwijderd schreef op 13 September 2003 @ 17:25:
[...]


Ik heb eens zoiets gemaakt met
Private Declare Sub keybd_event Lib "user32" (ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Long, ByVal dwExtraInfo As Long)

geloof ik.
MSDN:
The keybd_event function synthesizes a keystroke.
zeg dan niets

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • MidnightMotion
  • Registratie: April 2002
  • Laatst online: 03-04-2022
Goed, de global hook werkt weer. (parameter een keer veranderd om wat te testen en vergeten terug te zetten...) Nu alleen die message nog.

Eigenaar van domoticavergelijken.info


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

Ik weet uit ervaring dat het concept perfect werkt, dus je verneukt ergens iets in je code. Verder kunnen we je zo echt niet helpen hoor.

Professionele website nodig?


  • MidnightMotion
  • Registratie: April 2002
  • Laatst online: 03-04-2022
Code in de executable:

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
27
28
  function WindowProc(Hwnd: HWnd; Msg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
  begin
    if (Msg = WM_USER + 1) and (lParam > 0) then
    begin                         
      MessageBox(0, 'Received message from DLL', '!!', MB_OK);
    end;
    Result := DefWindowProc(Hwnd, Msg, WParam, LParam);
  end;

var
  lMsg: TMsg;
  WinClass: TWndClass;
begin
  WinClass.hInstance := Hinstance;
  WinClass.lpszClassName := AppName;
  WinClass.lpfnWndProc := @WindowProc;
  RegisterClass(WinClass);

  WindowHandle := CreateWindow(AppName, 'DummyHandle', SW_HIDE, 0,0,0,0,0,0, HInstance, nil);
  ShowWindow(WindowHandle, SW_SHOW);
  StartHook(WindowHandle);

  while GetMessage(lMsg, 0, 0, 0) do
  begin
    TranslateMessage(lMsg);
    DispatchMessage(lMsg);
  end;
end.


De DLL:

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
27
28
29
30
31
32
33
34
35
36
37
var
  MainHandle: Hwnd;
  HookHandle: HHOOK;

function KbdHookProc(Code: Integer; WParam: WPARAM; LParam: LPARAM): LRESULT; stdcall;
begin
  { Send windows message to registered application }
  if Code = HC_ACTION then
    PostMessage(MainHandle, WM_USER + 1, WParam, LParam);

  { Pass the message }
  Result := CallNextHookEx(HookHandle, Code, WParam, LParam);
end;

function StartHook(const aMainHandle: Cardinal): Cardinal;
begin
  { MainHandle is used to identify and communicate with the calling program }
  MainHandle := aMainHandle;

  { Create the hook }
  HookHandle := SetWindowsHookEx(WH_KEYBOARD, KbdHookProc, HInstance, 0);
  Result := HookHandle;
end;

procedure StopHook;
begin
  { Unhook the hook and so free the used memory } 
  if HookHandle <> 0 then
    UnhookWindowsHookEx(HookHandle);
end;

exports
  StartHook,
  StopHook;

begin
end.


Dit werkt dus perfect zolang de gecreërde window actief is, zodra deze op de achtergrond staat krijg ik geen messages meer door.


Let ajb niet op fouten in de code die er niet toe doen, ik ben er nog mee bezig en wil het eerst in hoofdlijnen werkend hebben voordat ik het netjes ga maken.

WM_USER + 1 is ook tijdelijk, ik weet dat je hiervoor een message moet registreren als je ze tussen apps stuurt, zie stukje hierboven...

.modbreak: even je code door de highlighter gegooid :) (tip: gebruik [code=c++]...[/code] voor highlighting)
woeps, het was delphi code :D

[ Voor 7% gewijzigd door .oisyn op 13-09-2003 18:11 ]

Eigenaar van domoticavergelijken.info


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 04:06

.oisyn

Moderator Devschuur®

Demotivational Speaker

Van waaruit worden StartHook en StopHook aangeroepen?
Iets zegt me namelijk dat je die alleen aanroept voor 1 bepaald proces... Terwijl, als dat proces geen focus meer heeft, hij natuurlijk ook geen keyboard messages meer krijgt; een ander proces krijgt die messages dan.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • MidnightMotion
  • Registratie: April 2002
  • Laatst online: 03-04-2022
Ik roep starthook aan vanuit de executable zodat in de DLL de hook aangemaakt wordt. De DLL blijft de keyboard strokes ontvangen (Getest mbv de welbekende MessageBox) maar de message die verstuurt wordt komt niet aan in de host applicatie (executable)

Eigenaar van domoticavergelijken.info


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 04:06

.oisyn

Moderator Devschuur®

Demotivational Speaker

En welke heeft dan niet de focus? De app waar die keystrokes binnenkomen, of jouw app waar de keystrokes naar toe worden gestuurd?

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • MidnightMotion
  • Registratie: April 2002
  • Laatst online: 03-04-2022
Mijn applicatie die de message moet ontvangen heeft geen focus en ontvangt geen messages meer

Eigenaar van domoticavergelijken.info


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

Je zet de Hook met als 3e parameter HInstance en die klopt niet. HInstance is op dat moment namelijk hoe dan ook de HInstance van de mainapplicatie omdat je de DLL meegelinked hebt. Omdat die DLL in je eigen processspace zit kunnen andere apps er niet heen vanuit hun processspace, en werkt alles dus alleen vanuit je eigen app.

De correcte methode voor een global hook is om met LoadLibrary de DLL te laden (en ja, daar krijg je dus een HMODULE uit ipv een HINSTANCE), en dan met die handle als parameter de SetHooks functie binnen de DLL uit te voeren (via GetProcAddress dus). In de SetHooks functie kun je vervolgens die HMODULE gebruiken als 3e parameter voor de SetWindowsHookEx functie.

[ Voor 90% gewijzigd door curry684 op 13-09-2003 18:57 ]

Professionele website nodig?


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 04:06

.oisyn

Moderator Devschuur®

Demotivational Speaker

MidnightMotion schreef op 13 September 2003 @ 18:19:
Ik roep starthook aan vanuit de executable zodat in de DLL de hook aangemaakt wordt.
kun je eens laten zien / uitleggen hoe precies?

[ Voor 3% gewijzigd door .oisyn op 13-09-2003 18:51 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • MidnightMotion
  • Registratie: April 2002
  • Laatst online: 03-04-2022
curry684 schreef op 13 September 2003 @ 18:51:
Link je de DLL mee met je main applicatie toevallig?
Nope, DLL staat gewoon los
.oisyn schreef op 13 September 2003 @ 18:51:
[...]


kun je eens laten zien / uitleggen hoe precies?
De DLL exporteert de functie:
code:
1
2
3
4
5
6
7
8
9
function StartHook(const aMainHandle: Cardinal): Cardinal;
begin
  { MainHandle is used to identify and communicate with the calling program }
  MainHandle := aMainHandle;

  { Create the hook }
  HookHandle := SetWindowsHookEx(WH_KEYBOARD, KbdHookProc, HInstance, 0);
  Result := HookHandle;
end;


Vanuit het andere programma roep ik gewoon StartHook(Handle) aan en zodoende start de hook netjes, echter: wanneer ik in de KbdHookProc procedure een message verstuur
code:
1
  PostMessage(MainHandle, WM_USER + 1, WParam, LParam);

komt deze niet aan in het andere programma als laatstgenoemde de focus niet heeft:
code:
1
2
3
4
5
6
  function WindowProc(Hwnd: HWnd; Msg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
  begin
    if (Msg = WM_USER + 1) and (lParam > 0) then
      MessageBox(0, 'Dit werkt dus alleen als het form de focus heeft :(', '!!', MB_OK);
    Result := DefWindowProc(Hwnd, Msg, WParam, LParam);
  end;

Eigenaar van domoticavergelijken.info


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

Professionele website nodig?


  • MidnightMotion
  • Registratie: April 2002
  • Laatst online: 03-04-2022
Ik heb de DLL nu dynamisch ingeladen en het handle hiervan meegegeven aan de SetWindowsHookEx functie in plaats van HInstance maar nog steeds hetzelfde resultaat....

Eigenaar van domoticavergelijken.info


  • madwizard
  • Registratie: Juli 2002
  • Laatst online: 26-10-2024

madwizard

Missionary to the word of ska

Als ik het me goed herinner hebben global hooks in elk proces een eigen data section, omdat ze als DLL overal ingehangen worden. Als je dus een globale variable wijzigt in het ene proces, verandert de waarde binnen een ander proces niet. Een oplossing is je gesharede data in een shared PE section zetten (kan met de linker) maar weet niet hoe dat in delphi gaat.
Waarschijnlijk klopt daarom de waarde van je window handle wel als je met je eigen proces bezig bent maar zodra je switcht naar een ander proces wordt een andere instantie van de DLL gebruikt waarbij deze waarde nog op default (0) staat.

www.madwizard.org


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 04:06

.oisyn

Moderator Devschuur®

Demotivational Speaker

MidnightMotion schreef op 13 September 2003 @ 19:24:
[...]


Ik heb de DLL nu dynamisch ingeladen en het handle hiervan meegegeven aan de SetWindowsHookEx functie in plaats van HInstance maar nog steeds hetzelfde resultaat....
natuurlijk, zoals madwizard boven me zegt, heeft elk proces zijn eigen addressspace. En je MainHandle, waar je de messages naar post, is niet geset in al die processen. Je moet er dan op een een of andere manier voor zorgen dat je de handle naar elke DLL stuurt. En dat kan met shared memory (zie CreateFileMapping)
madwizard schreef op 13 September 2003 @ 19:43:
Als ik het me goed herinner hebben global hooks in elk proces een eigen data section, omdat ze als DLL overal ingehangen worden. Als je dus een globale variable wijzigt in het ene proces, verandert de waarde binnen een ander proces niet. Een oplossing is je gesharede data in een shared PE section zetten (kan met de linker) maar weet niet hoe dat in delphi gaat.
Met een shared section in een dll kan idd ook, maar dat kan weer zoveel gedoe zijn. Bovendien moet je er rekening mee houden dat shared sections niet dezelfde offset krijgen in de verschillende processen, waardoor pointers naar het stukje shared geheugen niet werken (maar dat geldt natuurlijk ook voor dynamic shared memory)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 04:06

.oisyn

Moderator Devschuur®

Demotivational Speaker

MidnightMotion: ik zou het zo doen

Een header die je in beide include
C++:
1
2
3
4
5
struct SharedData
{
    HWND hMainWnd;
    HHOOK hHook;
};


Je DLL:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
HWND hMainWnd = 0;
HHOOK hHook = 0;

LRESULT __stdcall KeyboardProc (int code, int wParam, int lParam)
{
    if (!hMainWnd)
    {
        HANDLE h = OpenFileMapping (FILE_MAP_READ, FALSE, "KeyboardHookMemory");
        if (!h)
        {
            // iets ging fout
        }

        SharedData * data = (SharedData *)MapViewOfFile (h, FILE_MAP_READ, 0, 0, sizeof (SharedData));
        hMainWnd = data->hMainWnd;
        hHook = data->hHook;
        UnmapViewOfFile (data);
        CloseHandle (h);
    }

    PostMessage (hMainWnd, WM_USER + 1, wParam, lParam);

    return CallNextHookEx (hHook, Code, WParam, LParam);
}



Je app:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
HHOOK SetKeyboardHook (HWND pMainWnd)
{
    HANDLE h = CreateFileMapping (INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof (HWND), "KeyboardHookMemory");
    SharedData * data = (SharedData *)MapViewOfFile (h, FILE_MAP_WRITE, 0, 0, sizeof (SharedData));

    HMODULE hModule = LoadLibrary ("keyboardhook.dll");
    void * procAddr = GetProcAddress (hModule, "KeyboardProc");

    HHOOK hHook = SetWindowsHookEx (WH_KEYBOARD, (HOOKPROC)procAddr, hModule, 0);

    data->hMainWnd = pMainWnd;
    data->hHook = hHook;

    return hHook;
}


en dan is het simpelweg als je app opgestart is even SetKeyboardHook () aanroepen, en de rest gaat vanzelf.

(disclaimer: bovenstaande code is 100% niet getest :+)

[ Voor 16% gewijzigd door .oisyn op 14-09-2003 15:29 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

Ieder process dat de hook gebruikt connect aan de DLL en krijgt dus een PROCESS_ATTACH actie in je DllMain. Het is dus stukken handiger om je filemapping daar te openen.

Professionele website nodig?


  • MisterData
  • Registratie: September 2001
  • Laatst online: 20:35
Even een vraagje tussendoor: hoe kan ik bijvoorbeeld een string van het ene naar het andere programma sturen zonder last te hebben van access violations e.d?

  • Tomatoman
  • Registratie: November 2000
  • Laatst online: 00:12

Tomatoman

Fulltime prutser

MisterData schreef op 13 September 2003 @ 21:12:
Even een vraagje tussendoor: hoe kan ik bijvoorbeeld een string van het ene naar het andere programma sturen zonder last te hebben van access violations e.d?
Dit vraagje is behoorlijk offtopic, maar het antwoord in Delphi is de unit ShareMem. Zie Delphi Help voor uitleg.

Een goede grap mag vrienden kosten.


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 04:06

.oisyn

Moderator Devschuur®

Demotivational Speaker

MisterData schreef op 13 September 2003 @ 21:12:
Even een vraagje tussendoor: hoe kan ik bijvoorbeeld een string van het ene naar het andere programma sturen zonder last te hebben van access violations e.d?
shared mem, named pipes, sockets, ...
manieren genoeg :)

voor een constante stroom data binnen hetzelfde systeem is een named pipe de beste oplossing

tomatoman: als ik MisterData's posthistory mag geloven is hij amper met Delphi bezig ;)

[ Voor 11% gewijzigd door .oisyn op 13-09-2003 21:26 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • MisterData
  • Registratie: September 2001
  • Laatst online: 20:35
.oisyn schreef op 13 September 2003 @ 21:25:
[...]


shared mem, named pipes, sockets, ...
manieren genoeg :)

voor een constante stroom data binnen hetzelfde systeem is een named pipe de beste oplossing
Dan ga ik daar maar eens naar op zoek :)
tomatoman: als ik MisterData's posthistory mag geloven is hij amper met Delphi bezig ;)
Helemaal niet zelfs ;)

Verwijderd

[quote]MidnightMotion schreef op 13 September 2003 @ 18:01:
Code in de executable:

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
27
28
  function WindowProc(Hwnd: HWnd; Msg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
  begin
    if (Msg = WM_USER + 1) and (lParam > 0) then
    begin                         
      MessageBox(0, 'Received message from DLL', '!!', MB_OK);
    end;
    Result := DefWindowProc(Hwnd, Msg, WParam, LParam);
  end;

var
  lMsg: TMsg;
  WinClass: TWndClass;
begin
  WinClass.hInstance := Hinstance;
  WinClass.lpszClassName := AppName;
  WinClass.lpfnWndProc := @WindowProc;
  RegisterClass(WinClass);

  WindowHandle := CreateWindow(AppName, 'DummyHandle', SW_HIDE, 0,0,0,0,0,0, HInstance, nil);
  ShowWindow(WindowHandle, SW_SHOW);
  StartHook(WindowHandle);

  while GetMessage(lMsg, 0, 0, 0) do
  begin
    TranslateMessage(lMsg);
    DispatchMessage(lMsg);
  end;
end.

Waar wordt StopHook aangeroepen? :?
Verder raad ik je toch aan om toch (nog) iets gestruceerder te werk te gaan. Ook al is dit maar een test app. Bijvoorbeeld return waarden checken, try.. finally, GetLastError, etc. Dit vergemakkelijkt ook het debuggen, kan je wellicht toekomstige vragen voorkomen.
Dit werkt dus perfect zolang de gecreërde window actief is, zodra deze op de achtergrond staat krijg ik geen messages meer door.
Weet je dat zeker? Check Winsight (onderdeel van Delphi.)
Let ajb niet op fouten in de code die er niet toe doen, ik ben er nog mee bezig en wil het eerst in hoofdlijnen werkend hebben voordat ik het netjes ga maken.
zie boven.
WM_USER + 1 is ook tijdelijk, ik weet dat je hiervoor een message moet registreren als je ze tussen apps stuurt, zie stukje hierboven...
Let er ook op, dat je global hook niet werkt voor al geopende grafische applicaties nadat de global hook actief wordt.

Je .dll (met de global hook) wordt geladen zodra user32.dll voor het proces geladen wordt. Dit gebeurt normaal gesproken bij het opstarten van de applicatie.

[ Voor 4% gewijzigd door Verwijderd op 13-09-2003 23:47 ]


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 04:06

.oisyn

Moderator Devschuur®

Demotivational Speaker

Verwijderd schreef op 13 September 2003 @ 23:43:
Weet je dat zeker? Check Winsight (onderdeel van Delphi.)
Ik zal even voor de TS reageren ;)
Ja. De waarde van MainHandle is alleen juist in het proces dat de hook zet, omdat daar de DLL is geladen. In alle andere processen wordt de hook wel aangeroepen, maar MainHandle is daar 0, dus de message komt nergens aan. Vandaar dat ie de keys alleen krijgt als zijn eigen app de focus heeft
Let er ook op, dat je global hook niet werkt voor al geopende grafische applicaties nadat de global hook actief wordt.
definieer "grafische applicatie"
en bovendien wordt de hook _altijd_ geladen als ie nodig is, ongeacht wat voor app draait.
Je .dll (met de global hook) wordt geladen zodra user32.dll voor het proces geladen wordt. Dit gebeurt normaal gesproken bij het opstarten van de applicatie.
Nee, de hook wordt pas geladen op het moment dat de hook nodig is. Voor deze hook is dat dus als er een WM_KEYDOWN of een WM_KEYUP in de messagequeue wordt geplaatst (om preciezer te zijn, pas als ie uit de queue wordt gehaald door bijvoorbeeld GetMessage ()). Voor apps die nooit een key ontvangen wordt de dll ook niet in hun addressspace gemapt.

Misschien bedoelde je met grafische applicaties DirectX apps, en nee dat is niet omdat ze grafisch zijn, maar omdat ze DirectInput gebruiken om het toetsenbord te lezen. DirectInput werkt direct op de toetsenbord driver, en als die actief is worden er dus ook geen toetsen in de messagequeue geplaatst. En dus wordt de hook ook niet geladen.

[ Voor 4% gewijzigd door .oisyn op 14-09-2003 00:05 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Verwijderd

.oisyn schreef op 14 september 2003 @ 00:03:
[...]


Ik zal even voor de TS reageren ;)
Ja. De waarde van MainHandle is alleen juist in het proces dat de hook zet, omdat daar de DLL is geladen. In alle andere processen wordt de hook wel aangeroepen, maar MainHandle is daar 0, dus de message komt nergens aan. Vandaar dat ie de keys alleen krijgt als zijn eigen app de focus heeft
De rest van de reacties had ik niet gezien, vandaar een achterhaalde posting.
definieer "grafische applicatie"
ik doelde op een applicatie, die één of meer user32.dll functies gebruikt.
en bovendien wordt de hook _altijd_ geladen als ie nodig is, ongeacht wat voor app draait.
niet als het een console applicatie is.
Nee, de hook wordt pas geladen op het moment dat de hook nodig is. Voor deze hook is dat dus als er een WM_KEYDOWN of een WM_KEYUP in de messagequeue wordt geplaatst (om preciezer te zijn, pas als ie uit de queue wordt gehaald door bijvoorbeeld GetMessage ()). Voor apps die nooit een key ontvangen wordt de dll ook niet in hun addressspace gemapt.
"... op het moment dat de hook nodig is. ..."

Als dus een user API wordt aangeroepen (en een Window beschikbaar is?)

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 04:06

.oisyn

Moderator Devschuur®

Demotivational Speaker

Verwijderd schreef op 14 September 2003 @ 00:51:
[...]

De rest van de reacties had ik niet gezien, vandaar een achterhaalde posting.
lees de draad voor je blaat ;)
ik doelde op een applicatie, die één of meer user32.dll functies gebruikt.
oh wacht, ik zie dat ik je reply verkeerd las. Maar nee, het werkt dus voor alle apps die draaien
niet als het een console applicatie is.
In een console app wordt meestal geen messagepump gedaan nee, dus GetMessage () wordt niet aangeroepen, en wordt de hook dus ook niet aangeroepen. Overigens is dat niet per definitie zo, ik heb zat console apps gemaakt met een message pump
"... op het moment dat de hook nodig is. ..."

Als dus een user API wordt aangeroepen (en een Window beschikbaar is?)
Nee, vlak voordat een message waar een hook op zit geprocessed gaat worden. En dat is dus meestal bij een aanroep van GetMessage () waarbij de volgende message die gereturned gaat worden een dergelijke message is.

(geldt overigens niet voor alle soorten hooks, maar wel voor de meeste. Ook voor de keyboard hook die hier gezet wordt)

.edit:
uit de MSDN:
The KeyboardProc hook procedure is an application-defined or library-defined callback function used with the SetWindowsHookEx function. The system calls this function whenever an application calls the GetMessage or PeekMessage function and there is a keyboard message (WM_KEYUP or WM_KEYDOWN) to be processed.

[ Voor 13% gewijzigd door .oisyn op 14-09-2003 01:42 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • MidnightMotion
  • Registratie: April 2002
  • Laatst online: 03-04-2022
Oke, het is me nu volkomen duidelijk waarom het niet werkte... Ik was in de veronderstelling dat er slechts 1 process van de DLL zou zijn maar dit is er dus één voor elk programma waar de DLL tussen komt.

Ik heb het intussen opgelost met een simpele FindWindow(), deze geeft de handle van mijn programma terug aan de hand van de naam en caption.

Postmessage naar deze Handle en voila!

Bedankt allemaal voor de reakties, ik heb er veel aan gehad! :)

Eigenaar van domoticavergelijken.info


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 04:06

.oisyn

Moderator Devschuur®

Demotivational Speaker

Ja zo kan het ook, maar hoe kom je dan aan de hook handle die je door moet geven aan CallNextHookEx ()?

(dat was ik overigens vergeten in mijn voorbeeld, die waarde moet dan ook in het stukje shared memory)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • MidnightMotion
  • Registratie: April 2002
  • Laatst online: 03-04-2022
.oisyn schreef op 14 September 2003 @ 15:04:
Ja zo kan het ook, maar hoe kom je dan aan de hook handle die je door moet geven aan CallNextHookEx ()?

(dat was ik overigens vergeten in mijn voorbeeld, die waarde moet dan ook in het stukje shared memory)
Die krijg ik terug van SetWindowsHookEx (Deze word tenslotte gewoon in de DLL aangemaakt en daar sla ik m op in een variabele)

Eigenaar van domoticavergelijken.info


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 04:06

.oisyn

Moderator Devschuur®

Demotivational Speaker

Uhm nee, dan heb je er nog niets van begrepen. SetWindowsHookEx doe je maar 1x, vanuit je app. De rest van de dll's die geladen worden in de andere processen hebben die waarde dus ook niet, net als de window handle.

Kijk nog eens naar mijn code: [rml].oisyn in "[ Win32] Message sturen naar andere app *"[/rml]
ik zal 'm even aanpassen, want ik was vergeten die hook handle ook door te geven

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • MidnightMotion
  • Registratie: April 2002
  • Laatst online: 03-04-2022
.oisyn schreef op 14 september 2003 @ 15:25:
Uhm nee, dan heb je er nog niets van begrepen. SetWindowsHookEx doe je maar 1x, vanuit je app. De rest van de dll's die geladen worden in de andere processen hebben die waarde dus ook niet, net als de window handle.

Kijk nog eens naar mijn code: [rml].oisyn in "[ Win32] Message sturen naar andere app *"[/rml]
ik zal 'm even aanpassen, want ik was vergeten die hook handle ook door te geven
Hmm, ja daar heb je helemaal gelijk in.... Moet ik ook nog aanpassen dus.

Eigenaar van domoticavergelijken.info

Pagina: 1