Click here to Skip to main content
15,885,365 members
Articles / Programming Languages / C++

Iconizer

Rate me:
Please Sign up or sign in to vote.
4.95/5 (10 votes)
2 May 2001 147.7K   3.3K   62  
This handy utility adds an extra button near the minimize/maximize/close buttons of existing windows that allows you to minimise your applications to the system tray.
//===========================================================================
//
//	HomeWork from Belgium			Not licensed software  
//	1999 - 2000						No rights reserved
//
//===========================================================================
//
//	Project/Product :	Iconizer DLL
//  FileName		:	caption.cpp
//	Author(s)		:	Bart Gysens
//
//	Description		:	Implementation of caption related functionality
//
//	Classes			:	CCaptionRect	
//
//	Information		:
//	  Compiler(s)	:	Visual C++ 6.0 SP4
//	  Target(s)		:	Windows NT and Windows 2000
//	  Editor		:	Visual C++ 6.0 internal editor
//
//	History
//	Vers.  Date      Aut.  Type     Description
//  -----  --------  ----  -------  -----------------------------------------
//	1.00   07 12 99  BG    Create   Original
//
//===========================================================================

#include "stdafx.h"
#include "hooklist.h"
#include "trayicon.h"
#include "caption.h"
#include "Iconizer dll.h"

//===========================================================================
//	Externals
//===========================================================================

extern CTrayIcon g_TrayIcon;
extern LRESULT DoCallWindowProc( WNDPROC lpPrevWndFunc, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam );


//===========================================================================
//	Macros and typedefs
//===========================================================================


//===========================================================================
// 
//	Class			:	CCaptionRect
//	Author(s)		:	Bart Gysens
//
//	Description		:	Implementation of the CCaptionRect class
//
//	Comments		:	none
//
//	History			:	1.00  : Create
//
//===========================================================================

CCaption::CCaption()
{
	// Create pen
	m_hPen	= CreatePen( PS_SOLID, 2, RGB( 0, 0, 0 ) );	

	// Initialise parameters
	m_d1 = 2 + ( GetSystemMetrics( SM_CXSIZE ) - 5 ) * 7 / 16;
	m_d2 = 2 + ( GetSystemMetrics( SM_CYSIZE ) - 5 ) * 9 / 16;
}

CCaption::~CCaption()
{
	DeleteObject( m_hPen );
}

void CCaption::CalcCaptionRect( HWND hWnd, RECT& Rect )
{	
	DWORD dStyle		;
	SIZE  sFrame		;
	int	  Icon			;	

	// Get frame size of window
	dStyle    = GetWindowLong( hWnd, GWL_STYLE );
	sFrame.cx = GetSystemMetrics( ( dStyle & WS_THICKFRAME ) ? SM_CXSIZEFRAME : SM_CXFIXEDFRAME );
	sFrame.cy = GetSystemMetrics( ( dStyle & WS_THICKFRAME ) ? SM_CYSIZEFRAME : SM_CYFIXEDFRAME );

	// Get width of icon/button in caption
	Icon = GetSystemMetrics( SM_CXSIZE );

	// Calculate rectangle dimensions
	GetWindowRect( hWnd, &Rect );
	Rect.bottom -= Rect.top;
	Rect.right  -= Rect.left;
	Rect.top     = 0;
	Rect.left    = 0;

	Rect.left   += sFrame.cx;
	Rect.right  -= sFrame.cx;
	Rect.top    += sFrame.cy;
	Rect.bottom  = Rect.top + GetSystemMetrics( SM_CYCAPTION )
	                        - GetSystemMetrics( SM_CYBORDER );
}

void CCaption::DrawIconize( HDC hDc, int x, int y, int off )
{
	HPEN	OldPen	;
	RECT	R		;	

	/* Select new pen */
	OldPen = (HPEN) SelectObject( hDc, m_hPen );

	/* Calculate dimensions */
	R.top    = y + m_d1 + 2;
	R.left   = x + m_d1 + off;
	R.bottom = y + m_d2 + 2;
	R.right  = x + m_d2 + off;
	Rectangle( hDc, R.left, R.top, R.right, R.bottom );

	/* Restore old pen */
	SelectObject( hDc, OldPen );
}

