From: <mie...@us...> - 2009-11-29 22:27:59
|
Revision: 5347 http://oorexx.svn.sourceforge.net/oorexx/?rev=5347&view=rev Author: miesfeld Date: 2009-11-29 22:27:47 +0000 (Sun, 29 Nov 2009) Log Message: ----------- Fix and enhance the oowalk* example programs Modified Paths: -------------- main/trunk/samples/windows/oodialog/oograph.rex main/trunk/samples/windows/oodialog/oowalk2.rex main/trunk/samples/windows/oodialog/oowalker.rex main/trunk/samples/windows/oodialog/rc/walker.rc Modified: main/trunk/samples/windows/oodialog/oograph.rex =================================================================== --- main/trunk/samples/windows/oodialog/oograph.rex 2009-11-28 23:53:41 UTC (rev 5346) +++ main/trunk/samples/windows/oodialog/oograph.rex 2009-11-29 22:27:47 UTC (rev 5347) @@ -78,23 +78,28 @@ -- The 102 button height is much larger, it covers most of the lower part of the -- dialog. -- - -- Then, the bitmaps for the buttons are displaced (moved from the upper left corner - -- of the button) by a large amount. The 101 button is displaced far to the right, - -- and the 102 button is displaced far to the bottom and far to the left. In the run() - -- method, scrollBitmapFromTo() is used to scroll the bitmaps from their displaced positions - -- back to the upper left corner of the buttons. This gives the bitmaps the appearance of - -- scrolling from the right to the left, the 101 button, and from the bottom to the top, - -- the 102 button. + -- Then, the bitmaps for the buttons are positioned (moved from the upper left corner + -- of the button) by a large amount. The 101 button is positioned far to the right, + -- and the 102 button is positioned far to the bottom and far to the left. In the run() + -- method, scrollBitmapFromTo() is used to scroll the bitmaps from their positions back + -- to the upper left corner of the buttons. This gives the bitmaps the 101 button the + -- appearance of scrolling from the right to the left, and the 102 button the appearance + -- of scrolling from the bottom to the top. - self~createBitmapButton(101, 1, 10, self~SizeX-1, 130 / self~FactorY, "USEPAL", , , "bmp\install.bmp") - self~createBitmapButton(102, 20, but2pos, self~SizeX - 20 ,but2size, , , , "bmp\install2.bmp") - self~DisplaceBitmap(101,self~SizeX * self~FactorX+10, 0) - self~DisplaceBitmap(102, -450, 100) + self~createBitmapButton(101, 1, 10, self~sizeX-1, 130 / self~factorY, "USEPAL", , , "bmp\install.bmp") + self~createBitmapButton(102, 20, but2pos, self~sizeX - 20, but2size, , , , "bmp\install2.bmp") + pos = .Point~new(self~sizeX * self~factorX + 10, 0) + self~setBitmapPosition(101, pos) + + pos~x = -450 + pos~y = 100 + self~setBitmapPosition(102, pos) + -- Add the other controls. - self~createWhiteFrame(203, 10, self~SizeY - 52, self~SizeX-20, 28, "HIDDEN") - self~createPushButton(103, 12, self~SizeY - 50, self~SizeX-24, 24, "OWNER NOTAB") - self~createPushButtonGroup(self~SizeX-220, self~SizeY - 18,60,12, , + self~createWhiteFrame(203, 10, self~SizeY - 52, self~sizeX-20, 28, "HIDDEN") + self~createPushButton(103, 12, self~SizeY - 50, self~sizeX-24, 24, "OWNER NOTAB") + self~createPushButtonGroup(self~sizeX-220, self~sizeY - 18,60,12, , "&Bitmap-Viewer 111 BmpView &Draw-Color-Demo 112 OODraw &Cancel 2 CANCEL", 1, "DEFAULT") ::method initDialog Modified: main/trunk/samples/windows/oodialog/oowalk2.rex =================================================================== --- main/trunk/samples/windows/oodialog/oowalk2.rex 2009-11-28 23:53:41 UTC (rev 5346) +++ main/trunk/samples/windows/oodialog/oowalk2.rex 2009-11-29 22:27:47 UTC (rev 5347) @@ -1,12 +1,12 @@ /*----------------------------------------------------------------------------*/ /* */ /* Copyright (c) 1995, 2004 IBM Corporation. All rights reserved. */ -/* Copyright (c) 2005-2006 Rexx Language Association. All rights reserved. */ +/* Copyright (c) 2005-2009 Rexx Language Association. All rights reserved. */ /* */ /* This program and the accompanying materials are made available under */ /* the terms of the Common Public License v1.0 which accompanies this */ /* distribution. A copy is also available at the following address: */ -/* http://www.oorexx.org/license.html */ +/* http://www.oorexx.org/license.html */ /* */ /* Redistribution and use in source and binary forms, with or */ /* without modification, are permitted provided that the following */ @@ -35,12 +35,32 @@ /* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* */ /*----------------------------------------------------------------------------*/ -/*--------------------------------------------------------------------------*/ -/* */ -/* OODialog\Samples\oowalk2.rex Animation demonstration (using DLL) */ -/* */ -/*--------------------------------------------------------------------------*/ +/** + * oowalk2.rex Animation demonstration (using a compiled binary resource + * for the dialog template. A DLL file.) + * + * The only real difference between this sample and the oowalker.rex sample is + * the way the bitmaps for the animation are loaded. Look at the initDialog() + * method of the .WalkerDialog to see this difference. + * + * An animated button is used to simulate a man walking across the dialog. The + * user can adjust the pace of the waling by setting the amount the man is + * moved each time the button is redrawn and the delay between redrawing the + * button. The button is drawn using a sequence of bitmaps that show the man + * with different leg and arm positions. The user can also set how the man + * 'walking' off the edge of the dialog is handled, smoothly or bouncy, by + * using the "smooth corner wrap" check box. + * + * A 'got cha' point (!!!) is periodically drawn and if the man is close enough + * to this 'danger,' the man is 'gotten' and the animation is stopped. Each + * time the button is drawn, the !!! is over-drawn, so the !!! is only seen + * as a flicker. + * + * Normally the dialog ends when the walker is gotten. However there is a + * check box that allows the user to cancel this behavior and then restart the + * animation. + */ curdir = directory() parse source . . me @@ -51,7 +71,8 @@ sp = value('SOUNDPATH',,env) sp = value('SOUNDPATH',win';'mydir'\WAV;'sp,env) - dlg = .walkerdlg~new('res\oowalk2.dll',100,data.) + dlg = .WalkerDialog~new('res\oowalk2.dll',100,data.) + if dlg~InitCode \= 0 then exit dlg~Execute("SHOWTOP") dlg~deinstall @@ -64,49 +85,144 @@ /*---------------------------- walker dialog ------------------------*/ -::class walkerdlg subclass ResDialog +::class 'WalkerDialog' subclass ResDialog -::method InitDialog - self~InitDialog:super - self~installBitmapButton(100, '', 0); +::method initDialog + expose bitmaps spriteButton quitCheckBox restartButton okButton -::method Run - /* bitmaps have IDs 201-208 in oowalker.dll */ + -- Make button 105 a bitmap button. Bitmap buttons are owner-drawn and + -- ooDialog will manage the 'drawing' of the button by painting a series of + -- bitmaps on the button, using the AnimatedButton class. + self~installBitmapButton(105, '', 0); - sb = .walkbutton~new(100, 201,208, 10, 2, 70, 120, 60, 10, 10, self) + -- The bitmaps are loaded from the resource DLL by specifying their resouce + -- IDs in the DLL file, res\oowalk2.dll. + spriteButton = .WalkButton~new(105, 201, 208, 10, 2, 70, 120, 60, 10, 10, self) - sb~setsmooth(0) /* bouncy operation on edges */ - sb~setstep(1) /* size of step through bitmap IDs */ + -- Use 'bouncy' operation when hitting edges. + spriteButton~setSmooth(.false) - sb~filldata(data.) - self~setdatastem(data.) + -- Size of the step through the bitmap IDs. + spriteButton~setstep(1) + + -- Get things set up. + self~connectButtonEvent(107, "CLICKED", onRestart) + quitCheckBox = self~newCheckBox(106) + restartButton = self~newPushButton(107) + okButton = self~newPushButton(IDOK) + quitCheckBox~check + spriteButton~fillData(data.) + spriteButton~suspendGotCha(.false) + self~setDataStem(data.) ret = Play("tada.wav", n) - sb~run /* animate the button */ - return 0 + -- Animate the button. + spriteButton~run +::method doDataStemGet unguarded + use strict arg data. + self~getDataStem(data.) + +::method doDataStemSet unguarded + use strict arg data. + self~setDataStem(data.) + +::method onGotCha + expose okButton + use strict arg animatedButton x, y + okButton~disable + self~writetoButton(105, x, y, "Got-cha", "Arial", 28, "BOLD") + ret = play('gotcha.wav') + animatedButton~stop + call msSleep 1000 + +::method maybeQuit + expose quitCheckBox restartButton okButton + if quitCheckBox~checked then return self~ok + + restartButton~enable + okButton~enable + +::method onRestart + expose spriteButton restartButton + restartButton~disable + spriteButton~stopped = .false + + -- Suspend the 'GotCha' before we start the animated button. Otherwise the + -- walker will be 'gotten' as soon as he starts. + spriteButton~suspendGotCha(.true) + spriteButton~run + + -- Give the walker time to 'walk' out of the danger zone before reactivating + -- the 'GotCha.' + delay = self~newEdit(103)~getText + j = msSleep(2 * delay) + spriteButton~suspendGotCha(.false) + +::method ok + self~stopAnimation + return self~ok:super + +::method cancel + self~stopAnimation + return self~cancel:super + +::method stopAnimation private + expose bitmaps spriteButton + spriteButton~stop + + -- Wait until the animation sequence is finished. + do while spriteButton~isRunning + j = msSleep(30) + end + + /*------------------------------ animated button --------------------*/ -::class WalkButton subclass AnimatedButton +::class 'WalkButton' subclass AnimatedButton ::method run - expose xdanger ydanger - xdanger = 300; ydanger = 70 - do until(self~stopped = 1) | (self~ParentStopped = 1) - self~moveseq - self~ParentDlg~getdatastem(data.) - do k over data. - if data.k~datatype('N') = 0 then data.k = 0 - end - self~ParentDlg~HandleMessages - self~setmove(data.101, data.102) - self~setdelay(data.103) - self~setsmooth(data.104) - if self~stopped = 0 then - self~parentdlg~writetoButton(100,xdanger,ydanger,"!!!","Arial",20,"BOLD") + expose xDanger yDanger running + xDanger = 300; yDanger = 70; running = .true + + reply 0 + + do until(self~stopped = 1) | (self~parentStopped = 1) + self~doAnimatedSequence end - return 0 + -- Have the walker do one more sequence, gives the appearance of walking 'in + -- in place.' + self~doAnimatedSequence + + -- We are no longer running, tell the parent dialog to maybe quit. + running = .false + self~parentDlg~maybeQuit + +::method doAnimatedSequence private + expose xDanger yDanger + + self~moveseq + self~parentDlg~doDataStemGet(data.) + do k over data. + if data.k~datatype('N') = 0 then data.k = 0 + end + self~setmove(data.101, data.102) + self~setdelay(data.103) + self~setsmooth(data.104) + if self~stopped = 0 then + self~parentDlg~writetoButton(105,xDanger,yDanger,"!!!","Arial",20,"BOLD") + +::method isRunning unguarded + expose running + return running + +::method suspendGotCha unguarded + expose gotCha + use strict arg suspend + if suspend then gotCha = .false + else gotCha = .true + ::method hitright ret = play('ding.wav', 'YES') return 1 @@ -120,8 +236,8 @@ ret = play('chord.wav', 'YES') s.movey = -s.movey self~setsprite(s.) - self~filldata(data.) - self~ParentDlg~setdatastem(data.) + self~fillData(data.) + self~parentDlg~doDataStemSet(data.) return 0 ::method hittop @@ -130,18 +246,23 @@ ret = play('chimes.wav', 'YES') s.movey = -s.movey self~setsprite(s.) - self~filldata(data.) - self~ParentDlg~setdatastem(data.) + self~fillData(data.) + self~parentDlg~doDataStemSet(data.) return 0 -::method filldata +::method fillData + expose quitCheckBox use arg data. - self~GetSprite(msprite.) + if \ quitCheckBox~isA(.CheckBox) then quitCheckBox = self~parentDlg~newCheckBox(106) + self~getSprite(msprite.) data.101 = msprite.movex data.102 = msprite.movey data.103 = msprite.delay data.104 = msprite.smooth + if quitCheckBox~checked then data.106 = 1 + else data.106 = 0 + ::method movepos use arg px, py if self~stopped=0 then do @@ -150,11 +271,8 @@ end ::method checkDanger - expose xdanger ydanger + expose xDanger yDanger gotCha self~getpos(cur.) - if abs(cur.x+10-xdanger) <= 10 & abs(cur.y+55-ydanger) <= 30 then do - self~parentdlg~writetoButton(100,xdanger-50,ydanger,"Got-cha","Arial",28,"BOLD") - ret = play('gotcha.wav') - self~stop - call msSleep 1000 + if abs(cur.x+10-xDanger) <= 10 & abs(cur.y+55-yDanger) <= 30 then do + if gotCha then self~parentDlg~onGotCha(self, xDanger-50, yDanger) end Modified: main/trunk/samples/windows/oodialog/oowalker.rex =================================================================== --- main/trunk/samples/windows/oodialog/oowalker.rex 2009-11-28 23:53:41 UTC (rev 5346) +++ main/trunk/samples/windows/oodialog/oowalker.rex 2009-11-29 22:27:47 UTC (rev 5347) @@ -1,12 +1,12 @@ /*----------------------------------------------------------------------------*/ /* */ /* Copyright (c) 1995, 2004 IBM Corporation. All rights reserved. */ -/* Copyright (c) 2005-2006 Rexx Language Association. All rights reserved. */ +/* Copyright (c) 2005-2009 Rexx Language Association. All rights reserved. */ /* */ /* This program and the accompanying materials are made available under */ /* the terms of the Common Public License v1.0 which accompanies this */ /* distribution. A copy is also available at the following address: */ -/* http://www.oorexx.org/license.html */ +/* http://www.oorexx.org/license.html */ /* */ /* Redistribution and use in source and binary forms, with or */ /* without modification, are permitted provided that the following */ @@ -35,12 +35,32 @@ /* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* */ /*----------------------------------------------------------------------------*/ -/*--------------------------------------------------------------------------*/ -/* */ -/* OODialog\Samples\oowalker.rex Animation demonstration (using .RC) */ -/* */ -/*--------------------------------------------------------------------------*/ +/** + * oowalker.rex Animation demonstration (using a .rc file for the dialog + * template.) + * + * The only real difference between this sample and the oowalk2.rex sample is + * the way the bitmaps for the animation are loaded. Look at the initDialog() + * method of the .WalkerDialog to see this difference. + * + * An animated button is used to simulate a man walking across the dialog. The + * user can adjust the pace of the waling by setting the amount the man is + * moved each time the button is redrawn and the delay between redrawing the + * button. The button is drawn using a sequence of bitmaps that show the man + * with different leg and arm positions. The user can also set how the man + * 'walking' off the edge of the dialog is handled, smoothly or bouncy, by + * using the "smooth corner wrap" check box. + * + * A 'got cha' point (!!!) is periodically drawn and if the man is close enough + * to this 'danger,' the man is 'gotten' and the animation is stopped. Each + * time the button is drawn, the !!! is over-drawn, so the !!! is only seen + * as a flicker. + * + * Normally the dialog ends when the walker is gotten. However there is a + * check box that allows the user to cancel this behavior and then restart the + * animation. + */ curdir = directory() parse source . . me @@ -51,7 +71,7 @@ sp = value('SOUNDPATH',,env) sp = value('SOUNDPATH',win';'mydir'\WAV;'sp,env) - dlg = .walkerdlg~new(data.) + dlg = .WalkerDialog~new(data.) if dlg~InitCode \= 0 then exit if dlg~Load("rc\walker.rc") > 0 then exit @@ -66,18 +86,43 @@ /*---------------------------- walker dialog ------------------------*/ -::class walkerdlg subclass UserDialog +::class 'WalkerDialog' subclass UserDialog -::method InitDialog - expose bitmaps - self~InitDialog:super - self~installBitmapButton(100, '', 0); +::method initDialog + expose bitmaps spriteButton quitCheckBox restartButton okButton - bitmaps = .array~new(8) /* load bitmaps from file into array */ + -- Make button 105 a bitmap button. Bitmap buttons are owner-drawn and + -- ooDialog will manage the 'drawing' of the button by painting a series of + -- bitmaps on the button, using the AnimatedButton class. + self~installBitmapButton(105, '', 0); + + -- Load the bitmaps from the bitmap files into an array. + bitmaps = .array~new(8) do i= 1 to 8 - bitmaps[i] = self~LoadBitmap("bmp\wlkfig"i".bmp") + bitmaps[i] = self~loadBitmap("bmp\wlkfig"i".bmp") end + -- Create the animated button class and pass the array of bitmaps. + spriteButton = .WalkButton~new(105, bitmaps, 0, 10, 2, 70, 120, 60, 10, 10, self) + + -- Use 'bouncy' operation when hitting edges. + spriteButton~setSmooth(.false) + sb~setstep(1) /* size of step through bitmap IDs */ + + -- Get things set up. + self~connectButtonEvent(107, "CLICKED", onRestart) + quitCheckBox = self~newCheckBox(106) + restartButton = self~newPushButton(107) + okButton = self~newPushButton(IDOK) + quitCheckBox~check + spriteButton~fillData(data.) + spriteButton~suspendGotCha(.false) + self~setDataStem(data.) + ret = Play("tada.wav", n) + + -- Animate the button. + spriteButton~run + ::method doDataStemGet unguarded use strict arg data. self~getDataStem(data.) @@ -86,46 +131,107 @@ use strict arg data. self~setDataStem(data.) -::method Run - expose bitmaps - /* call animation class and pass array with bitmaps */ - sb = .walkbutton~new(100, bitmaps, 0, 10, 2, 70, 120, 60, 10, 10, self) +::method onGotCha + expose okButton + use strict arg animatedButton x, y + okButton~disable + self~writetoButton(105, x, y, "Got-cha", "Arial", 28, "BOLD") + ret = play('gotcha.wav') + animatedButton~stop + call msSleep 1000 - sb~setsmooth(0) /* bouncy operation on edges */ +::method maybeQuit + expose quitCheckBox restartButton okButton + if quitCheckBox~checked then return self~ok - sb~filldata(data.) - self~setdatastem(data.) - ret = Play("tada.wav", n) - sb~run /* animate the button */ + restartButton~enable + okButton~enable - do i= 1 to 8 /* remove bitmaps when done */ - self~RemoveBitmap(bitmaps[i]) +::method onRestart + expose spriteButton restartButton + restartButton~disable + spriteButton~stopped = .false + + -- Suspend the 'GotCha' before we start the animated button. Otherwise the + -- walker will be 'gotten' as soon as he starts. + spriteButton~suspendGotCha(.true) + spriteButton~run + + -- Give the walker time to 'walk' out of the danger zone before reactivating + -- the 'GotCha.' + delay = self~newEdit(103)~getText + j = msSleep(2 * delay) + spriteButton~suspendGotCha(.false) + +::method ok + self~stopAnimation + return self~ok:super + +::method cancel + self~stopAnimation + return self~cancel:super + +::method stopAnimation private + expose bitmaps spriteButton + spriteButton~stop + + -- Wait until the animation sequence is finished. + do while spriteButton~isRunning + j = msSleep(30) end - return 0 + -- Now it is safe to delete the bitmaps. + do i= 1 to 8 + self~removeBitmap(bitmaps[i]) + end + + /*------------------------------ animated button --------------------*/ -::class WalkButton subclass AnimatedButton +::class 'WalkButton' subclass AnimatedButton ::method run - expose xdanger ydanger - xdanger = 300; ydanger = 70 - do until(self~stopped = 1) | (self~ParentStopped = 1) - self~moveseq - self~parentDlg~doDataStemGet(data.) - --self~parentDlg~getdatastem(data.) - do k over data. - if data.k~datatype('N') = 0 then data.k = 0 - end - self~ParentDlg~HandleMessages - self~setmove(data.101, data.102) - self~setdelay(data.103) - self~setsmooth(data.104) - if self~stopped = 0 then - self~parentdlg~writetoButton(100,xdanger,ydanger,"!!!","Arial",20,"BOLD") + expose xDanger yDanger running + xDanger = 300; yDanger = 70; running = .true + + reply 0 + + do until(self~stopped = 1) | (self~parentStopped = 1) + self~doAnimatedSequence end - return 0 + -- Have the walker do one more sequence, gives the appearance of walking 'in + -- in place.' + self~doAnimatedSequence + + -- We are no longer running, tell the parent dialog to maybe quit. + running = .false + self~parentDlg~maybeQuit + +::method doAnimatedSequence private + expose xDanger yDanger + + self~moveseq + self~parentDlg~doDataStemGet(data.) + do k over data. + if data.k~datatype('N') = 0 then data.k = 0 + end + self~setmove(data.101, data.102) + self~setdelay(data.103) + self~setsmooth(data.104) + if self~stopped = 0 then + self~parentDlg~writetoButton(105,xDanger,yDanger,"!!!","Arial",20,"BOLD") + +::method isRunning unguarded + expose running + return running + +::method suspendGotCha unguarded + expose gotCha + use strict arg suspend + if suspend then gotCha = .false + else gotCha = .true + ::method hitright ret = play('ding.wav', 'YES') return 1 @@ -139,7 +245,7 @@ ret = play('chord.wav', 'YES') s.movey = -s.movey self~setsprite(s.) - self~filldata(data.) + self~fillData(data.) self~parentDlg~doDataStemSet(data.) return 0 @@ -149,18 +255,23 @@ ret = play('chimes.wav', 'YES') s.movey = -s.movey self~setsprite(s.) - self~filldata(data.) + self~fillData(data.) self~parentDlg~doDataStemSet(data.) return 0 -::method filldata +::method fillData + expose quitCheckBox use arg data. - self~GetSprite(msprite.) + if \ quitCheckBox~isA(.CheckBox) then quitCheckBox = self~parentDlg~newCheckBox(106) + self~getSprite(msprite.) data.101 = msprite.movex data.102 = msprite.movey data.103 = msprite.delay data.104 = msprite.smooth + if quitCheckBox~checked then data.106 = 1 + else data.106 = 0 + ::method movepos use arg px, py if self~stopped=0 then do @@ -169,11 +280,8 @@ end ::method checkDanger - expose xdanger ydanger + expose xDanger yDanger gotCha self~getpos(cur.) - if abs(cur.x+10-xdanger) <= 10 & abs(cur.y+55-ydanger) <= 30 then do - self~parentdlg~writetoButton(100,xdanger-50,ydanger,"Got-cha","Arial",28,"BOLD") - ret = play('gotcha.wav') - self~stop - call msSleep 1000 + if abs(cur.x+10-xDanger) <= 10 & abs(cur.y+55-yDanger) <= 30 then do + if gotCha then self~parentDlg~onGotCha(self, xDanger-50, yDanger) end Modified: main/trunk/samples/windows/oodialog/rc/walker.rc =================================================================== --- main/trunk/samples/windows/oodialog/rc/walker.rc 2009-11-28 23:53:41 UTC (rev 5346) +++ main/trunk/samples/windows/oodialog/rc/walker.rc 2009-11-29 22:27:47 UTC (rev 5347) @@ -49,8 +49,10 @@ EDITTEXT 102, 118, 23, 25, 12, ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_GROUP | WS_TABSTOP EDITTEXT 103, 199, 23, 38, 12, WS_BORDER | WS_TABSTOP AUTOCHECKBOX "&Smooth corner wrap", 104, 260, 22, 77, 15 + AUTOCHECKBOX "&Quit on 'Got-cha'", 106, 12, 237, 77, 15 + PUSHBUTTON "Restart", 107, 230, 237, 50, 14, WS_DISABLED DEFPUSHBUTTON "OK", 1, 290, 237, 50, 14 - AUTO3STATE "Button", 100, 3, 62, 341, 164, BS_OWNERDRAW | WS_CHILD | WS_VISIBLE | WS_TABSTOP + AUTO3STATE "Button", 105, 3, 62, 341, 164, BS_OWNERDRAW | WS_CHILD | WS_VISIBLE | WS_TABSTOP CONTROL "", -1, "STATIC", SS_BLACKFRAME | WS_CHILD | WS_VISIBLE, 1, 58, 345, 170 LTEXT "Move &X:", -1, 12, 25, 30, 9 LTEXT "Move &Y:", -1, 87, 25, 28, 9 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |