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

0 Members and 1 Guest are viewing this topic.

Aurel

  • Guest
GDI functions & Init problems?
« on: March 08, 2015, 11:00:20 AM »
This question is probably ..for Mike or Peter
I suspect that i have something not properly intitialized in my ruben GDI function.
Looks like some sort of DC corruption ?
When i look into DLib GDI drawing all looks different and not work very well in DLib  ::)
any help ..suggestion
thanks in advance !

Code: [Select]
' /////// 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
« Last Edit: March 08, 2015, 01:40:35 PM by Aurel »

Mike Lobanovsky

  • Guest
Re: GDI functions & Intit problems?
« Reply #1 on: March 08, 2015, 11:51:50 AM »
Hi Aurel,

Frankly, I don't want to dive deep into Ruben's sources. That is why, before I give a few practical pieces of advice without looking into them, please answer a few simple questions:
  • 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?
  • 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?
  • How does your main window callback handle the WM_ERASEBKGND message, if at all?
Thank you.

Aurel

  • Guest
Re: GDI functions & Intit problems?
« Reply #2 on: March 08, 2015, 01:39:53 PM »
Hi Mike..

Quote
Frankly, I don't want to dive deep into Ruben's sources
.
that is ok ..

 
Quote
   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?

1.well i am not sure,but i think that is because i draw into backbuffer then BitBlit into
current window to create pesistent image .
New window have under WM_PAINT :

Code: [Select]
'>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Case win2

 
Select wMsg

Case WM_PAINT
If win2 <> 0
BitBlt(hDC, 0, 0, ww, hh, hdcMem, 0, 0, SRCCOPY)
End If

this is very simple and i think that you understand this far better than me.
So content of window is persistent even i resize window or move window around edges of screen.
Do you can agree with that  or i really do that completelly wrong ?

2. well this is a mystery point...
when i test my program last night everything work fine and when i try today same
programs start to work strange ..without drawings or ...
then after some try-s ,programs work again properly ...this is really weird.
Mike..the number of GDI objets in Task are still the same 48..no mather what kind of drawing i do
what is ok ..i think and this is really confusing...
maybe is something wrong with oxygen..i don't know
In fact when i remove Space() function interpretr start towork properly
i hope ... ::)
 
3.WM_ERASEBKGND message is not currently part of new window procedure..

Aurel

  • Guest
Re: GDI functions & Init problems?
« Reply #3 on: March 08, 2015, 01:54:32 PM »
Mike
my drawing with mouse move is based on FBSL example


.

Aurel

  • Guest
Re: GDI functions & Init problems?
« Reply #4 on: March 08, 2015, 02:33:13 PM »
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)
'===================================================

Mike Lobanovsky

  • Guest
Re: GDI functions & Init problems?
« Reply #5 on: March 08, 2015, 02:57:37 PM »
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)
'===================================================

1. Yes but in any other language you will need one more temp var to store the value of GetDC(). This code is applicable in its verbatim form in the FBSL environment only!

2. Peter's code is better than yours but it isn't perfect either. For example, you don't need to select the new brush into the hDC in your FillSolidRect() sub. FillRect() works with any given brush directly, i.e. without selecting it into the context. But he's correct in pointing out to you that you must delete the new brush before the sub exits.

3. I'm currently writing a lengthy message to you. Let me take my time, please, before you make any hasty decisions.

Aurel

  • Guest
Re: GDI functions & Init problems?
« Reply #6 on: March 08, 2015, 03:06:38 PM »
Quote
3. I'm currently writing a lengthy message to you. Let me take my time, please, before you make any hasty decisions.

thanks Mike
I will wait of course because i am not sure what might be best possible option


Ps..thanks Peter  ;)

Mike Lobanovsky

  • Guest
Re: GDI functions & Init problems?
« Reply #7 on: March 08, 2015, 04:35:18 PM »
OK Aurel,

Thanks for responding. I will give you my suggestions but you're free to follow them or not, even if for the obvious reasons of language authorship. :)

1.
my drawing with mouse move is based on FBSL example
You 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. :)

2.
Quote
the number of GDI objets in Task are still the same 48..no mather what kind of drawing i do

I'm afraid this isn't so. Your FillSolidRect() creates a temporary (local) GDI object hBr and uses it to fill the rect but never deletes it when no longer needed. You must add DeleteObject(hBr) otherwise calling FillSolidRect() (or WindowColor() that uses it) in a loop will show you that your app is leaking one GDI object per each iteration.

3.
Quote
WM_ERASEBKGND message is not currently part of new window procedure.

If WindowColor() is the only  means to change the background color of your graphics window then you wouldn't want Windows to erase it with the graphics window's default color every time your app responds to a WM_PAINT message (every WM_PAINT is always preceded by WM_ERASEBKGND unless the latter is suppressed in your callback). Unsuppressed WM_ERASEBKGND followed by WindowColor() will cause your window to flicker like hell whenever it is resized or dragged from outside the screen bounds back onto your desktop. Add the following code to your callback to suppress WM_ERASEBKGND:

Code: OxygenBasic
  1. ...
  2.     Case WM_ERASEBKGND
  3.         Return 1
  4. ...

4. If your ww and wh parameters are the actual width and height of your graphics window's client area (I don't know what your GetSize() really does), then in order to make you graphics window respond to resizing events, add the following code to your callback:

Code: OxygenBasic
  1. ...
  2.     Case WM_SIZE
  3.         ww = lParam And &HFFFF ' equivalent to LoWord(lParam)
  4.        wh = lParam >> 16 ' equivalent to HiWord(lParam)
  5. ...

5. If your ww and wh parameters are the width and height of your graphics window's non-client area (effectively its outer sizes), then tell me so and I'll show you how to create a window from the very baginning based on the desired size of its client area rather than its outer dimensions.

6. You should create your memory DC's compatible bitmap to the exact size that your app needs rather than ww+1000 and wh+1000 because:
  • every platform and piece of hardware has a limit to the size of bitmaps that it can support; and
  • speed of BitBlt(), even if hardware assisted, is dependent roughly on the square of the bitmap's side; the smaller the bitmap, the faster the BitBlt() execution speed. The size of compatible bitmap should match exactly the size of graphics window drawing area it is blitted to; everything extra is a waste of system resources.

7. You tactics of blit-copying every single drawing operation into the memory DC is very very wasteful, both speed- and resource-wise. You will be much better off if you draw directly into the memory DC instead and have a new command called, say Refresh(hdc As Sys) (or Redraw like Peter's code has) that will be supposed to do only one thing, which will be to blit the contents of memory DC into the hDC of your graphics window:

Code: OxygenBasic
  1. Sub Refresh(hdc As Sys)
  2.     BitBlt(hdc, 0, 0, ww, wh, hDCmem, 0, 0, SRCCOPY)
  3. End Sub

Think for yourself: all you wanna do is set just one pixel on the entire canvas but at the same time you accompany that very simple and relatively fast task with an entire canvas blitting operation, and especially when your canvas is (ww*wh-1)+1000000 pixels larger than what's really needed! Now imagine what happens if you plan to draw a small row of a hundred pixels in a loop! :o I'm curious how Ruben can still draw anything at all! :)

8.
Quote
Code: OxygenBasic
  1. Case WM_PAINT
  2. If win2 <> 0
  3. BitBlt(hDC, 0, 0, ww, hh, hdcMem, 0, 0, SRCCOPY)
  4. End If

This is an absolutely unacceptable solution. The problem is that WM_PAINT uses its own, very special hDC value that does not generally coincide with the value returned by GetDC() in this particular message handler. You must use in this handler the value returned by a call to BeginPaint() and you must end this handler with a call to EndPaint(): Return 0 as prescribed by the Win32 Programmer's Reference: (watch out for line wrap!)

Code: OxygenBasic
  1. ...
  2.     Case WM_PAINT
  3.         Scope
  4.             Dim ps[64] As Byte ' this is a fake PAINTSTRUCT; we aren't going to use its members so no need to define it as genuine UDT
  5.            Refresh(BeginPaint(hwnd, ps)) ' hwnd is callback's argument, BeginPaint() returns hDC required to call Refresh()
  6.            EndPaint(hwnd, ps) ' ditto
  7.        End Scope
  8.         Return 0 ' as per Win32 SDK specs
  9. ...


Epilogue

We can discuss memory canvas resizing in WM_SIZE in further detail similar to what you found in the FBSL samples when and if you have implemented my suggestions. And my final advice would be that you and your users not attempt to draw anything at random places within your/their code (I remember you having been obsessed with this unreasonable idea some years ago) but rather have some well defined procedure (sub) where all drawing operations would be gathered together in order to be able to efficiently repaint the entire picture, if needed, and then blit it all from memory and into the on-screen graphics window in one go with a call to Refresh() as described above. This tactics would be very very handy to quickly restore the picture in case the window needs to be resized or restored from mini-/maximization.

Aurel

  • Guest
Re: GDI functions & Init problems?
« Reply #8 on: March 09, 2015, 12:38:58 PM »
Well what to say ...
Some of your suggestions are really very good but some of them i already tested and
not get good results...
this is funny...
Quote
:o I'm curious how Ruben can still draw anything at all! :)
heh .. i agree with you about that .
WM_ERASEBGND is not a option because create mess on window area...
Your point that i must delete brush is true and i forget do that .
Oh..obssesion or not ..i would like to create window like i can in Creative Basic
but there is created with DIB (as far as i can see from source code )..
well ..thanks again on reply ;)
by the way MMove ruben example work very fine but you must try if is not problem...
in addition ..i will try to replicate double buffering in FBSL just to check how work
 :)

Mike Lobanovsky

  • Guest
Re: GDI functions & Init problems?
« Reply #9 on: March 09, 2015, 02:11:02 PM »
Tell you what, Aurel,

...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...

My suggestions as they have been formulated at this very stage of our conversation are not to be tested or even discussed -- they are to be implemented exactly and unimpeachably, because they are an indispensable prerequisite to convert the Ruben mess into some form of graphics application that can work at least theoretically. The first thing to do is to set up and follow a strategic plan what the application should do and what it shouldn't. Currently, Ruben doesn't have or follow any reasonable strategy and never will if you continue to base its development on your own misconceptions about what graphics programming is, how it works, and what it does to keep the application stable, integral, and usable beyond psetting a coupla pixels on a shaky canvas.

The batch of suggestions I spitted out at four o'clock in the morning when you were already sound asleep were just the first steps to drag you back out of the swamp and onto some solid ground. The longer you stick with you current Ruben mess, the fewer chances you have to ever see any satisfaction from your fruitless "work" over all these years.

So, it is as follows: you either reshuffle your Ruben together with me in order to get stable, reliable and possibly fast graphics or just delete that brush in your FillSolidRect() and go on trolling BASIC sites in your usual vein instead of doing something useful. But then also forget about ever asking me any questions any more.

This message isn't meant to insult you or whatever. It is meant to set forth some principles on which I might do for you something that noone has ever done before over these countless years that you're haunting BASIC sites: I might help you to develop some working code of your own. This is because I think that once you have it in your hands, you'll become better towards people, and people will become milder towards you. The feeling of accomplishment is a great thing to conceive, after all. :)

Aurel

  • Guest
Re: GDI functions & Init problems?
« Reply #10 on: March 10, 2015, 03:58:35 AM »
Ok
But you must understand that my english is not good as yours
so maybe i don't understand whole things properly..sorry about that

ok
i try Peter version of function
Code: [Select]
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

And then i compile and try
Of course i look into taskbar what i going on with GDI objects
nothing is changed...number of GDI objects is still 50 without increasing
and is stable.

Mike
You suggest me to draw directly into new window hdc..right?
And i can do that of course,but how then i can get persistent imege
if i dont use double buffering ?
I am completlly confused...?
sorry if i bothering you with all that things   

Mike Lobanovsky

  • Guest
Re: GDI functions & Init problems?
« Reply #11 on: March 10, 2015, 07:02:12 AM »
Guys,

Peter's version of the function is redundant. You don't have to select the hBr object into any device context if you want to use it only for fillind a rectangle. FillRect() uses any brush directly and it doesnt care if this brush is selected into a DC or not; the result will be the same. So why bother selecting it there, saving the old brush, and finally deselecting it again if FillRect() does not require it to be done? This needs three unnecessary extra API calls in just one drawing operation!

Peter's amendments should have looked as follows:
Code: OxygenBasic
  1. ' set window color
  2. Sub FillSolidRect(wID as INT, x As Long, Y As Long, cx As Long, cy As Long, bbColor as INT)
  3.     Dim hBr As Long ' rc As RECT
  4.    hDC=GetDC(wID)
  5.     rc.Left = x
  6.     rc.Top = Y
  7.     rc.right = x + cx
  8.     rc.bottom = Y + cy
  9.     hBr = CreateSolidBrush(bbColor)
  10.     FillRect hDC, rc, hBr
  11.     '=======================================================
  12.    DeleteObject hBr ' you can (and must) delete it directly
  13.                     ' because it isn't selected into any DC at all
  14.    '=======================================================
  15.  
  16.     BitBlt(hDCmem, 0, 0, ww, hh, hdc, 0, 0, SRCCOPY)
  17.  
  18.     ReleaseDC( wID, hdc)
  19. End Sub

Quote
nothing is changed...number of GDI objects is still 50 without increasing and is stable.

No! Everything is changed!

