Click here to Skip to main content
12,357,409 members (72,020 online)
Click here to Skip to main content

Stats

119.4K views
4.9K downloads
71 bookmarked
Posted

Import/Export registry sections as XML

, 21 Jan 2003
Export registry sections as XML to simplify registry diffs
ReleaseMFCdll
registryasxml.exe
Release
registryasxml.exe
registryxml.dsp
registryxml.dsw
res
Icon_Anchor.jpg
Icon_Form.jpg
Icon_Frame.jpg
Icon_Media.jpg
Icon_Root.jpg
ImageList.bmp
ImageList256.bmp
registryxml.ico
RegistryxmlDoc.ico
TocImageList.bmp
Toolbar.bmp
registryxml.opt
registryxml.plg
registryxml.suo
registryasxml.exe
registryasxml.exe
registryxml.dsp
registryxml.dsw
Icon_Anchor.jpg
Icon_Form.jpg
Icon_Frame.jpg
Icon_Media.jpg
Icon_Root.jpg
ImageList.bmp
ImageList256.bmp
registryxml.ico
RegistryxmlDoc.ico
TocImageList.bmp
Toolbar.bmp
//
// Zhadum.cpp
//
// Copyright (c) 2001-2002 Mark H. P. Lord. All rights reserved.
// 
// This software is provided 'as-is', without any express or implied
// warranty.  In no event will the author(s) be held liable for any damages
// arising from the use of this software.
// 
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
// 
// 1. The origin of this software must not be misrepresented; you must not
//    claim that you wrote the original software. If you use this software
//    in a product, an acknowledgment in the product documentation would be
//    appreciated but is not required.
// 2. Altered source versions must be plainly marked as such, and must not be
//    misrepresented as being the original software.
// 3. This notice may not be removed or altered from any source distribution.
//

#include "stdafx.h"
#include <wingdi.h>
#include "Zhadum.h"
#include <assert.h>
#include <math.h>
#include <stdlib.h>

// Disable warning of conversion from LONG to x * (a Win64 portability warning
// given by VC7)
#pragma warning(disable:4312)
#pragma warning(disable:4311)

const char *dollarIdZhadum = "$Id: Zhadum.cpp,v 1.4 2002/10/21 23:31:52 mark Exp $";

//
// Win32 Defines
//

#define WS_EX_LAYERED           0x00080000

#define LWA_COLORKEY            0x00000001
#define LWA_ALPHA               0x00000002

#define ULW_COLORKEY            0x00000001
#define ULW_ALPHA               0x00000002
#define ULW_OPAQUE              0x00000004

#define AC_SRC_OVER                 0x00
#define AC_SRC_ALPHA                0x01

//
// Helpers
//

#define countof(x) (sizeof (x) / sizeof ((x)[0]))
#define minimum(a, b) ((a) < (b) ? (a) : (b))
#define maximum(a, b) ((a) > (b) ? (a) : (b))

#ifndef _WIN64
#define GetZhadumShadowDataFromHWnd(hwnd) (ZhadumShadowData *) GetWindowLong (hwnd, 0)
#define SetZhadumShadowDataForHWnd(hwnd, data) SetWindowLong (hwnd, 0, (LONG) data)
#else
#define GetZhadumShadowDataFromHWnd(hwnd) (ZhadumShadowData *) GetWindowLongPtr (hwnd, 0)
#define SetZhadumShadowDataForHWnd(hwnd, data) SetWindowLongPtr (hwnd, 0, (LONG_PTR) data)
#endif

#define is_atom(p) (((size_t) (p) & (~0xffff)) == 0)

//
// Z'Ha'Dum
//

// Types
struct ZhadumShadowData {
	HBITMAP bmp;
	bool vertical;
	int alpha;
};

typedef DWORD uint32;
typedef BYTE byte;

typedef BOOL (__stdcall *ZhadumSetLayeredWindowAttributesType) (HWND, COLORREF, BYTE, DWORD);
typedef BOOL (__stdcall *ZhadumUpdateLayeredWindowType) (HWND, HDC, POINT *, SIZE *, HDC, POINT *, COLORREF, BLENDFUNCTION *, DWORD);

// Constants
#define	ZHADUM_WM_SETALPHA (WM_USER + 1)
#define ZHADUM_WM_SETVERTICAL (WM_USER + 2)

#define MAX_ZHADUM_WNDS 128
#define MAX_ZHADUM_EXCLUSIONS 128

#if 1
	// Normal shadow size
	#define X_INDENT 2
	#define Y_INDENT 5
	#define X_SIZE 7
	#define Y_SIZE 7
	#define MAX_ALPHA 100
	#define MIN_ALPHA 0
#else
	// Chunkier shadows
	#define X_INDENT 4
	#define Y_INDENT 7
	#define X_SIZE 14
	#define Y_SIZE 14
	#define MAX_ALPHA 100
	#define MIN_ALPHA 0
#endif

static TCHAR zhadumShadowWndClassName[] = TEXT ("ZhadumShadow");

// Globals
static HINSTANCE zhadumHInst;
static HHOOK zhadumHook = NULL;

struct ZhadumWindowInfo {
	HWND hwnd;
	RECT rect;
	BOOL visible;
	HWND shadows[2];
};
static ZhadumWindowInfo zhadumWindows[MAX_ZHADUM_WNDS];
static int zhadumWindowCount = 0;

static BOOL zhadumRegisteredShadowClass = FALSE;

static ZhadumSetLayeredWindowAttributesType zhadumSetLayeredWindowAttributes;
static ZhadumUpdateLayeredWindowType zhadumUpdateLayeredWindow;

enum ZhadumExclusionType { 
	ZhadumExclusionType_Window,
	ZhadumExclusionType_Class,
	ZhadumExclusionType_Atom,
};
	
struct ZhadumExclusion {
	ZhadumExclusionType type;
	union {
		HWND hwnd;
		TCHAR *className;
		LPCTSTR atom;
	} u;
};

static ZhadumExclusion zhadumExclusions[MAX_ZHADUM_EXCLUSIONS];
static int zhadumExclusionCount = 0;

//
// Local Functions
//

static BOOL ZhadumInitialise () {
	HMODULE hmodule = GetModuleHandle (TEXT ("user32.dll"));
	
	if (zhadumSetLayeredWindowAttributes && zhadumUpdateLayeredWindow) {
		return TRUE;
	}

	zhadumSetLayeredWindowAttributes =
		(ZhadumSetLayeredWindowAttributesType) GetProcAddress (hmodule, "SetLayeredWindowAttributes");

	zhadumUpdateLayeredWindow =
		(ZhadumUpdateLayeredWindowType) GetProcAddress (hmodule, "UpdateLayeredWindow");
		
	if (! zhadumSetLayeredWindowAttributes || ! zhadumUpdateLayeredWindow) {
		return FALSE;
	}
	
	return TRUE;
}

static void FillU32 (uint32 *out, uint32 value, int count) {
	while (count--) {
		*out++ = value;
	}
}

static void FillPixels (uint32 *surf, int surfw, int surfh,
	int left, int top, int right, int bottom, uint32 value) {
	int w = right - left;

	assert (! (left < 0 || top < 0 || right > surfw || bottom > surfh || bottom < top || right < left));

	if (left < 0 || top < 0 || right > surfw || bottom > surfh || bottom < top || right < left) {
		return;
	}

	for (; top != bottom; ++top) {
		FillU32 (&surf[left + top * surfw], value, w);
	}
}

static void FillRoundedCorner (uint32 *surf, int cx, int cy, int cornersize,
	int left, int top, int right, int bottom, int dx, int dy) {
	if (left < 0 || top < 0 || right > cx || bottom > cy || bottom < top || right < left)
		return;
		
	uint32 *rowptr = surf + top;
	int cyminus1 = cornersize - 1;
	//double scale = sqrt (cyminus1*cyminus1 + cyminus1*cyminus1);
	double scale = cyminus1;
	int njinit = dx < 0 ? (cornersize-1) : 0;
	int ni = dy < 0 ? (cornersize-1) : 0;
	int nj;
	int i, j;
	uint32 value;
	for (i = top; i != bottom; ++i, rowptr += cx, ni += dy) {
		for (j = left, nj = njinit; j != right; ++j, nj += dx) {
			value = (uint32)floor (sqrt (ni*ni + nj*nj) * 255.0 / scale);
			if (value > 255)
				rowptr[j] = 0;
			else {
				value = 255-value;
				value = ((value * (MAX_ALPHA-MIN_ALPHA+1)) >> 8) + MIN_ALPHA;
				rowptr[j] = value << 24;
			}
		}
	}
}

