• Welcome to Jose's Read Only Forum 2023.
 

gdiplus spheres + rectangles effects

Started by Frank Brübach, January 23, 2010, 08:08:08 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Edwin Knoppert

#15
Frank, you have changed your code but you forgot to declare several variables.
Please add Option Explicit to your code :)

Added:
I took the wrong example :) the errors are in the star example.

Also, you should return 0 on WM_PAINT.

I have seen your vertex example, very nice.
I have modified to the desired colors as shown in my image:

  vertex(0).x      = 0
  vertex(0).y      = 0
  vertex(0).Red    = &HFA00
  vertex(0).Green  = &HF900
  vertex(0).Blue   = &HF500
  vertex(0).Alpha  = &H0000

  vertex(1).x      = rc.nRight - rc.nLeft
  vertex(1).y      = rc.nBottom - rc.nTop

  vertex(1).Red    = &HC000
  vertex(1).Green  = &HC000
  vertex(1).Blue   = &HA800
  vertex(1).Alpha  = &H0000

Edwin Knoppert

I don't understand the 16 bit rgb values yet, is this some kind of alpha channel per color or so?
I was trying to convert an ordinary rgb value to these vertex structures but found out they are not the same (16bit).

I was trying to paint my gradient with transparancy, something like a shadow.
I have used a label with some text and paint my gradient using this DC (on button click).
The text is overpainted unf.


Sub DrawGradient( ByVal hdc As Dword, ByVal R As RECT )

   Local gRect As GRADIENT_RECT
   Dim vertex( 0 To 1 ) As Local TRIVERTEX

   vertex( 0 ).x      = r.nLeft
   vertex( 0 ).y      = r.nTop
   
   vertex( 0 ).Red    = &HF500
   vertex( 0 ).Green  = &HF900
   vertex( 0 ).Blue   = &HF500
   vertex( 0 ).Alpha  = &H0000

   vertex( 1 ).x      = r.nLeft + r.nRight
   vertex( 1 ).y      = r.nTop + r.nBottom

   vertex( 1 ).Red    = &HC000
   vertex( 1 ).Green  = &HC000
   vertex( 1 ).Blue   = &HA800
   vertex( 1 ).Alpha  = &H0000

   gRect.UpperLeft  = 0
   gRect.LowerRight = 1

   Call GradientFill( hDc, ByVal VarPtr( vertex( 0 ) ), 2, gRect, 1, %GRADIENT_FILL_RECT_V )

End Sub


Using it as:


    Local R     As RECT
    Local hDC   As Long
    Local hWndc As Long
   
    hWndc = GetDlgItem( nCbHndl, %ID_FORM1_LABEL1 )                     
                     
    hDC = GETDC( hWndc )

    R.nLeft = 10
    R.nTop = 3
    R.nRight = 20
    R.nBottom = 100
    DrawGradient( hDC, R )

    ReleaseDC( hWndc, hDC )


Setting the alpha won't work as well.

Frank Brübach

#17
hi edwin, can you please show your example by an added picture ?

don't understand fully your problem as I didn't have whole pb example at my hands ;)

QuoteI was trying to paint my gradient with transparancy, something like a shadow.

1) you can use a second "drawGradient" function as shadow for first one and place it (for example)
for wx=15, hy=25 ?

my idea works fine:
SUB DrawGradient3 (BYVAL hwnd AS DWORD, BYVAL hdc AS DWORD)

  LOCAL rc AS RECT
  DIM   vertex(1) AS TRIVERTEX

  GetClientRect hwnd, rc

  vertex(0).x      = 15'0 -----------------> change here
  vertex(0).y      = 25'0 -----------------> change here
  vertex(0).Red    = &HFA00
  vertex(0).Green  = &HF900
  vertex(0).Blue   = &HF500
  vertex(0).Alpha  = &H0000

  vertex(1).x      = rc.nRight-20 - rc.nLeft '-----------------> -20! change here
  vertex(1).y      = rc.nBottom-20 - rc.nTop '-----------------> -20! change here

  vertex(1).Red    = &HC000
  vertex(1).Green  = &HC000
  vertex(1).Blue   = &HA800
  vertex(1).Alpha  = &H0000

  LOCAL gRect AS GRADIENT_RECT

  gRect.UpperLeft  = 0
  gRect.LowerRight = 1

  GradientFill hDc, vertex(0), 2, gRect, 1, %GRADIENT_FILL_RECT_H

END SUB                


2) perhaps ? ->try to use or do some experiments:

a) instead of
"Sub DrawGradient( ByVal hdc As Dword, ByVal R As RECT )"
take
"Sub DrawGradient( ByVal hdc As Dword )"
local R As RECT

use then

b) drawGradient hDc '--- >in your code below

c) don't understand this one in your example:
"hDC = GETDC( hWndc )"

d) sorry, I see I need more infos. What is your intention to build one gradient area with shadow and cover with some text ? ;)

3) quite another idea: I would prefer to use "GDIPLUS.INC" with:
"GDIP_ARGB_SetAlphaValue"

MiddleColorToOpaque = GDIP_ARGB_SetAlphaValue(%ARGB_MediumAquamarine, 0)
  hStatus = GdipSetPathGradientCenterColor(pBrush1, MiddleColorToOpaque)



servus, best regards, frank

Edwin Knoppert

My code is simply some testing code, the 2nd code block is actually placed in a button click event procedure, just for testing.

