1. get mouse position in win32
- Posted by Jamie Murphy <jmurphy914 at MEDIAONE.NET> Nov 13, 1998
- 1304 views
------=_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
- Posted by "Cuny, David" <David.Cuny at DSS.CA.GOV> Nov 13, 1998
- 1501 views
[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
- Posted by Ad Rienks <Ad_Rienks at COMPUSERVE.COM> Nov 13, 1998
- 1282 views
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
- Posted by "Cuny, David" <David.Cuny at DSS.CA.GOV> Nov 13, 1998
- 1309 views
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
- 1306 views
- 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
- 1303 views
- 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