[C++/Win32] Opvragen van object-name uit ander proces

Pagina: 1
Acties:
  • 191 views sinds 30-01-2008
  • Reageer

  • riezebosch
  • Registratie: Oktober 2001
  • Laatst online: 16-05 11:22
Ik ben bezig met een soort van macro-tooltje (maar dan gericht op testen), en moet daarvoor eigenlijk iets hebben waar ik objecten van een ander programma aan kan identificeren en wat niet wijzigt wanneer dat programma opnieuw gecompileerd word. De windowhandle is dus uitgesloten. Ik zit zelf te denken aan de "name" van het object, maar weet niet of dit standaard Win32 is. Bij Visual Basic en .NET geef je de controls een naam, waar je ze in je code uniek aan kan herkennen.

Dingen die ik al bekeken heb:

• GetClassName: maakt een object niet uniek;
• GetWindowName: deze gebruikt de WM_GETTEXT, en werkt dus niet voor tekstvakken e.d.
• Heb een manier gevonden om code in andermans proces te injecteren, waardoor je messages kan versturen alsof het in je eigen programma is. Maar weet dus niet of je met een SendMessage een attribuut kan opvragen wat het object uniek maakt.

Canon EOS 400D + 18-55mm F3.5-5.6 + 50mm F1.8 II + 24-105 F4L + 430EX Speedlite + Crumpler Pretty Boy Back Pack


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 12-05 22:23

curry684

left part of the evil twins

Als ik je vraag goed begrijp ga je niet veel verder komen dan GetClassName, maar ik snap het punt niet helemaal. Is het externe programma een third party produkt of van jezelf? Wil je communiceren met dat produkt vervolgens? Wil je alleen detecteren dat iets 'draait'?

Professionele website nodig?


  • riezebosch
  • Registratie: Oktober 2001
  • Laatst online: 16-05 11:22
Nee, ik wil de acties van de gebruiker ondervangen en loggen, zodat ik op een later tijdstip automatisch die actie kan herhalen (record & playback). Maar daarbij moet ik dus wel het object (tesktvak/knop) waar de gebruiker wat mee doet kunnen herkennen en later terugvinden zodat ik ook die actie er op uit kan voeren.

Het probleem is: veel macro-tooltjes gebruiken de handle van het control om deze op te zoeken, maar deze veranderd wanneer een programma opnieuw gecompileerd wordt.

Canon EOS 400D + 18-55mm F3.5-5.6 + 50mm F1.8 II + 24-105 F4L + 430EX Speedlite + Crumpler Pretty Boy Back Pack


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 12-05 22:23

curry684

left part of the evil twins

Je kunt gewoon alle muiskliks (en vooral hun locatie) en key-events loggen en die in volgorde afspelen, dan boeit het geen bal in welk control je zit zolang ze de layout van het scherm maar niet veranderen ;)

Professionele website nodig?


  • riezebosch
  • Registratie: Oktober 2001
  • Laatst online: 16-05 11:22
Dat is dus een optie voor record & playback, maar wel de minst gewenste (omdat je script dan resolutie afhankelijk is e.d.); De literatuur onderkendt de volgende mogelijkheden, in volgorde gerantschikt:
• Objectnaam
• Label/Prompt/Tekst
• Objecttype en de volgorde daarbinnen
• Windows ID
• Coördinaten

Canon EOS 400D + 18-55mm F3.5-5.6 + 50mm F1.8 II + 24-105 F4L + 430EX Speedlite + Crumpler Pretty Boy Back Pack


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 15:32

.oisyn

Moderator Devschuur®

Demotivational Speaker

De id's van controls zijn altijd wel hetzelfde, maar dat heeft eigenlijk alleen toepassing op reguliere dialogs

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.


  • riezebosch
  • Registratie: Oktober 2001
  • Laatst online: 16-05 11:22
Ja, en het programma waar die van mij mee moet werken is in VB gemaakt. In VB hebben alle controls wel een name (evenals in .NET), maar ik weet dus niet of dit Win32-standaard is en dus ook via standaard functies/messages te achterhalen.

Als die dingen altijd een vaste plek hebben in het geheugen, kan ik misschien dit gaan doorzoeken? Is waarschijnlijk alleen vrij inefficient, aangezien bij het opzoeken van de controls ik dan weer het hele geheugen moet gaan doorzoeken. Maar in feite doen voorgedefinieerde functies dat misschien ook wel...

Canon EOS 400D + 18-55mm F3.5-5.6 + 50mm F1.8 II + 24-105 F4L + 430EX Speedlite + Crumpler Pretty Boy Back Pack


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 12-05 22:23

curry684

left part of the evil twins

Names zijn in VCL, VB en .NET interne properties en dus niet vastgelegd (Windows zou er intern toch niets mee doen, dus is het logischerwijs niet vastgelegd ;) )

