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

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

Canvas.TextWidth вешает программу.


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

Kolan ©   (2007-02-05 14:58:00) 

Написал функцию для "подгонки" ширины столбцов StringGrid:
procedure TReportGrid.AdjustColWidth;
var
 WidthArr: array of Integer;
 I, J: Integer;
begin
 with MainForm.ReportStringGrid do
 begin
   SetLength(WidthArr, ColCount);
   for I := Low(WidthArr) to High(WidthArr) do
     WidthArr[I] := 0;
   for I := 0 to ColCount - 1 do
     for J := 0 to Cols[I].Count - 1 do
        if Canvas.TextWidth(Cols[I].Strings[J]) > WidthArr[I] then
         WidthArr[I] := Canvas.TextWidth(Cols[I].Strings[J]);

   for I := 0 to ColCount - 1 do
     ColWidths[I] := WidthArr[I]+8;
 end;
end;


Удивительным образом, когда идешь отладчиком, на выделеной строчке все останавливается.
Причем процессор не грузит, ничего. Как все равно что в занятую крит секцию попасть...

Почему?
ЗЫ
 Есть подозрегие что глючит BDS.
ЗЗЫ
 Утечек нет. ReportMemoryLeaks стоит.


Kolan   (2007-02-10 15:54:00) [1]

«Но изначально ты (давай уж на ты) говорил, что выделяешь
логически связанные операции в один класс, а не о наличии
нескольких стратегий.»

Изначально вопрос другой вообще был.

«„Рефакторинг: улучшение существующего кода“?»

Угу


«А вот обращение к глобальной переменной Form1 явно ухудшает „запах“ кода.»

Наверно обращение к синглетону вообще грех :)


«А сделать FieldMessageCallBack методом формы?»

А что будешь делать если надо на 10 формах отобразить? Кто то все равно будет знать о всех 10 формах. :)


«а не о наличии нескольких стратегий»

Стратегии привел чтобы было понятно, что объект напрямую недоступен.

Да спорить неохота дальше. Решение неплохое имхо…


GrayFace   (2007-02-10 12:09:00) [2]

Kolan ©   (09.02.07 9:46) [62]
Прочтите Фаулера про "запахи в коде".

"Рефакторинг: улучшение существующего кода"?

Kolan ©   (09.02.07 9:46) [62]
Комментарии там на первом месте.

Конечно, бессмысленные комментарии - большое зло, но к предлагаемым они не имеют никакого отношения. А вот обращение к глобальной переменной Form1 явно ухудшает "запах" кода.

Kolan ©   (09.02.07 15:54) [65]
Говорит о том, что модуль с TC знает о форме.

А сделать FieldMessageCallBack методом формы?
Но изначально ты (давай уж на ты) говорил, что выделяешь логически связанные операции в один класс, а не о наличии нескольких стратегий.


Kolan   (2007-02-09 15:55:00) [3]

> SomeEdit.Text := AMessage;
> Говорит о том, что модуль с TC знает о форме.

Вот еще довод:

А если бы я еще в 10 форм выводил.
У тебя их все тоже поключать пришлось.

У меня как был 1 модуль с оберткой подключен так и осталось....


Kolan   (2007-02-09 15:54:00) [4]

procedure TC.FieldMessageCallBack(AMessage: String);
begin
SomeEdit.Text := AMessage;
end;


Вот где вся суть разговора. Про существование событий я ессно в курсе.

SomeEdit.Text := AMessage;
Говорит о том, что модуль с TC знает о форме. Кроме того я хотел не просто добавить строку в эдит, а еще доавить
её в РичЭдит, да еще было бы неплохо подкрасить её.

И по твоему бедный переключатель стратегий(ТС) будет в себе содержать всю эту левую дрянь(типа функция изменения цвета итд).

А я предлогаю делать тоже самое + всю работу с интерфейсом скрывать за оберткой.

