//----------------------------------------------------------------------------
// ObjectWindows
// Copyright (c) 1992, 1996 by Borland International, All Rights Reserved
//
/// \file
/// Implementation of TTinyCaption
//----------------------------------------------------------------------------
#include <owl/pch.h>
#include <owl/tinycapt.h>
#include <owl/gdiobjec.h>
#include <owl/uimetric.h>
#if !defined(WS_EX_TOOLWINDOW)
# define WS_EX_TOOLWINDOW 0x00000080L
#endif
namespace owl {
OWL_DIAGINFO;
//
// We only want to search this mixin for events, so don't include any base
// classes in Find()
//
DEFINE_RESPONSE_TABLE(TTinyCaption)
EV_WM_NCHITTEST,
EV_WM_NCPAINT,
EV_WM_NCCALCSIZE,
EV_WM_NCLBUTTONDOWN,
EV_WM_MOUSEMOVE,
EV_WM_LBUTTONUP,
EV_WM_NCACTIVATE,
EV_WM_SYSCOMMAND,
END_RESPONSE_TABLE;
//
/// Constructs a TTinyCaption object attached to the given parent window.
/// Initializes the caption font to 0 and TCEnabled to false so that the tiny
/// caption bar is not displayed automatically.
///
/// Rely on TWindow's default ctor since we will always be mixed-in and another
/// window will perform Init()
//
TTinyCaption::TTinyCaption()
{
TCEnabled = false;
CaptionFont = 0;
}
//
/// Destroys a TTinyCaption object and deletes the caption font.
//
TTinyCaption::~TTinyCaption()
{
delete CaptionFont;
}
//
/// Activates the tiny caption bar. By default, EnableTinyCaption replaces the
/// system window with a tiny caption window that does not close when the system
/// window is clicked. If the closeBox argument is true, clicking on the system menu
/// will close the window instead of bringing up the menu. You can use
/// EnableTinyCaption to hide the window if you are using a tiny caption in a
/// derived class. To diminish the tiny caption bar, try the following values:
/// \code
/// EnableTinyCaption(30, true);
/// \endcode
/// To maximize the tiny caption bar, use these values:
/// \code
/// EnableTinyCaption(48, true);
/// \endcode
//
void
TTinyCaption::EnableTinyCaption(int captionHeight, bool closeBox)
{
Border.cx = TUIMetric::CxBorder;
Border.cy = TUIMetric::CyBorder;
// Get width of window borders, these will vary with type of window
// Really 3 styles are supported:
// Fixed frame - WS_DLGFRAME, no WS_BORDER, WS_THICKFRAME optional and
// only affects sizability, not look
// Thick frame - WS_BORDER + WS_THICKFRAME, visible thick frame for sizing
// Thin frame - WS_BORDER only. No sizing.
//
if ((Attr.Style & WS_CAPTION) == WS_DLGFRAME) {
Frame.cx = TUIMetric::CxFixedFrame;
Frame.cy = TUIMetric::CyFixedFrame;
}
else {
Attr.Style |= WS_BORDER; // must have at least a border
Attr.Style &= ~WS_DLGFRAME; // but never a caption (WS_BORDER+WS_DLGFRAME)
if (Attr.Style & WS_THICKFRAME) {
Frame.cx = TUIMetric::CxSizeFrame;
Frame.cy = TUIMetric::CySizeFrame;
}
else {
Frame = Border;
}
}
CloseBox = closeBox;
// If running under Win95 or NT NewShell, then use its extended style to
// become a tiny caption
//
Attr.Style |= WS_CAPTION;
Attr.ExStyle |= WS_EX_TOOLWINDOW;
if (closeBox)
Attr.Style |= WS_SYSMENU;
CaptionHeight = captionHeight ? captionHeight : TUIMetric::CySmCaption.Get();
// !CQ Need to keep CaptionHeight sync'd on sys changes?
return;
}
//
/// Return where in the non client area we are. We only handle caption
/// bar area
//
/// Responds to a cursor move or press of a mouse button by calling DoNCHitTest. If
/// DoNCHitTest does not return esComplete, EvNCHitTest calls TWindow::EvNCHitTest.
//
uint
TTinyCaption::EvNCHitTest(const TPoint& screenPt)
{
uint er = 0;
if (DoNCHitTest(screenPt, er) == esComplete)
return er;
return TWindow::EvNCHitTest(screenPt);
}
//
/// If the caption bar is not enabled, returns esPartial. Otherwise, sends a message
/// to the caption bar that the mouse or the cursor has moved, and returns
/// esComplete.
//
TEventStatus
TTinyCaption::DoNCHitTest(const TPoint& screenPt, uint& evRes)
{
if (!TCEnabled)
return esPartial;
// Check style bits to see what to paint
//
long style = GetStyle();
bool hasSysMenu, hasMaximize, hasMinimize;
hasSysMenu = hasMaximize = hasMinimize = false;
if (style & WS_SYSMENU)
hasSysMenu = true;
if (style & WS_MAXIMIZEBOX)
hasMaximize = true;
if (style & WS_MINIMIZEBOX)
hasMinimize = true;
// Convert to window coordinates
//
TPoint winPt = screenPt - GetWindowRect().TopLeft();
if ((hasSysMenu || CloseBox) && GetSysBoxRect().Contains(winPt)) {
evRes = HTSYSMENU;
return esComplete;
}
else if (hasMinimize && GetMinBoxRect().Contains(winPt)) {
evRes = HTMINBUTTON;
return esComplete;
}
else if (hasMaximize && GetMaxBoxRect().Contains(winPt)) {
evRes = HTMAXBUTTON;
return esComplete;
}
// CaptionRect includes buttons so make sure it's last checked
// Should modify this one to allow clicking in left, top, right thin
// borders of caption
//
else if (GetCaptionRect().Contains(winPt)) {
evRes = HTCAPTION;
return esComplete;
}
else {
return esPartial;
}
}
//
/// Responds to a request to change a title bar or icon. Paints the indicated device
/// context or display screen and does any special painting required for the caption.
///
/// We only need to paint the caption. Someone else will paint the borders
//
void TTinyCaption::EvNCPaint(HRGN /*region*/)
{
DefaultProcessing(); // Default border painting
DoNCPaint(); // Then our special caption painting
}
//
/// If the caption bar is not enabled or is iconized, returns esPartial. Otherwise,
/// gets the focus, paints the caption, and returns esPartial, thus indicating that
/// a separate paint function must be called to paint the borders of the caption.
//
TEventStatus
TTinyCaption::DoNCPaint()
{
if (!TCEnabled || IsIconic())
return esPartial; // We don't do anything special for an Icon
// If we have focus or our children have focus, then we're active
// Note: We can't rely only on GetFocus here because when we're being
// restored from an icon, we're active, but don't yet have focus!
//
THandle focus = GetFocus();
PaintCaption(GetActiveWindow() == GetHandle() || focus == GetHandle() || IsChild(focus));
return esPartial; // Caller must call function to paint borders
}
//
/// Calculates the size of the command window including the caption and border so
/// that it can fit within the window.
//
uint
TTinyCaption::EvNCCalcSize(bool calcValidRects, NCCALCSIZE_PARAMS & calcSize)
{
uint er = TWindow::EvNCCalcSize(calcValidRects, calcSize);
DoNCCalcSize(calcValidRects, calcSize, er);
return er;
}
//
/// Return the size of our client area, leaving room for caption bar
//
/// If the caption bar is not enabled or is iconic, returns esPartial. Otherwise,
/// calculates the dimensions of the caption and returns esComplete.
//
TEventStatus
TTinyCaption::DoNCCalcSize(bool /*calcValidRects*/,
NCCALCSIZE_PARAMS & calcSize, uint& /*evRes*/)
{
if (!TCEnabled || IsIconic())
return esPartial;
calcSize.rgrc[0].top += GetCaptionRect().Height();
return esComplete;
}
//
/// Responds to a press of the left mouse button while the cursor is within the
/// nonclient area of the caption bar by calling DoNCLButtonDown. If DoNCLButtonDown
/// does not return esComplete, EvNCLButtonDown calls TWindow::EvNCLButtonDown.
//
void
TTinyCaption::EvNCLButtonDown(uint hitTest, const TPoint& screenPt)
{
// Display system menu, invert min/max icons (not), etc
//
if (DoNCLButtonDown(hitTest, screenPt) == esPartial)
TWindow::EvNCLButtonDown(hitTest, screenPt);
}
//
/// If the caption bar is not enabled, returns esPartial. Otherwise, determines if
/// the user released the button outside or inside a menu, and returns esComplete.
//
TEventStatus
TTinyCaption::DoNCLButtonDown(uint hitTest, const TPoint& screenPt)
{
if (!TCEnabled)
return esPartial;
TWindowDC wdc(*this);
switch (hitTest) {
case HTSYSMENU:
DownHit = HTSYSMENU;
if (CloseBox) {
IsPressed = true;
SetCapture();
TRect rect(GetSysBoxRect());
PaintCloseBox(wdc, rect, IsPressed);
}
else {
TRect sysBoxRect = GetSysBoxRect().InflatedBy(-1,-1);
sysBoxRect.right += 1;
wdc.PatBlt(sysBoxRect, PATINVERT);
// Display sys menu on button down
// Need to lock sys menu until user clicks outside
// Set flag to indicate we're expecting a sys command, & then send
// message to popup sys menu
//
WaitingForSysCmd = true;
SendMessage(WM_SYSCOMMAND, SC_MOUSEMENU|HTSYSMENU,
MkParam2(screenPt.x,screenPt.y));
// If we didn't execute a command, user released btn outside of menu
// If it was released in sys menu box, then redisplay menu as if it
// were brought up with a keystroke
//
if (WaitingForSysCmd) {
uint hitTest;
TPoint pt;
GetCursorPos(pt);
DoNCHitTest(pt, hitTest);
if (hitTest == HTSYSMENU)
SendMessage(WM_SYSCOMMAND, SC_KEYMENU|HTSYSMENU);
}
if (GetHandle())
wdc.PatBlt(sysBoxRect, PATINVERT);
}
return esComplete;
case HTMINBUTTON: {
DownHit = HTMINBUTTON;
IsPressed = true;
SetCapture();
TRect rect(GetMinBoxRect());
PaintMinBox(wdc, rect, IsPressed);
return esComplete;
}
case HTMAXBUTTON:{
DownHit = HTMAXBUTTON;
IsPressed = true;
SetCapture();
TRect rect(GetMaxBoxRect());
PaintMaxBox(wdc, rect, IsPressed);
return esComplete;
}
}
DownHit = HTNOWHERE;
return esPartial;
}
//
/// Responds to a mouse-move message by calling DoMouseMove. If DoMouseMove does not
/// return IsComplete, EvMouseMove calls TWindow::EvMouseMove.
//
void
TTinyCaption::EvMouseMove(uint modKeys, const TPoint& pt)
{
if (DoMouseMove(modKeys, pt) == esPartial)
TWindow::EvMouseMove(modKeys, pt);
}
//
/// Returns TEventStatus.
//
TEventStatus
TTinyCaption::DoMouseMove(uint /*modKeys*/, const TPoint& pt)
{
if (TCEnabled && DownHit != HTNOWHERE) {
uint hitTest;
TPoint screenPt = pt;
ClientToScreen(screenPt); // Cvt to screen coord
DoNCHitTest(screenPt, hitTest);
bool isNowPressed = hitTest == DownHit;
if (isNowPressed != IsPressed) {
IsPressed = isNowPressed;
TWindowDC wdc(*this);
switch (DownHit) {
case HTSYSMENU:
if (CloseBox){
TRect rect(GetSysBoxRect());
PaintCloseBox(wdc, rect, IsPressed);
}
return esComplete;
case HTMINBUTTON:{
TRect rect(GetMinBoxRect());
PaintMinBox(wdc, rect, IsPressed);
}
return esComplete;
case HTMAXBUTTON:{
TRect rect(GetMaxBoxRect());
PaintMaxBox(wdc, rect, IsPressed);
}
return esComplete;
}
}
}
return esPartial;
}
//
/// Responds to a mouse button-up message by calling DoLButtonUp. If DoLButtonUp
/// does not return IsComplete, EvLButtonUp calls TWindow::EvLButtonUp.
//
void
TTinyCaption::EvLButtonUp(uint modKeys, const TPoint& pt)
{
// If we're still in area where buton went down, then do it
//
if (DoLButtonUp(modKeys, pt) == esPartial)
TWindow::EvLButtonUp(modKeys, pt);
}
//
/// Releases the mouse capture if the caption bar is enabled and a mouse button is
/// pressed. Sets hitTest, indicating the mouse button has been pressed. Captures
/// the mouse message and repaints the smaller buttons before returning esComplete.
//
TEventStatus
TTinyCaption::DoLButtonUp(uint modKeys, const TPoint& pt)
{
if (TCEnabled && DownHit != HTNOWHERE) {
ReleaseCapture();
DoMouseMove(modKeys, pt);
uint hitTest;
TPoint screenPt = pt;
ClientToScreen(screenPt); // Cvt to screen coord
DoNCHitTest(screenPt, hitTest);
if (hitTest == DownHit) {
DownHit = HTNOWHERE;
switch (hitTest) {
case HTSYSMENU:
if (CloseBox)
PostMessage(WM_CLOSE);
return esComplete;
// We have to handle these buttons also to prevent defproc from
// painting the standard big min/max buttons when left mouse button is
// pressed
//
case HTMINBUTTON:
HandleMessage(WM_SYSCOMMAND, SC_MINIMIZE);
return esComplete;
case HTMAXBUTTON:
HandleMessage(WM_SYSCOMMAND, IsZoomed() ? SC_RESTORE : SC_MAXIMIZE);
return esComplete;
}
}
DownHit = HTNOWHERE;
}
return esPartial;
}
//
/// Responds to a request to change a title bar or icon by calling DoNCActivate. If
/// DoNCActivate does not return esComplete, EvNCActivate calls
/// TWindow::EvNCActivate.
//
bool
TTinyCaption::EvNCActivate(bool active)
{
bool er;
if (DoNCActivate(active, er) == esPartial)
er = TWindow::EvNCActivate(active);
return er;
}
//
/// If the tiny caption is not enabled or is iconic, returns esPartial. Otherwise,
/// repaints the caption as an active caption and returns esComplete.
//
TEventStatus
TTinyCaption::DoNCActivate(bool active, bool& evRes)
{
if (!TCEnabled || IsIconic())
return esPartial; // Let default do it's thing
PaintCaption(active);
evRes = true;
return esComplete;
}
//
/// EvCommand provides extra processing for commands, but lets the focus window and
/// its parent windows handle the command first.
//
TResult
TTinyCaption::EvCommand(uint id, THandle hCtl, uint notifyCode)
{
TResult er;
if (DoCommand(id, hCtl, notifyCode, er) == esComplete)
return er;
return TWindow::EvCommand(id, hCtl, notifyCode);
}
//
/// Displays the system menu using ::&TrackPopup so that TTinyCaption sends
/// WM_COMMAND instead of WM_SYSCOMMAND messages. If a system menu command is
/// received, it's then transformed into a WM_SYSCOMMAND message. If the tiny
/// caption bar is false, DoCommand returns esPartial.
//
TEventStatus
TTinyCaption::DoCommand(uint id, THandle /*hCtl*/, uint notifyCode, TResult& evRes)
{
// We're displaying system menu using TrackPopup...
// This will send us WM_COMMAND messages instead of WM_SYSCOMMAND msgs
// If we get a system menu command then transform it into a WM_SYSCOMMAND
//
if (!TCEnabled)
return esPartial;
if (id >= 0xF000) {
WaitingForSysCmd = false; // Let LButtonDown handler know that a command was sent
evRes = HandleMessage(WM_SYSCOMMAND, id, notifyCode);
return esComplete;
}
else {
evRes = 0;
return esPartial;
}
}
//
/// Responds to a WM_SYSCOMMAND message by calling DoSysCommand. If DoSysCommand
/// returns esPartial, EvSysCommand calls TWindow::EvSysCommand.
//
void
TTinyCaption::EvSysCommand(uint cmdType, const TPoint& p)
{
if (DoSysCommand(cmdType,p) == esPartial)
TWindow::EvSysCommand(cmdType, p);
}
//
/// Handle WM_SYSCOMMAND to make sure that SC_KEYMENU and SC_MOUSEMENU bring up
/// our sys menu at the right coord w/ respect to the tiny sys box.
//
/// If iconic, then let default windows processing deal with the menu
//
/// If the caption bar is not enabled, returns esPartial. If the caption bar is
/// iconized and the user clicks the icon, calls DoSysMenu to display the menu in
/// its normal mode and returns esComplete.
//
TEventStatus
TTinyCaption::DoSysCommand(uint cmdType, const TPoint&)
{
if (!TCEnabled)
return esPartial;
cmdType &= 0xFFF0;
if ((cmdType == SC_KEYMENU || cmdType == SC_MOUSEMENU) && !IsIconic()) {
DoSysMenu();
return esComplete;
}
return esPartial;
}
//
/// Paints a blank button.
//
void
TTinyCaption::PaintButton(TDC& dc, TRect& r, bool pressed)
{
TBrush winFrameBr(TColor::SysWindowFrame);
// dc.OWLFastWindowFrame(winFrameBr, r, 1, 1);
dc.FrameRect(r, winFrameBr);
r.Inflate(-1,-1);
dc.TextRect(r, TColor::Sys3dFace);
if (r.Width() > 4 && r.Height() > 4) {
if (pressed) {
dc.TextRect(r.left, r.top, r.right, r.top+1, TColor::Sys3dShadow);
dc.TextRect(r.left, r.top+1, r.left+1, r.bottom, TColor::Sys3dShadow);
}
else {
dc.TextRect(r.left, r.top, r.right-1, r.top+1, TColor::Sys3dHilight);
dc.TextRect(r.left, r.top+1, r.left+1, r.bottom-1, TColor::Sys3dHilight);
dc.TextRect(r.right-1, r.top+1, r.right, r.bottom, TColor::Sys3dShadow);
dc.TextRect(r.left+1, r.bottom-1, r.right-1, r.bottom, TColor::Sys3dShadow);
}
}
}
//
/// Paints a close box on the tiny caption bar. You can override the default box if
/// you want to design your own close box.
//
void
TTinyCaption::PaintCloseBox(TDC& dc, TRect& boxRect, bool pressed)
{
// Fill the box with light gray & draw bevel if possible
//
PaintButton(dc, boxRect, pressed);
if (pressed)
boxRect.Offset(1,1);
// Do something different to differentiate from standard system menu--
// draw a recessed black box glyph about half the button size, centered
//
int glyphWidth = boxRect.Width() > 7 ?
boxRect.Width()-boxRect.Width()/2-1 : boxRect.Width()-3;
int glyphHeight = boxRect.Height() > 7 ?
boxRect.Height()-boxRect.Height()/2-1 : boxRect.Height()-3;
if (glyphWidth > 1 && glyphHeight > 1) {
TRect glyphRect(0, 0, glyphWidth, glyphHeight);
glyphRect.Offset(boxRect.left + (boxRect.Width()-glyphWidth-1)/2,
boxRect.top + (boxRect.Height()-glyphHeight-1)/2);
dc.TextRect(glyphRect, TColor::Sys3dShadow);
glyphRect.Offset(1,1);
dc.TextRect(glyphRect, TColor::Sys3dHilight);
glyphRect.BottomRight().Offset(-1,-1);
dc.TextRect(glyphRect, TColor::SysBtnText);
}
}
//
/// Paints the system box.
//
void
TTinyCaption::PaintSysBox(TDC& dc, TRect& boxRect, bool /*pressed*/)
{
// Dont paint over the left & top borders
//
boxRect.left++;
boxRect.top++;
// Fill the box with 3d face
//
dc.TextRect(boxRect, TColor::Sys3dFace);
// Draw the ventilator (sysmenu) box, with shadow
//
TPoint begPt = boxRect.TopLeft().OffsetBy(2, (boxRect.Height()-3)/2);
TRect ventRect(begPt, TSize(boxRect.Width()-5, 3));
// Draw shadow down and right 1
//
dc.TextRect(ventRect.left+1, ventRect.top+1,
ventRect.right+1, ventRect.bottom+1, TColor::Sys3dShadow);
// Draw ventilator rectangle
//
TBrush btnTextBr(TColor::SysBtnText);
dc.FrameRect(ventRect, btnTextBr);
// Draw white interior of ventilator
//
dc.TextRect(ventRect.left+1, ventRect.top+1,
ventRect.right-1, ventRect.top+2, TColor::Sys3dHilight);
dc.TextRect(boxRect.right, boxRect.top,
boxRect.right+1, boxRect.bottom, TColor::SysBtnText);
}
//
/// Paints a minimize box on the tiny caption bar.
//
void
TTinyCaption::PaintMinBox(TDC& dc, TRect& boxRect, bool pressed)
{
// Fill the box with light gray & draw bevel if possible
//
PaintButton(dc, boxRect, pressed);
if (pressed)
boxRect.Offset(1,1);
int bh = boxRect.Height();
int bw = boxRect.Width();
TPoint begPt = boxRect.TopLeft().OffsetBy((bw+1)/4, (bh+2)/3);
TPoint endPt = begPt.OffsetBy((bw+1)/2,0);
while (begPt.x < endPt.x) {
dc.MoveTo(begPt);
dc.LineTo(endPt);
begPt.Offset(1,1);
endPt.Offset(-1,1);
}
}
//
/// Paints a maximize box on the tiny caption bar.
//
void
TTinyCaption::PaintMaxBox(TDC& dc, TRect& boxRect, bool pressed)
{
// Fill the box with light gray & draw bevel if possible
//
PaintButton(dc, boxRect, pressed);
if (pressed)
boxRect.Offset(1,1);
// Down triangle
//
int bh = boxRect.Height();
int bw = boxRect.Width();
if (IsZoomed()) {
TPoint begPt = boxRect.BottomLeft().OffsetBy((bw+1)/4, -bh*3/8);
TPoint endPt = begPt.OffsetBy((bw+1)/2, 0);
while (begPt.x < endPt.x) {
dc.MoveTo(begPt);
dc.LineTo(endPt);
begPt.Offset(1,1);
endPt.Offset(-1,1);
}
}
// Up triangle
//
{
TPoint begPt = boxRect.TopLeft().OffsetBy((bw+1)/4, IsZoomed() ? bh*3/8 : bh*2/3);
TPoint endPt = begPt.OffsetBy((bw+1)/2, 0);
while (begPt.x < endPt.x) {
dc.MoveTo(begPt);
dc.LineTo(endPt);
begPt.Offset(1, -1);
endPt.Offset(-1, -1);
}
}
}
//
/// Calls dc.SelectObject() to select the given rectangle and dc.PatBlt() to paint the
/// tiny caption bar using the currently selected brush for this device context.
//
void
TTinyCaption::PaintCaption(bool active)
{
// Paint caption background and caption text if any.
//
TWindowDC dc(*this);
TRect captRect = GetCaptionRect();
dc.SetTextColor(active ? TColor::SysCaptionText :
TColor::SysInactiveCaptionText);
// Could use a TBrush and PatBlt instead, but text backgrounds are always
// solid so this works well.
//
dc.TextRect(captRect, active ? TColor::SysActiveCaption :
TColor::SysInactiveCaption);
CHECK(CaptionFont);
dc.SelectObject(*CaptionFont);
dc.SetBkMode(TRANSPARENT);
LPCTSTR c = GetCaption() ? GetCaption() : _T("");
const auto textSize = dc.GetTextExtentPoint32(c);
// Calc x coord for text, so that text is centered between caption buttons
//
int xOrg = captRect.right - captRect.left;
long style = GetWindowLong(GWL_STYLE);
if (style & WS_MINIMIZEBOX)
xOrg -= GetMinBoxRect().Width();
if (style & WS_MAXIMIZEBOX)
xOrg -= GetMaxBoxRect().Width();
if ((style & WS_SYSMENU) || CloseBox)
xOrg -= GetSysBoxRect().Width();
xOrg -= textSize.cx;
if (xOrg<0)
xOrg = 0;
else
xOrg = xOrg/2;
xOrg += captRect.left;
if ((style & WS_SYSMENU) || CloseBox)
xOrg += GetSysBoxRect().Width();
dc.ExtTextOut(xOrg, captRect.top-Border.cy,
ETO_CLIPPED,
&captRect,
c,
static_cast<int>(::_tcslen(c))
);
dc.RestoreFont();
// Paint widgets: sysmenu or close button, minimize button, maximize button
// They currently all use a black pen
//
dc.SelectStockObject(BLACK_PEN);
// Paint system menu or close button
//
if (CloseBox){
TRect rect(GetSysBoxRect());
PaintCloseBox(dc, rect, false);
}
else if (style & WS_SYSMENU){
TRect rect(GetSysBoxRect());
PaintSysBox(dc, rect, false);
}
// Paint minimize button
//
if (style & WS_MINIMIZEBOX){
TRect rect(GetMinBoxRect());
PaintMinBox(dc, rect, false);
}
// Paint maximize button
//
if (style & WS_MAXIMIZEBOX){
TRect rect(GetMaxBoxRect());
PaintMaxBox(dc, rect, false);
}
// Draw window-frame color line under caption
//
TBrush winFrameBr(TColor::SysWindowFrame);
dc.FrameRect(captRect.left, captRect.bottom-1, captRect.right, captRect.bottom,
winFrameBr);
}
//
/// Gets the area of the caption for changing or repainting.
/// \note GetCaptionRect and GetSysBoxRect must be kept in sync!
//
TRect
TTinyCaption::GetCaptionRect()
{
// Get caption rect converted to window relative coordinates
//
TRect captRect(GetWindowRect());
captRect -= captRect.TopLeft();
captRect.left += Frame.cx;
captRect.top += Frame.cy;
captRect.right -= Frame.cx;
captRect.bottom = captRect.top + CaptionHeight;
return captRect;
}
//
/// Returns the size of the system box rectangle.
//
TRect
TTinyCaption::GetSysBoxRect()
{
TRect boxRect(GetCaptionRect());
boxRect.right = boxRect.left + CaptionHeight;
boxRect.left -= 1;
boxRect.top -= 1;
return boxRect;
}
//
/// Returns the size of the minimize box rectangle.
//
TRect
TTinyCaption::GetMinBoxRect()
{
// Far right on caption if no max box, else next to max box
//
TRect boxRect(GetMaxBoxRect());
if (GetWindowLong(GWL_STYLE) & WS_MAXIMIZEBOX)
boxRect.Offset(-CaptionHeight, 0);
return boxRect;
}
//
/// Returns the size of the maximize box rectangle.
//
TRect
TTinyCaption::GetMaxBoxRect()
{
TRect boxRect(GetCaptionRect());
boxRect.left = boxRect.right - CaptionHeight;
boxRect.top -= 1;
boxRect.right += 1;
return boxRect;
}
//
/// Gets the system menu and sets up menu items. DoSysMenu is also responsible for
/// displaying and tracking the status of the menu.
//
void
TTinyCaption::DoSysMenu()
{
HMENU hSysMenu = GetSystemMenu();
if (hSysMenu) {
uint32 style = GetWindowLong(GWL_STYLE);
EnableMenuItem(hSysMenu, SC_RESTORE, (IsIconic() || IsZoomed()) ? MF_ENABLED : MF_GRAYED);
EnableMenuItem(hSysMenu, SC_MOVE, (1/*style & WS_CAPTION*/) ? MF_ENABLED : MF_GRAYED);
EnableMenuItem(hSysMenu, SC_SIZE, (style & WS_THICKFRAME) ? MF_ENABLED : MF_GRAYED);
EnableMenuItem(hSysMenu, SC_MINIMIZE, ((style&WS_MINIMIZEBOX) && !IsIconic()) ? MF_ENABLED : MF_GRAYED);
EnableMenuItem(hSysMenu, SC_MAXIMIZE, ((style&WS_MAXIMIZEBOX) && !IsZoomed()) ? MF_ENABLED : MF_GRAYED);
TRect r(GetSysBoxRect());
ClientToScreen(r.TopLeft()); // Cvt pt to screen coord
ClientToScreen(r.BottomRight());
TrackPopupMenu(hSysMenu, TPM_LEFTALIGN | TPM_LEFTBUTTON,
r.left-Frame.cx, r.top-Frame.cy, 0, GetHandle(), &r);
}
}
#if OWL_PERSISTENT_STREAMS
IMPLEMENT_STREAMABLE(TTinyCaption);
//
// Reads an instance of TTinyCaption from the given ipstream
//
void*
TTinyCaption::Streamer::Read(ipstream& is, uint32 /*version*/) const
{
TTinyCaption* o = GetObject();
o->CaptionFont = 0;
is >> o->TCEnabled;
if (o->TCEnabled) {
int captionHeight;
is >> captionHeight >> o->CloseBox;;
o->EnableTinyCaption(captionHeight, o->CloseBox);
}
return o;
}
//
// Writes the TTinyCaption to the given opstream
//
void
TTinyCaption::Streamer::Write(opstream& os) const
{
TTinyCaption* o = GetObject();
os << o->TCEnabled;
if (o->TCEnabled) {
int captionHeight = (100*o->CaptionHeight) /
(o->Border.cy+TUIMetric::CyCaption);
os << captionHeight << o->CloseBox;
}
}
#endif
} // OWL namespace
/* ========================================================================== */
↑ V730 Not all members of a class are initialized inside the constructor. Consider inspecting: CloseBox, CaptionHeight, DownHit, IsPressed, WaitingForSysCmd.