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> 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? 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> Where can I find some info on =
win32 low=20
level programming?</FONT></DIV>
<DIV> </DIV>
<DIV> </DIV>
<DIV><FONT size=3D2> Thank You,</FONT></DIV>
<DIV> </DIV>
<DIV><FONT size=3D2>Jamie Murphy</FONT></DIV>
------=_NextPart_000_0027_01BE0EE7.8EA89640--
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
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
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.
-- 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
5. Re: get mouse position in win32
- Posted by jiri babor <jbabor at PARADISE.NET.NZ>
Nov 14, 1998
-
Last edited Nov 15, 1998
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
6. Re: get mouse position in win32
- Posted by David Gay <moggie at INTERLOG.COM>
Nov 14, 1998
-
Last edited Nov 15, 1998
>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