GradientFillRect

N

NickP

Hi there,

I am trying to use GradientFillRect in a VB.NET application.

Does anyone have any examples of the correct PInvoke signature and
marshaling that I need to perform in order to achieve this?

BTW, I do not want to use .Nets gradient fill capabilities, and so far I
have this.

----------------------------------------------

Private Const GRADIENT_FILL_RECT_H As Long = &H0
Private Const GRADIENT_FILL_RECT_V As Long = &H1

<StructLayout(LayoutKind.Sequential)> _
Public Structure TRIVERTEX
Public x As Int32
Public y As Int32
Public Red As Int16
Public Green As Int16
Public Blue As Int16
Public Alpha As Int16
End Structure

<StructLayout(LayoutKind.Sequential)> _
Public Structure GRADIENT_RECT
Public UpperLeft As Integer
Public LowerRight As Integer
End Structure

<DllImport("msimg32.dll", EntryPoint:="GradientFill")> _
Public Shared Function GradientFillRect(ByVal hdc As IntPtr, _
ByVal pVertex As IntPtr, _
ByVal dwNumVertex As Integer, _
ByRef pMesh As GRADIENT_RECT, _
ByVal dwNumMesh As Integer, _
ByVal dwMode As Long) As Integer
End Function

Private Sub doGradientFill(ByVal iGraphics As Graphics, _
ByVal iSize As Size)
'//--------------------------------------------------
With iGraphics
Dim pTVxVert(2) As TRIVERTEX
Dim pGRtRect As GRADIENT_RECT
pTVxVert(0).x = 0
pTVxVert(0).y = 0
pTVxVert(0).Red = (Color.Green.R)
pTVxVert(0).Green = (Color.Green.G)
pTVxVert(0).Blue = (Color.Green.B)
pTVxVert(0).Alpha = (Color.Green.A)
pTVxVert(1).x = iSize.Width
pTVxVert(1).y = iSize.Height
pTVxVert(1).Red = (Color.Red.R)
pTVxVert(1).Green = (Color.Red.G)
pTVxVert(1).Blue = (Color.Red.B)
pTVxVert(1).Alpha = (Color.Red.A)
pGRtRect.UpperLeft = 0
pGRtRect.LowerRight = 1

Dim pIPrVert As IntPtr =
Marshal.AllocHGlobal(Marshal.SizeOf(pTVxVert))
Call Marshal.StructureToPtr(pTVxVert, pIPrVert, False)
Dim pIPrHDC As IntPtr = iGraphics.GetHdc()
GradientFillRect(pIPrHDC, pIPrVert, 2, pGRtRect, 1,
GRADIENT_FILL_RECT_H)
'GradientFillRect(pIPrHDC, pTVxVert, 2, pGRtRect, 1,
GRADIENT_FILL_RECT_V)
Call iGraphics.ReleaseHdc(pIPrHDC)
End With
End Sub

----------------------------------------------

Unfortunately this does not work as pTVxVert is an array and the size
cannot be calculated correctly. Any ideas?

Many thanks in advance.

Nick.
 
N

NickP

Just noticed 2 things but still can't get it working, just getting a solid
black block rather than gradient.

