Will a kind soul help to provide a vba solution to press a button (e.g 3) in Microsoft calculator without using sendkeys?

API_newnoob

New Member
Joined
Jun 6, 2020
Messages
21
Office Version
  1. 2016
Platform
  1. Windows
Hi all,



Will a kind soul help to provide a vba solution to press a button (e.g 3) in Microsoft calculator without using sendkeys?
 
Upvote 0

Excel Facts

Copy formula down without changing references
If you have =SUM(F2:F49) in F50; type Alt+' in F51 to copy =SUM(F2:F49) to F51, leaving the formula in edit mode. Change SUM to COUNT.
Dear @Jaafar Tribak ,

Thank you for your patience and time, I am currently using Windows 7 Home premium, therefore my view is the classic view. I am also currently using spy++.

I realize that before i can get to the buttons, there are 2 windows class name that are duplicates ((#32770 (Dialog)) and they do not have a control ID.

I believe i have to get to the second #32770 (Dialog) which is the correct window to the buttons.

Is my assumption correct and if my assumption is correct, can you show or guide me to a solution to let the program understand that I would like to select the second #32770 (Dialog) ?
 

Attachments

  • 1591515327162.png
    1591515327162.png
    33.1 KB · Views: 22
Upvote 0
Perhaps you could explain what you're trying to do with the Calculator that can't be done in VBA without it?
 
Upvote 0
Dear Paul,

VBA definitely can do what the calculator does, however, i am trying to learn to automate using API.

The external program i chose to use is calculator since all of us who utilizes Microsoft would have a calculator.

I do understand that i can use Sendkeys to fulfill the purpose of automation, however the aim is to learn to automate using API.

In my humble opinion that could be wrong, what i am trying to figure out would be crucial if i were to utilize VBA to control other programs because other programs might have the same issues just like calculator.

Therefore, instead of finding solutions to go around the problem, i hope to tackle the problem head on and learn, so that i can utilize the knowledge to automate external programs in future.

Below is the initial tutorial that i used.

 
Upvote 0
Dear @Jaafar Tribak ,

Thank you for your patience and time, I am currently using Windows 7 Home premium, therefore my view is the classic view. I am also currently using spy++.

I realize that before i can get to the buttons, there are 2 windows class name that are duplicates ((#32770 (Dialog)) and they do not have a control ID.

I believe i have to get to the second #32770 (Dialog) which is the correct window to the buttons.

Is my assumption correct and if my assumption is correct, can you show or guide me to a solution to let the program understand that I would like to select the second #32770 (Dialog) ?

Right click each Button module showing in your spy tool and choose Properties from the right-cick menu. Under the General tab you will find the specific control ID for the button in HEX format.

If you can post back with each control and its corresponding ID, we can take this further.

EDIT:
Do the same with each STATIC control
 
Upvote 0
Also, i done up a macro that is able to work, however, i am unhappy because this is a very "stupid" and inefficient way of doing it.

What i did was to go down the windows manually.

````
main_view = FindWindowEx(hwindow2, 0&, "Calcframe", vbNullString) 'whole calculator view
sub_view = FindWindowEx(main_view, 0&, "#32770", vbNullString) ' 1st 32770 (Dialog)
sub_view2 = FindWindowEx(main_view, sub_view, "#32770", vbNullString) '2nd 32770 (Dialog)
button1 = FindWindowEx(sub_view2, 0&, "Button", vbNullString) 'MC button on calculator
button2 = FindWindowEx(sub_view2, button1, "Button", vbNullString) ' Backspace button on calculator
button3 = FindWindowEx(sub_view2, button2, "Button", vbNullString) 'number button 7 on calculator
button4 = FindWindowEx(sub_view2, button3, "Button", vbNullString) 'number button 4 on calculator
button5 = FindWindowEx(sub_view2, button4, "Button", vbNullString) 'number button 1 on calculator
button6 = FindWindowEx(sub_view2, button5, "Button", vbNullString) 'number button 0 on calculator
button7 = FindWindowEx(sub_view2, button6, "Button", vbNullString) 'MR button on calculator
button8 = FindWindowEx(sub_view2, button7, "Button", vbNullString) 'CE button on calculator
button9 = FindWindowEx(sub_view2, button8, "Button", vbNullString) 'number button 8 on calculator
button10 = FindWindowEx(sub_view2, button9, "Button", vbNullString) 'number button 5 on calculator
button11 = FindWindowEx(sub_view2, button10, "Button", vbNullString) 'number button 2 on calculator
button12 = FindWindowEx(sub_view2, button11, "Button", vbNullString) 'MS button on calculator
button13 = FindWindowEx(sub_view2, button12, "Button", vbNullString) 'C button on calculator
button14 = FindWindowEx(sub_view2, button13, "Button", vbNullString) 'number 9 button on calculator
button15 = FindWindowEx(sub_view2, button14, "Button", vbNullString) 'number 6 button on calculator
button16 = FindWindowEx(sub_view2, button15, "Button", vbNullString) 'number 3 button on calculator
button17 = FindWindowEx(sub_view2, button16, "Button", vbNullString) '. button on calculator
button18 = FindWindowEx(sub_view2, button17, "Button", vbNullString) 'M+ button on calculator
button19 = FindWindowEx(sub_view2, button18, "Button", vbNullString) '+_ button on calculator
button20 = FindWindowEx(sub_view2, button19, "Button", vbNullString) '/ button on calculator
button21 = FindWindowEx(sub_view2, button20, "Button", vbNullString) '* button on calculator
button22 = FindWindowEx(sub_view2, button21, "Button", vbNullString) '- button on calculator
button23 = FindWindowEx(sub_view2, button22, "Button", vbNullString) '+ button on calculator
button24 = FindWindowEx(sub_view2, button23, "Button", vbNullString) 'M- button on calculator
button25 = FindWindowEx(sub_view2, button24, "Button", vbNullString) 'sqaure root button on calculator
button26 = FindWindowEx(sub_view2, button25, "Button", vbNullString) '% button on calculator
button27 = FindWindowEx(sub_view2, button26, "Button", vbNullString) '1/X button on calculator
button28 = FindWindowEx(sub_view2, button27, "Button", vbNullString) '= button on calculator

'Calculate 74+21=95
Call SendMessage(button3, BM_CLICK, 0, ByVal0&) 'click button 7 on calculator
Call SendMessage(button4, BM_CLICK, 0, ByVal0&) 'click button 4 on calculator
Call SendMessage(button23, BM_CLICK, 0, ByVal0&) 'click + on calculator
Call SendMessage(button11, BM_CLICK, 0, ByVal0&) 'click button 2 on calculator
Call SendMessage(button5, BM_CLICK, 0, ByVal0&) 'click button 1 on calculator
Call SendMessage(button28, BM_CLICK, 0, ByVal0&) 'click = on calculator
````

As you can see, although this works, there are a lots of feedbacks.
1) This will only work in the normal view, if you change it to programmer or scientific view. It should not work.
2) What if there are 1000 or more buttons ? (Write a program to loop to write the lines or use excel to concatenate to write the lines???)
3) How do we identify each button after writing the code ? (Manually use spy++ to highlight every window to know which button it is???)

I am sure that the developers of Microsoft saw this issue ages back and would have came up with a solution. Therefore, if anyone knows the legit "correct" way of doing it. Any help is kindly and deeply appreciated and i am sure many others would be able to use this thread to start learning.

Dear @Jaafar Tribak ,

The control ID does not seem to change with the view and therefore programming it with Control ID seems to be the legit "correct" way.

Do you have an example of how to write a code with a control ID so i can experiment further?
 
Upvote 0
As you say, the Dialog control IDs are not supposed to change as they are determined by the dialog template. On the other hand, window handles (hwnd) are dynamic window IDs given by the OS and change every time the window is created.

In addition to the FindWindow and FindWindowEx API functions, there are many other functions you can use to retrieve window handles depending on the situation.

Lookup the documentation for the following API functions:
EnumWindows,EnumChildWindows,EnumThreadWindows,GetWindow,GetParent,GetAncestor,GetActiveWindow,GetFocus,GetForeGroundWindow,GetLastActivePopUp,WindowFromPoint etc


For Dialog controls lookup the GetDlgItem and GetDlgCtrlID functions.
 
Upvote 0
Dear @Jaafar Tribak ,

Thank you for your patience and time for someone who does not have a background in IT, i really appreciate it.

I tried going through the link that you gave but unfortunately, i guess i am not smart enough to decipher what it means or how to use it.

I tried for hours with different ways of using the functions you gave until VBA crashed and my work is gone.

Will you be able to give me a code to show me how to activate button 7 on the calculator based on the Control ID from spy++?

1591631564715.png
 
Upvote 0

Forum statistics

Threads
1,223,941
Messages
6,175,537
Members
452,652
Latest member
eduedu

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top