На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! ПРАВИЛА РАЗДЕЛА · FAQ раздела Delphi · Книги по Delphi
Обязательно выделяйте текст программы тегом [сode=pas] ... [/сode]. Для этого используйте кнопку [code=pas] в форме ответа или комбобокс, если нужно вставить код на языке, отличном от Дельфи/Паскаля.

Этот раздел предназначен для вопросов, посвященных разработке компонентов, а также для тестирования собственных бесплатных компонентов с открытым исходным кодом.

Здесь запрещается:
1. Размещать ссылки на какие-либо коммерческие компоненты, реализующие требуемую функциональность.
2. Обсуждать и тестировать коммерческие компоненты или компоненты с закрытым кодом.
3. Давать ссылки на сайты с исходным кодом компонентов. Все тестируемые исходные коды должы быть размещены на сайте ИСХОДНИКИ.RU.
Модераторы: Rouse_, DimaBr
  
> Проблема с TComboBox в TStringGrid , Не появляется выпадающий список TComboBox
    Разрабатываю потомка TStringGrid с ComboBox в нескольких подряд идущих столбцах с одинаковыми списками
    Вроде почти все работает, но список при нажатии кнопки ComboBox-а не выпадает, приходится действовать только
    стрелками вверх / вниз для изменения значения
    Сейчас решаю проблему с передачей фокуса из ComboBox-а в StringGrid - тоже пока работает некорректно
    Помогите, пожалуйста, разобраться.
    И еще одна проблема - каждый раз при входе в ComboBox вызывается обработчик Grid.OnExit, а его я использую для анализа и сохранения данных из таблицы в своих переменных. Есть возможность отключить обработку OnExit, если управление передается не на "внешний" компонент, а на "внутренний" ComboBox ?

    ExpandedWrap disabled
      unit TitleGrid;
       
      interface
       
      uses
        Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
        Grids, stdctrls,Math;
       
        TNumComboGrid = class(TStringGrid)
        private
          fCB_FirstCol: integer;
          fCB_LastCol:  integer;
          fCB_Items:    TStringList;                        
          fCB:          TComboBox;                          //  Компонент TComboBox
        protected
          { Protected declarations }
          procedure FixObjPosn(vCol, vRow: LongInt);       // Рисование TComboBox в ячейке
          function Is_ColCombo(ACol:integer):boolean;      // Возвращает признак, что в колонке ACol есть TComboBox
          procedure CB_KeyDown(Sender: TObject; var Key: Word;Shift: TShiftState); // Реакция на клавиши в ComboBox
          procedure CB_Exit(Sender: TObject);
          procedure DrawCell(ACol, ARow: Longint; ARect: TRect; AState: TGridDrawState);override;
          procedure DoEnter; override;
        public
          constructor Create(AOwner: TComponent); override;
          destructor Destroy; override;
        published                                                                  // Назначается в design-time :
          property CB_FirstCol: integer read fCB_FirstCol write fCB_FirstCol; // Первая колонка с TComboBox
          property CB_LastCol: integer read fCB_LastCol write fCB_LastCol;    // Последняя колонка с TComboBox
          property CB_Items: TStringList read fCB_Items write fCB_Items;      // Список значений для TComboBox.Items;
        end;
       
      implementation
       
      constructor TNumComboGrid.Create(AOwner: TComponent);
      var
        i:integer;
      begin
        inherited;
        RowCount:= 2;
        fCB_Items:= TStringList.Create;
        fCB:= TComboBox.Create(AOwner);
        fCB.Parent:= Self;       //или AOwner as TWinControl; - Тогда список выпадает, но возникают другие проблемы
        fCB.Style:= csDropDownList;
        fCB.Visible:= false;
        fCB.OnKeyDown:= CB_KeyDown;
        fCB.OnExit:= CB_Exit;
      end;
       
      destructor TNumComboGrid.Destroy;
      var
        i,j:integer;
      begin
        fCB_Items.Free;
        fCB.Free;
        inherited;
      end;
       
      procedure TNumComboGrid.CB_Exit(Sender: TObject); // Хочу сдвигаться на следующую колонку
      begin
        Cells[Col,Row]:= fCB.Items[fCB.Itemindex];
        if Col<ColCount-1 then Col:= Col+1 else begin
          Col:=1;
          if Row<RowCount-1 then Row:= Row+1
          else Perform(WM_NEXTDLGCTL, 0, 0);//Row:= FixedRows;
        end;
        fCB.Visible:= false;
        SetFocus;
        SelectCell(Col,Row);
      end;
       
      procedure TNumComboGrid.CB_KeyDown(Sender: TObject;var Key:Word; Shift: TShiftState);
      begin
        if (Key=VK_RETURN) or (Key=VK_TAB) or (Key=VK_RIGHT) then begin
          Key:= 0;
          CB_Exit(Sender);
        end else inherited;
      end;
       
      procedure TNumComboGrid.DoEnter; // Решаю проблему с передачей фокуса в TStringGrid
      begin
        inherited;
        if ((Col=0) and (Row=0)) or ((Col=FixedCols) or (Row=FixedRows)) then
          SelectCell(FixedCols,FixedRows) else SelectCell(Col,Row);
      end;
       
      procedure TNumComboGrid.DrawCell(ACol, ARow: Integer; ARect: TRect;
        AState: TGridDrawState);
      begin
        if Is_ColCombo(ACol) and (ARow>=FixedRows) then begin
          Canvas.FillRect(ARect);
          canvas.font.style:=canvas.font.style+[fsbold];
          DrawText(Canvas.Handle,PChar(Cells[ACol,Arow]),length(Cells[ACol,Arow]),ARect,DT_LEFT);
        end else  inherited;
      end;
       
      procedure TNumComboGrid.FixObjPosn(vCol, vRow: Integer);
      var
        Rc: TRect;
      begin
        if Is_ColCombo(vCol) then begin
          Rc := CellRect(vCol, vRow);
          if Rc.Right = Rc.Left then {ïðÿìîóãîëüíèê ÿ÷åéêè íåâèäèì}
            fCB.Visible := False
          else begin
            InflateRect(Rc, -1, -1);
            // OffsetRect(Rc, Left + 1, Top + 1);// Требуется сдвиг, только если fCB.Parent - не Self, a AOwner
            if fCB.Items.Count=0 then begin
              fCB.Items.Assign(CB_Items);
              fCB.DropDownCount:= CB_Items.Count+1;
            end;
            fCB.BoundsRect := Rc;
            fCB.ItemIndex:= fCB.Items.IndexOf(Cells[vCol,vRow]);
            fCB.Visible := True;
            fCB.SetFocus;
          end;
        end;
      end;
       
      function TNumComboGrid.Is_ColCombo(ACol: integer): boolean;
      var res:boolean;
      begin
        Res:= ((CB_FirstCol>0) and (CB_LastCol>0));
        if ACol>=FixedCols then Res:= (res and (ACol>=CB_FirstCol) and (ACol<=CB_LastCol));
        Result:= res;
      end;
       
      function TNumComboGrid.SelectCell(ACol, ARow: Integer): Boolean;
      begin
        Result:= inherited SelectCell(ACol, ARow);
        if Is_ColCombo(ACol) then FixObjPosn(ACol, ARow);
      end;
       
       
      end.
      Если TComboBox.Create(Self); - что кажет?
        Спасибо. Так - лучше, но проблема не решилась.
        Возник еще один вопрос: что перехватывает нажатие клавиш <Enter> и <Tab> в ComboBoxe, когда он не в "раскрытом" состоянии (т.е. когда DroppedDown=false)?
        При отладке установил точки прерывания в обработчиках событий OnKeyDown и OnKeyPress.
        В фокусе ввода - ComboBox. Давлю <Enter> - не попадаю ни в KeyDown, ни в KeyPress
          Что-то я не допонял, собрал вот этот код в BDS 2007 - все нормально отрабатывает как тебе и нужно:

          ExpandedWrap disabled
            unit TitleGrid;
             
            interface
             
            uses
              Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
              Grids, stdctrls, Math;
             
            type
              TNumComboGrid = class(TStringGrid)
              private
                fCB_FirstCol: integer;
                fCB_LastCol:  integer;
                fCB_Items:    TStringList;                        
                fCB:          TComboBox;                          //  Компонент TComboBox
                FLock:        Boolean;
              protected
                procedure FixObjPosn(vCol, vRow: LongInt);       // Рисование TComboBox в ячейке
                function Is_ColCombo(ACol:integer):boolean;      // Возвращает признак, что в колонке ACol есть TComboBox
                procedure CB_KeyDown(Sender: TObject; var Key: Word;Shift: TShiftState); // Реакция на клавиши в ComboBox
                procedure CB_Exit(Sender: TObject);
                procedure DrawCell(ACol, ARow: Longint; ARect: TRect; AState: TGridDrawState);override;
                procedure DoEnter; override;
                function SelectCell(ACol, ARow: Integer): Boolean; override;
                procedure MouseDown(Button: TMouseButton; Shift: TShiftState;
                  X, Y: Integer); override;
                procedure MouseUp(Button: TMouseButton; Shift: TShiftState;
                  X, Y: Integer); override;
              public
                constructor Create(AOwner: TComponent); override;
                destructor Destroy; override;
              published                                                                  // Назначается в design-time :
                property CB_FirstCol: integer read fCB_FirstCol write fCB_FirstCol; // Первая колонка с TComboBox
                property CB_LastCol: integer read fCB_LastCol write fCB_LastCol;    // Последняя колонка с TComboBox
                property CB_Items: TStringList read fCB_Items write fCB_Items;      // Список значений для TComboBox.Items;
              end;
             
            implementation
             
            constructor TNumComboGrid.Create(AOwner: TComponent);
            var
              i:integer;
            begin
              inherited;
              RowCount:= 2;
              fCB_Items:= TStringList.Create;
              fCB:= TComboBox.Create(Self);
              fCB.Parent:= Self;       //или AOwner as TWinControl; - Тогда список выпадает, но возникают другие проблемы
              fCB.Style:= csDropDownList;
              fCB.Visible:= false;
              fCB.OnKeyDown:= CB_KeyDown;
              fCB.OnExit:= CB_Exit;
            end;
             
            destructor TNumComboGrid.Destroy;
            var
              i,j:integer;
            begin
              fCB_Items.Free;
              fCB.Free;
              inherited;
            end;
             
            procedure TNumComboGrid.CB_Exit(Sender: TObject); // Хочу сдвигаться на следующую колонку
            begin
              Cells[Col,Row]:= fCB.Items[fCB.Itemindex];
             
              if FLock then Exit;
             
              if Col<ColCount - 1 then
                Col:= Col + 1
              else
              begin
                Col:=1;
                if Row<RowCount-1 then
                  Row:= Row+1
                else
                  Perform(WM_NEXTDLGCTL, 0, 0);//Row:= FixedRows;
              end;
              fCB.Visible:= false;
              SetFocus;
              SelectCell(Col,Row);
            end;
             
            procedure TNumComboGrid.CB_KeyDown(Sender: TObject;var Key:Word; Shift: TShiftState);
            begin
              if (Key=VK_RETURN) or (Key=VK_TAB) or (Key=VK_RIGHT) then
              begin
                Key:= 0;
                CB_Exit(Sender);
              end
              else
                inherited;
            end;
             
            procedure TNumComboGrid.DoEnter; // Решаю проблему с передачей фокуса в TStringGrid
            begin
              inherited;
              if ((Col=0) and (Row=0)) or ((Col=FixedCols) or (Row=FixedRows)) then
                SelectCell(FixedCols,FixedRows)
              else
                SelectCell(Col,Row);
            end;
             
            procedure TNumComboGrid.DrawCell(ACol, ARow: Integer; ARect: TRect;
              AState: TGridDrawState);
            begin
              if Is_ColCombo(ACol) and (ARow>=FixedRows) then
              begin
                Canvas.FillRect(ARect);
                canvas.font.style:=canvas.font.style+[fsbold];
                DrawText(Canvas.Handle,PChar(Cells[ACol,Arow]),length(Cells[ACol,Arow]),ARect,DT_LEFT);
              end
              else
                inherited;
            end;
             
            procedure TNumComboGrid.FixObjPosn(vCol, vRow: Integer);
            var
              Rc: TRect;
            begin
              if Is_ColCombo(vCol) then
              begin
                Rc := CellRect(vCol, vRow);
                if Rc.Right = Rc.Left then
                  fCB.Visible := False
                else
                begin
                  InflateRect(Rc, -1, -1);
                  if fCB.Items.Count=0 then
                  begin
                    fCB.Items.Assign(CB_Items);
                    fCB.DropDownCount:= CB_Items.Count+1;
                  end;
                  fCB.BoundsRect := Rc;
                  fCB.ItemIndex:= fCB.Items.IndexOf(Cells[vCol,vRow]);
                  fCB.Visible := True;
                  fCB.SetFocus;
                end;
              end;
            end;
             
            function TNumComboGrid.Is_ColCombo(ACol: integer): boolean;
            var res:boolean;
            begin
              Res:= ((CB_FirstCol>0) and (CB_LastCol>0));
              if ACol>=FixedCols then
                Res := (res and (ACol>=CB_FirstCol) and (ACol<=CB_LastCol));
              Result := res;
            end;
             
            procedure TNumComboGrid.MouseDown(Button: TMouseButton; Shift: TShiftState; X,
              Y: Integer);
            begin
              FLock := True;
              inherited;
            end;
             
            procedure TNumComboGrid.MouseUp(Button: TMouseButton; Shift: TShiftState; X,
              Y: Integer);
            begin
              inherited;
              FLock := False;
            end;
             
            function TNumComboGrid.SelectCell(ACol, ARow: Integer): Boolean;
            begin
              Result:= inherited SelectCell(ACol, ARow);
              if Is_ColCombo(ACol) then
                FixObjPosn(ACol, ARow);
            end;
             
             
            end.
            У меня под Delphi 7 - не получается. Может быть, это из-за Среды разработки, а может, от того, что у меня
            Родитель - не TStringGrid, а свой Grid. Привожу модуль целиком
            ExpandedWrap disabled
              {                 TTitleGrid
                1. Многострочный заголовок колонок таблицы
                2. Содержимое заголовка и первой колонки задаются в Design-time
                   (TitlesRow - заголовки строк,  TitlesCol - заголовки колонок)
                3. Подсказки (Hints) выводятся для каждой колонки
                   (или строки при HintsOnCol=false), и задаются в Design-time
                   Подсказка может быть многострочной, новая строка - символ @
                4. Клавиша ENTER перемещает на след. ячейку
                   (и следующую строку на последней ячейке в строке)
                5. Выравнивание рабочих ячеек - по правому краю, заголовка колонок - по центру
                   ,Заголовки строк - по левому краю, или по центру, если выполнен медод
                   Assign_NumRow, заполняющий нулевую колонку номерами строк
                6. Ширина первой колонки задается в Design-time (FirstColWidth)
                7. Добавлена процедура удаления строки Delete_Row(ARow)
               
                                 TTitleNumGrid
                1. Числа в ячейках таблицы округляются до Precissions знаков после запятой
                2. Точность округления последних NumLastCol колонок может быть другой,
                   и задается в PrecLastCol.
               
                                 TNumComboGrid
                Несколько колонок, с CB_FirstCol по CB_LastCol  - выпадающий список
                TComboBox.   Содержимое списка задается в CB_Items
              }
              unit TitleGrid;
               
              interface
               
              uses
                Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
                Grids, stdctrls,Math;
               
              type
                TTitleGrid = class(TStringGrid)
                private
                  fHints:   TStringList; // Подсказки
                  fHintsOnCols: boolean;  // Подсказки по строкам, или столбцам?
                  function GetFirstCol: Integer;
                  procedure SetFirstCol(const Value: Integer);
                  procedure SetHintsOnCols(const Value: boolean);
                  procedure SetHints(const Value: TStringList);
                  procedure SetTitlesCol(Value: TStrings);
                  function GetTitlesCol: TStrings;
                  procedure SetTitlesRow(Value: TStrings);
                  function GetTitlesRow: TStrings;
                  function GetFirstCol1: Integer;
                  procedure SetFirstCol1(const Value: Integer);
                protected
                  { Protected declarations }
                  Old_Col:Integer; // Для отслеживания передвижения мыши
                  Old_Row:Integer; //  между строками и столбцами
                  StyleCol0: Cardinal; //Стиль колонки N 0
                  procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
                  procedure DrawCell(ACol, ARow: Longint; ARect: TRect; AState: TGridDrawState);override;
                  procedure KeyPress(var Key: Char); override;
                public
                  constructor Create(AOwner: TComponent); override;
                  destructor Destroy; override;
                  procedure Delete_Row(ARow:integer);dynamic;// Удалить строку вместе с подсказками
                  procedure Assign_NumRow; // Записывает в TitlesRow № строки
                published
                  property Hints: TStringList read fHints write SetHints;
                  Property HintsOnCols: boolean read FHintsOnCols write SetHintsOnCols;
                  property FirstColWidth: Integer read GetFirstCol write SetFirstCol;
                  property FirstCol1Width: Integer read GetFirstCol1 write SetFirstCol1;
                  property TitlesRow: TStrings read GetTitlesRow write SetTitlesRow;   // Первая колонка
                  property TitlesCol: TStrings read GetTitlesCol write SetTitlesCol; // Первая строка
                end;
              //========================================================
                TTitleNumGrid = class(TTitleGrid)
                private
                  fPrecissions: byte;
                  fNumLastCol: byte;
                  fPrecLastCol: byte;
                protected
                  { Protected declarations }
                  procedure KeyPress(var Key: Char); override;
                  procedure DrawCell(ACol, ARow: Longint; ARect: TRect; AState: TGridDrawState);override;
                public
                  procedure Delete_Row(ARow:integer); override;
                published
                  property Precissions: byte read fPrecissions write fPrecissions;
                  property NumLastCol: byte read fNumLastCol write fNumLastCol;
                  property PrecLastCol: byte read fPrecLastCol write fPrecLastCol;
                end;
              //======================================================================
                                           {TNumComboGrid}
                TNumComboGrid = class(TTitleNumGrid)
                private
                  fCB_FirstCol: integer;
                  fCB_LastCol:  integer;
                  fCB_Items:    TStringList;
                  fCB:          TComboBox;
                  fCB_OfsX:     integer;    // Смещения для Rect, если fCB создается
                  fCB_OfsY:     integer;    // как AOwner, а не Self
                  Col_CB:       integer;        //Текущая колонка и столбец ComboBox
                  Row_CB:       integer;
                  procedure Set_CB_Items(const Value: TStringList);
                protected
                  { Protected declarations }
                  procedure FixObjPosn(vCol, vRow: LongInt);
                  function SelectCell(ACol, ARow: Longint): Boolean; override;
                  function Is_ColCombo(ACol:integer):boolean;
                  procedure CB_KeyDown(Sender: TObject; var Key: Word;Shift: TShiftState);
                  procedure CB_Change(Sender: TObject);
                  procedure CB_Enter(Sender: TObject);
                  procedure CB_Exit(Sender: TObject);
                  procedure DrawCell(ACol, ARow: Longint; ARect: TRect; AState: TGridDrawState);override;
                  procedure DoEnter; override;
                public
                  constructor Create(AOwner: TComponent); override;
                  destructor Destroy; override;
                  function Get_CB_Index(Str:string): Integer; // Индекс по строке
                published
                  property CB_FirstCol: integer read fCB_FirstCol write fCB_FirstCol;
                  property CB_LastCol: integer read fCB_LastCol write fCB_LastCol;
                  property CB_OfsX: integer read fCB_OfsX write fCB_OfsX;
                  property CB_OfsY: integer read fCB_OfsY write fCB_OfsY;
                  property CB_Items: TStringList read fCB_Items write Set_CB_Items;
                end;
               
              procedure Register;
               
              implementation  //******************************************************
              uses StrUtils,DesignIntf;
               
              procedure Register;
              begin
                RegisterComponents('Art', [TTitleGrid]);
                RegisterPropertyEditor(TypeInfo(string), TTitleGrid, 'Hint', nil);
                RegisterComponents('Art', [TTitleNumGrid]);
                RegisterComponents('Art', [TNumComboGrid]);
                //RegisterPropertyEditor(TypeInfo(string), TNumComboGrid, 'Hint', nil);
                //RegisterPropertyEditor(TypeInfo(LongInt), TNumComboGrid, 'RowCount', nil);
              end;
               
              constructor TTitleGrid.Create(AOwner: TComponent);
              begin
                inherited;
                Options:= Options+[goEditing]+[goTabs];
                fHints:= TStringList.Create;
                Old_Col:= -1; Old_Row:= -1;
                StyleCol0:= DT_LEFT;
              end;
               
              destructor TTitleGrid.Destroy;
              begin
                fHints.Free;
                inherited;
              end;
               
              procedure TTitleGrid.SetTitlesRow(Value: TStrings);
              var
                i:integer;
              begin
                for i:=1 to Value.Count-1 do
                  if i<RowCount then Cells[FixedCols-1,i]:= Value[i] else if Value[i]<>'' then begin
                    RowCount:= RowCount+1;
                    Cells[FixedCols-1,i]:= Value[i];
                  end;
              end;
               
              procedure TTitleGrid.SetTitlesCol(Value: TStrings);
              var
                i:integer;
              begin
                if Value.Count<ColCount then begin
                  for i:=ColCount-1 downto Value.Count+FixedRows do Cells[i,0]:='';
                end;
                for i:=0 to Value.Count-1 do
                  if i<ColCount then Cells[i,0]:= Value[i] else if Value[i]<>'' then begin
                    ColCount:= ColCount+1;
                    Cells[i,0]:= Value[i];
                  end;
              end;
               
              function TTitleGrid.GetTitlesRow: TStrings;
              begin
                result := Cols[FixedCols-1];
              end;
               
              function TTitleGrid.GetTitlesCol: TStrings;
              begin
                result := Rows[0];
              end;
               
              function TTitleGrid.GetFirstCol: Integer;
              begin
                result:= ColWidths[0];
              end;
               
              procedure TTitleGrid.SetFirstCol(const Value: Integer);
              begin
                ColWidths[0]:= Value;
              end;
              function TTitleGrid.GetFirstCol1: Integer;
              begin
                result:= ColWidths[FixedCols-1];
              end;
               
              procedure TTitleGrid.SetFirstCol1(const Value: Integer);
              begin
                ColWidths[FixedCols-1]:= Value;
                //if FixedCols=1 then
              end;
               
              procedure TTitleGrid.SetHints(const Value: TStringList);
              begin
                fHints.Assign(Value);
              end;
               
              procedure TTitleGrid.SetHintsOnCols(const Value: boolean);
              begin
                FHintsOnCols := Value;
              end;
              //=========== Рисование заголовков =====================
              procedure TTitleGrid.DrawCell(ACol, ARow: Integer; ARect: TRect;
                AState: TGridDrawState);
              var
                Flag: Cardinal;
                H: integer;
              begin
                Canvas.FillRect(ARect);
                Inc(ARect.Left,3);
                if (ARow=0) and (FixedRows=1) then begin
                  Dec(ARect.Right,3);
                  canvas.font.style:=canvas.font.style+[fsbold];
                  Flag:= DT_WORDBREAK or DT_CENTER;
                  H := DrawText(Canvas.Handle,PChar(Cells[ACol,Arow]),length(Cells[ACol,Arow]),ARect,Flag);
                  if H>RowHeights[0] then RowHeights[0] := H;  //увеличиваем
                end else if (ACol=FixedCols-1) then begin
                  canvas.font.style:=canvas.font.style+[fsbold];
                  if FixedCols=1 then Flag:= StyleCol0 else Flag:= DT_LEFT;
                end else if ACol=FixedCols-2 then begin
                  canvas.font.style:=canvas.font.style+[fsbold];
                  Flag:= DT_CENTER;
                end else begin
                  Flag:=DT_RIGHT;
                  Dec(ARect.Right,3);
                end;
                DrawText(Canvas.Handle,PChar(Cells[ACol,Arow]),length(Cells[ACol,Arow]),ARect,Flag);
                canvas.font.style:=canvas.font.style-[fsbold];
              end;
              //======== Перемещение м/у ячейками по клавише ENTER ========================
              procedure TTitleGrid.KeyPress(var Key: Char);
              begin
                if Key=#13 then begin
                  if Col < ColCount-1 then {следующая колонка!}
                    Col := Col + 1
                  else if Row < RowCount-1 then begin {следующая строка!}
                    Row := Row + 1;
                    Col := FixedCols;
                  end else begin {Конец сетки! - Снова перемещаемся наверх!}
                    Row := 1;
                    Col := 1;
                    // или передать управление следующему элементу управления
                    //Perform(WM_NEXTDLGCTL, 0, 0);
                  end;
                  Key:= #00;
                end;
                inherited;
              end;
              //=========== Показывает Hint для отдельной колонки(строки) ============
              procedure TTitleGrid.MouseMove(Shift: TShiftState; X, Y: Integer);
              var
                ACol,Arow:integer;
                s:string;
              begin
                inherited MouseMove(Shift,x,y);
                MouseToCell(x,y,ACol,ARow);
                if (fHintsOnCols and ((Old_Col<>ACol) and (ACol>FixedCols-1) and (fHints.Count>ACol)))
                  or (not fHintsOnCols and ((Old_Row<>ARow) and (ARow>FixedRows-1) and (fHints.Count>ARow))) then begin
                  Old_Col:= ACol; Old_Row:= ARow;
                  ShowHint:= false;
                  Application.CancelHint;
                  s:= fHints.Strings[ACol];
                  While Pos('@',s) <> 0 Do s[Pos('@',s)] := #13;
                  Hint:= s;
                  ShowHint:= true;
                end;
              end;
              //==== Удаление строки с соответствующим Hint-ом (при HintsOnCols=false) ===
              procedure TTitleGrid.Delete_Row(ARow: integer);
              var
                i:integer;
              begin
                if ARow>FixedRows-1 then for i:=Arow to RowCount-2 do begin
                  Rows[i]:= Rows[i+1];
                end;
                if not HintsOnCols and (fhints.Count>ARow) then fHints.Delete(ARow);
                RowCount:= RowCount-1;
              end;
              //======= Заполняет колонку № 0 номерами строки и меняет выравнивание на CENTER
              procedure TTitleGrid.Assign_NumRow;
              var
                i:integer;
              begin
                StyleCol0:= DT_CENTER;
                for i:=1 to RowCount-1 do Cells[0,i]:= IntToStr(i);
              end;
               
              {================== TTitleNumGrid ============================}
               
              procedure TTitleNumGrid.Delete_Row(ARow: integer);
              begin
                inherited;
              end;
               
              procedure TTitleNumGrid.DrawCell(ACol, ARow: Integer; ARect: TRect;
                AState: TGridDrawState);
              var
                r:real;
                s:string;
                p:byte;
              begin
                if (ACol>=FixedCols) and (ARow>=FixedRows) then begin
                  Canvas.FillRect(ARect);
                  s:=Cells[ACol,ARow];
                  if (s='') or (s=' ') then s:= '0';
                  try
                    r:=StrToFloat(s); if abs(r)<0.00001 then r:=0;
                    if ACol<=ColCount-fNumLastCol then p:= -fPrecissions else p:=-fPrecLastCol;
                    s:= FloatToStr(RoundTo(r,p));
                    dec(ARect.Right,3);
                    DrawText(Canvas.Handle,PChar(s),length(s),ARect,DT_RIGHT);
                  except
                    on EConvertError do exit;
                  end;
                end else inherited;
              end;
               
              procedure TTitleNumGrid.KeyPress(var Key: Char);
              begin
                if Key=',' then Key:= '.'
                else if not ((Key='.') or (Key='-') or ((Key>='0') and (Key<='9'))
                  or (Key=#13) or (Key=#08) or (Key=#09)) then begin Beep;Key:=#00; end;
               
                inherited;
              end;
               
              //========================= TNumComboGrid ================================
               
              constructor TNumComboGrid.Create(AOwner: TComponent);
              var
                i:integer;
              begin
                inherited;
                RowCount:= 2;
                fCB_Items:= TStringList.Create;
                fCB:= TComboBox.Create(Self {AOwner});
                fCB.Parent:= Self; //AOwner as TWinControl; //Self;
                //fCB.Style:= csDropDownList;
                    // Значения - ТОЛЬКО из списка, поиск по нескольким начальным
                    // буквам, а не по одной
                SendMessage(GetWindow(fCB.Handle,GW_CHILD), EM_SETREADONLY, 1, 0);
                fCB.Visible:= false;
                fCB.OnKeyDown:= CB_KeyDown;
                fCB.OnChange:= CB_Change;
                fCB.OnEnter:= CB_Enter;
                fCB.OnExit:= CB_Exit;
              end;
               
              destructor TNumComboGrid.Destroy;
              var
                i,j:integer;
              begin
                fCB_Items.Free;
                fCB.Free;
                inherited;
              end;
               
              procedure TNumComboGrid.CB_Change(Sender: TObject);
              begin
                //if (Col_CB<>0) and (Row_CB<>0) then
                  Cells[Col_CB,Row_CB]:= fCB.Items[fCB.Itemindex];
              end;
               
              procedure TNumComboGrid.CB_Enter(Sender: TObject);
              begin
                Col_CB:= Col; Row_CB:= Row;
              end;
               
              procedure TNumComboGrid.CB_Exit(Sender: TObject);
              begin
                if Col=Col_CB then if Col<ColCount-1 then
                fCB.Visible:= false;
                SelectCell(Col,Row);
              end;
               
              procedure TNumComboGrid.CB_KeyDown(Sender: TObject;var Key:Word; Shift: TShiftState);
              begin
                if (Key=VK_RETURN) or (Key=VK_TAB) or (Key=VK_RIGHT) or (Key=VK_LEFT) then begin
                  if (Key=VK_LEFT) or (ssShift in Shift) then begin
                    if Col_CB<=FixedCols then exit;
                    Col:= Col_CB-1;
                  end else begin
                    if Col_CB<ColCount-1 then Col:= Col_CB+1 else begin
                      Col:=1;
                      if Row_CB<RowCount-1 then Row:= Row_CB+1
                      else Perform(WM_NEXTDLGCTL, 0, 0);//Row:= FixedRows;
                    end;
                  end;
                  Key:= 0;
                  //fCB.Visible:= false;
                  SetFocus;
                end;
              end;
               
              function TNumComboGrid.SelectCell(ACol, ARow: Integer): Boolean;
              begin
                Result:= inherited SelectCell(ACol, ARow);
                if Is_ColCombo(ACol) then FixObjPosn(ACol, ARow);
              end;
               
              procedure TNumComboGrid.DoEnter;
              begin
                inherited;
                if ((Col=0) and (Row=0)) or ((Col=FixedCols) or (Row=FixedRows)) then
                  SelectCell(FixedCols,FixedRows) else SelectCell(Col,Row);
              end;
               
              procedure TNumComboGrid.DrawCell(ACol, ARow: Integer; ARect: TRect;
                AState: TGridDrawState);
              begin
                if Is_ColCombo(ACol) and (ARow>=FixedRows) then begin
                  Canvas.FillRect(ARect);
                  canvas.font.style:=canvas.font.style+[fsbold];
                  DrawText(Canvas.Handle,PChar(Cells[ACol,Arow]),length(Cells[ACol,Arow]),ARect,DT_LEFT);
                end else  inherited;
              end;
               
              procedure TNumComboGrid.FixObjPosn(vCol, vRow: Integer);
              var
                Rc: TRect;
              begin
                if Is_ColCombo(vCol) then begin
                  Rc := CellRect(vCol, vRow);
                  if Rc.Right = Rc.Left then {прямоугольник ячейки невидим}
                    fCB.Visible := False
                  else begin
                    InflateRect(Rc, -1, -1);
                    OffsetRect(Rc, Left + fCB_OfsX, Top + fCB_OfsY);
                    if fCB.Items.Count=0 then begin
                      fCB.Items.Assign(CB_Items);
                      fCB.DropDownCount:= CB_Items.Count+1;         // ReadOnly   0 - выключить
                      SendMessage(GetWindow(fCB.Handle,GW_CHILD), EM_SETREADONLY, 1, 0);
                    end;
                    fCB.BoundsRect := Rc;
                    fCB.ItemIndex:= fCB.Items.IndexOf(Cells[vCol,vRow]);
                    fCB.Visible := True;
                    fCB.SetFocus;
                  end;
                end;
              end;
               
              function TNumComboGrid.Get_CB_Index(Str: string): Integer;
              begin
                Result:= CB_Items.IndexOf(Str);
              end;
               
              function TNumComboGrid.Is_ColCombo(ACol: integer): boolean;
              var res:boolean;
              begin
                Res:= ((CB_FirstCol>0) and (CB_LastCol>0));
                Res:= (res and (ACol>=CB_FirstCol) and (ACol<=CB_LastCol));
                Result:= res;
              end;
               
              procedure TNumComboGrid.Set_CB_Items(const Value: TStringList);
              var
                i:integer;
              begin
                fCB_Items.Clear;
                for i:=0 to Value.Count-1 do fCB_Items.Add(Value.Strings[i]);
              end;
               
               
              end.
              0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
              0 пользователей:


              Рейтинг@Mail.ru
              [ Script execution time: 0,0381 ]   [ 16 queries used ]   [ Generated: 20.04.24, 00:08 GMT ]