Ask if a control is active vs a window

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
WeThotUWasAToad
Posts: 312
Joined: 19 Nov 2013, 08:44

Ask if a control is active vs a window

08 Dec 2017, 00:04

Hello,

How do you ask if a control is active?

I continue to use Excel 2010 because of its ability to have multiple Excel workbooks open in a single Excel instance. Sometime ago I got help writing a script which positions both the main Excel instance window (by screen coords of course), and the workbooks (sort of sub-windows, ie controls) with coords relative to the Excel instance as shown here:

Code: Select all

^F2::			; use this one to display in exactly half screen width
CoordMode, Mouse, Screen	; to position main Excel window and its sub-windows
SetTitleMatchMode, 2	; the control coords are interpreted as relative regardless of coord mode
	; paste calculated positions (from "_sub window positioning.xlsm") below this row

	WinMove, Excel,, 0, 64, 1920, 2000
	WinWait, Excel
	    ControlMove, _Stmt, 13, 193, 674, 1307, , _Stmt
	    ControlMove, _Tags, 1907, 193, 1142, 1749, , _Tags
	    ControlMove, _MediaLog, 13, 1558, 1548, 386, , _MediaLog
	    ControlMove, _Directory, 865, 1500, 1042, 444, , _Directory
Return
Now I want to write an If/Else script which is dependent on which of the controls is active. I tried the following script but realized it is looking for a regular window, not a control.

Code: Select all

^1::
  SetTitleMatchMode, 2
  IfWinActive, _Stmt
    {
	Send {Enter}
	Send {Space 6}{u+2026}		; ellipsis
    }
  Else
    {
	Send {Enter}
	Send {Space 4}{u+2022}{Space}		;    •
    }
  Return
So how can I modify it to ask if a particular control is active (vs one of the other controls in the instance or another window all together)?

Thanks
A ------------------------------ [A LOT OF SPACE] ------------------------------ LOT

"ALOT" is not a word. It never has been a word and it never will be a word.
"A LOT" is 2 words. Remember it as though there's [A LOT OF SPACE] between them.
User avatar
Masonjar13
Posts: 1555
Joined: 20 Jul 2014, 10:16
Location: Не Россия
Contact:

Re: Ask if a control is active vs a window

08 Dec 2017, 01:45

ControlGetFocus will give you the active control, which you can then compare to whatever control you're needing to be active.

Code: Select all

; Give it the className of the control that needs to be checked; returns 1 if active, 0 if not
controlActive(controlClassName,winName:="a"){
    controlGetFocus,focusedControl,% winName
    return controlClassName=focusedControl?1:0
}
OS: Windows 10 Pro | Editor: Notepad++
My Personal Function Library | Old Build - New Build
WeThotUWasAToad
Posts: 312
Joined: 19 Nov 2013, 08:44

Re: Ask if a control is active vs a window

08 Dec 2017, 18:17

Thanks for the response.

Unfortunately, I'm not sure how to put that to work.

I tried inserting it as follows:

Code: Select all

^1::
; Give it the className of the control that needs to be checked; returns 1 if active, 0 if not
controlActive(controlClassName,winName:="a")
{
    controlGetFocus,focusedControl,% winName
    return controlClassName=focusedControl?1:0
}
Return
but that gave me the following error:
---------------------------
Error at line 4209.

Line Text: controlActive(controlClassName,winName:="a")
Error: Parameters of hotkey functions must be optional.
---------------------------
I use this short script to obtain the name of a regular window;

Code: Select all

