Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Сообщение полного конца, инициализации окна 
V
    Опции темы
Rickert
  Дата 29.5.2008, 08:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ситхи не пройдут!
****


Профиль
Группа: Комодератор
Сообщений: 3356
Регистрация: 11.7.2006
Где: Лакрима

Репутация: нет
Всего: 52



Есть окно, на нём куча элементов, все там по своему инициализируются и всё такое. Как мне поймать момент конца полной инициализации всех элементов, то бишь момент, после которого окно перейдёт в режим ожидания сообщений: когда уже всё отрисованно?

Это сообщение отредактировал(а) Rickert - 29.5.2008, 08:58


--------------------
Ни что не внушает сна крепче, чем день приисполненный трудов!
PM MAIL WWW Skype GTalk   Вверх
deniska
Дата 29.5.2008, 10:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 398
Регистрация: 1.7.2005
Где: Троицк

Репутация: 1
Всего: 0



может OnIdle переопределить? вроде как вызывается когда очередь сообщений пуста
PM MAIL ICQ   Вверх
Rickert
Дата 29.5.2008, 10:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ситхи не пройдут!
****


Профиль
Группа: Комодератор
Сообщений: 3356
Регистрация: 11.7.2006
Где: Лакрима

Репутация: нет
Всего: 52



Пардон, не сказал: у меня модальный диалог, для него OnIdle не перегрузишь насколько мне известно.


--------------------
Ни что не внушает сна крепче, чем день приисполненный трудов!
PM MAIL WWW Skype GTalk   Вверх
Rickert
Дата 29.5.2008, 11:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ситхи не пройдут!
****


Профиль
Группа: Комодератор
Сообщений: 3356
Регистрация: 11.7.2006
Где: Лакрима

Репутация: нет
Всего: 52



OnEnterIdle тоже ни при делах.


--------------------
Ни что не внушает сна крепче, чем день приисполненный трудов!
PM MAIL WWW Skype GTalk   Вверх
deniska
Дата 29.5.2008, 12:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 398
Регистрация: 1.7.2005
Где: Троицк

Репутация: 1
Всего: 0



объект CWinApp есть в каждом приложении...  как модальность\немодальность окна может влиять?
ты ведь не для диалога перегружаешь а для основного потока своего приложения. как только освобождается очередь сообщений для него, по идее сразу должен попасть в свой обработчик OnIdle
PM MAIL ICQ   Вверх
Rickert
Дата 30.5.2008, 07:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ситхи не пройдут!
****


Профиль
Группа: Комодератор
Сообщений: 3356
Регистрация: 11.7.2006
Где: Лакрима

Репутация: нет
Всего: 52



deniska, в одной из тем, здесь же на форуме я задавал вопрос немного другого плана и там, как мне было объяснено: OnIdle не вызывается, потом что модальный диалог идёт не через InitInstance().
Плюс к этому я уже трижды пробовал перегружать OnIdle в потомке от CWinApp - результата нет.


--------------------
Ни что не внушает сна крепче, чем день приисполненный трудов!
PM MAIL WWW Skype GTalk   Вверх
Andrey44
Дата 30.5.2008, 07:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1501
Регистрация: 4.12.2006
Где: На работе

Репутация: 12
Всего: 26



Может поможет
Код

BOOL GetMessage(
  LPMSG lpMsg, 
  HWND hWnd, 
  UINT wMsgFilterMin, 
  UINT wMsgFilterMax 
); 




--------------------
????? ??, ??????? ?????.  smile 
PM MAIL WWW ICQ   Вверх
deniska
Дата 30.5.2008, 08:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 398
Регистрация: 1.7.2005
Где: Троицк

Репутация: 1
Всего: 0



Rickert, по ходу ты прав. сейчас попробовал - не заходит. тогда можно в какойнить таймер воткнуть функцию, которую Andrey44 дал... 
а вообще если вся инициализация контролов находится в OnInitDialog, то наверно следующий после этой функции вызов OnPaint последний. по крайней мере можно с GetMessage по экспериментировать, проверить.
PM MAIL ICQ   Вверх
Earnest
Дата 30.5.2008, 11:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 87
Всего: 183



