Модераторы: feodorv, GremlinProg, xvr, Fixin
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Узнать запущен ли цикл обработки сообщений 
V
    Опции темы
borisbn
Дата 11.10.2012, 11:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 6
Всего: 135



Здравствуйте.
Делаю некий классик, в котором мне нужно реализовать две модели поведения: одну, если класс используется в консольном приложении без цикла обработки сообщений ( типа: while ( true ) { ... } ) и вторую, если класс используется в GUI-приложении, в котором цикл обработки сообщений запущен ( типа: while ( GetMessage(...) ) { PeekMessage + DispatchMessage } )
Собственно вопрос: как мне узнать, запущен ли цикл обработки сообщений или нет.
Спасибо.


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
YDean
Дата 11.10.2012, 12:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



GetActiveWindow()
для консоли возвращает ноль
PM   Вверх
borisbn
Дата 11.10.2012, 12:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 6
Всего: 135



YDean, неа. Не работает.
Цитата(GetActiveWindow)
The return value is the handle to the active window attached to the calling thread's message queue

Дело в том, что и в случае консоли и в случае GUI-приложения, мне нужно узнать о потоке обработки сообщений из другого (не оконного - working - потока), чтобы знать, вызывать SendMessage или вызывать некий callback напрямую.


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
YDean
Дата 11.10.2012, 12:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Непонятно.
Это надо знать на этапе компиляции?
В этом случае обычно определена _CONSOLE.
А если на этапе выполнения, то анализировать аргумент для SendMessage - (он ведь откуда-то берётся?)
PM   Вверх
Dem_max
Дата 11.10.2012, 13:22 (ссылка) |   (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

Репутация: 16
Всего: 39





--------------------
Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte")
PM MAIL   Вверх
xvr
Дата 11.10.2012, 13:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 40
Всего: 223



Цитата(Dem_max @ 11.10.2012,  13:22)
IsHungAppWindow() ????

http://www.rsdn.ru/article/qna/baseserv/hungapp.xml

Кстати, в статье говорится, что эта функция не документированна, но это уже не так - http://msdn.microsoft.com/en-us/library/wi...v=vs.85%29.aspx

Цитата

чтобы знать, вызывать SendMessage
Не понятно - если вы собираетесь звать SendMessage, то у вас есть HWND, кому вы собираетесь этот Message Send. А это значит, что это окно существует, а из этого следует, что там должен крутится цикл обработки сообщений, если конечно програмист не задумал создать окно для демонстрации состояния клинической смерти Win приложения  smile 


Это сообщение отредактировал(а) xvr - 11.10.2012, 13:53
PM MAIL   Вверх
borisbn
Дата 11.10.2012, 14:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 6
Всего: 135



Цитата(Dem_max @  11.10.2012,  13:22 Найти цитируемый пост)
IsHungAppWindow() 

Вау... Замечательно. И даже работает. Проверил. Единственное, что пугает - см. ниже ( в ответе для xvr )

Цитата(xvr @  11.10.2012,  13:52 Найти цитируемый пост)
Кстати, в статье говорится, что эта функция не документированна, но это уже не так 

Смущает это
Цитата
This function is not intended for general use. It may be altered or unavailable in subsequent versions of Windows


Цитата(xvr @  11.10.2012,  13:52 Найти цитируемый пост)
 кому вы собираетесь этот Message Send

Окну, которое сам создал. Но закручивать самому же цикл обработки сообщений нет никакого желания (особенно, если его уже закрутил какой-нибудь VCL или Qt)

В общем, делаю класс GUIMover, который в конструкторе создаёт окно, в обработчике которого дёргается заданный callback, а в функции move делается SendMessage своему окну.
Код

template< class Master >
class GuiMover
{
    typedef void (Master::*wait_func)( UINT message, WPARAM wParam, LPARAM lParam );
public:
    GuiMover( wait_func waitFunc, Master * master )
      : m_waitFunc( waitFunc )
      , m_master( master )
    {
        m_wnd = CreateWindowA( "STATIC", "", 0, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, HWND_MESSAGE, NULL, NULL, NULL);
        SetWindowLongPtr( m_wnd, GWL_USERDATA, (LONG_PTR)this );
        SetWindowLongPtr( m_wnd, GWL_WNDPROC, (LONG_PTR)s_netWndProc );
    }
    void move( UINT message, WPARAM wParam = 0, LPARAM lParam = 0 ) {
        ::SendMessage( m_wnd, message, wParam, lParam ); // <--------------- тут виснет в console-приложении
    }
    ~GuiMover() {
        DestroyWindow( m_wnd );
    }

private:
    static LRESULT CALLBACK s_netWndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
    {
        GuiMover< Master > * self = ( GuiMover< Master > * ) GetWindowLongPtr( hWnd, GWL_USERDATA );
        (self->m_master->*self->m_waitFunc)( message, wParam, lParam );
        return 0;
    }

    wait_func m_waitFunc;
    Master * m_master;
    HWND m_wnd;
};



Это сообщение отредактировал(а) borisbn - 11.10.2012, 14:13


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
xvr
Дата 11.10.2012, 14:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 40
Всего: 223



Цитата(borisbn @  11.10.2012,  14:11 Найти цитируемый пост)
Окну, которое сам создал.

Тогда отправьте сами тестовое сообщение (через SendMessageTimeout). Если не дойдет, то цикла обработки сообщений нет.

Цитата(borisbn @  11.10.2012,  14:11 Найти цитируемый пост)
Смущает это

Это есть. Но это все же лучше, чем полная недокументированность  smile

Добавлено через 14 минут и 6 секунд
Можно еще попробовать GetMessageTime(). Сравните то, что она вернет с текущим временем (ну и с 0 на всякий случай). Если там разница более нескольких секугд - то цикл обработки сообщений отвалился  smile 
PM MAIL   Вверх
borisbn
Дата 11.10.2012, 15:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 6
Всего: 135



Цитата(xvr @  11.10.2012,  14:16 Найти цитируемый пост)
Тогда отправьте сами тестовое сообщение (через SendMessageTimeout). Если не дойдет, то цикла обработки сообщений нет

Уже думал. Делать это каждый раз - глупо - при наличии отсутствия потока обработки будет подвисать на время таймаута. Делать это в конструкторе тоже нельзя, т.к. мой класс могут создать ДО запуска потока приложения. например:
Код

int main() {
    QApplication a;
    SomeWidget w;
    GuiMover< SomeWidget > m( ... ); // ( 1 )
    w.show();
    a.exec();     // ( 2 )
}



Это сообщение отредактировал(а) borisbn - 11.10.2012, 15:20


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
borisbn
Дата 11.10.2012, 16:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 6
Всего: 135



В общем, решил не заморачиваться, а отдать всё на откуп юзерам... Ну... типа сам виноват, если вообще стал использовать этот класс, не позаботившись о запуске потока обработки сообщений.
Если кому нужно - вот классик с описанием


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
Dem_max
Дата 11.10.2012, 16:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

Репутация: 16
Всего: 39



Используй такую конструкцию
Код

// An application returns zero if it processes this message.
SendMessageTimeOut(hWnd, 
      WM_NULL, 
      0, 
      0, 
      SMTO_NORMAL | SMTO_ABORTIFHUNG, 
      dwTime, 
      &lpdwResult);


Цитата

As another example, an application can check if a window is responding to messages by sending the WM_NULL message with the SendMessageTimeout function.



--------------------
Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte")
PM MAIL   Вверх
xvr
Дата 11.10.2012, 19:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 40
Всего: 223



Цитата(borisbn @  11.10.2012,  15:18 Найти цитируемый пост)
Делать это каждый раз

Делайте 1 раз - при посылке первого сообщения. Если не получилось послать - переключайтесь на прямой вызов callback'а

PM MAIL   Вверх
borisbn
Дата 11.10.2012, 19:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 6
Всего: 135



Цитата(xvr @  11.10.2012,  19:41 Найти цитируемый пост)
Делайте 1 раз - при посылке первого сообщения

тоже "просчитывал"... в приведённом примере:
Цитата(borisbn @  11.10.2012,  15:18 Найти цитируемый пост)
Код

int main() {
    QApplication a;
    SomeWidget w;
    GuiMover< SomeWidget > m( ... ); // ( 1 )
    w.show();
    a.exec();     // ( 2 )
}

если в конструкторе SomeWidget запускается поток, который шлёт ему callback'и, то первй вызов GuiMover::move будет ещё без a.exec(), и, соотв., я переключусь в режим прямых callback'ов...


Ладно.... мужики... спасибо. Буду заставлять юзеров читать описание... Тем более, что использование этого класса в консоли (!!!) под Windows (!!!) - маловероятно )))


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
Dem_max
Дата 12.10.2012, 04:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

Репутация: 16
Всего: 39



Цитата

если в конструкторе SomeWidget запускается поток, который шлёт ему callback'и, то первй вызов GuiMover::move будет ещё без a.exec(), и, соотв., я переключусь в режим прямых callback'ов...

Значит наверное алгоритм не правильный.


--------------------
Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte")
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »


 




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


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

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