HMG Graph based on Bos Taurus

HMG Samples and Enhancements

Moderator: Rathinagiri

User avatar
mol
Posts: 3720
Joined: Thu Sep 11, 2008 5:31 am
Location: Myszków, Poland
Contact:

Re: HMG Graph based on Bas Taurus

Post by mol »

srvet_claudio wrote:
Rathinagiri wrote:In that case, how can we assign the bitmap handle to an Image control of a form?
With:

BT_HMGSetImage (cFormName, cControlName, hBitmap, lReleasePrevious)

Sets a specified bitmap into an Image Control of HMG (@...IMAGE) and automatically releases the handle of the bitmap previously associated to the Image Control.

cFormName: is the name (e.g. "Win1") of the parent window.

cControlName: is the name (e.g. "Image1") of the image control.

hBitmap: is a handle to the bitmap to set.

lReleasePrevious: releases of the hBitmap previous associate to Image Control. For default is .T.

Can somebody test this solution? In my project it does not work. What's going on?


My code is:

Code: Select all

if lSaveToFile
		BT_BitmapSaveFile(hBitmap, cImageFileName )
		BT_DeleteDC( BTstruct )
		BT_BitmapRelease( hBitmap )
	else
		BT_HMGSetImage (cFormName, cControlName, hBitmap, .T.)	
	endif
User avatar
srvet_claudio
Posts: 2193
Joined: Thu Feb 25, 2010 8:43 pm
Location: Uruguay
Contact:

Re: HMG Graph based on Bas Taurus

Post by srvet_claudio »

Hi Marek,

1) open or create a bitmap

Code: Select all

   hBitmap := BT_BitmapLoadFile ("hmg.bmp")
or
   hBitmap := BT_BitmapCreateNew (300, 200, aRGBcolor)
2) open a Device Context (DC) for read/write into bitmap and immediately close DC

Code: Select all

   hDC := BT_CreateDC (hBitmap, BT_HDC_BITMAP, @BTstruct)     
     
     BT_DrawGradientFillVertical (hDC,  50,  50,  200,  100, aRGBcolor, BLACK)                 
     
     nTypeText    := BT_TEXT_OPAQUE + BT_TEXT_BOLD    
     nAlingText   := BT_TEXT_LEFT + BT_TEXT_TOP
     nOrientation := BT_TEXT_NORMAL_ORIENTATION
     BT_DrawText (hDC, 90, 80, " The Power of HMG ", "Times New Roman", 12, BLACK, WHITE, nTypeText, nAlingText, nOrientation)
     
  BT_DeleteDC (BTstruct)   
3) save to disk or assign to a image control

Code: Select all

   if lSaveToFile
      BT_BitmapSaveFile(hBitmap, cImageFileName )
      BT_BitmapRelease( hBitmap )
   else
      BT_HMGSetImage (cFormName, cControlName, hBitmap, .T.)   
   endif
Best regards.
Dr. Claudio Soto
(from Uruguay)
http://srvet.blogspot.com
User avatar
mol
Posts: 3720
Joined: Thu Sep 11, 2008 5:31 am
Location: Myszków, Poland
Contact:

Re: HMG Graph based on Bas Taurus

Post by mol »

Thanks!
I didn't use BT_DeleteDC (BTstruct) before BT_HMGSetImage (cFormName, cControlName, hBitmap, .T.)

I couldn't find this omission...
Now, it's working fine!
User avatar
serge_girard
Posts: 3165
Joined: Sun Nov 25, 2012 2:44 pm
DBs Used: 1 MySQL - MariaDB
2 DBF
Location: Belgium
Contact:

Re: HMG Graph based on Bas Taurus

Post by serge_girard »

Claudio or Rathi,

I made a simple BAR graph and found 2 minor problems:

- using a value range of -200 to 200 the division of the values is not correct and the highest negative bars fall out of the picture.
- the leftmost SERIEYNAMES is positioned at the right; last occurence of SERIEYNAMES is correct.


Greetings,

Serge

Code: Select all

aSer	      := ARRAY(1, 12 )	 
aVal			:= ARRAY(12)		    
aSERIE	   := ARRAY(1)
aCOL			:= ARRAY(1)						 

aCOL [1]		:= BLUE
aSERIE [1]  := 'a bit long seriename'

aSer	[1,  1] :=   -5 
aSer	[1,  2] :=   -20
aSer	[1,  3] :=   -50
aSer	[1,  4] :=   -200
aSer	[1,  5] :=   -210
aSer	[1,  6] :=   -175
aSer	[1,  7] :=   -150
aSer	[1,  8] :=    100
aSer	[1,  9] :=   -188
aSer	[1, 10] :=   55
aSer	[1, 11] :=   -170
aSer	[1, 12] :=   5


aVal	[1] :=   'Jan'
aVal	[2] :=   'Feb'
aVal	[3] :=   'Mrt'
aVal	[4] :=   'Apr'
aVal	[5] :=   'May'
aVal	[6] :=   'Jun'
aVal	[7] :=   'Jul'
aVal	[8] :=   'Aug'
aVal	[9] :=   'Sep'
aVal	[10] :=   'Oct'
aVal	[11] :=   'Nov'
aVal	[12] :=   'Dec'

GRAPH BITMAP   BARS ;          // Form_1.GraphType.VALUE ;  // constants: BARS = 1, LINES = 2, POINTS = 3 are defined in i_graph.ch 
   SIZE        1200, 900 ;
   SERIEVALUES aSer ;
   SERIENAMES  aSERIE ;
   SERIECOLORS aCOL ;
   SERIEYNAMES aVal ;
   PICTURE     "99,999.99" ;
   TITLE       'TITLE of a long seriename' ;
   TITLECOLOR  BLACK ;
   HVALUES     5 ;
   BARDEPTH    15 ; 
   BARWIDTH    15 ;
   SEPARATION  0 ;
   LEGENDWIDTH 150 ;
   3DVIEW      .T. ;
   SHOWGRID    .T. ;
   SHOWXGRID   .T. ;
   SHOWYGRID   .T. ;
   SHOWVALUES  .T. ;
   SHOWXVALUES .T. ;
   SHOWYVALUES .T. ;               
   SHOWLEGENDS .T. ; 
   NOBORDER    .F. ;
   STOREIN     hBitmap 


Form_DIAGRAM.Image_1.HBITMAP := hBitmap   // Assign hBitmap to the IMAGE control

Attachments
hmg-bt.gif
hmg-bt.gif (109.23 KiB) Viewed 5473 times
There's nothing you can do that can't be done...
User avatar
Rathinagiri
Posts: 5471
Joined: Tue Jul 29, 2008 6:30 pm
DBs Used: MariaDB, SQLite, SQLCipher and MySQL
Location: Sivakasi, India
Contact:

Re: HMG Graph based on Bas Taurus

Post by Rathinagiri »

I will see to it Serge.
East or West HMG is the Best.
South or North HMG is worth.
...the possibilities are endless.
User avatar
serge_girard
Posts: 3165
Joined: Sun Nov 25, 2012 2:44 pm
DBs Used: 1 MySQL - MariaDB
2 DBF
Location: Belgium
Contact:

Re: HMG Graph based on Bas Taurus

Post by serge_girard »

Thanks you so much Rathi !
There's nothing you can do that can't be done...
User avatar
mol
Posts: 3720
Joined: Thu Sep 11, 2008 5:31 am
Location: Myszków, Poland
Contact:

Re: HMG Graph based on Bas Taurus

Post by mol »

Rathinagiri wrote:Andy, I have modified the code to place the Values on the bar. But I don't know whether this will look good for all the other values/series.

Code: Select all

#include <hmg.ch>

Function Main


   define window graph at 0, 0 width 1000 height 700 main 
      define label selecttype
         row 10
         col 10
         width 150
         value 'Select Graph Type'
      end label
      define combobox graphtype
         row 10
         col 160
         width 100
         items { 'Bar', 'Lines', 'Points', 'Pie' }
         onchange drawgraph()
      end combobox   
      define checkbox enable3d
         row 10
         col 280
         width 100
         caption 'Enable 3D'
         onchange drawgraph()
      end checkbox   
      define image grapharea
         row 50
         col 50
         width 600
         height 600
      end image
   end window
   graph.graphtype.value := 1
   graph.center
   graph.activate
Return


function drawgraph
   local cImage := 'graph.bmp'
   local nImageWidth := 600
   local nImageHeight := 600
   local cTitle := 'Sample Graph'
   local aYValues := {"Jan","Feb","Mar","Apr","May"}
   local aData := { {14280,20420,12870,25347, 7640},;
           { 8350,10315,15870, 5347,12340},;
           {12345, -8945,10560,15600,17610} }
   local nBarDepth := 15
   local nBarWidth := 15   
   local nHValues := 5
   local l3D := graph.enable3D.value
   local lGrid := .t.
   local lXGrid := .t.
   local lYGrid := .t.
   local lXVal := .t.
   local lYVal := .t.
   local nGraphType := graph.graphtype.value
   local lViewVal := .t.
   local lLegends := .t.
   local cPicture := '99,999.99'
   local aSeries := {"Serie 1","Serie 2","Serie 3"}
   local aColors := { {128,128,255}, {255,102, 10}, {55,201, 48} }
   local lNoBorder := .f.
   local nLegendWidth := 50
   if graph.graphtype.value == 0
      return nil
   endif
   if graph.graphtype.value == 4 // pie
      drawpiegraphinBitMap( cImage, nImageWidth, nImageHeight, {1500,1800,200,500,800}, {"Product 1","Product 2","Product 3","Product 4","Product 5"}, {{255,0,0},{0,0,255},{255,255,0},{0,255,0},{255,128,64},{128,0,128}}, "Sales", 25, l3D, lxval, lLegends, lnoborder )   
   else      
      graphsave( cImage, nImageWidth, nImageHeight, aData,  cTitle, aYValues, nBarDepth, nBarWidth, nil, nHValues, l3d, lGrid, lXGrid, lYGrid, ;
               lXVal, lYVal, lLegends, aSeries, aColors, nGraphType, lViewVal, cPicture, nLegendWidth ,lNoBorder ) 
   endif               
   graph.grapharea.picture := 'graph.bmp'
   return nil
   
