Начало » Компютри » Управление на мишката и показалеца в MFC (Microsoft Foundation Class Library)

Управление на мишката и показалеца в MFC (Microsoft Foundation Class Library) ПДФ Печат
Технологии - Компютри
Изпратено от Стоян Георгиев   
Сряда, 22 Септември 2010 10:39

Мишката и клавиатурата са основните входни устройства на PC. Когато потребителя работи с тях те генерират апаратни прекъсвания IRC, които се поемат от ОС и се преобразуват в съобщения. Те се разпределят към приложенията на, които принадлежат. Мишката и клавиатурата се разпределят между работещият в дадения момент и приложението. По специално между техните прозорци. Тук влиза и самият Windows. Съобщенията генерирани от М и К се подават на прозореца владеещ входния фокус на диалога. Има разлика между М и К. Докато съобщенията на М се подават на прозореца в/у които е показалеца свързан с нея и така той придобива входния фокус, то съобщенията генерирани от К се подават на прозореца, които вече има входния фокус.
1.Мишка(М) – Windows използват около 20 събития. Те се разделят на 2 вида: свързани с клиентската област и свързани с останалата част на прозореца. Те са натискане и отпускане на бутон, двойно щракване на бутон, движение на мишката превъртане на колело. В повечето случаи приложенията обработват събития свързани с клиентската област и оставят на ОС да обработва събитията, които са извън нея.


А) събития свързани с клиентската област
L                 L             L               
WM_MBUTONDOWN;WM_MBUTTONUP;WM_MBUTTONDBLC;WM_MOUSEMOVE
R              R              R
Проверка колко бутона има М програмно: чрез глобалната функция
Int mButtonCount =::getSystemMetrics(SM_CMOUSEBUTTON);
Възможно е бутона да е натиснат в клиентската област, а отпуснат извън нея. Ако е необходимо се проследи тази двойка събития е възможно М да се хване от момента на натискане на бутона до момента на отпускане независимо дали напуска областта. Когато с бутон се прави двойно кликване, което е по подразбиране. Добре е да избягваме да насочваме 2 различни действия за единично и двойно щракване с 1 и същ бутон. С двойно щракване се генерират събитията WM_LBUTTONDOWN,WM_LBUTTONUP;WM_LBUTTONBLCLK,WM_LBUTTONUP
Когато М се движи в клиентската област би трябвало да се получи вихрушка от съобщения – wm_mousemove. Ако приложението бавно обработва това събитие то ще се претовари. Затова ОС управлява това събитие по различен начин. Когато М започва да се движи Windows вдига 1 флаг и праща на приложението съобщение само ако е обработено предходното. Така бързото приложение ще получи повече смс-и , а бавното по-малко. Ако е необходимо приложението да преработи събитие генерирано от М тогава то може да се прихване и чрез ClassWizard, да се направи функция за класа C::View On (L,M,R)ButtonDown() и т.н.Техният прототип е => void On…(MINT nFlags,CPoint point) параметъра point задава координатите на мишката при възникване на събитието. Това са физически координати т.е. пиксели отчетени спрямо горният ляв ъгъл на клиентската област.CDC::DPtolp() – тази точка може да се преобразува към логически координати=> CClientDC dc(this);dc.DCtoLP(point);
Параметъра nFlags в MFC (Microsoft Foundation Class Library) показва състоянието на трите бутона на М и на клавишите Ctrl ,Shift по време на възникване на събитието. Дефинирани са маски, които приложени към параметъра чрез побитово и показва дали тези бутони са натиснати.MK_MBUTTON; MK_CONTROL;MK_SHIFT
If(nFlags&MK_CONTROL){//НАТИСНАТ Е КЛАВИША ctrl}
Б)събития за неклиентската подобласт на прозореца
NLC                NCL                NCL   
WM_NCMBUTTONDOWN; WM_NCMBUTTONUP; WM_NCMBUTTONBLCLK
NCR                NCR                NCR       
WM_NCMOUSEMOVE
И функциите, които създава също има NC: Оn(NCL,NCM,NCR)BUTTONDOWN() и т.н
Тези събития се прихващат за главния прозорец не са клиентската област затова прототипа на тези събития е член-ф на
Void CMainFrame::OnNc…(UINT nHitTest,CPoint point)
Point – е в екранни координати
nHitTest – показва в коя част на прозореца е възникнало събитието за nHitTest са дефинирани const.HITAPTION – събитието на М е в заглавната лента на прозореца
HITCLOSE – M е върху бутона close
HITGROWBOX – М е върху бутона restore
HITSCROLL – М е върху екраннопревъртане
HITMENU – М е върху меню
HITREDUCE – М е върху бутона минимаиз
HITSIZE – М е върху рамката на прозореца
HITSSSMENU – М е върху системното меню
HITVSCROLL – М е върху вертикалната лента за превъртане
HITZOOM – М е върху бутона максимаиз
If (nHitTest==HCAPTION){//М е върху заглавната лента}
В)управление на колелото на мишката - при въртенето на колелото в потребителя се генерира съобщение WM_MOUSEWHEEL то се приема от клиентската област . чрез classwizard може да се създаде ф-ции
On::MouseWheel(UIN nflags,short zDelta,CPoint point)) BOOL C::View
Параметрите NFlag и point са същите като дръгите ф-ции. zDelta – показва завъртането на колелото ако е > 0 колелото се върти напред и обратното. Дефинираме константи WHEEL_DELTA=120 съответстваща на завъртане на 1 зъб. При М със зъбчато колело zDelta е кратно на константата.
Г)хващане на мишката при влачене с мишката тя мойе да напусне клиентската област на прозореца и тогава на WN_LBUTTONDOWN няма да съответства wn_lbuttonup, което би довело до проблеми. Този проблем се избягва чрез хващане , при натискане на бутона. Когато М е хваната тя остава да принадлежи на прозореца в които е хваната независимо че той е напусна. Хващането на бутона става с член-ф
CWnd::SetCapture() a пускането става с ::ReturnCapture(глобална ф)
Void C::View::OnLButtonDown(…){SetCapture;}-хваща
Void C::View::OnLButtonUp(…){::ReleaseCapture();}
При хващане на М при излизане извън прозореца той продължава да получава смс WN_MOUSEMOVE като координатите са извън видимата част на клиентската област. Чрез функцията CWnd::getcapture() може да се получи указател на прозореца хванал мишката if(getcapture()==NULL) М не е хваната ако е ==This e хваната
Д)Управление на показалеца – при нейното движение той също се движи т.е. трие се старото място и се рисува на новото. При всяко прерисуване се генерира смс WM_SETCURSOR. Може да се прихване в класа на главния прозорец и да се смени вида на курсора.
BOOL CMain::OmSetCursor(CWnd*pWnd,UINT nHitTest,UINT message){
If(nHitTest==HTCLIENT){::SetCursor(::LoadCursor(NULL,IDC_CROSS)); return TRUE:}
Има разработени 20 вида ресурси за различните курсори.IC_HAND,IDC_WAIT,IDC_HELP И ДР. курсора може да се скрива и показва чрез f ::ShowCursor(TRUE,FALSE). При заетост на приложението ОС показва курсор пясъчен часовник. Програмно може да стане по следния начин:CWaitCursor wait; - създава се обект на този клас от самоия конструктор.
Wait.Restore(); - за връщане на стария курсор
2.Клавиатура – събитията се насочват към прозорец които има входни курсор
А)управление на входния фокус когато прозореца който има входния фокус Windows праща съобщение WM_SETFOCUS,а като губи фокус WM_KILLFOCUS