Return focus to selected items on Desktop Topic is solved

Get help with using AutoHotkey and its commands and hotkeys
Quisquose
Posts: 43
Joined: 24 Jun 2016, 04:16

Return focus to selected items on Desktop

14 Jun 2019, 18:50

I've created a hotkey to toggle the properties dialog of selected items.

If the selected item is in an Explorer window, I can press the hotkey once and its properties dialog will appear. When I press the hotkey again, the dialog closes. I can do this repeatedly to open and close the same dialog for the currently selected Explorer item(s).

But if I do the same with a selected item (or items) on the Desktop, the focus never returns back to the Desktop (or to the selected item) once the dialog closed. Instead, Windows always switches focus to another open window.

How can I override this Windows behaviour and ensure that the selected desktop item(s) remain focussed after the dialog has closed, so that it can be opened again if necessary without having to manually reselect the file(s).

I tried storing the ID for the Desktop in a variable, and the setting focus back to it after the dialog closes, but this doesn't prevent focus being given away to another window, which means that any subsequent presses of the hotkey ends up affecting something else (in another window) rather than the originally selected items on the Desktop.
tmplinshi
Posts: 1410
Joined: 01 Oct 2013, 14:57

Re: Return focus to selected items on Desktop

15 Jun 2019, 00:17

This worked for me.

Code: Select all

F1::
	if _class
	{
		Send, {Esc}
		if _class in Progman,WorkerW
		{
			WinActivate, ahk_class %_class%
		}
		_class := ""
	}
	else
	{
		WinGetClass, _class, A
		Send, !{Enter}
	}
Return
Quisquose
Posts: 43
Joined: 24 Jun 2016, 04:16

Re: Return focus to selected items on Desktop

15 Jun 2019, 03:05

Success! This works perfectly.

It's the object part that I could not figure out. I will look more into how they work.

Much obliged to you for your help.

Cheers
Rohwedder
Posts: 2049
Joined: 04 Jun 2014, 08:33
Location: Germany

Re: Return focus to selected items on Desktop

15 Jun 2019, 09:39

Hallo,
there is no object part!
Only: if Var in MatchList
https://www.autohotkey.com/docs/commands/IfIn.htm

Perhaps:

Code: Select all

#IF WinActive("ahk_class Progman") Or WinActive("ahk_class WorkerW")
F1::
	Send, !{Enter}
WinWaitActive, ahk_class #32770,,.5
IF ErrorLevel
	Return
WinWaitNotActive, ahk_class #32770
{
	Send, {Esc}
	WinActivate, ahk_class Progman
}
Return
You only have to press the F1 key once
letacio
Posts: 29
Joined: 08 Mar 2018, 16:05

Re: Return focus to selected items on Desktop

15 Jun 2019, 12:35

tmplinshi wrote:
15 Jun 2019, 00:17
This worked for me.

Code: Select all

F1::
	if _class
	{
		Send, {Esc}
		if _class in Progman,WorkerW
		{
			WinActivate, ahk_class %_class%
		}
		_class := ""
	}
	else
	{
		WinGetClass, _class, A
		Send, !{Enter}
	}
Return

Could you elucidate for me what _class does, or what i could search about on the topic?

Thanks!
tmplinshi
Posts: 1410
Joined: 01 Oct 2013, 14:57

Re: Return focus to selected items on Desktop

15 Jun 2019, 13:11

_class is just a variable name, you can type anything you like.

Hope this is more clear to you.

Code: Select all

F1::
	if dialogOpened
	{
		Send, {Esc}
		if className in Progman,WorkerW
		{
			WinActivate, ahk_class %className%
		}
		dialogOpened := className := ""
	}
	else
	{
		WinGetClass, className, A
		Send, !{Enter}
		dialogOpened := true
	}
Return
Quisquose
Posts: 43
Joined: 24 Jun 2016, 04:16

Re: Return focus to selected items on Desktop

20 Jun 2019, 19:57

Just noticed an issue with the script.

Despite the fact that the WorkerW class has been included, the script does not function correctly after 'Show Desktop' has been used.

Any idea why? The inclusion of WorkerW usually fixes that issue.
tmplinshi
Posts: 1410
Joined: 01 Oct 2013, 14:57

Re: Return focus to selected items on Desktop  Topic is solved

20 Jun 2019, 22:04

Replace WinActivate, ahk_class %className% with one of following seems to work:
  • WinActivate, ahk_class Progman
  • WinActivate, % "ahk_id " . DllCall("GetShellWindow", "ptr")

