Программирование на Visual C++. Архив рассылки - Алекс Jenter
Шрифт:
Интервал:
Закладка:
Alexander Shargin по поводу ответа A1 (Sergey Emantayev) из №21 пишет:
Справедливости ради следует отметить, что всплывающие меню не обновляются в Idle loop'е. В нём обновляются тулбары, статус бар и т.п., но всплывающие меню обновляются только в ответ на WM_INITMENUPOPUP. Этой практики следует придерживаться и в собственных приложениях.
Продолжается дискуссия о комментариях:
Привет, что касается комментариев, то не кажется ли вам, господа, что сам код (естественно, грамотный код) и является самым лучшим и лаконичным комментарием к программе. И вообще, мне кажется, что комментарии нужны только тем людям, которые не писали конкретную программу, и причем, комментировать следует, только ключевые моменты, а если человек просто не понимает кода, то комментируй, не комментируй, это по барабану. Года два назад, я писал, одну небольшую софту, она работала под DDraw в полно-экранном режиме, я колбасил интерфейс a-la X-window Linux, фунций, переменных было море, и я закоментировал только, что и какая переменная делает, недавно, пришлось вернутся к этому коду, я его передал другому, человеку, немного видоизменив. И никаких проблем с восстановлением (в мозгу) архитектуры программы не было, как будто я с ней не работал не два года, а два дня. Код — это и сеть лучший комментарий, ну иногда желательно и присутствие "бумажной" модели программы.
Anton PalaginУ меня к Вам предложение по Вашей рассылки "Vsiual C++" – не могли бы Вы в поле сабжа каждой рассылки в конце ставить темы, которые рассматриваются в данном номере рассылки (например : "WinInet, Tray, Закладки"). Так будет значительно удобнее ориентироваться в архиве рассылке при поиске нужной темы. А то вот искал тот номер, где рассматривался вопрос с помещением программы в Tray и пришлось потратить некоторое время (линейно зависящее от количества вышедших номеров рассылки). А так посмотрел на заголовок и все понятно. А то поиск по сообщениям в Outlook Express глючный какой-то и нифига не находит.
Даниил ИвановОчень разумное предложение, на мой взгляд. Принял к исполнению – взгляните на subject этого выпуска. Спасибо, Даниил! Правда, в заголовок выношу только главную тему выпуска. Побочные придется искать по-старому.
В ПОИСКАХ ИСТИНЫQ. Все знают десктопные программы-ассистенты (screenmates/deskmates, MS Agent). Весь вопрос, что качественных, без артифактов, достаточно мало. Для реализации экранного помошника есть 2 различных подхода (если знаете еще, подскажите): – рисовать поверх десктопа, запоминать-востанавливать фон и т.д. Здесь сложно уследить за случаями, когда другие окна перекрывают место, где выводится текущий кадр персонажа, если на десктопе идет своя жизнь (меняются-появляются иконки, молчу про Drag'n'Drop) – использовать регионы, примеры есть на codeguru, но это достаточно трудоемкая штука – идея проста: создать полностью прозрачное окно и рисовать в нем просто текущий кадр с действием персонажа, не заботясь о том, на каком фоне его рисуешь, ведь окно прозрачное! Т.е. программа может просто рисовать постоянно меняющиеся картинки в таком прозрачном окне и это создаст эффект анимации персонажа, главное тут, чтобы любые изменения фона не влияли, т.е. просто добавление атрибута WS_EX_TRANSPARENT – это не то что нужно
Так вот, внимание, вопрос!
Знает ли кто, как можно создать такое полностью прозрачное-невидимое окно, которое при перемещении по экрану не тащит за собой кусок фона с предыдущего местоположения?
Кстати, на кодегуру прямого примера нет точно, а то что есть о том как рисовать прозрачные штучки – не то.
Valery Boronin АНОНСЧитайте в следующем выпуске
Многозадачность в Windows: теория и практика
Успехов в программировании!
Алекс Jenter [email protected] Красноярск, 2000.Программирование на Visual C++
Выпуск №23 от 12 ноября 2000 г.
Cын Билла Гейтса приходит к отцу и спрашивает:
"Папа, а что такое многозадачность?"
"Подожди, сынок, вот дискету доформатирую…"
Приветствую вас, уважаемые читатели!
Как я и ожидал, желающих становиться спонсором рассылки пока не нашлось. Ну что ж, ничего не поделаешь – будем придерживаться тогда пока старой системы.
СТАТЬЯ Многозадачность и ее применение Или зачем нужна многопоточность простому программистуОчень многие программисты, перейдя с DOS на Windows, в течение долгого времени все еще стараются программировать по-старому. Конечно, полностью это сделать не получается – такие вещи, как обработка сообщений, являются неотъемлемой частью любого Windows-приложения. Однако, 32-разрядная платформа в силу своей структуры предоставляет программистам новые захватывающие дух возможности. И если вы их не используете, а стараетесь решить проблему так, как привыкли, то вполне естественно, что из этого не получается ничего хорошего.
Эти возможности – возможности многозадачности. Прежде всего очень важно уяснить для себя, КОГДА вам следует подумать об ее использовании в своем приложении. Ответ так же очевиден, как и определение термина "многозадачность" – она нужна тогда, когда вы хотите, чтобы несколько участков кода выполнялось ОДНОВРЕМЕННО. Например, вы хотите, чтобы какие-то действия выполнялись в фоновом режиме, или чтобы в течение ресурсоемких вычислений, производимых вашей программой, она продолжала реагировать на действия пользователя. Я думаю, вы легко сможете придумать еще несколько примеров.
Процессы и потоки
Эти два понятия очень важны, и вы должны постараться их хорошенько осмыслить. Процессом (process) называется экземпляр вашей программы, загруженной в память. Этот экземпляр может создавать потоки (thread), которые представляют собой последовательность инструкций на выполнение. Важно понимать, что выполняются не процессы, а именно потоки. Причем любой процесс имеет хотя бы один поток. Этот поток называется главным (основным) потоком приложения.
Так как практически всегда потоков гораздо больше, чем физических процессоров для их выполнения, то потоки на самом деле выполняются не одновременно, а по очереди. (Заметьте, что распределение процессорного времени происходит именно между потоками, так как, еще раз повторю, процессы не выполняются.) Но переключение между ними происходит так часто, что кажется будто они выполняются параллельно.
В зависимости от ситуации потоки могут находиться в трех состояниях. Давайте посмотрим, что это за состояния. Во-первых, поток может выполняться, когда ему выделено процессорное время, т.е. он может находиться в состоянии активности. Во-вторых, он может быть неактивным и ожидать выделения процессора, т.е. быть в состоянии готовности. И есть еще третье, тоже очень важное состояние – состояние блокировки. Когда поток заблокирован, ему вообще не выделяется время. Обычно блокировка ставится на время ожидания какого-либо события. При возникновении этого события поток автоматически переводится из состояния блокировки в состояние готовности. Например, если один поток выполняет вычисления, а другой должен ждать результатов, чтобы сохранить их на диск. Второй мог бы использовать цикл типа "while (!isCalcFinished) continue;", но легко убедиться на практике, что во время выполнения этого цикла процессор занят на 100% (это называется активным ожиданием). Таких вот циклов следует по возможности избегать, в чем нам оказывает неоценимую помощь механизм блокировки. Второй поток может заблокировать себя до тех пор, пока первый не установит событие, сигнализирующее о том, что чтение окончено.
В системе выделяются два вида потоков – интерактивные, крутящие свой цикл обработки сообщений (такие, как главный поток приложения), и рабочие, представляющие собой простую функцию. Во втором случае поток завершается по мере завершения выполнения этой функции.
Заслуживающим внимания моментом является также способ организации очередности потоков. Можно было бы, конечно, обрабатывать все потоки по очереди, но такой способ далеко не самый эффективный. Гораздо разумнее оказалось ранжировать все потоки по приоритетам. Приоритет потока обозначается числом от 0 до 31, и определяется исходя из приоритета процесса, породившего поток, и относительного приоритета самого потока. Таким образом, достигается наибольшая гибкость, и каждый поток в идеале получает столько времени, сколько ему необходимо.
Иногда приоритет потока может изменяться динамически. Так интерактивные потоки, имеющие обычно класс приоритета Normal, система обрабатывает несколько иначе и несколько повышает фактический приоритет таких потоков, когда процесс, их породивший, находится на переднем плане (foreground). Это сделано для того, чтобы приложение, с которым в данный момент работает пользователь, быстрее реагировало на его действия.