Imports System.Runtime.InteropServices
Imports System.Drawing
Module Module1
Structure PALETTEENTRY
Public peRed As Byte
Public peGreen As Byte
Public peBlue As Byte
Public peFlags As Byte
End Structure
Structure LOGPALETTE
Public palVersion As Short
Public palNumEntries As Integer
End Structure
Public Class Win32
<DllImport("Gdi32.dll", SetLastError:=True)> Shared Function _
CreatePalette(ByVal ptr As IntPtr) As IntPtr
End Function
<DllImport("Gdi32.dll", SetLastError:=True)> Shared Function _
GetNearestPaletteIndex(ByVal hpal As IntPtr, ByVal crColor As Int32) As Integer
End Function
<DllImport("Gdi32.dll")> Shared Function _
DeleteObject(ByVal hObject As IntPtr) As Integer
End Function
End Class
Sub Main()
Dim hPalette As IntPtr
Dim colors(256) As Color
Dim i As Integer
' create grayscale palette as example
For i = 0 To 255
colors(i) = Color.FromArgb(0, i, i, i)
Next
hPalette = CreateWin32Palette(colors, 256)
If Not hPalette.Equals(IntPtr.Zero) Then
Console.WriteLine(GetPaletteIndex(hPalette, Color.FromArgb(0, 127, 127, 127)))
Console.WriteLine(GetPaletteIndex(hPalette, Color.FromArgb(0, 200, 200, 200)))
Console.WriteLine(GetPaletteIndex(hPalette, Color.FromArgb(0, 15, 100, 200)))
ReleaseWin32Palette(hPalette)
End If
End Sub
Public Function CreateWin32Palette(ByVal colors() As Color, ByVal nColors As Integer) As IntPtr
Dim memoryBlock As IntPtr
Dim ptr As IntPtr
Dim address As Int32
Dim nEntrySize As Integer
Dim logPalette As LOGPALETTE
Dim i As Integer
Dim entries(256) As PALETTEENTRY
''''
Dim result As IntPtr
Dim nError As Integer
If nColors < 1 Or nColors > 256 Then
Return IntPtr.Zero
End If
nEntrySize = Marshal.SizeOf(entries(0))
logPalette = New LOGPALETTE
logPalette.palVersion = 768
logPalette.palNumEntries = nColors
memoryBlock = Marshal.AllocHGlobal( _
nColors * nEntrySize + Marshal.SizeOf(logPalette))
For i = 0 To nColors - 1
entries(i).peRed = colors(i).R
entries(i).peGreen = colors(i).G
entries(i).peBlue = colors(i).B
entries(i).peFlags = 0
Next
Marshal.StructureToPtr(logPalette, memoryBlock, False)
address = memoryBlock.ToInt32() + Marshal.SizeOf(logPalette)
For i = 0 To nColors - 1
ptr = New IntPtr(address + i * nEntrySize)
Marshal.StructureToPtr(entries(i), ptr, False)
Next
'Return Win32.CreatePalette(memoryBlock)
result = Win32.CreatePalette(memoryBlock)
nError = Marshal.GetLastWin32Error()
Return result
End Function
Sub ReleaseWin32Palette(ByVal hPalette As IntPtr)
Win32.DeleteObject(hPalette)
End Sub
Function GetPaletteIndex(ByVal hPalette As IntPtr, ByVal color As Color) As Integer
Return Win32.GetNearestPaletteIndex(hPalette, color.ToArgb())
End Function
End Module