Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

Detecting the "Unlock Computer" Dialog?


  • Please log in to reply
4 replies to this topic
Marcus
  • Members
  • 188 posts
  • Last active: Dec 06 2011 11:46 PM
  • Joined: 13 May 2005
Hello Folks!

Seem to be having trouble identifying the underlying process for the "Unlock Computer" dialog (comes up with WIN+L).

Want to detect the presence of this window, and pause script ops until it's gone.

However, the dialog is not visible to .ahk; and the Task Manager and Spy Window are disabled when it's up :(

Any ideas as to how I can catch this little monster when it peeks out? :shock:


Thanks a bunch...

shimanov
  • Guests
  • Last active:
  • Joined: --

Seem to be having trouble identifying the underlying process for the "Unlock Computer" dialog (comes up with WIN+L).

Want to detect the presence of this window


I cannot tell you how to determine the window handle. I can tell you that the foreground window handle cannot be returned (i.e., active window) and the following method allows you to detect when the screen saver or the Session Logon window is active (disclaimer: this may not be a unique result of those events). This is probably by design to ensure security of the session.

DllCall( "LockWorkStation" )

Sleep, 2000

hw_sla := DllCall( "GetForegroundWindow" )

loop,
{
	Sleep, 1000

	hw_fg := DllCall( "GetForegroundWindow" )
	
	if ( hw_fg != 0 )
		break 
}

MsgBox, window handle identified while workstation was locked = %hw_sla%
ExitApp

An alternative is to monitor "WM_WTSSESSION_CHANGE" messages. However, this functionality is only available with Windows XP or Windows Server 2003

hw_ahk := FindWindowEx( 0, 0, "AutoHotkey", a_ScriptFullPath " - AutoHotkey v" a_AhkVersion )

WM_WTSSESSION_CHANGE = 0x02B1
OnMessage( WM_WTSSESSION_CHANGE, "HandleMessage" )

NOTIFY_FOR_THIS_SESSION = 0
result := DllCall( "Wtsapi32.dll\WTSRegisterSessionNotification", "uint", hw_ahk, "uint", NOTIFY_FOR_ALL_SESSIONS )

if ( ! result )
{
	MsgBox, WTSRegisterSessionNotification has failed!
	
	ExitApp
}

DllCall( "LockWorkStation" )
return

HandleMessage( p_w, p_l, p_m, p_hw )
{
	WTS_SESSION_LOCK	= 0x7
	WTS_SESSION_UNLOCK	= 0x8

	static text
	
	if ( p_w = WTS_SESSION_LOCK )
		text = %text%`nsession has been locked
	else if ( p_w = WTS_SESSION_UNLOCK )
		text = %text%`nsession has been unlocked
	
	ToolTip, %text%, 100, 100
}

FindWindowEx( p_hw_parent, p_hw_child, p_class, p_title )
{
	return, DllCall( "FindWindowEx", "uint", p_hw_parent, "uint", p_hw_child, "str", p_class, "str", p_title )
}

Thanks a bunch...


Hope one of the methods described above works for you.

Marcus
  • Members
  • 188 posts
  • Last active: Dec 06 2011 11:46 PM
  • Joined: 13 May 2005
Wow.

Thank you for your coding work here. Looks like it was quite a challenge...

I'll give it a whirl, and see what happens.

Maybe Chris could incorporate the gist of these codeblocks into the next ahk release :wink:

Thank you again, shimanov!

In^Xanity
  • Guests
  • Last active:
  • Joined: --
On the surface, shimanov's code appears to be exactly what I need. But, even though the code executes, it has no effect. Perhaps one of you guru's out there can figure out what I am missing.