function graphsave( cImageFileName, nWidth, nHeight, aData, cTitle, aYVals, nBarD, nWideB, nSep, nXRanges, ;
	              l3D, lGrid, lxGrid, lyGrid, lxVal, lyVal, lLegends, aSeries, aColors, nType, lViewVal, cPicture , nLegendWindth , lNoborder )
                 
   LOCAL nI, nJ, nPos, nMax, nMin, nMaxBar, nDeep
   LOCAL nRange, nResH, nResV,  nWide, aPoint, cName
   LOCAL nXMax, nXMin, nHigh, nRel, nZero, nRPos, nRNeg
   local hBitMap, hDC, BTStruct
   local nTop := 0
   local nLeft := 0
   local nBottom := nHeight
   local nRight := nWidth

	DEFAULT cTitle   := ""
	DEFAULT nSep     := 0
	DEFAULT cPicture := "999,999.99"
	DEFAULT nLegendWindth := 50
   private nPenWidth := 1

	If ( HMG_LEN (aSeries) != HMG_LEN ( aData ) ) .or. ;
		( HMG_LEN ( aSeries ) != HMG_LEN ( aColors ) ) 
		MsgHMGError("DRAW GRAPH: 'Series' / 'SerieNames' / 'Colors' arrays size mismatch. Program terminated", "HMG Error" )
	EndIf

   hBitMap := BT_BitmapCreateNew ( nWidth, nHeight, { 255, 255, 255 } )
   hDC := BT_CreateDC( hBitMap, BT_HDC_BITMAP, @BTStruct )

   IF lGrid
      lxGrid := lyGrid := .T.
   ENDIF
   
   IF nBottom <> NIL .AND. nRight <> NIL
      nHeight := nBottom - nTop / 2
      nWidth  := nRight - nLeft / 2
      nBottom -= IF( lyVal, 42, 32)
      nRight  -= IF( lLegends, 32 + nLegendWindth , 32 )
   ENDIF
   nTop    += 1 + IF( Empty( cTitle ), 30, 44 )             // Top gap
   nLeft   += 1 + IF( lxVal, 80 + nBarD, 30 + nBarD )     // LEFT
   DEFAULT nBottom := nHeight - 2 - IF( lyVal, 40, 30 )    // Bottom
   DEFAULT nRight  := nWidth - 2 - IF( lLegends, 30 + nLegendWindth , 30 ) // RIGHT

   l3D     := IF( nType == POINTS, .F., l3D )
   nDeep   := IF( l3D, nBarD, 1 )
   nMaxBar := nBottom - nTop - nDeep - 5
   nResH   := nResV := 1
   nWide   := ( nRight - nLeft )* nResH / ( nMax( aData ) + 1 ) * nResH

   // Graph area
   //
   IF ! lNoborder
	   DrawWindowBoxInBitMap( hDC, Max( 1, nTop - 44 ), Max( 1, nLeft - 80 - nBarD ), nHeight - 1, nWidth - 1 )
   ENDIF	

   // Back area
   //
   IF l3D
      drawrectinbitmap( hDC, nTop+1, nLeft, nBottom - nDeep, nRight, { 255, 255, 255 } )
   ELSE
      drawrectinbitmap( hDC, nTop-5, nLeft, nBottom, nRight, { 255, 255, 255 } )
   ENDIF

   IF l3D
      // Bottom area
      FOR nI := 1 TO nDeep+1
          DrawLineinbitmap( hDC, nBottom-nI, nLeft-nDeep+nI, nBottom-nI, nRight-nDeep+nI, { 255, 255, 255 } )
      NEXT nI

      // Lateral
      FOR nI := 1 TO nDeep
          DrawLineinbitmap( hDC, nTop+nI, nLeft-nI, nBottom-nDeep+nI, nLeft-nI, {192, 192, 192} )
      NEXT nI

      // Graph borders
      FOR nI := 1 TO nDeep+1
          DrawLineinbitmap( hDC, nBottom-nI     ,nLeft-nDeep+nI-1 ,nBottom-nI     ,nLeft-nDeep+nI  ,GRAY )
          DrawLineinbitmap( hDC, nBottom-nI     ,nRight-nDeep+nI-1,nBottom-nI     ,nRight-nDeep+nI ,BLACK )
          DrawLineinbitmap( hDC, nTop+nDeep-nI+1,nLeft-nDeep+nI-1 ,nTop+nDeep-nI+1,nLeft-nDeep+nI  ,BLACK )
          DrawLineinbitmap( hDC, nTop+nDeep-nI+1,nLeft-nDeep+nI-3 ,nTop+nDeep-nI+1,nLeft-nDeep+nI-2,BLACK )
      NEXT nI

      FOR nI=1 TO nDeep+2
          DrawLineinbitmap( hDC, nTop+nDeep-nI+1,nLeft-nDeep+nI-3,nTop+nDeep-nI+1,nLeft-nDeep+nI-2 ,BLACK )
          DrawLineinbitmap( hDC, nBottom+ 2-nI+1,nRight-nDeep+nI ,nBottom+ 2-nI+1,nRight-nDeep+nI-2,BLACK )
      NEXT nI

      DrawLineinbitmap( hDC, nTop         ,nLeft        ,nTop           ,nRight       ,BLACK )
      DrawLineinbitmap( hDC, nTop- 2      ,nLeft        ,nTop- 2        ,nRight+ 2    ,BLACK )
      DrawLineinbitmap( hDC, nTop         ,nLeft        ,nBottom-nDeep  ,nLeft        ,GRAY  )
      DrawLineinbitmap( hDC, nTop+nDeep   ,nLeft-nDeep  ,nBottom        ,nLeft-nDeep  ,BLACK )
      DrawLineinbitmap( hDC, nTop+nDeep   ,nLeft-nDeep-2,nBottom+ 2     ,nLeft-nDeep-2,BLACK )
      DrawLineinbitmap( hDC, nTop         ,nRight       ,nBottom-nDeep  ,nRight       ,BLACK )
      DrawLineinbitmap( hDC, nTop- 2      ,nRight+ 2    ,nBottom-nDeep+2,nRight+ 2    ,BLACK )
      DrawLineinbitmap( hDC, nBottom-nDeep,nLeft        ,nBottom-nDeep  ,nRight       ,GRAY  )
      DrawLineinbitmap( hDC, nBottom      ,nLeft-nDeep  ,nBottom        ,nRight-nDeep ,BLACK )
      DrawLineinbitmap( hDC, nBottom+ 2   ,nLeft-nDeep-2,nBottom+ 2     ,nRight-nDeep ,BLACK )
   ENDIF


   // Graph info
   //

   IF !Empty(cTitle)
      DrawTextInBitmap( hDC, nTop - 30 * nResV, nLeft, cTitle, 'Arial', 12, RED, 2 )
   ENDIF


   // Legends
   //
   IF lLegends
      nPos := nTop
      FOR nI := 1 TO HMG_LEN( aSeries )
         DrawBarinbitmap( hDC, nRight+(8*nResH), nPos+(9*nResV), 8*nResH, 7*nResV, l3D, 1, aColors[nI] )
         DrawTextInBitmap( hDC, nPos, nRight+(20*nResH), aSeries[nI], 'Arial', 8, BLACK, 0 )
         nPos += 18*nResV
      NEXT nI
   ENDIF

   // Max, Min values
   nMax := 0
   FOR nJ := 1 TO HMG_LEN(aSeries)
      FOR nI :=1 TO HMG_LEN(aData[nJ])
         nMax := Max( aData[nJ][nI], nMax )
      NEXT nI
   NEXT nJ
   nMin := 0
   FOR nJ := 1 TO HMG_LEN(aSeries)
      FOR nI :=1 TO HMG_LEN(aData[nJ])
         nMin := Min( aData[nJ][nI], nMin )
      NEXT nI
   NEXT nJ

   nXMax := IF( nMax > 0, DetMaxVal( nMax ), 0 )
   nXMin := IF( nMin < 0, DetMaxVal( nMin ), 0 )
   nHigh := nXMax + nXMin
   nMax  := Max( nXMax, nXMin )
   
   nRel  := ( nMaxBar / nHigh )
   nMaxBar := nMax * nRel



   nZero := nTop + (nMax*nRel) + nDeep + 5    // Zero pos
   IF l3D
      FOR nI := 1 TO nDeep+1
          DrawLineinbitmap( hDC, nZero-nI+1, nLeft-nDeep+nI   , nZero-nI+1, nRight-nDeep+nI, {192, 192, 192} )
      NEXT nI
      FOR nI := 1 TO nDeep+1
          DrawLineinbitmap( hDC, nZero-nI+1, nLeft-nDeep+nI-1 , nZero-nI+1, nLeft -nDeep+nI, GRAY )
          DrawLineinbitmap( hDC, nZero-nI+1, nRight-nDeep+nI-1, nZero-nI+1, nRight-nDeep+nI, BLACK )
      NEXT nI
      DrawLineinbitmap( hDC, nZero-nDeep, nLeft, nZero-nDeep, nRight, GRAY )
   ENDIF

   aPoint := Array( HMG_LEN( aSeries ), HMG_LEN( aData[1] ), 2 )
   nRange := nMax / nXRanges

   // xLabels
   nRPos := nRNeg := nZero - nDeep
   FOR nI := 0 TO nXRanges
      IF lxVal
         IF nRange*nI <= nXMax
            DrawTextInBitmap( hDC, nRPos, nLeft-nDeep-70, Transform(nRange*nI, cPicture), 'Arial', 8, BLUE )
         ENDIF
         IF nRange*(-nI) >= nXMin*(-1)
            DrawTextInBitmap( hDC, nRNeg, nLeft-nDeep-70, Transform(nRange*-nI, cPicture), 'Arial', 8, BLUE )
         ENDIF
      ENDIF

      IF lxGrid
         IF nRange*nI <= nXMax
            IF l3D
               FOR nJ := 0 TO nDeep + 1
                  DrawLineinbitmap( hDC, nRPos + nJ, nLeft - nJ - 1, nRPos + nJ, nLeft - nJ, BLACK )
               NEXT nJ
            ENDIF
            DrawLineinbitmap( hDC, nRPos, nLeft, nRPos, nRight, BLACK )
         ENDIF
         IF nRange*-nI >= nXMin*-1
            IF l3D
               FOR nJ := 0 TO nDeep + 1
                  DrawLineinbitmap( hDC, nRNeg + nJ, nLeft - nJ - 1, nRNeg + nJ, nLeft - nJ, BLACK )
               NEXT nJ
            ENDIF
            DrawLineinbitmap( hDC, nRNeg, nLeft, nRNeg, nRight, BLACK )
         ENDIF
      ENDIF
      nRPos -= ( nMaxBar / nXRanges )
      nRNeg += ( nMaxBar / nXRanges )
   NEXT nI

   IF lYGrid
      nPos:=IF(l3D, nTop, nTop-5 )
      nI  := nLeft + nWide
      FOR nJ := 1 TO nMax(aData)
         DrawlineinBitmap( hDC, nBottom-nDeep, nI, nPos, nI, {100,100,100} )
         DrawlineinBitmap( hDC, nBottom, nI-nDeep, nBottom-nDeep, nI, {100,100,100} )
         nI += nWide
      NEXT
   ENDIF

   DO WHILE .T.    // Bar adjust
      nPos = nLeft + ( nWide / 2 )
      nPos += ( nWide + nSep ) * ( HMG_LEN(aSeries) + 1 ) * HMG_LEN(aData[1])
      IF nPos > nRight
         nWide--
      ELSE
         EXIT
      ENDIF
   ENDDO

   nMin := nMax / nMaxBar

   nPos := nLeft + ( ( nWide + nSep ) / 2 )            // first point graph
   nRange := ( ( nWide + nSep ) * HMG_LEN(aSeries) ) / 2

   IF lyVal .AND. HMG_LEN( aYVals ) > 0                // Show yLabels
      nWideB  := ( nRight - nLeft ) / ( nMax(aData) + 1 )
      nI := nLeft + nWideB
      FOR nJ := 1 TO nMax(aData)
         cName := "yVal_Name_"+LTRIM(STR(nJ))
         DrawTextInBitmap( hDC, nBottom + 8, nI - nDeep - IF(l3D, 0, 8), aYVals[nJ], 'Arial', 8, BLUE )
         nI += nWideB
      NEXT
   ENDIF



   // Bars
   //
	
	IF nType == BARS
		if nMin <> 0
			nPos := nLeft + ( ( nWide + nSep ) / 2 )
			FOR nI=1 TO HMG_LEN(aData[1])
				FOR nJ=1 TO HMG_LEN(aSeries)
					DrawBarinbitmap( hDC, nPos, nZero, aData[nJ,nI] / nMin + nDeep, nWide, l3D, nDeep, aColors[nJ] )
					nPos += nWide+nSep
				NEXT nJ
				nPos += nWide+nSep
			NEXT nI
		endif
	ENDIF

   // Lines
   //
   IF nType == LINES
      if nMin <> 0
         nWideB  := ( nRight - nLeft ) / ( nMax(aData) + 1 )
         nPos := nLeft + nWideB
         FOR nI := 1 TO HMG_LEN(aData[1])
            FOR nJ=1 TO HMG_LEN(aSeries)
               IF !l3D
                  DrawPointinBitmap( hDC, nType, nPos, nZero, aData[nJ,nI] / nMin + nDeep, aColors[nJ] )
               ENDIF
               aPoint[nJ,nI,2] := nPos
               aPoint[nJ,nI,1] := nZero - ( aData[nJ,nI] / nMin + nDeep )
            NEXT nJ
            nPos += nWideB
         NEXT nI

         FOR nI := 1 TO HMG_LEN(aData[1])-1
            FOR nJ := 1 TO HMG_LEN(aSeries)
               IF l3D
                  drawpolygoninbitmap(hDC,{{aPoint[nJ,nI,1],aPoint[nJ,nI,2]},{aPoint[nJ,nI+1,1],aPoint[nJ,nI+1,2]}, ;
                              {aPoint[nJ,nI+1,1]-nDeep,aPoint[nJ,nI+1,2]+nDeep},{aPoint[nJ,nI,1]-nDeep,aPoint[nJ,nI,2]+nDeep}, ;
                              {aPoint[nJ,nI,1],aPoint[nJ,nI,2]}},,,aColors[nJ])
               ELSE
                  DrawLineinbitmap( hDC, aPoint[ nJ, nI, 1 ], aPoint[ nJ, nI, 2 ], aPoint[ nJ, nI+1, 1 ], aPoint[ nJ, nI + 1, 2 ], aColors[ nJ ] )
               ENDIF
            NEXT nJ
         NEXT nI

      endif
   ENDIF

   // Points
   //
   IF nType == POINTS
		if nMin <> 0
         nWideB := ( nRight - nLeft ) / ( nMax(aData) + 1 )
         nPos := nLeft + nWideB
         FOR nI := 1 TO HMG_LEN(aData[1])
            FOR nJ=1 TO HMG_LEN(aSeries)
               DrawPointinBitmap( hDC, nType, nPos, nZero, aData[nJ,nI] / nMin + nDeep, aColors[nJ] )
               aPoint[nJ,nI,2] := nPos
               aPoint[nJ,nI,1] := nZero - aData[nJ,nI] / nMin
            NEXT nJ
            nPos += nWideB
         NEXT nI
      ENDIF
   endif   

   IF lViewVal
      IF nType == BARS
         nPos := nLeft + nWide + ( ( nWide+nSep ) * ( HMG_LEN(aSeries) / 2 ) )
      ELSE
         nWideB := ( nRight - nLeft ) / ( nMax(aData) + 1 )
         nPos := nLeft + nWideB
      ENDIF
      FOR nI := 1 TO HMG_LEN( aData[ 1 ] )
         FOR nJ := 1 TO HMG_LEN( aSeries )
            DrawTextInBitmap( hDC, nZero - ( aData[nJ,nI] / nMin + nDeep + 18 ), IF(nType == BARS, nPos - IF(l3D, 44, 46), nPos + 10), Transform( aData[ nJ, nI ], cPicture ), 'Arial', 8 )
            nPos+= IF( nType == BARS, nWide + nSep, 0 )
         NEXT nJ
         IF nType == BARS
            nPos += nWide + nSep
         ELSE
            nPos += nWideB
         ENDIF
      NEXT nI
   ENDIF

   IF l3D
      DrawLineinbitmap( hDC, nZero, nLeft-nDeep, nZero, nRight-nDeep, BLACK )
   ELSE
      IF nXMax<>0 .AND. nXMin<>0
         DrawLineinbitmap( hDC, nZero-1, nLeft-2, nZero-1, nRight, RED )
      ENDIF

   endif

   BT_BitmapSaveFile(hBitmap, cImageFileName )
   BT_DeleteDC( BTstruct )
   BT_BitmapRelease( hBitmap )

