Конференция "KOL" » KOL SpinEdit [Delphi, Windows]
 
  • Сашик (06.03.08 10:50) [0]
    Если кому интересно, привожу простенький SpinEdit (по мотивам KOL UpDown). Максимальные значения практически не ограничены. Возможна масса доработок. Жду замечаний...

    unit NSpinEdit;

    interface
    uses Windows, KOL, Messages;

    type
     NM_UPDOWN = packed record
       hdr: TNMHDR;
       iPos: Integer;
       iDelta: Integer;
     end;

     TNMUpDown = NM_UPDOWN;
     PNMUpDown = ^TNMUpDown;

      PSpinEdit = ^TNSpinEdit;
    //   TKOLUpDown = PSpinEdit;

    TNSpinEdit = object(TObj)
     private
        FValue: Variant;
     protected
        procedure SetValue(const aValue: Variant);
     public
         UpHandle: THandle;
         Maximum,
         Minimum,
         Increment: Variant;
         UpDown,
         Edit: PControl;
         destructor Destroy; virtual;
        property Value: Variant read FValue write SetValue;
    end;

    function NewUpDown(AOwner: PControl; aValue, aMin, aMax, aInc: Variant): PSpinEdit;
    function NewUpDownDef(AOwner: PControl; aValue: Variant): PSpinEdit;

    function UpDownWndProc(Sender: PControl; var Msg:TMsg; var Rslt:Integer):Boolean;
    function SpinEditWndProc(Sender: PControl; var Msg:TMsg;var Rslt:Integer):Boolean;

    implementation

    const
     UPDOWN_CLASS = 'msctls_updown32';
     UDS_ALIGNRIGHT = $0004;
     UDN_FIRST    = 0-721;
     UDN_DELTAPOS = UDN_FIRST - 1;

    function NewUpDownDef(AOwner: PControl; aValue: Variant): PSpinEdit;
      begin
        Result:= NewUpDown(AOwner, aValue, 0, 1000000, 100);
    end;

    function NewUpDown(AOwner: PControl; aValue, aMin, aMax, aInc: Variant): PSpinEdit;
      var Flags: Integer;
      begin
          New(Result, Create);
          AOwner.Add2AutoFree(Result);
          Result.Edit:= NewEditBox(AOwner,[]);
          Result.Edit.Color:= clWindow;
          Flags:= UDS_ALIGNRIGHT;
          Result.UpDown:= _NewCommonControl(Result.Edit, UPDOWN_CLASS,
        WS_VISIBLE or  WS_CHILD or Flags, False,nil);
          Result.UpDown.ExStyle := WS_EX_CLIENTEDGE;
          Result.UpDown.TabStop:= False;
          Result.UpDown.HasBorder:= False;
          Result.UpHandle:= Result.UpDown.GetWindowHandle;
          Result.UpDown.Tag:= LongInt(Result);
          Result.Minimum:= aMin;
          Result.Value:= aValue;
          Result.Maximum:= aMax;
          Result.Increment:= aInc;
          Result.UpDown.AttachProc(UpDownWndProc);
          Result.Edit.AttachProc(SpinEditWndProc);
    end;

    function UpDownWndProc(Sender: PControl; var Msg:TMsg; var Rslt:Integer):Boolean;
       var NMUpDown: PNMUpDown; UpDownNow: PSpinEdit; Tmp: Variant;
       begin
          Result:= False;
          if Msg.message = WM_NOTIFY then begin
             NMUpDown:= PNMUpDown(Msg.lParam);
             if NMUpDown.hdr.code = UDN_DELTAPOS then begin
                UpDownNow:= PSpinEdit(Sender.Tag);
                if not Assigned(UpDownNow) then Exit;
                with UpDownNow^ do begin
                   if (NMUpDown.iDelta = -1) then Tmp:= FValue - Increment
                   else if (NMUpDown.iDelta = 1) then Tmp:= FValue + Increment;
                   if Tmp >= Maximum then Tmp:= Maximum;
                   if Tmp <= Minimum then Tmp:= Minimum;
                   Value:= Tmp;
           end;
         end;
       end;
    end;

    function SpinEditWndProc(Sender: PControl; var Msg:TMsg;var Rslt:Integer):Boolean;
      var UPD: PControl; H, W: Integer;
      begin
         Result:= False;
         with Sender^ do
             if Msg.message = WM_PAINT then begin
                UPD:= Children[0];
                H:= ClientHeight;
                W:= H;
                UPD.SetSize(W, H).SetPosition(Width - W - 4, 1);
            end else if (Msg.message = WM_KEYUP) and (Length(Text) > 0) then
             PSpinEdit(Children[0].Tag).Value:= Variant(Text);
    end;

    destructor TNSpinEdit.Destroy;
      begin
         FValue:= Unassigned;
         Free_And_Nil(UpDown);//.Free;
         Free_And_Nil(Edit);
        inherited Destroy;
    end;

    procedure TNSpinEdit.SetValue(const aValue: Variant);
      begin
         FValue:= aValue;
         Edit.Text:= VarTostr(FValue);
    end;

    initialization
      DoInitCommonControls(ICC_UPDOWN_CLASS);
    finalization

  • Сашик (06.03.08 11:16) [1]
    Инструкция по применению: NewUpDownDef(Form, 100).Edit.SetSize(80, 20).SetPosition(10,10);
  • mdw © (06.03.08 13:19) [2]
    Гм, ничего личного, но порадовали, порадовали!
    1. работать будет не везде (например в WinCE это точно не будет работать), в отличие от MHUpDown. Хотя там аналогично обрабатываются нажатия, а уж счетчик можно и самому организовать, как нравится.
    2. Edit.Text:= VarTostr(FValue); - Это вообще супер! Ну и вообще все конструкции с типом Variant.... А что, почему бы не цепануть Variants, SysUtils и иже с ними? Только нафига тогда KOL?
  • Dimaxx © (06.03.08 13:33) [3]
    А накой леший вообще тут Variant??
  • Сашик (06.03.08 14:25) [4]
    Variant дан для примера. При соответствующей обработки участка кода "супер VarToStr" можно создать SpinEdit для Float...
  • mdw © (06.03.08 20:22) [5]
    Просто, уже есть рабочий компонент, с зеркалом при том.
    А на счет "При соответствующей обработки участка кода "супер VarToStr" можно создать SpinEdit для Float..." - смысла нет, достаточно просто иметь возможность обрабатывать нажания кнопок (это тоже уже есть), а дальше самому реагировать как надо. Например анализировать где стоит каретка в едите (перед запятой или после), и соответственно менять челую или дробную часть, или вообше символы менять от 'A' до 'Z', например.
    А "сучности" плодить не сто`ит. Зачем отдельный контрол для Integer, отдельный для Float,  отдельный для Char и т.д?
  • Сашик (06.03.08 22:05) [6]
    mdw - большое спасибо за продолжение дискуссии.
    Однако хочу пояснить простоту использования предложенного SpinEdit:
    1) при вызове NewUpDown(Form, 1.4, 0, 4.2, 0.7).Edit.SetSize(80, 20).SetPosition(10,10) - это FloatSpinEdit
    2) при вызове NewUpDown(Form, 1, 0, 5, 1).Edit.SetSize(80, 20).SetPosition(10,10) - это IntegerSpinEdit
    Помимо этого при переборе дочерних Controls, мой SpinEdit проходит как 1 Children, а MHUpDown с довеском, как 2, что очень неудобно при массиве Controls (наблюдении их поведения и изменения размеров). Вообще не понимаю причину использования версий Delphi 6 и 7 для программирования в KOL? В Delphi 4 не требуется добавления uses Variant, и размер программ меньше...
  • mdw © (06.03.08 23:03) [7]
    Да я не против, присылайте юнит, выложу на сайте. Хуже никому не будет, а может пригодится.
    Насчет версий Delphi, тут дело каждого. Мне приходится работать на семерке, а дома принципиально даже не устанавливаю Делфи, да и времени нет. Да и вообще, что-то не очень были впечатления от чеверки..., ну да неважно, повторюсь, дело личного каждого.
    Короче, если считаете что есть код, полезный не только Вам, то присылайте.
  • Сашик (06.03.08 23:47) [8]
    mdw, я на на форумах в первый раз. Не знаю куда и как посылать, если не затруднит - подскажите...
  • Elec3C © (07.03.08 01:14) [9]

    > Не знаю куда

    На мыло mdw.
 
Конференция "KOL" » KOL SpinEdit [Delphi, Windows]
Есть новые Нет новых   [134431   +15][b:0][p:0.001]