Jump to content
RTollison

Get rectangle of the button that was pushed on another form...

Recommended Posts

i have this routine to get the active window, that may have multiple buttons at various places on the parent window.

when they user click on a button then i am calling a dll that currently tries to center itself on the parentwindow BUT i am needing to know if it is possible to get the rectangle coordinates of the button that actually got pushed.

here is my current lines for gathering the window rectangle.

    ParentWindowHandle := GetActiveWindow;
    GetClientRect(ParentWindowHandle, Rect);
 

is there a way to determine the button that was pushed and it location relative to screen so i can popup my control where the button is located and not in the center?

Share this post


Link to post

Make a note of the coordinates in the code that handles the button click event, and pass that on to other other code. 

 

I'm assuming that you are in control of all of the code. 

Share this post


Link to post

unfortunately no not in control of the source window. 

it used popup in the middle of the screen and i changed it to get the active window and put it in center of it, which is kind of odd since the button sometimes is near the bottom of the window. 

 

Share this post


Link to post
1 hour ago, RTollison said:

i have this routine to get the active window, that may have multiple buttons at various places on the parent window.

when they user click on a button then i am calling a dll that currently tries to center itself on the parentwindow

Is your routine being called inside of the button click handler? Or, is the routine inside of the DLL that the button handler calls into?

1 hour ago, RTollison said:

is there a way to determine the button that was pushed and it location relative to screen so i can popup my control where the button is located and not in the center?

Are you handling the button click event directly? If so, then it tells you the button that was clicked.  Otherwise, if the button in question took input focus when it was clicked (most buttons do) then trying using GetFocus() instead of GetActiveWindow().

Share this post


Link to post

anything about the button is not available to me. the button click (not delphi) basically says call dll that will popup on the screen and allow user to select a date from a calendar.

so my dll is only thing i have available to change. the original dev just created the popup calendar to be in center of the main screen which was ok since multi-screens weren't widely available.

but then i got tasked with updating it and at the time the best i could do was the center of the active window. now i was asked IF i could change it and i said i would see what i could do. And so far it is not looking good.

Share this post


Link to post

You could take current mouse coordinates but this will fail if button is clicked by key. Not a problem if the button is unfocusable

Share this post


Link to post
10 hours ago, RTollison said:

anything about the button is not available to me. the button click (not delphi) basically says call dll that will popup on the screen and allow user to select a date from a calendar.

so my dll is only thing i have available to change. the original dev just created the popup calendar to be in center of the main screen which was ok since multi-screens weren't widely available.

but then i got tasked with updating it and at the time the best i could do was the center of the active window. now i was asked IF i could change it and i said i would see what i could do. And so far it is not looking good.

The setup is pretty opaque for us here. These are the sort of details that matter. Without them it's just guesswork. 

Share this post


Link to post

i apologize for the lack of details. no excuses. i have been down this road to many times. was just wishing for a quick command like the getactivewindow but for a window control. even did a search for getactivewindow hoping some article would mention any info related to getting the control.

Thats when i posted here doing the wish stuff for another command from people that would know.

FYI my current dev language is COBOL and i have to tie into it for anything outside of it, such as this calendar dll. the original one was hokie and dated, so i created a new one that followed the parameters and decided that centering on the form was better than the main screen. that is when i was asked if we could popup at the button that was pushed. now we are here and i am going with not possible with 100% results.

Share this post


Link to post
1 hour ago, RTollison said:

was just wishing for a quick command like the getactivewindow but for a window control.

Did you try GetFocus(), like I suggested?

Share this post


Link to post

the GetFocus actually worked great but after i started testing the cobol programs and where it would pop up, it won't work out to well. some of our report type programs have these push-buttons at the bottom of the screen but the focus is at the top field on the screen. so as a user i could not want to change anything other than a date or multiple dates and just push the button at the bottom of the screen but the popup calendar is at the top. i checked if there was a way to force the focus to the button when pushed and there is not an option for down only that the button was clicked after the fact event. So i will do more thinking on this but in the mean time leave it as center of activewindow.

