Version 5 of TkAero

Updated 2009-05-04 14:48:02 by jdp

jdp - As promised on the Windows Aero page, here is the source code (below) and dll (here ) for a Tcl extension which allows Aero Glass [L1 ] to be extended inside a window. It is toolkit-independent, and requires knowledge of the handle of your application window. The you can use the command below to find the handle of your window (This only works if you have one application window, so call it before you create any more). (MG Is this the same returned by [winfo id $window]?) (jdp No - that command does return a valid window handle, and TkAero will accept it without complaint, but nothing happens. However, since the twapi command is from the Win32 api, I could probably package it with TkAero so that you don't need twapi)

twapi::find_windows -pids [pid] -visible 1 -toplevel 1

Usage is documented in the code below.

// TkAero.cpp - The one-and-only code file for TkAero.dll
// Written by jdp 2009
// This program is licensed under a Tcl-style BSD license.

// This will create one command, dwm::extendglass.
// It takes 5 arguments: hwnd, left, right, top, & bottom, in that order.
// hwnd is the window handle. You will probably want to use twapi to find this.
// left, right, top, & bottom are the number of pixels to extend the glass on those sides.
// Setting them all to -1 will make the whole window glass.
// Note that ONLY areas that are black will become glassified.
// Also note that drawing regular widgets onto this glass frame has some (spectacularly) ugly results.

// Macros defining things that are boring to type out

// Arguments for a proc defining a command
#define TCL_CMD_ARGS ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj * CONST objv[]

// Command to get an int from the args (with error checking)
#define TCL_GET_INT(n, p) if (Tcl_GetIntFromObj(interp, objv[n + 1], p) != TCL_OK) return TCL_ERROR;

// Check for the right number of args
#define TCL_WNA(n, m) if (objc != n + 1) {Tcl_WrongNumArgs(interp, 1, objv, m); return TCL_ERROR;}

// Create a command from a proc
#define TCL_CREATE_CMD(n, c) Tcl_CreateObjCommand(interp, n, c, NULL, NULL)

#define USE_TCL_STUBS 1

#include <tcl.h>

// This is the header file for the DWM API. You'll also want to have a reference to dwmapi.lib.
// Both files are in the Windows SDK. It is recommended that you delay-load dwmapi.dll.
#include <dwmapi.h>

extern "C"
{
        __declspec(dllexport) int Tkaero_Init(Tcl_Interp* interp);
}

// The command to extend glass.
// Note that you will have to do all your own version checking, etc. before calling this.
// If you are on Windows < Vista, you will get a nasty error when you call this.
// (Unless you didn't compile with delay-loading for dwmapi.dll, in which case the whole program will
// crash upon loading this extension.)
static int extendGlassCmd(TCL_CMD_ARGS)
{
        // Make sure we have the correct number of arguments
        TCL_WNA(5, "hwnd left right top bottom");

        // extract ints from our arguments
        int hwnd, left, right, top, bottom;
        TCL_GET_INT(0, &hwnd);
        TCL_GET_INT(1, &left);
        TCL_GET_INT(2, &right);
        TCL_GET_INT(3, &top);
        TCL_GET_INT(4, &bottom);

        // The DWM stuff.

        // Create the margins struct
        MARGINS mar = {top, bottom, left, right};

        // Extend the frame into the client area
        DwmExtendFrameIntoClientArea((HWND)hwnd, &mar);

        return TCL_OK;
}

int Tkaero_Init(Tcl_Interp *interp) {
        if (Tcl_InitStubs(interp, "8.1", 0) == NULL) {
                return TCL_ERROR;
        }
        TCL_CREATE_CMD("dwm::extendglass", extendGlassCmd);
        return TCL_OK;
}

enter categories here