Maar zolang de clientapplicatie niet onder jouw controle is of zelfs iedere gewenste client kan zijn ontkom je niet echt aan coordinaten ben ik bang....

Professionele website nodig?


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 15:32

.oisyn

Moderator Devschuur®

Demotivational Speaker

riezebosch schreef op 21 oktober 2004 @ 15:16:
Ja, en het programma waar die van mij mee moet werken is in VB gemaakt.
Ik geloof niet dat je me helemaal goed begrijpt, ik heb het over de id van een control, dus niet de hwnd, en ook niet een interne naam die VB oid aan z'n controls geeft. Deze id's worden gebuikt om in de window/dialog proc controls van elkaar te kunnen onderscheiden, en hebben derhalve een waarde die (over het algemeen, tenzij iemand vage dingen doet ;)) niet wijzigt. En deze waarden zijn wel gedefinieerd binnen native win32.

Met GetDlgCtrlID () kun je de id van een control opvragen gegeven de parent window en de hwnd van de control. GetDlgItem () doet dat precies andersom: die geeft de hwnd van een control gegeven de parent window en het control id.

[ Voor 11% gewijzigd door .oisyn op 21-10-2004 16:23 ]

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.


  • riezebosch
  • Registratie: Oktober 2001
  • Laatst online: 16-05 11:22
In ieder geval enorm bedankt voor jullie reacties; Ik zal hieronder nog ff quoten wat er in dat boek staat (valt hopelijk niet onder copyricht?):

[1] Objectnaam
Dit is de interne technische objectnaam die de applicatieprogrammeur aan het object heeft gegeven. Bijvoorbeeld PersID voor het personid-veld.

[2] Label/Prompt/Tekst
Dit is de zichtbare tekst die voor of op het object staat in het betreffende applicatiescherm. Bijvoorbeeld "Name: " voor het name-veld.

[3] Objecttype en volorgde daarbinnen
Dit is het volordenummer dat het betreffende object heeft binnen de objecten van hetzelfde type ini het betreffende applicatiescherm. Bijvoorbeeld "het zesde object van het type EditBox" voor het number-veld.

[4] Windows ID
Binnen een scherm heeft elk object een unieke Windows ID. Deze Windows ID wordt bepaald tijdens het opbouwen (presenteren) van het scherm. De Windows ID is te gebruiken om het object te adresseren in het betreffende applicatie-scherm. Bijvoorbeeld 21 voor de Add-button.

[5] Coördinaten
De exacte positie van een object op een applicatiescherm is vastgelegd in x,y-coördinaten afgemeten in pixels. De meeste testtools kunnen registreren op welke x,y-coördinaat een object zich bevindt binnen een applicatiescherm. Hierbij wordt meestal de linkerbovenhoek van het applicatiescherm als coördinaat 0,0 beschouwd. Bijvoorbeeld 402,90 voor de Close-button.

Hierbij is [1] het meest gewenst omdat een object het duidelijkst te adresseren is en de onderhoudsgevoeligheid het laagst. In geval bij [5] een object 1 pixel verplaatst worden kloppen de coördinaten niet meer. Dit is natuurlijk minder van belang als je niet de objecten probeert te vinden, maar gewoon op exact dezelfde plek (relatief aan het scherm) de actie simuleert.

Het schijnt dat macro-tools [5] wel vaak gebruiken voor het werken met VB-applicaties, omdat VB 1 class gebruikt voor alle controls die een ruimte specificeert, en dan een andere class aanroept om die ruimte te tekenen. Deze is dus niet direct aan het handle gerelateerd en is dus (misschien) alleen via een omweg door in het geheugen te zoeken te benaderen voor z'n (unieke) properties.

Canon EOS 400D + 18-55mm F3.5-5.6 + 50mm F1.8 II + 24-105 F4L + 430EX Speedlite + Crumpler Pretty Boy Back Pack


  • riezebosch
  • Registratie: Oktober 2001
  • Laatst online: 16-05 11:22
.oisyn schreef op 21 oktober 2004 @ 16:22:
[...]


Ik geloof niet dat je me helemaal goed begrijpt, ik heb het over de id van een control, dus niet de hwnd, en ook niet een interne naam die VB oid aan z'n controls geeft. Deze id's worden gebuikt om in de window/dialog proc controls van elkaar te kunnen onderscheiden, en hebben derhalve een waarde die (over het algemeen, tenzij iemand vage dingen doet ;)) niet wijzigt. En deze waarden zijn wel gedefinieerd binnen native win32.

Met GetDlgCtrlID () kun je de id van een control opvragen gegeven de parent window en de hwnd van de control. GetDlgItem () doet dat precies andersom: die geeft de hwnd van een control gegeven de parent window en het control id.
Ik zal het uitzoeken :) Maar is dit niet het ID wat wijzigt tijdens opnieuw compileren? Of werkt VB hier wel mee, ook al gaat het via een omweg zoals ik in vorige post duidelijk heb gemaakt?

