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

Шрифт
Интервал

с пометкой в subject'e для кого это письмо.

ВОПРОС – ОТВЕТ

Q. Идея рассылки и её тематика очень понравились, даже добавлять или изменять ничего не хочется, как по заказу. И даже уже вопрос созрел. При первом знакомстве с MFC помню была одна проблема. Никак не получалось сменить пиктограмку курсора во время выполнения программы. Т.е. последовательность стандартных действий LoadCursor и SetCursor не срабатывала, хотя при создании окна этих действий хватало. В связи с этим вопрос: Какие ещё действия надо выполнить для смены пиктограмки курсора во время работы приложения. Сейчас, к сожалению, интересы лежат не в области C++ и MFC. Поэтому на разрешение вопроса своими силами просто нет времени.

softmax

A. Спасибо за добрые слова о рассылке. По вопросу – проблема здесь в том, что система автоматически при каждом движении мыши восстанавливает тот курсор, который был указан при регистрации класса окна. Вообще я знаю три способа изменить курсор в MFC-приложении, причем два из них имеют некоторые ограничения: один используется, в самом деле, при создании окна, а второй работает только с одним курсором – стандартными песочными часами. Думаю, что стоит описать все три способа, для того, чтобы вы могли выбрать наиболее для вас подходящий. Итак:

Способ №1 (универсальный). Нужно перекрыть функцию OnSetCursor() класса CWnd, родителя вашего окна (вида). В ней необходимо сообщение обработать самому, устанавливая нужный курсор. Для тех, кто не знает, сообщение WM_SETCURSOR посылается окну тогда, когда курсор мыши двигается внутри окна, причем  мышь приложением  не захвачена (с помощью функции SetCapture()). Вот пример из MSDN:

>BOOL CMyView::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) {

> if (m_ChangeCursor) {

>  // устанавливаем стандартный курсор вида "I"

>  ::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_IBEAM));

>  return TRUE;

> }

> return CView::OnSetCursor(pWnd, nHitTest, message);

>}

Конечно, можно установить и ваш собственный курсор, только вместо LoadStandardCursor() нужно будет воспользоваться LoadCursor() или LoadOEMCursor(). С помощью параметра nHitTest можно определить область, в которой сейчас находится курсор. Вообще, этот способ лучше применять только тогда, когда вам в самом деле нужно динамически менять один курсор на другой (причем отличный от песочных часов), потому этот способ самый нерациональный (прикиньте-ка. сколько раз будет выполняться этот обработчик). Лучше все нужные курсоры загрузить заранее, а из функции– обработчика Load..Cursor() не вызывать. Хотя, в принципе, я для примера сделал такой обработчик – никакой разницы в скорости не заметил…но это уже зависит от конкретного компьютера, наверное. И потом, наверное не стали бы в MSDN это советовать, если бы не знали, что делали ;) 

Ну а тем, кому лишь надо видом курсора  показать пользователю, что компьютер сейчас занят какой-то операцией, идеально подходит

Способ №2 (песочные часы). Этот способ самый простой. Вызывайте функцию BeginWaitCursor() перед началом операции и EndWaitCursor() после ее завершения. Единственный нюанс здесь в том, что если эти два вызова должны находиться в разных функциях-обработчиках, то вам все же придется перекрыть OnSetCursor(), причем это выглядит примерно так:

>BOOL CMyView::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) {

> if (m_ChangeCursor) {

>  RestoreWaitCursor(); // восстанавливаем курсор-пес.часы

>  return TRUE;

> }

> return CView::OnSetCursor(pWnd, nHitTest, message);

>}

В этом случае перед вызовом BeginWaitCursor()  m_ChangeCursor нужно приравнять к TRUE, а после EndWaitCursor() – к FALSE.

Способ №3 (класс окна). Этот метод применяется, когда вам для какого-то окна нужно установить конкретный курсор, причем желательно на все время существования окна. Перекрываете PreCreateWindow() и регистрируете свой класс окна, изменяя поле lpszClass параметра cs типа CREATESTRUCT:

>BOOL CMyView::PreCreateWindow(CREATESTRUCT& cs) {

> cs.lpszClass = AfxRegisterWndClass(

>  CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW, //стили окна

>  AfxGetApp()->LoadCursor(IDC_MYCURSOR),// курсор

>  (HBRUSH)(COLOR_WINDOW + 1));          // цвет фона окна

> return CView::PreCreateWindow(cs)

>}

В  качестве  первого параметра для AfxRegisterWndClass() можно указать "cs.style", чтобы установить стиль окна по умолчанию.


Ну вот и все на сегодня. Удачного вам программирования.

©Алекс Jenter mailto:[email protected]
Красноярск, 2000.

Программирование на Visual C++

Выпуск №4 от 25/06/2000

Добрый день, уважаемые подписчики!

Мне приходит очень много ваших писем с вопросами, советами, комментариями, предложениями и т.д. Как повелось, самые интересные из них я публикую в рубриках "Обратная связь" и "Вопрос-ответ". Но, как вы наверное сами понимаете, я просто физически не в состоянии отвечать на такое количество вопросов, касающихся программирования. Я отвечаю быстро, когда сразу знаю ответ, но ведь чаще приходится самому сидеть и разбираться, а на это уходит много времени. От этого в первую очередь страдают другие рубрики рассылки – я не успеваю подготовить хороший материал для вас (кстати, я как раз хочу сделать несколько новых рубрик… но пусть лучше это будет сюрприз). Моя задача как автора рассылки состоит в том, чтобы готовить и публиковать интересную информацию по обозначенной тематике. Я же в последнее время больше сам занимаюсь  программированием. Для меня, это, конечно, полезно ;) но вот как насчет вас? На многие вопросы я уже ответил, хотя они не появятся в рассылке, т.к. довольно узко направлены и вряд ли интересны для "широкой общественности". Ответы на другие или слишком обширны и тянут на тему отдельного выпуска, или попросту элементарны.


Рекомендуем почитать
Pro Git

Разработчику часто требуется много сторонних инструментов, чтобы создавать и поддерживать проект. Система Git — один из таких инструментов и используется для контроля промежуточных версий вашего приложения, позволяя вам исправлять ошибки, откатывать к старой версии, разрабатывать проект в команде и сливать его потом. В книге вы узнаете об основах работы с Git: установка, ключевые команды, gitHub и многое другое.В книге рассматриваются следующие темы:основы Git;ветвление в Git;Git на сервере;распределённый Git;GitHub;инструменты Git;настройка Git;Git и другие системы контроля версий.


Java 7

Рассмотрено все необходимое для разработки, компиляции, отладки и запуска приложений Java. Изложены практические приемы использования как традиционных, так и новейших конструкций объектно-ориентированного языка Java, графической библиотеки классов Swing, расширенной библиотеки Java 2D, работа со звуком, печать, способы русификации программ. Приведено полное описание нововведений Java SE 7: двоичная запись чисел, строковые варианты разветвлений, "ромбовидный оператор", NIO2, новые средства многопоточности и др.


MFC и OpenGL

В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.


Симуляция частичной специализации

В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.


Обработка событий в С++

В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.


Питон — модули, пакеты, классы, экземпляры

Python - объектно-ориентированный язык сверхвысокого уровня. Python, в отличии от Java, не требует исключительно объектной ориентированности, но классы в Python так просто изучить и так удобно использовать, что даже новые и неискушенные пользователи быстро переходят на ОО-подход.