Sign in to follow this  
Followers 0
MilesAhead

Trick to get name of current function?

31 posts in this topic

#1 ·  Posted (edited)

I have a function to pass on a hotkey by temporarily disabling as shown in the help

Func _PassKey($funcname, $hKey = @HotKeyPressed)
HotKeySet($hkey)
Send($hkey)
HotKeySet($hkey, $funcname)
EndFunc   ;==>_PassKey

I use @HotKeyPressed to get the hotkey. I was just wondering if there's a macro or trick to get the current function name? Instead of having to enter _PassKey("MyFuncName") or use a variable I'd like to be able to just call it as _PassKey() and have it pick up both the hotkey and the name of the func it was called from. Something like:

Func _PassKey($funcname = @CallingFunc, $hKey = @HotKeyPressed)

??

Edited by MilesAhead

Share this post


Link to post
Share on other sites



You want to know where is the script at the moment of the hotkey was pressed? use variables to figure out

Just a demonstration scheme

Global $FunctionName
;...
;...
Func a()
$FunctionName = "a"
;....
;...
EndFunc
Func b()
$FunctionName = "b"
;....
;...
EndFunc
Func c()
$FunctionName = "c"
;....
;...
EndFunc
Func What()
$FunctionName = "What"
consolewrite($FunctionName&@crlf)
;....
;...
EndFunc

Share this post


Link to post
Share on other sites

I was just hoping for something like a macro to tell me the enclosing function without having to paste in the name. I could make a wrapper function for HotkeySet and store the function name in an assoc array with hotkey as key. But it's not really worth it I suppose. Just looking for a way to avoid the tedium of copy and paste of the current function name. It would just be a convenience. Instead of calling my function _PassKey("Function_I_Am_in_now") I could then just use _PassKey() for everything.

Looks like there isn't anything without using a variable.

Share this post


Link to post
Share on other sites

Probably would be a convenient macro, but as I've read in past threads, the developers are not fond of adding these kind of things when its easy enough to do yourself.

If you already have a large script you wish to add this too, another small script could do that for you.


AutoIt Absolute Beginners    Require a serial    Pause Script    Video Tutorials by Morthawt   ipify 

Monkey's are, like, natures humans.

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

Posted some code but it looks a mess. I'll post later after more debug maybe. But anyway, I could get to calling _PassKey() with no params by testing for a global with IsDeclared then using Eval to get the value of the hotkey function name. Ok for single hotkey function apps.

Edited by MilesAhead

Share this post


Link to post
Share on other sites

I decided to keep it simple. Just added a bit of error checking and return of 0 on fail and 1 on success.

; _PassKey() : Temporarily disables a hotkey, sends
; the key, then enables again.
;
; Returns 0 if either param is blank.
;
; Otherwise Returns the result of the HotKeySet()
; attempt to reset the hotkey.
;
Func _PassKey($funcName, $hKey = @HotKeyPressed)
    If $funcName = "" Or $hKey = "" Then
        Return 0
    EndIf
    HotKeySet($hKey)
    Send($hKey)
    Return HotKeySet($hKey, $funcName)
EndFunc   ;==>_PassKey

Share this post


Link to post
Share on other sites

Nice and clean... was necessary to disable the hotkey? I am asking because i never have that problem.

Share this post


Link to post
Share on other sites

#8 ·  Posted (edited)

In this case I was coding a little hack to make a new folder when pressing F7 function key. I check for Explorer and Desktop class names. But if none of those are the active window I wanted to pass the key on so that spell checkers in editors that often use F7 and FreeCommander, which already uses F7 for new folder, wouldn't be hosed. Then I noticed the note in the help about deactivating and using Send. Seems to work quite well.

On Windows Seven it just sends the built in Control-Shift-n. On Vista it does macro to use the New=>Folder in context menu on the desktop. Inside a folder it just does InputBox to ask you for the folder name then appends it to the path of the containing folder. It's just nice to get a new folder pressing one key instead of messing around.

From using FreeCommander for a long time I'm used to pressing F7 to get a new folder. But I don't use FC for everything. I do a lot with Explorer. Esp. since I found QTTabBar to get Explorer with tabs. That helps a lot.

:mellow:

Edited by MilesAhead

Share this post


Link to post
Share on other sites

