I can send keystrokes to the application, but I can only access some of the
program features - those that have a menu item.
I need to press a button on a toolbar, which presents me with two problems
a) how to locate the button, and b) how to simulate a mouse click on it.
I can locate the handle of the window that contains toolbar, and I know the
x-y position of the button in question within this window, but it is a
customisable toolbar, so the position, indeed presence, of the button is
unpredictable. How can I locate the location of a specific button within
this window? The window class of the toolbar is "tdpnpanel"
What messages do I need to send to simulate a mouseclick? I assumed a
WM_LBUTTONOWN followed by a WM_LBUTTONUP would be sufficient, but below is
the entire sequence of messages that occur when I click the button. Are all
these really necessary? Is there a simpler way to simulate a mouse click?
<00095> 000508B8 S WM_NCHITTEST xPos:190 yPos:96
<00096> 000508B8 R WM_NCHITTEST nHittest:HTCLIENT
<00097> 000508B8 S WM_MOUSEACTIVATE hwndTopLevel:00060830 nHittest:HTCLIENT
uMsg:WM_LBUTTONDOWN
<00098> 000508B8 R WM_MOUSEACTIVATE fuActivate:MA_ACTIVATE
<00099> 000508B8 S WM_SETCURSOR hwnd:000508B8 nHittest:HTCLIENT
wMouseMsg:WM_LBUTTONDOWN
<00100> 000508B8 R WM_SETCURSOR fHaltProcessing:False
<00101> 000508B8 P WM_LBUTTONDOWN fwKeys:MK_LBUTTON xPos:190 yPos:12
<00102> 000508B8 P WM_MOUSEMOVE fwKeys:MK_LBUTTON xPos:190 yPos:12
<00103> 000508B8 S WM_NCHITTEST xPos:190 yPos:96
<00104> 000508B8 R WM_NCHITTEST nHittest:HTCLIENT
<00105> 000508B8 P WM_LBUTTONUP fwKeys:0000 xPos:190 yPos:12
<00106> 000508B8 S WM_CAPTURECHANGED hwndNewCapture:00000000
<00107> 000508B8 R WM_CAPTURECHANGED
<00108> 000508B8 P WM_PAINT hdc:00000000
<00109> 000508B8 S WM_PAINT hdc:00000000
<00110> 000508B8 R WM_PAINT
<00111> 000508B8 S WM_PAINT hdc:00000000
<00112> 000508B8 R WM_PAINT
> I'm trying to control a Delphi app by remote control ...
Your own? If so, you can add something better to it than you're doing now.
Groetjes,
Maarten Wiltink
"Maarten Wiltink" <maa...@kittensandcats.net> wrote in message
news:4ba72b5d$0$22935$e4fe...@news.xs4all.nl...
Insert DLL into app.
Replacing a commonly called routine with a stub.
Then when the routine gets executed by the application, push your own
instruction pointer onto the stack.
(As a return address)
Then simply return from the routine...
The retun address will end up in the instruction pointer for the
application.
The trick is to set the return address to the routine that must be executed
inside the application.
This might be sufficient... depends on what the routine actually does and if
it interacts with the events and it's data..
if not then it might work.
So what you would need to do is:
1. Inject DLL.
2. Reverse engineer/disable the application, figure out where the routine
is.
3. Try to figure out where it is in virtual memory... should always be on
the same offset.
4. Place a stub on same routine
5. Put the offset on the stack.
6. Return from routine naturally.
Bye,
Skybuck.
"Marc Hillman" <7ows...@sneakemail.com> wrote in message
news:4ba71c19$1...@dnews.tpgi.com.au...
Some of the operations require you to be in the same process space..
for that, You need the process handle, create some virtual space, open
the process so that you can actually get items from it's space and not
yours, move the info into virtual space, close the process from your
space and now you have it..
If you already have the Toolbar handle, then look at the TB_xxxx
messages. Also, the TBBUTTON maybe of some interest to you. For that
contains the CommandID of the button you need. From there, you can
simply send the CommandID via the TB_PRESSBUTTON with the CommandID in
it. You do not need to know where the button is. YOu may want to be
careful with that because in some cases, you will not have a button
visible because its not in the proper time sequence. In other words, not
all menus/buttons are visible and for good reason..
Have fun with the fault generators!
I cannot see TB_BUTTON messages in any of the several application windows.
They are all WM_ type. Also I have no idea how to extract the command ID
from the application.
It's a Delphi app, and I have no source code. I understood most of what you
said, but when you said open the process space you started to lose me. Is
there a tool that will allow me to extract the command id's?
I have the toolbar handle, but from the fragment of the windows messages
below
"Jamie" <jamie_ka1lpa_not_v...@charter.net> wrote in message
news:cGSpn.77272$jt1....@newsfe01.iad...
> Thanks Jamie - I was unaware of the TB_BUTTON message, but I'm not out
> of the woods yet.
>
> I cannot see TB_BUTTON messages in any of the several application
> windows. They are all WM_ type. Also I have no idea how to extract the
> command ID from the application.
>
> It's a Delphi app, and I have no source code. I understood most of what
> you said, but when you said open the process space you started to lose
> me. Is there a tool that will allow me to extract the command id's?
>
> I have the toolbar handle, but from the fragment of the windows messages
> below
First of all, TB_BUTTON does not exist, it's not a message, it's a
Struct/Record object that contains information about a button.
This Record needs to be filled via one of the other TB_xxxxx messages
that gets sent directly to the Toolbar via a
"SendMessage(TollBarBHandle,TB_GETBUTTON,IndexOfBUtton, LpTBBUTTON)";
If you use the TB_BUTTONCOUNT, which is a message you send directly to
the contol, it'll report the number of buttons in the control..
By enumerating through the buttons to locate the desire button via
the text of it, for example, you can then find the IDcommand of that button.
All of this is find and dandy, how ever, you need to jump into the
process space of that app and transfer these returned items that have
pointer information, into a virtual piece of memory. This memory you can
access from your own app
First you need to get the processID>.
GetWindowThreadProcessId(H,@PID); //H is the handle of the window
that contains the control
//Open the process so that memory moves ends on your turf.
Ph := OpenProcess(PROCESS_VM_OPERATION or PROCESS_VM_READ or
PROCESS_VM_WRITE,false, PID); //PID is a cardinal/unsigned 32.
//Create a Virtual Page that the remote process can write too.
GM:=
VirtualAllocEx(PH,Pointer(0),$0400,MEM_COMMIT,PAGE_READWRITE);//$0400 is
the size of the page. should be on event boundaries. but It may not
matter these days.
// Now use the "SendMessage" messages to obtain the information you
need..
Example
SizeOfSTring :=
SendMessage(TheToolBarHandle,TB_GETBUTTONTEXT,IndexOfBUtton,
Integer(GM); // pass the virtual pointer as the destination memory chunk.
//To get this information into your app for use..
ReadProcessMemory(PH, GM, Pointer(Char String Var), SizeOFstring,Var
forNumberOFBytesRead);
//Now the "Char String VAR" will contain the text of the button.
// Use this method for obtaining the info you need via the TB_xxxx
messages to get the BUtton COUnt, and ButtinIDS (TBBUTTON) that you can
then directly send the ButtonID to press the button.
When done with this search and seek code which you only need to obtain
the CommandID's on inital start up, you do this.
VirtualFreeEx(PH, GM,0,MEM_RELEASE);
That will release the Virtual memory made for the remote process (PH)
referred too via the GM handle....
// next , close the process
CloseHandle(PH);
I know that's slopping but it's the best I could do with my current
notes I have here hacked from apps I've wrote and things off the top of
my head and 3 beers in me!
Have a good day!
"Jamie" <jamie_ka1lpa_not_v...@charter.net> wrote in message
news:e7dqn.37849$NH1....@newsfe14.iad...
Have you tried using the EnumChildWIndows with in that Menu panel?
You may find hidden buttons or at least get the class to come other
controls.
Another quick question - Is there a default font in Delphi? What is the most
likely proportional font for a developer to use in Delphi?
"Jamie" <jamie_ka1lpa_not_v...@charter.net> wrote in message
news:0DSqn.40177$NH1....@newsfe14.iad...
And if they were to change it, I can't read the minds of others.
I tend to use some kind of RASTER font for things that need to be
formatted in a list and such!
The GUI preferences aren't any different than in VB, I would think?