Share this post


Link to post

Since you are not in control of the UI that hosts the buttons you are interested in, then you don't have direct access to know which button is being clicked on.  Period.

 

However, there may be a way to determine this indirectly.  If the buttons in question are standard Win32 BUTTON controls, then you might try using SetWindowsHookEx() to catch their BN_CLICKED notifications, which carry each clicked button's HWND.  Or, you might try using SetWinEventHook() to catch EVENT_OBJECT_INVOKED events, which also carry each clicked button's HWND.

Share this post


Link to post

You might try googling "Microsoft UI Automation", MS's accessibility interface. If the other program is somewhat recent, you may be able to access it's user interface. I have used it to access controls in an external program that controlled a camera . It's not a quick and dirty solution as it involves COM, but it's really powerful. I think there might be a third party Delphi interface available for it. I haven't used it since XE6.

 

Dan

 

Share this post


Link to post
7 hours ago, Fr0sT.Brutal said:

Why not try GetMousePos?

The mouse could have moved between the time it took the button click to be queued and processed and the time the dialog is displayed.  If the DLL is being called in the context of the click handler, then GetMessagePos() would make more sense.  But again, the button could have been invoked by the keyboard (or even programmably) instead of by the mouse.  This is why I think it is better to hook and intercept the original click event itself so you can detect which button HWND is triggering the event in the first place.

Share this post


Link to post
Posted (edited)
On 7/15/2021 at 6:30 PM, Remy Lebeau said:

This is why I think it is better to hook and intercept the original click event itself so you can detect which button HWND is triggering the event in the first place

Of course you're right but I guess the assumption "mouse is still over a button being clicked" is pretty enough for the purposes of positioning a popup window. Implementation complexity/feature importance ratio seems very good.

Edited by Fr0sT.Brutal

Share this post


Link to post
7 hours ago, Fr0sT.Brutal said:

Of course you're right but I guess the assumption "mouse is still over a button being clicked" is pretty enough for the purposes of positioning a popup window.

Only if the mouse is being used to click the button in the first place, and not the keyboard.  And even then, this is assuming the user does not have a system setting enabled that moves the mouse to a popup window's default button whenever a new popup opens.

Share this post


Link to post
Quote

the GetFocus actually worked great but after i started testing the cobol programs ... the focus is at the top field on the screen. so .... just push the button at the bottom of the screen but the popup calendar is at the top. 

So on Cobol window only the edit fields can be focused? That is using the tab key to move to each control in window allowing editing in edit field or a key press with enter key.  

 

What event is called when pop up calendar Date is set?  How is the initial Date set in pop up when opened. 

 

You could let the user save the popup position in a inifile. This inifile could load a button for each cobol field update event. It could save the last date(s) entered to set calendar date if needed.  

Share this post


Link to post
Posted (edited)
16 hours ago, Remy Lebeau said:

Only if the mouse is being used to click the button in the first place, and not the keyboard.  And even then, this is assuming the user does not have a system setting enabled that moves the mouse to a popup window's default button whenever a new popup opens.

Well... Regarding mouse reposition: taking coordinates before showing the popup of course.

Regarding everything else: IDK what COBOL apps look like and IMHO it's senseless to keep theorizing without topic starter and additional input. Anyway the issue seems to me not worthy such strong efforts.

Edited by Fr0sT.Brutal

Share this post


Link to post

Yeah the screen center seems ok for our clients and they can see the calendar popup pretty easy. when calling the dll we pass in a date that it will move the calendar to that date and when the user selects a date and clicks an OK button it sends the value back to the cobol program. pretty simple stuff. as for a mouse click not always used some users just use keyboard and are very adapt at using it. the buttons do not have a tab stop. the date field is the tab stop. like i said center of screen is fine, mgmt just asked if possible to put by button without a lot of effort and verification that it works in all situations.

So thank you all very much.

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×