' /////// Init GDI drawing functions from win32 Api \\\\\\\\\\
'==========================================================================
SUB InitDrawing(byval wnd as INT)
'INT ww,hh
''get current size of window
GetSize(wnd,0,0,ww,hh)
'get window DC
hdc=GetDC(wnd)
hdcMem = CreateCompatibleDC(0)
hbmMem = CreateCompatibleBitmap(hdc,ww,hh)
oldBmp = SelectObject( hdcMem, hbmMem )
oldBrush = SelectObject(hdcMem, CreateSolidBrush( RGB(231,223,231)) )
oldPen = SelectObject(hdcMem, CreatePen(PS_SOLID,1,RGB(231,223,231)))
'fill rectangle memDC with brush color
rc.right = ww + 1000
rc.bottom = hh + 1000
FillRect ( hdcMem,rc, oldBrush)
SetTextColor( hDC,RGB(0,0,0))
SetBkColor( hDC, RGB(231,223,231))
'blit to memDC
BitBlt(hDCmem, 0, 0, ww, hh, hdc, 0, 0, SRCCOPY)
'UpdateWindow wnd
ReleaseDC( wnd, hdc)
End SUB
'=================================================
SUB TextColor (wID as INT,byval frontColor as sys,byval backColor as sys)
hdc = GetDC(wID)
fColor=frontColor
bColor = backColor
SetTextColor( hDC, frontColor)
SetBkColor( hDC, bColor)
BitBlt(hDCmem, 0, 0, ww, hh, hdc, 0, 0, SRCCOPY)
ReleaseDC( wID, hdc)
End SUB
'=================================================
Sub TextOn( int wnd,sys x, y, string txt)
'INT ww,hh
hdc=GetDC(wnd)
GetSize(wnd,0,0,ww,hh)
TextOut hdc,x,y,txt,Len(txt)
BitBlt(hDCmem, 0, 0, ww, hh, hdc, 0, 0, SRCCOPY)
ReleaseDC(wnd,Hdc)
End Sub
'=================================================
SUB LineXY (wID as INT,byval x as INT,byval y as INT,byval x1 as INT,byval y1 as INT)
hdc = GetDC(wID)
GetSize(wID,0,0,ww,hh)
'SelectObject(hdc, CreatePen(PS_SOLID,1,fColor))
int np = CreatePen(PS_SOLID,1,fColor)
int op = SelectObject(hdc, np)
MoveToEx hdc,x,y,Byval 0
LineTo hdc,x1,y1
BitBlt(hDCmem, 0, 0, ww, hh, hdc, 0, 0, SRCCOPY)
DeleteObject(SelectObject(hdc, op))
ReleaseDC( wID, hdc)
End SUB
'=================================================
SUB DrawRect(wID as INT,byval rx1 as INT,byval ry1 as INT,byval rx2 as INT,byval ry2 as INT)
hdc = GetDC(wID)
GetSize(wID,0,0,ww,hh)
SetBkMode( hDC, 1) 'transparent
SetBkColor(hDC, RGB(220,220,250))
int np = CreatePen(PS_SOLID,1,fColor) 'new pen
int op = SelectObject(hdc, np)
int nB = CreateSolidBrush( bColor) 'new Brush
int oB = SelectObject(hdc, nB)
'Rectangle bHdc,x,y,w+x,h+y ...hmmm
Rectangle (hdc,rx1,ry1,rx2+rx1,ry2+ry1)
BitBlt(hDCmem, 0, 0, ww, hh, hdc, 0, 0, SRCCOPY)
DeleteObject(SelectObject(hdc, op))
DeleteObject(SelectObject(hdc, oB))
ReleaseDC( wID, hdc)
END SUB
'=================================================
SUB Pset (wID as int , px as int ,py as int)
hdc = GetDC(wID)
'GetSize(wID,0,0,ww,hh)
SetPixel ( hdc, px, py, fColor)
BitBlt(hDCmem, 0, 0, ww, hh, hdc, 0, 0, SRCCOPY)
ReleaseDC( wID, hdc)
End SUB
'====================================================================================
SUB Circle (wID as INT,byval cix as INT,byval ciy as INT,byval cra as INT)
hdc = GetDC(wID)
GetSize(wID,0,0,ww,hh)
'SelectObject(hdc, CreatePen(PS_SOLID,1,fColor))
SetBkMode( hDC, 1) 'transparent
SetBkColor(hDC, RGB(220,220,250))
int np = CreatePen(PS_SOLID,1,fColor) 'new pen
int op = SelectObject(hdc, np)
int nB = CreateSolidBrush( bColor) 'new Brush
int oB = SelectObject(hdc, nB)
Ellipse hdc,cix-cra,ciy-cra,cra+cix,cra+ciy
BitBlt(hDCmem, 0, 0, ww, hh, hdc, 0, 0, SRCCOPY)
DeleteObject(SelectObject(hdc, op))
DeleteObject(SelectObject(hdc, oB))
ReleaseDC( wID, hdc)
End SUB
'====================================================================================
' set window color
Sub FillSolidRect(wID as INT, x As Long, Y As Long, cx As Long, cy As Long, bbColor as INT)
Dim hBr As Long ' rc As RECT
hDC=GetDC(wID)
rc.Left = x
rc.Top = Y
rc.right = x + cx
rc.bottom = Y + cy
hBr = CreateSolidBrush(bbColor)
FillRect hDC, rc, hBr
BitBlt(hDCmem, 0, 0, ww, hh, hdc, 0, 0, SRCCOPY)
ReleaseDC( wID, hdc)
End Sub
'----------------------------------------------------------
SUB WindowColor(wID as INT,wr as INT,wg as INT,wb as INT)
INT backColor = RGB (wr,wg,wb)
FillSolidRect(wID,0,0,ww,hh,backColor)
END SUB
'//////////////////////////////////////////////
SUB CleanUp
DeleteObject(SelectObject(hdcMem, oldBrush))
DeleteObject(SelectObject(hdcMem, oldPen))
DeleteObject(SelectObject(hdcMem, oldBmp))
DeleteDC(hdcMem)
End SUB
Frankly, I don't want to dive deep into Ruben's sources.
1 Why do all your drawing operations paint directly into your screen window and then make a copy of it into the memory DC instead of doing it the other way round?
2 Do you see at least some of your drawing operations, for example such as FillSolidRect() and WindowColor(), leaking GDI objects as seen in your Task Manager with the GDI Objects column visible?
3 How does your main window callback handle the WM_ERASEBKGND message, if at all?
'>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Case win2
Select wMsg
Case WM_PAINT
If win2 <> 0
BitBlt(hDC, 0, 0, ww, hh, hdcMem, 0, 0, SRCCOPY)
End If
Static hBmp As Integer
'===================================================
' Resize backbuffer DC
'===================================================
GetClientRect(ME, @rc)
DeleteObject(SelectObject(hBackDC, hBackBmp))
DeleteDC(hBackDC)
hBackDC = CreateCompatibleDC(GetDC(ME))
hBackBmp = SelectObject(hBackDC, CreateCompatibleBitmap(GetDC, rc.rcRight, rc.rcBottom))
ReleaseDC(ME, GetDC)
'===================================================
Also i found one interesting stuff in FBSL program Space Station
about how resize back buffer ..Code: [Select]Static hBmp As Integer
'===================================================
' Resize backbuffer DC
'===================================================
GetClientRect(ME, @rc)
DeleteObject(SelectObject(hBackDC, hBackBmp))
DeleteDC(hBackDC)
hBackDC = CreateCompatibleDC(GetDC(ME))
hBackBmp = SelectObject(hBackDC, CreateCompatibleBitmap(GetDC, rc.rcRight, rc.rcBottom))
ReleaseDC(ME, GetDC)
'===================================================
3. I'm currently writing a lengthy message to you. Let me take my time, please, before you make any hasty decisions.
my drawing with mouse move is based on FBSL exampleYou are free to use any piece of FBSL code found in the accompanying documentation or on the FBSL site for any purpose unless the code has an explicit license stated in the respective file. All such code is in the Public Domain and does not require any reference as to its origin. FBSL is freeware, after all. Thanks for the reference though. :)
the number of GDI objets in Task are still the same 48..no mather what kind of drawing i do
WM_ERASEBKGND message is not currently part of new window procedure.
Code: OxygenBasic
Case WM_PAINT If win2 <> 0 BitBlt(hDC, 0, 0, ww, hh, hdcMem, 0, 0, SRCCOPY) End If
:o I'm curious how Ruben can still draw anything at all! :)heh .. i agree with you about that .
...Some of your suggestions are really very good but some of them i already tested and not get good results...
...WM_ERASEBGND is not a option because create mess on window area...
Sub FillSolidRect(wID as INT, x As Long, Y As Long, cx As Long, cy As Long, bbColor as INT)
INT hBr,oBr ' rc As RECT
hDC=GetDC(wID)
rc.Left = x
rc.Top = Y
rc.right = x + cx
rc.bottom = Y + cy
hBr = CreateSolidBrush(bbColor)
oBr = SelectObject hdc,hBr
FillRect hDC, rc, hBr
BitBlt(hDCmem, 0, 0, ww, hh, hdc, 0, 0, SRCCOPY)
DeleteObject(SelectObject(hdc, oBr))
ReleaseDC( wID, hdc)
End Sub
nothing is changed...number of GDI objects is still 50 without increasing and is stable.
You suggest me to draw directly into new window hdc..right?
Sub FillSolidRect(wID as INT, x As Long, Y As Long, cx As Long, cy As Long, bbColor as INT)
INT hBr
hDC=GetDC(wID)
rc.Left = x
rc.Top = Y
rc.right = x + cx
rc.bottom = Y + cy
hBr = CreateSolidBrush(bbColor)
FillRect hDC, rc, hBr
DeleteObject hBr
BitBlt(hDCmem, 0, 0, ww, hh, hdc, 0, 0, SRCCOPY)
ReleaseDC( wID, hdc)
End Sub
2. You're making a new copy of your Ruben's entire development folder saving the older folder as a backup that you may always return to in case you don't like what we're doing and/or how we're doing it.
3. You're introducing all of the changes that I described earlier in my messages to this new development folder without omissions, or additions of your own, or attempts to test run it ahead of time, or criticize it prematurely.
/*
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
Hi Mike
sorry only bad news..
I remove all things from GDI functions as you suggested
i also remove InitDrawing() function where is created DC backbuffer.
then i try to implement @onpaint event ( WM_PAINT )
then everything else stop to work >:(
when mousemove & leftbuttondown events work
it looks that wm_paint simply freez my interpteter . ::)
this is really weird ...
i will post source code ...
thanks for asking.. ;)
Big problem i have in ruben is that i want to draw anywhere in program not only under wm_paint.
This program for example use in start 33 objects but when i resize window then
number of GDI ojects go up to 39.
i will post code of ruben4.
... PM me the resultant zip with all the Ruben sources ...
'Black Hole
wform 0,0,800,720,#SYS,0,"BlackHole"
defn w,h,a,r,ps,i,px,py
defn rr,gg,bb,rx,ry
sET w=700/2:
sET h=700/2:
wcolor 0,0,0
set a=1
set r= 0
label again
For i,1,30
set ps=10000/(i/a)
set rr=RAND(255),gg=RAND(255),bb=RAND(255)
txcolor rr,gg,bb,rr,gg,bb
set rx=cos(i*r)*ps+w , ry=sin(i*r)*ps+h
rect ry,rx,4,4
pix rx,ry
Next i
set a= -0.1
If a,<,20
set a=a+0.01
EndIf
ser r= -360
If r,<,360
set r=r+0.01
EndIf
wcolor 0,0,0
jump again
... maybe is not problem with dll but i get very big memory leaks over 220k ...
Meanwhile, I will continue string testing for leaks. I might also create a stringy interpreter to aid this process, since there are many o2 examples that use strings but none do so in a highly iterative manner.
Meanwhile, I will continue string testing for leaks. I might also create a stringy interpreter to aid this process, since there are many o2 examples that use strings but none do so in a highly iterative manner.Ok i will download latest release with latest RTL if you think that part of problem is there.
I will try indexbase 0 & 1 and what is the difference ...
John
open task manager and run ...then you will see how memory using grove...
simple ...
what kind of debugger ???
You need to do better than that if you want to call yourself a programmeroh tutie-frutie managero :P
QuoteYou need to do better than that if you want to call yourself a programmeroh tutie-frutie managero :P
enough for me
sorry but i am not creator of o2 , so how i know what is where :o
SLS ;D
I don't have Power Basic