1. get mouse position in win32

------=_NextPart_000_0027_01BE0EE7.8EA89640
        charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable

  Using win32lib, Does anyone know a function that would keep track of =
the mouse position in a win32 program, Like an onMouseOver routine?  =
Also, can anyone explain how to use the onEvent[] routine? I can't seem =
to do it without errors.=20
    Where can I find some info on win32 low level programming?


 Thank You,

Jamie Murphy
Boston,MA

------=_NextPart_000_0027_01BE0EE7.8EA89640
        charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable

<!DOCTYPE HTML PUBLIC "-//W3C//DTD W3 HTML//EN">
<HTML><HEAD>
<META content=3Dtext/html;charset=3Diso-8859-1 =
http-equiv=3DContent-Type>
<META content=3D'"MSHTML 5.00.0910.1309"' name=3DGENERATOR></HEAD>
<BODY bgColor=3D#f8f8f8>
<DIV><FONT size=3D2>&nbsp; Using win32lib, Does anyone know a function =
that would=20
keep track of the mouse position in a win32 program</FONT><FONT =
size=3D2>, Like an=20
onMouseOver routine?&nbsp; Also, can anyone explain how to use the =
onEvent[]=20
routine? I can't seem to do it without errors. </FONT></DIV>
<DIV><FONT size=3D2>&nbsp;&nbsp;&nbsp; Where can I find some info on =
win32 low=20
level programming?</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=3D2> Thank You,</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=3D2>Jamie Murphy</FONT></DIV>

------=_NextPart_000_0027_01BE0EE7.8EA89640--

new topic     » topic index » view message » categorize

2. Re: get mouse position in win32

[Sorry about the length of this post, but it the answer requires a bit of
detail. As a bonus, you also get a silly scribble program!]

Jamie Murphy wrote:

> Using win32lib, Does anyone know a function
> that would keep track of the mouse position
> in a win32 program, Like an onMouseOver routine?

Nothing like that exists in the library (yet). I'll add it eventually. In
the mean time, you should be able to hook into it with onEvent (see below).

> Also, can anyone explain how to use the
> onEvent[] routine? I can't seem to do it
> without errors.

The onEvent routine is used to hook into Win32 events that Win32Lib doesn't
trap. If a window or control has an onEvent() handler, it is called *before*
any other handling. The parameters that are passed are:

        onEvent( aMsg, wParam, lParam )

Please note that my documentation says that the first parameter is iMsg, but
it really should be defined as an atom! the aMsg parameter is the event that
Win32 is reporting. For example, here are some of the events Win32Lib traps,
and the names of the wrappers:

        WM_CREATE                       onLoad
        WM_SIZE                 onResize
        WM_SETFOCUS                     onGetFocus
        WM_KILLFOCUS            onLoseFocus
        WM_KEYDOWN                      onKeyPress
        WM_LBUTTONDOWN          onClick
        WM_RBUTTONDOWN          onRightClick
        WM_LBUTTONDBLCLK                onLeftClick
        WM_PAINT                        onPaint
        WM_HSCROLL                      onScroll
        WM_VSCROLL                      onScroll
        WM_TIMER                        onTimer
        WM_CLOSE                        onUnload

The parameters wParam and lParam hold the parameters of the event. In the
case of WM_KEYDOWN, for example, the key number is passed in wParam. Another
example of this is the mouse events, where the X value is in the low word of
lParam, and Y is in the high value of lParam .

Some events are even more complex. For example, there are several tests for
WM_COMMAND in Win32Lib's event loop. Here's one of them:

    elsif ( iMsg = WM_COMMAND and lParam = NULL) then

        -- menu or accelerator?
        if hi_word( wParam ) = 1 then
            -- from accelerator;
            -- this should not happen

        else
            -- get the menu id
            id = lo_word( wParam )

            -- get the pointer
            pointer = onMenu[ id ]

            -- action?
            if pointer != -1 then
                call_proc( pointer, {} )
            end if

        end if

In this case, If:

1. the event is WM_COMMAND, and
2. lParam is NULL, and
3. the high word in wParam is 0,

Then: the low word in wParam contains the id of a menu command.

> Where can I find some info on win32 low level programming?

You might want to look at:

        http://listserv.muohio.edu/archives/euphoria.html

and search on windows programming.

There is a Win32 help file in the Euphoria Archives which is quite helpful.

I also have a copy of the Win32 API file that came with Visual Basic, which
is very helpful for getting the definitions of constants (such as
WM_MOUSEMOVE, for example). These constants are explained, but not defined,
in the Win32 help file.

Ok, now to answer your question about tracking the mouse. Here is some
example code from the Win32 help file:

-- EXAMPLE BEGIN --

