Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Как правильно вызвать подпрограмму  (Прочитано 13453 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Дмитрий777
Гость
« : 04-02-2009 13:49 » 

Извиняюсь за дурацкий вопрос, но я только начал осваивать азы .
Мне нужно вызвать подпрограмму перерисовки шрифта ячеек стринггрида при нажатии кнопки.
Делаю так:
Код:
// сама подпрограмма
procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
  Rect: TRect; State: TGridDrawState);
begin
// здесь все работает, если запускать отдельно
end;

А это программа вызова подпрограммы
Код:
procedure TForm1.Button1Click(Sender: TObject);
begin
StringGrid1DrawCell ;
end;
Вот здесь компилятор ругается. Что я делаю не так?
Записан
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #1 : 04-02-2009 14:11 » 

а передать параметры в процедуру?
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
Дмитрий777
Гость
« Ответ #2 : 04-02-2009 14:49 » 

А разве тех параметров, которые указаны при запуске подпрограммы недостаточно?
И если при вызове п/п нужно указать пареметры, то какие именно ?
Записан
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #3 : 04-02-2009 15:02 » 

Вот гляди. Ты сам написал.
Код:
// сама подпрограмма
procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
  Rect: TRect; State: TGridDrawState);
begin
// здесь все работает, если запускать отдельно
end;
Тем самым ты ее (подпрограмму объявил  с параметрами
Sender: TObject;
ACol,
ARow: Integer;
Rect: TRect;
State: TGridDrawState

Здесь ты ее вызываешь
Код:
procedure TForm1.Button1Click(Sender: TObject);
begin
StringGrid1DrawCell ;
end;
Но уже без параметров.
Компилятор - естественно будет ругаться.

Объявление и вызов - это разные вещи.
у тебя должно быть что-то подобное
Код:
procedure TForm1.Button1Click(Sender: TObject);
begin
StringGrid1DrawCell(Sender, ACol, ARow,Rect, State);
end;

Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
zubr
Модератор

by
Offline Offline
Пол: Мужской

« Ответ #4 : 04-02-2009 15:24 » 

StringGrid1DrawCell - это обработчик события перерисовки ячеек грида. Какой смысл вызывать процедуру обработки данного события по нажатию кнопки?
Оставь данный обработчик в покое. А в обработчике нажатия кнопки вызови перерисовку грида:
Код:
procedure TForm1.Button1Click(Sender: TObject);
begin
  StringGrid1.Refresh;
end;
И будет счастье.
Записан
Дмитрий777
Гость
« Ответ #5 : 04-02-2009 18:39 » 

Вот весь текст

В первой колонке стринггрида находятся заголовки разделов, а во 2 и 4 колонках
и, в следующих строках, данные.
Программа построчно проверяет содержимое колонок 2 и 4. Отсутствие данных в этих
колонках свидетельствует о том, что в колонке 1 данной строки находится заголовок.
Шрифт заголовка изменяется на полужирный и продолжается проверка следующих строк.
Код:
var
  k:integer;
  //подпрограмма изменения шрифта в  строке (глобальная переменная - k )

 procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
  Rect: TRect; State: TGridDrawState);
begin
  if (ACol = 1)and(ARow = k) then with StringGrid1.Canvas do
  begin
    FillRect(Rect); //Изменяем атрибут шрифта
    Font.Style:= [fsBold];
    TextOut(Rect.Left, Rect.Top, StringGrid1.Cells[ACol,ARow]);
  end;
end;


 // Поиск и изменение заголовка

procedure TForm1.Button1Click(Sender: TObject);
 var
 label M_1 ;
begin
for k :=0 to StringGrid1.RowCount-1  do
begin
 if StringGrid1.Cells[2,k] = '' then // проверка колонки 2
     else  goto M_1 ;
 if StringGrid1.Cells[4,k] = '' then // проверка колонки 4
 else  goto M_1 ;
 begin
 // Вызов подпрограммы изменения шрифта в проверенной строке
   StringGrid1DrawCell(Sender, ACol, ARow,Rect, State);
 end;
 M_1:
end;
end;

end.
Sla. - Компилятор сообщает о незадекларированных ACol, ARow, State.

Перерисовывать всю таблицу. А если там 10000 строк и перерисовать
нужно 1000 раз. Мелькать не будет?
Записан
zubr
Модератор

by
Offline Offline
Пол: Мужской

« Ответ #6 : 04-02-2009 21:30 » 