I used a static control with some text and i expected when i draw with some alpha blending value other than 0 that it would still show the existing text and intermix the gradient.
(Any color you like, doing it for shadow effects is not important right now)
But it still overpainted the text from the static.
Question is how to draw a semi transparant gradient, in the future i may use it for shadows.. , whatever.

2nd question is that i could not really find wht MS is using some 16bit color value, is the 2nd part in the (hex)value also for transparancy?
:)

Frank Brübach

#19
If it's possible to make something like a "gradient brush" for fonts then you'll find the right solution.
my thoughts are running in that direction to give the font a gradient brush, but so far as I know there is no function like

hStatus1 = GdipCreateFontBrushFromString(rc, pGradientBrush, pGradientBrush1, %LinearGradientModeHorizontal, %WrapModeTile, pFontBrush) '----------> this would be the solution!!!

this string example works. if there is any way (I don't know yet the right way at this moment!) to set any gradient effect at a font, so you have won ;)

SUB GDIP_DrawString2 (BYVAL hdc AS DWORD)

  LOCAL hStatus AS LONG
  LOCAL hStatus1 AS LONG
  LOCAL pGraphics AS DWORD
  LOCAL pFont AS DWORD
  LOCAL pFontFamily AS DWORD
  LOCAL pBlackBrush AS DWORD
  LOCAL pGradientBrush AS DWORD
  LOCAL strFontName AS STRING
  LOCAL strText AS STRING
  LOCAL rcf AS RECTF
  LOCAL pHatchBrush AS DWORD
  LOCAL pColorRed AS DWORD
  LOCAL pColorBlue AS DWORD

  hStatus = GdipCreateFromHDC(hdc, pGraphics)

  ' // Create the font
  strFontName = UCODE$("Arial")
  hStatus = GdipCreateFontFamilyFromName(STRPTR(strFontName), %Null, pFontFamily) '
  IF hStatus = %StatusOk AND pFontFamily <> %NULL THEN
     hStatus = GdipCreateFont(pFontFamily, 36, %FontStyleRegular, %UnitPoint, pFont)
     GdipDeleteFontFamily(pFontFamily)
  END IF

  ' Note: You can use the wrapper function GdiPlusCreateFontFromName to create the font:
  '    hStatus1 = GdipCreateFontBrushFromString(rc, pGradientBrush, pGradientBrush1, %LinearGradientModeHorizontal, %WrapModeTile, pFontBrush) '----------> this would be the solution!!!
   pColorRed =  GDIP_ARGB(255, 255, 0, 100)
   pColorBlue  = GDIP_ARGB(255, 0, 100, 255)

  ' // Create a solid brush
  'hStatus = GdipCreateSolidFill(GDIP_ARGB(255, 0, 0, 0), pGradientBrush)
  hStatus = GdipCreateSolidFill(GDIP_ARGB(255, 255, 0, 0), pBlackBrush)

  ' // Create a HatchBrush object.
  hStatus = GdipCreateHatchBrush(%HatchStyleHorizontal, pColorRed, pColorBlue, pHatchBrush)

  ' // Draw the string
  rcf.x = 140.0! : rcf.y = 40.0!
  strText = UCODE$("this is a string Text Test")
  hStatus = GdipDrawString(pGraphics, STRPTR(strText), LEN(strText) \ 2, pFont, rcf, %NULL, pHatchBrush)

  ' // Cleanup
  IF pFont THEN GdipDeleteFont(pFont)
  IF pBlackBrush THEN GdipDeleteBrush(pBlackBrush)
  IF pGraphics THEN GdipDeleteGraphics(pGraphics)

END SUB


here might be the little black box within a perfect solution for gradient text effects for you, edwin :)
if I'll find a serious way I send you my solution, be sure.

good evening, frank (I have a cold, so I am not very fit to go through this wall tonight!)

Edwin Knoppert

Thanks Frank, that may become handy!
However i want to use a gradient area *over* existing text (and other existing stuff).
Well, let me give you an example what i may want to create in the future.
In Windows Vista and W7's control panel you have these mousehover effects..?
Or even simplier, checkout the menuitems (save as...) of for example notepad, these menus are using a 'themed menubar style' over existing text.
I would like to have a simple way like a drawing function to make this myself, at this moment without gdi+ if possible.

Don't worry, you don't have to find all kinds of answers but if you like to do these things, it would be nice.
There are some problem areas here:
1) Existing text should remain.
2) Mouse on and off hover
3) Rounded rectangle.
4) Preferred to draw it on any DC and not preparing a control.

Here is a simple snapshot:
http://www.hellobasic.com/images/w7menuhover.png


Edwin Knoppert

To elaborate a bit more how nice windows can look, their folders listview is so much more beautifully drawn (note: set to full size):

http://www.hellobasic.com/images/w7menuhoverLV.png

Edwin Knoppert

Frank, thanks for your help!
Here is somewhat of the result i was looking for (no code over there):

http://www.hellobasic.com/cgi-bin/forum/YaBB.pl?board=vd;action=display;num=1266533032;start=0

The exe shows the vertex stuff, i use it like:

Function DrawHoverEffect( _
      ByVal hDC             As Long _
    , ByVal dwStartColor    As Long _
    , ByVal dwEndColor      As Long _
    , ByVal dwLineColor     As Long _
    , ByVal R               As RECT _
    , ByVal nWidth          As Long _
    , ByVal nHeight         As Long _
    , ByVal pCallBack       As Dword _
    , ByVal lParam          As Long _
    ) As Long


Width and height determine the rounded corners.
:)