]>
git.saurik.com Git - wxWidgets.git/blob - src/msw/gaugemsw.cpp
1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxGaugeMSW class
4 // Author: Julian Smart
8 // Copyright: (c) Julian Smart and Markus Holzem
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "gauge.h"
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
30 #include "wx/msw/gaugemsw.h"
31 #include "wx/msw/private.h"
33 /* gas gauge graph control messages--class "zYzGauge" */
34 #define ZYZG_SETRANGE (WM_USER + 0)
35 #define ZYZG_GETRANGE (WM_USER + 1)
36 #define ZYZG_SETPOSITION (WM_USER + 2)
37 #define ZYZG_GETPOSITION (WM_USER + 3)
38 #define ZYZG_SETORIENTATION (WM_USER + 4)
39 #define ZYZG_GETORIENTATION (WM_USER + 5)
40 #define ZYZG_SETFGCOLOR (WM_USER + 6)
41 #define ZYZG_GETFGCOLOR (WM_USER + 7)
42 #define ZYZG_SETBKCOLOR (WM_USER + 8)
43 #define ZYZG_GETBKCOLOR (WM_USER + 9)
44 #define ZYZG_SETWIDTH3D (WM_USER + 10)
45 #define ZYZG_GETWIDTH3D (WM_USER + 11)
46 #define ZYZG_SETBEZELFACE (WM_USER + 12)
47 #define ZYZG_GETBEZELFACE (WM_USER + 13)
48 #define ZYZG_SETDELTAPOS (WM_USER + 14)
51 /* orientations for ZYZG_WW_ORIENTATION */
52 #define ZYZG_ORIENT_LEFTTORIGHT 0
53 #define ZYZG_ORIENT_RIGHTTOLEFT 1
54 #define ZYZG_ORIENT_BOTTOMTOTOP 2
55 #define ZYZG_ORIENT_TOPTOBOTTOM 3
58 #define ZYZGS_3D 0x8000L /* control will be 3D */
60 /* public function prototypes */
61 BOOL FAR PASCAL
gaugeInit(HINSTANCE hInstance
);
63 IMPLEMENT_DYNAMIC_CLASS(wxGaugeMSW
, wxControl
)
65 bool wxGaugeMSW::Create(wxWindow
*parent
, wxWindowID id
,
70 const wxValidator
& validator
,
73 static bool wxGaugeMSWInitialised
= FALSE
;
75 if ( !wxGaugeMSWInitialised
)
77 if (!gaugeInit((HINSTANCE
) wxGetInstance()))
78 wxFatalError("Cannot initalize Gauge library");
79 wxGaugeMSWInitialised
= TRUE
;
84 SetValidator(validator
);
85 #endif // wxUSE_VALIDATORS
87 if (parent
) parent
->AddChild(this);
91 SetBackgroundColour(parent
->GetBackgroundColour()) ;
92 SetForegroundColour(parent
->GetForegroundColour()) ;
94 m_windowStyle
= style
;
97 m_windowId
= (int)NewControlId();
106 long msFlags
= WS_CHILD
| WS_VISIBLE
| WS_TABSTOP
;
108 WXDWORD exStyle
= Determine3DEffects(WS_EX_CLIENTEDGE
, &want3D
);
113 CreateWindowEx(MakeExtendedStyle(m_windowStyle
), wxT("zYzGauge"), NULL
, msFlags
,
114 0, 0, 0, 0, (HWND
) parent
->GetHWND(), (HMENU
)m_windowId
,
115 wxGetInstance(), NULL
);
117 m_hWnd
= (WXHWND
)wx_button
;
119 // Subclass again for purposes of dialog editing mode
120 SubclassWin((WXHWND
)wx_button
);
124 if (m_windowStyle
& wxGA_HORIZONTAL
)
125 wOrient
= ZYZG_ORIENT_LEFTTORIGHT
;
127 wOrient
= ZYZG_ORIENT_BOTTOMTOTOP
;
129 SendMessage(wx_button
, ZYZG_SETORIENTATION
, wOrient
, 0);
130 SendMessage(wx_button
, ZYZG_SETRANGE
, range
, 0);
132 SendMessage(GetHwnd(), ZYZG_SETFGCOLOR
, 0, RGB(GetForegroundColour().Red(), GetForegroundColour().Green(), GetForegroundColour().Blue()));
133 SendMessage(GetHwnd(), ZYZG_SETBKCOLOR
, 0, RGB(GetBackgroundColour().Red(), GetBackgroundColour().Green(), GetBackgroundColour().Blue()));
138 SetFont(parent
->GetFont());
144 SetSize(x
, y
, width
, height
);
146 ShowWindow(GetHwnd(), SW_SHOW
);
151 void wxGaugeMSW::SetShadowWidth(int w
)
153 SendMessage(GetHwnd(), ZYZG_SETWIDTH3D
, w
, 0);
156 void wxGaugeMSW::SetBezelFace(int w
)
158 SendMessage(GetHwnd(), ZYZG_SETBEZELFACE
, w
, 0);
161 void wxGaugeMSW::SetRange(int r
)
165 SendMessage(GetHwnd(), ZYZG_SETRANGE
, r
, 0);
168 void wxGaugeMSW::SetValue(int pos
)
172 SendMessage(GetHwnd(), ZYZG_SETPOSITION
, pos
, 0);
175 int wxGaugeMSW::GetShadowWidth(void) const
177 return (int) SendMessage(GetHwnd(), ZYZG_GETWIDTH3D
, 0, 0);
180 int wxGaugeMSW::GetBezelFace(void) const
182 return (int) SendMessage(GetHwnd(), ZYZG_GETBEZELFACE
, 0, 0);
185 int wxGaugeMSW::GetRange(void) const
187 return (int) SendMessage(GetHwnd(), ZYZG_GETRANGE
, 0, 0);
190 int wxGaugeMSW::GetValue(void) const
192 return (int) SendMessage(GetHwnd(), ZYZG_GETPOSITION
, 0, 0);
195 bool wxGaugeMSW::SetForegroundColour(const wxColour
& col
)
197 if ( !wxControl::SetForegroundColour(col
) )
200 SendMessage(GetHwnd(), ZYZG_SETFGCOLOR
, 0, RGB(col
.Red(), col
.Green(), col
.Blue()));
205 bool wxGaugeMSW::SetBackgroundColour(const wxColour
& col
)
207 if ( !wxControl::SetBackgroundColour(col
) )
210 SendMessage(GetHwnd(), ZYZG_SETBKCOLOR
, 0, RGB(col
.Red(), col
.Green(), col
.Blue()));
219 * This module contains functions for creating nifty 3D borders
220 * around controls like zYzGauge.
223 * 3/14/91 cjp put in this comment
224 * 6/19/92 cjp touched it a bit
229 // (C) Copyright Microsoft Corp. 1992. All rights reserved.
231 // You have a royalty-free right to use, modify, reproduce and
232 // distribute the Sample Files (and/or any modified version) in
233 // any way you find useful, provided that you agree that
234 // Microsoft has no warranty obligations or liability for any
235 // Sample Application Files which are modified.
239 /* get the includes we need */
242 /* misc. control flag defines */
243 #define DRAW3D_IN 0x0001
244 #define DRAW3D_OUT 0x0002
246 #define DRAW3D_TOPLINE 0x0004
247 #define DRAW3D_BOTTOMLINE 0x0008
248 #define DRAW3D_LEFTLINE 0x0010
249 #define DRAW3D_RIGHTLINE 0x0020
252 /* public function prototypes */
253 void FAR PASCAL
Draw3DFaceFrame(HDC
, LPRECT
, WORD
);
254 void FAR PASCAL
Draw3DRect(HDC
, LPRECT
, WORD
, WORD
);
255 void FAR PASCAL
Draw3DLine(HDC
, WORD
, WORD
, WORD
, WORD
, WORD
);
258 /** void FAR PASCAL Draw3DFaceFrame(HDC hdc, LPRECT rc, WORD wWidth)
261 * This function draws a flat frame with the current button-face
265 * HDC hdc : The DC to draw into.
267 * LPRECT rc : The containing rect for the new frame.
269 * WORD wWidth : The width of the frame to draw.
271 * RETURN (void FAR PASCAL):
272 * The frame will have been drawn into the DC.
278 void FAR PASCAL
Draw3DFaceFrame(HDC hdc
, LPRECT rc
, WORD wWidth
)
283 /* don't go through a bunch of work if we don't have to */
287 /* set up color to be button-face color--so it may not be gray */
288 rgbOld
= SetBkColor(hdc
, GetSysColor(COLOR_BTNFACE
));
290 /* perform CopyRect w/o bloody windows style overhead */
296 rc1
.bottom
= rc
->top
+ wWidth
;
297 rc1
.right
= rc
->right
;
300 ExtTextOut(hdc
, rc1
.left
, rc1
.top
, ETO_OPAQUE
, &rc1
, NULL
, 0, NULL
);
303 rc1
.left
= rc
->right
- wWidth
;
304 rc1
.bottom
= rc
->bottom
;
306 /* blast this part now */
307 ExtTextOut(hdc
, rc1
.left
, rc1
.top
, ETO_OPAQUE
, &rc1
, NULL
, 0, NULL
);
311 rc1
.right
= rc
->left
+ wWidth
;
313 /* and another part */
314 ExtTextOut(hdc
, rc1
.left
, rc1
.top
, ETO_OPAQUE
, &rc1
, NULL
, 0, NULL
);
317 rc1
.right
= rc
->right
;
318 rc1
.top
= rc
->bottom
- wWidth
;
321 ExtTextOut(hdc
, rc1
.left
, rc1
.top
, ETO_OPAQUE
, &rc1
, NULL
, 0, NULL
);
323 /* restore the old bk color */
324 SetBkColor(hdc
, rgbOld
);
325 } /* Draw3DFaceFrame() */
328 /** void FAR PASCAL Draw3DRect(HDC, LPRECT, WORD, WORD)
331 * Draws a 3D rectangle that is shaded. wFlags can be used to
332 * control how the rectangle looks.
335 * HDC hdc : Handle to the device context that will be
336 * used to display the rectangle.
338 * RECT rect : A rectangle describing the dimensions of
339 * the rectangle in device coordinates.
341 * WORD wShadowWidth : Width of the shadow in device coordinates.
343 * WORD wFlags : The following flags may be passed to describe
344 * the style of the rectangle:
346 * DRAW3D_IN : The shadow is drawn such that
347 * the box appears to be sunk in to the screen.
348 * This is default if 0 is passed.
350 * DRAW3D_OUT : The shadow is drawn such that
351 * the box appears to be sticking out of the
354 * RETURN (void FAR PASCAL):
355 * The 3D looking rectangle will have been drawn into the DC.
361 void FAR PASCAL
Draw3DRect(HDC hdc
, LPRECT lpRect
,
362 WORD wShadowWidth
, WORD wFlags
)
364 /* sanity check--don't work if you don't have to! */
365 if (!wShadowWidth
|| !RectVisible(hdc
, lpRect
))
368 /* draw the top line */
369 Draw3DLine(hdc
, lpRect
->left
, lpRect
->top
,
370 lpRect
->right
- lpRect
->left
,
371 wShadowWidth
, DRAW3D_TOPLINE
| wFlags
);
374 Draw3DLine(hdc
, lpRect
->right
, lpRect
->top
,
375 lpRect
->bottom
- lpRect
->top
,
376 wShadowWidth
, DRAW3D_RIGHTLINE
| wFlags
);
379 Draw3DLine(hdc
, lpRect
->left
, lpRect
->bottom
,
380 lpRect
->right
- lpRect
->left
,
381 wShadowWidth
, DRAW3D_BOTTOMLINE
| wFlags
);
384 Draw3DLine(hdc
, lpRect
->left
, lpRect
->top
,
385 lpRect
->bottom
- lpRect
->top
,
386 wShadowWidth
, DRAW3D_LEFTLINE
| wFlags
);
390 /** void FAR PASCAL Draw3DLine(HDC hdc, WORD x, WORD y, WORD nLen,
393 * Draws a 3D line that can be used to make a 3D box.
396 * HDC hdc : Handle to the device context that will be
397 * used to display the 3D line.
399 * WORD x, y : Coordinates of the beginning of the line.
400 * These coordinates are in device units and
401 * represent the _outside_ most point. Horiz-
402 * ontal lines are drawn from left to right and
403 * vertical lines are drawn from top to bottom.
405 * WORD wShadowWidth : Width of the shadow in device coordinates.
407 * WORD wFlags : The following flags may be passed to
408 * describe the style of the 3D line:
410 * DRAW3D_IN : The shadow is drawn such that
411 * the box appears to be sunk in to the screen.
412 * This is default if 0 is passed.
414 * DRAW3D_OUT : The shadow is drawn such that
415 * the box appears to be sticking out of the
418 * DRAW3D_TOPLINE, _BOTTOMLINE, _LEFTLINE, and
419 * _RIGHTLINE : Specifies that a "top",
420 * "Bottom", "Left", or"Right" line is to be
423 * RETURN (void FAR PASCAL):
424 * The line will have been drawn into the DC.
430 void FAR PASCAL
Draw3DLine(HDC hdc
, WORD x
, WORD y
, WORD nLen
,
431 WORD wShadowWidth
, WORD wFlags
)
436 POINT Point
[ 4 ]; /* define a polgon with 4 points */
438 /* if width is zero, don't do nothin'! */
442 /* define shape of polygon--origin is always the same */
446 /* To do this we'll simply draw a polygon with four sides, using
447 * the appropriate brush. I dare you to ask me why this isn't a
450 if (wFlags
& DRAW3D_TOPLINE
)
452 /* across to right */
453 Point
[1].x
= x
+ nLen
- (wShadowWidth
== 1 ? 1 : 0);
457 Point
[2].x
= x
+ nLen
- wShadowWidth
;
458 Point
[2].y
= y
+ wShadowWidth
;
460 /* accross to left */
461 Point
[3].x
= x
+ wShadowWidth
;
462 Point
[3].y
= y
+ wShadowWidth
;
464 /* select 'dark' brush if 'in'--'light' for 'out' */
465 fDark
= (wFlags
& DRAW3D_IN
) ? TRUE
: FALSE
;
468 /* possibly the bottom? */
469 else if (wFlags
& DRAW3D_BOTTOMLINE
)
471 /* across to right */
472 Point
[1].x
= x
+ nLen
;
476 Point
[2].x
= x
+ nLen
- wShadowWidth
;
477 Point
[2].y
= y
- wShadowWidth
;
479 /* accross to left */
480 Point
[3].x
= x
+ wShadowWidth
;
481 Point
[3].y
= y
- wShadowWidth
;
483 /* select 'light' brush if 'in' */
484 fDark
= (wFlags
& DRAW3D_IN
) ? FALSE
: TRUE
;
487 /* ok, it's gotta be left? */
488 else if (wFlags
& DRAW3D_LEFTLINE
)
492 Point
[1].y
= y
+ nLen
- (wShadowWidth
== 1 ? 1 : 0);
495 Point
[2].x
= x
+ wShadowWidth
;
496 Point
[2].y
= y
+ nLen
- wShadowWidth
;
499 Point
[3].x
= x
+ wShadowWidth
;
500 Point
[3].y
= y
+ wShadowWidth
;
502 /* select 'dark' brush if 'in'--'light' for 'out' */
503 fDark
= (wFlags
& DRAW3D_IN
) ? TRUE
: FALSE
;
506 /* well maybe it's for the right side? */
507 else if (wFlags
& DRAW3D_RIGHTLINE
)
511 Point
[1].y
= y
+ nLen
;
514 Point
[2].x
= x
- wShadowWidth
;
515 Point
[2].y
= y
+ nLen
- wShadowWidth
;
518 Point
[3].x
= x
- wShadowWidth
;
519 Point
[3].y
= y
+ wShadowWidth
;
521 /* select 'light' brush if 'in' */
522 fDark
= (wFlags
& DRAW3D_IN
) ? FALSE
: TRUE
;
528 /* select NULL_PEN for no borders */
529 hOldPen
= (HPEN
) SelectObject(hdc
, GetStockObject(NULL_PEN
));
531 /* select the appropriate color for the fill */
533 hOldBrush
= (HBRUSH
) SelectObject(hdc
, GetStockObject(GRAY_BRUSH
));
535 hOldBrush
= (HBRUSH
) SelectObject(hdc
, GetStockObject(WHITE_BRUSH
));
537 /* finally, draw the dern thing */
538 Polygon(hdc
, (LPPOINT
)&Point
, 4);
540 /* restore what we killed */
541 SelectObject(hdc
, hOldBrush
);
542 SelectObject(hdc
, hOldPen
);
550 * Yet another 'Gas Gauge Custom Control.' This control gives you
551 * a 'progress bar' class (named zYzGauge) for use in your applications.
552 * You can set the range, position, font, color, orientation, and 3d
553 * effect of the gauge by sending messages to the control.
555 * Before you can use this control, you MUST first export the window
556 * procedure for the control (or define it with the _export keyword):
558 * EXPORTS gaugeWndProc
560 * You then need initialize the class before you use it:
562 * if (!gaugeInit(hInstance))
563 * die a horrible death
567 * The colors used by the control default to black and white if you
568 * are running on a mono-display. They default to blue and white
569 * if you are on a color display. You enable the 3D effect by setting
570 * the ZYZGS_3D style flag in the styles field of the control (like
571 * any other control).
573 * To select your own colors, you can send the ZYZG_SETFGCOLOR and
574 * ZYZG_SETBKCOLOR messages to set the foreground (percent done) and
575 * background (percent not done) colors. The lParam is the RGB()
576 * value--wParam is ignored.
578 * In all of the following ZYZG_??? messages, the arguments are
579 * WORDS. If you are setting parameters, the value is sent as
580 * the wParam (lParam is ignored). If you are getting parameters,
581 * the value is returned as a LONG and should be cast to a *signed*
584 * To set the depth of the 3D effect (if enabled), you can send the
585 * ZYZG_SETBEZELFACE and ZYZG_SETWIDTH3D messages. The bezel face
586 * is the flat top on the 3D border--its color will be that of the
587 * button-face. The 3D width is the width of the bezel itself; inside
588 * and outside. The light color is white, the dark color is gray.
589 * Both widths *can* be zero--both default to 2 which looks to me.
591 * The range of the control can be set by sending the ZYZG_SETRANGE
592 * message to the control. It can be any integer from 1 to 32767.
593 * What this specifies is the number of pieces that create a whole.
594 * The default is 100. You can get the current range setting by
595 * sending the ZYZG_GETRANGE message to the control.
597 * The position (number of pieces out of the whole have been used) is
598 * set with the ZYZG_SETPOSITION message. It can be any integer from
599 * 0 to the current range setting of the control--it will be clipped
600 * if the position is out of bounds. The default position is 0. You
601 * can get the current position at any time with the ZYZG_GETPOSITION
604 * You can also set the range using a delta from the current range.
605 * This is done by sending the ZYZG_SETDELTAPOS message with wParam
606 * set to a _signed_ integer value within the range of the control.
608 * The font used for the percentage text can be set using the standard
609 * WM_SETFONT message. You can get the current font at any time with
610 * the WM_GETFONT message.
612 * The orientation can be left to right, right to left, bottom to top,
613 * or top to bottom. Whatever suits your needs. You set this by
614 * sending the ZYZG_ORIENTATION message to the control with one of
615 * the following values (default is ZYZG_ORIENT_LEFTTORIGHT):
617 * ZYZG_ORIENT_LEFTTORIGHT (0)
618 * ZYZG_ORIENT_RIGHTTOLEFT (1)
619 * ZYZG_ORIENT_BOTTOMTOTOP (2)
620 * ZYZG_ORIENT_TOPTOBOTTOM (3)
623 * 3/12/91 cjp put in this comment
624 * 6/19/92 cjp touched it a bit
629 // (C) Copyright Microsoft Corp. 1992. All rights reserved.
631 // You have a royalty-free right to use, modify, reproduce and
632 // distribute the Sample Files (and/or any modified version) in
633 // any way you find useful, provided that you agree that
634 // Microsoft has no warranty obligations or liability for any
635 // Sample Application Files which are modified.
639 /* get the includes we need */
640 #if !defined(__GNUWIN32__) && !defined(__SALFORDC__)
646 // #include "zyz3d.h"
647 // #include "zyzgauge.h"
650 /* static global variables */
651 static wxChar gszzYzGaugeClass
[] = wxT("zYzGauge");
654 /* window word position definitions */
655 #define ZYZG_WW_PZYZGAUGE 0
656 /* #define ZYZG_WW_EXTRABYTES 2 */
657 #define ZYZG_WW_EXTRABYTES 4
660 /* control block structure typedef */
661 typedef struct tZYZGAUGE
667 WORD wWidthBezelFace
;
672 } ZYZGAUGE
, *PZYZGAUGE
, FAR
*LPZYZGAUGE
;
675 /* some default values for the control */
676 #define ZYZG_DEF_RANGE 100
677 #define ZYZG_DEF_POSITION 0
678 #define ZYZG_DEF_ORIENTATION ZYZG_ORIENT_LEFTTORIGHT
679 #define ZYZG_DEF_WIDTH3D 2
680 #define ZYZG_DEF_BEZELFACE 2
684 /* the default settings for drawing colors--display dependent */
685 static DWORD rgbDefTextColor
;
686 static DWORD rgbDefBkColor
;
687 static BOOL fSupport3D
;
689 #if !defined(APIENTRY) // NT defines APIENTRY, 3.x not
690 #define APIENTRY FAR PASCAL
696 #define _EXPORT _export
697 typedef signed short int SHORT
;
700 /* internal function prototypes */
701 static void PASCAL
gaugePaint(HWND
, HDC
);
702 /* LRESULT FAR PASCAL */
703 LRESULT APIENTRY _EXPORT
gaugeWndProc(HWND
, UINT
, WPARAM
, LPARAM
);
707 /** BOOL FAR PASCAL gaugeInit(HINSTANCE hInstance)
710 * Registers the window class for the zYzGauge control. Performs
711 * other initialization for the zYzGauge text control. This must
712 * be done before the zYzGauge control is used--or it will fail
713 * and your dialog box will not open!
716 * HINSTANCE hInstance : Instance handle to register class with.
719 * The return value is TRUE if the zYzGauge class was successfully
720 * registered. It is FALSE if the initialization fails.
726 //#pragma alloc_text(init, gaugeInit)
728 BOOL FAR PASCAL
gaugeInit(HINSTANCE hInstance
)
730 static BOOL fRegistered
= FALSE
;
734 /* assume already registered if not first instance */
738 /* fill in the class structure for the zyzgauge control */
739 wc
.hCursor
= LoadCursor(NULL
, IDC_ARROW
);
741 wc
.lpszMenuName
= NULL
;
742 wc
.lpszClassName
= gszzYzGaugeClass
;
743 wc
.hbrBackground
= (HBRUSH
)(COLOR_WINDOW
+ 1);
744 wc
.hInstance
= hInstance
;
747 wc
.style
= CS_GLOBALCLASS
| CS_HREDRAW
| CS_VREDRAW
;
749 wc
.style
= CS_HREDRAW
| CS_VREDRAW
;
752 wc
.lpfnWndProc
= gaugeWndProc
;
754 wc
.cbWndExtra
= ZYZG_WW_EXTRABYTES
;
756 /* attempt to register it--return FALSE if fail */
757 if (!RegisterClass(&wc
))
760 /* Get a DC to determine whether device is mono or not, and set
761 * default foreground/background colors as appropriate.
763 hdc
= CreateIC(wxT("DISPLAY"), NULL
, NULL
, 0L) ;
766 /* check for mono-display */
767 if ((GetDeviceCaps(hdc
, BITSPIXEL
) == 1) &&
768 (GetDeviceCaps(hdc
, PLANES
) == 1))
770 /* using a mono DC--white foreground, black background */
771 rgbDefTextColor
= RGB(255, 255, 255);
772 rgbDefBkColor
= RGB(0, 0, 0);
775 /* good! we have color: blue foreground, white background */
778 rgbDefTextColor
= RGB(0, 0, 255);
779 rgbDefBkColor
= RGB(255, 255, 255);
782 /* need at _least_ 8 for two shades of gray (>=VGA) */
783 fSupport3D
= (GetDeviceCaps(hdc
, NUMCOLORS
) >= 8) ? TRUE
: FALSE
;
785 /* get rid of the DC (IC) */
789 /* uh-oh... can't get DC (IC)... fail */
792 /* unregister the class */
793 UnregisterClass(gszzYzGaugeClass
, hInstance
);
798 return (fRegistered
= TRUE
);
802 /** static void PASCAL gaugePaint(HWND hwnd, HDC hdc)
805 * This function is responsible for painting the zYzGauge control.
808 * HWND hwnd : The window handle for the gauge.
810 * HDC hdc : The DC for the gauge's window.
813 * The control will have been painted.
819 static void PASCAL
gaugePaint(HWND hwnd
, HDC hdc
)
828 WORD dx
, dy
, wGomerX
, wGomerY
;
829 /* Win32s has no GetTextExtent(); let's try GetTextExtentPoint() instead,
830 * which needs a SIZE* parameter */
831 #if defined(__WIN32__)
835 /* get pointer to the control's control block */
836 // pgauge = (PZYZGAUGE)GetWindowWord(hwnd, ZYZG_WW_PZYZGAUGE);
837 pgauge
= (PZYZGAUGE
)GetWindowLong(hwnd
, ZYZG_WW_PZYZGAUGE
);
839 /* set the colors into for the gauge into the control */
840 SetTextColor(hdc
, pgauge
->rgbTextColor
);
841 SetBkColor(hdc
, pgauge
->rgbBkColor
);
843 /* draw black rectangle for gauge */
844 GetClientRect(hwnd
, &rc1
);
846 /* draw a black border on the _outside_ */
847 FrameRect(hdc
, &rc1
, (HBRUSH
) GetStockObject(BLACK_BRUSH
));
849 /* we want to draw _just inside_ the black border */
850 InflateRect(&rc1
, -1, -1);
852 /* one line thick so far... */
853 // Offset = (WORD) 1;
855 /* for 3D stuff, we need to have at least two shades of gray */
856 if ((GetWindowLong(hwnd
, GWL_STYLE
) & ZYZGS_3D
) && fSupport3D
)
858 Draw3DRect(hdc
, &rc1
, pgauge
->wWidth3D
, DRAW3D_OUT
);
859 InflateRect(&rc1
, ~(pgauge
->wWidth3D
), ~(pgauge
->wWidth3D
));
861 Draw3DFaceFrame(hdc
, &rc1
, pgauge
->wWidthBezelFace
);
862 InflateRect(&rc1
, ~(pgauge
->wWidthBezelFace
), ~(pgauge
->wWidthBezelFace
));
864 Draw3DRect(hdc
, &rc1
, pgauge
->wWidth3D
, DRAW3D_IN
);
865 InflateRect(&rc1
, ~(pgauge
->wWidth3D
), ~(pgauge
->wWidth3D
));
867 /* draw a black border on the _inside_ */
868 FrameRect(hdc
, &rc1
, (HBRUSH
) GetStockObject(BLACK_BRUSH
));
870 /* we want to draw _just inside_ the black border */
871 InflateRect(&rc1
, -1, -1);
873 /* add all the other pixels into the border width */
874 Offset
+= (2 * pgauge
->wWidth3D
) + pgauge
->wWidthBezelFace
+ 1;
877 /* dup--one rc for 'how much filled', one rc for 'how much empty' */
880 /* get the range--make sure it's a valid range */
881 if ((iRange
= pgauge
->wRange
) <= 0)
884 /* get the position--greater than 100% would be bad */
885 if ((iPos
= pgauge
->wPosition
) > iRange
)
888 /* compute the actual size of the gauge */
889 dx
= rc1
.right
- rc1
.left
;
890 dy
= rc1
.bottom
- rc1
.top
;
891 wGomerX
= (WORD
)((DWORD
)iPos
* dx
/ iRange
);
892 wGomerY
= (WORD
)((DWORD
)iPos
* dy
/ iRange
);
894 /* get the orientation and munge rects accordingly */
895 switch (pgauge
->wOrientation
)
897 case ZYZG_ORIENT_RIGHTTOLEFT
:
898 rc1
.left
= rc2
.right
= rc1
.right
- wGomerX
;
901 case ZYZG_ORIENT_BOTTOMTOTOP
:
902 rc1
.top
= rc2
.bottom
= rc1
.bottom
- wGomerY
;
905 case ZYZG_ORIENT_TOPTOBOTTOM
:
906 rc1
.bottom
= rc2
.top
+= wGomerY
;
910 rc1
.right
= rc2
.left
+= wGomerX
;
914 /* select the correct font */
915 hFont
= (HFONT
) SelectObject(hdc
, pgauge
->hFont
);
917 /* build up a string to blit out--ie the meaning of life: "42%" */
918 wsprintf(ach
, wxT("%3d%%"), (WORD
)((DWORD
)iPos
* 100 / iRange
));
919 /* Win32s has no GetTextExtent(); let's try GetTextExtentPoint() instead */
920 #if defined(__WIN32__)
921 GetTextExtentPoint(hdc
, ach
, wGomerX
= lstrlen(ach
), &size
);
924 dwExtent
= GetTextExtent(hdc
, ach
, wGomerX
= lstrlen(ach
));
928 /* Draw the finished (ie the percent done) side of box. If
929 * ZYZG_WW_POSITION is 42, (in range of 0 to 100) this ExtTextOut
930 * draws the meaning of life (42%) bar.
932 ExtTextOut(hdc
, (dx
- LOWORD(dwExtent
)) / 2 + Offset
,
933 (dy
- HIWORD(dwExtent
)) / 2 + Offset
,
934 ETO_OPAQUE
| ETO_CLIPPED
, &rc2
, ach
, wGomerX
, NULL
);
936 /* Reverse fore and back colors for drawing the undone (ie the non-
937 * finished) side of the box.
939 SetBkColor(hdc
, pgauge
->rgbTextColor
);
940 SetTextColor(hdc
, pgauge
->rgbBkColor
);
942 ExtTextOut(hdc
, (dx
- LOWORD(dwExtent
)) / 2 + Offset
,
943 (dy
- HIWORD(dwExtent
)) / 2 + Offset
,
944 ETO_OPAQUE
| ETO_CLIPPED
, &rc1
, ach
, wGomerX
, NULL
);
946 /* unselect the font */
947 SelectObject(hdc
, hFont
);
951 /** LRESULT FAR PASCAL gaugeWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
954 * This is the control's window procedure. Its purpose is to handle
955 * special messages for this custom control.
957 * The special control messages for the gauge control are:
959 * ZYZG_SETRANGE : Sets the range of the gauge. In other
960 * words, the number of parts that make a
963 * ZYZG_GETRANGE : Returns the current range of the gauge.
965 * ZYZG_SETORIENTATION : Sets the orientation of the gauge. This
966 * can be one of the ZYZG_ORIENT_?? msgs.
968 * ZYZG_GETORIENTATION : Gets the current orientation of the
971 * ZYZG_SETPOSITION : Sets the current position of the gauge.
972 * In other words, how many pieces of the
973 * whole have been used.
975 * ZYZG_GETPOSITION : Gets the current position of the gauge.
977 * ZYZG_SETDELTAPOS : Sets the position of the gauge +/- the
980 * ZYZG_SETFGCOLOR : Sets the foreground (percent done) color.
982 * ZYZG_GETFGCOLOR : Gets the foreground (percent done) color.
984 * ZYZG_SETBKCOLOR : Sets the background (percent not done)
987 * ZYZG_GETBKCOLOR : Gets the background (percent not done)
990 * WM_SETFONT : Sets the font to use for the percentage
993 * WM_GETFONT : Gets the current font in use by the
1000 /* LRESULT FAR PASCAL */
1002 LRESULT APIENTRY _EXPORT
gaugeWndProc(HWND hwnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
1009 // pgauge = (PZYZGAUGE)GetWindowWord(hwnd, ZYZG_WW_PZYZGAUGE);
1010 pgauge
= (PZYZGAUGE
)GetWindowLong(hwnd
, ZYZG_WW_PZYZGAUGE
);
1012 /* break to get DefWindowProc() */
1016 /* need to allocate a control block */
1017 // pgauge = (PZYZGAUGE)LocalAlloc(LPTR, sizeof(ZYZGAUGE));
1018 pgauge
= (PZYZGAUGE
)malloc(sizeof(ZYZGAUGE
));
1022 /* hang on to this control block */
1023 // SetWindowWord(hwnd, ZYZG_WW_PZYZGAUGE, (WORD)pgauge);
1024 SetWindowLong(hwnd
, ZYZG_WW_PZYZGAUGE
, (LONG
)pgauge
);
1026 /* fill control block with defaults */
1027 pgauge
->wRange
= ZYZG_DEF_RANGE
;
1028 pgauge
->wPosition
= ZYZG_DEF_POSITION
;
1029 pgauge
->wOrientation
= ZYZG_DEF_ORIENTATION
;
1030 pgauge
->wWidth3D
= ZYZG_DEF_WIDTH3D
;
1031 pgauge
->wWidthBezelFace
= ZYZG_DEF_BEZELFACE
;
1032 pgauge
->rgbTextColor
= rgbDefTextColor
;
1033 pgauge
->rgbBkColor
= rgbDefBkColor
;
1035 /* use system font */
1036 SendMessage(hwnd
, WM_SETFONT
, (WPARAM
)NULL
, 0L);
1038 /* go to DefWindowProc() to finish the job */
1042 /* get rid of the control's memory */
1044 // LocalFree((HANDLE)pgauge);
1048 case ZYZG_GETPOSITION
:
1049 return (pgauge
->wPosition
);
1052 return (pgauge
->wRange
);
1054 case ZYZG_GETORIENTATION
:
1055 return (pgauge
->wOrientation
);
1057 case ZYZG_GETWIDTH3D
:
1058 return (pgauge
->wWidth3D
);
1060 case ZYZG_GETBEZELFACE
:
1061 return (pgauge
->wWidthBezelFace
);
1063 case ZYZG_GETBKCOLOR
:
1064 return (pgauge
->rgbTextColor
);
1066 case ZYZG_GETFGCOLOR
:
1067 return (pgauge
->rgbBkColor
);
1069 case ZYZG_SETBKCOLOR
:
1070 pgauge
->rgbBkColor
= lParam
;
1073 case ZYZG_SETFGCOLOR
:
1074 pgauge
->rgbTextColor
= lParam
;
1078 case ZYZG_SETPOSITION
:
1079 pgauge
->wPosition
= wParam
;
1082 GetClientRect(hwnd
, &rc
);
1083 if ((GetWindowLong(hwnd
, GWL_STYLE
) & ZYZGS_3D
) && fSupport3D
)
1085 wParam
= (2 * pgauge
->wWidth3D
) +
1086 pgauge
->wWidthBezelFace
+ 2;
1092 InflateRect(&rc
, ~(wParam
), ~(wParam
));
1093 InvalidateRect(hwnd
, &rc
, FALSE
);
1098 pgauge
->wRange
= wParam
;
1099 goto zyzgForceRepaint
;
1101 case ZYZG_SETORIENTATION
:
1102 pgauge
->wOrientation
= wParam
;
1103 goto zyzgForceRepaint
;
1105 case ZYZG_SETWIDTH3D
:
1106 pgauge
->wWidth3D
= wParam
;
1109 InvalidateRect(hwnd
, NULL
, FALSE
);
1113 case ZYZG_SETBEZELFACE
:
1114 pgauge
->wWidthBezelFace
= wParam
;
1115 goto zyzgForceRepaint3D
;
1117 case ZYZG_SETDELTAPOS
:
1118 /* Watcom doesn't like the following line so removing typecasts */
1119 /* (int)pgauge->wPosition += (int)wParam; */
1120 pgauge
->wPosition
+= wParam
;
1121 goto zyzgForceRepaint
;
1124 BeginPaint(hwnd
, &ps
);
1125 gaugePaint(hwnd
, ps
.hdc
);
1126 EndPaint(hwnd
, &ps
);
1130 hFont
= pgauge
->hFont
;
1132 /* if system font, then return NULL handle */
1133 return (long)((hFont
== GetStockObject(SYSTEM_FONT
)) ? NULL
: hFont
);
1136 /* if NULL hFont, use system font */
1137 hFont
= (HFONT
)wParam
;
1139 hFont
= (HFONT
) GetStockObject(SYSTEM_FONT
);
1141 pgauge
->hFont
= hFont
;
1143 /* redraw if indicated in message */
1146 InvalidateRect(hwnd
, NULL
, TRUE
);
1152 /* let the dialog mangler take care of this message */
1153 return (DefWindowProc(hwnd
, uMsg
, wParam
, lParam
));
1154 } /* gaugeWndProc() */
1157 /** EOF: zyzgauge.c **/
1159 #endif // wxUSE_GAUGE