Итого:
У тебя:
procedure TC.FieldMessageCallBack(AMessage: String);
begin
SomeEdit.Text := AMessage;
RichEdit.Lines.Add(AMessage);
{Алгоритм раскрашивания этой строки в красный цвет. Это как пример.}
{А может я захочу еще BaloonTip показать. Тоже все тут.}
end;


У меня:
procedure TC.FieldMessageCallBack(AMessage: String);
begin
 UIInfoBlock.Add(AMessge);
end;


Способ отображения скрыт за оберткой. Какой бы сложный он небыл он всеь там.

А если теперь представить, что несколько объектов могут выводить эту строку. То тебе придется каждый раз этот вывод делать(в итоге duplicate code).
А у меня все в 1 месте. кому надо тот и вызывает...

ЗЫ
 Благодарю за спор :). выходит незря я так делаю... :)


Apollon604   (2007-02-09 13:39:00) [5]


> Kolan ©   (09.02.07 11:50) [63]
> > GrayFace ©Ну дык какие предложения?



interface

type

 TMessageCallBack = procedure(AMessage: String) of Object;

 TA = class
 private
   fMesCallBack: TMessageCallBack;
   ...
 public
   procedure Run;
   property MessageCallBack: TMessageCallBack read fMesCallBack write fMesCallBack;
   ...
 end;

 TB = class
 private
   fMesCallBack: TMessageCallBack;
   ...
 public
   procedure Run;
   property MessageCallBack: TMessageCallBack read fMesCallBack write fMesCallBack;
   ...
 end;

 TC = class
 private
   fA: TA;
   fB: TB;
   procedure FieldMessageCallBack(AMessage: String);
   ...
 public
   constructor Create;
   destructor Destroy;
   ...
 end;

implementation

{ TA }

procedure TA.Run;
begin
 ...
 if Assigned(fMesCallBack) then
   fMesCallBack('DCAB');
 ...
end;

{ TB }

procedure TB.Run;
begin
 ...
 if Assigned(fMesCallBack) then
   fMesCallBack('DCAB');
 ...
end;

{ TC }

constructor TC.Create;
begin
 fA := TA.Create;
 fA.MessageCallBack := FieldMessageCallBack;

 fB := TB.Create;
 fB.MessageCallBack := FieldMessageCallBack;
 ...
end;

destructor TC.Destroy;
begin
 fA.Free;
 fB.Free;
 ...
end;

procedure TC.FieldMessageCallBack(AMessage: String);
begin
 SomeEdit.Text := AMessage;
end;


В твоем случае TC - это и есть твоя главная форма. TA и TB ничего о ней не знают, а знают толко, что в определенный момент они должны передать сообщение в MessageCallBack.


Kolan   (2007-02-09 11:50:00) [6]

> GrayFace ©

Ну дык какие предложения?


Kolan   (2007-02-09 09:46:00) [7]

> [61] GrayFace ©   (09.02.07 01:27)
> Точнее, не можно, а нужно.

Блин, хотел промолчать...ну ладно.

Итак допустим Имеем паттерн стратегия. Есть 3 класса ТА и ТВ - стратегии, ТС - класс, который позволяет выбрать одну из них.

Те доступ к стратегии осушествляется только через экземпляр ТС.

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

Мой вариант:
Делаю обертку
ТОбертка = класс
 процедура ДобавитьСообщение(С: строка);
энд;


В нутри ДобавитьСообщениезаписываю строку в Эдит и РичЭдит.

Те стратегии знают только об обертке и пользуются её методом ДобавитьСообщение.

Ваше решение?

ЗЫ
группам и перед группой делать коммент.
Прочтите Фаулера про "запахи в коде". Комментарии там на первом месте.


GrayFace   (2007-02-09 01:27:00) [8]

Точнее, не можно, а нужно.


GrayFace   (2007-02-09 01:26:00) [9]

Вместо оберток можно методы в public формы разбивать по группам и перед группой делать коммент.


