Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
28710 Discussions

How can I create a LOGPALETTE structure with more than 1 PALETTEENTRY?

algraham
Beginner
1,218 Views
In order to display an 8-bit color-mapped BMP image with 256 entries in the color map, I need to create a LOGPALETTE structure and load the 256 colors from the BMP color map into the PALETTEENTRY array in the LOGPALETTE structure. However, the Intel Fortran T_LOGPALETTE structure is defined with its PALETTEENTRY array dimensioned at one element, and I can't figure out how to enlarge the PALETTEENTRY array to accomodate 256 elements. I have tried various methods involving allocating memory and overlaying the LOGPALETTE structure over it with pointers, but nothing seems to work. I would be grateful if someone could show me how to do this.

Thanks
algraham
0 Kudos
6 Replies
Paul_Curtis
Valued Contributor I
1,218 Views
Here is a code snippet from a routine which saves the screen to a bmp file:

[cpp]TYPE(T_PALETTEENTRY),DIMENSION(256) :: pe[/cpp]

[cpp]!	instead of using the LOGPALETTE type, simply block out
!	some memory and accomplish the same thing, only this allows
!	the paletteentry() array to be associated with a varying 
!	number of colors
IF (IAND(GetDeviceCaps (hdc, RASTERCAPS), RC_PALETTE) > 0) THEN
	lp = MALLOC (8 + 256*SIZEOF(pe(1)))
	rval = #300					! palVersion
	CALL CopyMemory (LOC(lp), LOC(rval), 4)
	rval = GetSystemPaletteEntries (hdc, 0, 255, pe(1))
	CALL CopyMemory (LOC(lp)+4, LOC(rval), 4)		! palNumEntries
	CALL CopyMemory (LOC(lp)+8, LOC(pe(1)), 256*SIZEOF(pe(1)))
	hpal = CreatePalette (lp)
	CALL FREE (lp)
ELSE
	hpal = GetStockObject (DEFAULT_PALETTE)
END IF
[/cpp]

I can provide the entire module if needed. HTH
0 Kudos
algraham
Beginner
1,218 Views
Quoting - algraham

Sorry - wrong mouse click posted empty reply.

I find that when I pass the pointer lp to the CreatePalette function it fails with an "The type of the actual argument differs from the type of the dummy argument" error. CreatePalette will only accept a logpalette structure as an argument.

I am trying to read in an 8-bit color-mapped bmp file and display it. I allocate a memory buffer and load it with the colormap data. I overlay the logpalette structure on the memory buffer using a pointer and then pass the logpalette structure to CreatePalette, which seems to work. I then select the palette into the device context, realize the palette, select the bitmap into the device context, and call stretchblt. The result is a completely black screen, which suggests that the palette is not getting there.

I also notice that the call to RealizePalette returns zero, suggesting that it cannot realize the palette, and the call to IAND (GetDeviceCaps(hDC,RASTERCAPS), RC_PALETTE)>0 returns false, suggesting that palette operations are not supported. However, I have a C++ program running on the same machine that does the same thing, and it works fine. I am totally confused.

Here is my code:

type(T_LOGPALETTE) logPal !allocatable logpalette structure to hold colour palatte

integer(byte) parray(1032)
pointer(lpPalette,logPal)
pointer(lpPalette,parray)

lpPalette = MALLOC(size)
logPal%palVersion = #300
logPal%palNumEntries = numColours

j = 1 !index into parray
do i=1, numColours
j = j + 4 !load parray with colours starting at 5th element (first 4 bytes are palVersion and palNumEntries
parray(j) = colorMap(i)%rgbRed
parray(j+1) = colorMap(i)%rgbGreen
parray(j+2) = colorMap(i)%rgbBlue
parray(j+3) = 0
enddo

hPalette = CreatePalette(logPal) !create a logical palette

if (hPalette .ne. 0) Then
hOldPalette = MSFWIN$SelectPalette(hScrDC, hPalette, 0) !select the palette into the screen device context
iret = RealizePalette(hScrDC) !copy the palette into the device's system palette
hOldMemPalette = MSFWIN$SelectPalette(hMemDC, hPalette, 0) !select the palette into the memory device context
iret = RealizePalette(hMemDC) !copy the palette into the memory dc palette
endif

hBitmap = CreateDIBitmap(hMemDC,pBMIH,CBM_INIT,pBits,pBMI,DIB_RGB_COLORS) !create a compatibile bitmap
hOldBitMap = SelectObject(hMemDC,hBitmap) !select our compatible bitmap into the memory device context

!copy the memory DC to the screen DC
iret = StretchBlt(hScrDC,rect.left,rect.top,rect.right,rect.bottom,hMemDC,0,0,iw,ih,SRCCOPY)

If you can see anything obviously wrong with this, or if you have an example of how to display a color-mapped bmp image that would be fantastic.

Thanks very much
0 Kudos
Paul_Curtis
Valued Contributor I
1,218 Views
Quoting - algraham
I find that when I pass the pointer lp to the CreatePalette function it fails with an "The type of the actual argument differs from the type of the dummy argument" error. CreatePalette will only accept a logpalette structure as an argument.



[cpp]!	custom interface to CreatePalette to pass the arg as an integer LOC()
!	passed by value instead of GDI32's version where the argument is a TYPE
!	passed by reference
INTERFACE 
	FUNCTION CreatePalette (arg1)
		USE ifwinTY
		integer(HANDLE) :: CreatePalette ! HPALETTE
		!DEC$ ATTRIBUTES DEFAULT, STDCALL, DECORATE,    &
ALIAS:'CreatePalette' :: CreatePalette integer(LPVOID) arg1 ! LPLOGPALETTE arg1 END FUNCTION END INTERFACE [/cpp]

0 Kudos
algraham
Beginner
1,218 Views
Quoting - Paul Curtis
Thanks very much. However, this creates a conflict between the interface definition for CreatePalette and the CreatePalette in the gdi32 library, which so far I haven't figured out how to resolve. You mentioned that you could provide a complete module - that might help me to see how it works (I am new to Intel Fortran after years in Visual C++).
0 Kudos
Paul_Curtis
Valued Contributor I
1,218 Views
Quoting - algraham
... this creates a conflict between the interface definition for CreatePalette and the CreatePalette in the gdi32 library, which so far I haven't figured out how to resolve.

Here is how you resolve such conflicts:

[cpp]USE GDI32, Ignore_cp => CreatePalette[/cpp]

This renames the GDI32 API function to Ignore_cp, so you can then provide your own interface.
0 Kudos
algraham
Beginner
1,218 Views
Quoting - Paul Curtis

Here is how you resolve such conflicts:

[cpp]USE GDI32, Ignore_cp => CreatePalette[/cpp]

This renames the GDI32 API function to Ignore_cp, so you can then provide your own interface.

That's fantastic - thanks a lot.
0 Kudos
Reply