home *** CD-ROM | disk | FTP | other *** search
/ Chip 2002 May / Chip_2002-05_cd1.bin / chplus / cpp / 5 / Komponety.exe / cspin.cpp < prev    next >
C/C++ Source or Header  |  1998-02-09  |  12KB  |  483 lines

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