void CCaption::DrawButtons( HWND hWnd )
{
	HDC	  hDc		;
	RECT  rCap		;
	DWORD dStyle	;
	DWORD dExStyle	;
	int	  cxBtn		;
	int   cyBtn		;
	RECT  rPos		;

	// Get window device context		
	if ( ( hDc = GetWindowDC( hWnd ) ) != NULL )
	{
		// Get caption coordinates
		CCaption::CalcCaptionRect( hWnd, rCap );

		// Get window style
		dStyle   = GetWindowLong( hWnd, GWL_STYLE );
		dExStyle = GetWindowLong( hWnd, GWL_EXSTYLE );
	
		// Check if we have a caption
		if ( ( dStyle & WS_CAPTION ) == WS_CAPTION )
		{
			// Calc position and draw minimize and iconize button
			if ( ( dStyle & WS_MINIMIZEBOX ) == WS_MINIMIZEBOX )
			{
				// Get button dimensions
				cxBtn = GetSystemMetrics( SM_CXSIZE );
				cyBtn = GetSystemMetrics( SM_CYSIZE );
				
				// Calc position and draw iconize button
				rPos.top    = rCap.top    + 2;
				rPos.bottom = rCap.bottom - 2;
				rPos.right  = rCap.right - ( 3 * ( cxBtn - 2 ) ) - 4;
				rPos.left   = rCap.right - ( 4 * ( cxBtn - 2 ) ) - 4;
				DrawFrameControl( hDc, &rPos, DFC_BUTTON, DFCS_BUTTONPUSH );

				// Draw a btnface
				DrawIconize( hDc, rPos.left, rPos.top, 0 );
			}
		}

		// Release device context
		ReleaseDC( hWnd, hDc );
	}
}

LRESULT CCaption::OnDefault( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam, CHookItem * pItem )
{
	// Call default window procedure and redraw caption buttons
	LRESULT result = DoCallWindowProc( pItem->m_DefWndProc, hWnd, Msg, wParam, lParam );
	CCaption::DrawButtons( hWnd );
	return result;
}

LRESULT CCaption::OnNcActivate( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam, CHookItem * pItem )
{
	// Call default window procedure and send WM_NCPAINT message
	LRESULT result = DoCallWindowProc( pItem->m_DefWndProc, hWnd, Msg, wParam, lParam );
	SendMessage( hWnd, WM_NCPAINT, 0, 0 );
	return result;
}

LRESULT CCaption::OnNcLButtonDown( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam, CHookItem * pItem )
{
	HDC		hDc			;
	POINT	Pnt			;
	RECT	rPos		;
	RECT	rWin		;
	LRESULT	result = 0	;

	// Redraw caption buttons
	if ( ( hDc = GetWindowDC( hWnd ) ) != NULL )
	{
		// Convert mouse postion relative to caption rectangle
		GetWindowRect( hWnd, &rWin );
		Pnt.x = MAKEPOINTS( lParam ).x - rWin.left;
		Pnt.y = MAKEPOINTS( lParam ).y - rWin.top;

		// Calculate rectangle position of iconize button
		CCaption::CalcCaptionRect( hWnd, rPos );		
		rPos.top    += 2;	
		rPos.bottom -= 2;
		rPos.right  -= ( ( GetSystemMetrics( SM_CXSIZE ) * 3 ) - 2 );
		rPos.left    = rPos.right - ( GetSystemMetrics( SM_CXSIZE ) - 2 );

		// Check if mouse position is in rectangle
		if ( PtInRect( &rPos, Pnt ) )
		{
			pItem->m_LBtnDown = TRUE;
			DrawFrameControl( hDc, &rPos, DFC_BUTTON, DFCS_BUTTONPUSH | DFCS_PUSHED );
			DrawIconize( hDc, rPos.left, rPos.top, 1 );
		}
		else
			result = DoCallWindowProc( pItem->m_DefWndProc, hWnd, Msg, wParam, lParam );
		DeleteObject( hDc );
	}

	return result;
}

