home *** CD-ROM | disk | FTP | other *** search
/ DOS/V Power Report 1997 May / VPR9705A.ISO / VPR_DATA / PROGRAM / CBTRIAL / SETUP / DATA.Z / SPIN.CPP < prev    next >
C/C++ Source or Header  |  1997-02-14  |  12KB  |  485 lines

  1. //---------------------------------------------------------------------------
  2. // Borland C++Builder
  3. // Copyright (c) 1987, 1997 Borland International Inc.  All Rights Reserved.
  4. //---------------------------------------------------------------------------
  5. #if !defined (REGISTER_ALL_CONTROLS)
  6.   #include "spin.h"
  7. #else
  8.   #include "source\spin.h"
  9. #endif
  10. //#pragma resource "*.res"   //IDE links .res automatically for components
  11. #pragma resource "updown.res"
  12.  
  13. //---------------------------------------------------------------------------
  14. namespace Spin {
  15. void __fastcall Register()
  16. {
  17.   TComponentClass classes[2] = {__classid(TSpinButton),
  18.                                 __classid(TSpinEdit)};
  19.   RegisterComponents("Samples",
  20.                      classes,
  21.                      (sizeof(classes)/sizeof(classes[0])) - 1);
  22. }
  23. } //end namespace
  24.  
  25. //---------------------------------------------------------------------------
  26. // TSpinButton
  27.  
  28. __fastcall TSpinButton::TSpinButton(TComponent *AOwner)
  29.                       : TWinControl(AOwner)
  30. {
  31.   (((ControlStyle >> csAcceptsControls)
  32.                   >> csSetCaption)
  33.                   << csFramed)
  34.                   << csOpaque;
  35.  
  36.   FUpButton = CreateButton();
  37.   FDownButton = CreateButton();
  38.   UpGlyph = NULL;
  39.   DownGlyph = NULL;
  40.  
  41.   Width = 20;
  42.   Height = 25;
  43.   FFocusedButton = FUpButton;
  44. }
  45.  
  46. TTimerSpeedButton *__fastcall TSpinButton::CreateButton(void)
  47. {
  48.   TTimerSpeedButton * Result;
  49.  
  50.   Result = new TTimerSpeedButton((TComponent *) this);
  51.   Result->OnClick = BtnClick;
  52.   Result->OnMouseDown = BtnMouseDown;
  53.   Result->Visible = True;
  54.   Result->Enabled = True;
  55.   Result->TimeBtnState << tbAllowTimer;
  56.   Result->NumGlyphs = 1;
  57.   Result->Parent = this;
  58.  
  59.   return Result;
  60. }
  61.  
  62. void __fastcall TSpinButton::AdjustSize(int &W, int &H)
  63. {
  64.   if ((FUpButton == NULL))//||(ComponentState.Contains(csLoading)))
  65.      return;
  66.  
  67.   if (W < 15)
  68.       W = 15;
  69.  
  70.   FUpButton->SetBounds (0, 0, W, H / 2);
  71.   FDownButton->SetBounds (0, FUpButton->Height - 1, W, H - FUpButton->Height + 1);
  72. }
  73.  
  74. void __fastcall TSpinButton::SetBounds(int ALeft, int ATop, int AWidth, int AHeight)
  75. {
  76.   int W, H;
  77.  
  78.   W = AWidth;
  79.   H = AHeight;
  80.   AdjustSize (W, H);
  81.   TWinControl::SetBounds (ALeft, ATop, W, H);
  82. }
  83.  
  84. void __fastcall TSpinButton::WMSize(TWMSize &Message)
  85. {
  86.   int W, H;
  87.   TWinControl::Dispatch(&Message);
  88.   // check for minimum size
  89.   W = Width;
  90.   H = Height;
  91.   AdjustSize (W, H);
  92.  
  93.   if ((W != Width) || (H != Height))
  94.       TWinControl::SetBounds(Left, Top, W, H);
  95.  
  96.   Message.Result = 0;
  97. }
  98.  
  99. void __fastcall TSpinButton::WMSetFocus(TWMSetFocus &Message)
  100. {
  101.   FFocusedButton->TimeBtnState << tbFocusRect;
  102.   FFocusedButton->Invalidate();
  103. }
  104.  
  105. void __fastcall TSpinButton::WMKillFocus(TWMKillFocus &Message)
  106. {
  107.   FFocusedButton->TimeBtnState >> tbFocusRect;
  108.   FFocusedButton->Invalidate();
  109. }
  110.  
  111. void __fastcall TSpinButton::KeyDown(Word &Key,  TShiftState Shift)
  112. {
  113.   switch (Key) {
  114.     case VK_UP:
  115.           SetFocusBtn (FUpButton);
  116.           FUpButton->Click();
  117.           break;
  118.     case VK_DOWN:
  119.           SetFocusBtn (FDownButton);
  120.           FDownButton->Click();
  121.           break;
  122.     case VK_SPACE:
  123.         FFocusedButton->Click();
  124.   }
  125. }
  126.  
  127. void __fastcall TSpinButton::BtnMouseDown(TObject *Sender, TMouseButton Button,
  128.                                        TShiftState Shift, int X, int Y)
  129. {
  130.   if (Button == mbLeft) {
  131.     SetFocusBtn ((TTimerSpeedButton*) Sender);
  132.     if((FFocusControl != NULL) && ( FFocusControl->TabStop ) &&
  133.       (FFocusControl->CanFocus()) && (GetFocus() != FFocusControl->Handle))
  134.             FFocusControl->SetFocus();
  135.     else if (TabStop && (GetFocus() != Handle) && CanFocus() )
  136.       SetFocus();
  137.   }
  138. }
  139.  
  140. void __fastcall TSpinButton::BtnClick(TObject *Sender)
  141. {
  142.   if (Sender == FUpButton) {
  143.     if (FOnUpClick != NULL)
  144.         FOnUpClick(this);
  145.   }
  146.   else
  147.     if (FOnDownClick != NULL)
  148.        FOnDownClick(this);
  149. }
  150.  
  151. void __fastcall TSpinButton::SetFocusBtn(TTimerSpeedButton *Btn)
  152. {
  153.   if (TabStop && CanFocus() &&  (Btn != FFocusedButton)) {
  154.     FFocusedButton->TimeBtnState >> tbFocusRect;
  155.     FFocusedButton = Btn;
  156.     if (GetFocus() == Handle) {
  157.        FFocusedButton->TimeBtnState << tbFocusRect;
  158.        Invalidate();
  159.     }
  160.   }
  161. }
  162.  
  163. void __fastcall TSpinButton::WMGetDlgCode(TWMNoParams &Message)
  164. {
  165.   Message.Result = DLGC_WANTARROWS;
  166. }
  167.  
  168. void __fastcall TSpinButton::Loaded(void)
  169. {
  170.  
  171.   int W, H;
  172.  
  173.   W = Width;
  174.   H = Height;
  175.   AdjustSize (W, H);
  176.  
  177.   if ((W != Width) || (H != Height))
  178.     TWinControl::SetBounds(Left, Top, W, H);
  179. }
  180.  
  181. Graphics::TBitmap *__fastcall TSpinButton::GetUpGlyph(void)
  182. {
  183.   Graphics::TBitmap * Result;
  184.  
  185.   Result = FUpButton->Glyph;
  186.   return Result;
  187. }
  188.  
  189. void __fastcall TSpinButton::SetUpGlyph(Graphics::TBitmap *Value)
  190. {
  191.   if (Value != NULL)
  192.     FUpButton->Glyph = Value;
  193.   else {
  194.     FUpButton->Glyph->Handle = LoadBitmap((void*) HInstance, "SpinUp");
  195.     FUpButton->NumGlyphs = 1;
  196.     FUpButton->Invalidate();
  197.   }
  198. }
  199.  
  200. Graphics::TBitmap *__fastcall TSpinButton::GetDownGlyph(void)
  201. {
  202.   Graphics::TBitmap * Result;
  203.  
  204.   Result = FDownButton->Glyph;
  205.   return Result;
  206. }
  207.  
  208. void __fastcall TSpinButton::SetDownGlyph(Graphics::TBitmap *Value)
  209. {
  210.   if (Value != NULL)
  211.     FDownButton->Glyph = Value;
  212.   else {
  213.     FDownButton->Glyph->Handle = LoadBitmap((void*)HInstance, "SpinDown");
  214.     FDownButton->NumGlyphs = 1;
  215.     FDownButton->Invalidate();
  216.   }
  217. }
  218.  
  219. // TSpinEdit
  220.  
  221. __fastcall TSpinEdit::TSpinEdit(TComponent *AOwner) : TCustomEdit(AOwner)
  222. {
  223.   FButton = new TSpinButton(this);
  224.  
  225.   FButton->Width = 15;
  226.   FButton->Height = 17;
  227.   FButton->Visible = True;
  228.   FButton->Parent = this;
  229.   FButton->FocusControl = this;
  230.   FButton->OnUpClick = UpClick;
  231.   FButton->OnDownClick = DownClick;
  232.   Text = "0";
  233.   ControlStyle >> csSetCaption;
  234.   FIncrement = 1;
  235.   FEditorEnabled = True;
  236. }
  237.  
  238. __fastcall TSpinEdit::~TSpinEdit(void)
  239. {
  240.   FButton = NULL;
  241. }
  242.  
  243. void __fastcall TSpinEdit::GetChildren(TGetChildProc Proc)
  244. {
  245. }
  246.  
  247. void __fastcall TSpinEdit::KeyDown(Word &Key,  TShiftState Shift)
  248. {
  249.   if (Key == VK_UP)
  250.     UpClick (this);
  251.   else if (Key == VK_DOWN)
  252.          DownClick (this);
  253.   TCustomEdit::KeyDown(Key, Shift);
  254. }
  255.  
  256. void __fastcall TSpinEdit::KeyPress(Char& Key)
  257. {
  258.   if (!IsValidChar(Key)) {
  259.     Key = 0;
  260.     MessageBeep(0);
  261.   }
  262.   if (Key != 0)
  263.     TCustomEdit::KeyPress(Key);
  264. }
  265.  
  266. bool __fastcall TSpinEdit::IsValidChar(Char Key)
  267. {
  268.   bool Result;
  269.   if(((Key == DecimalSeparator)       ||
  270.       (Key == '+')                    ||
  271.       (Key == '-')                    ||
  272.      ((Key >= '0') && (Key <= '9')))  ||
  273.      ((Key < 0x32) && (Key != Char(VK_RETURN))))
  274.    Result = True;
  275.  
  276.   if (!(FEditorEnabled) &&
  277.       Result &&
  278.       ((Key >= 0x32) ||
  279.        (Key == Char(VK_BACK)) ||
  280.        (Key == Char(VK_DELETE))))
  281.     Result = False;
  282.   return Result;
  283. }
  284.  
  285. void __fastcall TSpinEdit::CreateParams(TCreateParams &Params)
  286. {
  287.   TCustomEdit::CreateParams(Params);
  288.   //Params->Style &= ~WS_BORDER;
  289.   Params.Style |=  ES_MULTILINE | WS_CLIPCHILDREN;
  290. }
  291.  
  292. void __fastcall TSpinEdit::CreateWnd()
  293. {
  294.   TCustomEdit::CreateWnd();
  295.   SetEditRect();
  296. }
  297.  
  298. void __fastcall TSpinEdit::SetEditRect(void)
  299. {
  300.   TRect Loc;
  301.  
  302.   SendMessage(Handle, EM_GETRECT, 0, long(&Loc));
  303.   Loc.Bottom = ClientHeight + 1;  // +1 is workaround for windows paint bug
  304.   Loc.Right = ClientWidth - FButton->Width - 2;
  305.   Loc.Top = 0;
  306.   Loc.Left = 0;
  307.   SendMessage(Handle, EM_SETRECTNP, 0, long(&Loc));
  308.   SendMessage(Handle, EM_GETRECT, 0, long(&Loc));  // debug
  309. }
  310.  
  311. void __fastcall TSpinEdit::WMSize(TWMSize &Message)
  312. {
  313.   int MinHeight;
  314.  
  315.   MinHeight = GetMinHeight();
  316.     // text edit bug: if size to less than minheight, then edit ctrl does
  317.     //  not display the text
  318.   if (Height < MinHeight)
  319.     Height = MinHeight;
  320.   else if (FButton != NULL) {
  321.     if (NewStyleControls)
  322.       FButton->SetBounds(Width - FButton->Width - 5, 0, FButton->Width, Height - 5);
  323.     else FButton->SetBounds (Width - FButton->Width, 0, FButton->Width, Height);
  324.     SetEditRect();
  325.   };
  326. }
  327.  
  328. int __fastcall TSpinEdit::GetMinHeight(void)
  329. {
  330.   HDC DC;
  331.   HFONT SaveFont;
  332.   int I, Result;
  333.   TTextMetric SysMetrics, Metrics;
  334.  
  335.   DC = GetDC(NULL);
  336.   GetTextMetrics(DC, &SysMetrics);
  337.   SaveFont = SelectObject(DC, Font->Handle);
  338.   GetTextMetrics(DC, &Metrics);
  339.   SelectObject(DC, SaveFont);
  340.   ReleaseDC(0, DC);
  341.   I = SysMetrics.tmHeight;
  342.   if (I > Metrics.tmHeight)
  343.     I = Metrics.tmHeight;
  344.  
  345.   Result = Metrics.tmHeight + I / 4 + GetSystemMetrics(SM_CYBORDER) * 4 + 2;
  346.   return Result;
  347. }
  348.  
  349. void __fastcall TSpinEdit::UpClick(TObject *Sender)
  350. {
  351.   if (ReadOnly)
  352.     MessageBeep(0);
  353.   else Value += FIncrement;
  354. }
  355.  
  356. void __fastcall TSpinEdit::DownClick(TObject *Sender)
  357. {
  358.   if (ReadOnly)
  359.     MessageBeep(0);
  360.   else
  361.     Value -= FIncrement;
  362. }
  363.  
  364. void __fastcall TSpinEdit::WMPaste(TWMNoParams &Message)
  365. {
  366.   if (!FEditorEnabled || ReadOnly)
  367.     return;
  368. }
  369.  
  370. void __fastcall TSpinEdit::WMCut(TWMNoParams &Message)
  371. {
  372.   if (!FEditorEnabled || ReadOnly)
  373.     return;
  374. }
  375.  
  376. void __fastcall TSpinEdit::CMExit(TWMNoParams &Message)
  377. {
  378.   if (CheckValue (Value) != Value)
  379.     SetValue (Value);
  380. }
  381.  
  382. long __fastcall TSpinEdit::GetValue(void)
  383. {
  384.   long Result;
  385.   try {
  386.     Result = Text.ToInt();
  387.     }
  388.   catch(...) {
  389.       Text=AnsiString((int)FMinValue);
  390.     return FMinValue;
  391.   }
  392.   return Result;
  393. }
  394.  
  395. void __fastcall TSpinEdit::SetValue(long NewValue)
  396. {
  397.   Text = AnsiString((int)CheckValue(NewValue));
  398. }
  399.  
  400. long __fastcall TSpinEdit::CheckValue(long NewValue)
  401. {
  402.   long Result;
  403.   Result = NewValue;
  404.   if (FMaxValue != FMinValue) {
  405.     if (NewValue < FMinValue)
  406.       Result = FMinValue;
  407.     else if (NewValue > FMaxValue)
  408.       Result = FMaxValue;
  409.   }
  410.   return Result;
  411. }
  412.  
  413. void __fastcall TSpinEdit::CMEnter(TWMNoParams &Message)
  414. {
  415.   if (AutoSelect && !(ControlState.Contains(csLButtonDown)))
  416.     SelectAll();
  417. }
  418.  
  419. // TTimerSpeedButton
  420.  
  421.  __fastcall TTimerSpeedButton::TTimerSpeedButton(TComponent *AOwner) :
  422.                                TSpeedButton(AOwner) { }
  423.  
  424. __fastcall TTimerSpeedButton::~TTimerSpeedButton()
  425. {
  426.   if (FRepeatTimer != NULL)
  427.     delete FRepeatTimer;
  428. }
  429.  
  430. void __fastcall TTimerSpeedButton::MouseDown(TMouseButton Button,  TShiftState Shift,
  431.                           int X, int Y)
  432. {
  433.   TSpeedButton::MouseDown (Button, Shift, X, Y);
  434.  
  435.   if (FTimeBtnState.Contains(tbAllowTimer))
  436.   {
  437.     if (FRepeatTimer == NULL)
  438.       FRepeatTimer = new TTimer(this);
  439.  
  440.     FRepeatTimer->OnTimer = TimerExpired;
  441.     FRepeatTimer->Interval = InitRepeatPause;
  442.     FRepeatTimer->Enabled  = True;
  443.   };
  444. }
  445.  
  446. void __fastcall TTimerSpeedButton::MouseUp(TMouseButton Button,  TShiftState Shift,
  447.                                     int X, int Y)
  448. {
  449.   TSpeedButton::MouseUp (Button, Shift, X, Y);
  450.   if (FRepeatTimer != NULL)
  451.     FRepeatTimer->Enabled  = false;
  452. }
  453.  
  454. void __fastcall TTimerSpeedButton::TimerExpired(TObject *Sender)
  455. {
  456.   FRepeatTimer->Interval = RepeatPause;
  457.   if ((FState == bsDown) && MouseCapture) {
  458.     try {
  459.       Click();
  460.     }
  461.     catch(...) {
  462.       FRepeatTimer->Enabled = false;
  463.       throw;
  464.     }
  465.   }
  466. }
  467.  
  468. void __fastcall TTimerSpeedButton::Paint(void)
  469. {
  470.   TRect R;
  471.  
  472.   TSpeedButton::Paint();
  473.   if (FTimeBtnState.Contains(tbFocusRect)) {
  474.     R.Left = 0;
  475.     R.Top = 0;
  476.     R.Right = Width;
  477.     R.Bottom = Height;
  478.     InflateRect(&RECT(R), -3, -3);
  479.     if (FState == bsDown)
  480.       OffsetRect(&RECT(R), 1, 1);
  481.     DrawFocusRect(Canvas->Handle, &RECT(R));
  482.   }
  483. }
  484.  
  485.