Automated Screenshots and Quake-Style Console Popups with Autohotkey

This post is mostly a response to Silver2Falcon on the XCKD forums, but I’m putting it here in case anyone else is interested.

Here’s the other cool thing I’m running: the awesome and venerable AutoHotkey. I’ve got it doing a couple of neat tricks. First, when I hit Windows Key + PrtSc, it A) takes a screenshot, B) makes a copy of that screenshot and resizes it down to 500px wide, and C) dumps both of them into my Inbox folder on my desktop.

But the really neat trick is the console command line. If I hit Windows Key + Tilde, the command prompt comes up as if it were a Quake-style console. When I hit Esc, it hides until I hit Windows Key + Tilde again.

Would you mind posting/PMing me the scripts for those? You’ve just reminded me that program exists and I want to do both of those and more and I have never really done anything in AHK and I don’t have time to write anything up myself at the moment.

Sure. They both take a little setting up, but I find that they’re both useful enough to be worth the effort.

I’ve uploaded my Autohotkey script so that you can easily tweak and edit as desired, but I’ve also included the relevant bits of code in the instructions below.

Step 0: Obviously, install AutoHotkey if you haven’t already.

Automated Screenshots

I originally found the inspiration for this part of the script on the official AutoHotkey forums. I just tweaked it to make it more efficient for my workflow.

Step 1: Download the GDIPlusHelper.ahk script to your AutoHotkey program folder (typically C:\Program Files\AutoHotkey\).

Step 2: Copy the following into your AutoHotkey script file, at the top. We’ll tweak it a bit in the next step.

#Include GDIPlusHelper.ahk
#Include GDIPlusHelper.ahk

OnExit, handle_exit

main:
  SetWorkingDir C:\Users\Jeremy\Desktop\Inbox

  WinGet, hw_frame, id, "Program Manager"   ; Desktop ?
  hdc_frame := DllCall( "GetDC", "uint",  hw_frame )
  hdc_frame_full := DllCall( "GetDC", "uint",  hw_frame )
  counter:=0   ; thumbnails
  counter_f:=0   ; fullscreens
  thumb_w:= 500
  thumb_h:= ceil( thumb_w * A_ScreenHeight / A_ScreenWidth ) ; keep screenratio
  use_antialize := 1
 

  ; buffer
  hdc_buffer := DllCall( "gdi32.dll\CreateCompatibleDC"     , "uint", hdc_frame )
  hbm_buffer := DllCall( "gdi32.dll\CreateCompatibleBitmap" , "uint", hdc_frame, "int", 

thumb_w, "int", thumb_h )
  r          := DllCall( "gdi32.dll\SelectObject"           , "uint", hdc_buffer, "uint", 

hbm_buffer )

  hdc_buffer_full := DllCall( "gdi32.dll\CreateCompatibleDC"     , "uint", hdc_frame_full )
  hbm_buffer_full := DllCall( "gdi32.dll\CreateCompatibleBitmap" , "uint", hdc_frame_full, 

"int", A_ScreenWidth, "int", A_ScreenHeight )
  r_full          := DllCall( "gdi32.dll\SelectObject"           , "uint", hdc_buffer_full, 

"uint", hbm_buffer_full )

  ; comment this line for speed but less quality
  if use_antialize = 1
    DllCall( "gdi32.dll\SetStretchBltMode", "uint", hdc_buffer, "int", 4 )  ; Halftone better 

quality with stretch

return

