// Modified by:
// Created: 04/01/98
// RCS-ID: $Id$
-// Copyright: (c) Julian Smart and Markus Holzem
-// Licence: wxWindows license
+// Copyright: (c) Julian Smart
+// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#ifdef __GNUG__
#endif
#ifndef WX_PRECOMP
-#include "wx/setup.h"
-#include "wx/app.h"
-#include "wx/utils.h"
#endif
-#if wxUSE_ITSY_BITSY
-
#include "wx/minifram.h"
-#include "wx/msw/private.h"
-
-#ifdef __GNUWIN32__
-#include "wx/msw/gnuwin32/extra.h"
-#endif
-#if !USE_SHARED_LIBRARY
IMPLEMENT_DYNAMIC_CLASS(wxMiniFrame, wxFrame)
-#endif
-
-long wxMiniFrame::MSWDefWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
-{
- if ((GetWindowStyleFlag() & wxTINY_CAPTION_HORIZ) ||
- (GetWindowStyleFlag() & wxTINY_CAPTION_VERT))
- return ::ibDefWindowProc((HWND) GetHWND(), nMsg, wParam, lParam);
- else if ( m_oldWndProc )
- return ::CallWindowProc(CASTWNDPROC m_oldWndProc, (HWND) GetHWND(), (UINT) nMsg, (WPARAM) wParam, (LPARAM) lParam);
- else
- return ::DefWindowProc((HWND) GetHWND(), nMsg, wParam, lParam);
-}
-
-wxMiniFrame::~wxMiniFrame(void)
-{
-}
-
-/////////////////////////////////////////////////////////////////////////
-//
-// Project: ItsyBitsy window support module
-// Module: itsybits.c
-//
-//
-// ItsyBitsy is a support module that allows you to create windows
-// that look and act very much like a popup window witha system
-// menu and caption bar, except everything is scaled to about 2/3
-// scale.
-//
-// For documentation on how to use ItsyBits, read the document
-// ITSYBITS.DOC.
-//
-// Revisions:
-// 9/27/91 Charlie Kindel (cek/ckindel)
-// Wrote and documented it.
-//
-// 1/14/93 cek
-// 2/23/93 cek Added minimize/maximize buttons.
-// 3/18/93 cek Fixed system menu bug where system menu
-// popped back up if you clicked on the
-// icon again while it was up.
-// 3/24/93 cek More comments. Fixed DS_MODALDIALOG style
-// problem. Use auto precompiled headers
-// in MSVC.
-//
-//////////////////////////////////////////////////////////////////////////
-
-#include <windows.h>
-#include <windowsx.h>
-
-#include <string.h>
-
-#if !defined( __WATCOMC__ ) && !defined( __MWERKS__ )
-#include <memory.h>
-#endif
-
-#include <stdlib.h>
-
-#ifndef _RGB_H_
-#define _RGB_H_
-
- // Some mildly useful macros for the standard 16 colors
- #define RGBBLACK RGB(0,0,0)
- #define RGBRED RGB(128,0,0)
- #define RGBGREEN RGB(0,128,0)
- #define RGBBLUE RGB(0,0,128)
-
- #define RGBBROWN RGB(128,128,0)
- #define RGBMAGENTA RGB(128,0,128)
- #define RGBCYAN RGB(0,128,128)
- #define RGBLTGRAY RGB(192,192,192)
-
- #define RGBGRAY RGB(128,128,128)
- #define RGBLTRED RGB(255,0,0)
- #define RGBLTGREEN RGB(0,255,0)
- #define RGBLTBLUE RGB(0,0,255)
-
- #define RGBYELLOW RGB(255,255,0)
- #define RGBLTMAGENTA RGB(255,0,255)
- #define RGBLTCYAN RGB(0,255,255)
- #define RGBWHITE RGB(255,255,255)
-#endif
-
-#ifndef GlobalAllocPtr
-#define GlobalPtrHandle(lp) \
- ((HGLOBAL)GlobalHandle(lp))
-
-#define GlobalLockPtr(lp) \
- ((BOOL)GlobalLock(GlobalPtrHandle(lp)))
-#define GlobalUnlockPtr(lp) \
- GlobalUnlock(GlobalPtrHandle(lp))
-
-#define GlobalAllocPtr(flags, cb) \
- (GlobalLock(GlobalAlloc((flags), (cb))))
-#define GlobalReAllocPtr(lp, cbNew, flags) \
- (GlobalUnlockPtr(lp), GlobalLock(GlobalReAlloc(GlobalPtrHandle(lp) , (cbNew), (flags))))
-#define GlobalFreePtr(lp) \
- (GlobalUnlockPtr(lp), (BOOL)GlobalFree(GlobalPtrHandle(lp)))
-#endif
-
-#if defined(__BORLANDC__) || defined(__WATCOMC__)
-#define max(a,b) (((a) > (b)) ? (a) : (b))
-#define min(a,b) (((a) < (b)) ? (a) : (b))
-#endif
-
-// CAPTIONXY is the default size of the system menu icon. This
-// determines the height/width of the caption.
-//
-// The value that results from the following formula works out
-// nicely for the veritcal caption on VGA, 8514 (Large Fonts),
-// 8514 (Small Fonts), XGA (Small Fonts), XGA (Large Fonts),
-// and TIGA (Small Fonts). It may not be good on other displays.
-//
-// The problem is that TT fonts turn into bitmap fonts when they
-// are sized below a certain threshold. The idea is to make the
-// size of the caption just big enough to get the smallest TT
-// (scalable) font to fit.
-//
-#define CAPTIONXY (GetSystemMetrics( SM_CYCAPTION ) / 2 + 1)
-
-#define TestWinStyle( hWnd, dwStyleBit ) \
- (((DWORD)GetWindowLong( hWnd, GWL_STYLE ) & (DWORD)dwStyleBit) ? TRUE : FALSE )
-#define HASCAPTION( hwnd ) (TestWinStyle( hwnd, IBS_VERTCAPTION ) ||\
- TestWinStyle( hwnd, IBS_HORZCAPTION ))
-
-#define SETCAPTIONSIZE(h,i) (UINT)SetProp(h,"ibSize",(HANDLE)i)
-#define GETCAPTIONSIZE(h) (UINT)GetProp(h,"ibSize")
-#define FREECAPTIONSIZE(h) RemoveProp(h,"ibSize")
-
-#define SETMENUWASUPFLAG(h,i) (UINT)SetProp(h,"ibFlag",(HANDLE)i)
-#define GETMENUWASUPFLAG(h) (UINT)GetProp(h,"ibFlag")
-#define FREEMENUWASUPFLAG(h) RemoveProp(h,"ibFlag")
-
-/////////////////////////////////////////////////////////////////////
-// Little known fact:
-// ExtTextOut() is the fastest way to draw a filled rectangle
-// in Windows (if you don't want dithered colors or borders).
-//
-// Unfortunately there is a bug in the Windows 3.0 8514 driver
-// in using ExtTextOut() to a memory DC. If you are drawing
-// to an off screen bitmap, then blitting that bitmap to the
-// display, do not #define wxUSE_EXTTEXTOUT below.
-//
-// The following macro (DRAWFASTRECT) draws a filled rectangle
-// with no border and a solid color. It uses the current back-
-// ground color as the fill color.
-//////////////////////////////////////////////////////////////////////
-#define wxUSE_EXTTEXTOUT
-#ifdef wxUSE_EXTTEXTOUT
- #define DRAWFASTRECT(hdc,lprc) ExtTextOut(hdc,0,0,ETO_OPAQUE,lprc,NULL,0,NULL)
-#else
- #define DRAWFASTRECT(hdc,lprc) {\
- HBRUSH hbr = CreateSolidBrush( GetBkColor( hdc ) ) ;\
- hbr = SelectObject(hdc, hbr) ;\
- PatBlt(hdc,(lprc)->left,(lprc)->top,(lprc)->right-(lprc)->left,(lprc)->bottom-(lprc)->top,PATCOPY) ;\
- hbr = SelectObject(hdc, hbr) ;\
- DeleteObject( hbr ) ;\
- }
-#endif
-
-// The DrawArrow function takes the following to indicate what
-// kind of arrow to draw.
-//
-#define ARROW_UP 0
-#define ARROW_DOWN 1
-#define ARROW_RESTORE 2
-
-BOOL PASCAL DepressMinMaxButton( HWND hWnd, UINT uiHT, LPRECT ) ;
-BOOL PASCAL DoMenu( HWND hWnd ) ;
-void PASCAL SetupSystemMenu( HWND hWnd, HMENU hMenu ) ;
-BOOL PASCAL GetCaptionRect( HWND hWnd, LPRECT lprc ) ;
-BOOL PASCAL GetIconRect( HWND hWnd, LPRECT lprc ) ;
-BOOL PASCAL GetButtonRect( HWND hWnd, UINT nPos, LPRECT lprc ) ;
-BOOL PASCAL GetMinButtonRect( HWND hWnd, LPRECT lprc ) ;
-BOOL PASCAL GetMaxButtonRect( HWND hWnd, LPRECT lprc ) ;
-BOOL PASCAL DrawCaption( HDC hDC, HWND hWnd, LPRECT lprc,
- BOOL fVert, BOOL fSysMenu,
- BOOL fMin, BOOL fMax, BOOL fActive ) ;
-void PASCAL DrawSysMenu( HDC hDC, HWND hWnd, BOOL fInvert ) ;
-void PASCAL DrawButton( HDC hDC, HWND hWnd, BOOL fMin, BOOL fDepressed ) ;
-void PASCAL DrawArrow( HDC hdc, LPRECT lprc, UINT uiStyle ) ;
-
-// Global vars
-//
-static BOOL fWin31 ;
-
-///////////////////////////////////////////////////////////////////////
-// External/Public functions
-///////////////////////////////////////////////////////////////////////
-
-/////////////////////////////////////////////////////////////////
-// UINT WINAPI ibGetCaptionSize( HWND hWnd )
-//
-// Description:
-//
-// Gets the size of the caption (height if horz, width if
-// vertical).
-//
-// Comments:
-//
-///////////////////////////////////////////////////////////////
-UINT WINAPI ibGetCaptionSize( HWND hWnd )
-{
- return GETCAPTIONSIZE( hWnd ) + 1 ;
-} // ibSetCaptionSize()
-
-/////////////////////////////////////////////////////////////////
-// UINT WINAPI ibSetCaptionSize( HWND hWnd, UINT nSize )
-//
-// Description:
-//
-// Changes the size of the caption (height if horz, width if
-// vertical).
-//
-// Comments:
-//
-//////////////////////////////////////////////////////////////////
-UINT WINAPI ibSetCaptionSize( HWND hWnd, UINT nSize )
-{
- UINT ui ;
-
- if (nSize <= 0)
- return 0 ;
-
- nSize-- ;
- ui = SETCAPTIONSIZE( hWnd, nSize ) ;
-
- // Once we change the window style, we need a WM_NCCALCRECT
- // to be generated.
- //
- // SWP_FRAMECHANGED is not documented in the 3.1 SDK docs,
- // but *is* in WINDOWS.H.
- //
- SetWindowPos( hWnd, NULL, 0, 0, 0, 0, SWP_FRAMECHANGED |
- SWP_NOSIZE | SWP_NOMOVE |
- SWP_NOACTIVATE | SWP_NOZORDER) ;
-
- return ui ;
-
-} // ibSetCaptionSize()
-
-/////////////////////////////////////////////////////////////////
-// LRESULT WINAPI ibDefWindowProc( HWND hWnd, UINT uiMsg, WPARAM wParam, LPARAM lParam )
-//
-// Description:
-//
-// This function should be called instead of DefWindowProc() for
-// windows that want to have itsybitsy captions.
-//
-// Comments:
-//
-//////////////////////////////////////////////////////////////////
-LRESULT WINAPI ibDefWindowProc( HWND hWnd, UINT uiMsg, WPARAM wParam, LPARAM lParam )
-{
- LRESULT lRet ;
- UINT nCapSize ;
-
- switch( uiMsg )
- {
- case WM_SYSCHAR:
- // If ALT-SPACE
- // was hit then pop up the menu
- //
- if (HASCAPTION( hWnd ) && (wParam == VK_SPACE))
- {
- DoMenu( hWnd ) ;
- break ;
- }
-
- // FALL THROUGH!!!!
- //
-
- case WM_SYSKEYDOWN:
- case WM_SYSKEYUP:
- case WM_KEYDOWN:
- case WM_KEYUP:
- {
- DWORD dw = GetWindowLong( hWnd, GWL_STYLE ) ;
-
- // Fool DefWindowProc into thinking we do not have
- // a system menu. Otherwise it will try to
- // pop up its own.
- //
- SetWindowLong( hWnd, GWL_STYLE, dw &~WS_SYSMENU ) ;
- lRet = DefWindowProc( hWnd, uiMsg, wParam, lParam ) ;
- SetWindowLong( hWnd, GWL_STYLE, dw ) ;
- return lRet ;
- }
- break ;
-
- case WM_COMMAND:
- // The menu that is poped up for the system menu with
- // TrackPopupMenu() sends it's notifications as WM_COMMAND
- // messages. We need to translate these into
- // WM_SYSCOMMAND messages. All standard WM_SYSCOMMAND
- // ids are greater than 0xF000.
- //
- // This could be a possible cause of confusion if the
- // itsybitsy window had children that used SC_MOVE or SC_CLOSE
- // as their IDs. Take note and be careful.
- //
- // Also, because ibDefWindowProc looks at WM_COMMAND messages,
- // you will need to be careful to call ibDefWindowProc() for
- // any wm_command messages that you would normally ignore.
- // Otherwise the system menu won't work.
- //
- if (wParam >= 0xF000)
- // Call PostMessage() here instead of SendMessage!
- // Here's why:
- // Our menu was created by TrackPopupMenu(). TPM() does
- // not return until after the menu has been destroyed
- // (and thus the command associated with the menu selection
- // sent). Therefore when we get here, we are still
- // *inside* TPM(). If we Send WM_SYSCOMMAND, SC_CLOSE
- // to the window, the window will be destroyed before
- // TPM() returns to our code within DoMenu() below. Wel...
- // We do stuff with the window handle after DoMenu()
- // returns (namely GetProp()). Since the window has
- // been destroyed,this is bad.
- PostMessage( hWnd, WM_SYSCOMMAND, wParam, lParam ) ;
-
- return DefWindowProc( hWnd, uiMsg, wParam, lParam ) ;
-
- case WM_GETMINMAXINFO:
- {
- nCapSize = GETCAPTIONSIZE( hWnd ) ;
- if (HASCAPTION( hWnd ) && TestWinStyle( hWnd, WS_THICKFRAME ))
- {
- LPPOINT lppt = (LPPOINT)lParam ;
- RECT rcMenu ;
- RECT rcMin ;
- RECT rcMax ;
- int nX ;
- int cx, cy ; // window frame/border width
-
- if (TestWinStyle( hWnd, WS_THICKFRAME ))
- {
- cx = GetSystemMetrics( SM_CXFRAME ) ;
- cy = GetSystemMetrics( SM_CYFRAME ) ;
- }
- else if (TestWinStyle(hWnd, WS_BORDER ))
- {
- cx = GetSystemMetrics( SM_CXBORDER ) ;
- cy = GetSystemMetrics( SM_CYBORDER ) ;
- }
- else
- {
- // VZ: I don't know what should be here, but the vars must
- // be inited!
- wxFAIL_MSG("don't know how to initialize cx, cy");
-
- cx = cy = 0;
- }
-
- GetIconRect( hWnd, &rcMenu ) ;
- GetMinButtonRect( hWnd, &rcMin ) ;
- GetMaxButtonRect( hWnd, &rcMax ) ;
- nX = (rcMenu.right-rcMenu.left) +
- (rcMin.right-rcMin.left) +
- (rcMin.right-rcMin.left) ;
-
-
- if (TestWinStyle( hWnd, IBS_VERTCAPTION ) )
- {
- lppt[3].x = nCapSize + cx * 2 - 1 ;
- lppt[3].y = nX + (2* nCapSize) ;
- }
- else
- {
- lppt[3].x = nX + (2* nCapSize) ;
- lppt[3].y = nCapSize + cy * 2 - 1 ;
- }
- }
- return DefWindowProc( hWnd, uiMsg, wParam, lParam ) ;
- }
- break ;
-
- /////////////////////////////////////////////////////////////////////
- // Non-client area messages. These are used to allow the
- // minature caption bar to be handled correctly.
- //
- case WM_NCCREATE:
- {
- DWORD dwStyle ;
-
- // We have two things that we need to store somewhere:
- // 1) The caption height (width).
- // and 2) A flag indicating whether the sysmenu was
- // just up or not.
- //
- // CAPTIONXY is a macro that calls GetSystemMetrics.
- //
- SETCAPTIONSIZE( hWnd, CAPTIONXY ) ;
-
- // Set our flag that tells us whether the system menu was
- // 'just up'.
- //
- SETMENUWASUPFLAG( hWnd, FALSE ) ;
-
- // Are we in 3.1? If so we have some neat features
- // we can use like rotated TrueType fonts.
- //
- fWin31 = (BOOL)(LOWORD( GetVersion() ) >= 0x030A) ;
-
- // If IBS_????CAPTION was specified and the WS_DLGFRAME (or
- // WS_DLGFRAME 'cause it == WS_CAPTION | WS_BORDER)
- // was specified the creator made a mistake. Things get really
- // ugly if DefWindowProc sees WS_DLGFRAME, so we strip
- // the WS_DLGFRAME part off!
- //
- dwStyle = GetWindowLong( hWnd, GWL_STYLE ) ;
- if ((dwStyle & IBS_VERTCAPTION || dwStyle & IBS_HORZCAPTION) &&
- dwStyle & WS_DLGFRAME)
- {
- dwStyle &= (DWORD)~WS_DLGFRAME ;
- SetWindowLong( hWnd, GWL_STYLE, dwStyle ) ;
- }
- }
- return DefWindowProc( hWnd, uiMsg, wParam, lParam ) ;
-
- case WM_NCDESTROY:
- // We store the caption size in a window prop. so we
- // must remove props.
- //
- FREECAPTIONSIZE( hWnd ) ;
- FREEMENUWASUPFLAG( hWnd ) ;
- return DefWindowProc( hWnd, uiMsg, wParam, lParam ) ;
-
- case WM_NCCALCSIZE:
- // This is sent when the window manager wants to find out
- // how big our client area is to be. If we have a mini-caption
- // then we trap this message and calculate the cleint area rect,
- // which is the client area rect calculated by DefWindowProc()
- // minus the width/height of the mini-caption bar
- //
- lRet = DefWindowProc( hWnd, uiMsg, wParam, lParam ) ;
- if (!IsIconic( hWnd ) && HASCAPTION( hWnd ))
- {
- nCapSize = GETCAPTIONSIZE( hWnd ) ;
-
- if (TestWinStyle( hWnd, IBS_VERTCAPTION ) )
- ((LPRECT)lParam)->left += nCapSize ;
- else
- ((LPRECT)lParam)->top += nCapSize ;
- }
- return lRet ;
-
- case WM_NCHITTEST:
- // This message is sent whenever the mouse moves over us.
- // We will depend on DefWindowProc for everything unless
- // there is a mini-caption, in which case we will
- // return HTCAPTION or HTSYSMENU. When the user clicks
- // or double clicks, NC_LBUTTON/ message are sent with
- // wParam equal to what we return here.
- // This means that this is an ideal place to figure out
- // where we are!
- //
- // let defwindowproc handle the standard borders etc...
- //
- lRet = DefWindowProc( hWnd, uiMsg, wParam, lParam ) ;
- if (!IsIconic( hWnd ) && HASCAPTION( hWnd ) && lRet == HTNOWHERE)
- {
- RECT rc ;
- RECT rcMenu ;
- RECT rcMinButton ;
- RECT rcMaxButton ;
- POINT pt ;
-
- nCapSize = GETCAPTIONSIZE( hWnd ) ;
-
- // if DefWindowProc returned HTCAPTION then we have to
- // refine the area and return HTSYSMENU if appropriate
- //
- pt.x = LOWORD( lParam ) ;
- pt.y = HIWORD( lParam ) ;
-
- GetCaptionRect( hWnd, &rc ) ; // window coords
- if (PtInRect( &rc, pt ))
- {
- lRet = HTCAPTION ;
-
- // rely on the fact that Get???Rect() return an invalid
- // (empty) rectangle if the menu/buttons don't exist
- //
- GetIconRect( hWnd, &rcMenu ) ;
- GetMinButtonRect( hWnd, &rcMinButton ) ;
- GetMaxButtonRect( hWnd, &rcMaxButton ) ;
-
- if (PtInRect( &rcMenu, pt ))
- lRet = HTSYSMENU ;
-
- if (PtInRect( &rcMinButton, pt ))
- lRet = HTMINBUTTON ;
- else
- if (PtInRect( &rcMaxButton, pt ))
- lRet = HTMAXBUTTON ;
- }
- }
- if (lRet != HTSYSMENU)
- SETMENUWASUPFLAG( hWnd, FALSE ) ;
- return lRet ;
-
- case WM_NCLBUTTONDBLCLK:
- // Windows recieve WM_NC?BUTTONDBLCLK messages whether they
- // have CS_DBLCLKS or not. We watch for one of these
- // to see if the user double clicked on the system menu (to
- // close the window) or on the caption (to maximize the window).
- //
- if (!IsIconic( hWnd ) && HASCAPTION( hWnd ) && wParam == HTSYSMENU)
- {
- SendMessage( hWnd, WM_CLOSE, 0, 0L ) ;
- break ;
- }
- return DefWindowProc( hWnd, uiMsg, wParam, lParam ) ;
-
- case WM_NCLBUTTONDOWN:
- {
- RECT rc ;
-
- // If we're iconic or we don't have a caption then
- // DefWindowProc will do the job just fine.
- //
- if (IsIconic( hWnd ) || !HASCAPTION( hWnd ))
- return DefWindowProc( hWnd, uiMsg, wParam, lParam ) ;
-
- // Here's were we handle the system menu, the min and max buttons.
- // If you wanted to change the behavior of the min/max buttons
- // do something like swap tool palettes or something, you
- // would change the SendMessage() calls below.
- //
- switch (wParam)
- {
- case HTSYSMENU:
- if (GETMENUWASUPFLAG( hWnd ) == FALSE && DoMenu( hWnd ))
- SETMENUWASUPFLAG( hWnd, TRUE ) ;
- else
- SETMENUWASUPFLAG( hWnd, FALSE ) ;
- break ;
-
- case HTMINBUTTON:
- GetMinButtonRect( hWnd, &rc ) ;
- // Note that DepressMinMaxButton() goes into
- // a PeekMessage() loop waiting for the mouse
- // to come back up.
- //
- if (DepressMinMaxButton( hWnd, wParam, &rc ))
- SendMessage( hWnd, WM_SYSCOMMAND, SC_MINIMIZE, lParam ) ;
- break ;
-
- case HTMAXBUTTON:
- GetMaxButtonRect( hWnd, &rc ) ;
- // Note that DepressMinMaxButton() goes into
- // a PeekMessage() loop waiting for the mouse
- // to come back up.
- //
- if (DepressMinMaxButton( hWnd, wParam, &rc ))
- {
- if (IsZoomed(hWnd))
- SendMessage( hWnd, WM_SYSCOMMAND, SC_RESTORE, lParam ) ;
- else
- SendMessage( hWnd, WM_SYSCOMMAND, SC_MAXIMIZE, lParam ) ;
- }
- break ;
-
- default:
- // Well, it appears as though the user clicked somewhere other
- // than the buttons. We let DefWindowProc do it's magic.
- // This is where things like dragging and sizing the
- // window happen.
- //
- return DefWindowProc( hWnd, uiMsg, wParam, lParam ) ;
- }
- }
- break ;
-
- case WM_NCPAINT:
- case WM_NCACTIVATE:
- if (IsIconic( hWnd ))
- return DefWindowProc( hWnd, uiMsg, wParam, lParam ) ;
-
- // Paint the non-client area here. We will call DefWindowProc
- // after we are done so it can paint the borders and so
- // forth...
- //
- lRet = DefWindowProc( hWnd, uiMsg, wParam, lParam ) ;
- if (HASCAPTION( hWnd ))
- {
- RECT rcCap ;
- RECT rc ;
- HDC hDC = GetWindowDC( hWnd ) ;
- BOOL fActive ;
-
- GetCaptionRect( hWnd, &rcCap ) ; // Convert to window coords
- GetWindowRect( hWnd, &rc ) ;
- OffsetRect( &rcCap, -rc.left, -rc.top ) ;
-
- if (uiMsg == WM_NCPAINT)
- fActive = (hWnd == GetActiveWindow()) ;
- else
- fActive = wParam ;
-
- DrawCaption( hDC, hWnd, &rcCap,
- TestWinStyle(hWnd, IBS_VERTCAPTION),
- TestWinStyle(hWnd, WS_SYSMENU),
- TestWinStyle(hWnd, WS_MINIMIZEBOX),
- TestWinStyle(hWnd, WS_MAXIMIZEBOX),
- fActive ) ;
-
- ReleaseDC( hWnd, hDC ) ;
- }
- return lRet;
- break;
-
- default:
- return DefWindowProc( hWnd, uiMsg, wParam, lParam ) ;
- }
-
- return 0L ;
-
-} // ibDefWindowProc()
-
-// ibAdjustWindowRect( HWND hWnd, LPRECT lprc )
-//
-// Does the same thing as the USER function AdjustWindowRect(),
-// but knows about itsybitsy windows. AdjustWindowRect() is
-// bogus for stuff like this.
-//
-void WINAPI ibAdjustWindowRect( HWND hWnd, LPRECT lprc )
-{
- short cx = 0, cy = 0 ;
- UINT nCapSize ;
-
- nCapSize = GETCAPTIONSIZE( hWnd ) ;
-
- // First check Windows's styles, then our own.
- //
- if (TestWinStyle( hWnd, WS_THICKFRAME ))
- {
- cx = GetSystemMetrics( SM_CXFRAME ) ;
- cy = GetSystemMetrics( SM_CYFRAME ) ;
- }
- else
- if (TestWinStyle(hWnd, DS_MODALFRAME ))
- {
- cx = GetSystemMetrics( SM_CXDLGFRAME ) + GetSystemMetrics( SM_CXBORDER ) ;
- cy = GetSystemMetrics( SM_CYDLGFRAME ) + GetSystemMetrics( SM_CYBORDER ) ;
- }
- else
- if (TestWinStyle(hWnd, WS_BORDER ))
- {
- cx = GetSystemMetrics( SM_CXBORDER ) ;
- cy = GetSystemMetrics( SM_CYBORDER ) ;
- }
-
- InflateRect( lprc, cx, cy ) ;
-
- if (TestWinStyle( hWnd, IBS_VERTCAPTION ))
- lprc->left -= nCapSize ;
- else
- if (TestWinStyle( hWnd, IBS_HORZCAPTION ))
- lprc->top -= nCapSize ;
-
-} // ibAdjustWindowRect()
-
-
-///////////////////////////////////////////////////////////////////////
-// Internal functions
-///////////////////////////////////////////////////////////////////////
-
-// DepressMinMaxButton()
-//
-// This function is called when the user has pressed either the min or
-// max button (i.e. WM_NCLBUTTONDOWN). We go into a Peekmessage() loop,
-// waiting for the mouse to come back up. This allows us to make the
-// button change up/down state like a real button does.
-//
-// lprc points to the rectangle that describes the button the
-// user has clicked on.
-//
-BOOL PASCAL DepressMinMaxButton( HWND hWnd, UINT uiHT, LPRECT lprc )
-{
- BOOL fDepressed = TRUE ;
- MSG msg ;
-
- // Draw button in down state
- DrawButton( NULL, hWnd, uiHT == HTMINBUTTON, fDepressed ) ;
- SetCapture( hWnd ) ;
-
- while (TRUE)
- {
- if (PeekMessage((LPMSG)&msg, NULL, WM_MOUSEFIRST, WM_MOUSELAST, PM_REMOVE))
- {
- switch (msg.message)
- {
- case WM_LBUTTONUP:
- if (fDepressed)
- DrawButton( NULL, hWnd, uiHT == HTMINBUTTON, !fDepressed ) ;
- ReleaseCapture();
- return PtInRect( lprc, msg.pt ) ;
-
- case WM_MOUSEMOVE:
- if (PtInRect( lprc, msg.pt ))
- {
- if (!fDepressed)
- DrawButton( NULL, hWnd, uiHT == HTMINBUTTON, fDepressed = TRUE ) ;
- }
- else
- {
- if (fDepressed)
- DrawButton( NULL, hWnd, uiHT == HTMINBUTTON, fDepressed = FALSE ) ;
- }
- break;
- }
- }
- }
-
-} // DepressMinMaxButton()
-
-// DrawCaption( HDC hDC, HWND hWnd, LPRECT lprc,
-// BOOL fVert, BOOL fSysMenu, BOOL fActive )
-//
-// This function draws an itsy bitsy caption bar with or
-// without system menu to the dc specified by hDC. The
-// caption is drawn to fit within the lprc RECT and is
-// drawn//withOut/ borders.
-//
-BOOL PASCAL DrawCaption( HDC hDC, HWND hWnd, LPRECT lprc,
- BOOL fVert, BOOL fSysMenu, BOOL fMin,
- BOOL fMax, BOOL fActive )
-{
- RECT rc ;
- RECT rcCap ;
- COLORREF rgbCaptionBG ;
- COLORREF rgbText ;
- COLORREF rgbWindowFrame ;
- HBRUSH hbrCaption ;
- UINT ui ;
- UINT nCapSize ;
-
- nCapSize = GETCAPTIONSIZE( hWnd ) ;
-
- // Get the colors.
- //
- rgbWindowFrame = GetSysColor( COLOR_WINDOWFRAME ) ;
-
- // if we have focus use the active caption color
- // otherwise use the inactive caption color
- //
- if (fActive)
- {
- rgbText = GetSysColor( COLOR_CAPTIONTEXT ) ;
- rgbCaptionBG = GetSysColor( COLOR_ACTIVECAPTION ) ;
- }
- else
- {
- if (fWin31)
- rgbText = GetSysColor( COLOR_INACTIVECAPTIONTEXT ) ;
- else
- rgbText = GetSysColor( COLOR_CAPTIONTEXT ) ;
-
- rgbCaptionBG = GetSysColor( COLOR_INACTIVECAPTION ) ;
- }
-
- SetBkMode( hDC, TRANSPARENT ) ;
- SelectObject( hDC, GetStockObject( NULL_BRUSH ) ) ;
- SelectObject( hDC, GetStockObject( NULL_PEN ) ) ;
-
- rcCap = *lprc ;
-
- if (fSysMenu)
- {
- if (fVert)
- rcCap.top += nCapSize ;
- else
- rcCap.left += nCapSize ;
- }
-
- if (fMax)
- {
- if (fVert)
- rcCap.bottom -= nCapSize ;
- else
- rcCap.right -= nCapSize ;
- }
-
- if (fMin)
- {
- if (fVert)
- rcCap.bottom -= nCapSize ;
- else
- rcCap.right -= nCapSize ;
- }
-
- if (fVert)
- {
- rc.left = lprc->right - 1 ;
- rc.right = lprc->right ;
- rc.top = lprc->top ;
- rc.bottom = lprc->bottom ;
- }
- else
- {
- rc.left = lprc->left ;
- rc.right = lprc->right ;
- rc.bottom = lprc->bottom ;
- rc.top = rc.bottom - 1 ;
- }
-
- SetBkColor( hDC, rgbWindowFrame ) ;
- DRAWFASTRECT( hDC, &rc ) ;
-
- hbrCaption = CreateSolidBrush( rgbCaptionBG ) ;
- hbrCaption = (HBRUSH) SelectObject( hDC, hbrCaption ) ;
- SelectObject( hDC, (HPEN) GetStockObject( NULL_PEN ) ) ;
- if (fVert)
- Rectangle( hDC, rcCap.left, rcCap.top, rcCap.right, rcCap.bottom + 1 ) ;
- else
- Rectangle( hDC, rcCap.left, rcCap.top, rcCap.right+1, rcCap.bottom ) ;
- hbrCaption = (HBRUSH) SelectObject( hDC, hbrCaption ) ;
- DeleteObject( hbrCaption ) ;
-
-
- // Draw caption text here. Only do it in 3.1 'cause 3.1 gives
- // us 'small fonts'.
- //
- ui = GetWindowTextLength( hWnd ) ;
- if (fWin31)
- {
- HFONT hFont ;
- LPSTR lpsz ;
- LOGFONT lf ;
- TEXTMETRIC tm ;
- int cx ;
- int cy ;
- SIZE Size ;
-
- lpsz = (char*)GlobalAllocPtr( GHND, ui + 2 );
- if (lpsz)
- {
- UINT nBkMode ;
-
- GetWindowText( hWnd, lpsz, ui + 1 ) ;
- nBkMode = SetBkMode( hDC, TRANSPARENT ) ;
- rgbText = SetTextColor( hDC, rgbText ) ;
-
- memset( &lf, '\0', sizeof(LOGFONT) ) ;
-
- lf.lfHeight = -(int)(nCapSize - 3) ;
- lf.lfCharSet = ANSI_CHARSET ;
- lf.lfQuality = DEFAULT_QUALITY ;
- lf.lfClipPrecision = CLIP_LH_ANGLES | CLIP_STROKE_PRECIS ;
- if (nCapSize >= 20)
- {
- lf.lfWeight = FW_BOLD ;
- }
-
- if (fVert)
- {
- // Can only rotate true type fonts (well, ok, we could
- // try and use "modern").
- strcpy( lf.lfFaceName, "Arial" ) ;
- lf.lfPitchAndFamily = FF_SWISS | 0x04;
- lf.lfEscapement = 900 ;
-
- // Note: The Win 3.1 documentation for CreateFont() say's
- // that the lfOrientation member is ignored. It appears,
- // that on Windows 16 3.1 this is true, but when running
- // as a 16 bit WinApp on WindowsNT 3.1 the lfOrientation
- // must be set or the text does not rotate!
- //
- lf.lfOrientation = 900 ;
-
- hFont = CreateFontIndirect( &lf ) ;
- hFont = (HFONT) SelectObject( hDC, hFont ) ;
-
- GetTextExtentPoint( hDC, lpsz, ui, &Size ) ;
- cx = rcCap.bottom - ((rcCap.bottom - rcCap.top - Size.cx) / 2) ;
- cy = rcCap.left - 1 + ((rcCap.right - rcCap.left - Size.cy) / 2) ;
-
- // Make sure we got a rotatable font back.
- //
- GetTextMetrics( hDC, &tm ) ;
- if (tm.tmPitchAndFamily & TMPF_VECTOR ||
- tm.tmPitchAndFamily & TMPF_TRUETYPE)
- {
- ExtTextOut( hDC,
- cy,
- min( (long)cx, rcCap.bottom),
- ETO_CLIPPED, &rcCap,
- lpsz, ui, NULL ) ;
- }
-
- hFont = (HFONT) SelectObject( hDC, hFont ) ;
- DeleteObject( hFont ) ;
- }
- else
- {
- // Use small fonts always for the horizontal. Cause it looks
- // more like "System" than Arial.
- //
- lf.lfPitchAndFamily = FF_SWISS ;
-
- hFont = CreateFontIndirect( &lf ) ;
- hFont = (HFONT) SelectObject( hDC, hFont ) ;
-
- GetTextExtentPoint( hDC, lpsz, ui, &Size ) ;
- cx = rcCap.left + ((rcCap.right - rcCap.left - Size.cx) / 2) ;
- cy = rcCap.top + ((rcCap.bottom - rcCap.top - Size.cy) / 2) ;
-
- // Figger out how big the string is
- //
- ExtTextOut( hDC,
- max( (long)cx, rcCap.left ),
- cy,
- ETO_CLIPPED, &rcCap,
- lpsz, ui, NULL ) ;
-
- hFont = (HFONT) SelectObject( hDC, hFont ) ;
- DeleteObject( hFont ) ;
- }
-
- // Unsetup the DC
- //
- rgbText = SetTextColor( hDC, rgbText ) ;
- SetBkMode( hDC, nBkMode ) ;
-
- GlobalFreePtr( lpsz ) ;
- }
- }
-
- if (fSysMenu)
- DrawSysMenu( hDC, hWnd, FALSE ) ;
-
- if (fMin)
- DrawButton( hDC, hWnd, TRUE, FALSE ) ;
-
- if (fMax)
- DrawButton( hDC, hWnd, FALSE, FALSE ) ;
-
- return TRUE ;
-
-} // DrawCaption()
-
-
-// DrawSysMenu( HDC hDC, hWnd, BOOL fInvert )
-//
-// Draws the little system menu icon.
-//
-void PASCAL DrawSysMenu( HDC hDC, HWND hWnd, BOOL fInvert )
-{
- RECT rcIcon ;
- RECT rcTemp ;
- RECT rc ;
- COLORREF rgbIconFace ;
- COLORREF rgbWindowFrame ;
- BOOL fDC ;
- UINT nCapSize ;
-
- nCapSize = GETCAPTIONSIZE( hWnd ) ;
-
- if (!hDC)
- {
- fDC = TRUE ;
- hDC = GetWindowDC( hWnd ) ;
- }
- else
- fDC = FALSE ;
-
- if (hDC)
- {
- rgbIconFace = GetNearestColor( hDC, RGBLTGRAY ) ;
- rgbWindowFrame = GetSysColor( COLOR_WINDOWFRAME ) ;
-
- GetIconRect( hWnd, &rcIcon ) ;
- GetWindowRect( hWnd, &rc ) ;
-
- OffsetRect( &rcIcon, -rc.left, -rc.top ) ;
-
- rcTemp = rcIcon ;
-
- if (TestWinStyle( hWnd, IBS_VERTCAPTION ))
- {
- rc = rcIcon ; // separator line
- rc.top = ++rc.bottom - 1 ;
- }
- else
- {
- rc = rcIcon ; // separator line
- rc.left = ++rc.right - 1 ;
- }
-
- // Fill
- SetBkColor( hDC, rgbIconFace ) ;
- DRAWFASTRECT( hDC, &rcTemp ) ;
-
- // Draw separator line
- SetBkColor( hDC, rgbWindowFrame ) ;
- DRAWFASTRECT( hDC, &rc ) ;
-
- if (nCapSize > 4)
- {
- // Draw the little horizontal doo-hickey
- //
- rcTemp.top = rcIcon.top + ((nCapSize-1) / 2) ;
- rcTemp.bottom = rcTemp.top + 3 ;
- rcTemp.left = rcTemp.left + 3 ;
- rcTemp.right = rcTemp.right - 1 ;
-
- SetBkColor( hDC, RGBGRAY ) ;
- DRAWFASTRECT( hDC, &rcTemp ) ;
-
- rc = rcTemp ;
- OffsetRect( &rc, -1, -1 ) ;
- SetBkColor( hDC, RGBBLACK ) ;
- DRAWFASTRECT( hDC, &rc ) ;
-
- InflateRect( &rc, -1, -1 ) ;
- SetBkColor( hDC, RGBWHITE ) ;
- DRAWFASTRECT( hDC, &rc ) ;
- }
-
- if (fInvert)
- InvertRect( hDC, &rcIcon ) ;
-
- if (fDC)
- ReleaseDC( hWnd, hDC ) ;
- }
-
-} // DrawSysMenu()
-
-// DoMenu( HWND hWnd )
-//
-// Pops up the system menu.
-//
-BOOL PASCAL DoMenu( HWND hWnd )
-{
- HDC hDC ;
- RECT rcIcon ;
- RECT rc ;
- POINT pt ;
- HMENU hMenu ;
- DWORD dw ;
-
- if (!TestWinStyle(hWnd, WS_SYSMENU))
- return FALSE ;
-
- hDC = GetWindowDC( hWnd );
- if (hDC)
- {
- // Invert the icon
- //
- DrawSysMenu( hDC, hWnd, TRUE ) ;
-
- // Pop up the menu
- //
- if (TestWinStyle( hWnd, IBS_VERTCAPTION ))
- {
- pt.x = -1 ;
- pt.y = 0 ;
- }
- else
- {
- pt.x = 0 ;
- pt.y = -1 ;
- }
-
- GetIconRect( hWnd, &rcIcon ) ;
- GetWindowRect( hWnd, &rc ) ;
- OffsetRect( &rcIcon, -rc.left, -rc.top ) ;
-
- ClientToScreen( hWnd, &pt ) ;
- ClientToScreen( hWnd, (LPPOINT)&rc.right ) ;
-
- dw = GetWindowLong( hWnd, GWL_STYLE ) ;
- SetWindowLong( hWnd, GWL_STYLE, dw | WS_SYSMENU ) ;
-
- hMenu = GetSystemMenu( hWnd, FALSE ) ;
- SetupSystemMenu( hWnd, hMenu ) ;
-
- SetWindowLong( hWnd, GWL_STYLE, dw ) ;
-
- TrackPopupMenu( hMenu, 0, //TPM_LEFTALIGN,
- pt.x,
- pt.y,
- 0,
- hWnd,
- &rc ) ;
-
- DrawSysMenu( hDC, hWnd, FALSE ) ;
- ReleaseDC( hWnd, hDC ) ;
- }
- return TRUE ;
-
-} // DoMenu()
-
-// SetupSystemMenu( HWND hWnd, HMENU hMenu )
-//
-// Enables/Disables the appropriate menu items on the
-// menu passed for the window passed.
-//
-void PASCAL SetupSystemMenu( HWND hWnd, HMENU hMenu )
-{
- UINT wMove ;
- UINT wSize ;
- UINT wMinBox ;
- UINT wMaxBox ;
- UINT wRestore ;
-
- // Assume all should be grayed.
- //
- wSize = wMove = wMinBox = wMaxBox = wRestore = MF_GRAYED ;
-
- if (TestWinStyle( hWnd, WS_MAXIMIZEBOX ) || IsIconic( hWnd ))
- wMaxBox = MF_ENABLED ;
-
- if (TestWinStyle( hWnd, WS_MINIMIZEBOX ))
- wMinBox = MF_ENABLED ;
-
- if (IsZoomed( hWnd ))
- wRestore = MF_ENABLED ;
-
- if (TestWinStyle( hWnd, WS_THICKFRAME ) &&
- !(IsIconic( hWnd ) || IsZoomed( hWnd )))
- wSize = MF_ENABLED ;
-
- if (!IsZoomed( hWnd ) &&
- !IsIconic( hWnd ) &&
- TestWinStyle( hWnd, WS_CAPTION ) )
- wMove = MF_ENABLED ;
-
- EnableMenuItem( hMenu, SC_MOVE, wMove ) ;
- EnableMenuItem( hMenu, SC_SIZE, wSize ) ;
- EnableMenuItem( hMenu, SC_MINIMIZE, wMinBox ) ;
- EnableMenuItem( hMenu, SC_MAXIMIZE, wMaxBox ) ;
- EnableMenuItem( hMenu, SC_RESTORE, wRestore ) ;
-
-} // SetupSystemMenu()
-
-// GetCaptionRect( HWND hWnd, LPRECT lprc )
-//
-// calcluales the rectangle of the mini-caption in screen coords.
-//
-BOOL PASCAL GetCaptionRect( HWND hWnd, LPRECT lprc )
-{
- UINT nCapSize ;
-
- nCapSize = GETCAPTIONSIZE( hWnd ) ;
-
- if (!HASCAPTION( hWnd ))
- {
- SetRectEmpty( lprc ) ;
- return FALSE ;
- }
-
- GetWindowRect( hWnd, lprc ) ;
-
- // the window might have other non-client components like
- // borders
- //
- if (TestWinStyle( hWnd, WS_THICKFRAME ))
- {
- lprc->left += GetSystemMetrics( SM_CXFRAME ) ;
- lprc->top += GetSystemMetrics( SM_CYFRAME ) ;
- lprc->right -= GetSystemMetrics( SM_CXFRAME ) ;
- lprc->bottom -= GetSystemMetrics( SM_CYFRAME ) ;
- }
- else
- if (TestWinStyle( hWnd, DS_MODALFRAME )) // if it's a dialog box
- {
- lprc->left += GetSystemMetrics( SM_CXDLGFRAME ) + GetSystemMetrics( SM_CXBORDER ) ;
- lprc->top += GetSystemMetrics( SM_CYDLGFRAME ) + GetSystemMetrics( SM_CYBORDER ) ;
- lprc->right -= GetSystemMetrics( SM_CXDLGFRAME ) + GetSystemMetrics( SM_CXBORDER ) ;
- lprc->bottom -= GetSystemMetrics( SM_CYDLGFRAME ) + GetSystemMetrics( SM_CYBORDER ) ;
- }
- else
- if (TestWinStyle( hWnd, WS_BORDER ))
- {
- lprc->left += GetSystemMetrics( SM_CXBORDER ) ;
- lprc->top += GetSystemMetrics( SM_CYBORDER ) ;
- lprc->right -= GetSystemMetrics( SM_CXBORDER ) ;
- lprc->bottom -= GetSystemMetrics( SM_CYBORDER ) ;
- }
-
- if (TestWinStyle( hWnd, IBS_VERTCAPTION ))
- lprc->right = lprc->left + nCapSize ;
- else
- lprc->bottom = lprc->top + nCapSize ;
-
- return TRUE ;
-} // GetCaptionRect()
-
-// GetIconRect( HWND hWnd, LPRECT lprc )
-//
-// Calculates the rect of the icon in screen coordinates.
-//
-BOOL PASCAL GetIconRect( HWND hWnd, LPRECT lprc )
-{
- UINT nCapSize ;
- BOOL fMenu, fVert ;
-
- fMenu= TestWinStyle( hWnd, WS_SYSMENU ) ;
- fVert = TestWinStyle( hWnd, IBS_VERTCAPTION ) ;
-
- if (!GetCaptionRect( hWnd, lprc )) // window coords
- return FALSE ;
-
- if (!fMenu)
- {
- SetRectEmpty( lprc ) ;
- return FALSE ;
- }
-
- nCapSize = GETCAPTIONSIZE( hWnd ) ;
-
- if (fVert)
- lprc->bottom = lprc->top + nCapSize ;
- else
- lprc->right = lprc->left + nCapSize ;
-
- lprc->bottom-- ;
- lprc->right-- ;
-
- return TRUE ;
-
-} // GetIconRect()
-
-// GetMinButtonRect()
-//
-// Calculates the rect of the minimize button in screen
-// coordinates.
-//
-// For horizontal captions, we have the following situation ('Y' is minimize
-// and '^' is maximize or restore):
-//
-// +---------------------------------+
-// | - | | Y | ^ |
-// +---------------------------------+
-// | |.......| <-- This is the width (nSize)
-//
-// For vertical captions, we have the following:
-//
-// | |
-// | |
-// | |
-// | |
-// | |
-// | |
-// |--|--
-// | Y| .
-// |--| . <-- This is the height of the rectangle (nSize)
-// | ^| .
-// +--+--
-//
-// In order to figure out where the minimize button goes, we first need
-// to know if there is a maximize button. If so, use GetMaxButtonRect()
-// to place...
-//
-BOOL PASCAL GetMinButtonRect( HWND hWnd, LPRECT lprc )
-{
- if (!TestWinStyle( hWnd, WS_MINIMIZEBOX ))
- {
- SetRectEmpty( lprc ) ;
- return FALSE ;
- }
-
- // The minimize button can be in either position 1 or 2. If there
- // is a maximize button, it's in position 2.
- //
- if (TestWinStyle( hWnd, WS_MAXIMIZEBOX ))
- return GetButtonRect( hWnd, 2, lprc ) ;
- else
- return GetButtonRect( hWnd, 1, lprc ) ;
-}
-
-// GetMaxButtonRect()
-//
-// Calculates the rect of the maximize button in screen
-// coordinates.
-//
-// The maximize button, if present, is always to the far right
-// or bottom.
-//
-BOOL PASCAL GetMaxButtonRect( HWND hWnd, LPRECT lprc )
-{
- //The maximize button can only be in position 1.
- //
- if (TestWinStyle( hWnd, WS_MAXIMIZEBOX ))
- return GetButtonRect( hWnd, 1, lprc ) ;
- else
- {
- SetRectEmpty( lprc ) ;
- return FALSE ;
- }
-}
-
-// Get the rect where a button would go.
-//
-// This function does not care if it's a min or max, just whether
-// it is the first from the right/bottom or second from the right/bottom
-// and so on..
-//
-BOOL PASCAL GetButtonRect( HWND hWnd, UINT nPos, LPRECT lprc )
-{
- UINT nSize = 0 ;
-
- if (!GetCaptionRect( hWnd, lprc )) //window coords
- return FALSE ;
-
- nSize = GETCAPTIONSIZE( hWnd ) ;
-
- if (TestWinStyle( hWnd, IBS_VERTCAPTION ))
- {
- lprc->bottom -= nSize * (nPos-1) ;
- lprc->top = lprc->bottom - nSize + 1 ;
- }
- else
- {
- lprc->right -= nSize * (nPos-1) ;
- lprc->left = lprc->right - nSize + 1 ;
- }
-
- return TRUE ;
-} // GetButtonRect()
-
-// DrawButton( HDC hDC, HWND hWnd, BOOL fMin, BOOL fDepressed )
-//
-// Draws either the min, max, or restore buttons. If fMin is FALSE then it
-// will draw either the Max or Restore button. If fDepressed is TRUE it will
-// draw the button in a down state.
-//
-void PASCAL DrawButton( HDC hDC, HWND hWnd, BOOL fMin, BOOL fDepressed)
-{
- RECT rcButton ;
- RECT rc ;
- COLORREF rgbWindowFrame ;
- BOOL fDC ;
- UINT nCapSize ;
- UINT nOffset ;
- int n ;
-
- nCapSize = GETCAPTIONSIZE( hWnd ) ;
-
- // If you look at the standard Windows' min/max buttons, you will notice
- // that they have two pixels of 'shadow' to the bottom and right. Since
- // our buttons can be really, really small, we only want one pixel of
- // shadow when they are small. I arbitrarily decided that if the
- // caption size is greater than or equal to 20 we will use two
- // pixels. That's what this THREASHOLD stuff does.
- //
- #define THRESHOLD 20
- nOffset = (nCapSize >= THRESHOLD) ? 2 : 1 ;
-
- if (!hDC)
- {
- fDC = TRUE ;
- hDC = GetWindowDC( hWnd ) ;
- }
- else
- fDC = FALSE ;
-
- if (hDC)
- {
- rgbWindowFrame = GetSysColor( COLOR_WINDOWFRAME ) ;
-
- if (fMin)
- GetMinButtonRect( hWnd, &rcButton ) ;
- else
- GetMaxButtonRect( hWnd, &rcButton ) ;
-
- GetWindowRect( hWnd, &rc ) ;
- OffsetRect( &rcButton, -rc.left, -rc.top ) ;
-
- rc = rcButton ;
- if (TestWinStyle( hWnd, IBS_VERTCAPTION ))
- {
- rc = rcButton ; //separator line
- rc.bottom = --rc.top + 1 ;
- rcButton.right-- ;
- }
- else
- {
- rc = rcButton ; //separator line
- rc.right = --rc.left + 1 ;
- rcButton.bottom-- ;
- }
-
- //Draw separator line
- SetBkColor( hDC, rgbWindowFrame ) ;
- DRAWFASTRECT( hDC, &rc ) ;
-
- //Fill
- SetBkColor( hDC, RGBLTGRAY ) ;
- DRAWFASTRECT( hDC, &rcButton ) ;
-
- if (!fDepressed)
- {
- //The normal min/max buttons have one pixel on the top and left
- //sides for the highlight, and two pixels on the bottom and
- //right side for the shadow.
- //
- //When our caption is 'small' we only use one pixel on all
- //sides.
- //
- SetBkColor( hDC, RGBWHITE ) ;
- //Draw left side
- rc = rcButton ;
- rc.right = rc.left + 1 ;
- DRAWFASTRECT( hDC, &rc ) ;
-
- //Draw Top
- rc = rcButton ;
- rc.bottom = rc.top + 1 ;
- DRAWFASTRECT( hDC, &rc ) ;
-
- SetBkColor( hDC, RGBGRAY ) ;
- //Draw right side
- rc = rcButton ;
- rc.left = rc.right - 1 ;
- DRAWFASTRECT( hDC, &rc ) ;
- if (nCapSize > THRESHOLD)
- {
- rc.left-- ;
- rc.top++ ;
- DRAWFASTRECT( hDC, &rc ) ;
- }
-
- //Draw bottom
- rc = rcButton ;
- rc.top = rc.bottom - 1 ;
- DRAWFASTRECT( hDC, &rc ) ;
- if (nCapSize > THRESHOLD)
- {
- rc.top-- ;
- rc.left++ ;
- DRAWFASTRECT( hDC, &rc ) ;
- }
-
- rcButton.left++ ;
- rcButton.top++ ;
- rcButton.right -= nOffset ;
- rcButton.bottom -= nOffset ;
- }
- else
- {
- //Draw depressed state
-
- SetBkColor( hDC, RGBGRAY ) ;
- //Draw left side
- rc = rcButton ;
- rc.right = rc.left + nOffset ;
- DRAWFASTRECT( hDC, &rc ) ;
-
- //Draw Top
- rc = rcButton ;
- rc.bottom = rc.top + nOffset ;
- DRAWFASTRECT( hDC, &rc ) ;
-
- rcButton.left += 2 * nOffset ;
- rcButton.top += 2 * nOffset ;
- }
-
- // Now draw the arrows. We do not want the
- // arrows to grow too large when we have a bigger than
- // normal caption, so we restrict their size.
- //
- // rcButton now represents where we can place our
- // arrows.
- //
- // The maximum size of our arrows (i.e. the width of rcButton)
- // has been empirically determined to be SM_CYCAPTION / 2
- //
- n = ((GetSystemMetrics( SM_CYCAPTION )) / 2) -
- (rcButton.right - rcButton.left) ;
- if (n < 1)
- InflateRect( &rcButton, n/2-1, n/2-1 ) ;
-
- if (fMin)
- DrawArrow( hDC, &rcButton, ARROW_DOWN ) ;
- else
- if (IsZoomed( hWnd ))
- {
- DrawArrow( hDC, &rcButton, ARROW_RESTORE ) ;
- }
- else
- DrawArrow( hDC, &rcButton, ARROW_UP ) ;
-
- if (fDC)
- ReleaseDC( hWnd, hDC ) ;
- }
-
-} // DrawButton()
-
-
-// DrawArrow
-//
-// Draws either a up or down arrow. The arrow is bound by the rectangle
-//
-void PASCAL DrawArrow( HDC hdc, LPRECT lprc, UINT uiStyle )
-{
- int row ;
- int xTip ;
- int yTip ;
- RECT rc ;
- int nMax = (lprc->bottom - lprc->top) >> 1 ;
-
- SetBkColor( hdc, RGBBLACK ) ;
-
- // We draw the arrow by drawing a series of horizontal lines
- //
- xTip = lprc->left + ((lprc->right - lprc->left+1) >> 1) ;
- switch (uiStyle)
- {
- case ARROW_UP:
- yTip = lprc->top + ((lprc->bottom - lprc->top-1) >> 2) ;
- for (row = 1 ; row <= nMax ; row++ )
- {
- rc.left = xTip - row ;
- rc.right = xTip + row - 1 ;
- rc.top = yTip + row ;
- rc.bottom = rc.top + 1 ;
- DRAWFASTRECT( hdc, &rc ) ;
- }
- break ;
-
- case ARROW_DOWN:
- yTip = lprc->bottom - ((lprc->bottom - lprc->top-1) >> 2) ;
- for ( row = nMax ; row > 0 ; row-- )
- {
- rc.left = xTip - row ;
- rc.right = xTip + row - 1 ;
- rc.top = yTip - row ;
- rc.bottom = rc.top + 1 ;
- DRAWFASTRECT( hdc, &rc ) ;
- }
- break ;
-
- case ARROW_RESTORE:
- default:
- yTip = lprc->top + ((lprc->bottom - lprc->top-1) >> 3) - 2;
- for (row = 1 ; row <= nMax ; row++ )
- {
- rc.left = xTip - row ;
- rc.right = xTip + row - 1 ;
- rc.top = yTip + row ;
- rc.bottom = rc.top + 1 ;
- DRAWFASTRECT( hdc, &rc ) ;
- }
-
- yTip += (nMax+1) * 2 ;
- for ( row = nMax ; row > 0 ; row-- )
- {
- rc.left = xTip - row ;
- rc.right = xTip + row - 1 ;
- rc.top = yTip - row ;
- rc.bottom = rc.top + 1 ;
- DRAWFASTRECT( hdc, &rc ) ;
- }
- break ;
- }
-
-} // DrawArrow()
-#endif // wxUSE_ITSY_BITSY