|
Мишката и клавиатурата са основните входни устройства на 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
|