Алекс Jenter - Программирование на Visual C++. Архив рассылки

Здесь есть возможность читать онлайн «Алекс Jenter - Программирование на Visual C++. Архив рассылки» весь текст электронной книги совершенно бесплатно (целиком полную версию без сокращений). В некоторых случаях можно слушать аудио, скачать через торрент в формате fb2 и присутствует краткое содержание. Жанр: Программирование, на русском языке. Описание произведения, (предисловие) а так же отзывы посетителей доступны на портале библиотеки ЛибКат.

Программирование на Visual C++. Архив рассылки: краткое содержание, описание и аннотация

Предлагаем к чтению аннотацию, описание, краткое содержание или предисловие (зависит от того, что написал сам автор книги «Программирование на Visual C++. Архив рассылки»). Если вы не нашли необходимую информацию о книге — напишите в комментариях, мы постараемся отыскать её.

РАССЫЛКА ЯВЛЯЕТСЯ ЧАСТЬЮ
, НА САЙТЕ КОТОРОГО ВСЕГДА МОЖНО НАЙТИ ВСЮ НЕОБХОДИМУЮ РАЗРАБОТЧИКУ ИНФОРМАЦИЮ, СТАТЬИ, ФОРУМЫ, РЕСУРСЫ, ПОЛНЫЙ АРХИВ ПРЕДЫДУЩИХ ВЫПУСКОВ РАССЫЛКИ И МНОГОЕ ДРУГОЕ.

Программирование на Visual C++. Архив рассылки — читать онлайн бесплатно полную книгу (весь текст) целиком

Ниже представлен текст книги, разбитый по страницам. Система сохранения места последней прочитанной страницы, позволяет с удобством читать онлайн бесплатно книгу «Программирование на Visual C++. Архив рассылки», без необходимости каждый раз заново искать на чём Вы остановились. Поставьте закладку, и сможете в любой момент перейти на страницу, на которой закончили чтение.

Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать
MFC

Сегодня я хочу представить вашему вниманию статью – перевод из MSJ C++ Q&A, которую прислал Илья Простакишин.

Решение проблемы с OnIdle в dialog-based приложениях

Проблема в том, что OnIdle работает нормально только в приложениях document/view, что не скажешь о приложениях dialog-based. Функция CApp::InitInstance вызывает dlg.DoModal, которая в свою очередь вызывает CWnd::RunModalLoop, а та никогда не обращается к OnIdle. Кажется, что можно производить фоновую обработку посредством WM_ENTERIDLE, но это сообщение направляется только родительскому окну диалога, которого в нашем случае просто не существует. Как решить эту проблему?

Модальные диалоги на самом деле лишь имитируются в MFC. Когда вы вызываете CDialog::DoModal, MFC не вызывает ::DialogBox, как можно было ожидать; вместо этого вызывается ::CreateDialogIndirect, затем модальное поведение имитируется путем блокировки родительского окна и запуска своего собственного цикла обработки сообщений. По существу, тоже самое делает функция ::DialogBox. Тогда зачем изобретать велосипед? А дело в том, что теперь MFC имеет свой собственный цикл, в то время как раньше он "прятался" внутри функции API ::DialogBox. Это позволяет MFC обрабатывать сообщения посредством обычных потоков MFC (CWinThread::PumpMessage), что и делается с другими типами окон. В результате вы можете переопределять CWnd::PreTranslateMessage для модальных диалогов – например, для реализации "горячих" клавиш. Ранние версии MFC позволяли реализовывать свою собственную функцию PreTranslateMessage для модального диалога. Но толку от этого было мало, ведь она все равно никогда не вызывалась, т.к. CDialogDoModal напрямую обращалась к ::DialogBox. При этом управление в программу не возвращалось, пока один из обработчиков сообщений вашего диалога не вызывал EndDialog. По этой же причине была невозможна обработка интервала ожидания.