In the following example, the window procedure prepares for drawing when the
user presses and holds the left mouse button (sending the WM_LBUTTONDOWN
message). As the user moves the cursor within the window, the window
procedure receives a series of WM_MOUSEMOVE messages. For each message, the
window procedure draws a line connecting the previous position and the
current position. To draw the line, the procedure uses GetDC to retrieve a
display DC; then, as soon as drawing is complete and before returning from
the message, the procedure uses the ReleaseDC function to release the
display DC. As soon as the user releases the mouse button, the window
procedure clears the flag, and the drawing stops (which sends the
WM_LBUTTONUP message).


BOOL fDraw = FALSE;
POINT ptPrevious;

  .
  .
  .

case WM_LBUTTONDOWN:
    fDraw = TRUE;
    ptPrevious.x = LOWORD(lParam);
    ptPrevious.y = HIWORD(lParam);
    return 0L;

case WM_LBUTTONUP:
    if (fDraw) {
        hdc = GetDC(hwnd);
        MoveToEx(hdc, ptPrevious.x, ptPrevious.y, NULL);
        LineTo(hdc, LOWORD(lParam), HIWORD(lParam));
        ReleaseDC(hwnd, hdc);
    }
    fDraw = FALSE;
    return 0L;

case WM_MOUSEMOVE:

    if (fDraw) {
        hdc = GetDC(hwnd);
        MoveToEx(hdc, ptPrevious.x, ptPrevious.y, NULL);
        LineTo(hdc, ptPrevious.x = LOWORD(lParam),
          ptPrevious.y = HIWORD(lParam));
        ReleaseDC(hwnd, hdc);
    }
  return 0L;

An application that enables drawing, as in this example, typically records
either the points or lines so that the lines can be redrawn whenever the
window is updated. Drawing applications often use a memory DC and an
associated bitmap to store lines that were drawn by using a mouse.

-- EXAMPLE END --


The Win32Lib routines automatically take care of the DC, so you only have to
worry about trapping the events. I got the values from my VB API file:

        WM_MOUSEMOVE    = #200
        WM_LBUTTONDOWN  = #201
        WM_LBUTTONUP    = #202

WM_LBUTTONDOWN is already defined in Win32Lib. Translating the code is
trivial:

-- CODE BEGIN --
include win32lib.ew

constant Win =
    create( Window, "Draw Line Demo", 0, Default, Default, 200, 200, 0 )

-- mouse events
constant
    WM_MOUSEMOVE    = #200,
    -- WM_LBUTTONDOWN  = #201, (already defined )
    WM_LBUTTONUP    = #202


integer
    fDraw, priorX, priorY
    fDraw = 0   -- initially false

procedure Event( atom aMsg, atom wParam, atom lParam )

    -- implement mouse drawing

    integer x, y

    if compare( aMsg, WM_MOUSEMOVE ) = 0 then
        -- in drawing mode?
        if fDraw then

            -- capture mouse position
            x = lo_word( lParam )
            y = hi_word( lParam )

            -- draw a line
            drawLine( Win, priorX, priorY, x, y )

            -- save current point
            priorX = x
            priorY = y

        end if

    elsif compare( aMsg, WM_LBUTTONDOWN ) = 0 then
        -- flag drawing to begin
        fDraw = 1

        -- capture mouse position
        priorX = lo_word( lParam )
        priorY = hi_word( lParam )

    elsif compare( aMsg, WM_LBUTTONUP   ) = 0 then
        -- capture mouse position
        x = lo_word( lParam )
        y = hi_word( lParam )

        -- draw a line
        drawLine( Win, priorX, priorY, x, y )

        -- end drawing mode
        fDraw = 0

    end if

end procedure

-- tell Windows when to do the action
    onEvent[Win] = routine_id( "Event" )

-- hand control over to Windows
WinMain( Win )


-- CODE END --

I could have used the onClick event instead of trapping WM_LBUTTONDOWN, but
it seemed simpler to code it this way. Besides, it shows how you can pretty
much ignore Win32Lib's wrappers if you want to.

Hope this helps!

-- David Cuny

new topic     » goto parent     » topic index » view message » categorize

3. Re: get mouse position in win32

To all of you saying that Win32 programming is difficult,

Have you seen the neat 'silly scribble program' by David Cuny? Can you do=

it this easy in DOS, using whichever graphics library you want? (excludin=
g
Dos32Lib, of course)
I'm curious to see your answers!

Ad Rienks

new topic     » goto parent     » topic index » view message » categorize

4. Re: get mouse position in win32

Ad Reinks wrote:

> Can you do [the scribble program] this easy in DOS?

I couldn't resist, and ended up doing two versions of the code. The first
looked like this:

-- BEGIN CODE --

include graphics.e
include mouse.e

integer
    fDraw, x, y, priorX, priorY
    fDraw = 0   -- initially false

object mouse, result

