Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2007.10.14;
Скачать: CL | DM;

Вниз

StringGrid выделять текст, но нельзя было редактировать   Найти похожие ветки 

 
Dmitry_177   (2007-07-28 19:25) [0]

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


 
Dmitry_177   (2007-07-28 19:28) [1]

выделять курсором имеется ввиду..


 
Lacmus ©   (2007-07-28 19:37) [2]



type
 TStringGridX = class(TStringGrid);

procedure TForm6.StringGrid1GetEditText(Sender: TObject; ACol, ARow: Integer;
 var Value: string);
begin
 TStringGridX(StringGrid1).InplaceEditor .ReadOnly := True
end;



 
Dmitry_177   (2007-07-28 19:48) [3]

у TStringGridX(StringGrid1).InplaceEditor нету ReadOnly..


 
Lacmus ©   (2007-07-28 19:59) [4]

Это рабочий код, только Delphi 2007.

Какое точное сообщение об ошибке ?


 
Lacmus ©   (2007-07-28 20:02) [5]

Еще вариант


type
 TStringGridX = class(TStringGrid);

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



 
Dmitry_177   (2007-07-28 20:09) [6]

пишет:

> [Error] Unit1.pas(2179): Undeclared identifier: "ReadOnly"


а обязательно этот TStringGridX использовать? чем обычный TStringGrid не подходит?

А так как в Lacmus ©   (28.07.07 20:02) [5]
AV


 
Dmitry_177   (2007-07-28 20:13) [7]

а не...!!! работает =))) спасибо, это я просто стормозил =) У меня StringGrid подругому называется, не StringGrid1 =)))

а насчет TStringGridX всеже интересно почему так..


 
Lacmus ©   (2007-07-28 20:15) [8]

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

>AV

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


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

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


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

есть

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


 
Lacmus ©   (2007-07-28 20:26) [10]

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


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

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


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

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

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;


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


 
Lacmus ©   (2007-07-29 10:58) [13]

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


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

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


 
Lacmus ©   (2007-07-29 14:18) [15]


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 15:13) [16]

спасибо! :)


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

раз уж идет разговор о 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;) как я показывал не работает..


 
Lacmus ©   (2007-07-29 20:58) [18]

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


  StringGrid1.RowHeights[1] := 150;


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

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

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 21:53) [20]

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

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

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

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

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

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


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

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


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

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

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


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

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

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

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

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

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


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

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

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 23:35) [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:53) [25]

я вроде как понял почему у меня так рисуется.. у меня есть некоторые и пустые ячейки.. естественно 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", то рисуются такие: "|" символы..


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

вот!

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;


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


 
Lacmus ©   (2007-07-30 13:19) [27]

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



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 13:59) [28]


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


откуда убрать? что-то не пойму..


 
Dmitry_177   (2007-07-30 16:38) [29]

работает :) Lacmus, огромнейшее тебе спасибо! :)


 
Dmitry_177   (2007-07-30 16:53) [30]

я еще нашел один небольшой глюг..

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


 
GrayFace ©   (2007-07-30 22:08) [31]

Dmitry_177   (30.07.07 0:36) [26]
работает :)

А не должно :) Если сделать ячейку (1,0) самой большой, она будет обрубаться.
Чтобы сделать чисто, надо хранить высоты всех ячеек и выбирать максимальную при изменении текста.

Lacmus ©   (30.07.07 13:19) [27]
Так делать нельзя. Надо нормально наследоваться. У меня от такого фокуса были Exception"ы в абсолютно неожиданном месте. Когда убрал, все стало нормально.


 
Dmitry_177   (2007-07-30 23:23) [32]

GrayFace, ну а что тогда компонент свой писать?


 
{RASkov} ©   (2007-07-31 03:01) [33]

> [0] Dmitry_177   (28.07.07 19:25)
> Можно ли какнибудь сделать так, чтобы текст в StringGrid-
> е, который находится в ячейках можно было бы выделять, но
> нельзя было бы редактировать?

> [1] Dmitry_177   (28.07.07 19:28)
> выделять курсором имеется ввиду..


ReadOnly Грид:
procedure TForm1.FormCreate(Sender: TObject);
var C, R: Integer;
begin
 for C := 0 to StringGrid1.ColCount-1 do
  for R := 0 to StringGrid1.RowCount-1 do StringGrid1.Cells[C, R]:=Format("[%d, %d]", [C, R]);
 StringGrid1.Options:=StringGrid1.Options+[goEditing];