static void ZhadumShadowWindowUpdate (HWND hwnd) {
	ZhadumShadowData *data = GetZhadumShadowDataFromHWnd (hwnd);

	if (data->bmp) {
		DeleteObject (data->bmp);
	}

	SIZE sz;
	RECT rwnd;
	GetWindowRect (hwnd, &rwnd);
	sz.cx = rwnd.right - rwnd.left;
	sz.cy = rwnd.bottom - rwnd.top;

	if (! sz.cx || ! sz.cy) {
		data->bmp = NULL;
		return;
	}

	// We have to use a DIB section for 16-bit video mode support	
	BITMAPINFO bitmapInfo;
	bitmapInfo.bmiHeader.biSize = sizeof (bitmapInfo.bmiHeader);
	bitmapInfo.bmiHeader.biWidth = sz.cx;
	bitmapInfo.bmiHeader.biHeight = -(int)sz.cy;
	bitmapInfo.bmiHeader.biPlanes = 1;
	bitmapInfo.bmiHeader.biBitCount = 32;
	bitmapInfo.bmiHeader.biCompression = BI_RGB;
	bitmapInfo.bmiHeader.biSizeImage = sz.cx * sz.cy * 4;
	bitmapInfo.bmiHeader.biXPelsPerMeter = 0;
	bitmapInfo.bmiHeader.biYPelsPerMeter = 0;
	bitmapInfo.bmiHeader.biClrUsed = 0;
	bitmapInfo.bmiHeader.biClrImportant = 0;
	
	HDC hdc = GetDC (NULL);
	VOID *bits;
	data->bmp = CreateDIBSection (hdc, &bitmapInfo, DIB_RGB_COLORS, &bits, NULL, 0);
	ReleaseDC (NULL, hdc);
	if (! data->bmp) {
		//ZhadumDisplayWinError (GetLastError (), TEXT ("CreateBitmap"));
		return;
	}

	int area = sz.cx * sz.cy;
	int i;

	uint32 *pixels = (uint32 *) bits;
	uint32 *pixelptr = pixels;

	if (! data->vertical) {
		FillRoundedCorner (pixelptr, sz.cx, sz.cy, sz.cy, 
							0, 0, sz.cy, sz.cy, -1, 1);

		uint32 *rowptr = pixelptr;
		int maxx = minimum (sz.cx, sz.cy);
		for (i = 0; i != sz.cy; ++i, rowptr += sz.cx) {
			FillPixels (pixelptr, sz.cx, sz.cy, maxx, i, sz.cx, i + 1, rowptr[maxx-1]);
		}

		FillRoundedCorner (pixelptr, sz.cx, sz.cy, sz.cy, 
							sz.cx - sz.cy, 0, sz.cx, sz.cy, 1, 1);
	}
	else {	
		FillRoundedCorner (pixelptr, sz.cx, sz.cy, sz.cx,
							0, 0, sz.cx, sz.cx, 1, -1);
							
		int maxy = minimum (sz.cx, sz.cy);
		uint32 *rowptr = pixelptr + (maxy - 1) * sz.cx;
		for (i = 0; i != sz.cx; ++i) {
			FillPixels (pixelptr, sz.cx, sz.cy, i, maxy, i + 1, sz.cy, rowptr[i]);
		}
	}
	
	if (data->alpha != 255) {
		int alpha;
		if (data->alpha == 0) {
			alpha = 1;
		}
		else {
			alpha = data->alpha;
		}
		
		byte *alphaptr = (byte *) pixels;
		byte *alphaend = alphaptr + area * 4;
		alphaptr += 3;
		alphaend += 3;
		for (; alphaptr != alphaend; alphaptr += 4) {
			*alphaptr = (byte) ((int) (*alphaptr) * alpha / 255);
		}
	}

	hdc = ::GetDC (NULL);
	HDC hdctemp = CreateCompatibleDC (hdc);
	SetLayout (hdctemp, LAYOUT_BITMAPORIENTATIONPRESERVED);
	HGDIOBJ oldbmp = SelectObject (hdctemp, data->bmp);
	
	POINT ptwnd;
	ptwnd.x = rwnd.left;
	ptwnd.y = rwnd.top;
	
	POINT ptzero = { 0, 0 };
	BLENDFUNCTION blend;
	memset (&blend, 0, sizeof (blend));
	blend.BlendOp = AC_SRC_OVER;
	blend.BlendFlags = 0;
	blend.SourceConstantAlpha = 255;
	blend.AlphaFormat = AC_SRC_ALPHA;
	if (zhadumUpdateLayeredWindow) {
		(*zhadumUpdateLayeredWindow) (hwnd, hdc, &ptwnd, &sz, hdctemp, &ptzero, 0, &blend, ULW_ALPHA);
	}

	SelectObject (hdctemp, oldbmp);
	DeleteDC (hdctemp);
	::ReleaseDC (NULL, hdc);
}

