|
||||
|
Программирование на Visual C++Выпуск №3 от 23/06/2000 Здравствуйте! Да, это должно было произойти и это произошло! Рассылка получила официальный статус "обычной некоммерческой рассылки" (причем гораздо быстрее, чем я ожидал), с чем я себя и всех вас и поздравляю! Хочу извиниться перед подписчиками HTML-версии: во втором выпуске случилось некоторое искажение исходного кода (я упустил из виду, что при автоматической генерации HTML сервер Гор. Кота звездочки (*) интерпретирует как указание сделать шрифт жирным), в результате чего были потеряны указатели. Вот как этот код должен был выглядеть на самом деле: CRunTimeClass *pClass = RUNTIME_CLASS(СMyObject); // получаем ук-ль на структуру CRunTimeClass CObject *pNewObject = pClass->CreateObject(); // создаем новый объект нужного класса ASSERT(pNewObject->IsKindOf(RUNTIME_CLASS(CMyObject)); // проверяем класс объекта Меня удивило, что большинство из вас подписывается именно на HTML – я думал, наши люди как никакие другие считают каждый килобайт. Но, видимо, времена меняются – в лучшую сторону. Дай бог! Так что по вышеописанным причинам я решил поднапрячься и сработать собственный HTML-вариант. То, что получилось, сейчас перед вами, уважаемые HTML-подписчики. Тех, кто выписывает текстовый вариант, уговаривать подписаться на HTML я не буду, потому что прекрасно их понимаю ;) Оба варианта я буду делать лично, никакой автоматической генерации. Enjoy. ОБРАТНАЯ СВЯЗЬМне пришло интересное письмо на тему предыдущего выпуска. Хочу предложить его вашему вниманию:
Что ж, огромное спасибо Борису за комментарии и дополнения. Я надеюсь, он и в будущем будет нам посильно помогать. Что касается вопроса Броника – думаю, он все-таки спрашивал не о том, как сделать сериализацию для ActiveX(хотя это тоже очень интересный момент), а как организовать структурированное хранение данных в файле , наподобие того, что присутствует в ActiveX. Ответа на этот вопрос, за исключением предложенного мной в предыдущем выпуске, пока нет. Просьба: когда пишете мне, пожалуйста оговаривайте ваше отношение к публикации вашего e-mail адреса. Я оставляю за собой право решать, какие из ваших писем появятся в рассылке. По умолчанию адрес публиковаться не будет. Если вы хотите связаться с человеком, письмо которого вы прочитали в рассылке, но чей адрес не был указан, пишите мне с пометкой в subject'e для кого это письмо. ВОПРОС – ОТВЕТ
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:jenter@mail.ru) (Красноярск, 2000.) |
|
||
Главная | В избранное | Наш E-MAIL | Прислать материал | Нашёл ошибку | Наверх |
||||
|