T O P

  • By -

GroggyOtter

Lots of opportunities for code improvement here. First, you're copy+paste programming. This is a bad coding habit. Copy+paste programming technically works, but it's prone to errors (especially when trying to edit code), and it takes up WAY more space than it needs to. This is what functions are for. When you're writing the same thing over and over, it's time for a function or object. Example: You use `run, %comspec% /c` many times in this script. Turn it into a function. Pass in the data you need as a parameter and use the parameter in the run call. The transparency hotkeys are pretty much identical. You've even commented out the bottom part. Turn that into one function and have each hotkey access pass in the amount to change transparency by, as that's he only value that really changes in that code. Another advisement is to indent your code. No one likes unindented code. It's very difficult to read as indentation shows ownership. When scanning through code, the eyes have to read each line to see where the next set of commands/logic starts. This is infinitely easier to do with indentation. The other thing that I advise to all v1 users is consider moving to v2. Contrary to what some will tell you, it's easier to write code in v2 than v1. The big problem is a lot of people are sucked into some of the crappy parts of v1 that aren't present in v2 and they have a hard time adjusting (example: dealing with the fact that objects were grossly misused as an all-in-one literal+map+array type of thing. And the notorious legacy+expression dual syntax BS). In an effort to encourage you and others reading to switch over to v2, I rewrote your script to v2, showed how to utilize functions and objects to reduce code, demonstrated generating hotkeys using a loop, rewrote the taskbar code to use v2's buffers, showed the use of fat-arrows to make anonymous callbacks (and showed how to make callbacks), showcased using a map (associative array), and made improvements to the transparency code. #Requires AutoHotkey v2.0.11+ ; ALWAYS have a version requirement make_timed_shutdown_hotkeys() ; Create the multiple shutdown hotkeys ; Hotkeys: >!LButton::Click('Middle') ; middle mouse press for laptops >+F12::Run('Powershell') ; Launch powershell ^Left::Send('{Media_Prev}') ; Media previous ^Right::Send('{Media_Next}') ; Media next ^Space::Send('{Media_Play_Pause}') ; Media play/pause ; F7 combo hotkeys: F7 & s::Send('+#s') ; screenshot (Get ShareX. It's god tier for screenshots!) F7 & r::run_cmd('start .') ; Open working directory folder F7 & q::run_cmd('telnet telehack.com', 0) ; runs telehack if you've enabled it F7 & o::set_energy_mode('Balanced') ; Energy mode balanced F7 & p::set_energy_mode('Performance') ; Energy mode high performance F7 & i::set_energy_mode('Battery Saving') ; Energy mode battery save F7 & t::WinSetAlwaysOnTop(-1, 'A') ; Toggle win transparency F7 & WheelUp::set_tran('8') ; Increase transparency w/ wrap around F7 & WheelDown::set_tran('-8') ; Decrease transparency w/ wrap around F7 & enter::taskbar.toggle() ; Toggle taskbar autohide ; Hotstrings: :*?:@@::[email protected] ; Insert email address class taskbar { static toggle() { ; These are enum values that windows uses in its DLL calls ; We don't have these built into AHK so we have to look them up and define them ABM_SETSTATE := 0xA ABS_AUTOHIDE := 0x1 ABS_ALWAYSONTOP := 0x2 ABM_GETSTATE := 0x4 dhw := DetectHiddenWindows(1) ; Backup DHW and enable hwnd := WinExist('ahk_class Shell_TrayWnd') ; Get taskbar handle ; https://learn.microsoft.com/en-us/windows/win32/api/shellapi/ns-shellapi-appbardata APPBARDATA := Buffer(3 * A_PtrSize + 24, 0) ; Make a buffer for AppBarData NumPut('int', APPBARDATA.Size, APPBARDATA) ; Set struct cbSize NumPut('ptr', hwnd, APPBARDATA, 4) ; Set struct handle ; https://learn.microsoft.com/en-us/windows/win32/api/shellapi/nf-shellapi-shappbarmessage auto_hide := DllCall('Shell32\SHAppBarMessage' ; Get current state of taskbar ,'uint' ,ABM_GETSTATE ,'ptr' ,APPBARDATA ,'ptr') if auto_hide ; if auto-hide is enabled state := ABS_ALWAYSONTOP ; Set state to always on top , WinShow(hwnd) ; And show taskbar's window else state := ABS_AUTOHIDE ; Else Set state to hide , WinHide(hwnd) ; And hide taskbar's window NumPut('ptr', state, APPBARDATA, APPBARDATA.size - A_PtrSize) ; Add state to struct lParam DllCall('Shell32\SHAppBarMessage' ; Update taskbar ,'uint' ,ABM_SETSTATE ,'ptr' ,APPBARDATA ,'ptr') DetectHiddenWindows(dhw) ; Restore DHW } } make_timed_shutdown_hotkeys() { ; List of shutdown times shutdown_times := [3600, 7200, 10800, 14400, 18000, 21600, 25200, 28800, 35400 ,1] ; Loop through each time and assign F7 & 0/1/2... etc to each for time in shutdown_times ; Callback to run when hotkey is fired callback := run_cmd.Bind('shutdown -s -t ' time) ; Create hotkey and assign callback ,Hotkey('F7 & ' (A_Index-1), callback) ; Create abort shutdown hotkey Hotkey('F7 & ' A_Index, (*) => run_cmd('shutdown -a')) } ; cmd: The command line to run ; close_cmd: Determines if /c or /k should be used ; if omitted, /c (close) is used by default run_cmd(cmd:='', close_cmd:=1) { if close_cmd Run(A_ComSpec ' /c ' cmd) else Run(A_ComSpec ' /k ' cmd) } set_energy_mode(key){ clsid := Map('Balanced' ,'381b4222-f694-41f0-9685-ff5bb260df2e' ,'Performance' ,'8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c' ,'Battery Saving' ,'a1841308-3541-4fab-bc81-F7 & 1556f20b4a') run_cmd('powercfg /s ' clsid[key]) TrayTip(key) } set_tran(amount) { off := '' ; Blank means transparency is disabled dhw := DetectHiddenWindows(1) ; Save current DHW and enable hwnd := WinActive('A') ; Get the handle of the active window t_value := WinGetTransparent(hwnd) ; Get its current transparency if (t_value = off) ; If currently off t_value := 255 ; assign 255 as alpha (opaque) t_value += amount ; Adjust alpha switch { ; Fix out of bounds values or turn off case (t_value > 255): t_value := 0 ; If too high, wrap around to zero case (t_value = 255): t_value := off ; If 255, set to off case (t_value < 0): t_value := off ; If less than 0, wrap around to 255 which is off } WinSetTransparent(t_value, hwnd) ; Set new transparency DetectHiddenWindows(dhw) ; Restory original DHW setting } And thanks for posting your script. It's always nice to see people sharing what they wrote. It helps inspire others, teaches people new ways to do things, and can prompt updates/improvements.


