1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxMiniFrame
4 // Author: Julian Smart
8 // Copyright: (c) Julian Smart and Markus Holzem
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "minifram.h"
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
23 #include "wx/window.h"
24 #include "wx/msw/private.h"
36 #include "wx/minifram.h"
38 IMPLEMENT_DYNAMIC_CLASS(wxMiniFrame
, wxFrame
)
46 #include "wx/minifram.h"
50 #ifndef wxUSE_NORLANDER_HEADERS
51 #include "wx/msw/gnuwin32/extra.h"
56 IMPLEMENT_DYNAMIC_CLASS(wxMiniFrame
, wxFrame
)
58 long wxMiniFrame::MSWDefWindowProc(WXUINT nMsg
, WXWPARAM wParam
, WXLPARAM lParam
)
60 if ((GetWindowStyleFlag() & wxTINY_CAPTION_HORIZ
) ||
61 (GetWindowStyleFlag() & wxTINY_CAPTION_VERT
))
62 return ::ibDefWindowProc((HWND
) GetHWND(), nMsg
, wParam
, lParam
);
63 else if ( m_oldWndProc
)
64 return ::CallWindowProc(CASTWNDPROC m_oldWndProc
, (HWND
) GetHWND(), (UINT
) nMsg
, (WPARAM
) wParam
, (LPARAM
) lParam
);
66 return ::DefWindowProc((HWND
) GetHWND(), nMsg
, wParam
, lParam
);
69 wxMiniFrame::~wxMiniFrame(void)
73 /////////////////////////////////////////////////////////////////////////
75 // Project: ItsyBitsy window support module
79 // ItsyBitsy is a support module that allows you to create windows
80 // that look and act very much like a popup window witha system
81 // menu and caption bar, except everything is scaled to about 2/3
84 // For documentation on how to use ItsyBits, read the document
88 // 9/27/91 Charlie Kindel (cek/ckindel)
89 // Wrote and documented it.
92 // 2/23/93 cek Added minimize/maximize buttons.
93 // 3/18/93 cek Fixed system menu bug where system menu
94 // popped back up if you clicked on the
95 // icon again while it was up.
96 // 3/24/93 cek More comments. Fixed DS_MODALDIALOG style
97 // problem. Use auto precompiled headers
100 //////////////////////////////////////////////////////////////////////////
102 #include "wx/window.h"
103 #include "wx/msw/private.h"
107 #if !defined( __WATCOMC__ ) && !defined( __MWERKS__ ) && !defined(__SALFORDC__)
116 // Some mildly useful macros for the standard 16 colors
117 #define RGBBLACK RGB(0,0,0)
118 #define RGBRED RGB(128,0,0)
119 #define RGBGREEN RGB(0,128,0)
120 #define RGBBLUE RGB(0,0,128)
122 #define RGBBROWN RGB(128,128,0)
123 #define RGBMAGENTA RGB(128,0,128)
124 #define RGBCYAN RGB(0,128,128)
125 #define RGBLTGRAY RGB(192,192,192)
127 #define RGBGRAY RGB(128,128,128)
128 #define RGBLTRED RGB(255,0,0)
129 #define RGBLTGREEN RGB(0,255,0)
130 #define RGBLTBLUE RGB(0,0,255)
132 #define RGBYELLOW RGB(255,255,0)
133 #define RGBLTMAGENTA RGB(255,0,255)
134 #define RGBLTCYAN RGB(0,255,255)
135 #define RGBWHITE RGB(255,255,255)
138 #ifndef GlobalAllocPtr
139 #define GlobalPtrHandle(lp) \
140 ((HGLOBAL)GlobalHandle(lp))
142 #define GlobalLockPtr(lp) \
143 ((BOOL)GlobalLock(GlobalPtrHandle(lp)))
144 #define GlobalUnlockPtr(lp) \
145 GlobalUnlock(GlobalPtrHandle(lp))
147 #define GlobalAllocPtr(flags, cb) \
148 (GlobalLock(GlobalAlloc((flags), (cb))))
149 #define GlobalReAllocPtr(lp, cbNew, flags) \
150 (GlobalUnlockPtr(lp), GlobalLock(GlobalReAlloc(GlobalPtrHandle(lp) , (cbNew), (flags))))
151 #define GlobalFreePtr(lp) \
152 (GlobalUnlockPtr(lp), (BOOL)GlobalFree(GlobalPtrHandle(lp)))
155 #if defined(__BORLANDC__) || defined(__WATCOMC__)
156 #define max(a,b) (((a) > (b)) ? (a) : (b))
157 #define min(a,b) (((a) < (b)) ? (a) : (b))
160 // CAPTIONXY is the default size of the system menu icon. This
161 // determines the height/width of the caption.
163 // The value that results from the following formula works out
164 // nicely for the veritcal caption on VGA, 8514 (Large Fonts),
165 // 8514 (Small Fonts), XGA (Small Fonts), XGA (Large Fonts),
166 // and TIGA (Small Fonts). It may not be good on other displays.
168 // The problem is that TT fonts turn into bitmap fonts when they
169 // are sized below a certain threshold. The idea is to make the
170 // size of the caption just big enough to get the smallest TT
171 // (scalable) font to fit.
173 #define CAPTIONXY (GetSystemMetrics( SM_CYCAPTION ) / 2 + 1)
175 #define TestWinStyle( hWnd, dwStyleBit ) \
176 (((DWORD)GetWindowLong( hWnd, GWL_STYLE ) & (DWORD)dwStyleBit) ? TRUE : FALSE )
177 #define HASCAPTION( hwnd ) (TestWinStyle( hwnd, IBS_VERTCAPTION ) ||\
178 TestWinStyle( hwnd, IBS_HORZCAPTION ))
180 #define SETCAPTIONSIZE(h,i) (UINT)SetProp(h,wxT("ibSize"),(HANDLE)i)
181 #define GETCAPTIONSIZE(h) (UINT)GetProp(h,wxT("ibSize"))
182 #define FREECAPTIONSIZE(h) RemoveProp(h,wxT("ibSize"))
184 #define SETMENUWASUPFLAG(h,i) (UINT)SetProp(h,wxT("ibFlag"),(HANDLE)i)
185 #define GETMENUWASUPFLAG(h) (UINT)GetProp(h,wxT("ibFlag"))
186 #define FREEMENUWASUPFLAG(h) RemoveProp(h,wxT("ibFlag"))
188 /////////////////////////////////////////////////////////////////////
189 // Little known fact:
190 // ExtTextOut() is the fastest way to draw a filled rectangle
191 // in Windows (if you don't want dithered colors or borders).
193 // Unfortunately there is a bug in the Windows 3.0 8514 driver
194 // in using ExtTextOut() to a memory DC. If you are drawing
195 // to an off screen bitmap, then blitting that bitmap to the
196 // display, do not #define wxUSE_EXTTEXTOUT below.
198 // The following macro (DRAWFASTRECT) draws a filled rectangle
199 // with no border and a solid color. It uses the current back-
200 // ground color as the fill color.
201 //////////////////////////////////////////////////////////////////////
202 #define wxUSE_EXTTEXTOUT
203 #ifdef wxUSE_EXTTEXTOUT
204 #define DRAWFASTRECT(hdc,lprc) ExtTextOut(hdc,0,0,ETO_OPAQUE,lprc,NULL,0,NULL)
206 #define DRAWFASTRECT(hdc,lprc) {\
207 HBRUSH hbr = CreateSolidBrush( GetBkColor( hdc ) ) ;\
208 hbr = SelectObject(hdc, hbr) ;\
209 PatBlt(hdc,(lprc)->left,(lprc)->top,(lprc)->right-(lprc)->left,(lprc)->bottom-(lprc)->top,PATCOPY) ;\
210 hbr = SelectObject(hdc, hbr) ;\
211 DeleteObject( hbr ) ;\
215 // The DrawArrow function takes the following to indicate what
216 // kind of arrow to draw.
220 #define ARROW_RESTORE 2
222 BOOL PASCAL
DepressMinMaxButton( HWND hWnd
, UINT uiHT
, LPRECT
) ;
223 BOOL PASCAL
DoMenu( HWND hWnd
) ;
224 void PASCAL
SetupSystemMenu( HWND hWnd
, HMENU hMenu
) ;
225 BOOL PASCAL
GetCaptionRect( HWND hWnd
, LPRECT lprc
) ;
226 BOOL PASCAL
GetIconRect( HWND hWnd
, LPRECT lprc
) ;
227 BOOL PASCAL
GetButtonRect( HWND hWnd
, UINT nPos
, LPRECT lprc
) ;
228 BOOL PASCAL
GetMinButtonRect( HWND hWnd
, LPRECT lprc
) ;
229 BOOL PASCAL
GetMaxButtonRect( HWND hWnd
, LPRECT lprc
) ;
230 BOOL PASCAL
DrawCaption( HDC hDC
, HWND hWnd
, LPRECT lprc
,
231 BOOL fVert
, BOOL fSysMenu
,
232 BOOL fMin
, BOOL fMax
, BOOL fActive
) ;
233 void PASCAL
DrawSysMenu( HDC hDC
, HWND hWnd
, BOOL fInvert
) ;
234 void PASCAL
DrawButton( HDC hDC
, HWND hWnd
, BOOL fMin
, BOOL fDepressed
) ;
235 void PASCAL
DrawArrow( HDC hdc
, LPRECT lprc
, UINT uiStyle
) ;
241 ///////////////////////////////////////////////////////////////////////
242 // External/Public functions
243 ///////////////////////////////////////////////////////////////////////
245 /////////////////////////////////////////////////////////////////
246 // UINT WINAPI ibGetCaptionSize( HWND hWnd )
250 // Gets the size of the caption (height if horz, width if
255 ///////////////////////////////////////////////////////////////
256 UINT WINAPI
ibGetCaptionSize( HWND hWnd
)
258 return GETCAPTIONSIZE( hWnd
) + 1 ;
259 } // ibSetCaptionSize()
261 /////////////////////////////////////////////////////////////////
262 // UINT WINAPI ibSetCaptionSize( HWND hWnd, UINT nSize )
266 // Changes the size of the caption (height if horz, width if
271 //////////////////////////////////////////////////////////////////
272 UINT WINAPI
ibSetCaptionSize( HWND hWnd
, UINT nSize
)
280 ui
= SETCAPTIONSIZE( hWnd
, nSize
) ;
282 // Once we change the window style, we need a WM_NCCALCRECT
285 // SWP_FRAMECHANGED is not documented in the 3.1 SDK docs,
286 // but *is* in WINDOWS.H.
288 SetWindowPos( hWnd
, NULL
, 0, 0, 0, 0, SWP_FRAMECHANGED
|
289 SWP_NOSIZE
| SWP_NOMOVE
|
290 SWP_NOACTIVATE
| SWP_NOZORDER
) ;
294 } // ibSetCaptionSize()
296 /////////////////////////////////////////////////////////////////
297 // LRESULT WINAPI ibDefWindowProc( HWND hWnd, UINT uiMsg, WPARAM wParam, LPARAM lParam )
301 // This function should be called instead of DefWindowProc() for
302 // windows that want to have itsybitsy captions.
306 //////////////////////////////////////////////////////////////////
307 LRESULT WINAPI
ibDefWindowProc( HWND hWnd
, UINT uiMsg
, WPARAM wParam
, LPARAM lParam
)
316 // was hit then pop up the menu
318 if (HASCAPTION( hWnd
) && (wParam
== VK_SPACE
))
332 DWORD dw
= GetWindowLong( hWnd
, GWL_STYLE
) ;
334 // Fool DefWindowProc into thinking we do not have
335 // a system menu. Otherwise it will try to
338 SetWindowLong( hWnd
, GWL_STYLE
, dw
&~WS_SYSMENU
) ;
339 lRet
= DefWindowProc( hWnd
, uiMsg
, wParam
, lParam
) ;
340 SetWindowLong( hWnd
, GWL_STYLE
, dw
) ;
346 // The menu that is poped up for the system menu with
347 // TrackPopupMenu() sends it's notifications as WM_COMMAND
348 // messages. We need to translate these into
349 // WM_SYSCOMMAND messages. All standard WM_SYSCOMMAND
350 // ids are greater than 0xF000.
352 // This could be a possible cause of confusion if the
353 // itsybitsy window had children that used SC_MOVE or SC_CLOSE
354 // as their IDs. Take note and be careful.
356 // Also, because ibDefWindowProc looks at WM_COMMAND messages,
357 // you will need to be careful to call ibDefWindowProc() for
358 // any wm_command messages that you would normally ignore.
359 // Otherwise the system menu won't work.
361 if (wParam
>= 0xF000)
362 // Call PostMessage() here instead of SendMessage!
364 // Our menu was created by TrackPopupMenu(). TPM() does
365 // not return until after the menu has been destroyed
366 // (and thus the command associated with the menu selection
367 // sent). Therefore when we get here, we are still
368 // *inside* TPM(). If we Send WM_SYSCOMMAND, SC_CLOSE
369 // to the window, the window will be destroyed before
370 // TPM() returns to our code within DoMenu() below. Wel...
371 // We do stuff with the window handle after DoMenu()
372 // returns (namely GetProp()). Since the window has
373 // been destroyed,this is bad.
374 PostMessage( hWnd
, WM_SYSCOMMAND
, wParam
, lParam
) ;
376 return DefWindowProc( hWnd
, uiMsg
, wParam
, lParam
) ;
378 case WM_GETMINMAXINFO
:
380 nCapSize
= GETCAPTIONSIZE( hWnd
) ;
381 if (HASCAPTION( hWnd
) && TestWinStyle( hWnd
, WS_THICKFRAME
))
383 LPPOINT lppt
= (LPPOINT
)lParam
;
388 int cx
, cy
; // window frame/border width
390 if (TestWinStyle( hWnd
, WS_THICKFRAME
))
392 cx
= GetSystemMetrics( SM_CXFRAME
) ;
393 cy
= GetSystemMetrics( SM_CYFRAME
) ;
395 else if (TestWinStyle(hWnd
, WS_BORDER
))
397 cx
= GetSystemMetrics( SM_CXBORDER
) ;
398 cy
= GetSystemMetrics( SM_CYBORDER
) ;
402 // VZ: I don't know what should be here, but the vars must
404 wxFAIL_MSG(wxT("don't know how to initialize cx, cy"));
409 GetIconRect( hWnd
, &rcMenu
) ;
410 GetMinButtonRect( hWnd
, &rcMin
) ;
411 GetMaxButtonRect( hWnd
, &rcMax
) ;
412 nX
= (rcMenu
.right
-rcMenu
.left
) +
413 (rcMin
.right
-rcMin
.left
) +
414 (rcMin
.right
-rcMin
.left
) ;
417 if (TestWinStyle( hWnd
, IBS_VERTCAPTION
) )
419 lppt
[3].x
= nCapSize
+ cx
* 2 - 1 ;
420 lppt
[3].y
= nX
+ (2* nCapSize
) ;
424 lppt
[3].x
= nX
+ (2* nCapSize
) ;
425 lppt
[3].y
= nCapSize
+ cy
* 2 - 1 ;
428 return DefWindowProc( hWnd
, uiMsg
, wParam
, lParam
) ;
432 /////////////////////////////////////////////////////////////////////
433 // Non-client area messages. These are used to allow the
434 // minature caption bar to be handled correctly.
440 // We have two things that we need to store somewhere:
441 // 1) The caption height (width).
442 // and 2) A flag indicating whether the sysmenu was
445 // CAPTIONXY is a macro that calls GetSystemMetrics.
447 SETCAPTIONSIZE( hWnd
, CAPTIONXY
) ;
449 // Set our flag that tells us whether the system menu was
452 SETMENUWASUPFLAG( hWnd
, FALSE
) ;
454 // Are we in 3.1? If so we have some neat features
455 // we can use like rotated TrueType fonts.
457 fWin31
= (BOOL
)(LOWORD( GetVersion() ) >= 0x030A) ;
459 // If IBS_????CAPTION was specified and the WS_DLGFRAME (or
460 // WS_DLGFRAME 'cause it == WS_CAPTION | WS_BORDER)
461 // was specified the creator made a mistake. Things get really
462 // ugly if DefWindowProc sees WS_DLGFRAME, so we strip
463 // the WS_DLGFRAME part off!
465 dwStyle
= GetWindowLong( hWnd
, GWL_STYLE
) ;
466 if ((dwStyle
& IBS_VERTCAPTION
|| dwStyle
& IBS_HORZCAPTION
) &&
467 dwStyle
& WS_DLGFRAME
)
469 dwStyle
&= (DWORD
)~WS_DLGFRAME
;
470 SetWindowLong( hWnd
, GWL_STYLE
, dwStyle
) ;
473 return DefWindowProc( hWnd
, uiMsg
, wParam
, lParam
) ;
476 // We store the caption size in a window prop. so we
477 // must remove props.
479 FREECAPTIONSIZE( hWnd
) ;
480 FREEMENUWASUPFLAG( hWnd
) ;
481 return DefWindowProc( hWnd
, uiMsg
, wParam
, lParam
) ;
484 // This is sent when the window manager wants to find out
485 // how big our client area is to be. If we have a mini-caption
486 // then we trap this message and calculate the cleint area rect,
487 // which is the client area rect calculated by DefWindowProc()
488 // minus the width/height of the mini-caption bar
490 lRet
= DefWindowProc( hWnd
, uiMsg
, wParam
, lParam
) ;
491 if (!IsIconic( hWnd
) && HASCAPTION( hWnd
))
493 nCapSize
= GETCAPTIONSIZE( hWnd
) ;
495 if (TestWinStyle( hWnd
, IBS_VERTCAPTION
) )
496 ((LPRECT
)lParam
)->left
+= nCapSize
;
498 ((LPRECT
)lParam
)->top
+= nCapSize
;
503 // This message is sent whenever the mouse moves over us.
504 // We will depend on DefWindowProc for everything unless
505 // there is a mini-caption, in which case we will
506 // return HTCAPTION or HTSYSMENU. When the user clicks
507 // or double clicks, NC_LBUTTON/ message are sent with
508 // wParam equal to what we return here.
509 // This means that this is an ideal place to figure out
512 // let defwindowproc handle the standard borders etc...
514 lRet
= DefWindowProc( hWnd
, uiMsg
, wParam
, lParam
) ;
515 if (!IsIconic( hWnd
) && HASCAPTION( hWnd
) && lRet
== HTNOWHERE
)
523 nCapSize
= GETCAPTIONSIZE( hWnd
) ;
525 // if DefWindowProc returned HTCAPTION then we have to
526 // refine the area and return HTSYSMENU if appropriate
528 pt
.x
= LOWORD( lParam
) ;
529 pt
.y
= HIWORD( lParam
) ;
531 GetCaptionRect( hWnd
, &rc
) ; // window coords
532 if (PtInRect( &rc
, pt
))
536 // rely on the fact that Get???Rect() return an invalid
537 // (empty) rectangle if the menu/buttons don't exist
539 GetIconRect( hWnd
, &rcMenu
) ;
540 GetMinButtonRect( hWnd
, &rcMinButton
) ;
541 GetMaxButtonRect( hWnd
, &rcMaxButton
) ;
543 if (PtInRect( &rcMenu
, pt
))
546 if (PtInRect( &rcMinButton
, pt
))
549 if (PtInRect( &rcMaxButton
, pt
))
553 if (lRet
!= HTSYSMENU
)
554 SETMENUWASUPFLAG( hWnd
, FALSE
) ;
557 case WM_NCLBUTTONDBLCLK
:
558 // Windows recieve WM_NC?BUTTONDBLCLK messages whether they
559 // have CS_DBLCLKS or not. We watch for one of these
560 // to see if the user double clicked on the system menu (to
561 // close the window) or on the caption (to maximize the window).
563 if (!IsIconic( hWnd
) && HASCAPTION( hWnd
) && wParam
== HTSYSMENU
)
565 SendMessage( hWnd
, WM_CLOSE
, 0, 0L ) ;
568 return DefWindowProc( hWnd
, uiMsg
, wParam
, lParam
) ;
570 case WM_NCLBUTTONDOWN
:
574 // If we're iconic or we don't have a caption then
575 // DefWindowProc will do the job just fine.
577 if (IsIconic( hWnd
) || !HASCAPTION( hWnd
))
578 return DefWindowProc( hWnd
, uiMsg
, wParam
, lParam
) ;
580 // Here's were we handle the system menu, the min and max buttons.
581 // If you wanted to change the behavior of the min/max buttons
582 // do something like swap tool palettes or something, you
583 // would change the SendMessage() calls below.
588 if (GETMENUWASUPFLAG( hWnd
) == FALSE
&& DoMenu( hWnd
))
589 SETMENUWASUPFLAG( hWnd
, TRUE
) ;
591 SETMENUWASUPFLAG( hWnd
, FALSE
) ;
595 GetMinButtonRect( hWnd
, &rc
) ;
596 // Note that DepressMinMaxButton() goes into
597 // a PeekMessage() loop waiting for the mouse
600 if (DepressMinMaxButton( hWnd
, wParam
, &rc
))
601 SendMessage( hWnd
, WM_SYSCOMMAND
, SC_MINIMIZE
, lParam
) ;
605 GetMaxButtonRect( hWnd
, &rc
) ;
606 // Note that DepressMinMaxButton() goes into
607 // a PeekMessage() loop waiting for the mouse
610 if (DepressMinMaxButton( hWnd
, wParam
, &rc
))
613 SendMessage( hWnd
, WM_SYSCOMMAND
, SC_RESTORE
, lParam
) ;
615 SendMessage( hWnd
, WM_SYSCOMMAND
, SC_MAXIMIZE
, lParam
) ;
620 // Well, it appears as though the user clicked somewhere other
621 // than the buttons. We let DefWindowProc do it's magic.
622 // This is where things like dragging and sizing the
625 return DefWindowProc( hWnd
, uiMsg
, wParam
, lParam
) ;
632 if (IsIconic( hWnd
))
633 return DefWindowProc( hWnd
, uiMsg
, wParam
, lParam
) ;
635 // Paint the non-client area here. We will call DefWindowProc
636 // after we are done so it can paint the borders and so
639 lRet
= DefWindowProc( hWnd
, uiMsg
, wParam
, lParam
) ;
640 if (HASCAPTION( hWnd
))
644 HDC hDC
= GetWindowDC( hWnd
) ;
647 GetCaptionRect( hWnd
, &rcCap
) ; // Convert to window coords
648 GetWindowRect( hWnd
, &rc
) ;
649 OffsetRect( &rcCap
, -rc
.left
, -rc
.top
) ;
651 if (uiMsg
== WM_NCPAINT
)
652 fActive
= (hWnd
== GetActiveWindow()) ;
656 DrawCaption( hDC
, hWnd
, &rcCap
,
657 TestWinStyle(hWnd
, IBS_VERTCAPTION
),
658 TestWinStyle(hWnd
, WS_SYSMENU
),
659 TestWinStyle(hWnd
, WS_MINIMIZEBOX
),
660 TestWinStyle(hWnd
, WS_MAXIMIZEBOX
),
663 ReleaseDC( hWnd
, hDC
) ;
669 return DefWindowProc( hWnd
, uiMsg
, wParam
, lParam
) ;
674 } // ibDefWindowProc()
676 // ibAdjustWindowRect( HWND hWnd, LPRECT lprc )
678 // Does the same thing as the USER function AdjustWindowRect(),
679 // but knows about itsybitsy windows. AdjustWindowRect() is
680 // bogus for stuff like this.
682 void WINAPI
ibAdjustWindowRect( HWND hWnd
, LPRECT lprc
)
684 short cx
= 0, cy
= 0 ;
687 nCapSize
= GETCAPTIONSIZE( hWnd
) ;
689 // First check Windows's styles, then our own.
691 if (TestWinStyle( hWnd
, WS_THICKFRAME
))
693 cx
= GetSystemMetrics( SM_CXFRAME
) ;
694 cy
= GetSystemMetrics( SM_CYFRAME
) ;
697 if (TestWinStyle(hWnd
, DS_MODALFRAME
))
699 cx
= GetSystemMetrics( SM_CXDLGFRAME
) + GetSystemMetrics( SM_CXBORDER
) ;
700 cy
= GetSystemMetrics( SM_CYDLGFRAME
) + GetSystemMetrics( SM_CYBORDER
) ;
703 if (TestWinStyle(hWnd
, WS_BORDER
))
705 cx
= GetSystemMetrics( SM_CXBORDER
) ;
706 cy
= GetSystemMetrics( SM_CYBORDER
) ;
709 InflateRect( lprc
, cx
, cy
) ;
711 if (TestWinStyle( hWnd
, IBS_VERTCAPTION
))
712 lprc
->left
-= nCapSize
;
714 if (TestWinStyle( hWnd
, IBS_HORZCAPTION
))
715 lprc
->top
-= nCapSize
;
717 } // ibAdjustWindowRect()
720 ///////////////////////////////////////////////////////////////////////
721 // Internal functions
722 ///////////////////////////////////////////////////////////////////////
724 // DepressMinMaxButton()
726 // This function is called when the user has pressed either the min or
727 // max button (i.e. WM_NCLBUTTONDOWN). We go into a Peekmessage() loop,
728 // waiting for the mouse to come back up. This allows us to make the
729 // button change up/down state like a real button does.
731 // lprc points to the rectangle that describes the button the
732 // user has clicked on.
734 BOOL PASCAL
DepressMinMaxButton( HWND hWnd
, UINT uiHT
, LPRECT lprc
)
736 BOOL fDepressed
= TRUE
;
739 // Draw button in down state
740 DrawButton( NULL
, hWnd
, uiHT
== HTMINBUTTON
, fDepressed
) ;
745 if (PeekMessage((LPMSG
)&msg
, NULL
, WM_MOUSEFIRST
, WM_MOUSELAST
, PM_REMOVE
))
751 DrawButton( NULL
, hWnd
, uiHT
== HTMINBUTTON
, !fDepressed
) ;
753 return PtInRect( lprc
, msg
.pt
) ;
756 if (PtInRect( lprc
, msg
.pt
))
759 DrawButton( NULL
, hWnd
, uiHT
== HTMINBUTTON
, fDepressed
= TRUE
) ;
764 DrawButton( NULL
, hWnd
, uiHT
== HTMINBUTTON
, fDepressed
= FALSE
) ;
771 } // DepressMinMaxButton()
773 // DrawCaption( HDC hDC, HWND hWnd, LPRECT lprc,
774 // BOOL fVert, BOOL fSysMenu, BOOL fActive )
776 // This function draws an itsy bitsy caption bar with or
777 // without system menu to the dc specified by hDC. The
778 // caption is drawn to fit within the lprc RECT and is
779 // drawn//withOut/ borders.
781 BOOL PASCAL
DrawCaption( HDC hDC
, HWND hWnd
, LPRECT lprc
,
782 BOOL fVert
, BOOL fSysMenu
, BOOL fMin
,
783 BOOL fMax
, BOOL fActive
)
787 COLORREF rgbCaptionBG
;
789 COLORREF rgbWindowFrame
;
794 nCapSize
= GETCAPTIONSIZE( hWnd
) ;
798 rgbWindowFrame
= GetSysColor( COLOR_WINDOWFRAME
) ;
800 // if we have focus use the active caption color
801 // otherwise use the inactive caption color
805 rgbText
= GetSysColor( COLOR_CAPTIONTEXT
) ;
806 rgbCaptionBG
= GetSysColor( COLOR_ACTIVECAPTION
) ;
811 rgbText
= GetSysColor( COLOR_INACTIVECAPTIONTEXT
) ;
813 rgbText
= GetSysColor( COLOR_CAPTIONTEXT
) ;
815 rgbCaptionBG
= GetSysColor( COLOR_INACTIVECAPTION
) ;
818 SetBkMode( hDC
, TRANSPARENT
) ;
819 SelectObject( hDC
, GetStockObject( NULL_BRUSH
) ) ;
820 SelectObject( hDC
, GetStockObject( NULL_PEN
) ) ;
827 rcCap
.top
+= nCapSize
;
829 rcCap
.left
+= nCapSize
;
835 rcCap
.bottom
-= nCapSize
;
837 rcCap
.right
-= nCapSize
;
843 rcCap
.bottom
-= nCapSize
;
845 rcCap
.right
-= nCapSize
;
850 rc
.left
= lprc
->right
- 1 ;
851 rc
.right
= lprc
->right
;
853 rc
.bottom
= lprc
->bottom
;
857 rc
.left
= lprc
->left
;
858 rc
.right
= lprc
->right
;
859 rc
.bottom
= lprc
->bottom
;
860 rc
.top
= rc
.bottom
- 1 ;
863 SetBkColor( hDC
, rgbWindowFrame
) ;
864 DRAWFASTRECT( hDC
, &rc
) ;
866 hbrCaption
= CreateSolidBrush( rgbCaptionBG
) ;
867 hbrCaption
= (HBRUSH
) SelectObject( hDC
, hbrCaption
) ;
868 SelectObject( hDC
, (HPEN
) GetStockObject( NULL_PEN
) ) ;
870 Rectangle( hDC
, rcCap
.left
, rcCap
.top
, rcCap
.right
, rcCap
.bottom
+ 1 ) ;
872 Rectangle( hDC
, rcCap
.left
, rcCap
.top
, rcCap
.right
+1, rcCap
.bottom
) ;
873 hbrCaption
= (HBRUSH
) SelectObject( hDC
, hbrCaption
) ;
874 DeleteObject( hbrCaption
) ;
877 // Draw caption text here. Only do it in 3.1 'cause 3.1 gives
880 ui
= GetWindowTextLength( hWnd
) ;
891 lpsz
= (wxChar
*)GlobalAllocPtr( GHND
, (ui
+ 2) * sizeof(wxChar
) );
896 GetWindowText( hWnd
, lpsz
, ui
+ 1 ) ;
897 nBkMode
= SetBkMode( hDC
, TRANSPARENT
) ;
898 rgbText
= SetTextColor( hDC
, rgbText
) ;
900 memset( &lf
, '\0', sizeof(LOGFONT
) ) ;
902 lf
.lfHeight
= -(int)(nCapSize
- 3) ;
903 lf
.lfCharSet
= ANSI_CHARSET
;
904 lf
.lfQuality
= DEFAULT_QUALITY
;
905 lf
.lfClipPrecision
= CLIP_LH_ANGLES
| CLIP_STROKE_PRECIS
;
908 lf
.lfWeight
= FW_BOLD
;
913 // Can only rotate true type fonts (well, ok, we could
914 // try and use "modern").
915 wxStrcpy( lf
.lfFaceName
, wxT("Arial") ) ;
916 lf
.lfPitchAndFamily
= FF_SWISS
| 0x04;
917 lf
.lfEscapement
= 900 ;
919 // Note: The Win 3.1 documentation for CreateFont() say's
920 // that the lfOrientation member is ignored. It appears,
921 // that on Windows 16 3.1 this is true, but when running
922 // as a 16 bit WinApp on WindowsNT 3.1 the lfOrientation
923 // must be set or the text does not rotate!
925 lf
.lfOrientation
= 900 ;
927 hFont
= CreateFontIndirect( &lf
) ;
928 hFont
= (HFONT
) SelectObject( hDC
, hFont
) ;
930 GetTextExtentPoint( hDC
, lpsz
, ui
, &Size
) ;
931 cx
= rcCap
.bottom
- ((rcCap
.bottom
- rcCap
.top
- Size
.cx
) / 2) ;
932 cy
= rcCap
.left
- 1 + ((rcCap
.right
- rcCap
.left
- Size
.cy
) / 2) ;
934 // Make sure we got a rotatable font back.
936 GetTextMetrics( hDC
, &tm
) ;
937 if (tm
.tmPitchAndFamily
& TMPF_VECTOR
||
938 tm
.tmPitchAndFamily
& TMPF_TRUETYPE
)
942 min( (long)cx
, rcCap
.bottom
),
947 hFont
= (HFONT
) SelectObject( hDC
, hFont
) ;
948 DeleteObject( hFont
) ;
952 // Use small fonts always for the horizontal. Cause it looks
953 // more like "System" than Arial.
955 lf
.lfPitchAndFamily
= FF_SWISS
;
957 hFont
= CreateFontIndirect( &lf
) ;
958 hFont
= (HFONT
) SelectObject( hDC
, hFont
) ;
960 GetTextExtentPoint( hDC
, lpsz
, ui
, &Size
) ;
961 cx
= rcCap
.left
+ ((rcCap
.right
- rcCap
.left
- Size
.cx
) / 2) ;
962 cy
= rcCap
.top
+ ((rcCap
.bottom
- rcCap
.top
- Size
.cy
) / 2) ;
964 // Figger out how big the string is
967 max( (long)cx
, rcCap
.left
),
972 hFont
= (HFONT
) SelectObject( hDC
, hFont
) ;
973 DeleteObject( hFont
) ;
978 rgbText
= SetTextColor( hDC
, rgbText
) ;
979 SetBkMode( hDC
, nBkMode
) ;
982 GlobalFreePtr( (unsigned int)(DWORD
) lpsz
) ;
984 GlobalFreePtr( lpsz
) ;
990 DrawSysMenu( hDC
, hWnd
, FALSE
) ;
993 DrawButton( hDC
, hWnd
, TRUE
, FALSE
) ;
996 DrawButton( hDC
, hWnd
, FALSE
, FALSE
) ;
1003 // DrawSysMenu( HDC hDC, hWnd, BOOL fInvert )
1005 // Draws the little system menu icon.
1007 void PASCAL
DrawSysMenu( HDC hDC
, HWND hWnd
, BOOL fInvert
)
1012 COLORREF rgbIconFace
;
1013 COLORREF rgbWindowFrame
;
1017 nCapSize
= GETCAPTIONSIZE( hWnd
) ;
1022 hDC
= GetWindowDC( hWnd
) ;
1029 rgbIconFace
= GetNearestColor( hDC
, RGBLTGRAY
) ;
1030 rgbWindowFrame
= GetSysColor( COLOR_WINDOWFRAME
) ;
1032 GetIconRect( hWnd
, &rcIcon
) ;
1033 GetWindowRect( hWnd
, &rc
) ;
1035 OffsetRect( &rcIcon
, -rc
.left
, -rc
.top
) ;
1039 if (TestWinStyle( hWnd
, IBS_VERTCAPTION
))
1041 rc
= rcIcon
; // separator line
1042 rc
.top
= ++rc
.bottom
- 1 ;
1046 rc
= rcIcon
; // separator line
1047 rc
.left
= ++rc
.right
- 1 ;
1051 SetBkColor( hDC
, rgbIconFace
) ;
1052 DRAWFASTRECT( hDC
, &rcTemp
) ;
1054 // Draw separator line
1055 SetBkColor( hDC
, rgbWindowFrame
) ;
1056 DRAWFASTRECT( hDC
, &rc
) ;
1060 // Draw the little horizontal doo-hickey
1062 rcTemp
.top
= rcIcon
.top
+ ((nCapSize
-1) / 2) ;
1063 rcTemp
.bottom
= rcTemp
.top
+ 3 ;
1064 rcTemp
.left
= rcTemp
.left
+ 3 ;
1065 rcTemp
.right
= rcTemp
.right
- 1 ;
1067 SetBkColor( hDC
, RGBGRAY
) ;
1068 DRAWFASTRECT( hDC
, &rcTemp
) ;
1071 OffsetRect( &rc
, -1, -1 ) ;
1072 SetBkColor( hDC
, RGBBLACK
) ;
1073 DRAWFASTRECT( hDC
, &rc
) ;
1075 InflateRect( &rc
, -1, -1 ) ;
1076 SetBkColor( hDC
, RGBWHITE
) ;
1077 DRAWFASTRECT( hDC
, &rc
) ;
1081 InvertRect( hDC
, &rcIcon
) ;
1084 ReleaseDC( hWnd
, hDC
) ;
1089 // DoMenu( HWND hWnd )
1091 // Pops up the system menu.
1093 BOOL PASCAL
DoMenu( HWND hWnd
)
1102 if (!TestWinStyle(hWnd
, WS_SYSMENU
))
1105 hDC
= GetWindowDC( hWnd
);
1110 DrawSysMenu( hDC
, hWnd
, TRUE
) ;
1114 if (TestWinStyle( hWnd
, IBS_VERTCAPTION
))
1125 GetIconRect( hWnd
, &rcIcon
) ;
1126 GetWindowRect( hWnd
, &rc
) ;
1127 OffsetRect( &rcIcon
, -rc
.left
, -rc
.top
) ;
1129 ClientToScreen( hWnd
, &pt
) ;
1130 ClientToScreen( hWnd
, (LPPOINT
)&rc
.right
) ;
1132 dw
= GetWindowLong( hWnd
, GWL_STYLE
) ;
1133 SetWindowLong( hWnd
, GWL_STYLE
, dw
| WS_SYSMENU
) ;
1135 hMenu
= GetSystemMenu( hWnd
, FALSE
) ;
1136 SetupSystemMenu( hWnd
, hMenu
) ;
1138 SetWindowLong( hWnd
, GWL_STYLE
, dw
) ;
1140 TrackPopupMenu( hMenu
, 0, //TPM_LEFTALIGN,
1147 DrawSysMenu( hDC
, hWnd
, FALSE
) ;
1148 ReleaseDC( hWnd
, hDC
) ;
1154 // SetupSystemMenu( HWND hWnd, HMENU hMenu )
1156 // Enables/Disables the appropriate menu items on the
1157 // menu passed for the window passed.
1159 void PASCAL
SetupSystemMenu( HWND hWnd
, HMENU hMenu
)
1167 // Assume all should be grayed.
1169 wSize
= wMove
= wMinBox
= wMaxBox
= wRestore
= MF_GRAYED
;
1171 if (TestWinStyle( hWnd
, WS_MAXIMIZEBOX
) || IsIconic( hWnd
))
1172 wMaxBox
= MF_ENABLED
;
1174 if (TestWinStyle( hWnd
, WS_MINIMIZEBOX
))
1175 wMinBox
= MF_ENABLED
;
1177 if (IsZoomed( hWnd
))
1178 wRestore
= MF_ENABLED
;
1180 if (TestWinStyle( hWnd
, WS_THICKFRAME
) &&
1181 !(IsIconic( hWnd
) || IsZoomed( hWnd
)))
1182 wSize
= MF_ENABLED
;
1184 if (!IsZoomed( hWnd
) &&
1185 !IsIconic( hWnd
) &&
1186 TestWinStyle( hWnd
, WS_CAPTION
) )
1187 wMove
= MF_ENABLED
;
1189 EnableMenuItem( hMenu
, SC_MOVE
, wMove
) ;
1190 EnableMenuItem( hMenu
, SC_SIZE
, wSize
) ;
1191 EnableMenuItem( hMenu
, SC_MINIMIZE
, wMinBox
) ;
1192 EnableMenuItem( hMenu
, SC_MAXIMIZE
, wMaxBox
) ;
1193 EnableMenuItem( hMenu
, SC_RESTORE
, wRestore
) ;
1195 } // SetupSystemMenu()
1197 // GetCaptionRect( HWND hWnd, LPRECT lprc )
1199 // calcluales the rectangle of the mini-caption in screen coords.
1201 BOOL PASCAL
GetCaptionRect( HWND hWnd
, LPRECT lprc
)
1205 nCapSize
= GETCAPTIONSIZE( hWnd
) ;
1207 if (!HASCAPTION( hWnd
))
1209 SetRectEmpty( lprc
) ;
1213 GetWindowRect( hWnd
, lprc
) ;
1215 // the window might have other non-client components like
1218 if (TestWinStyle( hWnd
, WS_THICKFRAME
))
1220 lprc
->left
+= GetSystemMetrics( SM_CXFRAME
) ;
1221 lprc
->top
+= GetSystemMetrics( SM_CYFRAME
) ;
1222 lprc
->right
-= GetSystemMetrics( SM_CXFRAME
) ;
1223 lprc
->bottom
-= GetSystemMetrics( SM_CYFRAME
) ;
1226 if (TestWinStyle( hWnd
, DS_MODALFRAME
)) // if it's a dialog box
1228 lprc
->left
+= GetSystemMetrics( SM_CXDLGFRAME
) + GetSystemMetrics( SM_CXBORDER
) ;
1229 lprc
->top
+= GetSystemMetrics( SM_CYDLGFRAME
) + GetSystemMetrics( SM_CYBORDER
) ;
1230 lprc
->right
-= GetSystemMetrics( SM_CXDLGFRAME
) + GetSystemMetrics( SM_CXBORDER
) ;
1231 lprc
->bottom
-= GetSystemMetrics( SM_CYDLGFRAME
) + GetSystemMetrics( SM_CYBORDER
) ;
1234 if (TestWinStyle( hWnd
, WS_BORDER
))
1236 lprc
->left
+= GetSystemMetrics( SM_CXBORDER
) ;
1237 lprc
->top
+= GetSystemMetrics( SM_CYBORDER
) ;
1238 lprc
->right
-= GetSystemMetrics( SM_CXBORDER
) ;
1239 lprc
->bottom
-= GetSystemMetrics( SM_CYBORDER
) ;
1242 if (TestWinStyle( hWnd
, IBS_VERTCAPTION
))
1243 lprc
->right
= lprc
->left
+ nCapSize
;
1245 lprc
->bottom
= lprc
->top
+ nCapSize
;
1248 } // GetCaptionRect()
1250 // GetIconRect( HWND hWnd, LPRECT lprc )
1252 // Calculates the rect of the icon in screen coordinates.
1254 BOOL PASCAL
GetIconRect( HWND hWnd
, LPRECT lprc
)
1259 fMenu
= TestWinStyle( hWnd
, WS_SYSMENU
) ;
1260 fVert
= TestWinStyle( hWnd
, IBS_VERTCAPTION
) ;
1262 if (!GetCaptionRect( hWnd
, lprc
)) // window coords
1267 SetRectEmpty( lprc
) ;
1271 nCapSize
= GETCAPTIONSIZE( hWnd
) ;
1274 lprc
->bottom
= lprc
->top
+ nCapSize
;
1276 lprc
->right
= lprc
->left
+ nCapSize
;
1285 // GetMinButtonRect()
1287 // Calculates the rect of the minimize button in screen
1290 // For horizontal captions, we have the following situation ('Y' is minimize
1291 // and '^' is maximize or restore):
1293 // +---------------------------------+
1295 // +---------------------------------+
1296 // | |.......| <-- This is the width (nSize)
1298 // For vertical captions, we have the following:
1308 // |--| . <-- This is the height of the rectangle (nSize)
1312 // In order to figure out where the minimize button goes, we first need
1313 // to know if there is a maximize button. If so, use GetMaxButtonRect()
1316 BOOL PASCAL
GetMinButtonRect( HWND hWnd
, LPRECT lprc
)
1318 if (!TestWinStyle( hWnd
, WS_MINIMIZEBOX
))
1320 SetRectEmpty( lprc
) ;
1324 // The minimize button can be in either position 1 or 2. If there
1325 // is a maximize button, it's in position 2.
1327 if (TestWinStyle( hWnd
, WS_MAXIMIZEBOX
))
1328 return GetButtonRect( hWnd
, 2, lprc
) ;
1330 return GetButtonRect( hWnd
, 1, lprc
) ;
1333 // GetMaxButtonRect()
1335 // Calculates the rect of the maximize button in screen
1338 // The maximize button, if present, is always to the far right
1341 BOOL PASCAL
GetMaxButtonRect( HWND hWnd
, LPRECT lprc
)
1343 //The maximize button can only be in position 1.
1345 if (TestWinStyle( hWnd
, WS_MAXIMIZEBOX
))
1346 return GetButtonRect( hWnd
, 1, lprc
) ;
1349 SetRectEmpty( lprc
) ;
1354 // Get the rect where a button would go.
1356 // This function does not care if it's a min or max, just whether
1357 // it is the first from the right/bottom or second from the right/bottom
1360 BOOL PASCAL
GetButtonRect( HWND hWnd
, UINT nPos
, LPRECT lprc
)
1364 if (!GetCaptionRect( hWnd
, lprc
)) //window coords
1367 nSize
= GETCAPTIONSIZE( hWnd
) ;
1369 if (TestWinStyle( hWnd
, IBS_VERTCAPTION
))
1371 lprc
->bottom
-= nSize
* (nPos
-1) ;
1372 lprc
->top
= lprc
->bottom
- nSize
+ 1 ;
1376 lprc
->right
-= nSize
* (nPos
-1) ;
1377 lprc
->left
= lprc
->right
- nSize
+ 1 ;
1381 } // GetButtonRect()
1383 // DrawButton( HDC hDC, HWND hWnd, BOOL fMin, BOOL fDepressed )
1385 // Draws either the min, max, or restore buttons. If fMin is FALSE then it
1386 // will draw either the Max or Restore button. If fDepressed is TRUE it will
1387 // draw the button in a down state.
1389 void PASCAL
DrawButton( HDC hDC
, HWND hWnd
, BOOL fMin
, BOOL fDepressed
)
1393 COLORREF rgbWindowFrame
;
1399 nCapSize
= GETCAPTIONSIZE( hWnd
) ;
1401 // If you look at the standard Windows' min/max buttons, you will notice
1402 // that they have two pixels of 'shadow' to the bottom and right. Since
1403 // our buttons can be really, really small, we only want one pixel of
1404 // shadow when they are small. I arbitrarily decided that if the
1405 // caption size is greater than or equal to 20 we will use two
1406 // pixels. That's what this THREASHOLD stuff does.
1408 #define THRESHOLD 20
1409 nOffset
= (nCapSize
>= THRESHOLD
) ? 2 : 1 ;
1414 hDC
= GetWindowDC( hWnd
) ;
1421 rgbWindowFrame
= GetSysColor( COLOR_WINDOWFRAME
) ;
1424 GetMinButtonRect( hWnd
, &rcButton
) ;
1426 GetMaxButtonRect( hWnd
, &rcButton
) ;
1428 GetWindowRect( hWnd
, &rc
) ;
1429 OffsetRect( &rcButton
, -rc
.left
, -rc
.top
) ;
1432 if (TestWinStyle( hWnd
, IBS_VERTCAPTION
))
1434 rc
= rcButton
; //separator line
1435 rc
.bottom
= --rc
.top
+ 1 ;
1440 rc
= rcButton
; //separator line
1441 rc
.right
= --rc
.left
+ 1 ;
1445 //Draw separator line
1446 SetBkColor( hDC
, rgbWindowFrame
) ;
1447 DRAWFASTRECT( hDC
, &rc
) ;
1450 SetBkColor( hDC
, RGBLTGRAY
) ;
1451 DRAWFASTRECT( hDC
, &rcButton
) ;
1455 //The normal min/max buttons have one pixel on the top and left
1456 //sides for the highlight, and two pixels on the bottom and
1457 //right side for the shadow.
1459 //When our caption is 'small' we only use one pixel on all
1462 SetBkColor( hDC
, RGBWHITE
) ;
1465 rc
.right
= rc
.left
+ 1 ;
1466 DRAWFASTRECT( hDC
, &rc
) ;
1470 rc
.bottom
= rc
.top
+ 1 ;
1471 DRAWFASTRECT( hDC
, &rc
) ;
1473 SetBkColor( hDC
, RGBGRAY
) ;
1476 rc
.left
= rc
.right
- 1 ;
1477 DRAWFASTRECT( hDC
, &rc
) ;
1478 if (nCapSize
> THRESHOLD
)
1482 DRAWFASTRECT( hDC
, &rc
) ;
1487 rc
.top
= rc
.bottom
- 1 ;
1488 DRAWFASTRECT( hDC
, &rc
) ;
1489 if (nCapSize
> THRESHOLD
)
1493 DRAWFASTRECT( hDC
, &rc
) ;
1498 rcButton
.right
-= nOffset
;
1499 rcButton
.bottom
-= nOffset
;
1503 //Draw depressed state
1505 SetBkColor( hDC
, RGBGRAY
) ;
1508 rc
.right
= rc
.left
+ nOffset
;
1509 DRAWFASTRECT( hDC
, &rc
) ;
1513 rc
.bottom
= rc
.top
+ nOffset
;
1514 DRAWFASTRECT( hDC
, &rc
) ;
1516 rcButton
.left
+= 2 * nOffset
;
1517 rcButton
.top
+= 2 * nOffset
;
1520 // Now draw the arrows. We do not want the
1521 // arrows to grow too large when we have a bigger than
1522 // normal caption, so we restrict their size.
1524 // rcButton now represents where we can place our
1527 // The maximum size of our arrows (i.e. the width of rcButton)
1528 // has been empirically determined to be SM_CYCAPTION / 2
1530 n
= ((GetSystemMetrics( SM_CYCAPTION
)) / 2) -
1531 (rcButton
.right
- rcButton
.left
) ;
1533 InflateRect( &rcButton
, n
/2-1, n
/2-1 ) ;
1536 DrawArrow( hDC
, &rcButton
, ARROW_DOWN
) ;
1538 if (IsZoomed( hWnd
))
1540 DrawArrow( hDC
, &rcButton
, ARROW_RESTORE
) ;
1543 DrawArrow( hDC
, &rcButton
, ARROW_UP
) ;
1546 ReleaseDC( hWnd
, hDC
) ;
1554 // Draws either a up or down arrow. The arrow is bound by the rectangle
1556 void PASCAL
DrawArrow( HDC hdc
, LPRECT lprc
, UINT uiStyle
)
1562 int nMax
= (lprc
->bottom
- lprc
->top
) >> 1 ;
1564 SetBkColor( hdc
, RGBBLACK
) ;
1566 // We draw the arrow by drawing a series of horizontal lines
1568 xTip
= lprc
->left
+ ((lprc
->right
- lprc
->left
+1) >> 1) ;
1572 yTip
= lprc
->top
+ ((lprc
->bottom
- lprc
->top
-1) >> 2) ;
1573 for (row
= 1 ; row
<= nMax
; row
++ )
1575 rc
.left
= xTip
- row
;
1576 rc
.right
= xTip
+ row
- 1 ;
1577 rc
.top
= yTip
+ row
;
1578 rc
.bottom
= rc
.top
+ 1 ;
1579 DRAWFASTRECT( hdc
, &rc
) ;
1584 yTip
= lprc
->bottom
- ((lprc
->bottom
- lprc
->top
-1) >> 2) ;
1585 for ( row
= nMax
; row
> 0 ; row
-- )
1587 rc
.left
= xTip
- row
;
1588 rc
.right
= xTip
+ row
- 1 ;
1589 rc
.top
= yTip
- row
;
1590 rc
.bottom
= rc
.top
+ 1 ;
1591 DRAWFASTRECT( hdc
, &rc
) ;
1597 yTip
= lprc
->top
+ ((lprc
->bottom
- lprc
->top
-1) >> 3) - 2;
1598 for (row
= 1 ; row
<= nMax
; row
++ )
1600 rc
.left
= xTip
- row
;
1601 rc
.right
= xTip
+ row
- 1 ;
1602 rc
.top
= yTip
+ row
;
1603 rc
.bottom
= rc
.top
+ 1 ;
1604 DRAWFASTRECT( hdc
, &rc
) ;
1607 yTip
+= (nMax
+1) * 2 ;
1608 for ( row
= nMax
; row
> 0 ; row
-- )
1610 rc
.left
= xTip
- row
;
1611 rc
.right
= xTip
+ row
- 1 ;
1612 rc
.top
= yTip
- row
;
1613 rc
.bottom
= rc
.top
+ 1 ;
1614 DRAWFASTRECT( hdc
, &rc
) ;
1621 #endif // wxUSE_ITSY_BITSY