Модальному диалогу должно прийти WM_KICKIDLE - первый раз оно приходит после окончания инициализации, а дальше - как OnIdle. Это private MFC сообщение, определено в afxpriv.h


--------------------
...
PM   Вверх
Rickert
Дата 2.6.2008, 03:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ситхи не пройдут!
****


Профиль
Группа: Комодератор
Сообщений: 3356
Регистрация: 11.7.2006
Где: Лакрима

Репутация: нет
Всего: 52



Цитата(Earnest @  30.5.2008,  11:36 Найти цитируемый пост)
Модальному диалогу должно прийти WM_KICKIDLE - первый раз оно приходит после окончания инициализации, а дальше - как OnIdle. Это private MFC сообщение, определено в afxpriv.h 

Поставил у диалога в обработку PreTranslateMessage на WM_KICKIDLE - простой вывод MessageBox'а: никаких результатов. smile 


--------------------
Ни что не внушает сна крепче, чем день приисполненный трудов!
PM MAIL WWW Skype GTalk   Вверх
Earnest
Дата 2.6.2008, 15:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 87
Всего: 183



WM_KICKIDLE не помещается в очередь, а посылается прямо. Ставь обработчик - поймаешь.


--------------------
...
PM   Вверх
Rickert
Дата 3.6.2008, 03:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ситхи не пройдут!
****


Профиль
Группа: Комодератор
Сообщений: 3356
Регистрация: 11.7.2006
Где: Лакрима

Репутация: нет
Всего: 52



Цитата(Earnest @  2.6.2008,  15:38 Найти цитируемый пост)
WM_KICKIDLE не помещается в очередь, а посылается прямо. Ставь обработчик - поймаешь. 

Так как я его поставлю?
В BEGIN_MESSAGE_MAP()? Нету там ON_WM_KICKIDLE.
MSDN тоже, кстати, мало что внятного может сказать про WM_KICKIDLE.
Где ты про него вычитала интересно? smile

Это сообщение отредактировал(а) Rickert - 3.6.2008, 05:18


--------------------
Ни что не внушает сна крепче, чем день приисполненный трудов!
PM MAIL WWW Skype GTalk   Вверх
dizzy1984
Дата 3.6.2008, 08:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 675
Регистрация: 15.2.2007

Репутация: 10
Всего: 25



Цитата(Rickert @  3.6.2008,  05:59 Найти цитируемый пост)
Где ты про него вычитала интересно? 

Подобное можно узнать кропотливой отладкой исходников MFC.

Интересующее нас место тут (файл wincore.cpp, урезаны незначимые места)
Код

// acquire and dispatch messages until the modal state is done
    for (;;)
    {
        ASSERT(ContinueModal());

        // phase1: check to see if we can do idle work
        while (bIdle &&
            !::PeekMessage(pMsg, NULL, NULL, NULL, PM_NOREMOVE))
        {
            ASSERT(ContinueModal());

            if ((dwFlags & MLF_NOKICKIDLE) ||
                !SendMessage(WM_KICKIDLE, MSGF_DIALOGBOX, lIdleCount++))
            {
                // stop idle processing next time
                bIdle = FALSE;
            }
        }

        // phase2: pump messages while available
        do
        {
            ASSERT(ContinueModal());

            // pump message, but quit on WM_QUIT
            if (!AfxGetThread()->PumpMessage())
            {
                AfxPostQuitMessage(0);
                return -1;
            }

                           if (!ContinueModal())
                goto ExitModal;

            // reset "no idle" state after pumping "normal" message
            if (AfxGetThread()->IsIdleMessage(pMsg))
            {
                bIdle = TRUE;
                lIdleCount = 0;
            }

        } while (::PeekMessage(pMsg, NULL, NULL, NULL, PM_NOREMOVE));
    }