// Our window procedure for our shadow windows
static LRESULT CALLBACK ZhadumShadowWndProc (HWND hwnd, UINT msg, WPARAM wparam,
		LPARAM lparam) {
	ZhadumShadowData *data;
	
	switch (msg) {
		case WM_CREATE: {
			data = (ZhadumShadowData *) calloc (sizeof (ZhadumShadowData), 1);
			if (! data) {
				return -1;
			}
			
			SetZhadumShadowDataForHWnd (hwnd, data);
			
			data->alpha = 255;
			data->vertical = false;
			break;
		}
		
		case WM_DESTROY: {
			data = GetZhadumShadowDataFromHWnd (hwnd);
			if (data) {
				if (data->bmp) {
					DeleteObject (data->bmp);
				}
				free (data);
			}
			break;
		}
		
		case WM_PAINT: {
			ValidateRect (hwnd, NULL);
			return 0;
		}
		
		case WM_NCHITTEST: {
			return HTTRANSPARENT;
		}

		case WM_SIZE: {
			ZhadumShadowWindowUpdate (hwnd);
			break;
		}

		case ZHADUM_WM_SETVERTICAL: {
			ZhadumShadowData *data = GetZhadumShadowDataFromHWnd (hwnd);
			
			data->vertical = wparam != 0;			
			return 0;
		}
		
		case ZHADUM_WM_SETALPHA: {
			ZhadumShadowData *data = GetZhadumShadowDataFromHWnd (hwnd);
			
			int alpha = (int) wparam;
			if (alpha != data->alpha) {
				data->alpha = alpha;
				ZhadumShadowWindowUpdate (hwnd);
			}
			return 0;
		}
	}
	
	return DefWindowProc (hwnd, msg, wparam, lparam);
}

// Register the shadow window's window class, if it's not already been done
static BOOL ZhadumRegisterShadowClass () {
	if (! zhadumRegisteredShadowClass) {
		WNDCLASSEX wc;
		wc.cbSize = sizeof (wc);
		wc.cbClsExtra = 0;
		wc.cbWndExtra = sizeof (ZhadumShadowData *);
		wc.hbrBackground = NULL;
		wc.hCursor = LoadCursor (NULL, IDC_ARROW);
		wc.hIcon = NULL;
		wc.hIconSm = NULL;
		wc.hInstance = zhadumHInst;
		wc.lpfnWndProc = (WNDPROC) ZhadumShadowWndProc;
		wc.lpszClassName = zhadumShadowWndClassName;
		wc.lpszMenuName = NULL;
		wc.style = 0;
		
		if (RegisterClassEx (&wc)) {
			zhadumRegisteredShadowClass = TRUE;
		}
		
		return zhadumRegisteredShadowClass;
	}
	else {	
		return TRUE;
	}
}

