Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

альтернатива ShowModal

748
01 апреля 2006 года
AlphaOmega
159 / / 28.09.2004
Преамбула:
есть функция, во время которой появляется окно сообщения (вопрос), ответ на который влияет на дальнейшее выполнение функции. Например:
 
Код:
function(int iNumber)
{
Form2->Tag = iNumber;
Form2->ShowModal();
if (Form2->Tag == iNumber)
    {Caption = "без изменений";}
else {Caption = "изменено";}
}


Амбула (задача):
Представим, что НЕЛЬЗЯ использовать вторую форму. Тогда создаём TPanel (поверх другиих объектов первой формы) с содержанием второй формы.
Теперь нужно выполнить функцию, где вместо Form2->ShowModal(); будет использоваться типа Panel1->Visible = 1; и [COLOR=red]ещё кое-что, что задержит выполнение функции до момента скрытия панели (ответа пользователя)[/COLOR].

ИТАК, всё же, как это кое-что выглядит?
748
01 апреля 2006 года
AlphaOmega
159 / / 28.09.2004
P.S.:
 
Код:
while (Panel1->Visible) {Application->ProcessMessages();}
НЕ ПРЕДЛАГАТЬ! ибо в 1 из 10 вызовов начинается зацикливание и прога (почти с системой) не отвечают...
1
02 апреля 2006 года
kot_
7.3K / / 20.01.2000
Цитата:
Originally posted by AlphaOmega
Преамбула:
есть функция, во время которой появляется окно сообщения (вопрос), ответ на который влияет на дальнейшее выполнение функции. Например:
 
Код:
function(int iNumber)
{
Form2->Tag = iNumber;
Form2->ShowModal();
if (Form2->Tag == iNumber)
    {Caption = "без изменений";}
else {Caption = "изменено";}
}


Амбула (задача):
Представим, что НЕЛЬЗЯ использовать вторую форму. Тогда создаём TPanel (поверх другиих объектов первой формы) с содержанием второй формы.
Теперь нужно выполнить функцию, где вместо Form2->ShowModal(); будет использоваться типа Panel1->Visible = 1; и [COLOR=red]ещё кое-что, что задержит выполнение функции до момента скрытия панели (ответа пользователя)[/COLOR].

ИТАК, всё же, как это кое-что выглядит?


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

748
02 апреля 2006 года
AlphaOmega
159 / / 28.09.2004
Цитата:
Originally posted by kot_
Для данных целей в билдере существует инструмент - такой как фреймы. Можно в принципе использовать и панель - это твое решение, правда не самое лучшее. Для обработки не обязательно использовать задержку, достаточно организовать цикл сообщений и обрабатывать результат при получении сообщения.


