Pointer devices give users the ability to perform actions directly. The Open Class Library offers classes to handle the mouse pointer.
You can use IMouseHandler to process a variety of mouse events. These events include button presses and releases, double-clicks, multiple button presses, and mouse moves. You can also query keyboard state information at the time a mouse event is generated.
Begin by creating an IMouseHandler object and then attach it to any kind of window (for example, IMultiLineEdit or ISetCanvas). Although the window that the mouse is over receives a mouse event first, events are sometimes passed on for additional processing to their owner windows. A mouse event continues to travel up the owner window chain until either a handler stops it or the event is processed by the window itself. The mouse handler must return true to stop any additional processing of a mouse event.
When an IMouseHandler object receives a mouse event, it creates either an IMouseEvent, an IMouseClickEvent, or an IMousePointerEvent and routes it to a mouse handler virtual function. The mouse handler virtual functions are as follows:
Whenever a mouse button's state changes, the IMouseHandler calls its mouseClicked function. The IMouseClickEvent object identifies the button, its current keyboard state, and the mouse pointer position. The IMouseClickEvent defines the following virtual functions:
Note: | On a two-button mouse, button1 is the left mouse button on a right-handed mouse and the right button on a left-handed mouse. Button2 is the right mouse button on a right-handed mouse and the left button on a left-handed mouse. |
The IMouseEvent defines the following virtual functions:
You initiate a mouse pointer event when you enter and exit a window with a mouse handler attached. The IMousePointerEvent defines the following virtual functions:
The following code creates a multicell canvas as a client window with a view port control, and two bitmaps as its children. A mouse handler is attached to the client canvas, the view port and the bitmaps. Code, in the overloaded changeMousePointer member function, changes the mouse pointer when the mouse is over the view port. The information area at the bottom of the frame is updated to indicate when the mouse is over the view port and when it leaves the view port. When the mouse is over the bitmaps, the program invokes the mouseClicked member function. The code in the .hpp file is as follows:
/*************************************************************/ /* Define the Mouse Handler */ /*************************************************************/ class AMouseHandler : public IMouseHandler { public: AMouseHandler(MainWindow *aFrame); protected: virtual bool mouseClicked (IMouseClickEvent & event); virtual bool mousePointerChange (IMousePointerEvent& event); private: MainWindow * frame; }; /*************************************************************/ /* Define the Main Window */ /*************************************************************/ class MainWindow : public IFrameWindow { public: MainWindow( unsigned long windowId); bool handleClickEvent(unsigned long id); bool handleChangeEvent(IMousePointerEvent& event); private: IMultiCellCanvas clientCanvas; IViewPort aviewport; IStaticText viewText; IStaticText bmpText; IStaticText infoText; IBitmapControl bmp1; IBitmapControl bmp2; IPointerHandle ptr_bmp; AMouseHandler mouseHandler; };
The code in the .cpp file is as follows:
/*************************************************************/ /* Create the Main Window */ /*************************************************************/ MainWindow::MainWindow( unsigned long windowId) : IFrameWindow("Mouse Handler Example", windowId), clientCanvas(REMOTECANVASID, this, this), aviewport(VPID, &clientCanvas, &clientCanvas), viewText(VTXT, &aviewport, &aviewport, IRectangle(), IStaticText::defaultStyle() | IStaticText::center), bmpText(BMPTXT, &clientCanvas, &clientCanvas, IRectangle(), IStaticText::defaultStyle() | IStaticText::center | IStaticText::top), infoText(INFOID, this, this, IRectangle(), IStaticText::defaultStyle() | IStaticText::top | IStaticText::left | IStaticText::wordBreak ), bmp1(BMP1ID,&clientCanvas,&clientCanvas, ISystemBitmapHandle::minimizeButton), bmp2(BMP2ID,&clientCanvas,&clientCanvas, ISystemBitmapHandle::maximizeButton), mouseHandler(this) { addExtension(&infoText, IFrameWindow::belowClient, IFont(&infoText).maxCharHeight(), IFrameWindow::thickLine); infoText.setText(ID_TEXT); bmpText.setText("<==click on bitmaps"); viewtext.settext(vtxt); viewtext.setforegroundcolor(icolor::kwhite); setclient(&clientcanvas); aviewport.setbackgroundcolor(icolor::kpalegray); clientcanvas.addtocell(&aviewport, 2, 6, 40, 1); clientcanvas.addtocell(&bmp1, 2, 2, 4, 2); clientcanvas.addtocell(&bmp2, 8, 2, 4, 2); clientcanvas.addtocell(&bmptext, 12, 2, 5, 2); isize size="clientCanvas.minimumSize();" ipoint point="position();" movesizetoclient(irectangle(point.x(), point.y(), point.x() + size.width(), point.y() + size.height())); /********************************************************/ /* add the mouse handler */ /********************************************************/ mousehandler.handleeventsfor(&aviewport); mousehandler.handleeventsfor(&bmp1); mousehandler.handleeventsfor(&bmp2); mousehandler.handleeventsfor(&clientcanvas); iresourcelibrary reslib; ptr_bmp="reslib.loadPointer(PTR_BITMAP);" show(); setfocus(); } /*************************************************************/ /* change the mouse pointer and update the info area */ /*************************************************************/ bool mainwindow::handlechangeevent(imousepointerevent& event) { if (event.windowid()="=" ic_viewport_viewrectangle) { event.setmousepointer(ptr_bmp); infotext.settext("mouse is on top of the viewport"); return true; } else { infotext.settext("mouse is not on top of the viewport"); return false; } } /*************************************************************/ /* change the button bitmaps and update the info area. */ /*************************************************************/ bool mainwindow::handleclickevent(unsigned long id) { switch (id) { case bmp1id: bmp1.setbitmap(bmpcd); infotext.settext("minimize button pushed"); break; case bmp2id: bmp2.setbitmap(bmpmidi); infotext.settext("maximize button pushed"); break; } return true; } amousehandler :: amousehandler(mainwindow *aframe) { frame="aFrame;" } /*************************************************************/ /* hande the mouse click event */ /*************************************************************/ bool amousehandler :: mouseclicked (imouseclickevent & event) { iwindow * pwindow="IWindow::windowWithHandle(event.windowUnderPointer());" unsigned long int winid="pWindow-">id(); frame->handleClickEvent(winId); return true; } /*************************************************************/ /* Hande the mouse pointer change event */ /*************************************************************/ bool AMouseHandler :: mousePointerChange (IMousePointerEvent& event) { return (frame->handleChangeEvent(event)); }
The following graphics show the results of using the mouse handler.
Adding Events and Event Handlers
IEvent
IMouseHandler
IMouseClickEvent
IMousePointerEvent