Canon EOS 400D + 18-55mm F3.5-5.6 + 50mm F1.8 II + 24-105 F4L + 430EX Speedlite + Crumpler Pretty Boy Back Pack


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 15:32

.oisyn

Moderator Devschuur®

Demotivational Speaker

Oh, moet het tussen compiles ook nog hetzelfde blijven? Mja, dan ben je natuurlijk nergens meer, als een control wordt weggehaald dan klopt je testtool toch al niet meer.

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.


  • riezebosch
  • Registratie: Oktober 2001
  • Laatst online: 16-05 11:22
Dat is ook het probleem niet, daar bouw ik wel wat voor dat het makkelijk te onderhouden is. Maar het is niet de bedoeling dat ook voor alle ongewijzigde controls dingen aangepast moeten worden. Wat bij de handle (=ID?) wel het geval is.
Wat jij bedoelt is denk ik de IDC_ABOUT bijvoorbeeld? Die lijkt me wel altijd vrij gelijkt blijven. Maar hebben knoppen en tekstvakken ook zo'n ID? Of geldt dat alleen voor dialogs? En hoe gaat VB daarmee om, genereert ie er ook een voor al z'n controls?

Canon EOS 400D + 18-55mm F3.5-5.6 + 50mm F1.8 II + 24-105 F4L + 430EX Speedlite + Crumpler Pretty Boy Back Pack


  • riezebosch
  • Registratie: Oktober 2001
  • Laatst online: 16-05 11:22
.oisyn schreef op 21 oktober 2004 @ 16:22:
[...]
Met GetDlgCtrlID () kun je de id van een control opvragen gegeven de parent window en de hwnd van de control. GetDlgItem () doet dat precies andersom: die geeft de hwnd van een control gegeven de parent window en het control id.
Hele goeie tip; alleen hebben meerdere controls in het programma waar die van mij mee goet gaan werken hetzelfde ID :? Schiet dus nog niet echt op zo. Zal dan toch wel coördinaten worden :(

edit:

Bijna alle controls hebben ID 1, en sommige 3 of 4... Heb het getest op een ander programmaatje, en dan werkte het inderdaad wel goed. Ook tof dat je functies voor heen én terug aandroeg!

[ Voor 17% gewijzigd door riezebosch op 22-10-2004 10:05 ]

Canon EOS 400D + 18-55mm F3.5-5.6 + 50mm F1.8 II + 24-105 F4L + 430EX Speedlite + Crumpler Pretty Boy Back Pack


  • riezebosch
  • Registratie: Oktober 2001
  • Laatst online: 16-05 11:22
Ok, ik schop 'm zelf maar even omhoog. Mocht iemand ooit tegen hetzelfde probleem aanlopen, blijkbaar heb ik wat functies gevonden die onbekend zijn. Ik zal even per punt van objectherkenning laten zien wat de mogelijkheden zijn.

[1] Met het Microsoft Accessibility Architecture (MSAA) is het mogelijk met de functies IAccessibility::get_accName en IAccessibility::get_accValue de eigenschappen van een (standaard) Windows-control op te vragen.
Helaas kan ik dit niet gebruiken, omdat de objecten uit het programma waar ik mee moet werken (VB) geen waarde hebben.

[2] Standaard kan je dit natuurlijk doen met GetWindowText, maar voor VB-programma's kan je met behulp van deze code toch de tekst van labels uitlezen.
Helaas kan ik hier geen gebruik van maken. Ten tijde van Win95 liep het programma uit z'n Window-handles, en hebben ze dit opgelost door alle labels eraf te gooien en de tekst zelf op het form te tekenen.

[3] Spreekt voor zich, heb het verder nog niet uitgezocht.
Hmmm, misschien toch wel interessant om even uit te zoeken.

[4] Zoals door .oisyn al aangehaald kan je hiermee werken met de functies GetDlgCtrlID en de tegenhanger GetDlgItem.
Maar, zoals ook hierboven al vermeld, kan ik hiermee niet werken omdat de controls geen uniek ID hebben.

[5] Hiermee kan je werken met de functie WindowFromPoint. Gelukkig kan je wel met relatieve afstand ten opzichte van het actieve scherm werken, anders zou deze functie gelijk al waardeloos zijn bij het verschuiven van het venster.
Waarschijnlijk zal ik dus hiermee moeten werken. Het probleem is dat ik dan haast geen checks kan inbouwen voor de voortgang van mijn script, en zal dus ook gewoon de tijd van de initiële uitvoering op moeten nemen.

Canon EOS 400D + 18-55mm F3.5-5.6 + 50mm F1.8 II + 24-105 F4L + 430EX Speedlite + Crumpler Pretty Boy Back Pack

Pagina: 1