-- set up screen
if graphics_mode( 14 ) then
    puts( 1, "Unable to set graphics mode." )
    abort(0)
end if

procedure drawLine( integer x1, integer y1,
                    integer x2, integer y2 )

    -- hide the mouse
    mouse_pointer(0)

    -- draw a line
    draw_line( BLACK, {{x1, y1}, {x2, y2}} )

    -- show the mouse
    mouse_pointer(1)

end procedure

-- clear the screen
result = video_config()
x = result[VC_XPIXELS]
y = result[VC_YPIXELS]
polygon( WHITE, 1, {{0,0}, {x,0}, {x,y}, {0,y}} )

-- loop until exit key is pressed
while compare( get_key(), 27 ) do

    -- get a mouse event
    mouse = get_mouse()
    if not sequence( mouse ) then
        mouse = {0,0,0}
    end if


    if and_bits( mouse[1], LEFT_DOWN ) then
        -- flag drawing to begin
        fDraw = 1

        -- capture mouse position
        priorX = mouse[2]
        priorY = mouse[3]

    elsif and_bits( mouse[1], LEFT_UP ) then
        -- capture mouse position
        x = mouse[2]
        y = mouse[3]

        -- draw a line
        drawLine( priorX, priorY, x, y )

        -- end drawing mode
        fDraw = 0


    elsif and_bits( mouse[1], MOVE ) then
        -- in drawing mode?
        if fDraw then

            -- capture mouse position
            x = mouse[2]
            y = mouse[3]

            -- draw a line
            drawLine( priorX, priorY, x, y )

            -- save current point
            priorX = x
            priorY = y

        end if

    end if

end while

result = graphics_mode( -1 )

-- END CODE --

It *looks* about the same. But there was a lot more work involved in the
port than I thought. Some of the pitfalls I encountered were classics:

1. If you clear the screen by writing:

        bk_color( WHITE )
        clear_screen()

you end up redefining the color black. The pen color is then *invisible*. To
clear the screen, you need to draw a screen-sized polygon instead.

2. Mouse events are combined in DOS - so a "move" and "left click" can
appear in a single event. This means that you have to test with and_bits to
get the correct mouse event. Otherwise, you don't see the mouse events.

3. The test sequence has to be reordered. As it was, a mouse event of
MOVE+MOUSE_DOWN would hit the MOVE event first, so the MOUSE_DOWN event was
never seen. Either that, or the tests would have to be made into seperate IF
statements.

4. Before drawing a line, the mouse pointer had to be hidden, or it would
overwrite what had just been written to the screen.

Since Ad said "using whichever graphics library you want", I put together a
small library:

   - display a window
   - splitting mouse events into seperate events

It's about as simple as a basic GUI library can get, but still captures the
flavor of an event-oriented GUI. It wouldn't take a lot of work to extend
WinLib to handle keystrokes, text and other goodies, but I've already done
that with Dos32Lib. smile

-- START WINLIB.E --
include graphics.e
include mouse.e

global procedure drawLine( integer x1, integer y1,
                    integer x2, integer y2 )

    -- draw a line between two points

    -- hide the mouse
    mouse_pointer(0)

    -- draw a line
    draw_line( BLACK, {{x1, y1}, {x2, y2}} )

    -- show the mouse
    mouse_pointer(1)

end procedure

procedure box( integer color, integer fill, integer x1, integer y1,
                    integer x2, integer y2 )

    -- draws an optionally filled box
    polygon( color, fill, {{x1,y1}, {x2,y1}, {x2,y2}, {x1,y2}} )

end procedure

-- holds the callback id
integer callback

procedure postEvent( integer event, integer parm1, integer parm2 )
    -- send an event to the event handler callback
    call_proc( callback, {event, parm1, parm2 } )
end procedure


global procedure eventLoop( integer callbackID )

    -- simulates windows event loop

    integer x1, y1, x2, y2
    object mouse, result

    -- set the callback
    callback = callbackID

    -- set graphics mode
    if graphics_mode( 18 ) then
        puts( 1, "Unable to set graphics mode." )
        abort(0)
    end if

    -- clear the screen
    result = video_config()
    x2 = result[VC_XPIXELS]
    y2 = result[VC_YPIXELS]
    box( CYAN, 1, 0, 0, x2, y2 )

    -- calculate the size of a window
    x1 = 100
    y1 = 100
    x2 = x2 - 100
    y2 = y2 - 100

    -- draw a window with shadows
    box( BLACK, 0, x1+1, y1+1, x2+1, y2+1 )
    box( WHITE, 1, x1, y1, x2, y2 )
    box( BLACK, 0, x1, y1, x2, y2 )

    while 1 do

        -- exit on escape key
        if compare( get_key(), 27 ) = 0 then
            exit
        end if

        mouse = get_mouse()
        if sequence( mouse ) then

            -- in bounds?
            if mouse[2] < x1 or mouse[2] > x2
            or mouse[3] < y1 or mouse[3] > y2 then
                -- zap the event
                mouse[1] = 0
            end if

            -- click?
            if and_bits( mouse[1], LEFT_DOWN ) then
                postEvent( LEFT_DOWN, mouse[2], mouse[3] )
            end if

            -- mouse release?
            if and_bits( mouse[1], LEFT_UP ) then
                postEvent( LEFT_UP, mouse[2], mouse[3] )
            end if

            -- mouse move?
            if and_bits( mouse[1], MOVE ) then
                postEvent( MOVE, mouse[2], mouse[3] )
            end if

        end if

    end while

    result = graphics_mode( -1 )