1. Если можно, дай ссылку на описание фрэймов (и есть ли они в ПЕРВОМ билдере?
2. Приведи пример ВМЕСТО задержки...

1
02 апреля 2006 года
kot_
7.3K / / 20.01.2000
Цитата:
Originally posted by AlphaOmega
1. Если можно, дай ссылку на описание фрэймов (и есть ли они в ПЕРВОМ билдере?
2. Приведи пример ВМЕСТО задержки...


В первом - хз. Ты ж им пользуешься - посмотри. Если есть - в руководстве разработчика они должны быть описаны.
Цикл обработки сообщений - штука досточно стандартная, общая схема может выглядеть так:
1. В функцию, которая инициализирует твою форму(панель, фрейм, не важно), передается хендл окна, которое будет получать сообщения. Правда если это панель - необходимости в этом нет. Можно использовать хендл текущего окна.
2. Затем определяешь свое сообщение- можно использовать и стандартные - но воизбежание накладок, непоняток и т.д. - лучше определить свой мессадж. Делается так:

 
Код:
#define WM_MYMESSAGE WM_USER+100

3. Объявляешь функцию которая выполнит все что необходимо, например обработает введенное и скроет панель:
 
Код:
private:
void __fastcall MyFunction(TMessage&);

4. Рисуешь в заголовочном файле формы объявление цикла обработки сообщений:
 
Код:
BEGIN_MESSAGE_MAP
 MESSAGE_HANDLER(WM_MYMESSAGE,TMessage,MyFunction);
END_MESSAGE_MAP(TForm)

5. Определяешь функцию MyFunction:
 
Код:
void __fastcall TForm1::MyFunction(TMessage &Msg){
 switch(Msg.Msg){
   case WM_MYMESSAGE:
   ....
    Panel1->Visible = false;
   break;
 }
}

6. Кнопка на панели содержит такой код:
 
Код:
SendMessage(this->Handle,WM_MYMESSAGE,NULL,NULL);

ну вобщем то и все. Конечно, в реальном коде, тебе необходимо обеспечивать потокобезопасность - т.е. позаботится что бы приложение не могло использовать переменные до того как форма скроется, если это возможно - надо использовать мьютексы, события и функции ожидания. Естественно надо реализовать сообщение о том что пользователь отменил операцию, но здесь уже простор для твоей фантазии. Если будешь юзать стандартные сообщения- не забывай использовать DispatchMessage - что бы окно могло их тоже получать.
З.Ы. Естественно, если объявляешь более чем одно сообщение, не забывай правильно указывать смещение:
 
Код:
#define WM_MYMESSAGE2 WM_USER+200
//или
#define WM_MYMESSAGE2 WM_MYMESSAGE+100
1
02 апреля 2006 года
kot_
7.3K / / 20.01.2000
Цитата:
Originally posted by AlphaOmega
1. Если можно, дай ссылку на описание фрэймов (и есть ли они в ПЕРВОМ билдере?


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

748
02 апреля 2006 года
AlphaOmega
159 / / 28.09.2004
Способ интересный, но немного сложный. Ибо если я в нём запутаюсь - у проги будет много багов.

Кстати, я выяснил почему виснет вариант
 
Код:
while (Panel1->Visible) {Application->ProcessMessages();}
Дело всё в том, что до этого кода у меня используется функция PlaySound, воспроизводящая звук. Вот она-то и выдаёт MCI Error в 1 из 10 случаев (если вызывать эту "псевдо_форму_панель" очень быстро). Причём PlaySound у меня в блоке try-catch, но ошибка всё равно вылетает :(

Может как-то можно "поймать" эту ошибку или сделать что-то, чтобы подобных глюков не было?

Пока пытаюсь использовать
 
Код:
PlaySound(0, 0, SND_PURGE);
вроде помогает... но на долго ли?....
1
02 апреля 2006 года
kot_
7.3K / / 20.01.2000
Цитата:
Originally posted by AlphaOmega
Способ интересный, но немного сложный. Ибо если я в нём запутаюсь - у проги будет много багов.

Кстати, я выяснил почему виснет вариант
 
Код:
while (Panel1->Visible) {Application->ProcessMessages();}
Дело всё в том, что до этого кода у меня используется функция PlaySound, воспроизводящая звук. Вот она-то и выдаёт MCI Error в 1 из 10 случаев (если вызывать эту "псевдо_форму_панель" очень быстро). Причём PlaySound у меня в блоке try-catch, но ошибка всё равно вылетает :(

Может как-то можно "поймать" эту ошибку или сделать что-то, чтобы подобных глюков не было?

Пока пытаюсь использовать
 
Код:
PlaySound(0, 0, SND_PURGE);
вроде помогает... но на долго ли?....


Возможно тебе необходимо вызывать PlaySound с флагом SND_ASYNC.

748
02 апреля 2006 года
AlphaOmega
159 / / 28.09.2004
Цитата:
Originally posted by kot_
Возможно тебе необходимо вызывать PlaySound с флагом SND_ASYNC.

Дык так оно и есть. Вызываю звук из ресурса DLL`ки с флагом SND_ASYNC (если б я вызывал без этого флага, то и прога не могла бы в одно и то же время два потока запустить)....

1
02 апреля 2006 года
kot_
7.3K / / 20.01.2000
Цитата:
Originally posted by AlphaOmega
Дык так оно и есть. Вызываю звук из ресурса DLL`ки с флагом SND_ASYNC (если б я вызывал без этого флага, то и прога не могла бы в одно и то же время два потока запустить)....


 
Код:
PlaySound("SoundName", Application->Handle, SND_RESOURCE | SND_ASYNC);

как второй вариант, пример из МСДН, вызов функции:
Код:
BOOL PlayResource(LPSTR lpName)
{
    BOOL bRtn;
    LPSTR lpRes;
    HANDLE hResInfo, hRes;
 
    // Find the WAVE resource.
 
    hResInfo = FindResource(hInst, lpName, "WAVE");
    if (hResInfo == NULL)
        return FALSE;
 
    // Load the WAVE resource.
 
    hRes = LoadResource(hInst, hResInfo);
    if (hRes == NULL)
        return FALSE;
 
    // Lock the WAVE resource and play it.
 
    lpRes = LockResource(hRes);
    if (lpRes != NULL) {
        bRtn = sndPlaySound(lpRes, SND_MEMORY | SND_SYNC |
            SND_NODEFAULT);
        UnlockResource(hRes);
    }
    else
        bRtn = 0;
 
    // Free the WAVE resource and return success or failure.
 
    FreeResource(hRes);
    return bRtn;
}
748
07 мая 2006 года
AlphaOmega
159 / / 28.09.2004
Цитата:
Originally posted by kot_
 
Код:
// Lock the WAVE resource and play it.

lpRes = LockResource(hRes);
if (lpRes != NULL) {bRtn = sndPlaySound(lpRes, SND_MEMORY | SND_SYNC | SND_NODEFAULT);
UnlockResource(hRes); }


Судя по когду, музон играется СИНХРОННО. То есть не допускает продолжение работы приложении (в моём случае - анимация останавливается на время воспроизведения).

Какие есть ещё способы проигрывания звуковых файлов, загружаемых из ресурса DLL?

748
07 мая 2006 года
AlphaOmega
159 / / 28.09.2004
Кстати, вот ошибка которая возникает в цикле while что я описывал.

 
Код:
MCI command handling window: Project1.exe - Ошибка приложения
Инструкция по адресу "0x76b2594d" обратилась к памяти по адресу "0x01b2faa0". Память не может быть "read".

"OK" - завершение приложения
"Отмена" - отладка приложения


Причём я так и не понял, когда (из-за чего) возникает эта ошибка. Может кто-то знает???

Проблема больше в том, что прога после этого закрывается :(
20K
26 марта 2007 года
sja
22 / / 08.01.2007
когда кажется что прога вешает ситсему в основном цикле поставьте
Sleep(1);
и жизнь покажется раем :)
263
26 марта 2007 года
koltaviy
816 / / 16.12.2004
Цитата: sja
когда кажется что прога вешает ситсему в основном цикле поставьте
Sleep(1);
и жизнь покажется раем :)


А на дату последнего сообщения смотрим?Sleep!:D

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог