Author Topic: GDI functions & Init problems?  (Read 16279 times)

0 Members and 1 Guest are viewing this topic.

Mike Lobanovsky

  • Guest
Re: GDI functions & Init problems?
« Reply #15 on: March 11, 2015, 03:50:11 AM »
Hi Aurel,

Thank you; I take it as your consent with my proposition. I will be waiting for your signal that all the changes are ready.

Aurel

  • Guest
Re: GDI functions & Init problems?
« Reply #16 on: March 11, 2015, 01:50:35 PM »
Hi Mike
Just to inform you ,i made first small step and replace inside my interpreter loop
message processing from If PeekMessage (&wm,0,0,0,Pm_Remove)>0
to:
While PeekMessage (&wm,0,0,0,Pm_Remove)>0
and it looks to me that i get some speed up...what is good.. :D

Mike Lobanovsky

  • Guest
Re: GDI functions & Init problems?
« Reply #17 on: March 11, 2015, 01:58:29 PM »
Aurel,

C'mon, please...

Quote from: Myself
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.

Mike Lobanovsky

  • Guest
Re: GDI functions & Init problems?
« Reply #18 on: March 20, 2015, 04:05:16 AM »
Any news from the front, Aurel? :)

Aurel

  • Guest
Re: GDI functions & Init problems?
« Reply #19 on: March 20, 2015, 05:16:32 AM »
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.. ;)

Aurel

  • Guest
Re: GDI functions & Init problems?
« Reply #20 on: March 20, 2015, 05:21:08 AM »
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:
Code: [Select]
/*
 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

.

Mike Lobanovsky

  • Guest
Re: GDI functions & Init problems?
« Reply #21 on: March 20, 2015, 06:55:41 AM »
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.. ;)

Thanks for the feedback, Aurel.

If you have implemented all the mods that I suggested, then simply PM me the resultant zip with all the Ruben sources. It is too early to test or criticize anything in it yet. It is only the beginning of the overhaul.

Mike Lobanovsky

  • Guest
Re: GDI functions & Init problems?
« Reply #22 on: March 20, 2015, 07:10:09 AM »
I can't judge the entire EBasic program because I have no personal experience with this dialect but the plotting subroutine's GDI code seems to be perfectly correct. It does create, select and delete its temporary GDI objects properly, and all the defaults are saved and restored correctly before the respective DCs are released and deleted. Unlike your Ruben, it follows the classic strategy of drawing into the memory DC and then blitting the image to the screen window DC. This is exactly what I suggest your Ruben should do too.

Aurel

  • Guest
Re: GDI functions & Init problems?
« Reply #23 on: March 20, 2015, 07:36:02 AM »
Thanks Mike for reply and for trying EB program..
when i started GDI graphic i was looking into this program...
but something go wrong in my translation to oxygen (or some bugs in o2)  ::)
FIRST
i will try translate this program to oxygen again and then i will see if work properly .
Big problem i have in ruben is that i want to draw anywhere in program
not only under wm_paint.
Currently i can do that but with 44 GDI objects without increasing, as i say i tested
that in many programs i made ..
This program for example use in start 33 objects but when i resize window then
number of GDI ojects go up to 39.

ok
i don't want bothering you with my 'experience'  so i will post code of ruben4.

.
« Last Edit: March 20, 2015, 01:05:01 PM by Aurel »

Mike Lobanovsky

  • Guest
Re: GDI functions & Init problems?
« Reply #24 on: March 20, 2015, 08:10:54 AM »
Big problem i have in ruben is that i want to draw anywhere in program not only under wm_paint.

But all drawing becomes visible on your screen window only as an effect of the WM_PAINT message, Aurel. That's how Windows GDI works.

It looks as if you don't read my explanations attentively enough. I have already mentioned that drawing "anywhere in program" can be done only if you draw directly into the memory DC and then flush it (i.e. bit-blit it) to the screen in one go, first, when all your commands to draw into the memory DC have been issued anywhere in your program, and second, automatically in response to the WM_PAINT message whenever a part of the window needs repainting when i) dragged from beyond the screen borders, or ii) when uncovered by dragging another window that's on top of it, or iii) when resized.

Quote
This program for example use in start 33 objects but when i resize window then
number of GDI ojects go up to 39.

That's normal. Not all GDI objects are created at once when the program starts. But the main idea is to keep that number stable once all persistent GDI objects have been created, and their exact number will depend on what platform the program actually runs. At the same time, all temporary GDI objects should be deleted cleanly when no longer needed.

Quote
i will post code of ruben4.

Thanks.


[EDIT]
Quote from: Myself
... PM me the resultant zip with all the Ruben sources ...

Please post RTL32.inc and awinh.inc here that your Ruben currently relies on.

[EDIT2]

... and BMPs too.
« Last Edit: March 20, 2015, 09:03:32 AM by Mike Lobanovsky »

Aurel

  • Guest
Re: GDI functions & Init problems?
« Reply #25 on: March 20, 2015, 01:02:58 PM »
ahh sorry i forget that, bitmaps ?
you can ignore bitmaps because are not important part of interpreter and i
in the beginning try to use main window (hidden) as sort of debuger window...

.

Aurel

  • Guest
Re: GDI functions & Init problems?
« Reply #26 on: March 20, 2015, 02:51:42 PM »
Hi Mike
you can try this simple program and tell me how work on your computer
small correction ...enable InitDrawing(win2) under subroutine
exec_WINDOW()

Code: [Select]
'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

Mike Lobanovsky

  • Guest
Re: GDI functions & Init problems?
« Reply #27 on: March 20, 2015, 08:04:05 PM »
Thanks Aurel,

I'll be back when Ruben4 begins to function as intended. Please give me some time.

Aurel

  • Guest
Re: GDI functions & Init problems?
« Reply #28 on: May 12, 2015, 03:29:06 PM »
Hi Mike
do you maybe check some strange things in my interpreter.
today i just try few drawing examples with new o2 dll...
maybe is not problem with dll but i get very big memory leaks over 220k
but number of GDI objects stay ok...

Mike Lobanovsky

  • Guest
Re: GDI functions & Init problems?
« Reply #29 on: May 12, 2015, 05:31:30 PM »
... maybe is not problem with dll but i get very big memory leaks over 220k ...

Hi Aurel,

If one and the same source code of Ruben doesn't leak memory with some older DLL but does leak it with the new one and you can show it, then probably it isn't a question to me but rather to Charles? :)

Moreover, I don't have Ruben's original sources so I can't run reliable checks. The raw Ruben4 isn't suitable for testing and I must confess that I haven't yet touched it to make it usable. I am sorry to keep you waiting for so long; the files are still on my desktop right before my eyes. :-[