LRESULT CCaption::OnNcLButtonUp( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam, CHookItem * pItem )
{
	HDC		hDc			;
	POINT	Pnt			;
	RECT	rPos		;
	RECT	rWin		;
	LRESULT result = 0	;

	// Redraw caption buttons
	if ( ( hDc = GetWindowDC( hWnd ) ) != NULL )
	{
		// Convert mouse postion relative to caption rectangle
		GetWindowRect( hWnd, &rWin );
		Pnt.x = MAKEPOINTS( lParam ).x - rWin.left;
		Pnt.y = MAKEPOINTS( lParam ).y - rWin.top;

		// Calculate rectangle position of iconize button
		CCaption::CalcCaptionRect( hWnd, rPos );		
		rPos.top    += 2;	
		rPos.bottom -= 2;
		rPos.right  -= ( ( GetSystemMetrics( SM_CXSIZE ) * 3 ) - 2 );
		rPos.left    = rPos.right - ( GetSystemMetrics( SM_CXSIZE ) - 2 );

		// Check if mouse position is in rectangle
		if ( pItem->m_LBtnDown && PtInRect( &rPos, Pnt ) )
		{	
			pItem->m_bIconized = TRUE;
			SendMessage( hWnd, WM_SYSCOMMAND, SC_MINIMIZE, 0 );
			g_TrayIcon.AddTrayIcon( hWnd );
			ShowWindow( hWnd, SW_HIDE );			
		}
		else
			result = DoCallWindowProc( pItem->m_DefWndProc, hWnd, Msg, wParam, lParam );

		DrawFrameControl( hDc, &rPos, DFC_BUTTON, DFCS_BUTTONPUSH );
		DrawIconize( hDc, rPos.left, rPos.top, 0 );		
		pItem->m_LBtnDown = FALSE;
		ReleaseDC(hWnd, hDc);
	}

	return result;
}

LRESULT CCaption::OnNcMouseMove( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam, CHookItem * pItem )
{
	HDC		hDc		;
	POINT	Pnt		;	
	RECT	rPos	;
	RECT	rWin	;
	LRESULT	result	;

	// Redraw caption buttons
	if ( ( hDc = GetWindowDC( hWnd ) ) != NULL )
	{
		// Convert mouse postion relative to caption rectangle
		GetWindowRect( hWnd, &rWin );
		Pnt.x = MAKEPOINTS( lParam ).x - rWin.left;
		Pnt.y = MAKEPOINTS( lParam ).y - rWin.top;

		// Calculate rectangle position of iconize button
		CCaption::CalcCaptionRect( hWnd, rPos );	
		rPos.top    += 2;	
		rPos.bottom -= 2;
		rPos.right  -= ( ( GetSystemMetrics( SM_CXSIZE ) * 3 ) - 2 );
		rPos.left    = rPos.right - ( GetSystemMetrics( SM_CXSIZE ) - 2 );

		// Check if mouse position is in rectangle
		if ( PtInRect( &rPos, Pnt ) )
		{
			DrawFrameControl( hDc, &rPos, DFC_BUTTON, ( pItem ->m_LBtnDown ) ? DFCS_BUTTONPUSH | DFCS_PUSHED : DFCS_BUTTONPUSH );
			DrawIconize( hDc, rPos.left, rPos.top, ( pItem ->m_LBtnDown ) ? 1 : 0 );
		}
		else
		{
			result = DoCallWindowProc( pItem->m_DefWndProc, hWnd, Msg, wParam, lParam );
			if ( pItem->m_LBtnDown )
			{				
				DrawFrameControl( hDc, &rPos, DFC_BUTTON, DFCS_BUTTONPUSH );
				DrawIconize( hDc, rPos.left, rPos.top, 0 );
			}			
		}
	
		DeleteObject( hDc );
	}

	return result;
}

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


Written By
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions