#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(&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(&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(&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 { }