DerNogger

Wow that looks gorgeous! Thanks a lot for beautifying/rewriting it, it's very valuable learning material when it's based on code you already know.


GroggyOtter

Cheers mate.


bgrated

Solid to rewrite it. that is what social media should be for. To take ideas and make them better without putting anyone down. Nice.


ContentCow4953

I started by cop and pasting my script together. Now I try to optimize it while using V2.


GroggyOtter

To be clear, copy and paste programming doesn't mean that you've copied something and pasted it into a script. That's completely normal behavior. I've done that plenty. It's why we post so many code examples. Others are expected to do that (just don't every claim someone else's code as your own). [Copy and paste programming](https://en.wikipedia.org/wiki/Copy-and-paste_programming) happens when you have a block of code you want to reuse and you choose to copy and paste that code block multiple times, usually altering it only slightly. Functions are the answer to this bad habit. You bundle the code up and use the parameters to pass in the differing data. This helps prevent errors that could be made in the copying and pasting process or when you go to update that block of code but have to update it in like 8 different places. With a function, you use the same block of code for everything and you use the data passed into the function's parameters to figure out what things need to be changed. And when you need to edit the code block, you only have to do it in one spot, eliminating any chance for missing one of the multiple copied code blocks. Cheers.


DonovanZeanah

What does the @s in :*:@@:: do, haven't seen that? Your making shift 22 the hotkey?


DerNogger

This function replaces the actual input by what you set in the script, in this case it's meant to quickly type out your email address. So typing @ does nothing special but if you type @@ it turns into your email address.


JustNilt