RETURN



function DrawWindowBoxInBitMap( hDC, row, col, rowr, colr )
   BT_DrawRectangle ( hDC, Row, Col, Colr - col, rowr - row, { 0, 0, 0 }, nPenWidth )
return nil
		

   

function drawrectinbitmap( hDC, row, col, row1, col1, aColor )

   BT_DrawFillRectangle (hDC, Row, Col, col1 - col, row1 - row, aColor, aColor, nPenWidth )
return nil   

function DrawLineinbitmap( hDC, Row1, Col1, Row2, Col2, aColor )
   BT_DrawLine ( hDC, Row1, Col1, Row2, Col2, aColor, nPenWidth )
return nil   

function DrawTextInBitmap( hDC, Row, Col, cText, cFontName, nFontSize, aColor, nAlign )
   default nAlign := 0
   do case
   case nAlign == 0
      BT_DrawText ( hDC, Row, Col, cText, cFontName, nFontSize, aColor, )
   case nAlign == 1
      BT_DrawText ( hDC, Row, Col, cText, cFontName, nFontSize, aColor, , BT_TEXT_RIGHT )
   case nAlign == 2
      BT_DrawText ( hDC, Row, Col, cText, cFontName, nFontSize, aColor, , BT_TEXT_CENTER )
   endcase   
