Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

StringGrid выделять текст, но нельзя было редактировать [D7, WinXP]


Страницы:   1 2 3

Dmitry_177 ©   (2007-07-28 19:25:00) 

Можно ли какнибудь сделать так, чтобы текст в StringGrid-е, который находится в ячейках можно было бы выделять, но нельзя было бы редактировать?


Lacmus   (2007-07-30 13:19:00) [21]

>только мне не очень нравится то что если нажать на ячейку, т.е. выделить строку, как мы в начале этой темы обсуждали, то строка становится в одну строку, длинная-длинная... можно ли это как-то исправить?



unit Unit7;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, Grids;

type
 TStringGridX = class(TStringGrid)
 protected
   function CreateEditor: TInplaceEdit; override;
 end;

 TStringGrid = class(TStringGridX);

 TForm7 = class(TForm)
   StringGrid1: TStringGrid;
   procedure FormCreate(Sender: TObject);
   procedure StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
     Rect: TRect; State: TGridDrawState);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

var
 Form7: TForm7;

implementation

{$R *.dfm}

type
 TInplaceEditX = class(TInplaceEdit)
 protected
   procedure CreateParams(var Params: TCreateParams); override;
 end;

procedure TInplaceEditX.CreateParams(var Params: TCreateParams);
begin
 inherited CreateParams(Params);
 Params.Style := (Params.Style or ES_MULTILINE or ES_READONLY) and not ES_AUTOHSCROLL
end;

function TStringGridX.CreateEditor: TInplaceEdit;
begin
 Result := TInplaceEditX.Create(Self)
end;



Повторное объявление TStringGridX убрать.


Dmitry_177   (2007-07-30 00:36:00) [22]

вот!

procedure TForm6.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
                                  Rect: TRect; State: TGridDrawState);
var
 iHeight: Integer;
 TextRect: TRect;
begin
 if ACol = 1 then
   if ARow = 1 then
     begin
       TextRect := Rect;
       iHeight := DrawText(StringGrid1.Canvas.Handle, PChar(StringGrid1.Cells[ACol, ARow]), Length(StringGrid1.Cells[ACol, ARow]), TextRect, DT_CALCRECT or DT_WORDBREAK);
       if iHeight > StringGrid1.DefaultRowHeight then
         begin
           StringGrid1.RowHeights[ARow] := iHeight + 4;
            StringGrid1.Canvas.FillRect(Rect);
           DrawText(StringGrid1.Canvas.Handle, PChar(StringGrid1.Cells[ACol, ARow]), Length(StringGrid1.Cells[ACol, ARow]), Rect, DT_WORDBREAK);
         end;
     end;
end;


работает :) только мне не очень нравится то что если нажать на ячейку, т.е. выделить строку, как мы в начале этой темы обсуждали, то строка становится в одну строку, длинная-длинная... можно ли это как-то исправить?


Dmitry_177   (2007-07-29 23:53:00) [23]

я вроде как понял почему у меня так рисуется.. у меня есть некоторые и пустые ячейки.. естественно iHeight будет нулю равен.. и таблица сужается.. сделал так:

procedure TForm6.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
                                   Rect: TRect; State: TGridDrawState);
var
iHeight: Integer;
TextRect: TRect;
begin
if ACol = 1 then
  if ARow = 1 then begin
    TextRect := Rect;
    iHeight := DrawText(StringGrid1.Canvas.Handle, PChar(StringGrid1.Cells[ACol, ARow]), Length(StringGrid1.Cells[ACol, ARow]), TextRect, DT_CALCRECT or DT_WORDBREAK);
       if iHeight > StringGrid1.DefaultRowHeight then
         begin
           StringGrid1.RowHeights[ARow] := iHeight + 4;
           DrawText(StringGrid1.Canvas.Handle, PChar(StringGrid1.Cells[ACol, ARow]), Length(StringGrid1.Cells[ACol, ARow]), Rect, DT_WORDBREAK);
         end;
  end;
end;


вроде нормуль.. только почему-то где есть перевод строки на новую, т.е. '#13', то рисуются такие: " |" символы..


Lacmus   (2007-07-29 23:35:00) [24]

Без учета Lacmus ©   (29.07.07 21:53) [20]

procedure TForm6.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
                                    Rect: TRect; State: TGridDrawState);
var
 iHeight: Integer;
 TextRect: TRect;
begin
 if ACol = 1 then
   if ARow = 1 then begin
     TextRect := Rect;
     iHeight := DrawText(StringGrid1.Canvas.Handle, PChar(StringGrid1.Cells[ACol, ARow]), Length(StringGrid1.Cells[ACol, ARow]), TextRect, DT_CALCRECT or DT_WORDBREAK);
     StringGrid1.RowHeights[ARow] := iHeight;
     DrawText(StringGrid1.Canvas.Handle, PChar(StringGrid1.Cells[ACol, ARow]), Length(StringGrid1.Cells[ACol, ARow]), Rect, DT_WORDBREAK);
   end
end;


Dmitry_177   (2007-07-29 23:16:00) [25]

Код практически не изменился..

procedure TForm1.FormCreate(Sender: TObject);
begin
StringGrid1.Cells[1, 1] := 'fef ewfve few f ewf ewf e wf cv rt4f vr gfv erw gvreg vw wgh trvgh wtv g r vwergvrewgvvebrgvwer gvw v grw ergv wvgwgv r gvwerg re';  // любая длинная строка
end;

procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);
var
iHeight: Integer;
begin
if ACol = 1 then
 if ARow = 1 then
   begin
     iHeight := DrawText(StringGrid1.Canvas.Handle, PChar(StringGrid1.Cells[ACol, ARow]), Length(StringGrid1.Cells[ACol, ARow]), Rect, DT_CALCRECT or DT_WORDBREAK);
     StringGrid1.RowHeights[ARow] := iHeight;
      StringGrid1.Canvas.FillRect(Rect);
     DrawText(StringGrid1.Canvas.Handle, PChar(StringGrid1.Cells[ACol, ARow]), Length(StringGrid1.Cells[ACol, ARow]), Rect, DT_WORDBREAK);
   end;
end;


Lacmus   (2007-07-29 22:51:00) [26]

>пробовал FillRect, не помогло..

Какой сейчас код ?

>т.е. выделить так: SendMessage(TStringGridX(StringGrid1).InplaceEditor.Handle, EM_SETREADONLY, 1, 0); уже не получится?

Устанавливает запрет изменения текста, WordWrap - перенос по словам.

>ColWidths мне какраз не надо менять..
DrawText возвращает Rect с шириной > ColWidths[1]


Dmitry_177   (2007-07-29 22:15:00) [27]

пробовал FillRect, не помогло..


> Редактор грида (InplaceEditor) показывается с WordWrap =
> False, т.е. текст будет в одну строку.

т.е. выделить так: SendMessage(TStringGridX(StringGrid1).InplaceEditor.Handle, EM_SETREADONLY, 1, 0);уже не получится?

ColWidths мне какраз не надо менять..


Lacmus   (2007-07-29 21:53:00) [28]

Возможно, поможет ACanvas.FillRect(Rect);

но на этом проблемы не закончатся,

DrawText c DT_CALCRECT, вычисляет как высоту, так и ширину, то есть необходимо будет менять и ColWidths,

Редактор грида (InplaceEditor) показывается с WordWrap = False, т.е. текст будет в одну строку.

Менять ColWidths и RowHeights необходимо менять только, если текст не помещяется в ячейку.

Возможно, есть бесплатные гриды с требуемой функциональностью, из платных можно посоветовать TdxTreeList, TcxTreeList ( http://www.devexpress.com)


Dmitry_177   (2007-07-29 21:13:00) [29]

что-то не то.. у меня пол таблицы исчезло, а линии между строками почему-то ОЧЕНЬ жирными стали..

procedure TForm1.FormCreate(Sender: TObject);
begin
StringGrid1.Cells[1, 1] := 'fef ewfve few f ewf ewf e wf cv rt4f vr gfv erw gvreg vw wgh trvgh wtv g r vwergvrewgvvebrgvwer gvw v grw ergv wvgwgv r gvwerg re';  // любая длинная строка
end;

procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);
var
iHeight: Integer;
begin
if ACol = 1 then
  if ARow = 1 then
    begin
      iHeight := DrawText(StringGrid1.Canvas.Handle, PChar(StringGrid1.Cells[ACol, ARow]), Length(StringGrid1.Cells[ACol, ARow]), Rect, DT_CALCRECT or DT_WORDBREAK);   // подсчитываем высоту
      StringGrid1.RowHeights[ARow] := iHeight;
      DrawText(StringGrid1.Canvas.Handle, PChar(StringGrid1.Cells[ACol, ARow]), Length(StringGrid1.Cells[ACol, ARow]), Rect, DT_WORDBREAK);  // выводим строку
    end;
end;


Lacmus   (2007-07-29 20:58:00) [30]

>подскажите как мне программно задать высоту ячейки?


  StringGrid1.RowHeights[1] := 150;


Dmitry_177   (2007-07-29 19:03:00) [31]

раз уж идет разговор о StringGrid.. спрошу еще про него :) Мне нужно сделать многострочность с авто-маштабированием, т.е. изменять высоту ячеки в зависимости от высоты многострочного текста.. Делаю я так:

procedure TForm1.FormCreate(Sender: TObject);
begin
 StringGrid1.Cells[1, 1] := 'fef ewfve few f ewf ewf e wf cv rt4f vr gfv erw gvreg vw wgh trvgh wtv g r vwergvrewgvvebrgvwer gvw v grw ergv wvgwgv r gvwerg re';  // любая длинная строка
end;

procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
 Rect: TRect; State: TGridDrawState);
var
 iHeight: Integer;
begin
 if ACol = 1 then
   if ARow = 1 then
     begin
       iHeight := DrawText(StringGrid1.Canvas.Handle, PChar(StringGrid1.Cells[ACol, ARow]), Length(StringGrid1.Cells[ACol, ARow]), Rect, DT_CALCRECT or DT_WORDBREAK);   // подсчитываем высоту
       Rect.Bottom := Rect.Left + iHeight;  // а вот как изменить высоту ячейки? так не работает..
       DrawText(StringGrid1.Canvas.Handle, PChar(StringGrid1.Cells[ACol, ARow]), Length(StringGrid1.Cells[ACol, ARow]), Rect, DT_WORDBREAK);  // выводим строку
     end;
end;


подскажите как мне программно задать высоту ячейки? а то так(Rect.Bottom := Rect.Left + iHeight;) как я показывал не работает..


Dmitry_177   (2007-07-29 15:13:00) [32]

спасибо! :)


Lacmus   (2007-07-29 14:18:00) [33]


procedure TForm6.StringGrid1MouseDown(Sender: TObject; Button: TMouseButton;
 Shift: TShiftState; X, Y: Integer);
var
 GridCoord: TGridCoord;
begin
 if Button = mbRight then begin
   GridCoord := StringGrid1.MouseCoord(X, Y);
   if (GridCoord.X >= StringGrid1.FixedCols) and (GridCoord.Y >= StringGrid1.FixedRows) then begin
     TStringGridX(StringGrid1).FocusCell(GridCoord.X, GridCoord.Y, True);
     with TStringGridX(StringGrid1), ClientToScreen(Point(X, Y)) do
       SendMessage(InplaceEditor.Handle, WM_CONTEXTMENU, InplaceEditor.Handle, MakeLong(X, Y))
   end
 end
end;


Dmitry_177   (2007-07-29 13:42:00) [34]

подскажите еще пожалуйста, как можно сделать чтобы строка в ячейке также выделялась, по нажатию правойкнопкой мыши и плюс еще меню раскрывалось, которое всегда раскрывается при редактировании текста(ИМХО системный popup: копировать, вставить и т.д..)


Lacmus   (2007-07-29 10:58:00) [35]

[DCC Error] Unit6.pas(81): E2059 Local class, interface or object types not allowed - сообщение, по-моему, все объясняет


Dmitry_177   (2007-07-29 00:45:00) [36]

интересно еще вот что, то что сделав так:

procedure TForm6.StringGrid1GetEditText(Sender: TObject; ACol, ARow: Integer;
var Value: string);
type
 TStringGridX = class(TStringGrid);
begin
 SendMessage(TStringGridX(StringGrid1).InplaceEditor.Handle, EM_SETREADONLY, 1, 0);
end;


почему то даже не компилируется, а если так же, в самой процедуре или функции определять какие-нибудь другие типы, точнее структуры, а не объекты, то все нормально и работает... вот интересно почему так..


Dmitry_177   (2007-07-28 20:29:00) [37]

есть, спасибо большое! =)


Lacmus   (2007-07-28 20:26:00) [38]

TStringGrid.Options - goAlwaysShowEditor, если есть.


Dmitry_177   (2007-07-28 20:21:00) [39]

уже все работает, это моя ошибка была.. =)


> Событие TStringGrid.OnGetEditText есть ?

есть

а можно ли сделать еще так, чтобы при нажатии курсором на ячейку, чтобы сразу выделялась строка, а не по двойному?


Lacmus   (2007-07-28 20:15:00) [40]

> а обязательно этот TStringGridX использовать?
В Delphi 2007, да. InplaceEditor в секции protected.

>AV

Событие TStringGrid.OnGetEditText есть ? или в другое событие поместили код ?


Страницы:   1 2 3

Наверх

Титульная страница Поиск, карта сайта Написать письмо