^F7::
WinGetActiveStats, `Title, Width, Height, X, Y
MsgBox, The active title is: "%Title%"
Return
Should it look anything like that?
Masonjar13 wrote:Give it the className of the control that needs to be checked...
As shown in the OP, one of the controls is named "_stmt" (when preceded by SetTitleMatchMode, 2). Is that the same as the className? And if so, where should it be inserted?

Also, the definition at ControlGetFocus is:
Retrieves which control of the target window has input focus, if any.
Can you explain "input focus"?

Thanks
A ------------------------------ [A LOT OF SPACE] ------------------------------ LOT

"ALOT" is not a word. It never has been a word and it never will be a word.
"A LOT" is 2 words. Remember it as though there's [A LOT OF SPACE] between them.
User avatar
Masonjar13
Posts: 1555
Joined: 20 Jul 2014, 10:16
Location: Не Россия
Contact:

Re: Ask if a control is active vs a window

08 Dec 2017, 20:06

A function should be placed outside of any subroutines. I place them either at the bottom of my script or in my standard library.

Code: Select all

setTitleMatchMode, 2

^1::
if(winActive("Excel") && controlActive("_Stmt")) ; you can also use just controlActive() here
    send {enter}{space 6}{u+2026}
else
    send {enter}{space 4}{u+2022}{space}
return

controlActive(controlClassName,winName:="a"){
    controlGetFocus,focusedControl,% winName
    return controlClassName=focusedControl?1:0
}
Input focus is synonymous with "the control that is active." It simply means, if you type or give literal input, the active control will be the one to receive it.
OS: Windows 10 Pro | Editor: Notepad++
My Personal Function Library | Old Build - New Build
WeThotUWasAToad
Posts: 312
Joined: 19 Nov 2013, 08:44

Re: Ask if a control is active vs a window

08 Dec 2017, 22:03

Thanks for the script and explanation.

I copied/pasted the script just as you have it and while I'm no longer getting the error, it is still not entering the If result (ie 6 spaces and an ellipsis). Instead, it persists in entering the same Else result (4 spaces and a bullet) in the _Stmt workbook as it does in the others.

I tried it with the full filenames in case that was the problem:

Code: Select all

setTitleMatchMode, 2

^1::
if(winActive("Microsoft Excel") && controlActive("gs_2018_Stmt.xlsm")) ; you can also use just controlActive() here
    send {enter}{space 6}{u+2026}
else
    send {enter}{space 4}{u+2022}{space}
return

controlActive(controlClassName,winName:="a"){
    controlGetFocus,focusedControl,% winName
    return controlClassName=focusedControl?1:0
}
but continue to get only the bullet in the "Stmt" workbook.

In case it's relevant, the Excel instance (main window) contains four workbooks. The complete filenames for the workbooks are:

gs_2018_Data.xlsm
gs_2018_Text.xlsm
gs_2018_Notes.xlsm
gs_2018_Stmt.xlsm

Also, I tested the following to verify I've got the right Unicode number:

Code: Select all

^2::
	Send {Enter}
	Send {Space 4}{u+2026}{Space}
	Return
and it works as expected.
A ------------------------------ [A LOT OF SPACE] ------------------------------ LOT

"ALOT" is not a word. It never has been a word and it never will be a word.
"A LOT" is 2 words. Remember it as though there's [A LOT OF SPACE] between them.
User avatar
Masonjar13
Posts: 1555
Joined: 20 Jul 2014, 10:16
Location: Не Россия
Contact:

Re: Ask if a control is active vs a window

08 Dec 2017, 22:34

Add msgbox % focusedControl after controlGetFocus in the function. Sometimes controls overlap and some take precedence over others in being focused. That should give you a good idea how to proceed. Note that I don't use Excel, so I can't test anything.

Is it something you could do via COM? Excel does have a COM interface, bypassing the need for focus.
OS: Windows 10 Pro | Editor: Notepad++
My Personal Function Library | Old Build - New Build
WeThotUWasAToad
Posts: 312
Joined: 19 Nov 2013, 08:44

Re: Ask if a control is active vs a window

08 Dec 2017, 23:22

Masonjar13 wrote:Add msgbox % focusedControl after controlGetFocus in the function. Sometimes controls overlap and some take precedence over others in being focused. That should give you a good idea how to proceed. Note that I don't use Excel, so I can't test anything.

Is it something you could do via COM? Excel does have a COM interface, bypassing the need for focus.
OK, by "after controlGetFocus in the function", I assume you mean this:

Code: Select all

setTitleMatchMode, 2

^1::
if(winActive("Microsoft Excel") && controlActive("gs_2018_Stmt.xlsm")) ; you can also use just controlActive() here
    send {enter}{space 6}{u+2026}
else
    send {enter}{space 4}{u+2022}{space}
return

controlActive(controlClassName,winName:="a"){
    controlGetFocus,focusedControl,% winName
	msgbox % focusedControl
    return controlClassName=focusedControl?1:0
}
Which returns the following MsgBox:
---------------------------
1_qdscript.ahk
---------------------------
DgnExcel.RichEdit1
---------------------------
OK
---------------------------
And interestingly, I get the same MsgBox from all four controls.

Is that the reason it always sends the Else command?

I suppose it could be done using COM but I don't know any COM scripting — although as a coincidence, I just yesterday had a conversation with a friend (Joe Winograd) about it being high time I learned it. In the meantime — and if it's not too much trouble — could you give me a COM script to do what I'm after?

Also, purely out of curiosity, what do you use for a spreadsheet in place of Excel?

Thanks
A ------------------------------ [A LOT OF SPACE] ------------------------------ LOT

"ALOT" is not a word. It never has been a word and it never will be a word.
"A LOT" is 2 words. Remember it as though there's [A LOT OF SPACE] between them.
WeThotUWasAToad
Posts: 312
Joined: 19 Nov 2013, 08:44

Re: Ask if a control is active vs a window

08 Dec 2017, 23:27

And what are you doing up so early in the morning in Ukraine? ;)
A ------------------------------ [A LOT OF SPACE] ------------------------------ LOT

"ALOT" is not a word. It never has been a word and it never will be a word.
"A LOT" is 2 words. Remember it as though there's [A LOT OF SPACE] between them.
User avatar
Masonjar13
Posts: 1555
Joined: 20 Jul 2014, 10:16
Location: Не Россия
Contact:

Re: Ask if a control is active vs a window

09 Dec 2017, 00:00

WeThotUWasAToad wrote:And interestingly, I get the same MsgBox from all four controls.

Is that the reason it always sends the Else command?
That's what I thought would be the problem, and yes, that would be the reason why. I don't know any way around this, unfortunately.
WeThotUWasAToad wrote:could you give me a COM script to do what I'm after?
No I can't. While I've used COM plenty for IE, I've never used it for Excel, seeing as I've never had Excel installed. There are a great many tutorials available for COM with Excel though, I don't believe it should be too hard to make what you're asking for (a Google search will land you a lot of hits).
WeThotUWasAToad wrote:Also, purely out of curiosity, what do you use for a spreadsheet in place of Excel?
Nothing, usually. I don't generally have need for spreadsheets, but if I have to make/view one, I use LibreOffice, as it's open source.
WeThotUWasAToad wrote:And what are you doing up so early in the morning in Ukraine? ;)
:lol: I've never considered it before, but now that you point it out, I can see how "Not Russia," in Russian, could be construed as the Ukraine. I'm actually in the US, and with a terrible sleep schedule ;)
OS: Windows 10 Pro | Editor: Notepad++
My Personal Function Library | Old Build - New Build
WeThotUWasAToad
Posts: 312
Joined: 19 Nov 2013, 08:44

Re: Ask if a control is active vs a window

11 Dec 2017, 16:34

You mentioned you don't use Excel so I'd like to get this question in front of someone who does use Excel — and actually if possible, someone who is very familiar with Excel 2010 since part of the challenge, to me at least, is the significant changes which accompanied more recent versions like Excel 2013 & 2016.

A couple of issues to address though (particularly since you are a moderator):

1) I certainly don't want to imply (to you or anyone else) that I don't respect and appreciate your earlier posts.
2) Should I simply start a new thread with the same or a slightly altered subject/title?
3) Or is there a way to get existing threads fed back into the loop in a way that people will view them as new or at least not think they've already been answered?
4) Do any specific people come to mind who are most likely to know a solution (if indeed there is a solution)?
5) And would it be good for me (or you) to send a pm asking them to jump in?

I'm good with going any direction but I'll defer to your suggestion re which direction is best.

Thanks again
A ------------------------------ [A LOT OF SPACE] ------------------------------ LOT

"ALOT" is not a word. It never has been a word and it never will be a word.
"A LOT" is 2 words. Remember it as though there's [A LOT OF SPACE] between them.
User avatar
Masonjar13
Posts: 1555
Joined: 20 Jul 2014, 10:16
Location: Не Россия
Contact:

Re: Ask if a control is active vs a window

11 Dec 2017, 17:37

If you edit your first post, you should be able to change the title. If not, I could do that for you. That should get some relevant users. :thumbup: I don't know anyone specifically who's good at COM for Excel. You could certainly look at some Excel COM tutorials and PM who wrote them.

I believe your best bet would be to try it on your own, then create a new thread specifically for Excel COM (2010; not sure if its COM interface changed with the versions) if/when you encounter a problem. Ultimately, you're free to make a new thread at any time.
OS: Windows 10 Pro | Editor: Notepad++
My Personal Function Library | Old Build - New Build
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: Ask if a control is active vs a window

11 Dec 2017, 18:20

- I believe it's a bit like Internet Explorer:
-- The Internet Explorer_Server1 control is the active tab in Internet Explorer. Its class is Internet Explorer_Server.
-- The EXCEL71 control is the active workbook in Excel. Its class is EXCEL7.
- kon and FanaticGuru are good at Excel and COM. Although kon's been away for a while. I used to do a lot with Excel macros, so it's usually fairly easy to adapt my old knowledge to AutoHotkey. Especially since I resolved various Excel queries:
Excel VBA: UCase and LCase - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=5&t=34146
MS Office Excel COM Interface Constants - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=7&t=33914
- Key to using Excel via AutoHotkey is the Excel_Get function, linked below, which latches onto a specific Excel window and its workbooks.
- One thing that I've only realised today, because of your request, is that the function lets you latch onto a specific workbook, but I don't know if the object you get is any different for workbooks belonging to the same instance. I.e. is there any way to identify the workbook you originally latched onto via an object method.
- This should pretty much do what you're looking for. It's a bit confusing, the workbooks appear to be controls of a main Excel window, and yet have separate alt+tab icons.

Code: Select all

;[Excel_Get function]
;MS-Office-COM-Basics/Excel_Get.ahk at master · ahkon/MS-Office-COM-Basics · GitHub
;https://github.com/ahkon/MS-Office-COM-Basics/blob/master/Examples/Excel/Excel_Get.ahk

q:: ;excel - list workbooks (tested with Excel 2007)
WinGet, hWnd, ID, A

;get active workbook
ControlGetText, vText, EXCEL71, % "ahk_id " hWnd
;MsgBox, % vText

;list workbooks
WinGet, vCtlList, ControlList, % "ahk_id " hWnd
vOutput := ""
Loop
{
	vCtlClassNN := "EXCEL7" A_Index
	ControlGet, hCtl, Hwnd,, % vCtlClassNN, % "ahk_id " hWnd
	if !hCtl
		break
	ControlGetText, vText, % vCtlClassNN, % "ahk_id " hWnd
	vOutput .= vCtlClassNN "`r`n" vText "`r`n`r`n"
}
Clipboard := vOutput
MsgBox, % vOutput

;get active workbook
;oXl := Excel_Get("ahk_id " hWnd)
;MsgBox, % oXl.ActiveWorkbook.Name "`r`n" oXl.ActiveWorkbook.FullName
;oXl := ""

;list workbooks
vOutput := ""
oXl := Excel_Get("ahk_id " hWnd)
for oWorkbook in oXl.Workbooks
	vOutput .= oWorkbook.Name "`r`n" oWorkbook.FullName "`r`n`r`n"
oXl := ""
Clipboard := vOutput
MsgBox, % vOutput
return
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
WeThotUWasAToad
Posts: 312
Joined: 19 Nov 2013, 08:44

Re: Ask if a control is active vs a window

11 Dec 2017, 19:24

Masonjar13 wrote:Ultimately, you're free to make a new thread at any time.
Great. Thanks for the comments and all your help.
jeeswg wrote:- This should pretty much do what you're looking for.
Thanks for the input jeeswg. Your script contains quite a bit that's new to me so it will take some time to go through it. However, in the meantime, I was unable to test it due to the following error:
---------------------------
Error: Call to nonexistent function.

Specifically: Excel_Get("ahk_id " hWnd)

Line#
035: Break
036: ControlGetText,vText,vCtlClassNN,"ahk_id " hWnd
037: vOutput .= vCtlClassNN "

" vText "

"
038: }
039: Clipboard := vOutput
040: MsgBox,vOutput
043: vOutput := ""
---> 044: oXl := Excel_Get("ahk_id " hWnd)
045: For oWorkbook, in oXl.Workbooks
046: vOutput .= oWorkbook.Name "

" oWorkbook.FullName "

"
047: oXl := ""
048: Clipboard := vOutput
049: MsgBox,vOutput
050: Return
051: Exit

The program will exit.
---------------------------
Suggestions?
A ------------------------------ [A LOT OF SPACE] ------------------------------ LOT

"ALOT" is not a word. It never has been a word and it never will be a word.
"A LOT" is 2 words. Remember it as though there's [A LOT OF SPACE] between them.
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: Ask if a control is active vs a window

11 Dec 2017, 19:46

The error message is telling you that there was a call to a non-existent function, specifically Excel_Get.

There was also a link in the script:
[Excel_Get function]
MS-Office-COM-Basics/Excel_Get.ahk at master · ahkon/MS-Office-COM-Basics · GitHub
https://github.com/ahkon/MS-Office-COM- ... el_Get.ahk

In the time that I've been posting in this way, people never seem to put two and two together! I might have to make it clearer still.

==================================================

This script using Acc appears to latch onto a specific workbook.

Code: Select all

;[Acc functions]
;Acc library (MSAA) and AccViewer download links - AutoHotkey Community
;https://autohotkey.com/boards/viewtopic.php?f=6&t=26201

;Basic Ahk_L COM Tutorial for Excel - Tutorials - AutoHotkey Community
;https://autohotkey.com/board/topic/69033-basic-ahk-l-com-tutorial-for-excel/#entry437036

q::
Loop, 2
{
	ControlGet, hCtl, Hwnd,, % "Excel7" A_Index, ahk_class XLMAIN
	oWin := Acc_ObjectFromWindow(hCtl, -16)
	oBook := oWin.Parent
	MsgBox, % oBook.FullName
	oWin := oBook := ""
}
return
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
WeThotUWasAToad
Posts: 312
Joined: 19 Nov 2013, 08:44

Re: Ask if a control is active vs a window

12 Dec 2017, 10:12

jeeswg wrote:The error message is telling you that there was a call to a non-existent function, specifically Excel_Get.

There was also a link in the script:
[Excel_Get function]
MS-Office-COM-Basics/Excel_Get.ahk at master · ahkon/MS-Office-COM-Basics · GitHub
https://github.com/ahkon/MS-Office-COM- ... el_Get.ahk
Sorry I'm not getting this. Unfortunately, most of the content in these scripts is unfamiliar — so currently, my 1st goal is to get something that works. At that point, I will have the functionality I need and then 2nd, I can start reading up on the unfamiliar components as well as tweaking them to see what effect they have on the functionality.

So right now, I've got three scripts. This, from your first post:

Code: Select all

;[Excel_Get function]
;MS-Office-COM-Basics/Excel_Get.ahk at master · ahkon/MS-Office-COM-Basics · GitHub
;https://github.com/ahkon/MS-Office-COM-Basics/blob/master/Examples/Excel/Excel_Get.ahk

q:: ;excel - list workbooks (tested with Excel 2007)
WinGet, hWnd, ID, A

;get active workbook
ControlGetText, vText, EXCEL71, % "ahk_id " hWnd
;MsgBox, % vText

;list workbooks
WinGet, vCtlList, ControlList, % "ahk_id " hWnd
vOutput := ""
Loop
{
	vCtlClassNN := "EXCEL7" A_Index
	ControlGet, hCtl, Hwnd,, % vCtlClassNN, % "ahk_id " hWnd
	if !hCtl
		break
	ControlGetText, vText, % vCtlClassNN, % "ahk_id " hWnd
	vOutput .= vCtlClassNN "`r`n" vText "`r`n`r`n"
}
Clipboard := vOutput
MsgBox, % vOutput

;get active workbook
;oXl := Excel_Get("ahk_id " hWnd)
;MsgBox, % oXl.ActiveWorkbook.Name "`r`n" oXl.ActiveWorkbook.FullName
;oXl := ""

;list workbooks
vOutput := ""
oXl := Excel_Get("ahk_id " hWnd)
for oWorkbook in oXl.Workbooks
	vOutput .= oWorkbook.Name "`r`n" oWorkbook.FullName "`r`n`r`n"
oXl := ""
Clipboard := vOutput
MsgBox, % vOutput
return
And this, from the link you provided (https://github.com/ahkon/MS-Office-COM- ... Get.ahk#L1):

Code: Select all

; Excel_Get by jethrow (modified)
; Forum:    https://autohotkey.com/boards/viewtopic.php?f=6&t=31840
; Github:   https://github.com/ahkon/MS-Office-COM-Basics/blob/master/Examples/Excel/Excel_Get.ahk
Excel_Get(WinTitle:="ahk_class XLMAIN", Excel7#:=1) {
    static h := DllCall("LoadLibrary", "Str", "oleacc", "Ptr")
    WinGetClass, WinClass, %WinTitle%
    if !(WinClass == "XLMAIN")
        return "Window class mismatch."
    ControlGet, hwnd, hwnd,, Excel7%Excel7#%, %WinTitle%
    if (ErrorLevel)
        return "Error accessing the control hWnd."
    VarSetCapacity(IID_IDispatch, 16)
    NumPut(0x46000000000000C0, NumPut(0x0000000000020400, IID_IDispatch, "Int64"), "Int64")
    if DllCall("oleacc\AccessibleObjectFromWindow", "Ptr", hWnd, "UInt", -16, "Ptr", &IID_IDispatch, "Ptr*", pacc) != 0
        return "Error calling AccessibleObjectFromWindow."
    window := ComObject(9, pacc, 1)
    if ComObjType(window) != 9
        return "Error wrapping the window object."
    Loop
        try return window.Application
        catch e
            if SubStr(e.message, 1, 10) = "0x80010001"
                ControlSend, Excel7%Excel7#%, {Esc}, %WinTitle%
            else
                return "Error accessing the application object."
}

; References
;   https://autohotkey.com/board/topic/88337-ahk-failure-with-excel-get/?p=560328
;   https://autohotkey.com/board/topic/76162-excel-com-errors/?p=484371
;   https://autohotkey.com/boards/viewtopic.php?p=134048#p134048
And this, from your latest post:

Code: Select all

;[Acc functions]
;Acc library (MSAA) and AccViewer download links - AutoHotkey Community
;https://autohotkey.com/boards/viewtopic.php?f=6&t=26201

;Basic Ahk_L COM Tutorial for Excel - Tutorials - AutoHotkey Community
;https://autohotkey.com/board/topic/69033-basic-ahk-l-com-tutorial-for-excel/#entry437036

q::
Loop, 2
{
	ControlGet, hCtl, Hwnd,, % "Excel7" A_Index, ahk_class XLMAIN
	oWin := Acc_ObjectFromWindow(hCtl, -16)
	oBook := oWin.Parent
	MsgBox, % oBook.FullName
	oWin := oBook := ""
}
return
But I don't know how to combine them or even if they are meant to be combined in order to get a functioning script, (ie a script that identifies which control is currently active in order to use that info in an If/Else script).

Many thanks,

Steve
A ------------------------------ [A LOT OF SPACE] ------------------------------ LOT

"ALOT" is not a word. It never has been a word and it never will be a word.
"A LOT" is 2 words. Remember it as though there's [A LOT OF SPACE] between them.
WeThotUWasAToad
Posts: 312
Joined: 19 Nov 2013, 08:44

Re: Ask if a control is active vs a window

12 Dec 2017, 10:16

Also, I mentioned this earlier, but the following script seems so simple and yet works so well, simply by using a partial file name (_Text, _Notes) to identify each of the controls, I'm surprised that a similar approach cannot be used for determining which control is active. However, that statement may just be reemphasizing my naïveté so I will patiently await your next post. :P

Code: Select all

CoordMode, Mouse, Screen	; to position main Excel window and its sub-windows (ie controls) within the main window
SetTitleMatchMode, 2	;
	WinMove, Microsoft Excel,, 1000, 100, 2480, 1940
	WinWait, Microsoft Excel
	    ControlMove, _Text, 10, 175, 1000, 1700, , _Text
	    ControlMove, _Notes, 1010, 175, 1460, 1700, , _Notes
Return
A ------------------------------ [A LOT OF SPACE] ------------------------------ LOT

"ALOT" is not a word. It never has been a word and it never will be a word.
"A LOT" is 2 words. Remember it as though there's [A LOT OF SPACE] between them.
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: Ask if a control is active vs a window

12 Dec 2017, 10:49

- The two scripts with q hotkeys are completely separate. To put them both in the same script, comment out or change the hotkeys.
- The Excel_Get function needs to be in your script, or included via #Include (or placed in the Lib folder), for the first one to work. The Acc functions need to be in your script, or included via #Include (or placed in the Lib folder), for the second one to work.
- I didn't understand how this line was working initially because '_Text' is not a ClassNN, it has no digits.
ControlMove, _Text, 10, 175, 1000, 1700, , _Text
ControlMove, Control, X, Y, Width, Height, WinTitle, WinText
I didn't realise this:
ControlMove
https://autohotkey.com/docs/commands/ControlMove.htm
Can be either ClassNN (the classname and instance number of the control) or the control's text
And you were using _Text again as text that the window must contain.
- If you list the controls that a window contains, you will see that the '_Text' Excel workbook, has a ClassNN such as EXCEL71 / EXCEL72 / EXCEL73.
To get information for the active workbook, you would do something like:
ControlGetText, vText, EXCEL71, A
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
WeThotUWasAToad
Posts: 312
Joined: 19 Nov 2013, 08:44

Re: Ask if a control is active vs a window

12 Dec 2017, 13:30

jeeswg wrote:- I didn't understand how this line was working initially because '_Text' is not a ClassNN, it has no digits.
ControlMove, _Text, 10, 175, 1000, 1700, , _Text
ControlMove, Control, X, Y, Width, Height, WinTitle, WinText
Huge apologies. I should have realized that using "_Text" to represent a filename is not a good idea — ever. FYI, the full filenames (of the controls) referenced in the code in my previous post are:

gs_2018_Text.xlsm
gs_2018_Notes.xlsm

I'm so used to using SetTitleMatchMode, 2 and since "_Text" & "_Notes" are the distinguishing parts of the two filenames I just entered them that way without thinking much about it.

So it could just as easily be:

Code: Select all

CoordMode, Mouse, Screen	; to position main Excel window and its sub-windows (ie controls) within the main window
SetTitleMatchMode, 2	;
	WinMove, Microsoft Excel,, 1000, 100, 2480, 1940
	WinWait, Microsoft Excel
	    ControlMove, gs_2018_Text.xlsm, 10, 175, 1000, 1700, , gs_2018_Text.xlsm
	    ControlMove, gs_2018_Notes.xlsm, 1010, 175, 1460, 1700, , gs_2018_Notes.xlsm
Return
I'm really sorry for my miscommunication and whatever time you and/or Masonjar13 spent working on a false premise.

Steve
A ------------------------------ [A LOT OF SPACE] ------------------------------ LOT

"ALOT" is not a word. It never has been a word and it never will be a word.
"A LOT" is 2 words. Remember it as though there's [A LOT OF SPACE] between them.
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: Ask if a control is active vs a window

12 Dec 2017, 14:24

Well, the questions you asked were good ones, the code didn't take me very long, because I have lots of templates, and, you've led me to discover some quite interesting things about Excel: re. workbooks and controls, and workbooks and objects. Good content for my eventual Excel tutorial, some good fundamental information. Cheers.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
WeThotUWasAToad
Posts: 312
Joined: 19 Nov 2013, 08:44

Re: Ask if a control is active vs a window

12 Dec 2017, 23:39

I'm sorry jeeswg but in trying to straighten this out, I feel more confused than ever.

I earlier referred to three of your scripts which begin as follows:

Script #1

Code: Select all

;[Excel_Get function]
;MS-Office-COM-Basics/Excel_Get.ahk at master · ahkon/MS-Office-COM-Basics · GitHub
;https://github.com/ahkon/MS-Office-COM-Basics/blob/master/Examples/Excel/Excel_Get.ahk

q:: ;excel - list workbooks (tested with Excel 2007)
WinGet, hWnd, ID, A
...
Script #2

Code: Select all

; Excel_Get by jethrow (modified)
; Forum:    https://autohotkey.com/boards/viewtopic.php?f=6&t=31840
; Github:   https://github.com/ahkon/MS-Office-COM-Basics/blob/master/Examples/Excel/Excel_Get.ahk
...
Script #3

Code: Select all

;[Acc functions]
;Acc library (MSAA) and AccViewer download links - AutoHotkey Community
;https://autohotkey.com/boards/viewtopic.php?f=6&t=26201

;Basic Ahk_L COM Tutorial for Excel - Tutorials - AutoHotkey Community
;https://autohotkey.com/board/topic/69033-basic-ahk-l-com-tutorial-for-excel/#entry437036

q::
Loop, 2
...
and which (hopefully to simplify), I will now refer to as:

#1 ;[Excel_Get function]... — contains hotkey q::
#2 ;Excel_Get by jethrow (modified)...
#3 ;[Acc functions]... — contains hotkey q::

You said:
jeeswg wrote:- The two scripts with q hotkeys are completely separate.
and
jeeswg wrote:- The Excel_Get function needs to be in your script
So from that, I understand that #1 & #3 do not belong together and #2 should always be included. But when I tried #1 followed by #2 in the same script, I got this error:
---------------------------
Warning: This local variable has the same name as a global variable.

Specifically: hwnd (in function Excel_Get)

Line#
058: oXl := Excel_Get("ahk_id " hWnd)
059: For oWorkbook, in oXl.Workbooks
060: vOutput .= oWorkbook.Name "
" oWorkbook.FullName "

"
061: oXl := ""
062: Clipboard := vOutput
063: MsgBox,vOutput
064: Return
---> 069: {
071: WinGetClass,WinClass,%WinTitle%
072: if !(WinClass == "XLMAIN")
073: Return,"Window class mismatch."
074: ControlGet,hwnd,hwnd,,Excel7%Excel7#%,%WinTitle%
075: if (ErrorLevel)
076: Return,"Error accessing the control hWnd."
077: VarSetCapacity(IID_IDispatch, 16)

For more details, read the documentation for #Warn.
---------------------------
and when I tried #3 followed by #2 in the same script, I got this error:
---------------------------
Error: Call to nonexistent function.

Specifically: Acc_ObjectFromWindow(hCtl, -16)

Line#
007: Return
018: ControlGetText,vText,EXCEL71,A
019: MsgBox,%vText%
020: Return
040: Loop,2
041: {
042: ControlGet,hCtl,Hwnd,,"Excel7" A_Index,ahk_class XLMAIN
---> 043: oWin := Acc_ObjectFromWindow(hCtl, -16)
044: oBook := oWin.Parent
045: MsgBox,oBook.FullName
046: oWin := oBook := ""
047: }
048: Return
053: {
054: Static,h,DllCall("LoadLibrary", "Str", "oleacc", "Ptr")

The program will exit.
---------------------------
Also, from this:
Can be either ClassNN (the classname and instance number of the control) or the control's text
And you were using _Text again as text that the window must contain.
- If you list the controls that a window contains, you will see that the '_Text' Excel workbook, has a ClassNN such as EXCEL71 / EXCEL72 / EXCEL73.
I don't understand: "classname and instance number" or what is meant by "the controls text" or "text that the window must contain" or "list the controls that a window contains".

I did — after clicking somewhere in one of the workbooks to make it active — run this script:

Code: Select all

q::
ControlGetText, vText, EXCEL71, A		; retrieves name of control (workbook filename)
MsgBox %vText%
Return
and it simply returned the filename of that workbook.

I'm sure I've hampered my understanding by not clarifying the use of "_Text" earlier but is it possible at this point for you to post the exact and complete script I should use so I can simply copy & paste it in order to designate the active control in an If/Else script?

If that's possible then I believe I can work backwards to learn/understand what the script is doing.

Thanks for your patience and assistance.

Steve
A ------------------------------ [A LOT OF SPACE] ------------------------------ LOT

"ALOT" is not a word. It never has been a word and it never will be a word.
"A LOT" is 2 words. Remember it as though there's [A LOT OF SPACE] between them.

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: No registered users and 403 guests