"Monitor Off" Key Hook

[Home]   [Puzzles & Projects]    [Delphi Techniques]   [Math topics]   [Library]   [Utilities]




Search WWW

Search DelphiForFun.org

As of October, 2016, Embarcadero is offering a free release of Delphi (Delphi 10.1 Berlin Starter Edition ).     There are a few restrictions, but it is a welcome step toward making more programmers aware of the joys of Delphi.  They do say "Offer may be withdrawn at any time", so don't delay if you want to check it out.  Please use the feedback link to let me know if the link stops working.


Support DFF - Shop

 If you shop at Amazon anyway,  consider using this link. 


We receive a few cents from each purchase.  Thanks


Support DFF - Donate

 If you benefit from the website,  in terms of knowledge, entertainment value, or something otherwise useful, consider making a donation via PayPal  to help defray the costs.  (No PayPal account necessary to donate via credit card.)  Transaction is secure.

Mensa Daily Puzzlers

For over 15 years Mensa Page-A-Day calendars have provided several puzzles a year for my programming pleasure.  Coding "solvers" is most fun, but many programs also allow user solving, convenient for "fill in the blanks" type.  Below are Amazon  links to the two most recent years.

Mensa 365 Puzzlers  Calendar 2017

Mensa 365 Puzzlers Calendar 2018

(Hint: If you can wait, current year calendars are usually on sale in January.)


Feedback:  Send an e-mail with your comments about this program (or anything else).

Search DelphiForFun.org only




Problem Description

Required: A program which will turn off the computer screen whenever a specific key is pressed, regardless of the active program at the time. 

Background & Techniques

We recently bought a new weather station (Oregon Scientific WMR968) that will display current weather on a small LCD display console but can also connect to a PC to display weather info.   I took an old Dell Latitude out of retirement and put it to work for this purpose.  It works nicely sitting on a bookshelf in one corner of the room.  A program called Virtual Weather not only displays weather conditions but also collects history and builds web pages that can be called up from any computer  in the house.  

I wanted a way to turn the monitor off overnight but the program needs to keep running to capture weather history data.    Windows  Power Management will turn the monitor off after a preset amount of time with no mouse or keyboard activity, but that is not a very satisfactory solution.

This program turns the monitor off whenever the "Pause" key is pressed.  It uses the same technique as Windows, so any mouse movement or key-press will restore the display.   It uses a Windows facility called "Global Keyboard Hook" which gets to look at every key press from any program and decide whether to process it or pass it on.   I this case, we look for the "Pause" key code and generate a "Monitor off" message when we see one.

Non-programmers are welcome to read on, but may want to skip to the bottom of this page to download executable version of the program.

Notes for Programmers

The code here is based on sample code found at delphi.about.com which also has an excellent description of the process.   I won't try to improve on that introduction but here is a summary:  

Global hooks must run from a separate DLL (Dynamic Link Library) module, so we need two projects, one to build the DLL with the key processing logic and one to load the DLL into memory and initialize it.  

First the initialization program, MonitorOff .  The following steps are all contained in the form create procedure.

  1.  Call LoadLibrary to load the DLL (MonitorOffDLL in this case) containing the hook procedure.
  2. Call GetProcAddress to get the addresses in the DLL of the  procedures to be called to initialize
    the hook (
    SetHookHandle in this case) and one to be called when a key is pressed (GlobalKeyboardHook in thsi case).
  3. Call SetWindowsHookEx specifying WH_KEYBOARD as the hook type and the
    addresses obtained in step 2.  Set the ThreadId parameter  to 0 to indicate a global hook.  The handled assigned to this hook must be passed to the DLL because it is used to define the chain of hooks in case other guys are also using hooks to watch the keyboard.
  4. Call the hook initialization procedure in the DLL to pass the handle assigned to the hook.

That's  all MonitorOff has to do except call FreeLibrary to release the DLL then the program is closed.  

In MonitorOffDLL,  procedure SetHookhandle simply saves the handle assigned to this hook  for use by the GlobalKeyboardHook  which now gets called whenever a key is pressed.  The logic in the hook procedure is quite simple - just look for the "Pause" key to be released and send a Syscommand windows message with the parameters necessary to turn off the monitor power.

Addendum March 13, 2008: A viewer recently discovered that the program did not work under his version of Vista.   After a little checking, I discovered that the problem was probably that not all monitors recognize the "standby" command that was previously issued.  At least in my case, the only version of Vista running here is on a laptop which does not "Standby".   The "Poweroff" command does work however, so the current update allows you to specify which command "Standby" or "Poweroff" is to be issued when the Pause key is pressed.  

Addendum March 17, 2010:  Version 2 fixes a problem with the alternative code for blanking the monitor (Code value 2, Power-Off), should now work when the default code value 1, Standby, does not.  I have tested it under Windows 7 on my first laptop to require its use, a Dell Studio 17.  In the process of testing, I also found that the Studio 17 uses the Fn + F12 keys to emulate the missing Pause key.  I have no experience with other company's laptops, but I suspect that thay all use a similar technique to replace  the real Pause key with a virtual alternative.  Dell does not document the "feature" that I could find, but my Key Codes program will help find the hidden key in short order.  This version also fixes a bug that only showed up under Windows 7 - when the program is closed, the "key hook" that was checking for the Pause key was not being  "unhooked" at close time.  It now is.     

Running/Exploring the Program 

bullet Download source
bullet Download  executable

Suggestions for Further Explorations

If the Pause key was needed for some other purpose.   MonitorOff could  let the user choose the key or key combination to be used.  The key information would then be passed to the initialization call to the DLL.



Original Date: September 12, 2006

Modified: May 11, 2018


  [Feedback]   [Newsletters (subscribe/view)] [About me]
Copyright 2000-2018, Gary Darby    All rights reserved.