Вверх
Выше описанное приложение работает хорошо, но каждый раз
при движении мышью указатель меняет свою форму на указанную
по умолчанию. Как сохранить указанную нами новую форму мыши?
Всякий раз, когда надо перерисовать указатель мыши -например
при ее перемещении - вашему приложению направляется сообщение
о событии WM_SETCURSOR. Надо изменить поведение приложения
обусловленное этим событием так, чтобы новая форма указателя
мыши не изменялась до тех пор, пока вы ее не измените умышленно.
Выполните пошаговые инструкции :
//инициализировать курсор в виде стрелки
m_bCursor = FALSE;
Листинг 4.5 Функия OnInitDialog
SetIcon(m_hIcon,TRUE);//установить большой значек
//инициализировать курсор в виде стрелки
m_bCursor = FALSE;
return TRUE;
Листинг 4.6 Функция OnKeyDown
cChar = char(nChar);
if(cChar == 'A')
if(cChar == 'C')
OnOK();
else
CDialog::OnKeyDown(nChar,nRepCnt,nFlags)
}
Листинг 4.7
Необходимо чтобы функция OnSetCursor() всегда возвращала значение TRUE
или как то иначе вызывала основную функцию. Основная функция (АВ:имеется в
виду функция OnKeyDown?) изменяет указатель мыши и ее не следует вызывать
при запуске приложения.Поэтому переменной следует присвоить значение FALSE
(АВ:в функции OnInitDialog)-благодаря чему до тех пор, пока пользователь
не нажмет одну из клавиш, с помощью которых меняется форма указателей мыши,
будет выполняться функция OnSetCursor, заданная по умолчанию.
После того как пользователь изменил форму указателя мыши, требуется обойти
обработку по умолчанию и возвратить значение TRUE.(АВ:это и сделано в
измененной нами функции OnSetCursor).Это позволит пользователю
рисовать любым выбранным им указателем мыши, включая даже песочные часы.
hPrevCursor = SetCursor(hCursor);
Это сделано затем.что функция OnSetCursor нами немного переделана
таким образом, что если переменная m_bCursor имеет значение не ноль
(а значит единица) ,то функция возвратит TRUE:
Напоминаю что функция OnSetCursor вызывается системой постоянно (циклически)
в те моменты, когда мышь движется (а курсор движится по экран)у,
благодаря этой функции изображение курсора все время перерисовывается
в новом месте экрана.
При возвращении нашей функцией OnSetCursor значения TRUE без вызова функции
OnSetCursor заданной по умолчанию, сохраняется тот курсор
который имеется на экране в данный момент. А функция OnSetCursor вызывается
постоянно с определенной частотой при перемещении курсора по экрану, так как курсор при этом постоянно надо перерисовывать, а благодаря именно этой функции система перерисовывает
курсор заданный по умолчанию.
Вверх
Все стандартные команды контекста устройства для рисования на экране
по умолчанию используют карандаш (часто называемый пером). Он во многом подобен обычному карандашу, которым вы рисуете на бумаге. Чтобы нарисовать
более толстую линию или изменить цвет, необходимо взять новый карандаш.
Это можно сделать изменив код функции OnMouseMove с того места,
где создается контекст устройства.
Следующий код позволяет рисовать толстым красным карандашом:
//создать новое перо
//использовать новое перо
//провести линию от предыдущей точки до текущей точки
Следует вызвать другую функцию - ::GetKeyState с ключом конкретной клавиши. Эта функция
позволяет определить была ли нажата указанная вами клавиша.
Если значение возвращаемое функцией ::GetKeyState отрицательно, то интересующая клавиши
нажата.В противном случае клавиша не нажата.
Например чтобы определить была ли нажата клавиша Shift, можно воспользоваться
следующим кодом:
В Windows для всех специальных клавиш определены виртуальные ключи.
Можно воспользоваться этими виртуальными ключами в функции ::GetKeyState
или передать их функции OnKeyDown в качестве аргумента nChar.
Список виртуальных ключей находится в документации Visual C++.
Назад |
Начало урока |
Вверх |
Фиксация формы указателя мыши
BOOL CMousDlg::OnInitDialog
{
//Добавить пункт меню "About ... " к системному меню.
//IDM_ABOUTBOX должен быть среди системных команд.
ASSERT(IDB_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDB_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSistemMenu(FALSE);//
if(pSysMenu != NULL) //пустой указатель
{
strAboutMenu.LoadString(IDS_ABOUTBOX);
if(!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_STRING,IDM_ABOUTBOX,strAboutMenu);
//установить пиктограмму для этого диалога
//Каркас делает это автоматически,
//когда основное окно приложения не диалог
SetIcon(m_hIcon,FALSE);//установить маленький значек
void CMouseDlg::OnKeyDown(UINT nChar,UINT nRepCnt,UINT nFlags)
{
HCURSOR hCursor = 0;
HCURSOR hPrevCursor = 0;
{
m_bCursor(TRUE);
hPrevCursor = SetCursor(hCursor);
if(hPrevCursor)
DestroyCursor(hPrevCursor);
{
{
m_bCursor = TRUE;
if(hPrevCursor)
DestroyCursor(hPrevCursor);
BOOL CMouseDlg:: OnSetCursor(CWnd pWnd,UINT nHitTest,UINT message)
{
return TRUE;
return CDialog::OnSetCursor(pWnd,nHitTest,message);
Сначала объявляем переменную m_bCursor типа BOOL,
затем в функции OnInitDialog присваиваем ей значение FALSE.
Затем в функции OnKeyDown в случаях,когда выбраны клавиши 'A', 'B' или 'C' вызывается функция SetCursor, которой передается дескриптор нового курсора,и одновременно переменной m_bCursor присваивается значение TRUE:
m_bCursor = TRUE;
BOOL CMouseDlg:: OnSetCursor(CWnd pWnd,UINT nHitTest,UINT message)
{
if(m_bCursor)
return TRUE;
return CDialog::OnSetCursor(pWnd,nHitTest,message);
}
Резюме
Вы узнали :
Вопросы и ответы
Вверх
//получить контекст устройства
CClientDC dc(this);
CPen lpen(PS_SOLID,16,RGB(255,0,0));
dc.SelectObject(&lpen);
dc.MoveTo(m_iPrevX,m_iPrevY);
dc.LineTo(point.x,point.y);
if(::GetKeyState(VK_SHIFT)<0)
MessageBox("Shift key is down");
Вопросы
Упражнения
Содержание