Retro video games delivered to your door every month!
Click above to get retro games delivered to your door ever month!
X-Hacker.org- The Guide to Clip-4-Win version 3.0 - http://www.X-Hacker.org [<<Previous Entry] [^^Up^^] [Next Entry>>] [Menu] [About The Guide]
  
  event          other info     meaning
  
  EVENT_NONE     none           event queue is empty
  
  EVENT_OTHER    varies         a Windows message which is not one of those
                                below, but which you might possibly wish to
                                process
  
  EVENT_MENU     _LastwParam()  the menu id
  
  EVENT_KEY      inkey()        the keystroke
  
  EVENT_LCLICK   MouseX(), MouseY()     the x,y position
                 MouseRow(), MouseCol()   the row,col position
  EVENT_LDBLCLK \
  EVENT_RCLICK    \
  EVENT_RDBLCLK    >---  see EVENT_LCLICK
  EVENT_MCLICK    /
  EVENT_MDBLCLK /
  
  EVENT_REDRAW   none           re-draw the client area
  
  EVENT_SETFOCUS none           getting the input focus
  
  EVENT_KILLFOCUS  none         losing the input focus
  
  EVENT_WINMOVE  _LastLolParam()  the x position
                 _LastHilParam()  the y position
  
  EVENT_WINSIZE  _LastLolParam()  the new width in pixels
                 _LastHilParam()  the new height in pixels
  
  EVENT_DESTROY  none           the window is being destroyed
  
  EVENT_QUIT     none           the application should exit
  
  EVENT_CONTROL  _LastwParam()  the control's id
  
  EVENT_HSCROLL  _LastwParam()  the scrollbar code
                                (one of the SB_* values)
  
  EVENT_VSCROLL  _LastwParam()  the scrollbar code
                                (one of the SB_* values)
  
  EVENT_ACCELKEY _LastwParam()  the numeric id for the accelerator key
  
  EVENT_TIMER    none           the time delay you set has elapsed

  EVENT_LBTNUP \
  EVENT_RBTNUP  >---            the mouse button was released
  EVENT_MBTNUP /
  
  
  One event that you will not be used to in Clipper is the user
  re-sizing a window (signalled by the ChkEvent() return value
  EVENT_WINSIZE).  You can get the new size as shown in the
  table above.  Additionally, MAXROW() and MAXCOL() return new
  values.  It is up to the application to decide how to re-draw
  the window's client area, but note that Windows does NOT do
  this for you.
  
  You must also re-draw the window's client area when ChkEvent()
  returns the code EVENT_REDRAW.
  
  To be able to refresh each window, it's often best to set up
  the information you'll need (for example, in an array or
  arrays), and then send your own application an EVENT_REDRAW.
  The InvalidateRect() function is an easy way to force such an
  event.
  
  Another way to set up the information you need to be able to
  redraw the screen is to use Clipper local or static variables,
  perhaps with a code block to transfer the handling of an event
  to the appropriate piece of program code.  For a simple
  Windows program that has one window (or very few), you will
  find this easy.  Just structure your program like this:
  
       static    bEvent := {|nEvent| nil}    // default event handler
  
       .
       .    // set up the main window
       .    // and its menu
       .
  
       do while .T.
            do while (nEvent := ChkEvent()) == EVENT_NONE
                 // some "background" processing could go here
            enddo
  
            eval(bEvent, nEvent)     // handle the event
       enddo
  
  This is innocent enough, but how does it work?  The menu for
  the main window provides the answer: when your user chooses a
  menu item, the ChkEvent() function runs the code block
  associated with that menu item.
  
  Don't worry about the details of the user making a menu
  choice.  Windows does it all for you: the highlighting,
  dropping the menus down, allowing keyboard and/or mouse
  activation, and so on.  You end up with an EVENT_MENU, which
  ChkEvent() handles automatically.
  
  However, it is up to your menu code block to keep the above
  event loop doing the right thing.  You can do this by changing
  the bEvent variable, if necessary, so that a new code block
  handles events for as long as you want.  Some time later the
  user will make another menu choice, thus changing bEvent
  again, and so on.  (The sample program DEM4.PRG uses this
  technique.)
  
  This sort of program is easy to write and understand, but it's
  not terribly easy to be modeless.  It's also not too easy to
  manage multiple windows.  The major problem is the use of the
  single variable bEvent.
  
  To overcome this problem, you might like to use an array to
  hold a code block for each of the separate output areas
  (windows).  Your event loop should use the window handle to
  find the appropriate code block(s) in the array, and run it
  (them).  This way, to display something new you just add the
  appropriate code block to the array.  To stop displaying
  something you remove the code block.  (The sample program
  DEM4M.PRG uses this technique.)
  
  NOTE:  An improved version of the code presented here is in
  the file evhand.prg, and the functions are included in
  clip4win.lib.
  
  The skeletal code for this is:
  
       static    aWnd := { }         // the windows now existing
       static    aAction := { }      // the action code blocks
  
       .
       .    // set up the main window
       .    // and its menu
       .
  
       do while .T.
            do while (nEvent := ChkEvent()) == EVENT_NONE
                 // some "background" processing could go here
            enddo
  
            HandleEvent(nEvent)
       enddo
  
  
  As before, your menus determine what happens.  But, this time
  you can add a new handler with code like this:
  
       // arrange to send events for window hWnd to the handler bAction
       function AddHandler(hWnd, bAction)
       aadd(aWnd, hWnd)
       aadd(aAction, bAction)
       return len(aWnd)              // an id suitable for DelHandler()
  
  
  The mysterious HandleEvent() function is actually very
  simple: it can use ASCAN() to find the right handler and then
  give the handler the event.  You can use the window handle to
  find the handler.  To allow multiple handlers per window, the
  following code works its way all along the aWnd array:
  
       procedure HandleEvent(nEvent)
       local     hWnd := _LasthWnd(), i := 0
  
       do while (i := ascan(aWnd, hWnd, ++i)) != 0
            eval(aAction[i], nEvent)
       enddo
  
       return
  
  Although the above is enough, it's convenient in practice to
  have HandleEvent() do some special processing for the
  destruction of a window: it can make sure the handlers are
  removed.  Of course, you want your handlers to be passed the
  event first so that they can tidy up (e.g. by closing files).
  The event is EVENT_DESTROY, as shown here:
  
       procedure HandleEvent(nEvent)
       local     hWnd := _LasthWnd(), i := 0
  
       do while (i := ascan(aWnd, hWnd, ++i)) != 0
            eval(aAction[i], nEvent)
       enddo
  
       if nEvent == EVENT_DESTROY
            // clean up, so that the event handler needn't bother
            do while (i := ascan(aWnd, hWnd)) != 0
                 DelHandler(i)
            enddo
       endif
  
       return
  
  In passing, it's worth noticing just how easy ASCAN() makes
  things.
  
  
  For completeness, even though you could no doubt write it
  yourself, here's DelHandler():
  
       procedure DelHandler(nId)
       adel(aWnd, nId)
       asize(aWnd, len(aWnd) - 1)
       adel(aAction, nId)
       asize(aAction, len(aAction) - 1)
       return
  
  
  Exactly which events you handle is a matter for you, but the
  following are the commonest (EVENT_MENU is omitted on
  purpose):
  
            EVENT_KEY
            EVENT_LCLICK
            EVENT_REDRAW
            EVENT_DESTROY
            EVENT_QUIT
  
  
  You have an opportunity to do some special processing when
  ChkEvent() returns the values EVENT_SETFOCUS and
  EVENT_KILLFOCUS, which indicate that your window is receiving
  and losing the input focus.  (EVENT_SETFOCUS means user input
  is sent to your application's window, whereas EVENT_KILLFOCUS
  means another window/application will receive any input.)
  Often you will not do anything special with these events.

  
  You might like to know how Clip-4-Win converts the messages
  from Windows into these values:
  
  
  event               Windows message
  
  EVENT_KEY           WM_KEYDOWN / WM_SYSKEYDOWN
  
  EVENT_MENU          WM_COMMAND
  
  EVENT_LCLICK        WM_LBUTTONDOWN
  
  EVENT_LDBLCLK       WM_LBUTTONDBLCLK
  
  EVENT_RCLICK    \
  EVENT_RDBLCLK    >--- see EVENT_LCLICK / EVENT_LDBLCLK
  EVENT_MCLICK    /
  EVENT_MDBLCLK /
  
  EVENT_LBTNUP  \
  EVENT_RBTNUP   >--- WM_xBUTTONUP
  EVENT_MBTNUP /
  
  EVENT_REDRAW        WM_PAINT
  
  EVENT_SETFOCUS      WM_SETFOCUS
  
  EVENT_KILLFOCUS     WM_KILLFOCUS
  
  EVENT_WINMOVE       WM_MOVE
  
  EVENT_WINSIZE       WM_SIZE
  
  EVENT_DESTROY       WM_DESTROY
  
  EVENT_QUIT          WM_QUIT
  
  EVENT_CONTROL       WM_COMMAND
  
  EVENT_HSCROLL       WM_HSCROLL
  
  EVENT_VSCROLL       WM_VSCROLL
  
  EVENT_ACCELKEY      WM_COMMAND
  
  EVENT_TIMER         WM_TIMER



Online resources provided by: http://www.X-Hacker.org --- NG 2 HTML conversion by Dave Pearson