Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2005.03.20;
Скачать: [xml.tar.bz2];

Вниз

Проблемы со StringGrid ом! С многострочностью не клеится...   Найти похожие ветки 

 
syscoder   (2005-03-06 18:56) [0]

Как правильно реализовать многострочность в ячейке StringGrid"а. Перепробовал несколько примеров, а в итоге никакого правильного результата. Приведу пару примеров обработчика OnDrawCell:
[-1-]
Format := DT_LEFT or DT_WORDBREAK;
SGmem.Canvas.FillRect(Rect);
StrPCopy(C, SGmem.Cells[ACol, ARow]);
DrawText(SGmem.Canvas.Handle, C, StrLen(C), Rect, Format);


Во время добавлении строк в таблицу делаю так:
SGmem.Cells[1,indxMemRow] := StrFM_gap.Strings[0];
StrFM_gap.Delete(0);
SGmem.Cells[2,indxMemRow] := SGmem.Cells[2,indxMemRow] + StrFM_gap.Text;
// если кол-во строк в ячейке больше её высоты
if (SGmem.canvas.TextHeight(SGmem.Cells[2,indxMemRow])*2) > SGmem.RowHeights[indxMemRow] then
// то делаем высоту ячейки во столько раз больше, сколько этих строк
SGmem.RowHeights[indxMemRow] := SGmem.canvas.TextHeight(SGmem.Cells[2,indxMemRow])*(StrFM_gap.Count-1)+20;


В этом случае возникает какой-то глюк в обработчике OnDrawCell при добавлении большого количества строк. Прога просто напросто закрывается без всяких ошибок, а в Дельфях пишет AV.
В чём тут дело?

[-2-]
S := SGmem.Cells[ACol,ARow];
if gdSelected in State then
begin
 SGmem.Canvas.Brush.Color := clInactiveCaptionText;
 SGmem.Canvas.FillRect(Rect);
end;
Inc(Rect.Top, 2);
Dec(Rect.Bottom, 2);
Inc(Rect.Left, 2);
Dec(Rect.Right, 2);
DrawText(SGmem.Canvas.Handle, pChar(S), Length(S), Rect, DT_LEFT or DT_WORDBREAK);


Попробовал так, при таком же методе заполнения строк. Работает лучше! НО, никак не могу докумекать до одной фишки. Дело в том, что тект разбивается на строки, но в ячейке получается такая лажа: в первой строке ячейки добавляется вся остальная строка, разбитая ниже на строки, а когда выделяешь ячейку, то она отсекается и становиться всё пучком,... пока не сдвинешь на другую ячейку. Вот так.

Помогите кто шарит в этом деле, срочно нужно, я уже сегодня весь день у компа торчу, уже недумается...


 
ShimON ©   (2005-03-06 19:07) [1]

procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow:
 Integer;
 Rect: TRect; State: TGridDrawState);
var
 Format: Word;
 C: array[0..255] of Char;
begin
 Format := DT_LEFT or DT_WORDBREAK;
 (Sender as TStringGrid).Canvas.FillRect(Rect);
 StrPCopy(C, (Sender as TStringGrid).Cells[ACol, ARow]);
 WinProcs.DrawText((Sender as TStringGrid).Canvas.Handle, C,
   StrLen(C), Rect, Format);
end;


 
ShimON ©   (2005-03-06 19:10) [2]

Сперва необходимо установить свойство DefaultDrawing в False. Далее, необходимо вставить следующий код в обработчик события OnDrawCell:

procedure TForm1.StringGrid1DrawCell(Sender: TObject;
 Col, Row: Longint;
 Rect: TRect;
 State: TGridDrawState);
var
 Line1: string;
 Line2: string;
 ptr: integer;
 padding: integer;
 hGrid: TStringGrid;

begin
 hGrid := (Sender as TStringGrid);
 ptr := Pos(";", hGrid.Cells[Col, Row]);
 if ptr > 0 then
 begin
   Line1 := Copy(hGrid.Cells[Col, Row], 1, ptr - 1);
   Line2 := Copy(hGrid.Cells[Col, Row], ptr + 1,
     Length(hGrid1.Cells[Col, Row]) - ptr);
 end
 else
   Line1 := hGrid.Cells[Col, Row];
 hGrid.Canvas.FillRect(Rect);
 hGrid.Canvas.TextOut(Rect.Left, Rect.Top + 2, Line1);
 if ptr > 0 then
   hGrid.Canvas.TextOut(Rect.Left, Rect.Top -
     hGrid.Canvas.Font.Height + 3, Line2);
end;
Теперь достаточно для переноса строки вставить в неё точку с запятой. Так же не забудьте изменить высоту строки так, чтобы переносы строки поместились в ячейку:

