Return to Appendix B.

ESBUTTON.CPP
// Matt Streeter
// 2/27/00
// ESBUTTON.CPP
// Implementation of class TESButton; custom implementation of TButton control
// Copyright Matt Streeter, 2000.  All rights reserved

#include "esbutton.h"
#include "eswindow.h"
#include <owl\dc.h>

// Static colors
TESButtonNode *TESButton::mpESButtonList=0;
TColor TESButton::mFrameHighlightColor(196,196,255);
TColor TESButton::mFrameLowlightColor(128,128,255);

// FRAME_WIDTH specifies the width, in pixels, of the frame drawn around a
// TESButton when the mouse moves over it.
#define FRAME_WIDTH 2

// The following three #defines specify the face, height, and weight,
// respectively, of the font used for the button label of a TESButton.
#define LABEL_FONT_FACE "MS Sans Serif"
#define LABEL_FONT_HEIGHT 18
#define LABEL_FONT_WEIGHT FW_BOLD

// The following two #defines determine the amount of vertical and horizontal
// padding, in pixels, between the button text and the edge of the window.
#define BUTTON_VPADDING 5
#define BUTTON_HPADDING 5

#if(!USE_PRETTY_BUTTONS)
TESButton::TESButton(TWindow* parent,int Id,const char far* text,int X,int Y,
	int W,int H,bool isDefault,TModule* module)
	:TButton(parent,Id,text,X,Y,W,H,isDefault,module)
{
}
#else

DEFINE_RESPONSE_TABLE1(TESButton,TButton)
	EV_WM_MOUSEMOVE,
END_RESPONSE_TABLE;

// Public member functions

TESButton::TESButton(TESWindow* parent,int Id,const char far* text,
	int X,int Y,int W,int H,bool isDefault,TModule* module)
	:TButton((TWindow*)parent,Id,text,X,Y,W,H,isDefault,module)
{
	AddToButtonList(this);
	Attr.Style|=BS_OWNERDRAW;
	mbMouseIn=0;
	mpESParent=parent;
}

TESButton::TESButton(TESWindow *parent,int Id,const char far* text,
	int X,int Y,bool isDefault,TModule* module)
	:TButton((TWindow*)parent,Id,text,X,Y,GetMinWidth(parent,(char*)text),
		GetMinHeight(parent,(char*)text),isDefault,module)
{
	AddToButtonList(this);
	Attr.Style|=BS_OWNERDRAW;
	mbMouseIn=0;
	mpESParent=parent;
}

TESButton::~TESButton()
{
	RemoveFromButtonList(this);
}

int TESButton::IsESButton(TWindow *pWindow)
{
	TESButtonNode *pCurrent=mpESButtonList;
	while(pCurrent)
	{
		if((TWindow*)(pCurrent->pButton)==pWindow)
			return(1);
		pCurrent=pCurrent->pNext;
	}
	return(0);
}

void TESButton::EvMouseMove(uint modKeys, TPoint& point)
{
	if(!mbMouseIn)
	{
		MouseEnter();
		mbMouseIn=1;
	}

	ClientToScreen(point);
	mpESParent->EvChildMouseMove(modKeys,point);
}

void TESButton::EvParentMouseMove(uint /*modKeys*/, TPoint& point)
{
	TRect WRect;
	GetWindowRect(WRect);
	if(WRect.Contains(point))
	{
		if(!mbMouseIn)
		{
			MouseEnter();
			mbMouseIn=1;
		}
	}
	else if(mbMouseIn)
	{
		MouseLeave();
      mbMouseIn=0;
	}
}

// Protected member functions

void TESButton::MouseEnter()
{
	TBrush HiBrush(mFrameHighlightColor);
	TBrush LoBrush(mFrameLowlightColor);
	TClientDC dc(*this);
	TRect ClientRect;
	GetClientRect(ClientRect);

	// draw top bar
	dc.FillRect(ClientRect.left,ClientRect.top,ClientRect.right+1,
		ClientRect.top+FRAME_WIDTH,HiBrush);
	// draw bottom bar
	dc.FillRect(ClientRect.left,ClientRect.bottom-FRAME_WIDTH+1,
		ClientRect.right+1,ClientRect.bottom+1,LoBrush);
	// draw left bar
	dc.FillRect(ClientRect.left,ClientRect.top,
		ClientRect.left+FRAME_WIDTH,ClientRect.bottom+1,HiBrush);
	// draw right bar
	dc.FillRect(ClientRect.right-FRAME_WIDTH+1,ClientRect.top,
		ClientRect.right+1,ClientRect.bottom+1,LoBrush);
}

void TESButton::MouseLeave()
{
	Draw();
}

void TESButton::GetWindowClass(WNDCLASS& WndClass)
{
	TWindow::GetWindowClass(WndClass);
	WndClass.hbrBackground=(HBRUSH)(TESWindow::mBackgroundFillBrush);
}

void TESButton::ODADrawEntire(DRAWITEMSTRUCT far&)
{
	Draw();
}

void TESButton::Draw()
{
	TClientDC dc(*this);
	TRect ClientRect;
	GetClientRect(ClientRect);
	dc.FillRect(ClientRect.left,ClientRect.top,ClientRect.right+1,
		ClientRect.bottom+1,TESWindow::mBackgroundFillBrush);

	// Draw button label
	dc.SetBkColor(TESWindow::mBackgroundColor);
	dc.SetTextColor(TESWindow::mTextColor);

	TFont LabelFont(LABEL_FONT_FACE,LABEL_FONT_HEIGHT,0,0,0,LABEL_FONT_WEIGHT,
		DEFAULT_PITCH|FF_DONTCARE,false,false,false,1,OUT_DEFAULT_PRECIS,
		CLIP_DEFAULT_PRECIS,PROOF_QUALITY);
	dc.SelectObject(LabelFont);
	TSize Size=dc.GetTextExtent(Title,strlen(Title));
	TPoint TextPos(ClientRect.left+(ClientRect.Width()+1-Size.cx)/2,
		ClientRect.top+(ClientRect.Height()+1-Size.cy)/2);
	dc.TextOut(TextPos,Title,strlen(Title));
}

int TESButton::GetMinHeight(TWindow *pParent,char *pText)
{
	TClientDC dc(*pParent);
	TFont LabelFont(LABEL_FONT_FACE,LABEL_FONT_HEIGHT,0,0,0,LABEL_FONT_WEIGHT,
		DEFAULT_PITCH|FF_DONTCARE,false,false,false,1,OUT_DEFAULT_PRECIS,
		CLIP_DEFAULT_PRECIS,PROOF_QUALITY);
	dc.SelectObject(LabelFont);
	TSize Size=dc.GetTextExtent(pText,strlen(pText));
	return(Size.cy+BUTTON_VPADDING*2);
}

int TESButton::GetMinWidth(TWindow *pParent,char *pText)
{
	TClientDC dc(*pParent);
	TFont LabelFont(LABEL_FONT_FACE,LABEL_FONT_HEIGHT,0,0,0,LABEL_FONT_WEIGHT,
		DEFAULT_PITCH|FF_DONTCARE,false,false,false,1,OUT_DEFAULT_PRECIS,
		CLIP_DEFAULT_PRECIS,PROOF_QUALITY);
	dc.SelectObject(LabelFont);
	TSize Size=dc.GetTextExtent(pText,strlen(pText));
	return(Size.cx+BUTTON_HPADDING*2);
}

// Private member functions

int TESButton::AddToButtonList(TESButton *pButton)
{
	if(!mpESButtonList)
	{
		mpESButtonList=new TESButtonNode;
		if(!mpESButtonList)
			return(-1);
		mpESButtonList->pButton=pButton;
		mpESButtonList->pNext=0;
		return(0);
	}

	TESButtonNode *pLast=mpESButtonList;
	while(pLast->pNext)
		pLast=pLast->pNext;
	pLast->pNext=new TESButtonNode;
	if(!pLast->pNext)
		return(-1);
	pLast->pNext->pButton=pButton;
	pLast->pNext->pNext=0;
	return(0);
}

int TESButton::RemoveFromButtonList(TESButton *pButton)
{
	TESButtonNode *pLast=0,*pCurrent=mpESButtonList;
	while(pCurrent)
	{
		if(pCurrent->pButton==pButton)
		{
			if(!pLast)
				mpESButtonList=0;
			else
				pLast->pNext=pCurrent->pNext;
			delete(pCurrent);
			return(0);
		}
		pLast=pCurrent;
		pCurrent=pCurrent->pNext;
	}
   return(-1);
}

#endif

Return to Appendix B.