Using GetSystemPaletteEntries

  • Thread starter Thread starter Just Me
  • Start date Start date
J

Just Me

I've been trying to debug this but when it executes GetSystemPaletteEntries
it bombs. I mean it just dies.

I set a breakpoint an try to get QuickWatch to evaluate
GetSystemPaletteEntries(...) and it say - Evaluation stopped..



Any ideas?



Thanks

Dim lHDCMemory As IntPtr

Dim lHBmp As IntPtr

Dim lHPal As IntPtr

Dim lHBmpPrev As IntPtr

Dim lHPalPrev As IntPtr

Dim lHDCSrc As IntPtr

Dim lRasterCapabilities As Integer

Dim lHasPalette As Boolean

Dim lPaletteSize As Integer

Dim lLogPal As GDI.LOGPALETTE

lHDCSrc = User.GetWindowDC(hWndSrc)

lHDCMemory = GDI.CreateCompatibleDC(lHDCSrc)

lHBmp = GDI.CreateCompatibleBitmap(lHDCSrc, widthSrc, heightSrc)

lHBmpPrev = GDI.SelectObject(lHDCMemory, lHBmp)

lRasterCapabilities = GDI.GetDeviceCaps(lHDCSrc, GDI.RASTERCAPS)

lHasPalette = (lRasterCapabilities And GDI.RC_PALETTE) = GDI.RC_PALETTE

lPaletteSize = GDI.GetDeviceCaps(lHDCSrc, User.SIZEPALETTE)

If lHasPalette AndAlso (lPaletteSize = 256) Then

lLogPal.palVersion = &H300S

lLogPal.palNumEntries = 256

ReDim lLogPal.palPalEntry(255)

Try

Dim zz As Integer = GDI.GetSystemPaletteEntries(lHDCSrc, 0, 256,
lLogPal.palPalEntry)

Catch ex As Exception

Console.WriteLine(ex.ToString)

End Try
 
I've been trying to debug this but when it executes GetSystemPaletteEntries
it bombs. I mean it just dies.

How did you declare the functions and structures?




Mattias
 
Played around a little with Pack= since I don't know what it does for sure
and couldn't find out using Help

Most of my code is VB but I also have a C# library

I'm confused about the ByValArray, since I expect a return it seems like it
should be ByRefArray but that does not exists.
// [StructLayout(LayoutKind.Sequential, Pack=1, CharSet=CharSet.Auto)]

public struct PALETTEENTRY

{

public byte peRed;

public byte peGreen;

public byte peBlue;

public byte peFlags;

}

//[StructLayout(LayoutKind.Sequential, Pack=2, CharSet=CharSet.Auto)]

public struct LOGPALETTE

{

public short palVersion;

public short palNumEntries;

[MarshalAs(UnmanagedType.ByValArray, SizeConst=256)] public PALETTEENTRY[]
palPalEntry;

}


[DllImport("gdi32", CharSet=CharSet.Auto)] public static extern int
GetSystemPaletteEntries(HDC hdc, int wStartIndex, int wNumEntries, ref
PALETTEENTRY[] lpPaletteEntries);
 
[MarshalAs(UnmanagedType.ByValArray, SizeConst=256)] public PALETTEENTRY[]
palPalEntry;

Unfortunately the marshaler doesn't support struct arrays inside other
structs.



Mattias
 
are you saying this can't be done?

Mattias Sjögren said:
[MarshalAs(UnmanagedType.ByValArray, SizeConst=256)] public
PALETTEENTRY[]
palPalEntry;

Unfortunately the marshaler doesn't support struct arrays inside other
structs.



Mattias
 
are you saying this can't be done?

No, just taht it takes a bit more work and isn't as convenient as it
should be.

You typically have to allocate an unmanaged memory buffer
(Marshal.Alloc*) and pass that to the API you're calling. Then use
Marshal.PtrToStructure to retrieve the PALETTEENTRY structs one by
one.



Mattias
 
While waiting for your help I tried the following. It stopped the bombing
but the resulting display looks like the palette is wrong.

BTW palPalEntry0 = 0 and palPalEntry1=128 the rest look like they might be
OK

Does this look like it ought to work?
I could move to your suggestion but hate to leave this without knowing why
it does work?

[DllImport("gdi32", CharSet=CharSet.Auto)] public static extern int
GetSystemPaletteEntries(HDC hdc, int wStartIndex, int wNumEntries,ref
PALETTEENTRY lpPaletteEntries);

lPaletteSize = GDI.GetSystemPaletteEntries(lHDCSrc, 0, 256,
lLogPal.palPalEntry0)



[StructLayout(LayoutKind.Sequential, Pack=2, CharSet=CharSet.Auto)]

public struct LOGPALETTE

{

public short palVersion;

public short palNumEntries;

public PALETTEENTRY palPalEntry0;

public PALETTEENTRY palPalEntry1;

public PALETTEENTRY palPalEntry2;

....
public int palPalEntry254;

public int palPalEntry255;

}
 
Revised

While waiting for your help I tried the following. It stopped the bombing
but the resulting display looks like the palette is wrong.

BTW palPalEntry0 = 0 and palPalEntry1=128 the rest look like they might be
OK - maybe the 0th entry is black?

Does this look like it should be to working? I don't use the colors, simply
pass the log palette to CreatPalette. (I could move on to your suggestion
but hate to leave this without knowing why
it does work?)

[DllImport("gdi32", CharSet=CharSet.Auto)] public static extern int
GetSystemPaletteEntries(HDC hdc, int wStartIndex, int wNumEntries,
uint lpPaletteEntries); //REMOVED THE ref

lPaletteSize = GDI.GetSystemPaletteEntries(lHDCSrc, 0, 256,
lLogPal.palPalEntry0)

USED AN ARRAY OF uint
[StructLayout(LayoutKind.Sequential, Pack=2, CharSet=CharSet.Auto)]
public struct LOGPALETTE

{

public short palVersion;

public short palNumEntries;

[MarshalAs(UnmanagedType.ByValArray, SizeConst=256)] public uint[]
palPalEntry;

}
 

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

Back
Top