Страница 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
&quot писал(а):А зачем бы тогда придумывали SetEvent и WairForSingleObject ?
SetEvent и WairForSingleObject придумали для того, чтобы обеспечивать синхронизацию нескольких потоков. Здесь несколько потоков ни к чему вовсе, так как сначала мы их вводим, а потом избавляемся от параллельного исполнения кода двумя WaitForSingleObject (один в одном потоке, другой в другом). Зачем поток, если он не будет выполняться параллельно?
&quot писал(а):но оно тоже имеет право на жизнь.
Не имеет оно право на жизнь. Могу об этом спорить сколько угодно. Давай тогда все функции в нашей программы запускать в отдельных потоках, а чтобы добиться того, чтобы они всё таки выполнялись по очереди, будем использовать синхронизирующие объекты. Программа превратится в диковинного уродца, которого будут показывать начинающим программистам со словами "Смотрите, вот предел абсурда".

Мдя, я вот тут подумал. Подход действительно имеет право на жизнь. Право на жизнь в качестве наглядного пособия о том, как делать нельзя :) Я помню, когда учился в университете, то нам преподаватель давал пример программы, которая выводила на экран слово 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) :

Код: Выделить всё

this->OnPaint = NULL;

P.S. Извините я только начинающий программист ...