Nice and clean... was necessary to disable the hotkey? I am asking because i never have that problem.

btw, if you have a better technique to let the hotkey pass through please share it. Is there a way to avoid "eating" the key without getting an endless loop?

Share this post


Link to post
Share on other sites

#10 ·  Posted (edited)

This is working for me.... :mellow: whitout shutdown the hotkey...

HotKeySet("{F2}", "_NewFolder")
 
While True
    Sleep(50)
WEnd
 
Func _NewFolder()
    WinActivate("[CLASS:CabinetWClass]")
    Send("^+n")
EndFunc
Edited by monoscout999

Share this post


Link to post
Share on other sites

@monoscout999

You need a new monocle if you think "{F2}" and "^+n" is THE SAME key :mellow:

btw, if you have a better technique to let the hotkey pass through please share it.

I don't think he has...

Share this post


Link to post
Share on other sites

#12 ·  Posted (edited)

@monoscout999

You need a new monocle if you think "{F2}" and "^+n" is THE SAME key :mellow:

I don't think he has...

I did´t undertand before... now i see... O.O Is endless... but why someone will need to use the same hotkey to activate a function that will send a key that is the same hotkey to activate a....etc.etc. ??

Edited by monoscout999

Share this post


Link to post
Share on other sites

I did´t undertand before... now i see... O.O Is endless... but why someone will need to use the same hotkey to activate a function that will send a key that is the same hotkey to activate a....etc.etc. ??

In AHK it's possible to group a bunch of class names together and then hotkey only be "in effect" if the active window has a class name in the group. For instance, only Explorer Windows. The program doesn't "eat" the key if the active window class name is not in the group. I'm trying to simulate that. I could use AHK to do the program but I prefer AutoIt3 when possible since the variable scoping is better and I can create reusable functions using a more straight-forward syntax. Also I have trouble in AHK trying to get the current folder from the active window without using the clipboard. From experimentation I found how to dig it out using AutoIt StringBetween on Vista and W7 if "show full path in address bar" is active. Also AHK is a bear with window matching due to case sensitivity whereas in AutoIt3 I can just set the WinTitleMatchMode to -3. Simple.

Some things with the mouse are just easier in AHK so often I'll have a "mouse handler" slave app in AHK launched by my main AutoIt3 app just to send a keyboard hotkey when it detects the mouse hotkey. Using multiple tools a la Linux mentality. :mellow:

Anyway, probably the way the hotkey is implemented(just guessing) it's not simple to screen out class names in the detection code. So I'm trying to generalize the hack shown in the help file.

Share this post


Link to post
Share on other sites

I am still don´t get it. what has to do the infinite loop with the window that accepts the hotkey? and more important, why define as HotKey a Key that is being used by another window?

Getting the ClassName is easy...

#include <WinAPI.au3>

HotKeySet("{ESC}", "_Exit")            ; ESC = EXIT THE CODE
HotKeySet("+{F2}", "_NewFolder")    ; SHIFT + F2 = CREATE A NEW FOLDER

While True
    Sleep(50)
WEnd

Func _NewFolder()
    Local $hWin = WinGetHandle("[ACTIVE]")
    Local $sClass = _WinAPI_GetClassName($hWin)
    If $sClass = "CabinetWClass" Then Send("^+n") ; CabinetWClass = Win7 Explorer.
EndFunc

Func _Exit()
    Exit
EndFunc

Share this post


Link to post
Share on other sites

#15 ·  Posted (edited)

I know getting the class name is easy. It's not eating the key if it's not a class of interest that's the issue.

You can't test what class it is until you're in the hotkey handler. Whereas AHK the system does it for you.

I still need a mechanism to pass it on. So far all I've found is the method shown in the help file.

Seems code tags are messed up so I can't post indented code.

Edited by MilesAhead

Share this post


Link to post
Share on other sites

#16 ·  Posted (edited)

I'll just post the Windows Seven part of the function so you can see.

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

Func _MakeNewFolder()

Local $newFolder = "New folder"

Local $title = ""

Local $folder = ""

Local $handle = _WinAPI_GetForegroundWindow()

Local $className = _WinAPI_GetClassName($handle)

If _WinVersion() >= 6.1 Then

If $className = "ExploreWClass" Or $className = "CabinetWClass" _

Or $className = "Progman" Or $className = "WorkerW" Then

Send("^+n") ; <<--- send W7 built in Control-Shift-n for new folder

Return

EndIf

If Not _PassKey("_MakeNewFolder") Then ; <<----- pass the hotkey if Active Window not Explorer or Desktop

_ShowError("Error Resetting Hotkey: " & $hotkey)

EndIf

Return

EndIf

EndFunc

Edited by MilesAhead

Share this post


Link to post
Share on other sites

#17 ·  Posted (edited)

I get it :mellow:

But this code doesn´t work in SciTe, and is using the same method that you use... If you press F1 in the Explorer it will create a new folder, but if you press it in the SciTe windows will create a rare character instead of open the help file :S

#include <WinAPI.au3>
 
HotKeySet("{ESC}", "_Exit") ; ESC = EXIT THE CODE
HotKeySet("{F1}", "_NewFolder") ; F1 = CREATE A NEW FOLDER
 
While True
    Sleep(50)
WEnd
 
Func _NewFolder()
    Local $hWin = WinGetHandle("[ACTIVE]")
    Local $sClass = _WinAPI_GetClassName($hWin)
    If Not $sClass = "CabinetWClass" Then
        HotKeySet("{F1}")
        Send("{F1}")
        HotKeySet("{F1}", "_NewFolder")
    Else
        Send("^+n")
    EndIf
EndFunc   ;==>_NewFolder
 
Func _Exit()
    Exit
EndFunc   ;==>_Exit

Accelerators woks in especific windows, but it trigger a ControlID event instead a function.... :S

Accelerators that triggers functions instead ControlID asociated events... is a good feature to add to AutoIt..

Maybe there is already an API that do that, i will investigate about it

Did you try your method in SciTe and with the F1 Hotkey? try it and see if happend the same to you.

EDIT: The ESC key is also an issue, maybe i press ESC to do some action in a specific window, but instead of trigger that action it will close my script.

Edited by monoscout999

Share this post


Link to post
Share on other sites

#18 ·  Posted (edited)

I did notice that SciTE kept changing to another tab now that you mention it. I took the same approach I was using with Mouse Hotkeys. I launched a slave app in AHK to filter the classes. It and the launching AutoIt3 app use RegisterWindowMessage. The AHK app uses PostMessage and the AutoIt3 handler is the NewFolder function. I removed the _PassKey() calls. So far it works gang busters. I can change the hotkey from the main app by launching the slave with a different command line param.

I tried F7 in PsPad and FreeCommander also SciTE does a "build" which is normal. Only thing is name collisiong but I don't think too many apps are running around named NF2HotKeyHandler.exe. I'll test it a bit more. But I like this approach. I'll just have to come up with a unique message for each pair of apps. Guess I'll have to use a Guid string to guarantee unique string for each pair. I can just recompile the slave app with the Guid string of the particular AutoIt3 app.

I've done this with AHK mouse handlers and it worked fine.

Edited by MilesAhead

Share this post


Link to post
Share on other sites

can you give me an example of how AHK filter the classes... sorry if i ask too much, you are the one that start the topic but i have curiosity about this issue.

Share this post


Link to post
Share on other sites

#20 ·  Posted (edited)

I have no clue how it does it internally. But there's a directive #IfWinActive

Hotkeys below that line in the script are only active when the window that fits the directive is active. In this case it's only active when Explorer Window or the Desktop has the focus. An easy way to do it for several class names is to create a group like the one below:

GroupAdd,DesktopGroup, ahk_class CabinetWClass

GroupAdd,DesktopGroup, ahk_class ExploreWClass

GroupAdd,DesktopGroup, ahk_class Progman

GroupAdd,DesktopGroup, ahk_class WorkerW

and to use the group:

#IfWinActive ahk_group DeskTopGroup

F7::

do stuff

Return

The F7 will only "eat" the key if the active window is in DesktTopGroup

Also you can process the key and still pass it on using a tilde as in

#IfWinActive ahk_group DeskTopGroup

~F7::

do stuff

Return

You can also set the hotkey using a variable and function call rather than hard wiring it.

Edited by MilesAhead

Share this post


Link to post
Share on other sites

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
Sign in to follow this  
Followers 0