Страница 1 из 3
Запуск функции
Добавлено: 16 июл 2009, 11:43
Arbis
Я работаю в Turbo C++. Немогу понять как сделать так чтобы сначала рисовалась форма (VCL Forms Application) и только потом выполнялась моя функция. Пробовал вызывать функцию из файла проекта, но не понимаю как это сделать - выдает ошибку компиляции

.
Вешать на форму Button с надписью "Чтобы запустить программу - нажми!" и в обработчик нажатия кнопки вставлять мою функцию будет совсем глупо!!! А у формы я не нашел обработчика, который запускается
после рисования формы.
Помогите плз!
Re: Запуск функции
Добавлено: 16 июл 2009, 19:41
Airhand
Ты, наверное, работаешь в билдере, т.к. в Турбо С++ нет форм.
Как вариант, сделать событие, которое запускать после прорисовки формы и ждать его наступления WaitForSingleObject.
Но должно быть более простое решение, просто я его не помню.
Re: Запуск функции
Добавлено: 16 июл 2009, 21:19
Arbis
Airhand писал(а):Ты, наверное, работаешь в билдере, т.к. в Турбо С++ нет форм..
Работаю с Turbo C++ 2006 Explorer
http://www.turboexplorer.com/cpp , он мало отличается от Borland Developer Studio 2006.
Airhand писал(а):Как вариант, сделать событие, которое запускать после прорисовки формы и ждать его наступления WaitForSingleObject.
Но должно быть более простое решение, просто я его не помню
Сложновато! Не совсем понимаю как можно с WaitForSingleObject отловить окончание прорисовки формы. Да - должно быть более простое решение ...
Re: Запуск функции
Добавлено: 17 июл 2009, 00:13
Romeo
Airhand, насколько это мне видится, WaitForSingleObject тут никак не прикрутить. Даже если очень захочешь, всё равно не прикрутить. Если сможешь это сделать, то пример кода в студию. Мне кажется, ты не совсем ясно представляешь зачем нужен WaitForSingleObject, если даёшь подобные советы.
Arbis, я не спец в VCL, но я уверен, что среда разработки должна позволять вешать свой обработчик на события, возникающие в форме. Перерисовка - это всёго лишь одно из событий. Достаточно повесится на перерисовку, в обработчике вызвать сначала базовый обработчик, а затем твою функцию.
Если форму написал не ты (например если это сторонний компонент), то в этом случае повешаться на обработчик не получится. Специального для таких случаев существует механизм subclassing'а. Суть его заключается в том, чтобы запомнить указатель на WindowProc некого окна и затем проставить в это окно указатель на другую WindowProc (её мы сделаем сами), которая будет в некоторых случаях обработывать сообщения сама, а других случаях делегировать вызов старой, запомненной ранее WindowProc. Такой подход можно реализовать как дёргая указатели руками, там и вызвав специально предусмотренную для этого метод SubclassWindow, который есть у класса окна практически в каждой библиотеке-обёртке-WinAPI.
Re: Запуск функции
Добавлено: 17 июл 2009, 12:18
Airhand
WaitForSingleObject сюда можно прикрутить следующим образом: ждать события завершения прорисовки формы, которое запускается после всех отрисовок методом SetEvent.
--------------------------------------------------------------------------------
Добавлено сообщение
--------------------------------------------------------------------------------
Romeo
Если не знаеш как, не наезжай.
Когда кажется - креститься надо.
Re: Запуск функции
Добавлено: 17 июл 2009, 18:40
Romeo
Согласен, я ошибся. Если очень захотеть, то действительно прикрутить можно. Я ещё не дорос до таких высот: столь извращённое мышление мне ещё не подвластно
Я попросил предоставить код, ты как обычно обошёлся туманными фразами. Я правильно понял, ты предлагаешь запустить отдельный поток, который будет ждать взведения объекта в сигнальное состояние, затем, после вызова SetEvent из главного потока, в этом же отдельном потоке отработает наша функция.
Airhand, скажи мне пожалуйста, если мы точно знаем в каком месте нужно сделать SetEvent, то что нам мешает в этом же месте вызвать нашу функцию, вместо вызова SetEvent? Зачем отдельный поток? Зачем семафор? Ты всегда из одной комнаты ходишь в другую комнату самой ближней дорогой - через северный полюс?
Re: Запуск функции
Добавлено: 17 июл 2009, 19:28
Airhand
Romeo
А зачем бы тогда придумывали SetEvent и WairForSingleObject ?
Я не говорю, что это эффективное решение, более того я утверждаю, что оно излишне сложное, но оно тоже имеет право на жизнь.
Arbis
Должно быть что-то вроде Form->Redraw().
Re: Запуск функции
Добавлено: 17 июл 2009, 20:03
Romeo
" писал(а):А зачем бы тогда придумывали SetEvent и WairForSingleObject ?
SetEvent и WairForSingleObject придумали для того, чтобы обеспечивать синхронизацию нескольких потоков. Здесь несколько потоков ни к чему вовсе, так как сначала мы их вводим, а потом избавляемся от параллельного исполнения кода двумя WaitForSingleObject (один в одном потоке, другой в другом). Зачем поток, если он не будет выполняться параллельно?
" писал(а):но оно тоже имеет право на жизнь.
Не имеет оно право на жизнь. Могу об этом спорить сколько угодно. Давай тогда все функции в нашей программы запускать в отдельных потоках, а чтобы добиться того, чтобы они всё таки выполнялись по очереди, будем использовать синхронизирующие объекты. Программа превратится в диковинного уродца, которого будут показывать начинающим программистам со словами "Смотрите, вот предел абсурда".
Мдя, я вот тут подумал. Подход действительно имеет право на жизнь. Право на жизнь в качестве наглядного пособия о том, как делать нельзя

Я помню, когда учился в университете, то нам преподаватель давал пример программы, которая выводила на экран слово Hello, причём в теле программы использовалось 5 операторов goto. Очень поучительный пример, ровно, как и этот.
Re: Запуск функции
Добавлено: 20 июл 2009, 23:16
Rycharg
Приветствую.
Arbis, если Turbo C++ действительно похож на Builder, то можно пойти таким путём: класс TForm имеет свойство OnPaint ( void __fastcall (__closure* OnPaint )(TObject *Sender) ). Это указатель на метод класса, который будет вызываться при рисовании на форме. Использовать можно так:
Код: Выделить всё
void MyFunc();
//-----
class TMyFrm : public TForm{
//
//
__fastcall TMyFrm(TComponent* Owner);
void __fastcall CallMyFunc(TObject *Sender);
};
//------
__fastcall TMyFrm::TMyFrm(TComponent* Owner) : TForm(Owner){
this->OnPaint = &CallMyFunc;
}
//------
void __fastcall TMyFrm::CallMyFunc(TObject *Sender){
MyFunc();
this->OnPaint = NULL; // Либо другая функция
}
Re: Запуск функции
Добавлено: 21 июл 2009, 14:46
Arbis
Rycharg , если я правильно понимаю, то ваша идея - заменить вызов OnPaint вызовом CallMyFunc. Немогу понять эту строку (NULL) :
P.S. Извините я только начинающий программист ...