]> git.saurik.com Git - wxWidgets.git/blame - src/msw/dibutils.cpp
Add detachmenu
[wxWidgets.git] / src / msw / dibutils.cpp
CommitLineData
2bda0e17
KB
1/////////////////////////////////////////////////////////////////////////////
2// Name: dibutils.cpp
3// Purpose: Utilities for DIBs
4// Author: Julian Smart
5// Modified by:
6// Created: 04/01/98
7// RCS-ID: $Id$
8// Copyright: (c) Microsoft, Julian Smart and Markus Holzem
3f4a0c5b 9// Licence: wxWindows license
2bda0e17
KB
10/////////////////////////////////////////////////////////////////////////////
11
12#ifdef __GNUG__
13#pragma implementation "dibutils.h"
14#endif
15
16// For compilers that support precompilation, includes "wx.h".
17#include "wx/wxprec.h"
18
19#ifdef __BORLANDC__
20#pragma hdrstop
21#endif
22
23#ifndef WX_PRECOMP
2bda0e17
KB
24#include "wx/setup.h"
25#include "wx/defs.h"
2662e49e 26#include "wx/string.h"
2bda0e17
KB
27#endif
28
29#include <windows.h>
30#include <windowsx.h>
31#include <stdio.h>
3f4a0c5b
VZ
32
33#include "wx/msw/dibutils.h"
2bda0e17 34
c455ab93
RR
35#ifdef __WXWINE__
36 #include <module.h>
37#endif
38
2bda0e17 39#if defined(__WIN32__)
ce3ed50d 40#if !defined(__MWERKS__) && !defined(__SALFORDC__)
2bda0e17 41 #include <memory.h> // for _fmemcpy()
17dff81c 42#endif
3f4a0c5b 43 #define _huge
2bda0e17
KB
44#ifndef hmemcpy
45 #define hmemcpy memcpy
46#endif
47#endif
48
49#define BFT_ICON 0x4349 /* 'IC' */
50#define BFT_BITMAP 0x4d42 /* 'BM' */
51#define BFT_CURSOR 0x5450 /* 'PT' */
52
2662e49e 53#ifndef SEEK_CUR
2bda0e17
KB
54/* flags for _lseek */
55#define SEEK_CUR 1
56#define SEEK_END 2
57#define SEEK_SET 0
2662e49e
RR
58#endif
59
60/* Copied from PNGhandler for coompilation with MingW32, RR */
61
62#ifndef GlobalAllocPtr
63#define GlobalPtrHandle(lp) \
64 ((HGLOBAL)GlobalHandle(lp))
65
66#define GlobalLockPtr(lp) \
67 ((BOOL)GlobalLock(GlobalPtrHandle(lp)))
68#define GlobalUnlockPtr(lp) \
69 GlobalUnlock(GlobalPtrHandle(lp))
70
71#define GlobalAllocPtr(flags, cb) \
72 (GlobalLock(GlobalAlloc((flags), (cb))))
73#define GlobalReAllocPtr(lp, cbNew, flags) \
74 (GlobalUnlockPtr(lp), GlobalLock(GlobalReAlloc(GlobalPtrHandle(lp) , (cbNew), (flags))))
75#define GlobalFreePtr(lp) \
76 (GlobalUnlockPtr(lp), (BOOL)GlobalFree(GlobalPtrHandle(lp)))
77#endif
2bda0e17
KB
78
79
80/*
81 * Clear the System Palette so that we can ensure an identity palette
82 * mapping for fast performance.
83 */
84
85void ClearSystemPalette(void)
86{
87 //*** A dummy palette setup
88 struct
89 {
90 WORD Version;
91 WORD NumberOfEntries;
92 PALETTEENTRY aEntries[256];
93 } Palette =
94 {
95 0x300,
96 256
97 };
98
99 HPALETTE ScreenPalette = 0;
100 HDC ScreenDC;
101 int Counter;
102 UINT nMapped = 0;
103 BOOL bOK = FALSE;
104 int nOK = 0;
105
c455ab93 106 // *** Reset everything in the system palette to black
2bda0e17
KB
107 for(Counter = 0; Counter < 256; Counter++)
108 {
109 Palette.aEntries[Counter].peRed = 0;
3f4a0c5b 110 Palette.aEntries[Counter].peGreen = 0;
2bda0e17
KB
111 Palette.aEntries[Counter].peBlue = 0;
112 Palette.aEntries[Counter].peFlags = PC_NOCOLLAPSE;
113 }
114
c455ab93
RR
115 // *** Create, select, realize, deselect, and delete the palette
116#ifdef __WXWINE__
117 ScreenDC = GetDC((HWND)NULL);
118#else
2bda0e17 119 ScreenDC = GetDC(NULL);
c455ab93 120#endif
2bda0e17
KB
121 ScreenPalette = CreatePalette((LOGPALETTE *)&Palette);
122
123 if (ScreenPalette)
124 {
3f4a0c5b
VZ
125 ScreenPalette = SelectPalette(ScreenDC,ScreenPalette,FALSE);
126 nMapped = RealizePalette(ScreenDC);
2bda0e17
KB
127 ScreenPalette = SelectPalette(ScreenDC,ScreenPalette,FALSE);
128 bOK = DeleteObject(ScreenPalette);
129 }
130
c455ab93
RR
131#ifdef __WXWINE__
132 nOK = ReleaseDC((HWND)NULL, ScreenDC);
133#else
2bda0e17 134 nOK = ReleaseDC(NULL, ScreenDC);
c455ab93 135#endif
2bda0e17
KB
136
137 return;
138}
139
140
141/*
142 * Open a DIB file and return a MEMORY DIB, a memory handle containing..
143 *
144 * BITMAP INFO bi
145 * palette data
146 * bits....
147 */
148
837e5743 149int DibWriteFile(LPTSTR szFile, LPBITMAPINFOHEADER lpbi)
2bda0e17 150{
3f4a0c5b
VZ
151 HFILE fh;
152 OFSTRUCT of;
2bda0e17 153
837e5743 154 fh = OpenFile(wxConvFile.cWX2MB(szFile), &of, OF_WRITE | OF_CREATE);
2bda0e17
KB
155
156 if (!fh) {
3f4a0c5b
VZ
157// printf("la regamos0");
158 return 0;
2bda0e17
KB
159 }
160
161 long size = DibSize(lpbi);
162
163 // write file header
164 BITMAPFILEHEADER bmf;
165 bmf.bfType = 'BM';
166 bmf.bfSize = sizeof(bmf) + size;
167 bmf.bfReserved1 = 0;
168 bmf.bfReserved2 = 0;
2662e49e 169 bmf.bfOffBits = sizeof(bmf) + (char FAR*)(DibPtr(lpbi)) - (char FAR*)lpbi;
65fd5cb0 170#if defined( __WATCOMC__) || defined(__VISUALC__) || defined(__SC__) || defined(__SALFORDC__) || defined(__MWERKS__) || defined(wxUSE_NORLANDER_HEADERS)
2bda0e17 171 if (_hwrite(fh, (LPCSTR)(&bmf), sizeof(bmf))<0 ||
3f4a0c5b
VZ
172 _hwrite(fh, (LPCSTR)lpbi, size)<0) {
173 _lclose(fh);
174// printf("la regamos1");
175 return 0;
2bda0e17
KB
176 }
177#else
178 if (_hwrite(fh, (LPBYTE)(&bmf), sizeof(bmf))<0 ||
3f4a0c5b
VZ
179 _hwrite(fh, (LPBYTE)lpbi, size)<0) {
180 _lclose(fh);
181// printf("la regamos1");
182 return 0;
2bda0e17
KB
183 }
184#endif
185
186 _lclose(fh);
187 return 1;
188}
189
837e5743 190PDIB DibOpenFile(LPTSTR szFile)
2bda0e17 191{
3f4a0c5b
VZ
192 HFILE fh;
193 DWORD dwLen;
194 DWORD dwBits;
195 PDIB pdib;
196 LPVOID p;
197 OFSTRUCT of;
2bda0e17
KB
198
199#if defined(WIN32) || defined(_WIN32)
3f4a0c5b 200 #define GetCurrentInstance() GetModuleHandle(NULL)
2bda0e17 201#else
3f4a0c5b 202 #define GetCurrentInstance() (HINSTANCE)SELECTOROF((LPVOID)&of)
2bda0e17
KB
203#endif
204
837e5743 205 fh = OpenFile(wxConvFile.cWX2MB(szFile), &of, OF_READ);
2bda0e17 206
3f4a0c5b
VZ
207 if (fh == -1)
208 {
209 HRSRC h;
2bda0e17
KB
210
211 // TODO: Unicode version
62448488 212#ifdef __WIN16__
3f4a0c5b 213 h = FindResource(GetCurrentInstance(), szFile, RT_BITMAP);
837e5743
OK
214#elif wxUSE_UNICODE
215 h = FindResourceW(GetCurrentInstance(), szFile, RT_BITMAP);
62448488 216#else
3f4a0c5b 217 h = FindResourceA(GetCurrentInstance(), szFile, RT_BITMAP);
62448488 218#endif
2bda0e17 219
62448488 220#if defined(__WIN32__)
3f4a0c5b
VZ
221 //!!! can we call GlobalFree() on this? is it the right format.
222 //!!! can we write to this resource?
223 if (h)
224 return (PDIB)LockResource(LoadResource(GetCurrentInstance(), h));
2bda0e17 225#else
3f4a0c5b
VZ
226 if (h)
227 fh = AccessResource(GetCurrentInstance(), h);
2bda0e17 228#endif
3f4a0c5b 229 }
2bda0e17 230
3f4a0c5b
VZ
231 if (fh == -1)
232 return NULL;
2bda0e17 233
3f4a0c5b 234 pdib = DibReadBitmapInfo(fh);
2bda0e17 235
3f4a0c5b
VZ
236 if (!pdib)
237 return NULL;
2bda0e17
KB
238
239 /* How much memory do we need to hold the DIB */
240
241 dwBits = pdib->biSizeImage;
242 dwLen = pdib->biSize + DibPaletteSize(pdib) + dwBits;
243
244 /* Can we get more memory? */
245
3f4a0c5b 246 p = GlobalReAllocPtr(pdib,dwLen,0);
2bda0e17
KB
247
248 if (!p)
249 {
3f4a0c5b 250 GlobalFreePtr(pdib);
2bda0e17
KB
251 pdib = NULL;
252 }
253 else
254 {
255 pdib = (PDIB)p;
256 }
257
258 if (pdib)
259 {
3f4a0c5b
VZ
260 /* read in the bits */
261 _hread(fh, (LPBYTE)pdib + (UINT)pdib->biSize + DibPaletteSize(pdib), dwBits);
2bda0e17
KB
262 }
263
264 _lclose(fh);
265
266 return pdib;
267}
268
269
270/*
271 * ReadDibBitmapInfo()
272 *
273 * Will read a file in DIB format and return a global HANDLE to its
274 * BITMAPINFO. This function will work with both "old" and "new"
275 * bitmap formats, but will always return a "new" BITMAPINFO.
276 */
277
278PDIB DibReadBitmapInfo(HFILE fh)
279{
280 DWORD off;
2bda0e17
KB
281 int size;
282 int i;
283 int nNumColors;
284
285 RGBQUAD FAR *pRgb;
286 BITMAPINFOHEADER bi;
287 BITMAPCOREHEADER bc;
288 BITMAPFILEHEADER bf;
289 PDIB pdib;
290
291 if (fh == -1)
292 return NULL;
293
294 off = _llseek(fh,0L,SEEK_CUR);
295
296 if (sizeof(bf) != _lread(fh,(LPSTR)&bf,sizeof(bf)))
297 return FALSE;
298
299 /*
300 * do we have a RC HEADER?
301 */
302 if (bf.bfType != BFT_BITMAP)
303 {
304 bf.bfOffBits = 0L;
305 _llseek(fh,off,SEEK_SET);
306 }
307
308 if (sizeof(bi) != _lread(fh,(LPSTR)&bi,sizeof(bi)))
309 return FALSE;
310
311 /*
312 * what type of bitmap info is this?
313 */
314 switch (size = (int)bi.biSize)
315 {
316 default:
317 case sizeof(BITMAPINFOHEADER):
318 break;
319
320 case sizeof(BITMAPCOREHEADER):
321 bc = *(BITMAPCOREHEADER*)&bi;
322 bi.biSize = sizeof(BITMAPINFOHEADER);
323 bi.biWidth = (DWORD)bc.bcWidth;
324 bi.biHeight = (DWORD)bc.bcHeight;
325 bi.biPlanes = (UINT)bc.bcPlanes;
326 bi.biBitCount = (UINT)bc.bcBitCount;
327 bi.biCompression = BI_RGB;
328 bi.biSizeImage = 0;
329 bi.biXPelsPerMeter = 0;
330 bi.biYPelsPerMeter = 0;
331 bi.biClrUsed = 0;
332 bi.biClrImportant = 0;
333
334 _llseek(fh,(LONG)sizeof(BITMAPCOREHEADER)-sizeof(BITMAPINFOHEADER),SEEK_CUR);
335
336 break;
337 }
338
339 nNumColors = DibNumColors(&bi);
340
341#if 0
342 if (bi.biSizeImage == 0)
343 bi.biSizeImage = DibSizeImage(&bi);
344
345 if (bi.biClrUsed == 0)
346 bi.biClrUsed = DibNumColors(&bi);
347#else
348 FixBitmapInfo(&bi);
349#endif
350
351 pdib = (PDIB)GlobalAllocPtr(GMEM_MOVEABLE,(LONG)bi.biSize + nNumColors * sizeof(RGBQUAD));
352
353 if (!pdib)
354 return NULL;
355
356 *pdib = bi;
357
358 pRgb = DibColors(pdib);
359
360 if (nNumColors)
361 {
362 if (size == sizeof(BITMAPCOREHEADER))
363 {
364 /*
365 * convert a old color table (3 byte entries) to a new
366 * color table (4 byte entries)
367 */
368 _lread(fh,(LPVOID)pRgb,nNumColors * sizeof(RGBTRIPLE));
369
370 for (i=nNumColors-1; i>=0; i--)
371 {
372 RGBQUAD rgb;
373
374 rgb.rgbRed = ((RGBTRIPLE FAR *)pRgb)[i].rgbtRed;
375 rgb.rgbBlue = ((RGBTRIPLE FAR *)pRgb)[i].rgbtBlue;
376 rgb.rgbGreen = ((RGBTRIPLE FAR *)pRgb)[i].rgbtGreen;
377 rgb.rgbReserved = (BYTE)0;
378
379 pRgb[i] = rgb;
380 }
381 }
382 else
383 {
384 _lread(fh,(LPVOID)pRgb,nNumColors * sizeof(RGBQUAD));
385 }
386 }
387
388 if (bf.bfOffBits != 0L)
389 _llseek(fh,off + bf.bfOffBits,SEEK_SET);
390
391 return pdib;
392}
393
394/*
395 * DibSetUsage(hdib,hpal,wUsage)
396 *
397 * Modifies the color table of the passed DIB for use with the wUsage
398 * parameter specifed.
399 *
400 * if wUsage is DIB_PAL_COLORS the DIB color table is set to 0-256
401 * if wUsage is DIB_RGB_COLORS the DIB color table is set to the RGB values
402 * in the passed palette
403 */
404
405BOOL DibSetUsage(PDIB pdib, HPALETTE hpal,UINT wUsage)
406{
407 PALETTEENTRY ape[256];
408 RGBQUAD FAR * pRgb;
409 WORD FAR * pw;
410 int nColors;
411 int n;
412
413 if (hpal == NULL)
414 hpal = (HPALETTE)GetStockObject(DEFAULT_PALETTE);
415
416 if (!pdib)
417 return FALSE;
418
419 nColors = DibNumColors(pdib);
420
421 if (nColors == 3 && DibCompression(pdib) == BI_BITFIELDS)
422 nColors = 0;
423
424 if (nColors > 0)
425 {
426 pRgb = DibColors(pdib);
427
428 switch (wUsage)
429 {
430 //
431 // Set the DIB color table to palette indexes
432 //
433 case DIB_PAL_COLORS:
434 for (pw = (WORD FAR*)pRgb,n=0; n<nColors; n++,pw++)
435 *pw = n;
436 break;
437
438 //
439 // Set the DIB color table to RGBQUADS
440 //
441 default:
442 case DIB_RGB_COLORS:
443 nColors = (nColors < 256) ? nColors: 256;
444
445 GetPaletteEntries(hpal,0,nColors,ape);
446
447 for (n=0; n<nColors; n++)
448 {
449 pRgb[n].rgbRed = ape[n].peRed;
450 pRgb[n].rgbGreen = ape[n].peGreen;
451 pRgb[n].rgbBlue = ape[n].peBlue;
452 pRgb[n].rgbReserved = 0;
453 }
454 break;
455 }
456 }
457 return TRUE;
458}
459
460/*
461 * DibCreate(bits, dx, dy)
462 *
463 * Creates a new packed DIB with the given dimensions and the
464 * given number of bits per pixel
465 */
466
467PDIB DibCreate(int bits, int dx, int dy)
468{
469 LPBITMAPINFOHEADER lpbi ;
470 DWORD dwSizeImage;
471 int i;
472 DWORD FAR *pdw;
473
474 dwSizeImage = dy*(DWORD)((dx*bits/8+3)&~3);
475
476 lpbi = (PDIB)GlobalAllocPtr(GHND,sizeof(BITMAPINFOHEADER)+dwSizeImage + 1024);
477
478 if (lpbi == NULL)
479 return NULL;
480
481 lpbi->biSize = sizeof(BITMAPINFOHEADER) ;
482 lpbi->biWidth = dx;
483 lpbi->biHeight = dy;
484 lpbi->biPlanes = 1;
485 lpbi->biBitCount = bits ;
486 lpbi->biCompression = BI_RGB ;
487 lpbi->biSizeImage = dwSizeImage;
488 lpbi->biXPelsPerMeter = 0 ;
489 lpbi->biYPelsPerMeter = 0 ;
490 lpbi->biClrUsed = 0 ;
491 lpbi->biClrImportant = 0 ;
492
493 if (bits == 4)
494 lpbi->biClrUsed = 16;
495
496 else if (bits == 8)
497 lpbi->biClrUsed = 256;
498
499 pdw = (DWORD FAR *)((LPBYTE)lpbi+(int)lpbi->biSize);
500
501 for (i=0; i<(int)lpbi->biClrUsed/16; i++)
502 {
503 *pdw++ = 0x00000000; // 0000 black
504 *pdw++ = 0x00800000; // 0001 dark red
505 *pdw++ = 0x00008000; // 0010 dark green
3f4a0c5b 506 *pdw++ = 0x00808000; // 0011 mustard
2bda0e17
KB
507 *pdw++ = 0x00000080; // 0100 dark blue
508 *pdw++ = 0x00800080; // 0101 purple
509 *pdw++ = 0x00008080; // 0110 dark turquoise
510 *pdw++ = 0x00C0C0C0; // 1000 gray
511 *pdw++ = 0x00808080; // 0111 dark gray
512 *pdw++ = 0x00FF0000; // 1001 red
513 *pdw++ = 0x0000FF00; // 1010 green
3f4a0c5b 514 *pdw++ = 0x00FFFF00; // 1011 yellow
2bda0e17
KB
515 *pdw++ = 0x000000FF; // 1100 blue
516 *pdw++ = 0x00FF00FF; // 1101 pink (magenta)
517 *pdw++ = 0x0000FFFF; // 1110 cyan
518 *pdw++ = 0x00FFFFFF; // 1111 white
519 }
520
521 return (PDIB)lpbi;
522}
523
524static void xlatClut8(BYTE FAR *pb, DWORD dwSize, BYTE FAR *xlat)
525{
526 DWORD dw;
527
528#ifdef __cplusplus
529 for (dw = 0; dw < dwSize; dw++, ((BYTE _huge *&)pb)++)
530#else
531 for (dw = 0; dw < dwSize; dw++, ((BYTE _huge *)pb)++)
532#endif
533 *pb = xlat[*pb];
534}
535
536static void xlatClut4(BYTE FAR *pb, DWORD dwSize, BYTE FAR *xlat)
537{
538 DWORD dw;
539
540#ifdef __cplusplus
541 for (dw = 0; dw < dwSize; dw++, ((BYTE _huge *&)pb)++)
542#else
543 for (dw = 0; dw < dwSize; dw++, ((BYTE _huge *)pb)++)
544#endif
545 *pb = (BYTE)(xlat[*pb & 0x0F] | (xlat[(*pb >> 4) & 0x0F] << 4));
546}
547
548#define RLE_ESCAPE 0
549#define RLE_EOL 0
550#define RLE_EOF 1
551#define RLE_JMP 2
552
553static void xlatRle8(BYTE FAR *pb, DWORD dwSize, BYTE FAR *xlat)
554{
555 BYTE cnt;
556 BYTE b;
557 BYTE _huge *prle = pb;
558
559 for(;;)
560 {
561 cnt = *prle++;
562 b = *prle;
563
564 if (cnt == RLE_ESCAPE)
565 {
566 prle++;
567
568 switch (b)
569 {
570 case RLE_EOF:
571 return;
572
573 case RLE_EOL:
574 break;
575
576 case RLE_JMP:
577 prle++; // skip dX
578 prle++; // skip dY
579 break;
580
581 default:
582 cnt = b;
583 for (b=0; b<cnt; b++,prle++)
584 *prle = xlat[*prle];
585
586 if (cnt & 1)
587 prle++;
588
589 break;
590 }
591 }
592 else
593 {
594 *prle++ = xlat[b];
595 }
596 }
597}
598
599static void xlatRle4(BYTE FAR *pb, DWORD dwSize, BYTE FAR *xlat)
600{
601}
602
603static void hmemmove(BYTE _huge *d, BYTE _huge *s, LONG len)
604{
605 d += len-1;
606 s += len-1;
607
608 while (len--)
609 *d-- = *s--;
610}
611
612/*
613 * DibMapToPalette(pdib, hpal)
614 *
615 * Map the colors of the DIB, using GetNearestPaletteIndex, to
616 * the colors of the given palette.
617 */
618
619BOOL DibMapToPalette(PDIB pdib, HPALETTE hpal)
620{
3f4a0c5b
VZ
621 LPBITMAPINFOHEADER lpbi;
622 PALETTEENTRY pe;
623 int n;
624 int nDibColors;
625 int nPalColors=0;
626 BYTE FAR * lpBits;
627 RGBQUAD FAR * lpRgb;
628 BYTE xlat[256];
629 DWORD SizeImage;
630
631 if (!hpal || !pdib)
632 return FALSE;
633
634 lpbi = (LPBITMAPINFOHEADER)pdib;
635 lpRgb = DibColors(pdib);
636
637 GetObject(hpal,sizeof(int),(LPSTR)&nPalColors);
638 nDibColors = DibNumColors(pdib);
639
640 if ((SizeImage = lpbi->biSizeImage) == 0)
641 SizeImage = DibSizeImage(lpbi);
642
643 //
644 // build a xlat table. from the current DIB colors to the given
645 // palette.
646 //
647 for (n=0; n<nDibColors; n++)
648 xlat[n] = (BYTE)GetNearestPaletteIndex(hpal,RGB(lpRgb[n].rgbRed,lpRgb[n].rgbGreen,lpRgb[n].rgbBlue));
649
650 lpBits = (LPBYTE)DibPtr(lpbi);
651 lpbi->biClrUsed = nPalColors;
652
653 //
654 // re-size the DIB
655 //
656 if (nPalColors > nDibColors)
657 {
658 GlobalReAllocPtr(lpbi, lpbi->biSize + nPalColors*sizeof(RGBQUAD) + SizeImage, 0);
659 hmemmove((BYTE _huge *)DibPtr(lpbi), (BYTE _huge *)lpBits, SizeImage);
660 lpBits = (LPBYTE)DibPtr(lpbi);
661 }
662 else if (nPalColors < nDibColors)
663 {
664 hmemcpy(DibPtr(lpbi), lpBits, SizeImage);
665 GlobalReAllocPtr(lpbi, lpbi->biSize + nPalColors*sizeof(RGBQUAD) + SizeImage, 0);
666 lpBits = (LPBYTE)DibPtr(lpbi);
667 }
668
669 //
670 // translate the DIB bits
671 //
672 switch (lpbi->biCompression)
673 {
674 case BI_RLE8:
675 xlatRle8(lpBits, SizeImage, xlat);
676 break;
677
678 case BI_RLE4:
679 xlatRle4(lpBits, SizeImage, xlat);
680 break;
2bda0e17
KB
681
682 case BI_RGB:
3f4a0c5b 683 if (lpbi->biBitCount == 8)
2bda0e17
KB
684 xlatClut8(lpBits, SizeImage, xlat);
685 else
686 xlatClut4(lpBits, SizeImage, xlat);
687 break;
688 }
689
690 //
691 // Now copy the RGBs in the logical palette to the dib color table
692 //
693 for (n=0; n<nPalColors; n++)
694 {
695 GetPaletteEntries(hpal,n,1,&pe);
696
697 lpRgb[n].rgbRed = pe.peRed;
3f4a0c5b
VZ
698 lpRgb[n].rgbGreen = pe.peGreen;
699 lpRgb[n].rgbBlue = pe.peBlue;
700 lpRgb[n].rgbReserved = (BYTE)0;
701 }
2bda0e17 702
3f4a0c5b 703 return TRUE;
2bda0e17
KB
704}
705
706
707HPALETTE MakePalette(const BITMAPINFO FAR* Info, UINT flags)
708{
709 HPALETTE hPalette;
2662e49e 710 const RGBQUAD FAR* rgb = Info->bmiColors;
2bda0e17
KB
711
712 WORD nColors = Info->bmiHeader.biClrUsed;
713 if (nColors) {
3f4a0c5b
VZ
714 LOGPALETTE* logPal = (LOGPALETTE*)
715 new BYTE[sizeof(LOGPALETTE) + (nColors-1)*sizeof(PALETTEENTRY)];
716
717 logPal->palVersion = 0x300; // Windows 3.0 version
718 logPal->palNumEntries = nColors;
48c12cb1 719 for (WORD n = 0; n < nColors; n++) {
3f4a0c5b
VZ
720 logPal->palPalEntry[n].peRed = rgb[n].rgbRed;
721 logPal->palPalEntry[n].peGreen = rgb[n].rgbGreen;
722 logPal->palPalEntry[n].peBlue = rgb[n].rgbBlue;
723 logPal->palPalEntry[n].peFlags = (BYTE)flags;
724 }
725 hPalette = ::CreatePalette(logPal);
726 delete logPal;
2bda0e17 727 } else
3f4a0c5b 728 hPalette = 0;
2bda0e17
KB
729
730 return hPalette;
731}
732