Видно, что в код, расположенный в первой фазе бесконечного цикла, будет выполнен на следующей итерации после того, как очередь сообщений опустеет. Выход из него осуществляется в зависимости от результата ответа на магическое сообщение "SendMessage(WM_KICKIDLE, MSGF_DIALOGBOX, lIdleCount++)". Ясно, что если это FALSE - бесконечные цикл войдет во вторую фазу и на этом успокоится.
Соответственно Earnest уже сказала, что SendMessage(WM_KICKIDLE...) займется тем, что вызовет процедуру окна, которую MFC зарегистрировала как "AfxWndProc"(тот же Wincore.cpp) и которая в конечном счете найдет CWnd, соответсвующее полученному ей HWND и просмотрит его карту отклика. Там она может увидеть обработчик сообщения WM_KICKIDLE. В таком случае вместо стандартного обработчика DefWindowProc будет взят именно он.
Резюмируя, пишем код
Код

#include <afxpriv.h>
//...

BEGIN_MESSAGE_MAP(CTest2Dlg, CDialog)
//...
ON_MESSAGE(WM_KICKIDLE, Proc)
//...
END_MESSAGE_MAP()

BOOL CTest2Dlg::Proc()
{
return FALSE;
}

Замечательно, работает, но зачем мы все это написали? Я не знаю.
Все это ни к чему, т.к идеологически неверно - такой обработчик будет вызываться постоянно, после появления новых сообщений в очереди.
Нормальный вариант решения проблемы с моей точки зрения будет посылка произвольного сообщения из OnInitDialog.
Обработчик такого сообщения будет вызван после того, как очередь опустеет.
Пишем код
Код

BEGIN_MESSAGE_MAP(CTest2Dlg, CDialog)
//...
ON_MESSAGE(WM_USER, Proc2)
//...
END_MESSAGE_MAP()

BOOL CTest2Dlg::OnInitDialog()
{
         //...
    SendMessage(WM_USER, 0, 0);
    return FALSE;  // return TRUE  unless you set the focus to a control
}

void CTest2Dlg::Proc2() 
{    
    return ;
}


PM MAIL   Вверх
Earnest
Дата 3.6.2008, 10:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 87
Всего: 183



Цитата(Rickert @  3.6.2008,  04:59 Найти цитируемый пост)
В BEGIN_MESSAGE_MAP()? Нету там ON_WM_KICKIDLE.

Убойный аргумент, что и говорить.

