Изменение курсора Win API
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
| ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
| [216.73.217.99] |
С Днём Победы, друзья!
|
|
Правила раздела C/C++: Системное программирование и WinAPI
FAQ Сайта (C++)
FAQ Форума
Наши Исходники
Поиск по Разделу
MSDN Library Online (Windows Driver Kit)
Google
Изменение курсора Win API
|
Сообщ.
#1
,
|
|
|
|
Доброго времени суток. Необходимо изменять курсор над определённой областью окна. Вот мой код, курсор меняется, однако не над областью, которая мне нужна, а над всей рабочей областью окна. Подскажите, где ошибка, заранее благодарен!
![]() ![]() case WM_SETCURSOR: { HCURSOR hBlackCursor = LoadCursor(hInstan, "BLACK_CUR"); HCURSOR hBlueCursor = LoadCursor(hInstan, "BLUE_CUR"); HCURSOR hWhiteCursor = LoadCursor(hInstan, "WHITE_CUR"); HCURSOR hRedCursor = LoadCursor(hInstan, "RED_CUR"); if(((LOWORD(lp) >= 0 && HIWORD(lp) >= 0) && (LOWORD(lp) <= 800 && HIWORD(lp) <= 600)) && (ActiveChip == 1)) { SetCursor(hBlackCursor); break; } if(((LOWORD(lp) >= 0 && HIWORD(lp) >= 0) && (LOWORD(lp) <= 800 && HIWORD(lp) <= 600)) && (ActiveChip == 5)) { SetCursor(hBlueCursor); break; } if(((LOWORD(lp) >= 0 && HIWORD(lp) >= 0) && (LOWORD(lp) <= 800 && HIWORD(lp) <= 600)) && (ActiveChip == 25)) { SetCursor(hWhiteCursor); break; } if(((LOWORD(lp) >= 0 && HIWORD(lp) >= 0) && (LOWORD(lp) <= 800 && HIWORD(lp) <= 600)) && (ActiveChip == 100)) { SetCursor(hRedCursor); break; } } |
|
Сообщ.
#2
,
|
|
|
|
Вполне возможно, что у вас ActiveChip принимает какое-то одно значение, а потому другие виды курсора не ставятся. Проясните значение и место изменения этой переменной, тогда посмотрим внимательнее.
И скажите, какова нужная вам область, а то везде 800x600 ?.. Добавлено А ещё лучше как-то бы так, наверное: ![]() ![]() if( (LOWORD(lp)>=0 && HIWORD(lp)>=0 && LOWORD(lp)<=800 && HIWORD(lp)<=600 ) switch( ActiveChip ) { case 1: SetCursor(hBlackCursor); break; ... case 100: SetCursor(hRedCursor); break; } else SetCursor(LoadCursor(IDC_ARROW));// стандарт Добавлено Ну и ещё один break опосля if/else... |
|
Сообщ.
#3
,
|
|
|
|
а что такое lp?
|
|
Сообщ.
#4
,
|
|
|
|
Цитата Relaxander @ Очевидноа что такое lp? ![]() ![]() LPARAM lp |
|
Сообщ.
#5
,
|
|
|
|
Славян , ActiveChip принимает значения 1, 5, 25, 100. По идее оно меняется. Вот код по ActiveChip:
![]() ![]() case LBUTTONDOWN: { ... if ((LOWORD(lp) >= 50 && HIWORD(lp) >= 638) && (LOWORD(lp) <= 130 && HIWORD(lp) <= 718)) ActiveChip = Chip1; if ((LOWORD(lp) >= 150 && HIWORD(lp) >= 638) && (LOWORD(lp) <= 230 && HIWORD(lp) <= 718)) ActiveChip = Chip5; if ((LOWORD(lp) >= 250 && HIWORD(lp) >= 638) && (LOWORD(lp) <= 330 && HIWORD(lp) <= 718)) ActiveChip = Chip25; if ((LOWORD(lp) >= 350 && HIWORD(lp) >= 638) && (LOWORD(lp) <= 430 && HIWORD(lp) <= 718)) ActiveChip = Chip100; ... } А насчёт области, везде нужна 800х600, в зависимости от ActiveChip курсор должен изменятся над это областью. |
|
Сообщ.
#6
,
|
|
|
|
Цитата kalter14i77 @ Ясно. Ну тогда примените те строки, кои я выше написал. Добавить к ним ещё надо А насчёт области, везде нужна 800х600, в зависимости от ActiveChip курсор должен изменятся над это областью. ![]() ![]() default: SetCursor(LoadCursor(IDC_ARROW));// стандарт |
|
Сообщ.
#7
,
|
|
|
|
Славян Попробовал ваш вариант. Вот что получилось:
![]() ![]() case WM_SETCURSOR: { HCURSOR hBlackCursor = LoadCursor(hInstan, "BLACK_CUR"); HCURSOR hBlueCursor = LoadCursor(hInstan, "BLUE_CUR"); HCURSOR hWhiteCursor = LoadCursor(hInstan, "WHITE_CUR"); HCURSOR hRedCursor = LoadCursor(hInstan, "RED_CUR"); if(((LOWORD(lp) >= 0 && HIWORD(lp) >= 0) && (LOWORD(lp) <= 800 && HIWORD(lp) <= 600))) switch( ActiveChip) { case 1: {SetCursor(hBlackCursor); break;} case 5: {SetCursor(hBlueCursor); break;} case 25: {SetCursor(hWhiteCursor); break;} case 100: {SetCursor(hRedCursor); break;} default: SetCursor(LoadCursor(hInstan, IDC_ARROW)); } else SetCursor(LoadCursor(hInstan, IDC_ARROW)); } return 0; Теперь, когда ActiveChip = 0, курсор не отображается вообще, а когда равно 1, 5, 25, 100, выбирается нужный, но работает опять же над всей областью. Изначально в классе окна я прописывал так ![]() ![]() wc.hCursor = NULL; |
|
Сообщ.
#8
,
|
|
|
|
Цитата kalter14i77 @ Изначально в классе окна я прописывал так wc.hCursor = LoadCursor(hInstan, IDC_ARROW); |
|
Сообщ.
#9
,
|
|
|
|
Relaxander прописал по вашему, всё равно та же проблемма
|
|
Сообщ.
#10
,
|
|
|
|
Цитата kalter14i77 @ Ваш обработчик - для всего окна или только для вашей области? Если для всего окна, то странно, т.к. у вас есть явные проверки попадания в 800x600. Опишите поподробнее цепочку "выбирается нужный, но работает над всей областью". Верно ли, что выбрался, скажем, красный, а после ухода за область (0,0)..(800,600) он остался красным? Или как?а когда равно 1, 5, 25, 100, выбирается нужный, но работает опять же над всей областью. П.С. фигурные скобки в case'ах можете=лучше убрать. |
|
Сообщ.
#11
,
|
|
|
|
Цитата kalter14i77 @ Необходимо изменять курсор над определённой областью окна. ![]() ![]() case WM_SETCURSOR: { HCURSOR hBlackCursor = LoadCursor(hInstan, "BLACK_CUR"); HCURSOR hBlueCursor = LoadCursor(hInstan, "BLUE_CUR"); HCURSOR hWhiteCursor = LoadCursor(hInstan, "WHITE_CUR"); HCURSOR hRedCursor = LoadCursor(hInstan, "RED_CUR"); if(((LOWORD(lp) >= 0 && HIWORD(lp) >= 0) && (LOWORD(lp) <= 800 && HIWORD(lp) <= 600)) && //... } А это что, действительно так ? Что по сообщению WM_SETCURSOR передаются координаты курсора ? Я думаю, что нужно самому вычислить координаты курсора, сравнить и после этого поменять курсор. |
|
Сообщ.
#12
,
|
|
|
|
Цитата ЫукпШ @ Блин, точно. Привыкли мы ко всяким WM_LBUTTONDOWN'ам... Что по сообщению WM_SETCURSOR передаются координаты курсора ? Я думаю, что нужно самому вычислить координаты курсора, сравнить и после этого поменять курсор. |
|
Сообщ.
#13
,
|
|
|
|
Попробуй так:
![]() ![]() case WM_SETCURSOR: { POINT cpoint; RECT wrect; RECT crect; if(::GetCursorPos(&cpoint)) { if(::GetWindowRect(hwnd, &wrect)) { if(::GetClientRect(hwnd, &crect)) { LONG dxw = wrect.right - wrect.left; LONG dxc = crect.right - crect.left; LONG dx = (dxw - dxc)/2;// толщина рамки LONG dy = (wrect.bottom - wrect.top) - (crect.bottom - crect.top) - dx; // толщина заголовка // координаты курсора в координатах клиентской области окна: LONG xc = cpoint.x - wrect.left - dx; LONG yc = cpoint.y - wrect.top - dy; BOOL changecur=FALSE; HCURSOR hcura = ::LoadCursor(NULL, IDC_ARROW); HCURSOR hcurc = ::LoadCursor(NULL, IDC_CROSS); if((xc >= 50)&&(xc <= 100)) { if((yc >= 70)&&(yc <= 190)) { changecur=TRUE; } } if(changecur) { ::SetCursor(hcurc); } else { ::SetCursor(hcura); } //... //... |
|
Сообщ.
#14
,
|
|
|
|
ЫукпШ огромное спасибо Вам, Огроомное! Я с Win API только знакомлюсь, поэтому такие банальные ошибки допускаю, заранее извиняюсь. Славян Вам тоже огромное спасибо за терпение. Всего вам самого наилучшего!
Добавлено Вот код под чистый си, мало ли кому понадобится ![]() ![]() case WM_SETCURSOR: { POINT cpoint; RECT wrect; RECT crect; HCURSOR hBlackCursor = LoadCursor(hInstan, "BLACK_CUR"); HCURSOR hBlueCursor = LoadCursor(hInstan, "BLUE_CUR"); HCURSOR hWhiteCursor = LoadCursor(hInstan, "WHITE_CUR"); HCURSOR hRedCursor = LoadCursor(hInstan, "RED_CUR"); GetCursorPos(&cpoint); GetWindowRect(hwnd, &wrect); GetClientRect(hwnd, &crect); LONG dxw = wrect.right - wrect.left; LONG dxc = crect.right - crect.left; LONG dx = (dxw - dxc) / 2; LONG dy = (wrect.bottom - wrect.top) - (crect.bottom - crect.top) - dx; LONG xc = cpoint.x - wrect.left - dx; LONG yc = cpoint.y - wrect.top - dy; /*BOOL changecur = FALSE;*/ HCURSOR hcura = LoadCursor(NULL, IDC_ARROW); if(((xc >= 0)&&(xc <= 800)) && ((yc >= 0)&&(yc <= 600))) { switch(ActiveChip) { case 1: SetCursor(hBlackCursor); break; case 5: SetCursor(hBlueCursor); break; case 25: SetCursor(hWhiteCursor); break; case 100: SetCursor(hRedCursor); break; default: SetCursor(hcura); break; } } else SetCursor(hcura); } Добавлено =) |