StringGrid1.RowHeights[0] := StringGrid1.DefaultRowHeight * 2;


 
ShimON ©   (2005-03-06 19:11) [3]

И еще большая куча других, так что если это не подойдет, скажи, дам еще


 
syscoder   (2005-03-06 19:21) [4]

>> ShimON ©   (06.03.05 19:11) [3]
О-О-О-О!! Эти примеры я уже перелопатил. Реализация у них хреновая, да и не работают они. Кстати первый ваш пример аналогичен моему и выдран, наверное, из тех же FAQ. Проблему-то он не решает!!!


 
ShimON ©   (2005-03-06 19:53) [5]

У меня сборник из многих факов,  так что может другие подойдут??


 
syscoder   (2005-03-06 20:03) [6]

>> ShimON ©   (06.03.05 19:53) [5]
У меня сборник из многих факов,  так что может другие подойдут??


Дык у меня тоже не хилый сборничек скопился. Никогда просто с этим гридом не работал, а тут пришлось возиться.
Если не затруднит, то подкинте что-нибудь из вашего, посмотрим...


 
ShimON ©   (2005-03-06 20:09) [7]

procedure TForm1.grid1DrawCell(Sender: TObject; Col, Row: Longint;
  Rect: TRect; State: TGridDrawState);

 var l_oldalign : word;
     l_YPos,l_XPos,i : integer;
     s,s1 : string;
     l_col,l_row :longint;