My API declaration for GradientFillRect includes a "Long" parameter, should
be Integer. Also I was not converting the RGB values to shorts, this is now
being done but still no luck :-(

Oh yeah and my array was 1 too big, not that this shoud effect the output.

Nick.
 
N

NickP

I now have this.... (which doesn't work also)... Even after hardcoding some
colours!

------------------

Private Const GRADIENT_FILL_RECT_H As Long = &H0
Private Const GRADIENT_FILL_RECT_V As Long = &H1

<StructLayout(LayoutKind.Sequential)> _
Public Structure TRIVERTEX
Public x As Int32
Public y As Int32
Public Red As UInt16
Public Green As UInt16
Public Blue As UInt16
Public Alpha As UInt16
End Structure

<StructLayout(LayoutKind.Sequential)> _
Public Structure GRADIENT_RECT
Public UpperLeft As Integer
Public LowerRight As Integer
End Structure

<DllImport("msimg32.dll", EntryPoint:="GradientFill")> _
Public Shared Function GradientFill(ByVal hdc As IntPtr, _
<MarshalAs(UnmanagedType.LPArray, ArraySubType:=UnmanagedType.Struct)> _
ByRef pVertex() As TRIVERTEX, _
ByVal dwNumVertex As Integer, _
ByRef pMesh As GRADIENT_RECT, _
ByVal dwNumMesh As Integer, _
ByVal dwMode As Integer) As Boolean
End Function

Private Sub doGradientFill(ByVal iGraphics As Graphics, _
ByVal iSize As Size)
'//--------------------------------------------------
With iGraphics
Dim pTVxVert(1) As TRIVERTEX
Dim pGRtRect As GRADIENT_RECT
pTVxVert(0).x = 0
pTVxVert(0).y = 0
pTVxVert(0).Red = 0 'ByteToUShort(255)
pTVxVert(0).Green = &HFF00 'ByteToUShort(0)
pTVxVert(0).Blue = 0 'ByteToUShort(0)
pTVxVert(0).Alpha = 0 'ByteToUShort(0)
pTVxVert(1).x = iSize.Width
pTVxVert(1).y = iSize.Height
pTVxVert(1).Red = &HFF00 'ByteToUShort(0)
pTVxVert(1).Green = 0 'ByteToUShort(255)
pTVxVert(1).Blue = 0 'ByteToUShort(0)
pTVxVert(1).Alpha = &HFF00 'ByteToUShort(0)
pGRtRect.UpperLeft = 0
pGRtRect.LowerRight = 1
Dim pIPrHDC As IntPtr = iGraphics.GetHdc()
Console.WriteLine(GradientFill(pIPrHDC, pTVxVert, 2, pGRtRect, 1,
GRADIENT_FILL_RECT_V).ToString)
Call iGraphics.ReleaseHdc(pIPrHDC)
End With
End Sub
------------------

I've tried to add as much marshaling information as I can think of as well
as assuring the signatures are correct but the lack of information with
regard to this method and .NET is upsetting :-(

If anyone else has done this, some info would be great. I'll post this on
the graphics one too just incase.

Nick.
 
N

NickP

Hi Jay,
NOTE: I have not used the API, as I find using .NET's simply & very
flexible.

And also very slow in comparrison. All .net graphics methods are slow in
comparrison. Currently I have a drawing routine that has 1 bottle neck, it
is the drawing of this gradient unfortunately.

I'll check that link out, many thanks :)

Nick.

Jay B. Harlow said:
Nick,
BTW, I do not want to use .Nets gradient fill capabilities, and so far
I have this.
As Stuart asked: Why not??????

.NET has already done all the hard work for you.


If you have an actual need to call the API itself, I would recommend you
start here:

http://pinvoke.net/search.aspx?search=GradientFill&namespace=[All]

NOTE: I have not used the API, as I find using .NET's simply & very
flexible.

--
Hope this helps
Jay B. Harlow [MVP - Outlook]
.NET Application Architect, Enthusiast, & Evangelist
T.S. Bradley - http://www.tsbradley.net


NickP said:
Hi there,

I am trying to use GradientFillRect in a VB.NET application.

Does anyone have any examples of the correct PInvoke signature and
marshaling that I need to perform in order to achieve this?

BTW, I do not want to use .Nets gradient fill capabilities, and so far
I have this.

----------------------------------------------

Private Const GRADIENT_FILL_RECT_H As Long = &H0
Private Const GRADIENT_FILL_RECT_V As Long = &H1

<StructLayout(LayoutKind.Sequential)> _
Public Structure TRIVERTEX
Public x As Int32
Public y As Int32
Public Red As Int16
Public Green As Int16
Public Blue As Int16
Public Alpha As Int16
End Structure

<StructLayout(LayoutKind.Sequential)> _
Public Structure GRADIENT_RECT
Public UpperLeft As Integer
Public LowerRight As Integer
End Structure

<DllImport("msimg32.dll", EntryPoint:="GradientFill")> _
Public Shared Function GradientFillRect(ByVal hdc As IntPtr, _
ByVal pVertex As IntPtr, _
ByVal dwNumVertex As Integer, _
ByRef pMesh As GRADIENT_RECT, _
ByVal dwNumMesh As Integer, _
ByVal dwMode As Long) As Integer
End Function

Private Sub doGradientFill(ByVal iGraphics As Graphics, _
ByVal iSize As Size)
'//--------------------------------------------------
With iGraphics
Dim pTVxVert(2) As TRIVERTEX
Dim pGRtRect As GRADIENT_RECT
pTVxVert(0).x = 0
pTVxVert(0).y = 0
pTVxVert(0).Red = (Color.Green.R)
pTVxVert(0).Green = (Color.Green.G)
pTVxVert(0).Blue = (Color.Green.B)
pTVxVert(0).Alpha = (Color.Green.A)
pTVxVert(1).x = iSize.Width
pTVxVert(1).y = iSize.Height
pTVxVert(1).Red = (Color.Red.R)
pTVxVert(1).Green = (Color.Red.G)
pTVxVert(1).Blue = (Color.Red.B)
pTVxVert(1).Alpha = (Color.Red.A)
pGRtRect.UpperLeft = 0
pGRtRect.LowerRight = 1

Dim pIPrVert As IntPtr =
Marshal.AllocHGlobal(Marshal.SizeOf(pTVxVert))
Call Marshal.StructureToPtr(pTVxVert, pIPrVert, False)
Dim pIPrHDC As IntPtr = iGraphics.GetHdc()
GradientFillRect(pIPrHDC, pIPrVert, 2, pGRtRect, 1,
GRADIENT_FILL_RECT_H)
'GradientFillRect(pIPrHDC, pTVxVert, 2, pGRtRect, 1,
GRADIENT_FILL_RECT_V)
Call iGraphics.ReleaseHdc(pIPrHDC)
End With
End Sub

----------------------------------------------

Unfortunately this does not work as pTVxVert is an array and the size
cannot be calculated correctly. Any ideas?

Many thanks in advance.

Nick.
 
N

NickP

BTW,

I don't see Stuarts reply, I think my outlook express is borked :-(

Jay B. Harlow said:
Nick,
BTW, I do not want to use .Nets gradient fill capabilities, and so far
I have this.
As Stuart asked: Why not??????

.NET has already done all the hard work for you.


If you have an actual need to call the API itself, I would recommend you
start here:

http://pinvoke.net/search.aspx?search=GradientFill&namespace=[All]

NOTE: I have not used the API, as I find using .NET's simply & very
flexible.

--
Hope this helps
Jay B. Harlow [MVP - Outlook]
.NET Application Architect, Enthusiast, & Evangelist
T.S. Bradley - http://www.tsbradley.net


NickP said:
Hi there,

I am trying to use GradientFillRect in a VB.NET application.

Does anyone have any examples of the correct PInvoke signature and
marshaling that I need to perform in order to achieve this?

BTW, I do not want to use .Nets gradient fill capabilities, and so far
I have this.

----------------------------------------------

Private Const GRADIENT_FILL_RECT_H As Long = &H0
Private Const GRADIENT_FILL_RECT_V As Long = &H1

<StructLayout(LayoutKind.Sequential)> _
Public Structure TRIVERTEX
Public x As Int32
Public y As Int32
Public Red As Int16
Public Green As Int16
Public Blue As Int16
Public Alpha As Int16
End Structure

<StructLayout(LayoutKind.Sequential)> _
Public Structure GRADIENT_RECT
Public UpperLeft As Integer
Public LowerRight As Integer
End Structure

<DllImport("msimg32.dll", EntryPoint:="GradientFill")> _
Public Shared Function GradientFillRect(ByVal hdc As IntPtr, _
ByVal pVertex As IntPtr, _
ByVal dwNumVertex As Integer, _
ByRef pMesh As GRADIENT_RECT, _
ByVal dwNumMesh As Integer, _
ByVal dwMode As Long) As Integer
End Function

Private Sub doGradientFill(ByVal iGraphics As Graphics, _
ByVal iSize As Size)
'//--------------------------------------------------
With iGraphics
Dim pTVxVert(2) As TRIVERTEX
Dim pGRtRect As GRADIENT_RECT
pTVxVert(0).x = 0
pTVxVert(0).y = 0
pTVxVert(0).Red = (Color.Green.R)
pTVxVert(0).Green = (Color.Green.G)
pTVxVert(0).Blue = (Color.Green.B)
pTVxVert(0).Alpha = (Color.Green.A)
pTVxVert(1).x = iSize.Width
pTVxVert(1).y = iSize.Height
pTVxVert(1).Red = (Color.Red.R)
pTVxVert(1).Green = (Color.Red.G)
pTVxVert(1).Blue = (Color.Red.B)
pTVxVert(1).Alpha = (Color.Red.A)
pGRtRect.UpperLeft = 0
pGRtRect.LowerRight = 1

Dim pIPrVert As IntPtr =
Marshal.AllocHGlobal(Marshal.SizeOf(pTVxVert))
Call Marshal.StructureToPtr(pTVxVert, pIPrVert, False)
Dim pIPrHDC As IntPtr = iGraphics.GetHdc()
GradientFillRect(pIPrHDC, pIPrVert, 2, pGRtRect, 1,
GRADIENT_FILL_RECT_H)
'GradientFillRect(pIPrHDC, pTVxVert, 2, pGRtRect, 1,
GRADIENT_FILL_RECT_V)
Call iGraphics.ReleaseHdc(pIPrHDC)
End With
End Sub

----------------------------------------------

Unfortunately this does not work as pTVxVert is an array and the size
cannot be calculated correctly. Any ideas?

Many thanks in advance.

Nick.
 
J

Jay B. Harlow [MVP - Outlook]

And also very slow in comparrison.
Slow is a user perception.

For where & how I'm using gradients I don't see/perceive that they are slow.

Although I realize there are places where high performant graphics is
important. Which is where having 3 systems to choose from; GDI, GDI+ or
DirectX is nice...

--
Hope this helps
Jay B. Harlow [MVP - Outlook]
..NET Application Architect, Enthusiast, & Evangelist
T.S. Bradley - http://www.tsbradley.net


NickP said:
Hi Jay,
NOTE: I have not used the API, as I find using .NET's simply & very
flexible.

And also very slow in comparrison. All .net graphics methods are slow in
comparrison. Currently I have a drawing routine that has 1 bottle neck,
it is the drawing of this gradient unfortunately.

I'll check that link out, many thanks :)

Nick.

Jay B. Harlow said:
Nick,
BTW, I do not want to use .Nets gradient fill capabilities, and so
far I have this.
As Stuart asked: Why not??????

.NET has already done all the hard work for you.


If you have an actual need to call the API itself, I would recommend you
start here:

http://pinvoke.net/search.aspx?search=GradientFill&namespace=[All]

NOTE: I have not used the API, as I find using .NET's simply & very
flexible.

--
Hope this helps
Jay B. Harlow [MVP - Outlook]
.NET Application Architect, Enthusiast, & Evangelist
T.S. Bradley - http://www.tsbradley.net


NickP said:
Hi there,

I am trying to use GradientFillRect in a VB.NET application.

Does anyone have any examples of the correct PInvoke signature and
marshaling that I need to perform in order to achieve this?

BTW, I do not want to use .Nets gradient fill capabilities, and so
far I have this.

----------------------------------------------

Private Const GRADIENT_FILL_RECT_H As Long = &H0
Private Const GRADIENT_FILL_RECT_V As Long = &H1

<StructLayout(LayoutKind.Sequential)> _
Public Structure TRIVERTEX
Public x As Int32
Public y As Int32
Public Red As Int16
Public Green As Int16
Public Blue As Int16
Public Alpha As Int16
End Structure

<StructLayout(LayoutKind.Sequential)> _
Public Structure GRADIENT_RECT
Public UpperLeft As Integer
Public LowerRight As Integer
End Structure

<DllImport("msimg32.dll", EntryPoint:="GradientFill")> _
Public Shared Function GradientFillRect(ByVal hdc As IntPtr, _
ByVal pVertex As IntPtr, _
ByVal dwNumVertex As Integer, _
ByRef pMesh As GRADIENT_RECT, _
ByVal dwNumMesh As Integer, _
ByVal dwMode As Long) As Integer
End Function

Private Sub doGradientFill(ByVal iGraphics As Graphics, _
ByVal iSize As Size)
'//--------------------------------------------------
With iGraphics
Dim pTVxVert(2) As TRIVERTEX
Dim pGRtRect As GRADIENT_RECT
pTVxVert(0).x = 0
pTVxVert(0).y = 0
pTVxVert(0).Red = (Color.Green.R)
pTVxVert(0).Green = (Color.Green.G)
pTVxVert(0).Blue = (Color.Green.B)
pTVxVert(0).Alpha = (Color.Green.A)
pTVxVert(1).x = iSize.Width
pTVxVert(1).y = iSize.Height
pTVxVert(1).Red = (Color.Red.R)
pTVxVert(1).Green = (Color.Red.G)
pTVxVert(1).Blue = (Color.Red.B)
pTVxVert(1).Alpha = (Color.Red.A)
pGRtRect.UpperLeft = 0
pGRtRect.LowerRight = 1

Dim pIPrVert As IntPtr =
Marshal.AllocHGlobal(Marshal.SizeOf(pTVxVert))
Call Marshal.StructureToPtr(pTVxVert, pIPrVert, False)
Dim pIPrHDC As IntPtr = iGraphics.GetHdc()
GradientFillRect(pIPrHDC, pIPrVert, 2, pGRtRect, 1,
GRADIENT_FILL_RECT_H)
'GradientFillRect(pIPrHDC, pTVxVert, 2, pGRtRect, 1,
GRADIENT_FILL_RECT_V)
Call iGraphics.ReleaseHdc(pIPrHDC)
End With
End Sub

----------------------------------------------

Unfortunately this does not work as pTVxVert is an array and the size
cannot be calculated correctly. Any ideas?

Many thanks in advance.

Nick.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top