Насчет WM_KICKIDLE... я его использую для аснхронного обновления контролов диалога, очень полезная вешь (примерно так, как работает WM_IDLEUPDATECMDUI в фрейворке...
Насчет "приходить много раз" - да, конечно, однако нетрудно поставить какой-то флаг инициализации. Но это дело вкуса - я лично терпеть не могу юзеровские сообщения плодить. По-хорошему, нужно использовать Registered Messages, а это хлопотно. Или поддерживать общий пул юзеровских сообщений... что порождает лишние связи между модулями... Можно, конечно, плюнуть и плыть по течению, но в большом проекте такой бардак рано или поздно приведет к проблемам...
В общем, ваш выбор...

Цитата(dizzy1984 @  3.6.2008,  09:22 Найти цитируемый пост)
SendMessage(WM_USER, 0, 0);

Цитата(dizzy1984 @  3.6.2008,  09:22 Найти цитируемый пост)
Обработчик такого сообщения будет вызван после того, как очередь опустеет.

Ты сам-то понял, что чушь написал? Ну, будем считать это опиской  smile 



--------------------
...
PM   Вверх
Rickert
Дата 4.6.2008, 04:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ситхи не пройдут!
****


Профиль
Группа: Комодератор
Сообщений: 3356
Регистрация: 11.7.2006
Где: Лакрима

Репутация: нет
Всего: 52



Да, что-то я относительно ON_MESSAGE прогнал smile
Всем спасибо, solved smile 


--------------------
Ни что не внушает сна крепче, чем день приисполненный трудов!
PM MAIL WWW Skype GTalk   Вверх
dizzy1984
Дата 4.6.2008, 05:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 675
Регистрация: 15.2.2007

Репутация: 10
Всего: 25



Цитата(Earnest @  3.6.2008,  12:27 Найти цитируемый пост)
Ты сам-то понял, что чушь написал? Ну, будем считать это опиской   

Написал по-проще для ясности, имелось в виду, что очередь значимых сообщений (идущих до WM_USER) уже будет обработана, останется только "надуманное" сообщение (WM_USER), которое, конечно, формально будет последним в той же очереди, но кого это волнует? Это как раз и нужно.

Это сообщение отредактировал(а) dizzy1984 - 4.6.2008, 05:21
PM MAIL   Вверх
dizzy1984
Дата 4.6.2008, 07:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 675
Регистрация: 15.2.2007

Репутация: 10
Всего: 25



А на счет RegisterWindowMessage, это было дельное предложение. Вот более верный вариант :
Код

static const UINT messageAppInit = ::RegisterWindowMessage("3D5914BB-6689-4697-81F9-4DADA4A5964B");

BEGIN_MESSAGE_MAP(CTest2Dlg, CDialog)
//...    
ON_REGISTERED_MESSAGE(messageAppInit, Proc2)    
//...    
END_MESSAGE_MAP()    

BOOL CTest2Dlg::OnInitDialog()    
{    
         //...    
    SendMessage(messageAppInit, 0, 0);    
    return FALSE;  // return TRUE  unless you set the focus to a control    
}    
void CTest2Dlg::Proc2()    
{     
    return ;    
}

PM MAIL   Вверх
Earnest
Дата 4.6.2008, 07:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 87
Всего: 183



ОК, поясняю: ни в какую очередь SendMessage не идет - это, считай, прямой вызов CallWindowProc.


--------------------
...
PM   Вверх
dizzy1984
Дата 4.6.2008, 11:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 675
Регистрация: 15.2.2007

Репутация: 10
Всего: 25



И в самом деле лопухнулся! Ведь знал же, что если SendMessage вызывается кодом процесса породившим окно-получатель, сообщение не ставится в очередь! Выходит, мой код ничем не лучше вызова процедуры из OnInitDialog. Ладно, тогда вот 3-я редакция. На этот раз с PostMessage :
Код

static const UINT messageAppInit = ::RegisterWindowMessage("3D5914BB-6689-4697-81F9-4DADA4A5964B");    
BEGIN_MESSAGE_MAP(CTest2Dlg, CDialog)    
//...     
ON_REGISTERED_MESSAGE(messageAppInit, Proc2)     
//...     
END_MESSAGE_MAP()     
BOOL CTest2Dlg::OnInitDialog()     
{     
    //...     
    PostMessage(messageAppInit, 0, 0);     
    return FALSE;  // return TRUE  unless you set the focus to a control     
}     
void CTest2Dlg::Proc2()     
{      
    return ;     
}

Поставил флажки afxTraceFlags = traceAppMsg | traceWinMsg - вроде бы уж последнее-распоследнее.
Здесь-то хоть не накосячил?
PM MAIL   Вверх
Earnest
Дата 4.6.2008, 14:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 87
Всего: 183



Увы... smile  
В студии 7 и выше просто не скомпилируется, а в более ранних - весьма вероятны проблемы в релизе, т.к.
у обработчика должна быть другая сигнатура:
LRESULT CTest2Dlg::OnProc  (WPARAM, LPARAM);

И еще: использовать для имени зарегистрированного сообщения GUID, мягко говоря, неудобно. Смысл ведь в том, чтобы из разных мест можно было к одному сообщению обратиться, не перевязывая код общими хедерами... так что сообщение должно быть типа "Test2Dlg_InitMessage"... Но это мелочи




--------------------
...
PM   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Visual C++/MFC/WTL | Следующая тема »


 




[ Время генерации скрипта: 0.1023 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.