begin
  l_col := col;
  l_row := row;
  with sender as tstringgrid do
  begin
    if (l_row=0) then
      canvas.font.style:=canvas.font.style+[fsbold];
    if l_row=0 then
    begin
      l_oldalign:=settextalign(canvas.handle,ta_center);
      l_XPos:=rect.left + (rect.right - rect.left) div 2;
      s:=cells[l_col,l_row];
      while s<>"" do
      begin
        if pos(#13,s)<>0 then
        begin
          if pos(#13,s)=1 then
            s1:=""
          else
          begin
            s1:=trim(copy(s,1,pred(pos(#13,s))));
            delete(s,1,pred(pos(#13,s)));
          end;
          delete(s,1,2);
        end
        else
        begin
          s1:=trim(s);
          s:="";
        end;
        l_YPos:=rect.top+2;
        canvas.textrect(rect,l_Xpos,l_YPos,s1);
        inc(rect.top,rowheights[l_row] div 3);
      end;
      settextalign(canvas.handle,l_oldalign);
    end
    else
    begin
       canvas.textrect(rect,rect.left+2,rect.top+2,cells[l_col,l_row]);
    end;

    canvas.font.style:=canvas.font.style-[fsbold];
  end;
end;


 
ShimON ©   (2005-03-06 20:11) [8]

Это тоже может помочь - только для заголовков, на сколько я понял..
TFTVerticalAlignment = (vaTop, vaMiddle, vaBottom);

procedure DrawTextAligned(const Text: string; Canvas: TCanvas; ъ
 var Rect: TRect; Alignment: TAlignment; VerticalAlignment:
 TFTVerticalAlignment; WordWrap: Boolean);
var
 P: array[0..255] of Char;
 H: Integer;
 T: TRect;
 F: Word;
begin
 StrPCopy(P, Text);
 T := Rect;
 with Canvas, Rect do
 begin
   F := DT_CALCRECT or DT_EXPANDTABS or DT_VCENTER or
     TextAlignments[Alignment];
   if WordWrap then
     F := F or DT_WORDBREAK;
   H := DrawText(Handle, P, -1, T, F);
   H := MinInt(H, Rect.Bottom - Rect.Top);
   if VerticalAlignment = vaMiddle then
   begin
     Top := ((Bottom + Top) - H) div 2;
     Bottom := Top + H;
   end
   else if VerticalAlignment = vaBottom then
     Top := Bottom - H - 1;
   F := DT_EXPANDTABS or DT_VCENTER or TextAlignments[Alignment];
   if WordWrap then
     F := F or DT_WORDBREAK;
   DrawText(Handle, P, -1, Rect, F);
 end;
end;


 
KSergey ©   (2005-03-06 20:29) [9]

> [-2-]
> S := SGmem.Cells[ACol,ARow];
> if gdSelected in State then
> begin
>  SGmem.Canvas.Brush.Color := clInactiveCaptionText;
>  SGmem.Canvas.FillRect(Rect);
> end;
...

Почему чистим ячейку только в случае ее выделения?? Может все же правильнее FillRect вынести из if?


 
Юрий Зотов ©   (2005-03-06 20:48) [10]

Может, и я на что сгожусь?

type
 TForm1 = class(TForm)
   Edit1: TEdit;
   AddButton: TButton;
   StringGrid1: TStringGrid;
   procedure FormCreate(Sender: TObject);
   procedure Edit1Change(Sender: TObject);
   procedure Edit1KeyPress(Sender: TObject; var Key: Char);
   procedure AddButtonClick(Sender: TObject);
   procedure StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
     Rect: TRect; State: TGridDrawState);
 private
   FRow: integer;
   FCol: integer;
   procedure AdjustRowHeight;
 end;

procedure TForm1.AdjustRowHeight;
var
 S: string;
 R: TRect;
begin
 with StringGrid1 do
 begin
   S := Cells[FCol, FRow];
   if S = "" then
     S := "!";
   R := CellRect(FCol, FRow);
   InflateRect(R, -2, -2);
   DrawText(Canvas.Handle, PChar(S), Length(S), R, DT_WORDBREAK or DT_CALCRECT);
   RowHeights[FRow] := R.Bottom - R.Top + 2
 end
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
 AdjustRowHeight;
 FCol := -1
end;

procedure TForm1.Edit1Change(Sender: TObject);
begin
 AddButton.Enabled := Edit1.Text <> ""
end;

procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
begin
 if Key = #13 then
 begin
   Key := #0;
   AddButtonClick(Sender)
 end
end;

procedure TForm1.AddButtonClick(Sender: TObject);
begin
 with StringGrid1 do
 begin
   Inc(FCol);
   if FCol = ColCount then
   begin
     RowCount := RowCount + 1;
     FCol := 0;
     FRow := RowCount - 1
   end;
   Cells[FCol, FRow] := Edit1.Text;
   AdjustRowHeight;
   Edit1.SetFocus
 end
end;

procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
 Rect: TRect; State: TGridDrawState);
var
 S: string;
begin
 with StringGrid1, Canvas do
 begin
   if gdSelected in State then
   begin
     Brush.Color := clHighlight;
     Font.Color := clHighlightText;
   end
   else
     begin
       Brush.Color := clWindow;
       Font.Color := clWindowText
     end;
   FillRect(Rect);
   InflateRect(Rect, -2, -2);
   S := Cells[ACol, ARow];
   DrawText(Canvas.Handle, PChar(S), Length(S), Rect, DT_WORDBREAK)
 end
end;


А это файл DFM:

object Form1: TForm1
 Left = 229
 Top = 137
 Width = 699
 Height = 552
 BorderIcons = [biSystemMenu]
 Caption = "Form1"
 Color = clBtnFace
 Font.Charset = DEFAULT_CHARSET
 Font.Color = clWindowText
 Font.Height = -13
 Font.Name = "MS Sans Serif"
 Font.Style = []
 OldCreateOrder = False
 OnCreate = FormCreate
 DesignSize = (
   691
   518)
 PixelsPerInch = 120
 TextHeight = 16
 object Edit1: TEdit
   Left = 0
   Top = 0
   Width = 692
   Height = 24
   Anchors = [akLeft, akTop, akRight]
   TabOrder = 0
   OnChange = Edit1Change
   OnKeyPress = Edit1KeyPress
 end
 object AddButton: TButton
   Left = 8
   Top = 30
   Width = 75
   Height = 25
   Caption = "Add"
   Enabled = False
   TabOrder = 1
   OnClick = AddButtonClick
 end
 object StringGrid1: TStringGrid
   Left = 0
   Top = 60
   Width = 691
   Height = 458
   Anchors = [akLeft, akTop, akRight, akBottom]
   DefaultDrawing = False
   FixedCols = 0
   RowCount = 1
   FixedRows = 0
   Options = [goFixedVertLine, goFixedHorzLine, goVertLine, goHorzLine, goColSizing]
   TabOrder = 2
   OnDrawCell = StringGrid1DrawCell
 end
end


 
syscoder   (2005-03-06 21:24) [11]

>> Юрий Зотов ©   (06.03.05 20:48) [10]

Вот это да-а-а-а! Весомый аргумент вы привели. Это уже годится, благодарю вас за помощь.

Также спасибо за свой предложения и критику в мою сторону других участников этой ветки.

Мне кстати посоветовали воспользоваться AdvStringGrid"ом с сайта
www.tmssoftware.com. В этом компоненте, говорят, это реализованно без глюков.



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

Форум: "Основная";
Текущий архив: 2005.03.20;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.5 MB
Время: 0.036 c
14-1109862873
Opilki_Inside
2005-03-03 18:14
2005.03.20
Как работать с Remote Desktop через прокси?


1-1109775906
Anatoliy T.
2005-03-02 18:05
2005.03.20
Word - форматирование абзаца


14-1109743012
Думкин
2005-03-02 08:56
2005.03.20
Живой и разговаривающий я


3-1108732968
DSKalugin
2005-02-18 16:22
2005.03.20
Кодировка DOS в Paradox4.5


4-1107707452
Локли
2005-02-06 19:30
2005.03.20
Уровень звука





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский