Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations TouchToneTommy on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

API GradientFill

Status
Not open for further replies.

DannC

Programmer
Apr 5, 2001
75
RO
Hi,

I've got a little problem using the GradientFill APi function. Everything works fine ( it returns .t. ) but there is no fill area on my form :( (getlasterror = 3 witch makes no sense ??? ). If someone has allready solve this problem please help me.


Regards

Thanks for sharing your knowlege.
 
DannC

If you want to create a gradient in a form a simpler way would be to use the following in the init of the form:
Code:
LOCAL lnRow
ThisForm.ScaleMode = 3
ThisForm.DrawWidth = 1
FOR lnRow = 0 TO ThisForm.Height
 ThisForm.ForeColor = RGB(0,0,255-255*lnRow/ThisForm.Height)
 ThisForm.Line(0, lnRow, ThisForm.Width, lnRow)
NEXT lnRow
You can adjust the forecolor parameter to suit your needs.

Otherwise please supply us with the code for your GradientFill API so we can tell where the problem is.


Mike Gagnon

If you want to get the best response to a question, please check out FAQ184-2483 first.
 
Hi Mike

That is nice one!. Only problem is that, if the form is resized, it will show odd background. Nor we can shift this code to any other evet to repeat the process.. since the lines will be drawn over other objects making them invisible. Have you thought of anyway.. which will make the gradiant fill after the form is loaded with objects.. I mean.. let us say the same code from a buttons click event.. for example.. to get the same effect. If yes.. then I have code.. top to bottom or left to right or circular or eliptical..gradiants. I was not able to repaint and if done.. the buttons.. text boxes.. grids and all controls vanish.

I have seen a way of calling the Windows way of doing a gradiant.. which will work only on W2000 OS. But I will not do it that way.. since it becoms OS dependant.

I dont know if Dannc is using a different OS while that API will only work on W2000 OS.

:) ramani :)
(Subramanian.G),FoxAcc, ramani_g@yahoo.com
Merry Christmas & Happy New Year [bigears] [party] [2thumbsup]

 
Ramani

That is nice one!. Only problem is that, if the form is resized, it will show odd background. Nor we can shift this code to any other evet to repeat the process..

Yes, it has it's limitations,I would definetely prevent the resizing.
Mike Gagnon

If you want to get the best response to a question, please check out FAQ184-2483 first.
 
DannC

Although, there is an nice (and configurable) gradiant Activex I have used in the past called "Super Gradient Control". Its somewhere on my system... Mike Gagnon

If you want to get the best response to a question, please check out FAQ184-2483 first.
 
Seems to me that Mike's code will work fine if it painted those lines on a class control that was placed on the form same height and width and then repainted and resized from form's resize event...also, gradient control's events could be delegated to the form so form didn't lose certain events...just a thought Slighthaze = NULL
 
Thanks for the lines tip i'll try it. Thanks for sharing your knowlege.
 
Regarding using the WinAPI:

I found that the problem with it showing up black is that you're specifying the RGB+A colors as numbers in the 0x00FF range... the MSDN docs say they should be in the 0xFF00 range.

So, take the numbers for RGB+A you want, and provide them through BITLSHIFT( color, 8 )

( ps: How do you retrieve the main VFP window's HWND/DC? )

Here's a sample producing a gradient triangle in VFP through the WinAPI:
Code:
SET PROC TO ApiStructure && for the STRUCT class.
_SCREEN.LockScreen = .T.
DECLARE LONG GetDC ;
  IN Win32api ;
  LONG nhWnd 
DECLARE LONG ReleaseDC ;
  IN Win32api ;
  LONG nhWnd, ;
  LONG nhDC

LOCAL WHND,hDC,Depth,cRect,loRect

  * WHND = FindWindow( _SCREEN.Caption )
* Use Spy++ to find your main VFP output window's handle here
* I haven't found a way yet to retrieve it.

  whnd = 0x001204E4
  hDC = GetDC( WHND )


DECLARE LONG GetClientRect IN User32.dll ;
  LONG HWND_hWnd, STRING @ LPRECT_lpRect
loRec = CREATE('Struct_RECT')
cRect = loRec.Structure
GetClientRect(whnd, @cRect)
loRec.Structure = cRect 

*// Use the rect coordinates to define a clipping region. 
 
DECLARE LONG CreateRectRgn IN gdi32.dll ;
  INTEGER ul_x, INTEGER ul_y, INTEGER br_x, INTEGER br_y

hrgn = CreateRectRgn(loRec.fld('left'),loRec.fld('top'),loRec.fld('right'),loRec.fld('bottom'))

DECLARE LONG SelectClipRgn IN gdi32.dll ;
  LONG HDC_hdc, LONG HRGN_hrgn
SelectClipRgn(hdc, hrgn)

DECLARE INTEGER GradientFill IN msImg32.dll ;
  LONG     HDC_hdc, ;
  STRING @ PTRIVERTEX_pVertex, ;
  LONG     ULONG_dwNumVertex, ;
  STRING @ PVOID_pMesh, ;
  LONG     ULONG_dwNumMesh, ;
  LONG     ULONG_dwMode 

#define GRADIENT_FILL_RECT_H    0x00000000
#define GRADIENT_FILL_RECT_V    0x00000001
#define GRADIENT_FILL_TRIANGLE  0x00000002

LOCAL lcVert, lcMesh
loStr = CREATE('Struct_TRIVERTEX')
loStr.Fld('x') = 3
loStr.Fld('y') = 10
loStr.Fld('red')   = BITLSHIFT(255,8)
loStr.Fld('blue')  = BITLSHIFT(127,8)
loStr.Fld('green') = BITLSHIFT(200,8)
lcVert = loStr.Structure
loStr.Fld('x') = 50
loStr.Fld('y') = 300
loStr.Fld('red')   = BITLSHIFT(128,8)
loStr.Fld('blue')  = BITLSHIFT(255,8)
loStr.Fld('green') = 0
lcVert = lcVert+loStr.Structure
loStr.Fld('x') = 200
loStr.Fld('y') = 20
loStr.Fld('red')   = 0
loStr.Fld('blue')  = BITLSHIFT(255,8)
loStr.Fld('green') = 0
lcVert = lcVert+loStr.Structure

loStr = CREATE('struct_GRADIENT_TRIANGLE')
loStr.Fld('Vertex1')=0
loStr.Fld('Vertex2')=1
loStr.Fld('Vertex3')=2
lcMesh = loStr.Structure

DECLARE LONG SetPixel IN GDI32.dll ;
  INTEGER HDC_hdc, INTEGER int_X, INTEGER int_Y, LONG COLORREF_crColor
SetPixel( hDC, 5,5,12345 )

GradientFill( hDC, @lcVert, 3, @lcMesh, 1, GRADIENT_FILL_TRIANGLE )

DEBUG
SUSP

=ReleaseDC( WHND, hDC )
_SCREEN.LockScreen = .F.
 
DEFINE CLASS struct_TRIVERTEX AS Struct 
  PROCEDURE Init
    THIS.AddField('x',      'LONG', 0)
    THIS.AddField('y',      'LONG', 0)
    THIS.AddField('Red',    'WORD', BITLSHIFT(128,8))
    THIS.AddField('Green',  'WORD', BITLSHIFT(128,8))
    THIS.AddField('Blue',   'WORD', BITLSHIFT(128,8))
    THIS.AddField('Alpha',  'WORD', BITLSHIFT(255,8))
  ENDPROC
ENDDEFINE

DEFINE CLASS struct_GRADIENT_TRIANGLE AS Struct 
  PROCEDURE Init
    THIS.AddField('Vertex1', 'LONG', 0)
    THIS.AddField('Vertex2', 'LONG', 0)
    THIS.AddField('Vertex3', 'LONG', 0)
  ENDPROC
ENDDEFINE
DEFINE CLASS struct_GRADIENT_RECT  AS Struct 
  PROCEDURE Init
    THIS.AddField('UpperLeft',  'LONG', 0)
    THIS.AddField('LowerRight', 'LONG', 0)
  ENDPROC
ENDDEFINE

DEFINE CLASS struct_RECT  AS Struct 
  PROCEDURE Init
    THIS.AddField('left',   'LONG', 0)
    THIS.AddField('top',    'LONG', 0)
    THIS.AddField('right',  'LONG', 0)
    THIS.AddField('bottom', 'LONG', 0)
  ENDPROC
ENDDEFINE
 
You can use this function to get a window to put the gradient fill into:

Code:
*Instead of:
 whnd = 0x001204E4

*Do This:
  loForm = CREATE('FORM')
  loForm.caption = 'GradientFill'
  loForm.Visible = .t.
  loForm.LockScreen = .T.
  WHND= FindVfpWindow( 'GradientFill' )


************************************************************************
*  FindVfpWindow( cWindowName )
*
*  Auth: William GC Steinford
*  Date: Feb 19, 2004
*  Purp: Ask windows if a particular window name exists
*        (Case Insensitive)
*
************************************************************************
FUNCTION FindVfpWindow
LPARAMETERS pcWindowTitle
LOCAL lnWHND, lnVFP, lnRes, lnCNT

DECLARE INTEGER FindWindow in win32api as apiFindWindow ;
  INTEGER nClass, STRING cName
DECLARE INTEGER FindWindowEx in win32api as apiFindWindowEx ;
  INTEGER nParent, INTEGER nChildAfter, ;
  INTEGER nClass, STRING cName

* First get the VFP window handle
lnVFP = apiFindWindow( 0, _Screen.Caption )
if lnVFP<=0
  RETURN -1
ENDIF
lnWHND = lnVFP

if not empty(pcWindowTitle)
  lnWHND = apiFindWindowEx( lnVFP, 0, 0, pcWindowTitle ) && Look in VFP window
  if lnWHND=0 && Not in Main VFP window... This is the case if this window was created by VFP
    && Container windows in VFP have no title
    lnCNT  = apiFindWindowEx( lnVFP, 0, 0, '' ) && Find in container window
    do while lnWHND=0 and lnCNT<>0
      lnWHND = apiFindWindowEx( lnCNT, 0, 0, pcWindowTitle ) && Look in container
      lnCNT  = apiFindWindowEx( lnVFP, lnCNT, 0, '' ) && Find next container window
    enddo
  endif
endif
RETURN lnWHND

 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top