Запуск функции

Модераторы: Hawk, Romeo, Absurd, DeeJayC, WinMain

Arbis
Сообщения: 25
Зарегистрирован: 05 авг 2008, 14:40

Я работаю в Turbo C++. Немогу понять как сделать так чтобы сначала рисовалась форма (VCL Forms Application) и только потом выполнялась моя функция. Пробовал вызывать функцию из файла проекта, но не понимаю как это сделать - выдает ошибку компиляции :( .
Вешать на форму Button с надписью "Чтобы запустить программу - нажми!" и в обработчик нажатия кнопки вставлять мою функцию будет совсем глупо!!! А у формы я не нашел обработчика, который запускается после рисования формы.
Помогите плз!
Аватара пользователя
Airhand
Сообщения: 239
Зарегистрирован: 06 окт 2005, 16:21
Откуда: Dnepropetrovsk

Ты, наверное, работаешь в билдере, т.к. в Турбо С++ нет форм.
Как вариант, сделать событие, которое запускать после прорисовки формы и ждать его наступления WaitForSingleObject.
Но должно быть более простое решение, просто я его не помню.
Оптимизация по скорости:
#define while if
Оптимизация по размеру:
#define struct union
Arbis
Сообщения: 25
Зарегистрирован: 05 авг 2008, 14:40

Airhand писал(а):Ты, наверное, работаешь в билдере, т.к. в Турбо С++ нет форм..
Работаю с Turbo C++ 2006 Explorer http://www.turboexplorer.com/cpp , он мало отличается от Borland Developer Studio 2006.
Airhand писал(а):Как вариант, сделать событие, которое запускать после прорисовки формы и ждать его наступления WaitForSingleObject.
Но должно быть более простое решение, просто я его не помню
Сложновато! Не совсем понимаю как можно с WaitForSingleObject отловить окончание прорисовки формы. Да - должно быть более простое решение ...
Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

Airhand, насколько это мне видится, WaitForSingleObject тут никак не прикрутить. Даже если очень захочешь, всё равно не прикрутить. Если сможешь это сделать, то пример кода в студию. Мне кажется, ты не совсем ясно представляешь зачем нужен WaitForSingleObject, если даёшь подобные советы.

Arbis, я не спец в VCL, но я уверен, что среда разработки должна позволять вешать свой обработчик на события, возникающие в форме. Перерисовка - это всёго лишь одно из событий. Достаточно повесится на перерисовку, в обработчике вызвать сначала базовый обработчик, а затем твою функцию.

Если форму написал не ты (например если это сторонний компонент), то в этом случае повешаться на обработчик не получится. Специального для таких случаев существует механизм subclassing'а. Суть его заключается в том, чтобы запомнить указатель на WindowProc некого окна и затем проставить в это окно указатель на другую WindowProc (её мы сделаем сами), которая будет в некоторых случаях обработывать сообщения сама, а других случаях делегировать вызов старой, запомненной ранее WindowProc. Такой подход можно реализовать как дёргая указатели руками, там и вызвав специально предусмотренную для этого метод SubclassWindow, который есть у класса окна практически в каждой библиотеке-обёртке-WinAPI.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Аватара пользователя
Airhand
Сообщения: 239
Зарегистрирован: 06 окт 2005, 16:21
Откуда: Dnepropetrovsk

WaitForSingleObject сюда можно прикрутить следующим образом: ждать события завершения прорисовки формы, которое запускается после всех отрисовок методом SetEvent.
--------------------------------------------------------------------------------
Добавлено сообщение
--------------------------------------------------------------------------------
Romeo
Если не знаеш как, не наезжай.
Когда кажется - креститься надо.
Оптимизация по скорости:
#define while if
Оптимизация по размеру:
#define struct union
Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

Согласен, я ошибся. Если очень захотеть, то действительно прикрутить можно. Я ещё не дорос до таких высот: столь извращённое мышление мне ещё не подвластно :)

Я попросил предоставить код, ты как обычно обошёлся туманными фразами. Я правильно понял, ты предлагаешь запустить отдельный поток, который будет ждать взведения объекта в сигнальное состояние, затем, после вызова SetEvent из главного потока, в этом же отдельном потоке отработает наша функция.

Airhand, скажи мне пожалуйста, если мы точно знаем в каком месте нужно сделать SetEvent, то что нам мешает в этом же месте вызвать нашу функцию, вместо вызова SetEvent? Зачем отдельный поток? Зачем семафор? Ты всегда из одной комнаты ходишь в другую комнату самой ближней дорогой - через северный полюс?
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Аватара пользователя
Airhand
Сообщения: 239
Зарегистрирован: 06 окт 2005, 16:21
Откуда: Dnepropetrovsk

Romeo
А зачем бы тогда придумывали SetEvent и WairForSingleObject ?
Я не говорю, что это эффективное решение, более того я утверждаю, что оно излишне сложное, но оно тоже имеет право на жизнь.

Arbis
Должно быть что-то вроде Form->Redraw().
Оптимизация по скорости:
#define while if
Оптимизация по размеру:
#define struct union
Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

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

Мдя, я вот тут подумал. Подход действительно имеет право на жизнь. Право на жизнь в качестве наглядного пособия о том, как делать нельзя :) Я помню, когда учился в университете, то нам преподаватель давал пример программы, которая выводила на экран слово Hello, причём в теле программы использовалось 5 операторов goto. Очень поучительный пример, ровно, как и этот.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Rycharg
Сообщения: 28
Зарегистрирован: 15 апр 2009, 14:23
Откуда: SPb

Приветствую.
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;  // Либо другая функция
}
Arbis
Сообщения: 25
Зарегистрирован: 05 авг 2008, 14:40

Rycharg , если я правильно понимаю, то ваша идея - заменить вызов OnPaint вызовом CallMyFunc. Немогу понять эту строку (NULL) :

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

this->OnPaint = NULL;

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