end procedure

-- END WINLIB.E --


Here is the resulting event-oriented DOS Scribble program:

-- BEGIN SCRIBBLE.EX --

integer
    fDraw, x, y, priorX, priorY

    fDraw = 0   -- initially false


procedure process( integer event, integer parm1, integer parm2 )

    if compare( event, MOVE ) = 0 then
        -- in drawing mode?
        if fDraw then

            -- capture mouse position
            x = parm1
            y = parm2

            -- draw a line
            drawLine( priorX, priorY, x, y )

            -- save current point
            priorX = x
            priorY = y

       end if

    elsif compare( event, LEFT_DOWN ) = 0 then
        -- flag drawing to begin
        fDraw = 1

        -- capture mouse position
        priorX = parm1
        priorY = parm2

    elsif compare( event, LEFT_UP ) = 0 then
        -- capture mouse position
        x = parm1
        y = parm2

        -- draw a line
        drawLine( priorX, priorY, x, y )

        -- end drawing mode
        fDraw = 0

    end if

end procedure


-- call the event loop
eventLoop( routine_id( "process" ) )

-- END SCRIBBLE.EX --


-- David Cuny

new topic     » goto parent     » topic index » view message » categorize

5. Re: get mouse position in win32

David,

I do not want to be drawn into the silly argument, which library is
easier to use (btw it would be more revealing to compare the speed,
responsiveness as well as transparency of similar programs written for
various platforms, but that is a vastly different and much more
difficult topic), I just want to know why you stubbornly and
wastefully use the despised compare() function even when both
arguments are integers? In your last example every occurrence of
compare could be replaced by a simple equal or not equal (= or !=)
test. Why not? jiri

new topic     » goto parent     » topic index » view message » categorize

6. Re: get mouse position in win32

>To all of you saying that Win32 programming is difficult,


Here's my answer :>

It's not so much the programming that is hard, it's how a Windows
environment is so different from a DOS environment that can confound a
person not familar with it, even if the person has programmed in DOS for a
while.

I've been programming for nearly three years professionally and 17 years
personally, using languages like C, RPG, and Assembler, all of which under a
non-GUI system. I find DOS programming is easier because basically you
design everything from database management to graphics in your program. And
if the program aborts, it does so cleanly, and you know you do not have to
look far for the cause: your source. Because of the way DOS programs run, a
newcomer to programming can learn quickly. There are many entry level
tutorials out there.

In Windows programming, you deal with programming modules you didn't write
in order to invoke functions like the GUI. If your program aborts, it could
be because of your source, or it could be because of the module you tried to
call. The way Windows reacts to a programming abort is mortifying. It's like
a tenant in an apartment breaking wind and the apartment collapses (pardon
the humour) because of it. And just try to go on the Internet or in a
bookstore to get a primer for the newcomer programmer regarding the Windows
API. I say try because there is currently no such thing. Windows API
programming is not for entry level programmers. That's why we have languages
like Visual Basic that use a interface to handle the hard work using a form
layout.

We need to keep a perspective here. Win32 programming is more of a
challenge. While David Cuny has done a great job on creating a library that
simplifys Windows programming, you still need to know about parent and child
windows, controls. and other aspects of Windows programming not found in
DOS. If you do not know that, even using David's library will be difficult
at first.

To answer your last question, yes, you can write a DOS program that can
simulate the same GUI features found in Windows without using the API. My
tutorial on Euphoria is completely mouse-driven and relies on a clickable
interface, though it is primitive compared to David Cuny's DOS32Lib. Yes, I
had to write every line of code that performed the GUI interface in the
tutorial, but it can be done. DOS programmers are not handicapped when it
comes to GUI programming.

This is not to sound anti-Windows Programming. I like to remind everyone I
am currently seeking info on the Windows 9x environment. I even picked up a
book strongly recommended by a recent Windows convert called "Teach Yourself
Windows 95 Programming In 21 Days" by Charles Calvert and have found it so
far very helpful.

David Gay
http://www.geocities.com/SiliconValley/Vista/4346
A Beginner's Guide To Euphoria

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu