Mike
I just want to post here one program written in EBasic then you can tell me if is
created properly .Because it seems to me that work fine:
code in EB:
/*
flicker_free_graph.eba by jos de jong
with help from the ibasic forums (see codingmonkeys.com)
tweaked by John Siino
this version of flicker free graph does take a certain scale factor as constant,
and depending on that calculates the boundaries xmin, xmax, ymin, ymax of the graph
when the graph is resized or moved
you can move the graph by dragging the mouse or with the arrow keys
you can zoom the graph with keys + and -
*/
'DECLARATIONS
$INCLUDE "windows.inc"
DECLARE IMPORT, LoadCursor ALIAS LoadCursorA(hInstance AS INT,lpCursorName AS POINTER),INT
DECLARE IMPORT, GetCursorPos(lppoint:POINTER)
DECLARE IMPORT, ScreenToClient(HWND:uint, lppoint:POINTER)
WINDOW figure, plotwin
'axes of the graphics screen
DOUBLE xmin, xmax, ymin, ymax
'factors such that xscreen = x * xfactor + xshift and yscreen = y * yfactor + yshift
DOUBLE xfactor, xshift, yfactor, yshift
DEF MouseDownL, MouseDownR, MouseStartX, MouseStartY:INT
CONST Black=0
Figure_Load()
Refresh_Scale()
Plot_Graph()
SETFOCUS plotwin
WAITUNTIL figure=0
END
'_______________________________________________________________________
SUB Figure_Load()
'load window figure with subwindow plotwin
string figtxt
figtxt = "Figure - Move by dragging mouse or with arrow keys, zoom with + and -"
'load the window (outside the screen)
OPENWINDOW figure, -600,100,500,400, @MINBOX|@MAXBOX|@SIZE|@NOAUTODRAW, 0, figtxt, &RoutineFigure
OPENWINDOW plotwin, 0,0,200,200, @NOCAPTION | @NOAUTODRAW, figure, "plot", &RoutinePlotWin
'create this window with a sunken border
_SetWindowLong(plotwin.hwnd,-20,512)
_SetWindowPos(plotwin.hwnd,NULL,0,0,0,0,39)
Resize()
CfgSetDefault()
'center the window in the screen so it is visible now
CENTERWINDOW figure
RETURN
ENDSUB
'_______________________________________________________________________
SUB RoutineFigure()
'handling of messages from window figure
SELECT @MESSAGE
CASE @IDCLOSEWINDOW
'close the figure window
CLOSEWINDOW plotwin
CLOSEWINDOW figure
CASE @IDSIZECHANGED
Resize()
Refresh_Scale()
Plot_Graph()
ENDSELECT
RETURN
ENDSUB
'_______________________________________________________________________
SUB RoutinePlotwin() :'handling of messages from window plotwin
SETTYPE @HITWINDOW, WINDOW
SELECT @MESSAGE
CASE @IDPAINT
Refresh_Scale()
Plot_Graph()
CASE @IDLBUTTONDN
'move axes
_SetCapture(*@HITWINDOW.hwnd)
GetCursorPos(&@MOUSEX)
ScreenToClient(*@HITWINDOW.hwnd, &@MOUSEX)
MouseStartX = @MOUSEX
MouseStartY = @MOUSEY
SETCURSOR plotwin, @CSCUSTOM, LoadCursor(NULL, IDC_SIZEALL) :'cursor "move"
CASE @IDLBUTTONUP
_ReleaseCapture()
SETCURSOR plotwin, @CSARROW :' cursor back to normal cursor
CASE @IDMOUSEMOVE
if (_GetCapture() = *@HITWINDOW.hwnd)
GetCursorPos(&@MOUSEX)
ScreenToClient(*@HITWINDOW.hwnd, &@MOUSEX)
'Left mousebutton down. move the plot with the mouse movement
'xmin -= (@MOUSEX-MouseStartX) / xfactor
'xmax -= (@MOUSEX-MouseStartX) / xfactor
'ymin -= (@MOUSEY-MouseStartY) / yfactor
'ymax -= (@MOUSEY-MouseStartY) / yfactor
xshift += (@MOUSEX-MouseStartX)
yshift += (@MOUSEY-MouseStartY)
MouseStartX = @MOUSEX
MouseStartY = @MOUSEY
'replot
Refresh_Scale()
Plot_Graph()
ENDIF
CASE @IDKEYDOWN
'check keypresses
'for the keycodes, see the usersguide Appendix, Virtual key codes
SELECT @WPARAM
CASE 0x25
'left arrow is pressed. move the graph to the left
xshift -= 20
Refresh_Scale()
Plot_Graph()
CASE 0x27
'right arrow is pressed. move the graph to the right
xshift += 20
Refresh_Scale()
Plot_Graph()
CASE 0x26
'up arrow is pressed. move the graph up
yshift -= 20
Refresh_Scale()
Plot_Graph()
CASE 0x28
'down arrow is pressed. move the graph to down
yshift += 20
Refresh_Scale()
Plot_Graph()
ENDSELECT
CASE @IDCHAR
'check keypresses
'for the keycodes, see the usersguide Appendix, Virtual key codes
SELECT @WPARAM
CASE ASC("+")
CASE& ASC("=")
'+ key is pressed. zoom the graph in
xfactor *= 1.2
yfactor *= 1.2
Refresh_Scale()
Plot_Graph()
CASE ASC("-")
CASE& ASC("_")
'- key is pressed. zoom the graph out
xfactor /= 1.2
yfactor /= 1.2
Refresh_Scale()
Plot_Graph()
ENDSELECT
ENDSELECT
RETURN
ENDSUB
'_______________________________________________________________________
SUB Plot_Graph() :'this sub repaints the graph
INT L,T,W,H, hdc, hdcMem, hbmMem, oldBmp, oldBrush, oldPen, oldFont
DOUBLE xscreen, yscreen
GETCLIENTSIZE(plotwin, L,T,W,H) :'get size of window
'Create an off-screen DC for double-buffering
hdc = _GetDC(plotwin.hwnd)
hdcMem = _CreateCompatibleDC(0)
hbmMem = _CreateCompatibleBitmap(hdc, W, H)
oldBmp = _SelectObject(hdcMem, hbmMem)
oldBrush = _SelectObject(hdcMem, _CreateSolidBrush(RGB(255,255,255)))
oldPen = _SelectObject(hdcMem, _CreatePen(PS_SOLID,1,RGB(255,255,255)))
'set specific font
INT textW, textH, fontsize, fontwt
STRING fontface
fontface = "Courier New" : fontsize = 12 : fontwt = 600
SETFONT plotwin, fontface, fontsize, fontwt, 0
GETTEXTSIZE(plotwin, "A", textW, textH) :'find the desired text Height
oldFont = _SelectObject(hdcMem, _CreateFont(textH,0,0,0,fontwt, 0,0,0,0,0,0,0,0, fontface))
_SetTextColor(hdcMem, RGB(0,0,255))
_SetBkMode(hdcMem, TRANSPARENT)
_SetTextAlign(hdcMem,TA_UPDATECP)
'empty window -> draw white, filled rectangle
_Rectangle(hdcMem, 0, 0, W, H)
'Paint axes with black frontpen
_DeleteObject(_SelectObject(hdcMem, _CreatePen(PS_SOLID,1,RGB(0,0,0))))
_MoveToEx(hdcMem, xmin * xfactor + xshift, 0 * yfactor + yshift, NULL)
_LineTo(hdcMem, xmax * xfactor + xshift, 0 * yfactor + yshift)
_MoveToEx(hdcMem, 0 * xfactor + xshift, ymin * yfactor + yshift, NULL)
_LineTo(hdcMem, 0 * xfactor + xshift, ymax * yfactor + yshift)
'paint the function with red frontpen
_DeleteObject(_SelectObject(hdcMem, _CreatePen(PS_SOLID,1,RGB(255,0,0))))
xscreen = 0 : yscreen = -myfunction((xscreen-xshift)/xfactor) * yfactor + yshift
_MoveToEx(hdcMem, xscreen, yscreen, NULL)
FOR n=0 TO w+5 STEP 2
xscreen = n : yscreen = -myfunction((xscreen-xshift)/xfactor) * yfactor + yshift
_LineTo(hdcMem, xscreen, yscreen)
NEXT n
'Print some text with blue frontpen
_DeleteObject(_SelectObject(hdcMem, _CreatePen(PS_SOLID,1,RGB(0,0,255))))
STRING mystring : mystring = "Sin(x)"
_MoveToEx(hdcMem, 10, 19 * H / 20, NULL)
_TextOut(hdcMem, 0, 0, mystring, len(mystring))
'Print axes labels with black frontpen
_DeleteObject(_SelectObject(hdcMem, _CreatePen(PS_SOLID,1,RGB(0,0,0))))
_MoveToEx(hdcMem, 19 * W / 20, yshift, NULL)
_TextOut(hdcMem, 0, 0, "x", len("x"))
_MoveToEx(hdcMem, xshift, H /40, NULL)
_TextOut(hdcMem, 0, 0, " y", len(" y"))
'Print axes tick marks with black frontpen
_DeleteObject(_SelectObject(hdcMem, _CreatePen(PS_SOLID,1,RGB(0,0,0))))
FOR n=0 TO w+5 STEP 1
_MoveToEx(hdcMem, -n * xfactor + xshift, yshift - H / 50, NULL)
_LineTo(hdcMem, -n * xfactor + xshift, yshift + H / 50)
_MoveToEx(hdcMem, n * xfactor + xshift, yshift - H / 50, NULL)
_LineTo(hdcMem, n * xfactor + xshift, yshift + H / 50)
_MoveToEx(hdcMem, xshift - H / 50, -n * yfactor + yshift, NULL)
_LineTo(hdcMem, xshift + H /50, -n * yfactor + yshift)
_MoveToEx(hdcMem, xshift - H / 50, n * yfactor + yshift, NULL)
_LineTo(hdcMem, xshift + H /50, n * yfactor + yshift)
NEXT n
'Transfer the off-screen DC to the screen
_BitBlt(hdc, 0, 0, W, H, hdcMem, 0, 0, SRCCOPY)
'Free-up the off-screen DC
_DeleteObject(_SelectObject(hdcMem, oldFont))
_DeleteObject(_SelectObject(hdcMem, oldBrush))
_DeleteObject(_SelectObject(hdcMem, oldPen))
_DeleteObject(_SelectObject(hdcMem, oldBmp))
_DeleteDC(hdcMem)
_ReleaseDC(plotwin.hwnd, hdc)
RETURN
ENDSUB
'_______________________________________________________________________
SUB myfunction(value:DOUBLE),DOUBLE
'calculate a functionvalue
RETURN sin(value)
ENDSUB
'_______________________________________________________________________
SUB Refresh_Scale()
'calculate the boundaries xmin, xmax, ymin, ymax for painting in the screen plotwin
'this depends on the scale of the graph and the size of the window plotwin
INT L,T,W,H
GETCLIENTSIZE plotwin, L,T,W,H
'xfactor = W / (xmax - xmin)
'yfactor = -H / (ymax - ymin)
'xshift = -xmin * xfactor
'yshift = -ymax * yfactor
xmin = (0-xshift) / xfactor
xmax = (w-xshift) / xfactor
ymin = (0-yshift) / yfactor
ymax = (h-yshift) / yfactor
RETURN
ENDSUB
'_______________________________________________________________________
SUB Resize()
'resize figure window with its subwindow
INT L,T,W,H
GETCLIENTSIZE figure, L,T,W,H
SETSIZE plotwin, 0,0,W,H
RETURN
ENDSUB
'_______________________________________________________________________
SUB CfgSetDefault()
'set default values for the properties of the figure
INT L,T,W,H
GETCLIENTSIZE plotwin, L,T,W,H
'xmin=-5
'xmax=5
'ymin=-5
'ymax=5
xfactor = 40
yfactor = 35
xshift = W/2 :'start the axis at half the width of the plotwin
yshift = H/2
RETURN
ENDSUB
.