// Update the specified window's shadows. If isvisible is specified it should
// be zero if the window is being hidden or > zero if the window is being
// shown
static void ZhadumUpdateWindow (HWND hwnd, int isvisible = -1) {
	ZhadumWindowInfo *p = zhadumWindows;
	ZhadumWindowInfo *e = p + zhadumWindowCount;
	for (; p != e; ++p) {
		if (p->hwnd == hwnd) {
			break;
		}
	}
	
	if (p == e) {
		// Window's not being shadowed, so quit
		return;
	}
	
	int i;

	if (isvisible >= 0) {
		// "isvisible" was passed to us, so we received a WM_SHOWWINDOW or some
		// other indication that the window's visibility is changing
	
		if (! isvisible) {
			// We should be invisible
			if (p->visible) {
				// We're currently visibile
				p->visible = FALSE;
				
				// Destroy the shadow windows
				for (i = 0; i != 2; ++i) {
					if (p->shadows[i]) {
						DestroyWindow (p->shadows[i]);
					}
				}
				
				memset (p->shadows, 0, sizeof (HWND) * 2);
				return;
			}
			else {
				// No problem, already invisible
				return;
			}
		}
		else {
			// We should be visible
			if (! p->visible) {
				// We're not, so we're going to need the shadow window class
				if (! ZhadumRegisterShadowClass ()) {
					return;
				}

				// Update visible flag now
				p->visible = TRUE;
				
				// Make the shadow windows
				for (i = 0; i != 2; ++i) {
					p->shadows[i] = CreateWindowEx (WS_EX_LAYERED | WS_EX_TRANSPARENT, 
							zhadumShadowWndClassName, NULL,
							WS_POPUP | WS_DISABLED,
							0, 0, 0, 0, hwnd, NULL, zhadumHInst, NULL);
					SendMessage (p->shadows[i], ZHADUM_WM_SETVERTICAL, i, 0);
					ShowWindow (p->shadows[i], SW_SHOWNA);
				}
				
				// Reset the rectangle to force it to update as necessary
				memset (&p->rect, 0, sizeof (p->rect));
			}
		}
	}
	
	// If we reach here then either our visibility state didn't change or we've
	// just become visible
	if (! p->visible) {
		return;
	}

	// Get the window's current location
	RECT rect;
	GetWindowRect (hwnd, &rect);
	
	// Compare the current rectangles to the rectangle the shadows were last set
	// to.
	if (p->rect.left == rect.left && p->rect.top == rect.top 
            && p->rect.right == rect.right && p->rect.bottom == rect.bottom) {
        // No change, quit now
		return;
	}
	
	// Shadows need to follow the window
	p->rect = rect;

	SetWindowPos (p->shadows[0], NULL, rect.left+X_INDENT, rect.bottom,
			rect.right - rect.left + X_SIZE - X_INDENT, Y_SIZE, SWP_NOZORDER | SWP_NOACTIVATE);
	SetWindowPos (p->shadows[1], NULL, rect.right, rect.top+Y_INDENT, X_SIZE, 
			rect.bottom-rect.top-Y_INDENT, SWP_NOZORDER | SWP_NOACTIVATE);
}

// Add a window to the list of windows to be shadowed
static void ZhadumAddWindow (HWND hwnd) {
	ZhadumWindowInfo *p = zhadumWindows;
	ZhadumWindowInfo *e = p + zhadumWindowCount;
	for (; p != e; ++p) {
		if (p->hwnd == hwnd) {
			return;
		}
	}
	
	if (e != zhadumWindows + countof (zhadumWindows)) {
		// There's room
		memset (e, 0, sizeof (*e));
		e->hwnd = hwnd;
		++zhadumWindowCount;
	}
}

// Remove a window from the list of windows to be shadowed
static void ZhadumRemoveWindow (HWND hwnd) {
	ZhadumWindowInfo *p = zhadumWindows;
	ZhadumWindowInfo *e = p + zhadumWindowCount;
	for (; p != e; ++p) {
		if (p->hwnd == hwnd) {
			// Remove the shadows, if they exist
			for (int i = 0; i != 2; ++i) {
				if (p->shadows[i]) {
					DestroyWindow (p->shadows[i]);
				}
			}
			
			// Shrink the list
			if (p + 1 < e) {
				memmove (p, p + 1, (e - (p + 1)) * sizeof (ZhadumWindowInfo));
				return;
			}
			
			--zhadumWindowCount;
		}
	}
}

// Should we shadow a window?
static BOOL ZhadumShouldShadow (HWND hwnd, LPCREATESTRUCT cs) {
	// Child windows are a no no
	if ((cs->style & (WS_POPUP | WS_CHILD | WS_OVERLAPPED)) == WS_CHILD) {
		return FALSE;
	}
	
	// Check for us first
	if (! is_atom (cs->lpszClass)) {
		if (lstrcmp (cs->lpszClass, zhadumShadowWndClassName) == 0) {
			return FALSE;
		}
	}
	
	// Scan the exclusions
	ZhadumExclusion *p = zhadumExclusions;
	ZhadumExclusion *e = zhadumExclusions + zhadumExclusionCount;
	for (; p != e; ++p) {
		switch (p->type) {
			case ZhadumExclusionType_Window:
				if (hwnd == p->u.hwnd) {
					return FALSE;
				}
				break;
				
			case ZhadumExclusionType_Atom:
				if (cs->lpszClass == p->u.atom) {
					return FALSE;
				}
				break;
				
			case ZhadumExclusionType_Class:
				if (! is_atom (cs->lpszClass) 
						&& 0 == lstrcmp (cs->lpszClass, p->u.className)) {
					return FALSE;
				}
				break;
		}
	}
	
	return TRUE;
}

// Our hook procedure. We're only interested in certain messages.
static LRESULT CALLBACK ZhadumHookProc (int code, WPARAM wparam, LPARAM lparam) {
    HWND hwnd;
    
	switch (((CWPRETSTRUCT *) lparam)->message) {
		case WM_CREATE: {
			// Window being created. If it's suitable for shadowing (i.e.,
			// it's not a child window and it's not disabled) then add it
			// to the list of windows to shadow.
			// We catch shadows this way because they're always disabled.
			LPCREATESTRUCT cs = (LPCREATESTRUCT) ((CWPRETSTRUCT *) lparam)->lParam;
			if (ZhadumShouldShadow (((CWPRETSTRUCT *) lparam)->hwnd, cs)) {
				ZhadumAddWindow (((CWPRETSTRUCT *) lparam)->hwnd);
			}
			break;
		}
			
		case WM_DESTROY:
			// A window is being destroyed. Remove it from the shadowed window
			// list, if it's there.
			ZhadumRemoveWindow (((CWPRETSTRUCT *) lparam)->hwnd);
			break;
			
		case WM_SIZE:
		case WM_MOVE:
		case WM_MOVING:
		case WM_SIZING:
        case WM_ACTIVATE:
			// The window has moved or resized so we should adjust the shadows
            hwnd = ((CWPRETSTRUCT *) lparam)->hwnd;
			ZhadumUpdateWindow (hwnd, 
                    (GetWindowLong (hwnd, GWL_STYLE) & WS_VISIBLE) ? 1 : 0);
			break;

		case WM_SHOWWINDOW:
			// The window is being shown or hidden, update the shadows accordingly
			ZhadumUpdateWindow (((CWPRETSTRUCT *) lparam)->hwnd, 
					((CWPRETSTRUCT *) lparam)->wParam ? 1 : 0);
			break;
	}
	
	return CallNextHookEx (zhadumHook, code, wparam, lparam);
}

// Add an exclusion to the list
static BOOL ZhadumAddExclusion (const ZhadumExclusion *exclusion) {
	if (zhadumExclusionCount == MAX_ZHADUM_EXCLUSIONS) {
		return FALSE;
	}
	
	zhadumExclusions[zhadumExclusionCount++] = *exclusion;
	
	return TRUE;
}

// Free a single ZhadumExclusion
static void ZhadumFreeExclusion (ZhadumExclusion *exclusion) {
	if (exclusion->type == ZhadumExclusionType_Class) {
		free (exclusion->u.className);
	}
	
	exclusion->type = ZhadumExclusionType_Window;
}

// Free all exclusions
static void ZhadumFreeExclusions () {
	ZhadumExclusion *p = zhadumExclusions;
	ZhadumExclusion *e = zhadumExclusions + zhadumExclusionCount;
	for (; p != e; ++p) {
		ZhadumFreeExclusion (p);
	}
	
	zhadumExclusionCount = 0;
}

//
// Global Functions
//

// Exclude the specified window from window shadows. Returns FALSE if there
// are too many exclusions in place.
BOOL WINAPI ZhadumExcludeWindow (HWND hwnd) {
	ZhadumExclusion excl;
	
	ZhadumRemoveWindow (hwnd);
	
	excl.type = ZhadumExclusionType_Window;
	excl.u.hwnd = hwnd;
	return ZhadumAddExclusion (&excl);
}

// Remove the exclusion on the specified window. This won't create shadows
// but it will allow any future windows with the same HWND to have shadows.
// You no longer have to call this, it's handled internally.
void WINAPI ZhadumUnexcludeWindow (HWND hwnd) {
	ZhadumExclusion *p = zhadumExclusions;
	ZhadumExclusion *e = zhadumExclusions + zhadumExclusionCount;
	for (; p != e; ++p) {
		if (p->type == ZhadumExclusionType_Window 
				&& p->u.hwnd == hwnd) {
			memmove (p, p + 1, (e - (p + 1)) * sizeof (ZhadumExclusion));
			return;
		}
	}
}

// Exclude the specified WNDCLASS (can be an internal class, e.g. WC_DIALOG).
// Returns FALSE if there are too many exclusions in place.
BOOL WINAPI ZhadumExcludeClass (LPCTSTR classname) {
	ZhadumExclusion excl;
	
	if (! is_atom (classname)) {
		excl.type = ZhadumExclusionType_Atom;
		int size = (lstrlen (classname) + 1) * sizeof (TCHAR);
		excl.u.className = (TCHAR *) malloc (size);
		if (! excl.u.className) {
			return FALSE;
		}
		memcpy (excl.u.className, classname, size);
		if (! ZhadumAddExclusion (&excl)) {
			free (excl.u.className);
			return FALSE;
		}
		else {
			return TRUE;
		}
	}
	else {
		excl.type = ZhadumExclusionType_Atom;
		excl.u.atom = classname;
		return ZhadumAddExclusion (&excl);
	}
}

// Set the alpha of the shadows belonging to the specified window.
void WINAPI ZhadumSetWindowShadowAlpha (HWND hwnd, BYTE alpha) {
	ZhadumWindowInfo *p = zhadumWindows;
	ZhadumWindowInfo *e = p + zhadumWindowCount;
	for (; p != e; ++p) {
		if (p->hwnd == hwnd) {
			for (int i = 0; i != 2; ++i) {
				if (p->shadows[i]) {
					SendMessage (p->shadows[i], ZHADUM_WM_SETALPHA, (WPARAM) alpha, 0);
				}
			}
		}
	}
}

// Begins automatically applying window shadows to our popup windows
BOOL WINAPI ZhadumBegin (HINSTANCE hinst) {
	if (zhadumHook != NULL) {
		// Hook already installed
		return TRUE;
	}

	// Remember this
	zhadumHInst = hinst;

	// Make sure shadows are available
	if (! ZhadumInitialise ()) {
		return FALSE;
	}

	// Exclude menus
	ZhadumExcludeClass ((LPCTSTR) 32768);
	
	// Set a Windows CALLWNDPROCRECT hook, which will get called whenever
	// a window procedure returns. We inspect the messages and work on the
	// ones we're interested in.
	zhadumHook = SetWindowsHookEx (WH_CALLWNDPROCRET, ZhadumHookProc, GetModuleHandle (NULL), GetCurrentThreadId ());
	
	// Return boolean indicating success
	return zhadumHook != NULL ? TRUE : FALSE;
}

// Stop auto-shadowing
void WINAPI ZhadumEnd () {
	if (zhadumHook != NULL) {
		UnhookWindowsHookEx (zhadumHook);
		zhadumHook = NULL;
	}
	
	// Remove all the window entries from the list
	ZhadumWindowInfo *p = zhadumWindows;
	ZhadumWindowInfo *e = p + zhadumWindowCount;
	zhadumWindowCount = 0;
	for (; p != e; ++p) {
		for (int i = 0; i != 2; ++i) {
			if (p->shadows[i]) {
				DestroyWindow (p->shadows[i]);
			}
		}
	}
	
	// Remove all the exclusions
	ZhadumFreeExclusions ();
}

void WINAPI ZhadumDisplayWinError (DWORD err, LPCTSTR title) {
	TCHAR buf[128];
	FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
			NULL,
			err,
			0,
			buf,
			countof (buf),
			NULL);
	MessageBox (NULL, buf, title, MB_OK | MB_ICONSTOP);
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

Addicted to reverse engineering. At work, I am developing business intelligence software in a team of smart people (independent software vendor).

Need a fast Excel generation component? Try xlsgen.


You may also be interested in...

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.160621.1 | Last Updated 22 Jan 2003
Article Copyright 2002 by Stephane Rodriguez.
Everything else Copyright © CodeProject, 1999-2016
Layout: fixed | fluid