Code: Select all

F1::OpenCloseProperties()

OpenCloseProperties() {
	static isOpened, className

	if isOpened
	{
		Send, {Esc}
		if className in Progman,WorkerW
		{
			; WinActivate, ahk_class Progman
			WinActivate, % "ahk_id " . DllCall("GetShellWindow", "ptr")
		}
		isOpened := className := ""
	}
	else
	{
		WinGetClass, className, A
		Send, !{Enter}
		isOpened := true
	}
}
Quisquose
Posts: 43
Joined: 24 Jun 2016, 04:16

Re: Return focus to selected items on Desktop

20 Jun 2019, 22:54

Thanks.

I had already tried WinActivate, ahk_class Progman but it didn't work, which is why I thought I'd make a follow-up post for more suggestions.

When I saw that you had an alternative WinActivate method, I gave that a go, but it didn't work either.

The fact that both methods work for you and neither work for me led me to suspect something else in my script as being the culprit. So I killed my running script and just ran your code on its own, and it worked. So it's definitely something else in my code screwing things up (but only after Show Desktop; the rest of it works fine even with my script running). Now that I know what's responsible, I'll go and see if I can track down the conflict.

Thanks for your additional solution. It set me on the right path to find the problem.
tmplinshi
Posts: 1410
Joined: 01 Oct 2013, 14:57

Re: Return focus to selected items on Desktop

21 Jun 2019, 01:29

Here is a more complex code. The properties dialog can be closed by manually pressing ESC key or clicking the "x" button, it dose not affect the script.

Code: Select all

F1::OpenCloseProperties()

OpenCloseProperties() {
	OpenCloseProperties.DoIt()
}

class OpenCloseProperties
{
	DoIt() {
		if this.isOpened && WinExist("ahk_id " this.dialogHwnd)
		{
			WinClose
			if this.isInDesktop {
				WinActivate, % "ahk_id " . DllCall("GetShellWindow", "ptr") ; activate desktop
			}
			this.isOpened := false
		}
		else
			this.OpenDialog()
	}

	OpenDialog() {
		WinGetClass, class, A

		if class in Progman,WorkerW
			success := this.Desktop_OpenSelProperties(), this.isInDesktop := true
		else if class in CabinetWClass,ExploreWClass
			success := this.Explorer_OpenSelProperties(), this.isInDesktop := false

		if success {
			WinWait, ahk_class #32770 ahk_exe explorer.exe
			this.dialogHwnd := WinExist()
			this.isOpened := true
		}
	}

	Desktop_OpenSelProperties() {
		oWindows := ComObjCreate("Shell.Application").Windows
		VarSetCapacity(hWnd, 4, 0)
		;SWC_DESKTOP := 0x8 ;VT_BYREF := 0x4000 ;VT_I4 := 0x3 ;SWFO_NEEDDISPATCH := 0x1
		oWin := oWindows.FindWindowSW(0, "", 8, ComObject(0x4003, &hWnd), 1)
		oWin.Document.SelectedItems.InvokeVerbEx("Properties")
		return oWin.Document.SelectedItems.Count
	}

	Explorer_OpenSelProperties() {
		hWnd := WinExist("A")
		for oWin in ComObjCreate("Shell.Application").Windows
		{
			if (oWin.hWnd = hWnd)
			{
				oWin.Document.SelectedItems.InvokeVerbEx("Properties")
				return oWin.Document.SelectedItems.Count
			}
		}
	}
}
Quisquose
Posts: 43
Joined: 24 Jun 2016, 04:16

Re: Return focus to selected items on Desktop

21 Jun 2019, 08:37

I did some digging around and I found the problem. It was my fault! (it usually is, haha).

I had modified your code slightly to make an exception for when the Start Menu has focus. I needed to send a different hotkey in that instance because !{Enter} just launches the Start Menu shortcut link for the selected item instead of opening the selected item's Properties page. So, in that one instance I needed to send {AppsKey}r instead.

However, in my attempt at making this exception, my If statement was not properly isolated and got a bit mixed up with those in your code. The result was that it did work perfectly for the Start Menu and all other cases, but after 'Show Desktop' had been used, focus would not get returned to the selected Desktop items.

I've since fixed my code, and it now works under all situations (even when I'm running my full existing script with many different commands in it).

By the way, thanks for previously posting the 'clearer' example of your code. That was easier for me to understand than the first example.

Return to “Ask For Help”

Who is online

Users browsing this forum: chrispage, flyingDman, ineuw, omar, TAC109 and 144 guests