Using Intel® Visual Fortran to Create and Build Windows*-Based Applications

ID 757211
Date 7/23/2021
Public
Document Table of Contents

Using a Mouse

Your applications can detect and respond to mouse events, such as left mouse button down, right mouse button down, or double-click. Mouse events can be used as an alternative to keyboard input or for manipulating what is shown on the screen.

QuickWin provides two types of mouse functions:

  1. Event-based functions, which call an application-defined callback routine when a mouse click occurs

  2. Blocking (sequential) functions, which provide blocking functions that halt an application until mouse input is made

The mouse is an asynchronous device, so the user can click the mouse anytime while the application is running (mouse input does not have to be synchronized to anything). When a mouse-click occurs, Windows sends a message to the application, which takes the appropriate action. Mouse support in applications is most often event-based, that is, a mouse-click occurs and the application does something.

However, an application can use blocking functions to wait for a mouse-click. This allows an application to execute in a particular sequential order and yet provide mouse support. QuickWin performs default processing based on mouse events.

To change the shape of the mouse cursor, use the SETMOUSECURSOR routine.

Event-Based Functions

The QuickWin function REGISTERMOUSEEVENT registers the routine to be called when a particular mouse event occurs (left mouse button, right mouse button, double-click, and so on). You define what events you want it to handle and the routines to be called if those events occur. UNREGISTERMOUSEEVENT unregisters the routines so that QuickWin doesn't call them but uses default handling for the particular event.

By default, QuickWin typically ignores events except when mouse-clicks occur on menus or dialog controls. Note that no events are received on a minimized window. A window must be restored or maximized in order for mouse events to happen within it.

For example:

  USE IFQWIN
  INTEGER result
  OPEN (4, FILE= 'USER')
  ...
  result = REGISTERMOUSEEVENT (4, MOUSE$LBUTTONDBLCLK, CALCULATE)

This registers the routine CALCULATE, to be called when the user double-clicks the left mouse button while the mouse cursor is in the child window opened as unit 4. The symbolic constants available to identify mouse events are:

Mouse Event 1

Description

MOUSE$LBUTTONDOWN

Left mouse button down

MOUSE$LBUTTONUP

Left mouse button up

MOUSE$LBUTTONDBLCLK

Left mouse button double-click

MOUSE$RBUTTONDOWN

Right mouse button down

MOUSE$RBUTTONUP

Right mouse button up

MOUSE$RBUTTONDBLCLK

Right mouse button double-click

MOUSE$MOVE

Mouse moved

1 For every BUTTONDOWN and BUTTONDBLCLK event there is an associated BUTTONUP event. When the user double-clicks, four events happen: BUTTONDOWN and BUTTONUP for the first click, and BUTTONDBLCLK and BUTTONUP for the second click. The difference between getting BUTTONDBLCLK and BUTTONDOWN for the second click depends on whether the second click occurs in the double-click interval, set in the system's CONTROL PANEL/MOUSE.

To unregister the routine in the preceding example, use the following code:

result = UNREGISTERMOUSEEVENT (4, MOUSE$LBUTTONDBLCLK)

If REGISTERMOUSEEVENT is called again without unregistering a previous call, it overrides the first call. A new callback routine is then called on the specified event.

The callback routine you create to be called when a mouse event occurs should have the following prototype:

  INTERFACE
   SUBROUTINE MouseCallBackRoutine (unit, mouseevent, keystate, &
    & MouseXpos,MouseYpos)
      INTEGER unit
      INTEGER mouseevent
      INTEGER keystate
      INTEGER MouseXpos
      INTEGER MouseYpos
   END SUBROUTINE
  END INTERFACE

The unit parameter is the unit number associated with the child window where events are to be detected, and the mouseevent parameter is one of those listed in the preceding table. The MouseXpos and the MouseYpos parameters specify the x and y positions of the mouse during the event. The keystate parameter indicates the state of the shift and control keys at the time of the mouse event, and can be any ORed combination of the following constants:

Keystate Parameter

Description

MOUSE$KS_LBUTTON

Left mouse button down during event

MOUSE$KS_RBUTTON

Right mouse button down during event

MOUSE$KS_SHIFT

Shift key held down during event

MOUSE$KS_CONTROL

Control key held down during event

QuickWin callback routines for mouse events should do a minimum of processing and then return. While processing a callback, the program will appear to be non-responsive because messages are not being serviced, so it is important to return quickly. If more processing time is needed in a callback, another thread should be started to perform this work; threads can be created by calling the Windows API CreateThread. If a callback routine does not start a new thread, the callback will not be re-entered until it is done processing.

NOTE:

In event-based functions, there is no buffering of events. Therefore, issues such as multithreading and synchronizing access to shared resources must be addressed. To avoid multithreading problems, use blocking functions rather than event-based functions. Blocking functions work well in applications that proceed sequentially. Applications where there is little sequential flow and the user jumps around the application are probably better implemented as event-based functions.

Blocking (Sequential) Functions

The QuickWin blocking function WAITONMOUSEEVENT blocks execution until a specific mouse input is received. This function is similar to INCHARQQ, except that it waits for a mouse event instead of a keystroke.

For example:

   USE IFQWIN
  INTEGER mouseevent, keystate, x, y, result
  ...
  mouseevent = MOUSE$RBUTTONDOWN .OR. MOUSE$LBUTTONDOWN
  result = WAITONMOUSEEVENT (mouseevent, keystate, x , y) ! Wait
 ! until right or left mouse button clicked, then check the keystate
 ! with the following:
  if ((MOUSE$KS_SHIFT .AND. keystate) == MOUSE$KS_SHIFT) then      &
  & write (*,*) 'Shift key was down'
  if ((MOUSE$KS_CONTROL .AND. keystate) == MOUSE$KS_CONTROL) then  &
  & write (*,*) 'Ctrl key was down'

Your application passes a mouse event parameter, which can be any ORed combination of mouse events, to WAITONMOUSEEVENT. The function then waits and blocks execution until one of the specified events occurs. It returns the state of the Shift and Ctrl keys at the time of the event in the parameter keystate, and returns the position of the mouse when the event occurred in the parameters x and y.

A mouse event must happen in the window that had focus when WAITONMOUSEEVENT was initially called. Mouse events in other windows will not end the wait. Mouse events in other windows cause callbacks to be called for the other windows, if callbacks were previously registered for those windows.

Default QuickWin Processing

QuickWin performs some actions based on mouse events. It uses mouse events to return from the FullScreen mode and to select text and/or graphics to copy to the Clipboard. Servicing the mouse event functions takes precedence over return from FullScreen mode. Servicing mouse event functions does not take precedence over Cut/Paste selection modes. Once selection mode is over, processing of mouse event functions resumes.