Windows Desktop modifications with Ffidl

SeS 2014-09-30?

I hereby would like to present a little wrapper to toy around with the Windows desktop properties. This gadget provides a way to perform the following two tasks, by means of the ffidl package and thus DLL-calls:

  1. hide all icons from desktop
  2. hide taskbar and Windows Start button

I can think of various reasons in terms of possible use cases:

  1. record a video of an application, with focus only on the GUI and desktop background wallpaper only
  2. provide a way of personalization of the desktop dynamically by a tcl/tk GUI, on demand

In fact, the upcoming beta version of tG² already has implemented this, including the method to change the background wallpaper too, also with DLL calls... NOTE: The script is tested on a Win7 OS only...

# ------------------------------------------------------------------------
# Part of ffidl_1.tcl for tG² - Generic BSD License is applicable, just in case:
# THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 
# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHOR 
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 
# CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
# Copyright (C) 2009-2014 by Sedat Serper
# ------------------------------------------------------------------------
package require Ffidl 0.6

ffidl::callout dll_ShowWindow {int int} int               [ffidl::symbol user32.dll ShowWindow]
ffidl::callout dll_IsWindowVisible  {int} int             [ffidl::symbol user32.dll IsWindowVisible]
ffidl::callout dll_FindWindowTitle {int pointer-utf8} int [ffidl::symbol user32.dll FindWindowA]
ffidl::callout dll_ShowWindow {int int} int               [ffidl::symbol user32.dll ShowWindow]
ffidl::callout dll_FindWindowByClass {pointer-utf8 pointer-utf8} int [ffidl::symbol user32.dll FindWindowA]

# ------------------------------------------------------------------------
# Purpose         : retrieve the HWND of an external Windows program
# Usage example        : getHwnd [wm title .]
# ------------------------------------------------------------------------
proc getHwnd {windowname} {return [dll_FindWindowTitle 0 $windowname]}

# ------------------------------------------------------------------------
# Purpose : toggles the visibility of the Desktop icons 
# ------------------------------------------------------------------------
proc toggleDesktopIcons {{mode toggle}} {
  set hWnd  [getHwnd "Program Manager"]
  set isVis [dll_IsWindowVisible $hWnd]
  switch $mode {
   "toggle" {if {$isVis} {dll_ShowWindow $hWnd 0} {dll_ShowWindow $hWnd 4}}
   "hide"   {dll_ShowWindow $hWnd 0}
   "show"   {dll_ShowWindow $hWnd 4}
  }
}

# ------------------------------------------------------------------------
# from generic_1.tcl tG2 wrapper 
# ------------------------------------------------------------------------
proc isInteger {theString} {
  string is integer -strict $theString
}

# ------------------------------------------------------------------------
# Purpose : toggels various attributes of the Desktop 
# ------------------------------------------------------------------------
proc toggleDesktop... {mode value} {
  switch $mode {
   "icons" {
     if {[isInteger $value]} {if {$value} {set value show} {set value hide}}
     toggleDesktopIcons $value
   }
   "taskbar"    {
     if {![isInteger $value]} {if {$value=="hide"} {set value 0} {set value 1}}
     dll_ShowWindow [dll_FindWindowByClass "Shell_TrayWnd" ""] $value
     dll_ShowWindow [dll_FindWindowByClass "Button" "Start"] $value
   }
   "all" {
     toggleDesktop... "icons"     $value 
     toggleDesktop... "taskbar"   $value 
   }
  }
}

# test with a Wish.exe session
toggleDesktop... all hide
tk_messageBox -message "What?! get back my icons and taskbar!"
toggleDesktop... all show

SeS 12th Nov 2015

As it turned out, on Win10, a slightly different method needs to be used to accomplish manipulating desktop icons visibility. It seems that the desktop is split into several children, of which the icons are part of one group of children. The following adaptations ensure compatibility in both Win7 & 10.

ffidl::callout dll_GetWindow {int int} int             [ffidl::symbol user32.dll GetWindow]

# ------------------------------------------------------------------------
# Purpose : toggels the visibility of the Desktop icons 
# ------------------------------------------------------------------------
proc toggleDesktopIcons {{mode toggle}} {
  set hWnd [getHwnd "Program Manager"]
  set hWnd [dll_GetWindow $hWnd 5] ;# retrieve icons-child hWnd
  set isVis [dll_IsWindowVisible $hWnd]
  switch $mode {
   "toggle" {if {$isVis} {dll_ShowWindow $hWnd 0} {dll_ShowWindow $hWnd 1}}
   "hide"   {dll_ShowWindow $hWnd 0}
   "show"   {dll_ShowWindow $hWnd 1}
  }
}