Перерисовка происходит всякий раз, когда пользователь выводит окно на передний план, а следовательно происходит событие StringGrid1DrawCell (попробуй в отладке поставь брикпоинт в коде данного обработчика - как только ты будешь пытаться вывести окно программы на передний план, отладчик будет останавливаться на этом брикпоинте). При этом, заметь ничего не мелькает, конечно в случае если у тебя код обработчика оптимальный. Если ты будешь что то рисовать в контексте грида не в обработчике данного события, то естественно, например при сворачивании окна и затем последующего его восстановления от нарисованного не останется и следа.
« Последнее редактирование: 04-02-2009 21:32 от zubr » Записан
Дмитрий777
Гость
« Ответ #7 : 05-02-2009 07:53 » 

Не понял..
Перерисовка грида не изменит атрибуты шрифта в нужных ячейках. Их же нужно изменять "принудительно".
Может проще разобраться с вызовом подпрограммы. Почему компилятор сообщает о незадекларированных
ACol, ARow, State. Где я их должен задекларировать? В учебнике об этом мало и непонятно.
Записан
zubr
Модератор

by
Offline Offline
Пол: Мужской

« Ответ #8 : 05-02-2009 08:42 » 

Дмитрий777,
1. ты читать умеешь? Я вроде по русски пишу. Советую почитать на тему оконных сообщений Windows. Еще раз разъясняю: StringGrid1DrawCell - это процедура (как бы пустой шаблон), предусмотренная разработчиками Borland для компонента TStringGrid, которая вызывается при получении окном TStringGrid от Windows сообщения WM_PAINT (обновления изображения окна). Код, который ты пропишешь в тело данной процедуры будет выполняться всякий раз при перерисовки окна компонента.
2. Брикпоинт ставил в теле обработчика StringGrid1DrawCell?
Записан
Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #9 : 05-02-2009 08:47 » 

zubr, я вот думаю, следует уточнить: она будет выполняться при перерисовке для всех ячеек - то есть, по разу на каждую - ведь так?
Остаётся вопрос, как задаётся стиль текста в ячейке (не помню, есть ли такое свойство у ячейки, или это нужно свою матрицу хранить, чтобы при вызове StringGrid1DrawCell для нужной ячейки с нетривиальным стилем выводить что-то специфическое, а потом возвращать стиль в дефолт)?

Дмитрий777, я думаю, отдельно стоит с языком поближе ознакомиться. Потому что если бы сначала изучался сам диалект, а уже потом шли попытки соорудить свой UI, не было бы нелепых вопросов про объявление переменных и передачу параметров в процедуры и функции.
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


WWW
« Ответ #10 : 05-02-2009 08:51 » 

zubr, Остаётся вопрос, как задаётся стиль текста в ячейке (не помню, есть ли такое свойство у ячейки, или это нужно свою матрицу хранить, чтобы при вызове StringGrid1DrawCell для нужной ячейки с нетривиальным стилем выводить что-то специфическое, а потом возвращать стиль в дефолт)?

думаю, надо создать динамический массив с некими дескрипторами стилей, в которых всё что на до описано, а для каждой ячейки сопоставить свойство - ID дескриптора
Записан

zubr
Модератор

by
Offline Offline
Пол: Мужской

« Ответ #11 : 05-02-2009 09:34 » 

Вад, у него код этого обработчика приложен, там шрифты меняются в ячейках при определенных условиях
Код:
if (ACol = 1)and(ARow = k) then with StringGrid1.Canvas do
  begin
    FillRect(Rect); //Изменяем атрибут шрифта
    Font.Style:= [fsBold];
    TextOut(Rect.Left, Rect.Top, StringGrid1.Cells[ACol,ARow]);
  end;
Исходя из этого кода ничего тормозить не будет. Ведь по большому счету при перерисовке грид все равно для каждой видимой ячейки по новому отрисовывает текст, при скролинге опять происходит перерисовка. В видимую же часть окна входит не так много ячеек, что бы что то тормозило.

Тут все что надо сделать - это по нажатию кнопки вызвать перерисовку и компонент перерисует видимую часть окна. При скролинге она сама перерисуется.
Записан
Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #12 : 05-02-2009 09:38 » 

zubr, а фонт сам восстановится? В смысле, не надо ли сохранить стиль, а после TextOut вернуть на место?
Записан
zubr
Модератор

by
Offline Offline
Пол: Мужской

« Ответ #13 : 05-02-2009 10:20 » 

Не надо. Так как компонент в своей внутренней части обработчика практически делает то же самое (TextOut), но для установки параметров прорисовки использует данные из внутренних переменных, которые пользователем устанавливаются из свойств.
StringGrid1.Canvas.Font.Style:= [fsBold]; - данная же конструкция свойства шрифта компонента не меняет, а напрямую меняет параметры контекста компонента.
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines