Files
Oogynize/Hooks/ButtonHook/ButtonStrategy.cpp

390 lines
16 KiB
C++

#include "StdAfx.h"
#include "ButtonStrategy.h"
//#include "HiddenWindow.h" // for Some Strategies we need to create
// a hidden window and draw the buttons on it
////
// We are delay-loading the UXTheme.dll. In case we are running on
// a system where the dll doesn't exist, we'll only load it we know
// that this is a system where it should exist
////
#include "uxtheme.h"
////
// We are delay-loading the DWMapi.dll. In case we are running on
// a system where the dll doesn't exist, we'll only load it we know
// that this is a system where it should exist
////
#include "dwmapi.h"
using namespace Ooganizer;
//********************************************************************
// Clss ButtonStrategy
//
// Programmer Daniel Romischer
// Ooganizer Development Team
//
// Description Base/Abstract Class for all Button Strategies
//
// Note CalcCaptionRect() and CalcCaptionButtonRect()
// is implemented in the base class for now (as it appears
// to be the same calculation for all Button Strategies).
//
// Created 06-01-2008
//********************************************************************
//////////////////////////////////////////////////////////////////////
//********************************************************************
// Construction / Destruction
//********************************************************************
//////////////////////////////////////////////////////////////////////
ButtonStrategy::ButtonStrategy(void)
{
}
ButtonStrategy::~ButtonStrategy(void)
{
}
//////////////////////////////////////////////////////////////////////
// Func: CalcCaptionRect()
// Desc: Calculates the dimensions of the Caption Bar
//
// Prms: +hWnd, handle to a Windows
// +-Rect, returns the x,y RECT area dimension coordinates of the caption bar
// +-SIZE, returns the width and height of the Caption bar
//////////////////////////////////////////////////////////////////////
void ButtonStrategy::CalcCaptionRect(HWND hWnd, RECT &RectCaption, SIZE &heightNwidth)const
{
RECT Rect;
SIZE sFrame;
DWORD dStyle = GetWindowLong( hWnd, GWL_STYLE );
// Get frame size of window
// (x and y height width dim of the resizable or non-resizable windows frame)
sFrame.cy = GetSystemMetrics( ( dStyle & WS_THICKFRAME ) ? SM_CYSIZEFRAME : SM_CYFIXEDFRAME );
sFrame.cx = GetSystemMetrics( ( dStyle & WS_THICKFRAME ) ? SM_CXSIZEFRAME : SM_CXFIXEDFRAME );
// Gets the location of the Window
GetWindowRect( hWnd, &Rect );
// Height and Width of the Window
LONG height = Rect.bottom - Rect.top; // Window height not intersting to us (not used)
LONG width = Rect.right - Rect.left;
// Pass the CaptionBar Dimension out
RectCaption.top = sFrame.cy; // 4, 8
RectCaption.left = sFrame.cx; // 4, 8
RectCaption.right = width - sFrame.cy; // 771
// SM_CYCAPTION = The height of a caption area, in pixels
// SM_CYBORDER = The height of a window border
int heightCaption = GetSystemMetrics( SM_CYCAPTION ); // 20
int heightWindowBorder = GetSystemMetrics( SM_CYBORDER ); // 1
RectCaption.bottom = heightCaption;
//heightCaption gives us the correct caption height, but in order to get the exact RECT location,
//calculated from top left, we need to add sFrame.cy to it. ~we substract the bottom border because,
//otherwise the height will be too long
//sFrame.cy + heightCaption - heightWindowBorder;
// sample return
// top = 4, left = 4, bottom = 23, right = 771
// Pass out the height & Width of the CaptionBar
heightNwidth.cx = heightCaption;
heightNwidth.cy = width;
}
//********************************************************************
// Clss ClassicButtonStrategy
//
// Description Implementation for our Windows Classic Theme Strategy
//
// Note Uses DrawFrameControl() to draw the Button. This will
// Only work in Windows2000/XP without theme (classic View)
//
// Created 06-01-2008
//********************************************************************
//////////////////////////////////////////////////////////////////////
//********************************************************************
// Construction / Destruction
//********************************************************************
//////////////////////////////////////////////////////////////////////
ClassicButtonStrategy::ClassicButtonStrategy()
{
}
ClassicButtonStrategy::~ClassicButtonStrategy()
{
}
//////////////////////////////////////////////////////////////////////
// Func: draw()
// Desc: generic draw function - called for all default messages
//////////////////////////////////////////////////////////////////////
void ClassicButtonStrategy::draw(HWND hWnd, const HDC &hDc, const RECT &rPos) const
{
// Use the regular Frame Control *Windows Classic*
// DrawFrameControl( hDc, const_cast<LPRECT>(&rPos), DFC_BUTTON, DFCS_BUTTONPUSH );
HICON hIcon = (HICON) LoadImage(NULL, L"C:\\bridge.ico", IMAGE_ICON, 0, 0, LR_LOADFROMFILE);
DrawIcon(hDc, rPos.left, rPos.top, hIcon);
}
//////////////////////////////////////////////////////////////////////
// Func: drawButtonUp()
// Desc: draw the button in an up state
//////////////////////////////////////////////////////////////////////
void ClassicButtonStrategy::drawButtonUp(HWND hWnd, const HDC &hDc, const RECT &rPos) const
{
// Use the regular Frame Control *Windows Classic*
// DrawFrameControl( hDc, const_cast<LPRECT>(&rPos), DFC_BUTTON, DFCS_BUTTONPUSH );
HICON hIcon = (HICON) LoadImage(NULL, L"C:\\bridge.ico", IMAGE_ICON, 0, 0, LR_LOADFROMFILE);
DrawIcon(hDc, rPos.left, rPos.top, hIcon);
}
//////////////////////////////////////////////////////////////////////
// Func: drawButtonDown()
// Desc: draw the button in a down state
//////////////////////////////////////////////////////////////////////
void ClassicButtonStrategy::drawButtonDown(HWND hWnd, const HDC &hDc, const RECT &rPos) const
{
// Use the regular Frame Control *Windows Classic*
// DrawFrameControl( hDc, const_cast<LPRECT>(&rPos), DFC_BUTTON, DFCS_BUTTONPUSH | DFCS_PUSHED );
HICON hIcon = (HICON) LoadImage(NULL, L"C:\\bridge.ico", IMAGE_ICON, 0, 0, LR_LOADFROMFILE);
DrawIcon(hDc, rPos.left, rPos.top, hIcon);
}
//********************************************************************
// Clss AeroButtonStrategy
//
// Description Implementation for our Windows Aero Theme Strategy
//
// Note
//
//
// Created 06-01-2008
//********************************************************************
//////////////////////////////////////////////////////////////////////
//********************************************************************
// Construction / Destruction
//********************************************************************
//////////////////////////////////////////////////////////////////////
AeroButtonStrategy::AeroButtonStrategy()
{
}
AeroButtonStrategy::~AeroButtonStrategy()
{
}
//////////////////////////////////////////////////////////////////////
// Func: CalcCaptionButtonRect()
// Desc: Calculates the dimensions of the Caption Button. Takes into
// account the number of caption buttons on the window and returns
// the pos (RECT) where to draw the Caption Button.
//
// Prms: +hWnd, handle to a Windows
// +-RectButtonPos, returns the x,y dimension of where to place the Button
//////////////////////////////////////////////////////////////////////
void AeroButtonStrategy::CalcCaptionButtonRect(HWND hWnd, RECT& RectButtonPos) const
{
// Button Constants
const LONG BUTTON_MARGIN = 2; // The Margin Space between the Buttons
//The width of a button in a window caption or title bar, in pixels
const LONG CAPTION_WIDTH = GetSystemMetrics(SM_CXSIZE); // should be 28
log(LOGGING_HIGH, "Caption Width = %i", CAPTION_WIDTH);
RECT rect;
SIZE size;
// Get The dimensions of the CaptionBar
CalcCaptionRect(hWnd,rect,size);
// sample return from CalcCaptionRect()
// top = 4, left = 4, bottom = 23, right = 771
// On Aero the distance of the Button is 10 not 6. Calculating by multiplying top * 2 (=8)
// ~this makes sense because our Rect start at the top most location (not where vista wants to draw the button
const LONG TOP_PLACEMENT = (2 * rect.top) + BUTTON_MARGIN;
const LONG BOTTOM_PLACEMENT = rect.bottom - BUTTON_MARGIN;
// Left and Right Placement has to be calculated using the spacing on the right, the caption button widths,
// of (close, max, min) and the margins in between the buttons. (RECT includes all caption buttons),
// we also subtract rect.top from the left because a window border on right is not considered (+ another margin)
const LONG RIGHT_PLACEMENT = rect.right - (CAPTION_WIDTH * 3) - (BUTTON_MARGIN * 3) - (rect.top + BUTTON_MARGIN);
const LONG LEFT_PLACEMENT = RIGHT_PLACEMENT - CAPTION_WIDTH; // - BUTTON_MARGIN?
////
// Pass out the dimension of the CaptionButton
////
RectButtonPos.top = TOP_PLACEMENT;
RectButtonPos.bottom = BOTTOM_PLACEMENT;
RectButtonPos.right = RIGHT_PLACEMENT;
RectButtonPos.left = LEFT_PLACEMENT;
}
//////////////////////////////////////////////////////////////////////
// Func: draw()
// Desc: generic draw function - called for all default messages
//////////////////////////////////////////////////////////////////////
void AeroButtonStrategy::draw(HWND hWnd, const HDC &hDc, const RECT &rPos) const
{
// HTHEME hTheme = OpenThemeData(hWnd, L"OkButton;Button;Window");
// HTHEME hTheme = OpenThemeData(hWnd, L"Button");
// DrawThemeParentBackground(hWnd,hDc,&rPos);
// DrawThemeBackground(hTheme,hDc,0,0,&rPos,0);
HICON hIcon = (HICON) LoadImage(NULL, L"C:\\VistaNoAero.ico", IMAGE_ICON, 0, 0, LR_LOADFROMFILE);
DrawIcon(hDc, rPos.left, rPos.top, hIcon);
}
//////////////////////////////////////////////////////////////////////
// Func: drawButtonUp()
// Desc: draw the button in an up state
//////////////////////////////////////////////////////////////////////
void AeroButtonStrategy::drawButtonUp(HWND hWnd, const HDC &hDc, const RECT &rPos) const
{
HICON hIcon = (HICON) LoadImage(NULL, L"C:\\bridge.ico", IMAGE_ICON, 0, 0, LR_LOADFROMFILE);
DrawIcon(hDc, rPos.left, rPos.top, hIcon);
}
//////////////////////////////////////////////////////////////////////
// Func: drawButtonDown()
// Desc: draw the button in a down state
//////////////////////////////////////////////////////////////////////
void AeroButtonStrategy::drawButtonDown(HWND hWnd, const HDC &hDc, const RECT &rPos) const
{
HICON hIcon = (HICON) LoadImage(NULL, L"C:\\bridge.ico", IMAGE_ICON, 0, 0, LR_LOADFROMFILE);
DrawIcon(hDc, rPos.left, rPos.top, hIcon);
}
//********************************************************************
// Clss VistaNoAeroStrategy
//
// Description Implementation for Vista when Aero (Glass) is not running
//
// Note
//
//
// Created 06-01-2008
//********************************************************************
//////////////////////////////////////////////////////////////////////
//********************************************************************
// Construction / Destruction
//********************************************************************
//////////////////////////////////////////////////////////////////////
VistaNoAeroStrategy::VistaNoAeroStrategy()
{
}
VistaNoAeroStrategy::~VistaNoAeroStrategy()
{
}
//////////////////////////////////////////////////////////////////////
// Func: CalcCaptionButtonRect()
// Desc: Calculates the dimensions of the Caption Button. Takes into
// account the number of caption buttons on the window and returns
// the pos (RECT) where to draw the Caption Button.
//
// Prms: +hWnd, handle to a Windows
// +-RectButtonPos, returns the x,y dimension of where to place the Button
//////////////////////////////////////////////////////////////////////
void VistaNoAeroStrategy::CalcCaptionButtonRect(HWND hWnd, RECT& RectButtonPos) const
{
// Button Constants
const LONG BUTTON_MARGIN = 2; // The Margin Space between the Buttons
//The width of a button in a window caption or title bar, in pixels
const LONG CAPTION_WIDTH = GetSystemMetrics(SM_CXSIZE); // 32 (appears to include left and righ Margin)
RECT rect;
SIZE size;
// Get The dimensions of the CaptionBar
CalcCaptionRect(hWnd,rect,size);
log(LOGGING_HIGH, "rect is top %i, bottom %i, left %i, right %i", rect.top, rect.bottom, rect.left, rect.right);
// sample return from CalcCaptionRect()
// Vista Aero
// top = 4, left = 4, bottom = 23, right = 771
// Vista NoAero
// rect is top 8, bottom 27, left 8, right 831
// On Aero the distance of the Button is 10 not 6. Calculating by multiplying top * 2 (=8)
// ~this makes sense because our Rect start at the top most location (not where vista wants to draw the button
const LONG TOP_PLACEMENT = 10; //(2 * rect.top) + BUTTON_MARGIN;
const LONG BOTTOM_PLACEMENT = rect.bottom - BUTTON_MARGIN;
// Left and Right Placement has to be calculated using the spacing on the right, the caption button widths,
// of (close, max, min) and the margins in between the buttons. (RECT includes all caption buttons),
// we also subtract rect.top from the left because a window border on right is not considered (+ another margin)
// 96
const LONG RIGHT_PLACEMENT = rect.right - 96;
const LONG LEFT_PLACEMENT = RIGHT_PLACEMENT - 28; // - BUTTON_MARGIN?
////
// Pass out the dimension of the CaptionButton
////
RectButtonPos.top = TOP_PLACEMENT;
RectButtonPos.bottom = BOTTOM_PLACEMENT;
RectButtonPos.right = RIGHT_PLACEMENT;
RectButtonPos.left = LEFT_PLACEMENT;
}
//////////////////////////////////////////////////////////////////////
// Func: draw()
// Desc: generic draw function - called for all default messages
//////////////////////////////////////////////////////////////////////
void VistaNoAeroStrategy::draw(HWND hWnd, const HDC &hDc, const RECT &rPos) const
{
HICON hIcon = (HICON) LoadImage(NULL, L"C:\\VistaNoAero.ico", IMAGE_ICON, 28, 15, LR_LOADFROMFILE);
DrawIcon(hDc, rPos.left, rPos.top, hIcon);
}
//////////////////////////////////////////////////////////////////////
// Func: drawButtonUp()
// Desc: draw the button in an up state
//////////////////////////////////////////////////////////////////////
void VistaNoAeroStrategy::drawButtonUp(HWND hWnd, const HDC &hDc, const RECT &rPos) const
{
}
//////////////////////////////////////////////////////////////////////
// Func: drawButtonDown()
// Desc: draw the button in a down state
//////////////////////////////////////////////////////////////////////
void VistaNoAeroStrategy::drawButtonDown(HWND hWnd, const HDC &hDc, const RECT &rPos) const
{
}
//********************************************************************
// Clss XPButtonStrategy
//
// Description Implementation for Windows XP Themed Strategy
//
// Note
//
//
// Created 06-01-2008
//********************************************************************
//////////////////////////////////////////////////////////////////////
//********************************************************************
// Construction / Destruction
//********************************************************************
//////////////////////////////////////////////////////////////////////
XPButtonStrategy::XPButtonStrategy()
{
}
XPButtonStrategy::~XPButtonStrategy()
{
}
//////////////////////////////////////////////////////////////////////
// Func: draw()
// Desc: generic draw function - called for all default messages
//////////////////////////////////////////////////////////////////////
void XPButtonStrategy::draw(HWND hWnd, const HDC &hDc, const RECT &rPos) const
{
}
//////////////////////////////////////////////////////////////////////
// Func: drawButtonUp()
// Desc: draw the button in an up state
//////////////////////////////////////////////////////////////////////
void XPButtonStrategy::drawButtonUp(HWND hWnd, const HDC &hDc, const RECT &rPos) const
{
}
//////////////////////////////////////////////////////////////////////
// Func: drawButtonDown()
// Desc: draw the button in a down state
//////////////////////////////////////////////////////////////////////
void XPButtonStrategy::drawButtonDown(HWND hWnd, const HDC &hDc, const RECT &rPos) const
{
}