#Persistent
#SingleInstance FORCE

	hw_ahk := FindWindowEx( 0, 0, "AutoHotkey", a_ScriptFullPath " - AutoHotkey v" a_AhkVersion )

	WM_WTSSESSION_CHANGE = 0x02B1
	OnMessage( WM_WTSSESSION_CHANGE, "HandleMessage" )

	NOTIFY_FOR_THIS_SESSION = 0
	result := DllCall( "Wtsapi32.dll\WTSRegisterSessionNotification", "uint", hw_ahk, "uint", NOTIFY_FOR_ALL_SESSIONS )

	if ( ! result )
	{
	   MsgBox, WTSRegisterSessionNotification has failed!
	   
	   ExitApp
	}


return  ;**** END AUTOEXEC

	HandleMessage( p_w, p_l, p_m, p_hw )
	{
		WTS_SESSION_LOCK   = 0x7
		WTS_SESSION_UNLOCK   = 0x8
		Static CapsState
	   
		if ( p_w = WTS_SESSION_LOCK )
		{
			GetKeyState, CapsState, CapsLock, T
			Sleep 2000
			; if CapsState = D
			SetCapsLockState, Off
		}
		else if ( p_w = WTS_SESSION_UNLOCK )
		{
			Sleep 2000
			if CapsState = D
				SetCapsLockState, On
		}
	}

	FindWindowEx( p_hw_parent, p_hw_child, p_class, p_title )
	{
		return, DllCall( "FindWindowEx", "uint", p_hw_parent, "uint", p_hw_child, "str", p_class, "str", p_title )
	}
	
Return

The gist of the code is to turn off CapsLock whenever the computer is locked (by Win+L, inactivity, whatever) and set it back to it's previous state once the user has unlocked the computer. The unlock bit works, but even though the code executes, CapsLock remains on when the computer locks.

Below is the log of executed lines, including comments.

004: hw_ahk := FindWindowEx( 0, 0, "AutoHotkey", a_ScriptFullPath " - AutoHotkey v" a_AhkVersion )
045: Return,DllCall( "FindWindowEx", "uint", p_hw_parent, "uint", p_hw_child, "str", p_class, "str", p_title )
006: WM_WTSSESSION_CHANGE = 0x02B1
007: OnMessage( WM_WTSSESSION_CHANGE, "HandleMessage" )  
009: NOTIFY_FOR_THIS_SESSION = 0
010: result := DllCall( "Wtsapi32.dll\WTSRegisterSessionNotification", "uint", hw_ahk, "uint", NOTIFY_FOR_ALL_SESSIONS ) (0.03)
012: if ( ! result )  
020: Return (6.72)
;; Auto Exec section ends

;; Computer Locked
024: WTS_SESSION_LOCK = 0x7
025: WTS_SESSION_UNLOCK = 0x8
028: if ( p_w = WTS_SESSION_LOCK )  
030: GetKeyState,CapsState,CapsLock,T
031: Sleep,2000 (2.00)
033: SetCapslockState,Off                                 ;; Executed with no effect
034: }
041: } (9.20)

;;Computer unlocked
024: WTS_SESSION_LOCK = 0x7
025: WTS_SESSION_UNLOCK = 0x8
028: if ( p_w = WTS_SESSION_LOCK )  
035: if ( p_w = WTS_SESSION_UNLOCK )  
037: Sleep,2000 (2.00)
038: if CapsState = D
039: SetCapslockState,On
040: }
041: } (1117.41)


wto605
  • Members
  • 2 posts
  • Last active: Sep 25 2008 08:07 AM
  • Joined: 25 Sep 2008
Hello,

I actually made this script using another script as a reference for a working implementation of this code. I figured since I had landed here a lot in trying to accomplish this I'd post my result here. For the inspiration and perhaps to get a bit more out of what is going on look here http://www.autohotke.../topic9384.html

This works in the same way that does, by a separate script file. However, in the event of a lock or unlock it calls functions in the main script file.

The actual file is notifylockunlock.ahk
;--------------------------------------------------------------- 
;Notify Lock\Unlock
;	This script monitors LockWorkstation calls
;
;	If a change is detected it 'notifies' the calling script
;		On Lock
;			This script will call function "on_lock()"
;		On Unlock
;			This script will call fucntion "on_unlock()"
;IMPORTANT: The functions "on_lock()" and "on_unlock()" DO NOT
;exist in this script, they are to be created in the script that
;calls notify_lock_unlock() (presumably your main script)
;---------------------------------------------------------------
;Re-purposed by WTO605
;Last edited 2009-08-18 16:34 UTC
;---------------------------------------------------------------
;Based on Winamp_Lock_Pause by MrInferno
;Posted: Fri Apr 21, 2006 4:49 am
;Source: http://www.autohotkey.com/forum/topic9384.html
;---------------------------------------------------------------
;Winamp_Lock_Pause was/is based on script codes from "shimanov"
;Posted: Thu Sep 15, 2005 12:26 am   
;Source: http://www.autohotkey.com/forum/viewtopic.php?t=5359
;Posted: Tue Dec 06, 2005 9:14 pm
;Source: http://www.autohotkey.com/forum/viewtopic.php?t=6755
;---------------------------------------------------------------

;Initialize global constants
WTS_SESSION_LOCK		:=	0x7
WTS_SESSION_UNLOCK		:=	0x8
NOTIFY_FOR_ALL_SESSIONS	:=	1
NOTIFY_FOR_THIS_SESSION	:=	0
WM_WTSSESSION_CHANGE	:=	0x02B1

notify_lock_unlock()
{
	Global WM_WTSSESSION_CHANGE
	Global NOTIFY_FOR_ALL_SESSION

	hw_ahk := FindWindowEx( 0, 0, "AutoHotkey", a_ScriptFullPath " - AutoHotkey v" a_AhkVersion ) 

	OnMessage( WM_WTSSESSION_CHANGE, "Handle_WTSSESSION_CHANGE" ) 

	success := DllCall( "wtsapi32.dll\WTSRegisterSessionNotification", "uint", hw_ahk, "uint", NOTIFY_FOR_ALL_SESSIONS )

	if( ErrorLevel OR ! success ) 
	{
		success := DllCall( "wtsapi32.dll\WTSUnRegisterSessionNotification", "uint", hw_ahk )
		;If DLL registration fails, wait 20 seconds and try again
		Sleep, 20000
		notify_lock_unlock()
		;MsgBox, [WTSRegisterSessionNotification] failed: EL = %ErrorLevel%
	}
	return
}

Handle_WTSSESSION_CHANGE( p_w, p_l, p_m, p_hw )
; p_w  = wParam   ;Session state change event
; p_l  = lParam   ;Session ID
; p_m  = Msg   ;WM_WTSSESSION_CHANGE
; p_hw = hWnd   ;Handle to Window
{
	Global WTS_SESSION_LOCK
	Global WTS_SESSION_UNLOCK

	If ( p_w = WTS_SESSION_LOCK ) 
	{
		on_lock()
	}
	Else If ( p_w = WTS_SESSION_UNLOCK ) 
	{
		on_unlock()
	}
}

FindWindowEx( p_hw_parent, p_hw_child, p_class, p_title ) 
{
	return, DllCall( "FindWindowEx", "uint", p_hw_parent, "uint", p_hw_child, "str", p_class, "str", p_title ) 
}

to use it put that file in your my documents folder and add this to the beginning of your main script
#include %A_ScriptDir%\notifylockunlock.ahk
notify_lock_unlock()
; Calls function "on_lock()" when computer is locked and "on_unlock()" when computer is unlocked

You will also need to add a function "on_lock()" and "on_unlock()" somewhere (either in an included file or the main file). Even if you don't want to use one of them the must be defined. For example:
on_lock()
{
	; do nothing
}

on_unlock()
{
	msgbox You have unlocked your computer.
}

Hopefully this is helpful for you, and if not then hopefully it's helpful for other people who search this.

Thanks,
Will