Вместо этого Windows имеет свой собсвенный механизм, WM_ENTERIDLE, предназначенный для обработки интервала ожидания в модальных диалогах. После обработки одного или нескольких сообщений, если в очереди больше ничего нет, Windows автоматически посылает WM_ENTERIDLE окну-владельцу модального диалога или меню. Работает это только в модальных диалогах. Поскольку MFC теперь использует немодальные диалоги в качестве модальных, WM_ENTERIDLE посылается библиотекой "вручную", чтобы самостоятельно имитировать модальные диалоги, но, опять же, только если имеется родительское окно.

Хорошо, если все сообщения модального диалога проходят через стандартную очередь, почему не вызывается CWnd::OnIdle, как часть этого процесса? Проблема в том, что функция CWnd::RunModalLoop вызывает CWinThread::PumpMessage, однако OnIdle вызывается только внутри CWinThread::Run. MFC вызывает CWinThread::Run для запуска вашего приложения после вызова функции InitInstance. В сокращенном виде функция CWinThread::Run выглядит так:

// (from THRDCORE.CPP)

int CWinThread::Run() {

// for doing idle cycle

BOOL bIdle = TRUE;

LONG lIdleCount = 0;

for (;;) {

while (bIdle && !::PeekMessage(…)) {

// call OnIdle while in bIdle state

if (!OnIdle(lIdleCount++)) // assume "no idle" state

bIdle = FALSE;

}

// Get/Translate/Dispatch the message

// (calls CWinThread::PumpMessage)

}

}

Я убрал все лишнее, чтобы заострить внимание на том, как реализована обработка интервала ожидания. Если соообщений не поступает, MFC вызывает CWinThread::OnIdle, каждый раз увеличивая аргумент-счетчик. Вы можете использовать этот счетчик для установки приоритета различиных обработчиков интервала ожидания. Например, можно выполнять форматирование (диска C:, например :)), когда счетчик ожидания равен 1, затем обновлять показания часов при счетчике, равном 2 и т.п. Если OnIdle возвращает FALSE, то MFC прекращает его вызывать и ждет пока ваш поток получит какое-нибудь сообщение, просле чего обработчик будет вызываться снова.

Обратите внимание, что модальный диалог никогда не будет выполнять этот код, поскольку CWnd::RunModalLoop вызывает CWinThread::PumpMessage сразу из своего собственного цикла обработки сообщений. Он не вызывает CWinThread::Run и, следовательно, никогда не обращается к CWinThread::OnIdle. По-видимому, так было задумано разработчиками. Очевидно, что опасно вызывать OnIdle внутри модального диалога, поскольку многие обработчики сообщений создают временные объекты CWnd, которые, вполне возможно, будут существовать все время, пока существует диалог. Частью процесса обработки OnIdle является освобождение временных карт дескрипторов (handle).

Не могу удержаться от упоминания о том, что механизм временной/постоянной карты дескрипторов (handle map), используемый для связывания дескрипторов HWND с классами CWnd – это один из самых потенциально опасных элементов каркаса приложения, даже более опасный, чем карты сообщений. Проблема "временной карты" непрерывно преследует программистов, особенно в многопотоковых приложениях, делая их трудными для написания в MFC.

Читать дальше
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

Похожие книги на «Программирование на Visual C++. Архив рассылки»

Представляем Вашему вниманию похожие книги на «Программирование на Visual C++. Архив рассылки» списком для выбора. Мы отобрали схожую по названию и смыслу литературу в надежде предоставить читателям больше вариантов отыскать новые, интересные, ещё непрочитанные произведения.


Алексей Макеев - Смертельный архив
Алексей Макеев
libcat.ru: книга без обложки
Алексей Апухтин
Отзывы о книге «Программирование на Visual C++. Архив рассылки»

Обсуждение, отзывы о книге «Программирование на Visual C++. Архив рассылки» и просто собственные мнения читателей. Оставьте ваши комментарии, напишите, что Вы думаете о произведении, его смысле или главных героях. Укажите что конкретно понравилось, а что нет, и почему Вы так считаете.

x