]>
git.saurik.com Git - wxWidgets.git/blob - src/msw/gauge.cpp
1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxGauge 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/private.h"
32 /* gas gauge graph control messages--class "zYzGauge" */
33 #define ZYZG_SETRANGE (WM_USER + 0)
34 #define ZYZG_GETRANGE (WM_USER + 1)
35 #define ZYZG_SETPOSITION (WM_USER + 2)
36 #define ZYZG_GETPOSITION (WM_USER + 3)
37 #define ZYZG_SETORIENTATION (WM_USER + 4)
38 #define ZYZG_GETORIENTATION (WM_USER + 5)
39 #define ZYZG_SETFGCOLOR (WM_USER + 6)
40 #define ZYZG_GETFGCOLOR (WM_USER + 7)
41 #define ZYZG_SETBKCOLOR (WM_USER + 8)
42 #define ZYZG_GETBKCOLOR (WM_USER + 9)
43 #define ZYZG_SETWIDTH3D (WM_USER + 10)
44 #define ZYZG_GETWIDTH3D (WM_USER + 11)
45 #define ZYZG_SETBEZELFACE (WM_USER + 12)
46 #define ZYZG_GETBEZELFACE (WM_USER + 13)
47 #define ZYZG_SETDELTAPOS (WM_USER + 14)
50 /* orientations for ZYZG_WW_ORIENTATION */
51 #define ZYZG_ORIENT_LEFTTORIGHT 0
52 #define ZYZG_ORIENT_RIGHTTOLEFT 1
53 #define ZYZG_ORIENT_BOTTOMTOTOP 2
54 #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 #define USE_PROGRESS_BAR 1
65 #if defined(__WIN95__) && !defined(__GNUWIN32__)
69 #if !USE_SHARED_LIBRARY
70 IMPLEMENT_DYNAMIC_CLASS(wxGauge
, wxControl
)
73 bool wxGauge::Create(wxWindow
*parent
, const wxWindowID id
,
78 const wxValidator
& validator
,
81 static bool wxGaugeInitialised
= FALSE
;
83 if ( !wxGaugeInitialised
)
85 if (!gaugeInit((HWND
) wxGetInstance()))
86 wxFatalError("Cannot initalize Gauge library");
87 wxGaugeInitialised
= TRUE
;
91 SetValidator(validator
);
93 if (parent
) parent
->AddChild(this);
96 SetBackgroundColour(parent
->GetDefaultBackgroundColour()) ;
97 SetForegroundColour(parent
->GetDefaultForegroundColour()) ;
99 m_useProgressBar
= FALSE
;
100 m_windowStyle
= style
;
103 m_windowId
= (int)NewControlId();
112 // Use the Win95 progress bar if possible, but not if
113 // we request a vertical gauge.
114 #if defined(__WIN95__) && USE_PROGRESS_BAR
115 if ((m_windowStyle
& wxGA_PROGRESSBAR
) && ((m_windowStyle
& wxGA_HORIZONTAL
) == wxGA_HORIZONTAL
))
116 m_useProgressBar
= TRUE
;
119 if (m_useProgressBar
)
121 #if defined(__WIN95__) && USE_PROGRESS_BAR
122 long msFlags
= WS_CHILD
| WS_VISIBLE
| WS_TABSTOP
;
125 CreateWindowEx(MakeExtendedStyle(m_windowStyle
), PROGRESS_CLASS
, NULL
, msFlags
,
126 0, 0, 0, 0, (HWND
) parent
->GetHWND(), (HMENU
)m_windowId
,
127 wxGetInstance(), NULL
);
129 m_hWnd
= (WXHWND
)wx_button
;
131 // Subclass again for purposes of dialog editing mode
132 SubclassWin((WXHWND
) wx_button
);
134 SendMessage((HWND
) GetHWND(), PBM_SETRANGE
, 0, MAKELPARAM(0, range
));
139 long msFlags
= WS_CHILD
| WS_VISIBLE
| WS_TABSTOP
;
140 /* if (m_windowStyle & wxTHREED) */
144 CreateWindowEx(MakeExtendedStyle(m_windowStyle
), "zYzGauge", NULL
, msFlags
,
145 0, 0, 0, 0, (HWND
) parent
->GetHWND(), (HMENU
)m_windowId
,
146 wxGetInstance(), NULL
);
148 m_hWnd
= (WXHWND
)wx_button
;
150 // Subclass again for purposes of dialog editing mode
151 SubclassWin((WXHWND
)wx_button
);
155 if (m_windowStyle
& wxGA_HORIZONTAL
)
156 wOrient
= ZYZG_ORIENT_LEFTTORIGHT
;
158 wOrient
= ZYZG_ORIENT_BOTTOMTOTOP
;
160 SendMessage(wx_button
, ZYZG_SETORIENTATION
, wOrient
, 0);
161 SendMessage(wx_button
, ZYZG_SETRANGE
, range
, 0);
163 SendMessage((HWND
) GetHWND(), ZYZG_SETFGCOLOR
, 0, RGB(GetForegroundColour().Red(), GetForegroundColour().Green(), GetForegroundColour().Blue()));
164 SendMessage((HWND
) GetHWND(), ZYZG_SETBKCOLOR
, 0, RGB(GetBackgroundColour().Red(), GetBackgroundColour().Green(), GetBackgroundColour().Blue()));
167 SetFont(* parent
->GetFont());
173 SetSize(x
, y
, width
, height
);
175 ShowWindow((HWND
) GetHWND(), SW_SHOW
);
180 void wxGauge::SetSize(const int x
, const int y
, const int width
, const int height
, const int sizeFlags
)
182 int currentX
, currentY
;
183 GetPosition(¤tX
, ¤tY
);
189 if (x
== -1 || (sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
))
191 if (y
== -1 || (sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
))
194 float control_width
, control_height
, control_x
, control_y
;
196 // If we're prepared to use the existing size, then...
197 if (width
== -1 && height
== -1 && ((sizeFlags
& wxSIZE_AUTO
) != wxSIZE_AUTO
))
202 // Deal with default size (using -1 values)
204 w1
= DEFAULT_ITEM_WIDTH
;
207 h1
= DEFAULT_ITEM_HEIGHT
;
209 control_x
= (float)x1
;
210 control_y
= (float)y1
;
211 control_width
= (float)w1
;
212 control_height
= (float)h1
;
214 MoveWindow((HWND
) GetHWND(), (int)control_x
, (int)control_y
, (int)control_width
, (int)control_height
, TRUE
);
216 #if WXWIN_COMPATIBILITY
217 GetEventHandler()->OldOnSize(width
, height
);
219 wxSizeEvent
event(wxSize(width
, height
), m_windowId
);
220 event
.eventObject
= this;
221 GetEventHandler()->ProcessEvent(event
);
225 void wxGauge::SetShadowWidth(const int w
)
227 if (m_useProgressBar
)
231 SendMessage((HWND
) GetHWND(), ZYZG_SETWIDTH3D
, w
, 0);
234 void wxGauge::SetBezelFace(const int w
)
236 if (m_useProgressBar
)
240 SendMessage((HWND
) GetHWND(), ZYZG_SETBEZELFACE
, w
, 0);
243 void wxGauge::SetRange(const int r
)
247 #if defined(__WIN95__) && USE_PROGRESS_BAR
248 if (m_useProgressBar
)
249 SendMessage((HWND
) GetHWND(), PBM_SETRANGE
, 0, MAKELPARAM(0, r
));
252 SendMessage((HWND
) GetHWND(), ZYZG_SETRANGE
, r
, 0);
255 void wxGauge::SetValue(const int pos
)
259 #if defined(__WIN95__) && USE_PROGRESS_BAR
260 if (m_useProgressBar
)
261 SendMessage((HWND
) GetHWND(), PBM_SETPOS
, pos
, 0);
264 SendMessage((HWND
) GetHWND(), ZYZG_SETPOSITION
, pos
, 0);
267 int wxGauge::GetShadowWidth(void) const
269 if (m_useProgressBar
)
272 return (int) SendMessage((HWND
) GetHWND(), ZYZG_GETWIDTH3D
, 0, 0);
275 int wxGauge::GetBezelFace(void) const
277 if (m_useProgressBar
)
280 return (int) SendMessage((HWND
) GetHWND(), ZYZG_GETBEZELFACE
, 0, 0);
283 int wxGauge::GetRange(void) const
285 if (m_useProgressBar
)
288 return (int) SendMessage((HWND
) GetHWND(), ZYZG_GETRANGE
, 0, 0);
291 int wxGauge::GetValue(void) const
293 if (m_useProgressBar
)
296 return (int) SendMessage((HWND
) GetHWND(), ZYZG_GETPOSITION
, 0, 0);
299 void wxGauge::SetForegroundColour(const wxColour
& col
)
301 m_foregroundColour
= col
;
302 if (m_useProgressBar
)
306 SendMessage((HWND
) GetHWND(), ZYZG_SETFGCOLOR
, 0, RGB(col
.Red(), col
.Green(), col
.Blue()));
309 void wxGauge::SetBackgroundColour(const wxColour
& col
)
311 m_backgroundColour
= col
;
312 if (m_useProgressBar
)
316 SendMessage((HWND
) GetHWND(), ZYZG_SETBKCOLOR
, 0, RGB(col
.Red(), col
.Green(), col
.Blue()));
323 * This module contains functions for creating nifty 3D borders
324 * around controls like zYzGauge.
327 * 3/14/91 cjp put in this comment
328 * 6/19/92 cjp touched it a bit
333 // (C) Copyright Microsoft Corp. 1992. All rights reserved.
335 // You have a royalty-free right to use, modify, reproduce and
336 // distribute the Sample Files (and/or any modified version) in
337 // any way you find useful, provided that you agree that
338 // Microsoft has no warranty obligations or liability for any
339 // Sample Application Files which are modified.
343 /* get the includes we need */
346 /* misc. control flag defines */
347 #define DRAW3D_IN 0x0001
348 #define DRAW3D_OUT 0x0002
350 #define DRAW3D_TOPLINE 0x0004
351 #define DRAW3D_BOTTOMLINE 0x0008
352 #define DRAW3D_LEFTLINE 0x0010
353 #define DRAW3D_RIGHTLINE 0x0020
356 /* public function prototypes */
357 void FAR PASCAL
Draw3DFaceFrame(HDC
, LPRECT
, WORD
);
358 void FAR PASCAL
Draw3DRect(HDC
, LPRECT
, WORD
, WORD
);
359 void FAR PASCAL
Draw3DLine(HDC
, WORD
, WORD
, WORD
, WORD
, WORD
);
362 /** void FAR PASCAL Draw3DFaceFrame(HDC hdc, LPRECT rc, WORD wWidth)
365 * This function draws a flat frame with the current button-face
369 * HDC hdc : The DC to draw into.
371 * LPRECT rc : The containing rect for the new frame.
373 * WORD wWidth : The width of the frame to draw.
375 * RETURN (void FAR PASCAL):
376 * The frame will have been drawn into the DC.
382 void FAR PASCAL
Draw3DFaceFrame(HDC hdc
, LPRECT rc
, WORD wWidth
)
387 /* don't go through a bunch of work if we don't have to */
391 /* set up color to be button-face color--so it may not be gray */
392 rgbOld
= SetBkColor(hdc
, GetSysColor(COLOR_BTNFACE
));
394 /* perform CopyRect w/o bloody windows style overhead */
400 rc1
.bottom
= rc
->top
+ wWidth
;
401 rc1
.right
= rc
->right
;
404 ExtTextOut(hdc
, rc1
.left
, rc1
.top
, ETO_OPAQUE
, &rc1
, NULL
, 0, NULL
);
407 rc1
.left
= rc
->right
- wWidth
;
408 rc1
.bottom
= rc
->bottom
;
410 /* blast this part now */
411 ExtTextOut(hdc
, rc1
.left
, rc1
.top
, ETO_OPAQUE
, &rc1
, NULL
, 0, NULL
);
415 rc1
.right
= rc
->left
+ wWidth
;
417 /* and another part */
418 ExtTextOut(hdc
, rc1
.left
, rc1
.top
, ETO_OPAQUE
, &rc1
, NULL
, 0, NULL
);
421 rc1
.right
= rc
->right
;
422 rc1
.top
= rc
->bottom
- wWidth
;
425 ExtTextOut(hdc
, rc1
.left
, rc1
.top
, ETO_OPAQUE
, &rc1
, NULL
, 0, NULL
);
427 /* restore the old bk color */
428 SetBkColor(hdc
, rgbOld
);
429 } /* Draw3DFaceFrame() */
432 /** void FAR PASCAL Draw3DRect(HDC, LPRECT, WORD, WORD)
435 * Draws a 3D rectangle that is shaded. wFlags can be used to
436 * control how the rectangle looks.
439 * HDC hdc : Handle to the device context that will be
440 * used to display the rectangle.
442 * RECT rect : A rectangle describing the dimensions of
443 * the rectangle in device coordinates.
445 * WORD wShadowWidth : Width of the shadow in device coordinates.
447 * WORD wFlags : The following flags may be passed to describe
448 * the style of the rectangle:
450 * DRAW3D_IN : The shadow is drawn such that
451 * the box appears to be sunk in to the screen.
452 * This is default if 0 is passed.
454 * DRAW3D_OUT : The shadow is drawn such that
455 * the box appears to be sticking out of the
458 * RETURN (void FAR PASCAL):
459 * The 3D looking rectangle will have been drawn into the DC.
465 void FAR PASCAL
Draw3DRect(HDC hdc
, LPRECT lpRect
,
466 WORD wShadowWidth
, WORD wFlags
)
468 /* sanity check--don't work if you don't have to! */
469 if (!wShadowWidth
|| !RectVisible(hdc
, lpRect
))
472 /* draw the top line */
473 Draw3DLine(hdc
, lpRect
->left
, lpRect
->top
,
474 lpRect
->right
- lpRect
->left
,
475 wShadowWidth
, DRAW3D_TOPLINE
| wFlags
);
478 Draw3DLine(hdc
, lpRect
->right
, lpRect
->top
,
479 lpRect
->bottom
- lpRect
->top
,
480 wShadowWidth
, DRAW3D_RIGHTLINE
| wFlags
);
483 Draw3DLine(hdc
, lpRect
->left
, lpRect
->bottom
,
484 lpRect
->right
- lpRect
->left
,
485 wShadowWidth
, DRAW3D_BOTTOMLINE
| wFlags
);
488 Draw3DLine(hdc
, lpRect
->left
, lpRect
->top
,
489 lpRect
->bottom
- lpRect
->top
,
490 wShadowWidth
, DRAW3D_LEFTLINE
| wFlags
);
494 /** void FAR PASCAL Draw3DLine(HDC hdc, WORD x, WORD y, WORD nLen,
497 * Draws a 3D line that can be used to make a 3D box.
500 * HDC hdc : Handle to the device context that will be
501 * used to display the 3D line.
503 * WORD x, y : Coordinates of the beginning of the line.
504 * These coordinates are in device units and
505 * represent the _outside_ most point. Horiz-
506 * ontal lines are drawn from left to right and
507 * vertical lines are drawn from top to bottom.
509 * WORD wShadowWidth : Width of the shadow in device coordinates.
511 * WORD wFlags : The following flags may be passed to
512 * describe the style of the 3D line:
514 * DRAW3D_IN : The shadow is drawn such that
515 * the box appears to be sunk in to the screen.
516 * This is default if 0 is passed.
518 * DRAW3D_OUT : The shadow is drawn such that
519 * the box appears to be sticking out of the
522 * DRAW3D_TOPLINE, _BOTTOMLINE, _LEFTLINE, and
523 * _RIGHTLINE : Specifies that a "top",
524 * "Bottom", "Left", or"Right" line is to be
527 * RETURN (void FAR PASCAL):
528 * The line will have been drawn into the DC.
534 void FAR PASCAL
Draw3DLine(HDC hdc
, WORD x
, WORD y
, WORD nLen
,
535 WORD wShadowWidth
, WORD wFlags
)
540 POINT Point
[ 4 ]; /* define a polgon with 4 points */
542 /* if width is zero, don't do nothin'! */
546 /* define shape of polygon--origin is always the same */
550 /* To do this we'll simply draw a polygon with four sides, using
551 * the appropriate brush. I dare you to ask me why this isn't a
554 if (wFlags
& DRAW3D_TOPLINE
)
556 /* across to right */
557 Point
[1].x
= x
+ nLen
- (wShadowWidth
== 1 ? 1 : 0);
561 Point
[2].x
= x
+ nLen
- wShadowWidth
;
562 Point
[2].y
= y
+ wShadowWidth
;
564 /* accross to left */
565 Point
[3].x
= x
+ wShadowWidth
;
566 Point
[3].y
= y
+ wShadowWidth
;
568 /* select 'dark' brush if 'in'--'light' for 'out' */
569 fDark
= (wFlags
& DRAW3D_IN
) ? TRUE
: FALSE
;
572 /* possibly the bottom? */
573 else if (wFlags
& DRAW3D_BOTTOMLINE
)
575 /* across to right */
576 Point
[1].x
= x
+ nLen
;
580 Point
[2].x
= x
+ nLen
- wShadowWidth
;
581 Point
[2].y
= y
- wShadowWidth
;
583 /* accross to left */
584 Point
[3].x
= x
+ wShadowWidth
;
585 Point
[3].y
= y
- wShadowWidth
;
587 /* select 'light' brush if 'in' */
588 fDark
= (wFlags
& DRAW3D_IN
) ? FALSE
: TRUE
;
591 /* ok, it's gotta be left? */
592 else if (wFlags
& DRAW3D_LEFTLINE
)
596 Point
[1].y
= y
+ nLen
- (wShadowWidth
== 1 ? 1 : 0);
599 Point
[2].x
= x
+ wShadowWidth
;
600 Point
[2].y
= y
+ nLen
- wShadowWidth
;
603 Point
[3].x
= x
+ wShadowWidth
;
604 Point
[3].y
= y
+ wShadowWidth
;
606 /* select 'dark' brush if 'in'--'light' for 'out' */
607 fDark
= (wFlags
& DRAW3D_IN
) ? TRUE
: FALSE
;
610 /* well maybe it's for the right side? */
611 else if (wFlags
& DRAW3D_RIGHTLINE
)
615 Point
[1].y
= y
+ nLen
;
618 Point
[2].x
= x
- wShadowWidth
;
619 Point
[2].y
= y
+ nLen
- wShadowWidth
;
622 Point
[3].x
= x
- wShadowWidth
;
623 Point
[3].y
= y
+ wShadowWidth
;
625 /* select 'light' brush if 'in' */
626 fDark
= (wFlags
& DRAW3D_IN
) ? FALSE
: TRUE
;
632 /* select NULL_PEN for no borders */
633 hOldPen
= SelectObject(hdc
, GetStockObject(NULL_PEN
));
635 /* select the appropriate color for the fill */
637 hOldBrush
= SelectObject(hdc
, GetStockObject(GRAY_BRUSH
));
639 hOldBrush
= SelectObject(hdc
, GetStockObject(WHITE_BRUSH
));
641 /* finally, draw the dern thing */
642 Polygon(hdc
, (LPPOINT
)&Point
, 4);
644 /* restore what we killed */
645 SelectObject(hdc
, hOldBrush
);
646 SelectObject(hdc
, hOldPen
);
654 * Yet another 'Gas Gauge Custom Control.' This control gives you
655 * a 'progress bar' class (named zYzGauge) for use in your applications.
656 * You can set the range, position, font, color, orientation, and 3d
657 * effect of the gauge by sending messages to the control.
659 * Before you can use this control, you MUST first export the window
660 * procedure for the control (or define it with the _export keyword):
662 * EXPORTS gaugeWndProc
664 * You then need initialize the class before you use it:
666 * if (!gaugeInit(hInstance))
667 * die a horrible death
671 * The colors used by the control default to black and white if you
672 * are running on a mono-display. They default to blue and white
673 * if you are on a color display. You enable the 3D effect by setting
674 * the ZYZGS_3D style flag in the styles field of the control (like
675 * any other control).
677 * To select your own colors, you can send the ZYZG_SETFGCOLOR and
678 * ZYZG_SETBKCOLOR messages to set the foreground (percent done) and
679 * background (percent not done) colors. The lParam is the RGB()
680 * value--wParam is ignored.
682 * In all of the following ZYZG_??? messages, the arguments are
683 * WORDS. If you are setting parameters, the value is sent as
684 * the wParam (lParam is ignored). If you are getting parameters,
685 * the value is returned as a LONG and should be cast to a *signed*
688 * To set the depth of the 3D effect (if enabled), you can send the
689 * ZYZG_SETBEZELFACE and ZYZG_SETWIDTH3D messages. The bezel face
690 * is the flat top on the 3D border--its color will be that of the
691 * button-face. The 3D width is the width of the bezel itself; inside
692 * and outside. The light color is white, the dark color is gray.
693 * Both widths *can* be zero--both default to 2 which looks to me.
695 * The range of the control can be set by sending the ZYZG_SETRANGE
696 * message to the control. It can be any integer from 1 to 32767.
697 * What this specifies is the number of pieces that create a whole.
698 * The default is 100. You can get the current range setting by
699 * sending the ZYZG_GETRANGE message to the control.
701 * The position (number of pieces out of the whole have been used) is
702 * set with the ZYZG_SETPOSITION message. It can be any integer from
703 * 0 to the current range setting of the control--it will be clipped
704 * if the position is out of bounds. The default position is 0. You
705 * can get the current position at any time with the ZYZG_GETPOSITION
708 * You can also set the range using a delta from the current range.
709 * This is done by sending the ZYZG_SETDELTAPOS message with wParam
710 * set to a _signed_ integer value within the range of the control.
712 * The font used for the percentage text can be set using the standard
713 * WM_SETFONT message. You can get the current font at any time with
714 * the WM_GETFONT message.
716 * The orientation can be left to right, right to left, bottom to top,
717 * or top to bottom. Whatever suits your needs. You set this by
718 * sending the ZYZG_ORIENTATION message to the control with one of
719 * the following values (default is ZYZG_ORIENT_LEFTTORIGHT):
721 * ZYZG_ORIENT_LEFTTORIGHT (0)
722 * ZYZG_ORIENT_RIGHTTOLEFT (1)
723 * ZYZG_ORIENT_BOTTOMTOTOP (2)
724 * ZYZG_ORIENT_TOPTOBOTTOM (3)
727 * 3/12/91 cjp put in this comment
728 * 6/19/92 cjp touched it a bit
733 // (C) Copyright Microsoft Corp. 1992. All rights reserved.
735 // You have a royalty-free right to use, modify, reproduce and
736 // distribute the Sample Files (and/or any modified version) in
737 // any way you find useful, provided that you agree that
738 // Microsoft has no warranty obligations or liability for any
739 // Sample Application Files which are modified.
743 /* get the includes we need */
750 // #include "zyz3d.h"
751 // #include "zyzgauge.h"
754 /* static global variables */
755 static char gszzYzGaugeClass
[] = "zYzGauge";
758 /* window word position definitions */
759 #define ZYZG_WW_PZYZGAUGE 0
760 /* #define ZYZG_WW_EXTRABYTES 2 */
761 #define ZYZG_WW_EXTRABYTES 4
764 /* control block structure typedef */
765 typedef struct tZYZGAUGE
771 WORD wWidthBezelFace
;
776 } ZYZGAUGE
, *PZYZGAUGE
, FAR
*LPZYZGAUGE
;
779 /* some default values for the control */
780 #define ZYZG_DEF_RANGE 100
781 #define ZYZG_DEF_POSITION 0
782 #define ZYZG_DEF_ORIENTATION ZYZG_ORIENT_LEFTTORIGHT
783 #define ZYZG_DEF_WIDTH3D 2
784 #define ZYZG_DEF_BEZELFACE 2
788 /* the default settings for drawing colors--display dependent */
789 static DWORD rgbDefTextColor
;
790 static DWORD rgbDefBkColor
;
791 static BOOL fSupport3D
;
793 #if !defined(APIENTRY) // NT defines APIENTRY, 3.x not
794 #define APIENTRY FAR PASCAL
800 #define _EXPORT _export
801 typedef signed short int SHORT
;
804 /* internal function prototypes */
805 static void PASCAL
gaugePaint(HWND
, HDC
);
806 /* LRESULT FAR PASCAL */
807 LRESULT APIENTRY _EXPORT
gaugeWndProc(HWND
, UINT
, WPARAM
, LPARAM
);
811 /** BOOL FAR PASCAL gaugeInit(HINSTANCE hInstance)
814 * Registers the window class for the zYzGauge control. Performs
815 * other initialization for the zYzGauge text control. This must
816 * be done before the zYzGauge control is used--or it will fail
817 * and your dialog box will not open!
820 * HINSTANCE hInstance : Instance handle to register class with.
823 * The return value is TRUE if the zYzGauge class was successfully
824 * registered. It is FALSE if the initialization fails.
830 //#pragma alloc_text(init, gaugeInit)
832 BOOL FAR PASCAL
gaugeInit(HINSTANCE hInstance
)
834 static BOOL fRegistered
= FALSE
;
838 /* assume already registered if not first instance */
842 /* fill in the class structure for the zyzgauge control */
843 wc
.hCursor
= LoadCursor(NULL
, IDC_ARROW
);
845 wc
.lpszMenuName
= NULL
;
846 wc
.lpszClassName
= gszzYzGaugeClass
;
847 wc
.hbrBackground
= (HBRUSH
)(COLOR_WINDOW
+ 1);
848 wc
.hInstance
= hInstance
;
851 wc
.style
= CS_GLOBALCLASS
| CS_HREDRAW
| CS_VREDRAW
;
853 wc
.style
= CS_HREDRAW
| CS_VREDRAW
;
856 wc
.lpfnWndProc
= gaugeWndProc
;
858 wc
.cbWndExtra
= ZYZG_WW_EXTRABYTES
;
860 /* attempt to register it--return FALSE if fail */
861 if (!RegisterClass(&wc
))
864 /* Get a DC to determine whether device is mono or not, and set
865 * default foreground/background colors as appropriate.
867 if ((hdc
= CreateIC("DISPLAY", NULL
, NULL
, 0L)))
869 /* check for mono-display */
870 if ((GetDeviceCaps(hdc
, BITSPIXEL
) == 1) &&
871 (GetDeviceCaps(hdc
, PLANES
) == 1))
873 /* using a mono DC--white foreground, black background */
874 rgbDefTextColor
= RGB(255, 255, 255);
875 rgbDefBkColor
= RGB(0, 0, 0);
878 /* good! we have color: blue foreground, white background */
881 rgbDefTextColor
= RGB(0, 0, 255);
882 rgbDefBkColor
= RGB(255, 255, 255);
885 /* need at _least_ 8 for two shades of gray (>=VGA) */
886 fSupport3D
= (GetDeviceCaps(hdc
, NUMCOLORS
) >= 8) ? TRUE
: FALSE
;
888 /* get rid of the DC (IC) */
892 /* uh-oh... can't get DC (IC)... fail */
895 /* unregister the class */
896 UnregisterClass(gszzYzGaugeClass
, hInstance
);
901 return (fRegistered
= TRUE
);
905 /** static void PASCAL gaugePaint(HWND hwnd, HDC hdc)
908 * This function is responsible for painting the zYzGauge control.
911 * HWND hwnd : The window handle for the gauge.
913 * HDC hdc : The DC for the gauge's window.
916 * The control will have been painted.
922 static void PASCAL
gaugePaint(HWND hwnd
, HDC hdc
)
931 WORD dx
, dy
, wGomerX
, wGomerY
;
932 /* Win32s has no GetTextExtent(); let's try GetTextExtentPoint() instead,
933 * which needs a SIZE* parameter */
934 #if defined(__WIN32__)
938 /* get pointer to the control's control block */
939 // pgauge = (PZYZGAUGE)GetWindowWord(hwnd, ZYZG_WW_PZYZGAUGE);
940 pgauge
= (PZYZGAUGE
)GetWindowLong(hwnd
, ZYZG_WW_PZYZGAUGE
);
942 /* set the colors into for the gauge into the control */
943 SetTextColor(hdc
, pgauge
->rgbTextColor
);
944 SetBkColor(hdc
, pgauge
->rgbBkColor
);
946 /* draw black rectangle for gauge */
947 GetClientRect(hwnd
, &rc1
);
949 /* draw a black border on the _outside_ */
950 FrameRect(hdc
, &rc1
, GetStockObject(BLACK_BRUSH
));
952 /* we want to draw _just inside_ the black border */
953 InflateRect(&rc1
, -1, -1);
955 /* one line thick so far... */
956 // Offset = (WORD) 1;
958 /* for 3D stuff, we need to have at least two shades of gray */
959 if ((GetWindowLong(hwnd
, GWL_STYLE
) & ZYZGS_3D
) && fSupport3D
)
961 Draw3DRect(hdc
, &rc1
, pgauge
->wWidth3D
, DRAW3D_OUT
);
962 InflateRect(&rc1
, ~(pgauge
->wWidth3D
), ~(pgauge
->wWidth3D
));
964 Draw3DFaceFrame(hdc
, &rc1
, pgauge
->wWidthBezelFace
);
965 InflateRect(&rc1
, ~(pgauge
->wWidthBezelFace
), ~(pgauge
->wWidthBezelFace
));
967 Draw3DRect(hdc
, &rc1
, pgauge
->wWidth3D
, DRAW3D_IN
);
968 InflateRect(&rc1
, ~(pgauge
->wWidth3D
), ~(pgauge
->wWidth3D
));
970 /* draw a black border on the _inside_ */
971 FrameRect(hdc
, &rc1
, GetStockObject(BLACK_BRUSH
));
973 /* we want to draw _just inside_ the black border */
974 InflateRect(&rc1
, -1, -1);
976 /* add all the other pixels into the border width */
977 Offset
+= (2 * pgauge
->wWidth3D
) + pgauge
->wWidthBezelFace
+ 1;
980 /* dup--one rc for 'how much filled', one rc for 'how much empty' */
983 /* get the range--make sure it's a valid range */
984 if ((iRange
= pgauge
->wRange
) <= 0)
987 /* get the position--greater than 100% would be bad */
988 if ((iPos
= pgauge
->wPosition
) > iRange
)
991 /* compute the actual size of the gauge */
992 dx
= rc1
.right
- rc1
.left
;
993 dy
= rc1
.bottom
- rc1
.top
;
994 wGomerX
= (WORD
)((DWORD
)iPos
* dx
/ iRange
);
995 wGomerY
= (WORD
)((DWORD
)iPos
* dy
/ iRange
);
997 /* get the orientation and munge rects accordingly */
998 switch (pgauge
->wOrientation
)
1000 case ZYZG_ORIENT_RIGHTTOLEFT
:
1001 rc1
.left
= rc2
.right
= rc1
.right
- wGomerX
;
1004 case ZYZG_ORIENT_BOTTOMTOTOP
:
1005 rc1
.top
= rc2
.bottom
= rc1
.bottom
- wGomerY
;
1008 case ZYZG_ORIENT_TOPTOBOTTOM
:
1009 rc1
.bottom
= rc2
.top
+= wGomerY
;
1013 rc1
.right
= rc2
.left
+= wGomerX
;
1017 /* select the correct font */
1018 hFont
= SelectObject(hdc
, pgauge
->hFont
);
1020 /* build up a string to blit out--ie the meaning of life: "42%" */
1021 wsprintf(ach
, "%3d%%", (WORD
)((DWORD
)iPos
* 100 / iRange
));
1022 /* Win32s has no GetTextExtent(); let's try GetTextExtentPoint() instead */
1023 #if defined(__WIN32__)
1024 GetTextExtentPoint(hdc
, ach
, wGomerX
= lstrlen(ach
), &size
);
1027 dwExtent
= GetTextExtent(hdc
, ach
, wGomerX
= lstrlen(ach
));
1031 /* Draw the finished (ie the percent done) side of box. If
1032 * ZYZG_WW_POSITION is 42, (in range of 0 to 100) this ExtTextOut
1033 * draws the meaning of life (42%) bar.
1035 ExtTextOut(hdc
, (dx
- LOWORD(dwExtent
)) / 2 + Offset
,
1036 (dy
- HIWORD(dwExtent
)) / 2 + Offset
,
1037 ETO_OPAQUE
| ETO_CLIPPED
, &rc2
, ach
, wGomerX
, NULL
);
1039 /* Reverse fore and back colors for drawing the undone (ie the non-
1040 * finished) side of the box.
1042 SetBkColor(hdc
, pgauge
->rgbTextColor
);
1043 SetTextColor(hdc
, pgauge
->rgbBkColor
);
1045 ExtTextOut(hdc
, (dx
- LOWORD(dwExtent
)) / 2 + Offset
,
1046 (dy
- HIWORD(dwExtent
)) / 2 + Offset
,
1047 ETO_OPAQUE
| ETO_CLIPPED
, &rc1
, ach
, wGomerX
, NULL
);
1049 /* unselect the font */
1050 SelectObject(hdc
, hFont
);
1051 } /* gaugePaint() */
1054 /** LRESULT FAR PASCAL gaugeWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
1057 * This is the control's window procedure. Its purpose is to handle
1058 * special messages for this custom control.
1060 * The special control messages for the gauge control are:
1062 * ZYZG_SETRANGE : Sets the range of the gauge. In other
1063 * words, the number of parts that make a
1066 * ZYZG_GETRANGE : Returns the current range of the gauge.
1068 * ZYZG_SETORIENTATION : Sets the orientation of the gauge. This
1069 * can be one of the ZYZG_ORIENT_?? msgs.
1071 * ZYZG_GETORIENTATION : Gets the current orientation of the
1074 * ZYZG_SETPOSITION : Sets the current position of the gauge.
1075 * In other words, how many pieces of the
1076 * whole have been used.
1078 * ZYZG_GETPOSITION : Gets the current position of the gauge.
1080 * ZYZG_SETDELTAPOS : Sets the position of the gauge +/- the
1083 * ZYZG_SETFGCOLOR : Sets the foreground (percent done) color.
1085 * ZYZG_GETFGCOLOR : Gets the foreground (percent done) color.
1087 * ZYZG_SETBKCOLOR : Sets the background (percent not done)
1090 * ZYZG_GETBKCOLOR : Gets the background (percent not done)
1093 * WM_SETFONT : Sets the font to use for the percentage
1094 * text of the gauge.
1096 * WM_GETFONT : Gets the current font in use by the
1103 /* LRESULT FAR PASCAL */
1105 LRESULT APIENTRY _EXPORT
gaugeWndProc(HWND hwnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
1112 // pgauge = (PZYZGAUGE)GetWindowWord(hwnd, ZYZG_WW_PZYZGAUGE);
1113 pgauge
= (PZYZGAUGE
)GetWindowLong(hwnd
, ZYZG_WW_PZYZGAUGE
);
1115 /* break to get DefWindowProc() */
1119 /* need to allocate a control block */
1120 // pgauge = (PZYZGAUGE)LocalAlloc(LPTR, sizeof(ZYZGAUGE));
1121 pgauge
= (PZYZGAUGE
)malloc(sizeof(ZYZGAUGE
));
1125 /* hang on to this control block */
1126 // SetWindowWord(hwnd, ZYZG_WW_PZYZGAUGE, (WORD)pgauge);
1127 SetWindowLong(hwnd
, ZYZG_WW_PZYZGAUGE
, (LONG
)pgauge
);
1129 /* fill control block with defaults */
1130 pgauge
->wRange
= ZYZG_DEF_RANGE
;
1131 pgauge
->wPosition
= ZYZG_DEF_POSITION
;
1132 pgauge
->wOrientation
= ZYZG_DEF_ORIENTATION
;
1133 pgauge
->wWidth3D
= ZYZG_DEF_WIDTH3D
;
1134 pgauge
->wWidthBezelFace
= ZYZG_DEF_BEZELFACE
;
1135 pgauge
->rgbTextColor
= rgbDefTextColor
;
1136 pgauge
->rgbBkColor
= rgbDefBkColor
;
1138 /* use system font */
1139 SendMessage(hwnd
, WM_SETFONT
, (WPARAM
)NULL
, 0L);
1141 /* go to DefWindowProc() to finish the job */
1145 /* get rid of the control's memory */
1147 // LocalFree((HANDLE)pgauge);
1151 case ZYZG_GETPOSITION
:
1152 return (pgauge
->wPosition
);
1155 return (pgauge
->wRange
);
1157 case ZYZG_GETORIENTATION
:
1158 return (pgauge
->wOrientation
);
1160 case ZYZG_GETWIDTH3D
:
1161 return (pgauge
->wWidth3D
);
1163 case ZYZG_GETBEZELFACE
:
1164 return (pgauge
->wWidthBezelFace
);
1166 case ZYZG_GETBKCOLOR
:
1167 return (pgauge
->rgbTextColor
);
1169 case ZYZG_GETFGCOLOR
:
1170 return (pgauge
->rgbBkColor
);
1172 case ZYZG_SETBKCOLOR
:
1173 pgauge
->rgbBkColor
= lParam
;
1176 case ZYZG_SETFGCOLOR
:
1177 pgauge
->rgbTextColor
= lParam
;
1181 case ZYZG_SETPOSITION
:
1182 pgauge
->wPosition
= wParam
;
1185 GetClientRect(hwnd
, &rc
);
1186 if ((GetWindowLong(hwnd
, GWL_STYLE
) & ZYZGS_3D
) && fSupport3D
)
1188 wParam
= (2 * pgauge
->wWidth3D
) +
1189 pgauge
->wWidthBezelFace
+ 2;
1195 InflateRect(&rc
, ~(wParam
), ~(wParam
));
1196 InvalidateRect(hwnd
, &rc
, FALSE
);
1201 pgauge
->wRange
= wParam
;
1202 goto zyzgForceRepaint
;
1204 case ZYZG_SETORIENTATION
:
1205 pgauge
->wOrientation
= wParam
;
1206 goto zyzgForceRepaint
;
1208 case ZYZG_SETWIDTH3D
:
1209 pgauge
->wWidth3D
= wParam
;
1212 InvalidateRect(hwnd
, NULL
, FALSE
);
1216 case ZYZG_SETBEZELFACE
:
1217 pgauge
->wWidthBezelFace
= wParam
;
1218 goto zyzgForceRepaint3D
;
1220 case ZYZG_SETDELTAPOS
:
1221 /* Watcom doesn't like the following line so removing typecasts */
1222 /* (int)pgauge->wPosition += (int)wParam; */
1223 pgauge
->wPosition
+= wParam
;
1224 goto zyzgForceRepaint
;
1227 BeginPaint(hwnd
, &ps
);
1228 gaugePaint(hwnd
, ps
.hdc
);
1229 EndPaint(hwnd
, &ps
);
1233 hFont
= pgauge
->hFont
;
1235 /* if system font, then return NULL handle */
1236 return (long)((hFont
== GetStockObject(SYSTEM_FONT
)) ? NULL
: hFont
);
1239 /* if NULL hFont, use system font */
1240 if (!(hFont
= (HFONT
)wParam
))
1241 hFont
= GetStockObject(SYSTEM_FONT
);
1243 pgauge
->hFont
= hFont
;
1245 /* redraw if indicated in message */
1248 InvalidateRect(hwnd
, NULL
, TRUE
);
1254 /* let the dialog mangler take care of this message */
1255 return (DefWindowProc(hwnd
, uMsg
, wParam
, lParam
));
1256 } /* gaugeWndProc() */
1259 /** EOF: zyzgauge.c **/