(Whenever I'm talking about a window, I mean the graphics window, its hWnd, its hDC, its callback and events, etc. I do not care if there are any other windows in your application.)

Write a short .RUB script that does the following (sorry, I don't know Ruben syntax but you must have something similar to express the loop):
Code: OxygenBasic
  1. .... ' your usual window initialization stuff goes here
  2. FOR i = 1 TO 10000000
  3.     FillSolidRect hWnd, 0, 0, 100, 100, 255 ' hWnd belongs to your graphics window, 255 is pure bright red
  4. NEXT i
  5. ....
and run it with your old implementation of FillSolidRect(). You will see that the number of GDI objects in your Task Manager increases with every passing second till your system may actually freeze or the application may crash. This is because there will be exactly one GDI object -- the hBr brush -- created in each iteration of this loop but never deleted in the same iteration, thus being lost both to you and the system eating its resources.

Now do the same with the new implementation of FillSolidRect() corrected as above and you will see that the number of GDI objects shown in your Task Manager remains the same (actually it may deviate +/- 1 GDI object while the loop runs depending on when the Task Manager actually takes its measurement) when the loop ends after 10 million iterations. This is how all of your function implementations, both old and new, should always be tested before they go public, here or elsewhere.

Quote
You suggest me to draw directly into new window hdc..right?

No again! I suggest you always:
  • draw only into the memory DC (hDCmem is what you call it in your own code) whose handle, and bitmap, and foreground/background colors, and font, and pen, and brush you create only once in the WM_CREATE handler of your graphics window callback and keep them for ready access until your app quits or your graphics window is resized;
  • put Refresh() that I suggested earlier into the WM_PAINT handler exactly as I suggested;
  • add WM_ERASEBKGND handler as I suggested;
  • add your WindowColor() (I would actually call this function Cls() BTW) to the WM_SIZE handler right after the two lines with the ww and wh parameters that I suggested earlier (this will serve instead of the suppressed WM_ERASEBKGND message), then add a call to Draw() (see its description further below);
  • delete all your unnecessary
    hDC=GetDC(wID)
    ....
    BitBlt(hDCmem, 0, 0, ww, hh, hdc, 0, 0, SRCCOPY)
    ....
    ReleaseDC( wID, hdc)

    from all your drawing functions.

Then add one more command to your vocabulary:
Code: OxygenBasic
  1. Sub Draw()
  2.     Sys hDC = GetDC(hWnd) ' the graphics window, naturally
  3.    Refresh hDC ' Refresh blits from the memory DC into the graphics window's on-screen DC
  4.    ReleaseDC hWnd, hDC
  5. End Sub
which is an analog to Refresh() for drawing anywhere outside the WM_PAINT handler, for example, in the WM_MOUSEMOVE handler as in the FBSL example that draws those colored bubbles, or in the WM_SIZE handler as described in item 4 above.

Now whenever and wherever you want to draw something on your screen, you just write e.g. the following: (pseudocode!)

For i = 1 To 1000000
PSet ...
Circle ...
DrawRect ...
FillSolidRect ...
Next i
Draw


and you spare yourself 3999999 GetDCs, 3999999 ReleaseDCs, and 3999999 BitBlts in just one single action in your graphics program.
« Last Edit: March 10, 2015, 07:27:40 AM by Mike Lobanovsky »

Aurel

  • Guest
Re: GDI functions & Init problems?
« Reply #12 on: March 10, 2015, 01:49:02 PM »
ok Mike
I modify FillSolidRect() function as you suggest :
Code: [Select]
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

Then i compile and try with 100000 iterations
(10 000 000 is to much for ruben )
number of GDI objects in taskbar is now 46 and is constant
in attacmnet is testing program..

Your idea that i should put all drawings into WM_PAINT is good ..
for now i have just 3 event handler implemented
@mousemove
@leftmbdown
@onclick

so next will be @onpaint


.

Mike Lobanovsky

  • Guest
Re: GDI functions & Init problems?
« Reply #13 on: March 10, 2015, 02:49:29 PM »
Hi Aurel,

Thanks for keeping me informed. I won't however download this file because I am not interested in working with Ruben's sources the way they are now; I consider this a waste of time, yours and mine alike.

My proposition still holds as follows:

1. You're stopping any of your planned activities to develop the older version of Ruben.

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.

4. You're notifying me when you're through with this work and ready to send me these new sources in their entirety for final verification.

5. I'm looking through all the sources to verify them, add code as necessary to finalize clean resize of the graphics window with respect to its backbuffer, and send the finalized sources back to you.

6. You're field testing these finalized sources notifying me of any unexpected behavior, potential memory and GDI leaks, and other possible bugs.

7. Field testing over, you resume your development work as previously planned, but this time based on this new, dramatically faster and cleaner implementation of Ruben's GDI drawing engine. My mission ends there and then.

Please let me know a.s.a.p. if and when you're ready to follow this schedule.

Thank you.

Aurel

  • Guest
Re: GDI functions & Init problems?
« Reply #14 on: March 10, 2015, 10:56:57 PM »
Quote
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.

ok..i i will backup current version - ruben3
and then i will made all changes you say in new ruben4
then i will post code .