end;

procedure TForm1.StringGrid1KeyPress(Sender: TObject; var Key: Char);
begin
  Key:=#0;
end;


Я всю ветку внимательно не читал, поэтому сорри, если это уже не нужно....


 
Lacmus ©   (2007-07-31 10:58) [34]

>GrayFace ©   (30.07.07 22:08) [31]

Вам плохая Delphi попалась.

>Dmitry_177   (30.07.07 16:53) [30]

Когда ячейка выделена, показывается TInplaceEditor и OnDrawCell действительно не работает, возможно поможет StringGrid1.HideEditor, StringGrid1.ShowEditor.


 
Dmitry_177   (2007-07-31 12:36) [35]


> возможно поможет StringGrid1.HideEditor, StringGrid1.ShowEditor.

что-то я не нашел у себя в StringGrid-е этого.. ни в свойствах ни в событиях..


 
Lacmus ©   (2007-07-31 12:48) [36]

Delphi?\Source\Vcl\Grids.pas

HideEditor, ShowEditor - это protected методы TCustomGrid


 
{RASkov} ©   (2007-07-31 12:56) [37]

Оказывается, что тут еще и многострочность нужна в Гриде...)
Dmitry_177
Имхо.... ответь положительно на свой вопрос в [32]....
Иначе это изврат... тем более, что при написании нового у тебя уже многое имеется, из этой ветки хотя-бы....
Тебе нужно переопределить ИнплэйЭдит, и немного поведение самого TStringGrid.... Это, имхо, будет куда лучше, чем извращатся над уже готовым, и для других целей, компонентом....


 
Dmitry_177   (2007-07-31 13:43) [38]


> Когда ячейка выделена, показывается TInplaceEditor и OnDrawCell
> действительно не работает, возможно поможет StringGrid1.
> HideEditor, StringGrid1.ShowEditor.


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


 
Dmitry_177   (2007-07-31 16:33) [39]

что-то у меня никак не получается..:(


 
Lacmus ©   (2007-07-31 16:46) [40]

with StringGrid1 do FocusCell(Col, Row, False)


 
Dmitry_177   (2007-07-31 17:36) [41]

не помогло..


 
Dmitry_177   (2007-07-31 17:37) [42]

строка всеравно выделенной остается..


 
Lacmus ©   (2007-07-31 17:43) [43]

В таблице обязательно должна быть выделена ячейка.
Можно скрыть редактор: HideEditor или EditorMode := False;


 
Dmitry_177   (2007-07-31 18:04) [44]

т.е. я как понял алгоритм такой?

1. HideEditor
2. загружаем строку
3. ShowEditor

по идее должен сработать OnDrawCell..


 
Lacmus ©   (2007-07-31 18:16) [45]



 StringGrid1.HideEditor;
 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";  // любая длинная строка
 Application.ProcessMessages;
 StringGrid1.ShowEditor;

или

 StringGrid1.HideEditor;
 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";  // любая длинная строка



 
Dmitry_177   (2007-07-31 18:56) [46]

вот так работает:
StringGrid1.HideEditor;
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";  // любая длинная строка
Application.ProcessMessages;
StringGrid1.ShowEditor;


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


 
Dmitry_177   (2007-07-31 19:21) [47]

спас InvalidateGrid:

StringGrid1.HideEditor;
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";  // любая длинная строка
Application.ProcessMessages;
StringGrid1.ShowEditor;
StringGrid1.InvalidateGrid;



Страницы: 1 2 вся ветка

Текущий архив: 2007.10.14;
Скачать: CL | DM;

Наверх




Память: 0.6 MB
Время: 0.024 c
15-1189683434
tytus
2007-09-13 15:37
2007.10.14
<Windows>+<R> rundll32 user32.dll,ExitWindowsEx 2,0 --????


1-1185553239
ins
2007-07-27 20:20
2007.10.14
TWebBrowser и правая кнопка мыши


15-1190004777
naumovmag
2007-09-17 08:52
2007.10.14
Работа с COM портами


2-1190010340
alshtam
2007-09-17 10:25
2007.10.14
Tstring list


3-1181563376
Sapos
2007-06-11 16:02
2007.10.14
Как правильно составить SQL запрос