#SC137:: ; Windows Key + Print Screen
SaveImage:
  counter := counter +1
  FormatTime, myTime, , yyyyMMdd_hhmmss
  fileNameDestP = SMALL-T_%myTime%_%counter%_%thumb_w%x%thumb_h%.png

  If (GDIplus_Start() != 0)
     Goto GDIplusError

  ; Copy BMP from DC
  DllCall( "gdi32.dll\StretchBlt"
          , "uint", hdc_buffer, "int", 0, "int", 0, "int", thumb_w, "int", thumb_h
          , "uint", hdc_frame,  "int", 0, "int", 0, "int", A_ScreenWidth, "int", 

A_ScreenHeight, "uint", 0x00CC0020 )

  DllCall( "GDIplus\GdipCreateBitmapFromHBITMAP", uint, hbm_buffer, uint, 0, uintp, bitmap )

  ; Save to PNG

  If (GDIplus_GetEncoderCLSID(pngEncoder, #GDIplus_mimeType_png) != 0)
     Goto GDIplusError

  noParams = NONE
  If (GDIplus_SaveImage(bitmap, fileNameDestP, pngEncoder, noParams) != 0)
     Goto GDIplusError
   Gosub GDIplusStop
;Return

SaveImage_Full:
  counter_f := counter_f +1
  FormatTime, myTime, , yyyyMMdd_hhmmss
  fileNameDestP = FULL-S_%myTime%_%counter_f%_%A_ScreenWidth%x%A_ScreenHeight%.png
  If (GDIplus_Start() != 0)
     Goto GDIplusError

  ; Copy BMP from DC
  DllCall( "gdi32.dll\BitBlt"
          , "uint", hdc_buffer_full, "int", 0, "int", 0, "int", A_ScreenWidth, "int", 

A_ScreenHeight
          , "uint", hdc_frame_full,  "int", 0, "int", 0, "uint", 0x00CC0020 )

  DllCall( "GDIplus\GdipCreateBitmapFromHBITMAP", uint, hbm_buffer_full, uint, 0, uintp, 

bitmap )

  ; Save to PNG

  If (GDIplus_GetEncoderCLSID(pngEncoder, #GDIplus_mimeType_png) != 0)
     Goto GDIplusError

  noParams = NONE
  If (GDIplus_SaveImage(bitmap, fileNameDestP, pngEncoder, noParams) != 0)
     Goto GDIplusError
   Gosub GDIplusStop
Return

GDIplusError:
GDIplusStop:
   If (#GDIplus_lastError != "")
      MsgBox 16, GDIplus Test, Error in %#GDIplus_lastError%
   GDIplus_Stop()
Return

#q::
handle_exit:
   DllCall( "gdi32.dll\DeleteObject", "uint", hbm_buffer )
   DllCall( "gdi32.dll\DeleteDC"    , "uint", hdc_frame )
   DllCall( "gdi32.dll\DeleteDC"    , "uint", hdc_buffer )
ExitApp

Step 3: Change the line SetWorkingDir C:\Users\Jeremy\Desktop\Inbox to be SetWorkingdir and the folder you want your screenshots saved in.

Step 4: If you want to change the size of the thumbnails, change the line thumb_w:= 500 from 500 pixels to the desired number of pixels wide. By default, this script will keep the aspect ratio the same for you.

Step 5: Reload your autohotkey script and hit Windows-Key + PrtSc. In the folder you selected, there should appear two PNG files, one a full-sized version of the screenshot and one a 500 pixel wide thumbnail.

Quake-Style Console

Mostly made by paraxion over at Instructables, where you’ll find the step-by-step guide to how this was originally programmed. This I tweaked to handle both the Windows Command Prompt (Windows Key+Tilde) and the Unix emulator Cygwin (Windows Key+Shift+Tilde).

Step 1: Install Console, a configurable open-source console manager for Windows.

Step 2: Save the following console.xml and consolecyg.xml files to the Console program folder (typically C:\Program Files\Console\)

Step 3: Create shortcuts in your Windows folder named “console” and “consolecyg.” Console should just be a regular shortcut to C:\Program Files\Console\Console.exe. consolecyg should link to "C:\Program Files\Console\console.exe" consolecyg.xml

Step 4: Copy the following into your AutoHotkey script file, after the previous script.

; Launch console if necessary; hide/show on Win+`
#`::
DetectHiddenWindows, on
IfWinExist ahk_class Console Main Command Window
{
	IfWinActive ahk_class Console Main Command Window
	  {
			WinHide ahk_class Console Main Command Window
			; need to move the focus somewhere else.
			WinActivate ahk_class Shell_TrayWnd
		}
	else
	  {
	    WinShow ahk_class Console Main Command Window
	    WinActivate ahk_class Console Main Command Window
	  }
}
else
	Run console

DetectHiddenWindows, off
return

; Launch console if necessary; hide/show on Win+Shift+`
#+`::
DetectHiddenWindows, on
IfWinExist ahk_class Console Main Command Window
{
	IfWinActive ahk_class Console Main Command Window
	  {
			WinHide ahk_class Console Main Command Window
			; need to move the focus somewhere else.
			WinActivate ahk_class Shell_TrayWnd
		}
	else
	  {
	    WinShow ahk_class Console Main Command Window
	    WinActivate ahk_class Console Main Command Window
	  }
}
else
	Run consolecyg

DetectHiddenWindows, off
return

; hide console on "esc".
#IfWinActive ahk_class Console Main Command Window
esc::
 {
   WinHide ahk_class Console Main Command Window
   WinActivate ahk_class Shell_TrayWnd
 }
return

Step 5: Reload your autohotkey script and hit Win+~. This should pop up a standard-issue command prompt at the top of your screen, as if it were a Quake console.

Step 6: Hit Esc. This should hide the console until you hit Win+~ again.

Step 6: In the console, type “exit” and hit enter. Then hit Win+Shift+~ to open Cygwin (assuming that you have cygwin installed to the default location; if not, you’ll need to tweak the xml file linked in step 2.)

Step 7: Again, hit Esc to hide, hit Win+~ to reopen, and type “exit” to close the program entirely.

That should get you up and running. Let me know if you have any questions or comments.

Comments are closed.