return nil   

function DrawBarinbitmap( hDC, nY, nX, nHigh, nWidth, l3D, nDeep, aColor )
   LOCAL nI, nColTop, nShadow, nH := nHigh

   nColTop := ClrShadow( RGB(aColor[1],aColor[2],aColor[3]), 15 )
   nShadow := ClrShadow( nColTop, 15 )
   nColTop := {GetRed(nColTop),GetGreen(nColTop),GetBlue(nColTop)}
   nShadow := {GetRed(nShadow),GetGreen(nShadow),GetBlue(nShadow)}

   FOR nI=1 TO nWidth
      DrawLineinbitmap( hDC, nX, nY+nI, nX+nDeep-nHigh, nY+nI, aColor )  // front
   NEXT nI

   IF l3D
      // Lateral
      drawpolygoninBitmap( hDC,{{nX-1,nY+nWidth+1},{nX+nDeep-nHigh,nY+nWidth+1},;
                   {nX-nHigh+1,nY+nWidth+nDeep},{nX-nDeep,nY+nWidth+nDeep},;
                   {nX-1,nY+nWidth+1}},nShadow,,nShadow )
      // Superior
      nHigh   := Max( nHigh, nDeep )
      drawpolygoninBitmap( hDC,{{nX-nHigh+nDeep,nY+1},{nX-nHigh+nDeep,nY+nWidth+1},;
                   {nX-nHigh+1,nY+nWidth+nDeep},{nX-nHigh+1,nY+nDeep},;
                   {nX-nHigh+nDeep,nY+1}},nColTop,,nColTop )
      // Border
      DrawBoxinBitmap( hDC, nY, nX, nH, nWidth, l3D, nDeep )
   ENDIF

RETURN

STATIC FUNCTION ClrShadow( nColor, nFactor )
   LOCAL aHSL, aRGB

   aHSL := RGB2HSL( GetRed(nColor), GetGreen(nColor), GetBlue(nColor) )
   aHSL[3] -= nFactor
   aRGB := HSL2RGB( aHSL[1], aHSL[2], aHSL[3] )

RETURN RGB( aRGB[1], aRGB[2], aRGB[3] )


STATIC FUNCTION nMax(aData)
   LOCAL nI, nMax := 0

   FOR nI :=1 TO HMG_LEN( aData )
      nMax := Max( HMG_LEN(aData[nI]), nMax )
   NEXT nI

RETURN( nMax )


STATIC FUNCTION DetMaxVal(nNum)
   LOCAL nE, nMax, nMan, nVal, nOffset

   nE:=9
   nVal:=0
   nNum:=Abs(nNum)

   DO WHILE .T.

      nMax := 10**nE

      IF Int(nNum/nMax)>0

         nMan:=(nNum/nMax)-Int(nNum/nMax)
         nOffset:=1
         nOffset:=IF(nMan<=.75,.75,nOffset)
         nOffset:=IF(nMan<=.50,.50,nOffset)
         nOffset:=IF(nMan<=.25,.25,nOffset)
         nOffset:=IF(nMan<=.00,.00,nOffset)
         nVal := (Int(nNum/nMax)+nOffset)*nMax
         EXIT

      ENDIF

      nE--

   ENDDO

RETURN (nVal)


function DrawPointinBitmap( hDC, nType, nY, nX, nHigh, aColor )

   IF nType == POINTS

         DrawCircleinBitmap( hDC, nX - nHigh - 3, nY - 3, 8, aColor )

   ELSEIF nType == LINES

      DrawCircleinBitmap( hDC, nX - nHigh - 2, nY - 2, 6, aColor )

   ENDIF

RETURN

function DrawCircleinBitmap( hDC, nCol, nRow, nWidth, aColor )
   BT_DrawFillEllipse( hDC, nCol, nRow, nWidth, nWidth, aColor, aColor, nPenWidth)
RETURN



function drawpiegraphinBitMap( cImageFileName, nWidth, nHeight, series, aname, colors, ctitle, depth, l3d, lxval, lsleg, lnoborder )
   local fromrow := 0
   local fromcol := 0
   local torow := nHeight
   local tocol := nWidth
   local topleftrow := fromrow
   local topleftcol := fromcol
   local toprightrow := fromrow
   local toprightcol := tocol
   local bottomrightrow := torow
   local bottomrightcol := tocol
   local bottomleftrow := torow
   local bottomleftcol := fromcol
   local middletoprow := fromrow
   local middletopcol := fromcol + int(tocol - fromcol) / 2
   local middleleftrow := fromrow + int(torow - fromrow) / 2
   local middleleftcol := fromcol
   local middlebottomrow := torow
   local middlebottomcol := fromcol + int(tocol - fromcol) / 2
   local middlerightrow := fromrow + int(torow - fromrow) / 2
   local middlerightcol := tocol
   local fromradialrow := 0
   local fromradialcol := 0
   local toradialrow := 0
   local toradialcol := 0
   local degrees := {}
   local cumulative := {}
   local j,i,sum := 0
   local cname := ""
   local shadowcolor := {}
   local previos_cumulative
   local hDC, hBitMap, BTStruct
   
   private nPenWidth := 1


   hBitMap := BT_BitmapCreateNew ( nWidth, nHeight, { 255, 255, 255 } )
   hDC := BT_CreateDC( hBitMap, BT_HDC_BITMAP, @BTStruct )

   if ! lnoborder

      DrawLineinbitmap( hDC, torow  ,fromcol  ,torow  ,tocol  ,WHITE)
      DrawLineinbitmap( hDC, torow-1,fromcol+1,torow-1,tocol-1,GRAY )
      DrawLineinbitmap( hDC, torow-1,fromcol  ,fromrow  ,fromcol  ,GRAY )
      DrawLineinbitmap( hDC, torow-2,fromcol+1,fromrow+1,fromcol+1,GRAY )
      DrawLineinbitmap( hDC, fromrow  ,fromcol  ,fromrow  ,tocol-1,GRAY )
      DrawLineinbitmap( hDC, fromrow+1,fromcol+1,fromrow+1,tocol-2,GRAY )
      DrawLineinbitmap( hDC, fromrow  ,tocol  ,torow  ,tocol  ,WHITE)
      DrawLineinbitmap( hDC, fromrow  ,tocol-1,torow-1,tocol-1,GRAY )
      
   endif

   if HMG_LEN(ALLTRIM(ctitle)) > 0
      DrawTextInBitmap( hDC, fromrow + 10, iif(HMG_LEN(ALLTRIM(ctitle)) * 12 > (tocol - fromcol),fromcol,int(((tocol - fromcol) - (HMG_LEN(ALLTRIM(ctitle)) * 12))/2) + fromcol), ALLTRIM(ctitle), 'Arial', 12, {0,0,255} )
      fromrow := fromrow + 40
   endif   

   if lsleg
      if HMG_LEN(aname) * 20 > (torow - fromrow)
         msginfo("No space for showing legends")
      else
         torow := torow - (HMG_LEN(aname) * 20)
      endif
   endif

   drawrectinbitmap( hDC, fromrow + 10, fromcol + 10, torow - 10, tocol - 10, { 255, 255, 255 } )

   if l3d
      torow := torow - depth
   endif

   fromcol := fromcol + 25
   tocol := tocol - 25
   torow := torow - 25
   fromrow := fromrow + 25


   topleftrow := fromrow
   topleftcol := fromcol
   toprightrow := fromrow
   toprightcol := tocol
   bottomrightrow := torow
   bottomrightcol := tocol
   bottomleftrow := torow
   bottomleftcol := fromcol
   middletoprow := fromrow
   middletopcol := fromcol + int(tocol - fromcol) / 2
   middleleftrow := fromrow + int(torow - fromrow) / 2
   middleleftcol := fromcol
   middlebottomrow := torow
   middlebottomcol := fromcol + int(tocol - fromcol) / 2
   middlerightrow := fromrow + int(torow - fromrow) / 2
   middlerightcol := tocol






   torow := torow + 1
   tocol := tocol + 1

   for i := 1 to HMG_LEN(series)
      sum := sum + series[i]
   next i
   for i := 1 to HMG_LEN(series)
      aadd(degrees,round(series[i]/sum * 360,0))
   next i
   sum := 0
   for i := 1 to HMG_LEN(degrees)
      sum := sum + degrees[i]
   next i
   if sum <> 360
      degrees[HMG_LEN(degrees)] := degrees[HMG_LEN(degrees)] + (360 - sum)
   endif

   sum := 0
   for i := 1 to HMG_LEN(degrees)
      sum := sum + degrees[i]
      aadd(cumulative,sum)
   next i

   previos_cumulative := -1

   fromradialrow := middlerightrow
   fromradialcol := middlerightcol
   for i := 1 to HMG_LEN(cumulative)

      if cumulative[i] == previos_cumulative
         loop
      endif

      previos_cumulative := cumulative[i]

      shadowcolor := {iif(colors[i,1] > 50,colors[i,1] - 50,0),iif(colors[i,2] > 50,colors[i,2] - 50,0),iif(colors[i,3] > 50,colors[i,3] - 50,0)}

      do case
         case cumulative[i] <= 45
            toradialcol := middlerightcol
            toradialrow := middlerightrow - round(cumulative[i] / 45 * (middlerightrow - toprightrow),0)
            drawpieinbitmap(hDC,fromrow,fromcol,torow,tocol,fromradialrow,fromradialcol,toradialrow,toradialcol,,,colors[i])
            fromradialrow := toradialrow
            fromradialcol := toradialcol
         case cumulative[i] <= 90 .and. cumulative[i] > 45
            toradialrow := toprightrow
            toradialcol := toprightcol - round((cumulative[i] - 45) / 45 * (toprightcol - middletopcol),0)
            drawpieinbitmap(hDC,fromrow,fromcol,torow,tocol,fromradialrow,fromradialcol,toradialrow,toradialcol,,,colors[i])
            fromradialrow := toradialrow
            fromradialcol := toradialcol
         case cumulative[i] <= 135 .and. cumulative[i] > 90          
            toradialrow := topleftrow
            toradialcol := middletopcol - round((cumulative[i] - 90) / 45 * (middletopcol - topleftcol),0)
            drawpieinbitmap(hDC,fromrow,fromcol,torow,tocol,fromradialrow,fromradialcol,toradialrow,toradialcol,,,colors[i])
            fromradialrow := toradialrow
            fromradialcol := toradialcol
         case cumulative[i] <= 180 .and. cumulative[i] > 135          
            toradialcol := topleftcol
            toradialrow := topleftrow + round((cumulative[i] - 135) / 45 * (middleleftrow - topleftrow),0)
            drawpieinbitmap(hDC,fromrow,fromcol,torow,tocol,fromradialrow,fromradialcol,toradialrow,toradialcol,,,colors[i])
            fromradialrow := toradialrow
            fromradialcol := toradialcol
         case cumulative[i] <= 225 .and. cumulative[i] > 180          
            toradialcol := topleftcol
            toradialrow := middleleftrow + round((cumulative[i] - 180) / 45 * (bottomleftrow - middleleftrow),0)
            if l3d
               for j := 1 to depth
                  drawarcinBitMap(hDC,fromrow + j,fromcol,torow+j,tocol,fromradialrow+j,fromradialcol,toradialrow+j,toradialcol,shadowcolor)
               next j
            endif   
            drawpieinbitmap(hDC,fromrow,fromcol,torow,tocol,fromradialrow,fromradialcol,toradialrow,toradialcol,,,colors[i])
            fromradialrow := toradialrow
            fromradialcol := toradialcol
         case cumulative[i] <= 270 .and. cumulative[i] > 225          
            toradialrow := bottomleftrow
            toradialcol := bottomleftcol + round((cumulative[i] - 225) / 45 * (middlebottomcol - bottomleftcol),0)
            if l3d
               for j := 1 to depth
                  drawarcinbitmap(hDC,fromrow + j,fromcol,torow+j,tocol,fromradialrow+j,fromradialcol,toradialrow+j,toradialcol,shadowcolor)
               next j
            endif   
            drawpieinbitmap(hDC,fromrow,fromcol,torow,tocol,fromradialrow,fromradialcol,toradialrow,toradialcol,,,colors[i])
            fromradialrow := toradialrow
            fromradialcol := toradialcol
         case cumulative[i] <= 315 .and. cumulative[i] > 270          
            toradialrow := bottomleftrow
            toradialcol := middlebottomcol + round((cumulative[i] - 270) / 45 * (bottomrightcol - middlebottomcol),0)
            if l3d
               for j := 1 to depth
                  drawarcinBitMap(hDC,fromrow + j,fromcol,torow+j,tocol,fromradialrow+j,fromradialcol,toradialrow+j,toradialcol,shadowcolor)
               next j
            endif   
            drawpieinbitmap(hDC,fromrow,fromcol,torow,tocol,fromradialrow,fromradialcol,toradialrow,toradialcol,,,colors[i])
            fromradialrow := toradialrow
            fromradialcol := toradialcol
         case cumulative[i] <= 360 .and. cumulative[i] > 315
            toradialcol := bottomrightcol
            toradialrow := bottomrightrow - round((cumulative[i] - 315) / 45 * (bottomrightrow - middlerightrow),0)
            if l3d
               for j := 1 to depth
                  drawarcinBitMap(hDC,fromrow + j,fromcol,torow+j,tocol,fromradialrow+j,fromradialcol,toradialrow+j,toradialcol,shadowcolor)
               next j
            endif
            drawpieinbitmap(hDC,fromrow,fromcol,torow,tocol,fromradialrow,fromradialcol,toradialrow,toradialcol,,,colors[i])
            fromradialrow := toradialrow
            fromradialcol := toradialcol
         endcase
      if l3d            
         drawlineinbitmap(hDC, middleleftrow, middleleftcol, middleleftrow+depth, middleleftcol, { 0, 0, 0 } )
         drawlineinbitmap(hDC, middlerightrow, middlerightcol, middlerightrow+depth, middlerightcol, { 0, 0, 0 } )
         drawarcinBitMap(hDC,fromrow + depth,fromcol,torow + depth,tocol,middleleftrow+depth,middleleftcol,middlerightrow+depth,middlerightcol )
      endif
   next i
   if lsleg
      fromrow := torow + 20 + iif(l3d,depth,0)
      for i := 1 to HMG_LEN(aname)
         drawrectinbitmap(hDC, fromrow, fromcol, fromrow + 15, fromcol + 15, colors[ i ] )
         drawtextinbitmap( hDC, fromrow, fromcol + 20, aname[i]+iif(lxval," - "+ALLTRIM(STR(series[i],19,2))+" ("+ALLTRIM(STR(degrees[i] / 360 * 100,6,2))+" %)",""), 'Arial', 8, colors[i] )
         fromrow := fromrow + 20
      next i
   endif   
   BT_BitmapSaveFile(hBitmap, cImageFileName )
   BT_DeleteDC( BTstruct )
   BT_BitmapRelease( hBitmap )