Apollon604   (2007-02-08 18:58:00) [10]


> with MainForm.ReportStringGrid do


Завязывай с такими "обертками" - класс не должен знать имена объектов, которые его используют... И вообще, для таких целей нормальные люди используют процедуры обычные.


GrayFace   (2007-02-08 18:06:00) [11]

Kolan ©   (06.02.07 23:22) [56]
Чем же ?

Canvas.TextWidth(Cells[i, j]) дважды не вычисляется. И красивее.

Kolan ©   (07.02.07 9:50) [57]
Надо видимо все снести...

И отформатировать диск %)


Kolan   (2007-02-07 09:50:00) [12]

Видимо это Чарт сволочь.
Установил Про Чарт. В итоге:
1. Он изгадил хелп. Если чарт лежит и на жать Ф1, то появляется сранное окно со списком тем, но клик по ним не к чему не приводит.

2. Он выснет, сам чарт. Остальная прогармма работает :)

3. И вот это.

ЗЫ
 Надо видимо все снести...


Kolan   (2007-02-06 23:22:00) [13]

«Лучше»

Чем же ?


GrayFace   (2007-02-06 21:41:00) [14]

Separator ©   (06.02.07 10:22) [23]
Лучше
procedure TForm1.Button1Click(Sender: TObject);
var
  i, j, w: integer;
begin
  with StringGrid1 do
      for i:= 0 to ColCount - 1 do
      begin
          w:= 0;
          for j:= 0 to RowCount - 1 do
              w:= max(w, Canvas.TextWidth(Cells[i, j]));
          ColWidths[i]:= w + 8;
      end;
end;


Loginov Dmitry   (2007-02-06 17:54:00) [15]

Создай TBitmap, скопируй в него свойства канвы с грида и не мучайся. Видимо канва глючит именно из-за того, что Грид закрывается другой вкладкой.


Kolan   (2007-02-06 14:17:00) [16]

Сделал так:
if MainForm.Canvas.TextWidth(Cells[I, J]) > W then
И работает. Что-то не так с канвой грида :(.
Все-равно результат одинаковы...


Kolan   (2007-02-06 14:05:00) [17]

Так а что делать если пользовыатель смотрит на Таб с гридом?
Получается колонки не выровнятся пока он туда сюда не переключит...


Kolan   (2007-02-06 14:01:00) [18]

> А выравнивать грид на закладке, на которую возможно никто
> и не зайдет,

Как и ожидалось все работает.
Только получается раньше я выравнивал при загрузке данных в грид, а теперь при каждом перекключении, но наверно это легко решится с помошью флага.

Однако суть проблемы неясна...


Kolan   (2007-02-06 13:57:00) [19]

> А выравнивать грид на закладке, на которую возможно никто
> и не зайдет,

А в смысли пре переключении на закладку выравнивать - это наверно сработает.

С TChart-ом же справился
Вот оказалось что не совсем :) См топик...


> Run Pause а затем Стек или Трассировка

Ты меня сделал :) Я ниче не понимаю в CPU окне.

Я шас попробовал.
Написано ntdll.KiFastSystemCallRect на этом месте стоит стелка.
Иду далее а далее попадаю в код потока(дополнительного) который что-то там делает..

А потом process is not accessible. А в CPU окне ------.
Наверно это значит что поток termianted.


Kolan   (2007-02-06 13:49:00) [20]

procedure TReportGrid.AdjustColWidth(Grid: TStringGrid);
var
 I, J: Integer;
 W: Integer;
begin
   for I := 0 to Grid.ColCount - 1 do
   begin
     W := 0;
     for J := 0 to Grid.RowCount - 1 do
       if Grid.Canvas.TextWidth(Grid.Cells[I,J]) > W then
         W := Grid.Canvas.TextWidth(Grid.Cells[I, J]);
     Grid.ColWidths[I] := W + 8;
     end;
end;


Всеравно неработает.


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

Наверх

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