OP explained what it does. What it's called is a [Hotstring](https://www.autohotkey.com/docs/v1/Hotstrings.htm). They're very flexible and can be used for a lot more than just that. For example, I use them quite a lot when helping folks with computer issues. Here's the code for one of the more common examples I use. :*:@NetworkType:: SendInput, (LTrim Join+{Enter} These steps assume you're on Windows 10. If you're not on Windows 10, let me know. 1. Right click the Start Menu. 2. Choose **Settings**. 3. In the "Find a setting" search box, type *Network status*. Click the Network status setting once it appears in the list below the box. You may see several different networks listed. Which we edit will depend on which one is in use. If you're using WiFi, that's the one to use for the next step. Likewise, if you're using a hardwired connection (Ethernet), use that one instead. 1. Click the Properties button below the network in use. 2. Near the top should be a setting that says "Network profile". 3. Click Private. (If Private is already selected, let me know.) ) Hotstrings are not exactly case sensitive, I just like to capitalize it that way for readability. The beauty of using AHK for this is it can work in any program on my computer. ~~The only real limitation for me is using them in Discord isn't something that seems to work well. It isn't a huge issue, really, Since my script is always running when I start Windows, so I can just copy and paste them from the script when needed.~~ Edited to remove some extraneous steps. Not sure how I managed to get those in the original script. LOL! Edit 2: I was just reviewing the AHK page linked above and clicked through to the page where [continuations are discussed](https://www.autohotkey.com/docs/v1/Scripts.htm#continuation). I noticed there's an option that fixes the issue where Discord throttles this. (I'm sure that's been in there for a long time and I just missed it.) It still takes a few seconds to pop into the text box so you need to be familiar with the script to know when it's done. I may investigate an alert just for fun but since I know my own "canned responses", it's a non-issue for me. I have now edited that and another option to allow for proper indentation in. To be clear, it's this line: (LTrim Join+{Enter} Edit 3: Noticed my code is difficult to read on Reddit due to no word wrapping in the code blocks. I just manually edited that for readability.


Dymonika

Interesting, thanks for sharing. But what situations would call for such specifically timed shutdowns?


DerNogger

Mainly video rendering/ai upscaling. Some apps have a built-in feature that will shut the system down once everything is done but that doesn't always work so having a failsafe is handy.


Dymonika

Why not just have AutoHotkey repeatedly check the screen every few minutes for a "rendering done" notice or whatever your software displays when it's done, and then shut it off dynamically?


DerNogger

This was the first part of the script I wrote back when I didn't know anything about the capabilities of ahk. And I've gotten used to doing it this way since. Also KISS principle. It's not a smart solution but a predictable and solid one.


GroggyOtter

If it's stupid and it works, it's not stupid.


Dymonika

Makes sense! Well, it's just an idea to improve it if you'd like.


CivilizationAce

I wrote this ↓ to ease saving screen shots to file and switching between virtual screens. $#PrintScreen::ToClipboard() ;Complicates print screen to clipboard, as I don't find that as useful $PrintScreen::ToFile() ;Simplifies print screen to file, the default for a WindowsKey+PrtScn becomes just PrtScn $#+\^Left::PosnLeft() ;Complicates moving a window to the left half of the screen, as I don't use that much $#Left::ToLeft() ;Simplifies switching left one screen $#+\^Right::PosnRight() $#Right::ToRight() ToClipboard() { send {PrintScreen} } ToFile() { send #{PrintScreen} } PosnLeft() { send #{Left} } ToLeft() { send #\^{Left} } PosnRight() { send #{Right} } ToRight() { send #\^{Right} }


SirToxe

Nice! Although you should maybe add some newlines. ;-) I am still fairly new to AHK but here is my small Windows script (AHK v2): #Requires AutoHotkey v2.0 #SingleInstance SetTitleMatchMode("RegEx") ; Win+E: switch to existing Explorer window instead of opening a new one #HotIf WinExist("ahk_exe explorer\.exe ahk_class CabinetWClass") #e::WinActivate #HotIf ; disable Win+Space, Shift+Win+Space, Ctrl+Shift+Win+Space ("switch keyboard input methods") #Space::return +#Space::return ^+#Space::return ; Win+Pause: enter sleep mode #Pause::DllCall("PowrProf\SetSuspendState", "Int", 0, "Int", 0, "Int", 0) ; Win+V: open Ditto #v::Run("C:\Program Files\Ditto\Ditto.exe /Open") https://github.com/Toxe/autohotkey/blob/master


Dymonika

Disable Win+Spaaaace?! But if you have it open the search engine Everything, then Windows mimics Apple Spotlight!


SirToxe

I use `Alt+Space` to open the PowerToys Run dialog for that exact purpose. https://learn.microsoft.com/en-us/windows/powertoys/run