return nil

function drawarcinBitMap(hDC,row,col,row1,col1,rowr,colr,rowr1,colr1,penrgb,penwidth)
   if valtype(penrgb) == "U"
      penrgb = {0,0,0}
   endif
   if valtype(penwidth) == "U"
      penwidth = 1
   endif
   arcdrawbitmap( hDC ,row,col,row1,col1,rowr,colr,rowr1,colr1,penrgb,penwidth)

return nil

function drawpieinbitmap(hDC,row,col,row1,col1,rowr,colr,rowr1,colr1,penrgb,penwidth,fillrgb)

   if valtype(penrgb) == "U"
      penrgb = {0,0,0}
   endif
   if valtype(penwidth) == "U"
      penwidth = 1
   endif
   if valtype(fillrgb) == "U"
      fillrgb := {255,255,255}
      fill := .f.
   else
      fill := .t.   
   endif
   piedrawbitmap( hDC,row,col,row1,col1,rowr,colr,rowr1,colr1,penrgb,penwidth,fillrgb,fill)

return nil

function drawpolygoninbitmap( hDC, apoints, penrgb, penwidth, fillrgb )
   local xarr := {}
   local yarr := {}
   local x := 0
   if valtype(penrgb) == "U"
      penrgb = {0,0,0}
   endif
   if valtype(penwidth) == "U"
      penwidth = 1
   endif
   if valtype(fillrgb) == "U"
      fillrgb := {255,255,255}
      fill := .f.
   else
      fill := .t.   
   endif
   for x := 1 to HMG_LEN(apoints)
       aadd(xarr,apoints[x,2])
       aadd(yarr,apoints[x,1])
   next x
   polygondrawbitmap( hDC, xarr, yarr, penrgb, penwidth, fillrgb, fill )
return nil

STATIC FUNCTION RGB2HSL( nR, nG, nB )
   LOCAL nMax, nMin
   LOCAL nH, nS, nL

   IF nR < 0
      nR := Abs( nR )
      nG := GetGreen( nR )
      nB := GetBlue( nR )
      nR := GetRed( nR )
   ENDIF

   nR := nR / 255
   nG := nG / 255
   nB := nB / 255
   nMax := Max( nR, Max( nG, nB ) )
   nMin := Min( nR, Min( nG, nB ) )
   nL := ( nMax + nMin ) / 2

   IF nMax = nMin
      nH := 0
      nS := 0
   ELSE
      IF nL < 0.5
         nS := ( nMax - nMin ) / ( nMax + nMin )
      ELSE
         nS := ( nMax - nMin ) / ( 2.0 - nMax - nMin )
      ENDIF
      DO CASE
         CASE nR = nMax
            nH := ( nG - nB ) / ( nMax - nMin )
         CASE nG = nMax
            nH := 2.0 + ( nB - nR ) / ( nMax - nMin )
         CASE nB = nMax
            nH := 4.0 + ( nR - nG ) / ( nMax - nMin )
      ENDCASE
   ENDIF

   nH := Int( (nH * 239) / 6 )
   IF nH < 0 ; nH += 240 ; ENDIF
   nS := Int( nS * 239 )
   nL := Int( nL * 239 )

RETURN { nH, nS, nL }


STATIC FUNCTION HSL2RGB( nH, nS, nL )
   LOCAL nFor
   LOCAL nR, nG, nB
   LOCAL nTmp1, nTmp2, aTmp3 := { 0, 0, 0 }

   nH /= 239
   nS /= 239
   nL /= 239
   IF nS == 0
      nR := nL
      nG := nL
      nB := nL
   ELSE
      IF nL < 0.5
         nTmp2 := nL * ( 1 + nS )
      ELSE
         nTmp2 := nL + nS - ( nL * nS )
      ENDIF
      nTmp1 := 2 * nL - nTmp2
      aTmp3[1] := nH + 1 / 3
      aTmp3[2] := nH
      aTmp3[3] := nH - 1 / 3
      FOR nFor := 1 TO 3
         IF aTmp3[nFor] < 0
            aTmp3[nFor] += 1
         ENDIF
         IF aTmp3[nFor] > 1
            aTmp3[nFor] -= 1
         ENDIF
         IF 6 * aTmp3[nFor] < 1
            aTmp3[nFor] := nTmp1 + ( nTmp2 - nTmp1 ) * 6 * aTmp3[nFor]
         ELSE
            IF 2 * aTmp3[nFor] < 1
               aTmp3[nFor] := nTmp2
            ELSE
               IF 3 * aTmp3[nFor] < 2
                  aTmp3[nFor] := nTmp1 + ( nTmp2 - nTmp1 ) * ( ( 2 / 3 ) - aTmp3[nFor] ) * 6
               ELSE
                  aTmp3[nFor] := nTmp1
               ENDIF
            ENDIF
         ENDIF
      NEXT nFor
      nR := aTmp3[1]
      nG := aTmp3[2]
      nB := aTmp3[3]
   ENDIF

RETURN { Int( nR * 255 ), Int( nG * 255 ), Int( nB * 255 ) }


STATIC PROC DrawBoxinBitmap( hDC, nY, nX, nHigh, nWidth, l3D, nDeep )

   // Set Border
   DrawLineinbitmap( hDC, nX, nY        , nX-nHigh+nDeep    , nY       , BLACK )  // LEFT
   DrawLineinbitmap( hDC, nX, nY+nWidth , nX-nHigh+nDeep    , nY+nWidth, BLACK )  // RIGHT
   DrawLineinbitmap( hDC, nX-nHigh+nDeep, nY, nX-nHigh+nDeep, nY+nWidth, BLACK )  // Top
   DrawLineinbitmap( hDC, nX, nY, nX, nY+nWidth, BLACK )                          // Bottom
   IF l3D
      // Set shadow
      DrawLineinbitmap( hDC, nX-nHigh+nDeep, nY+nWidth, nX-nHigh, nY+nDeep+nWidth, BLACK )
      DrawLineinbitmap( hDC, nX, nY+nWidth, nX-nDeep, nY+nWidth+nDeep, BLACK )
      IF nHigh > 0
         DrawLineinbitmap( hDC, nX-nDeep, nY+nWidth+nDeep, nX-nHigh, nY+nWidth+nDeep, BLACK )
         DrawLineinbitmap( hDC, nX-nHigh, nY+nDeep, nX-nHigh , nY+nWidth+nDeep, BLACK )
         DrawLineinbitmap( hDC, nX-nHigh+nDeep, nY, nX-nHigh, nY+nDeep, BLACK )
      ELSE
         DrawLineinbitmap( hDC, nX-nDeep, nY+nWidth+nDeep, nX-nHigh+1, nY+nWidth+nDeep, BLACK )
         DrawLineinbitmap( hDC, nX, nY, nX-nDeep, nY+nDeep, BLACK )
      ENDIF
   ENDIF

RETURN



#pragma BEGINDUMP

#include "SET_COMPILE_HMG_UNICODE.ch"
#include "HMG_UNICODE.h"


#include <windows.h>
#include <commctrl.h>
#include "hbapi.h"
#include <wingdi.h>
#include <winuser.h>

HB_FUNC ( PIEDRAWBITMAP )
{
   HDC hdc1;
   HGDIOBJ hgdiobj1,hgdiobj2;
   HPEN hpen;
   HBRUSH hbrush;
   hdc1 = (HDC) HMG_parnl (1);
   hpen = CreatePen( (int) PS_SOLID, (int) hb_parni(11), (COLORREF) RGB( (int) hb_parvni(10,1), (int) hb_parvni(10,2), (int) hb_parvni(10,3) ) );
   hgdiobj1 = SelectObject((HDC) hdc1, hpen);
   if (hb_parl(13))
   {
      hbrush = CreateSolidBrush((COLORREF) RGB((int) hb_parvni(12,1),(int) hb_parvni(12,2),(int) hb_parvni(12,3)));    
      hgdiobj2 = SelectObject((HDC) hdc1, hbrush);
   }   
   else
   {
      hbrush = GetSysColorBrush((int) COLOR_WINDOW);    
      hgdiobj2 = SelectObject((HDC) hdc1, hbrush);
   }      
   Pie((HDC) hdc1,(int) hb_parni(3),(int) hb_parni(2),(int) hb_parni(5),(int) hb_parni(4),(int) hb_parni(7),(int) hb_parni(6),(int) hb_parni(9),(int) hb_parni(8));
   SelectObject((HDC) hdc1,(HGDIOBJ) hgdiobj1);
   SelectObject((HDC) hdc1,(HGDIOBJ) hgdiobj2);
   DeleteObject( hpen );
   DeleteObject( hbrush );
}
   
HB_FUNC( POLYGONDRAWBITMAP )
{
   HDC hdc1;
   HGDIOBJ hgdiobj1,hgdiobj2;
   HPEN hpen;
   HBRUSH hbrush;
   POINT apoints[1024];
   int number=hb_parinfa(2,0);
   int i;
   hdc1 = (HDC) HMG_parnl (1);
   hpen = CreatePen( (int) PS_SOLID, (int) hb_parni(5), (COLORREF) RGB( (int) hb_parvni(4,1), (int) hb_parvni(4,2), (int) hb_parvni(4,3) ) );
   hgdiobj1 = SelectObject((HDC) hdc1, hpen);
   if (hb_parl(7))
   {
      hbrush = CreateSolidBrush((COLORREF) RGB((int) hb_parvni(6,1),(int) hb_parvni(6,2),(int) hb_parvni(6,3)));    
      hgdiobj2 = SelectObject((HDC) hdc1, hbrush);
   }   
   else
   {
      hbrush = GetSysColorBrush((int) COLOR_WINDOW);    
      hgdiobj2 = SelectObject((HDC) hdc1, hbrush);
   }      
   for(i = 0; i <= number-1; i++)
   {
   apoints[i].x=hb_parvni(2,i+1);
   apoints[i].y=hb_parvni(3,i+1);
   }
   Polygon((HDC) hdc1,apoints,number);
   SelectObject((HDC) hdc1,(HGDIOBJ) hgdiobj1);
   SelectObject((HDC) hdc1,(HGDIOBJ) hgdiobj2);
   DeleteObject( hpen );
   DeleteObject( hbrush );
}

HB_FUNC ( ARCDRAWBITMAP )
{
   HDC hdc1;
   HGDIOBJ hgdiobj1;
   HPEN hpen;
   hdc1 = (HDC) HMG_parnl (1);
   hpen = CreatePen( PS_SOLID, (int) hb_parni(11), (COLORREF) RGB( (int) hb_parvni(10,1), (int) hb_parvni(10,2), (int) hb_parvni(10,3) ) );
   hgdiobj1 = SelectObject( hdc1, hpen );
   Arc( hdc1,(int) hb_parni(3),(int) hb_parni(2),(int) hb_parni(5),(int) hb_parni(4),(int) hb_parni(7),(int) hb_parni(6),(int) hb_parni(9),(int) hb_parni(8));
   SelectObject( hdc1, hgdiobj1);
   DeleteObject( hpen );
}

HB_FUNC( POLYBEZIERDRAWBITMAP )
{
   HDC hdc1;
   HGDIOBJ hgdiobj1;
   HPEN hpen;
   POINT apoints[1024];
   DWORD number=(DWORD) hb_parinfa(2,0);
   DWORD i;
   hdc1 = (HDC) HMG_parnl (1);
   hpen = CreatePen( (int) PS_SOLID, (int) hb_parni(5), (COLORREF) RGB( (int) hb_parvni(4,1), (int) hb_parvni(4,2), (int) hb_parvni(4,3) ) );
   hgdiobj1 = SelectObject((HDC) hdc1, hpen);
   for(i = 0; i <= number-1; i++)
   {
   apoints[i].x=hb_parvni(2,i+1);
   apoints[i].y=hb_parvni(3,i+1);
   }
   PolyBezier((HDC) hdc1,apoints,number);
   SelectObject((HDC) hdc1,(HGDIOBJ) hgdiobj1);
   DeleteObject( hpen );
}   

#pragma ENDDUMP
I'm quoting this post from over the year ago.
I'm using Rathi's graph solution for generating bar graphs. After few regenerating graph, My app does strange screen effects. I've modified a little original code, so, I thought this is my error.
But, I'm testing original code, and after few changes, this sample works bad, too.
Try to compile this sample ang change only bar type until your graph dissappear.

Where is the error? Can sb. test it?

In my opinion, i tcan be Bos Taurus library problem...
User avatar
Rathinagiri
Posts: 5471
Joined: Tue Jul 29, 2008 6:30 pm
DBs Used: MariaDB, SQLite, SQLCipher and MySQL
Location: Sivakasi, India
Contact:

Re: HMG Graph based on Bas Taurus

Post by Rathinagiri »

Does it happen every time or when some one changes the graph type in a fast manner?
East or West HMG is the Best.
South or North HMG is worth.
...the possibilities are endless.
User avatar
mol
Posts: 3720
Joined: Thu Sep 11, 2008 5:31 am
Location: Myszków, Poland
Contact:

Re: HMG Graph based on Bas Taurus

Post by mol »

Everytime.
I've embedded this graph procedures in my app, and after 7-8 regenerations screen crashes (mayb because of memory usage it happens quicker).
In your sample it happens after dozen of times (after 120 hanges of graph type).
Post Reply