1 //* Written by Microsoft Product Support Services, Windows Developer Support. *
2 //*****************************************************************************
3 // (C) Copyright Microsoft Corp. 1993. All rights reserved.
4 // You have a royalty-free right to use, modify, reproduce and
5 // distribute the Sample Files (and/or any modified version) in
6 // any way you find useful, provided that you agree that
7 // Microsoft has no warranty obligations or liability for any
8 // Sample Application Files which are modified.
10 // Modified by Petr Smilauer, March 1994 for wxWin library purposes!
12 // For compilers that support precompilation, includes "wx.h".
13 #include "wx/wxprec.h"
22 #if defined(__MWERKS__)
29 #include "wx/msw/gnuwin32/extra.h"
33 #include "wx/msw/curicop.h"
34 #include "wx/msw/curico.h"
35 #include "wx/wxchar.h"
36 #include "wx/string.h"
38 //*****************************************************************************
39 //* Function : ReadIconFile() *
40 //* Purpose : Reads an icon resource file and creates an icon based on that *
42 //* Parameters : char *szFileName - The icon resource file. *
43 //* Returns : A handle to an icon. The handle will be NULL if an icon cannot *
44 //* be created for any reason. *
45 //*****************************************************************************
47 HICON
ReadIconFile( wxChar
*szFileName
, HINSTANCE hInst
, int *W
, int *H
)
51 if( (hDIB
= ReadIcon(szFileName
, W
, H
)) == (HANDLE
) NULL
)
52 // read the icon DIB from file
54 hIcon
= MakeIcon( hDIB
, hInst
); // create an icon from DIB
59 //*****************************************************************************
60 //* Function : CursorToIcon() *
61 //* Purpose : Reads a cursor resource file and creates an icon based on that *
63 //* Parameters : char *szFileName - The cursor resource file. *
64 //* Returns : A handle to an icon. The handle will be NULL if an icon cannot *
65 //* be created for any reason. *
66 //* Comments : A cursor is monochrome. So, the resulting icon will also be *
68 //*****************************************************************************
70 HICON
CursorToIcon( wxChar
*szFileName
, HINSTANCE hInst
, int *W
, int *H
)
71 { HANDLE hDIB
; // Handle to DIB memory
72 HICON hIcon
; // Handle to Icon
74 if( (hDIB
= ReadCur( szFileName
, NULL
, W
, H
)) == (HANDLE
) NULL
)
77 hIcon
= MakeIcon( hDIB
, hInst
); // make icon from cursor DIB
82 //*****************************************************************************
83 //* Function : ReadIcon() *
84 //* Purpose : Reads an icon resource file and extracts the DIB information. *
85 //* Parameters : char *szFileName - The icon resource file. *
86 //* Returns : A handle to a DIB. The handle will be NULL if the resource file*
87 //* is corrupt or if memory cannot be allocated for the DIB info. *
88 //*****************************************************************************
90 HANDLE
ReadIcon( wxChar
*szFileName
, int *W
, int *H
)
91 { ICONFILEHEADER iconFileHead
; // ICON file header structure
92 ICONFILERES iconFileRes
; // ICON file resource
95 cbBits
; // Used for reading in file
96 int hFile
; // File handle
97 LPBITMAPINFO lpDIB
; // Pointer to DIB memory
99 int nWidth
= GetSystemMetrics( SM_CXICON
),
100 nHeight
= GetSystemMetrics( SM_CYICON
),
103 // Open and read the .ICO file header and the first ICONFILERES
104 hFile
= _lopen( wxFNCONV(szFileName
), OF_READ
);
105 cbHead
= _lread( hFile
, (LPSTR
)&iconFileHead
, sizeof(ICONFILEHEADER
));
106 cbRes
= _lread( hFile
, (LPSTR
)&iconFileRes
, sizeof(ICONFILERES
));
109 if((cbHead
!= sizeof( ICONFILEHEADER
)) || (cbRes
!= sizeof( ICONFILERES
)))
110 return (HANDLE
) NULL
;
111 // Verify that it's an .ICON file
112 if( iconFileHead
.wResourceType
!= 1)
113 return (HANDLE
) NULL
;
116 while( (nDirEntries
< iconFileHead
.wResourceCount
) &&
117 ((iconFileRes
.bWidth
!= nWidth
) || (iconFileRes
.bHeight
!= nHeight
)))
119 cbRes
= _lread( hFile
, (LPSTR
)&iconFileRes
, sizeof( ICONFILERES
));
120 if(cbRes
!= sizeof( ICONFILERES
))
121 return (HANDLE
) NULL
;
127 *W
= iconFileRes
.bWidth
;
129 *H
= iconFileRes
.bHeight
;
131 // Allocate and lock memory to read in the DIB
132 hDIB
= GlobalAlloc(GHND
, iconFileRes
.dwDIBSize
);
133 if(hDIB
== (HANDLE
) NULL
)
134 return (HANDLE
) NULL
;
136 #ifdef __WINDOWS_386__
137 lpDIB
= (LPBITMAPINFO
)MK_FP32(GlobalLock(hDIB
));
139 lpDIB
= (LPBITMAPINFO
)GlobalLock(hDIB
);
142 // Now read the DIB portion of the file, which follows the
143 // end of icon resource table
144 _llseek( hFile
, iconFileRes
.dwDIBOffset
, 0);
145 cbBits
= _lread( hFile
, (LPSTR
)lpDIB
, (WORD
)iconFileRes
.dwDIBSize
);
152 if( (DWORD
)cbBits
!= iconFileRes
.dwDIBSize
)
155 return (HANDLE
) NULL
;
160 //*****************************************************************************
161 //* Function : MakeIcon() *
162 //* Purpose : Creates an icon based on the DIB info. returned by ReadIcon. *
163 //* Parameters : HANDLE hDIB - A handle to the icon's DIB information. *
164 //* Returns : A handle to an Icon. NULL is returned if an icon cannot be *
165 //* successfully created. *
166 //* Comments : The steps involved in making an icon from a DIB are very *
167 //* similar to those involved in making a cursor from a DIB. *
168 //* Steps : 1) Obtain a pointer to the Icon's DIB bits. *
169 //* 2) Divide the DIB'd height with 2 to account for the fact that the*
170 //* DIB stores both the XOR and the AND masks, one after the other.*
171 //* 3) Determine the offset to the XOR bits. *
172 //* 4) Determine the offset to the AND bits. *
173 //* 5) Create a device dependent bitmap with the XOR bits. *
174 //* 6) Obtain the device dependent XOR bitmask and save in memory. *
175 //* The AND bitmask is monochrome. Monochrome bits are identical *
176 //* in both the device dependent bitmaps and device independent *
177 //* bitmaps. So, no need to convert the AND bitmask. *
178 //* 7) Since a DIB is stored upside down, flip the monochrome AND bits*
180 //* 8) Use the XOR and AND bits and create an icon with CreateIcon. *
181 //*****************************************************************************
183 HICON
MakeIcon( HANDLE hDIB
, HINSTANCE hInst
)
185 lpANDbits
; // Pointer to XOR and AND bits
186 HBITMAP hbmXor
; // handle to XOR bitmap
187 BITMAP bmpXor
; // Used to manipulate XOR bitmap
188 DWORD dwBmpSize
; // Size of XOR bitmap
198 // 1) Obtain a pointer to the Icon's DIB bits.
199 #ifdef __WINDOWS_386__
200 lpDIB
= (LPBITMAPINFO
)MK_FP32(GlobalLock( hDIB
));
202 lpDIB
= (LPBITMAPINFO
)GlobalLock( hDIB
);
205 // 2) Divide the DIB'd height with 2 to account for the fact that the
206 // DIB stores both the XOR and the AND masks, one after the other.
207 lpDIB
->bmiHeader
.biHeight
/= 2;
209 // 3) Determine the offset to the XOR bits.
210 // To obtain this value, we have to skip the header, and color table
211 lpXORbits
= (LPSTR
)lpDIB
+ (int )lpDIB
->bmiHeader
.biSize
+
212 (DIBNumColors( (LPSTR
)lpDIB
) * sizeof( RGBQUAD
));
214 // 4) Determine the offset to the AND bits.
215 // To obtain this value, skip the XOR bits
216 lpANDbits
= lpXORbits
+ (int )(lpDIB
->bmiHeader
.biHeight
*
217 (WIDTHBYTES ( lpDIB
->bmiHeader
.biWidth
*
218 lpDIB
->bmiHeader
.biBitCount
)));
220 // Get a hDC so we can create a bitmap compatible with it
221 hDC
= CreateDC( _T("DISPLAY"), NULL
, NULL
, NULL
);
223 // 5) Create a device dependent bitmap with the XOR bits.
224 hbmXor
= CreateDIBitmap( hDC
, (LPBITMAPINFOHEADER
)&(lpDIB
->bmiHeader
),
225 CBM_INIT
, lpXORbits
, lpDIB
, DIB_RGB_COLORS
);
227 GetObject( hbmXor
, sizeof(BITMAP
), (LPSTR
)&bmpXor
);
229 dwBmpSize
= (DWORD
)(bmpXor
.bmWidthBytes
* bmpXor
.bmHeight
* bmpXor
.bmPlanes
);
230 hXorDDB
= GlobalAlloc( GHND
, dwBmpSize
);
231 if(hXorDDB
== (HANDLE
) NULL
)
233 // clean up before quitting
234 DeleteObject( hbmXor
);
240 #ifdef __WINDOWS_386__
241 lpXorDDB
= (LPSTR
)MK_FP32(GlobalLock( hXorDDB
));
243 lpXorDDB
= (LPSTR
)GlobalLock( hXorDDB
);
246 // 6) Obtain the device dependent XOR bitmask and save in memory.
247 // The AND bitmask is monochrome. Monochrome bits are identical
248 // in both the device dependent bitmaps and device independent
249 // bitmaps. So, no need to convert the AND bitmask.
250 GetBitmapBits( hbmXor
, dwBmpSize
, lpXorDDB
);
252 // 7) Since a DIB is stored upside down, flip the monochrome AND bits by scanlines.
253 k
= (int )lpDIB
->bmiHeader
.biHeight
;
254 for( j
= 0 ; j
< k
; j
++, lpANDbits
+= sizeof(DWORD
))
255 szFlip
[(k
- 1) - j
] = *(DWORD FAR
*)lpANDbits
;
257 // 8) Use the XOR and AND bits and create an icon with CreateIcon.
258 hIcon
= CreateIcon( hInst
, bmpXor
.bmWidth
, bmpXor
.bmHeight
, bmpXor
.bmPlanes
,
259 bmpXor
.bmBitsPixel
, (const BYTE
*)szFlip
, (const BYTE
*)lpXorDDB
);
261 // Clean up before exiting.
262 DeleteObject( hbmXor
);
263 GlobalUnlock( hXorDDB
);
264 GlobalFree( hXorDDB
);
271 // **************************************************************************
273 //*****************************************************************************
274 //* Function : ReadCursorFile() *
275 //* Purpose : Reads a cursor resource file and creates a cursor based on that*
277 //* Parameters : char *szFileName - The cursor resource file. *
278 //* Returns : A handle to a cursor. The handle will be NULL if a cursor can't*
279 //* be created for any reason. *
280 //*****************************************************************************
282 HCURSOR
ReadCursorFile( wxChar
*szFileName
, HINSTANCE hInst
, int *W
, int *H
,
283 int *XHot
, int *YHot
)
284 { HANDLE hDIB
; // Handle to DIB memory
288 // read cur DIB from file
289 if( (hDIB
= ReadCur( szFileName
, (LPPOINT
)&ptHotSpot
, W
, H
)) == (HANDLE
) NULL
)
290 return (HCURSOR
) NULL
;
291 hCursor
= MakeCursor( hDIB
, (LPPOINT
)&ptHotSpot
, hInst
);//create cur from DIB
300 //*****************************************************************************
301 //* Function : IconToCursor() *
302 //* Purpose : Reads an icon resource file and creates a cursor based on that *
304 //* Parameters : char *szFileName - The icon resource file. *
305 //* Returns : A handle to a cursor. The handle will be NULL if a cursor can't*
306 //* be created for any reason. *
307 //* Comments : An icon may be in color. So, the DIB has to be forced to be *
309 //*****************************************************************************
311 HCURSOR
IconToCursor( wxChar
*szFileName
, HINSTANCE hInst
, int XHot
, int YHot
,
317 if( (hDIB
= ReadIcon( szFileName
, W
, H
)) == (HANDLE
) NULL
)
318 //read icon file to get icon DIB
319 return (HCURSOR
) NULL
;
320 // Set the hot spot of the cursor
323 hCursor
= MakeCursor( hDIB
, (LPPOINT
)&ptHotSpot
, hInst
);
324 //create cursor from DIB
329 //*****************************************************************************
330 //* Function : ReadCur() *
331 //* Purpose : Reads a cursor resource file and extracts the DIB information. *
332 //* Parameters : LPSTR szFileName - The cursor resource file. *
333 //* Returns : A handle to a DIB. The handle will be NULL if the resource file*
334 //* is corrupt or if memory cannot be allocated for the DIB info. *
335 //*****************************************************************************
337 HANDLE
ReadCur( wxChar
*szFileName
, LPPOINT lpptHotSpot
, int *W
, int *H
)
338 { CURFILEHEADER curFileHead
; // CURSOR file header structure
339 CURFILERES curFileRes
; // CURSOR file resource
342 cbBits
; // Used for reading in file
343 LPBITMAPINFO lpDIB
; // Pointer to DIB memory
344 int hFile
; // Handle to File
346 int nWidth
= GetSystemMetrics( SM_CXCURSOR
),
347 nHeight
= GetSystemMetrics( SM_CYCURSOR
),
350 // Open and read the .ICO file header and the first ICONFILERES
351 hFile
= _lopen( wxFNCONV(szFileName
), OF_READ
);
352 cbHead
= _lread( hFile
, (LPSTR
)&curFileHead
, sizeof( CURFILEHEADER
));
353 cbRes
= _lread( hFile
, (LPSTR
)&curFileRes
, sizeof( CURFILERES
));
356 if((cbHead
!= sizeof( CURFILEHEADER
)) || (cbRes
!= sizeof( CURFILERES
)))
357 return (HANDLE
) NULL
;
359 // Verify that it's an .CUR file
360 if ((curFileRes
.bReserved1
!= 0) || (curFileHead
.wResourceType
!= 2))
361 return (HANDLE
) NULL
;
363 // following added by P.S.
364 while( (nDirEntries
< curFileHead
.wResourceCount
) &&
365 ((curFileRes
.bWidth
!= nWidth
) || (curFileRes
.bHeight
!= nHeight
)))
367 cbRes
= _lread( hFile
, (LPSTR
)&curFileRes
, sizeof( CURFILERES
));
368 if(cbRes
!= sizeof( CURFILERES
))
369 return (HANDLE
) NULL
;
374 *W
= curFileRes
.bWidth
;
376 *H
= curFileRes
.bHeight
;
379 // Allocate & lock memory to read in the DIB
380 hDIB
= GlobalAlloc(GHND
, curFileRes
.dwDIBSize
);
381 if(hDIB
== (HANDLE
) NULL
)
382 return (HANDLE
) NULL
;
384 #ifdef __WINDOWS_386__
385 lpDIB
= (LPBITMAPINFO
)MK_FP32(GlobalLock(hDIB
));
387 lpDIB
= (LPBITMAPINFO
)GlobalLock(hDIB
);
390 // Now read the DIB portion of the file, which follows the
391 // end of icon resource table
392 _llseek( hFile
, curFileRes
.dwDIBOffset
, 0);
393 cbBits
= _lread( hFile
, (LPSTR
)lpDIB
, (WORD
)curFileRes
.dwDIBSize
);
398 if((DWORD
)cbBits
!= curFileRes
.dwDIBSize
)
402 return (HANDLE
) NULL
;
404 if(lpptHotSpot
!= (LPPOINT
) NULL
) // If it is necessary to know the hot spot
406 lpptHotSpot
->x
= (int )curFileRes
.wXHotspot
;
407 lpptHotSpot
->y
= (int )curFileRes
.wYHotspot
;
413 //*****************************************************************************
414 //* Function : ColorDDBToMonoDDB() *
415 //* Purpose : Converts a color bitmap to a monochrome bitmap. *
416 //* Parameters : HBITMAP hbm - The color bitmap. *
417 //* Returns : A handle to a monochrome bitmap. *
418 //*****************************************************************************
419 HBITMAP
ColorDDBToMonoDDB ( HBITMAP hbm
)
422 LPBITMAPINFOHEADER lpbi
;
429 GetObject( hbm
, sizeof( bm
), (LPSTR
)&bm
);
431 bi
.biSize
= sizeof( BITMAPINFOHEADER
); // size of this structure
432 bi
.biWidth
= bm
.bmWidth
; // bitmap width in pixels
433 bi
.biHeight
= bm
.bmHeight
; // bitmap height in pixels
434 bi
.biPlanes
= 1; // # of planes always 1 for DIBs
435 bi
.biBitCount
= bm
.bmPlanes
* bm
.bmBitsPixel
; // color bits per pixel
436 bi
.biCompression
= BI_RGB
; // no compression
437 bi
.biSizeImage
= 0; // 0 means default size
438 bi
.biXPelsPerMeter
= 0; // not used
439 bi
.biYPelsPerMeter
= 0; // not used
440 bi
.biClrUsed
= 0; // 0 means default colors
441 bi
.biClrImportant
= 0; // 0 means defaults
443 dwLen
= bi
.biSize
+ PaletteSize((LPSTR
)&bi
);
445 hdc
= GetDC( (HWND
) NULL
);
447 hdib
= GlobalAlloc( GHND
, dwLen
);
448 if (hdib
== (HANDLE
) NULL
)
450 ReleaseDC( (HWND
) NULL
, hdc
);
451 return (HBITMAP
) NULL
;
454 #ifdef __WINDOWS_386__
455 lpbi
= (LPBITMAPINFOHEADER
)MK_FP32(GlobalLock( hdib
));
457 lpbi
= (LPBITMAPINFOHEADER
)GlobalLock( hdib
);
462 // Call GetDIBits with a NULL lpBits parameter; it will calculate
463 // the biSizeImage field.
464 GetDIBits( hdc
, hbm
, 0, (WORD
)bi
.biHeight
,
465 NULL
, (LPBITMAPINFO
)lpbi
, DIB_RGB_COLORS
);
470 // If the driver did not fill in the biSizeImage field, make one up.
471 if(bi
.biSizeImage
== 0)
472 bi
.biSizeImage
= WIDTHBYTES( (DWORD
)bm
.bmWidth
* bi
.biBitCount
) * bm
.bmHeight
;
474 // Reallocate the buffer big enough to hold all the bits.
475 dwLen
= bi
.biSize
+ PaletteSize((LPSTR
)&bi
) + bi
.biSizeImage
;
476 if( (h
= GlobalReAlloc( hdib
, dwLen
, 0)) != 0)
481 ReleaseDC( (HWND
) NULL
, hdc
);
482 return (HBITMAP
) NULL
;
485 // Call GetDIBits with a NON-NULL lpBits parameter, to actually
486 // get the bits this time.
488 #ifdef __WINDOWS_386__
489 lpbi
= (LPBITMAPINFOHEADER
)MK_FP32(GlobalLock( hdib
));
491 lpbi
= (LPBITMAPINFOHEADER
)GlobalLock( hdib
);
494 if( GetDIBits( hdc
, hbm
, 0, (WORD
)bi
.biHeight
,
495 (LPSTR
)lpbi
+ (WORD
)lpbi
->biSize
+ PaletteSize((LPSTR
)lpbi
),
496 (LPBITMAPINFO
)lpbi
, DIB_RGB_COLORS
) == 0)
499 hdib
= (HANDLE
) NULL
;
500 ReleaseDC( (HWND
) NULL
, hdc
);
501 return (HBITMAP
) NULL
;
504 // Finally, create a monochrome DDB, and put the DIB into
505 // it. SetDIBits does smart color conversion.
506 hbmMono
= CreateBitmap((WORD
)lpbi
->biWidth
, (WORD
)lpbi
->biHeight
, 1, 1, NULL
);
507 SetDIBits( hdc
, hbmMono
, (WORD
)0, (WORD
)lpbi
->biHeight
,
508 (LPSTR
)lpbi
+ (int )lpbi
->biSize
+ PaletteSize((LPSTR
)lpbi
),
509 (LPBITMAPINFO
)lpbi
, DIB_RGB_COLORS
);
515 ReleaseDC((HWND
) NULL
, hdc
);
519 //*****************************************************************************
520 //* Function : MakeCursor() *
521 //* Purpose : Creates a cursor based on the DIB info. returned by ReadCursor.*
522 //* Parameters : HANDLE hDIB - A handle to the cursor's DIB information. *
523 //* LPPOINT lppt - A pointer to a point struct. indicating the *
524 //* location of the Cursor's hot spot. *
525 //* Returns : A handle to a cursor. NULL is returned if a cursor cannot be *
526 //* successfully created. *
527 //* Comments : The steps involved in making a cursor from a DIB are very *
528 //* similar to those involved in making an icon from a DIB. *
529 //* Steps : 1) Obtain a pointer to the Cursor's DIB bits. *
530 //* 2) Divide the DIB's height with 2 to account for the fact that the*
531 //* DIB stores both the XOR and the AND masks, one after the other.*
532 //* 3) Determine the offset to the XOR bits. *
533 //* 4) Determine the offset to the AND bits. *
534 //* 5) Create a device dependent bitmap with the XOR bits. *
535 //* 6) Obtain the device dependent XOR bitmask and save in memory. *
536 //* The AND bitmask is monochrome. Monochrome bits are identical *
537 //* in both the device dependent bitmaps and device independent *
538 //* bitmaps. So, no need to convert the AND bitmask. *
539 //* 7) Since a DIB is stored upside down, flip the monochrome AND bits*
541 //* 8) Use the XOR and AND bits and create a cursor with CreateCursor.*
542 //*****************************************************************************
544 HCURSOR
MakeCursor( HANDLE hDIB
, LPPOINT lpptHotSpot
, HINSTANCE hInst
)
546 lpANDbits
; // Pointer to XOR and AND bits
547 HBITMAP hbmXor
; // handle to XOR bitmap
548 BITMAP bmpXor
; // Used to manipulate XOR bitmap
549 DWORD dwBmpSize
; // Size of XOR bitmap
559 // 1) Obtain a pointer to the Cursor's DIB bits.
560 #ifdef __WINDOWS_386__
561 lpDIB
= (LPBITMAPINFO
)MK_FP32(GlobalLock( hDIB
));
563 lpDIB
= (LPBITMAPINFO
)GlobalLock( hDIB
);
566 // 2) Divide the DIB's height with 2 to account for the fact that the
567 // DIB stores both the XOR and the AND masks, one after the other.
568 lpDIB
->bmiHeader
.biHeight
/= 2;
570 // 3) Determine the offset to the XOR bits.
571 // To obtain this value, we have to skip the header, and color table
572 lpXORbits
= (LPSTR
)lpDIB
+ (int )lpDIB
->bmiHeader
.biSize
+
573 (DIBNumColors((LPSTR
)lpDIB
) * sizeof(RGBQUAD
));
575 // 4) Determine the offset to the AND bits
576 // To obtain this value, skip the XOR bits
577 lpANDbits
= lpXORbits
+ (int )( lpDIB
->bmiHeader
.biHeight
*
578 (WIDTHBYTES( lpDIB
->bmiHeader
.biWidth
*
579 lpDIB
->bmiHeader
.biBitCount
)));
581 // Get a hDC so we can create a bitmap compatible with it
582 hDC
= CreateDC( _T("DISPLAY"), NULL
, NULL
, NULL
);
584 // 5) Create a device dependent bitmap with the XOR bits.
585 hbmXor
= CreateBitmap( (int )lpDIB
->bmiHeader
.biWidth
,
586 (int )lpDIB
->bmiHeader
.biHeight
, 1, 1, NULL
);
587 SetDIBits( hDC
, hbmXor
, 0, (WORD
)lpDIB
->bmiHeader
.biHeight
, lpXORbits
,
588 lpDIB
, DIB_RGB_COLORS
);
589 GetObject( hbmXor
, sizeof( BITMAP
), (LPSTR
)&bmpXor
);
591 dwBmpSize
= (DWORD
)(bmpXor
.bmWidthBytes
* bmpXor
.bmHeight
* bmpXor
.bmPlanes
);
592 hXorDDB
= GlobalAlloc( GHND
, dwBmpSize
);
593 if(hXorDDB
== (HANDLE
) NULL
)
594 { // clean up before quitting
595 DeleteObject( hbmXor
);
598 return (HCURSOR
) NULL
;
600 #ifdef __WINDOWS_386__
601 lpXorDDB
= (LPSTR
)MK_FP32(GlobalLock( hXorDDB
));
603 lpXorDDB
= (LPSTR
)GlobalLock( hXorDDB
);
606 // 6) Obtain the device dependent XOR bitmask and save in memory.
607 // The AND bitmask is monochrome. Monochrome bits are identical
608 // in both the device dependent bitmaps and device independent
609 // bitmaps. So, no need to convert the AND bitmask.
610 GetBitmapBits( hbmXor
, dwBmpSize
, lpXorDDB
);
612 // 7) Since a DIB is stored upside down, flip the monochrome AND bits by scanlines.
613 k
= (int)lpDIB
->bmiHeader
.biHeight
;
614 for( j
= 0 ; j
< k
; j
++, lpANDbits
+= sizeof( DWORD
))
615 szFlip
[(k
- 1) - j
] = *(DWORD FAR
*)lpANDbits
;
617 // 8) Use the XOR and AND bits and create a cursor with CreateCursor.
618 hCursor
= CreateCursor( hInst
, lpptHotSpot
->x
, lpptHotSpot
->y
,
619 bmpXor
.bmWidth
, bmpXor
.bmHeight
, (LPSTR
)szFlip
, lpXorDDB
);
621 // Clean up before exiting.
622 DeleteObject( hbmXor
);
623 GlobalUnlock( hXorDDB
);
624 GlobalFree( hXorDDB
);
631 //*****************************************************************************
632 //* Function : PaletteSize() *
633 //* Purpose : Calculates the palette size in bytes. If the info. block is of *
634 //* the BITMAPCOREHEADER type, the number of colors is multiplied *
635 //* by sizeof(RGBTRIPLE) to give the palette size, otherwise the *
636 //* number of colors is multiplied by sizeof(RGBQUAD). *
637 //* Parameters : LPSTR pv - pointer to the BITMAPINFOHEADER *
638 //* Returns : The size of the palette. *
639 //*****************************************************************************
641 WORD
PaletteSize( LPSTR pv
)
642 { LPBITMAPINFOHEADER lpbi
;
645 lpbi
= (LPBITMAPINFOHEADER
)pv
;
646 NumColors
= DIBNumColors((LPSTR
)lpbi
);
648 if(lpbi
->biSize
== sizeof( BITMAPCOREHEADER
)) // OS/2 style DIBs
649 return NumColors
* sizeof( RGBTRIPLE
);
651 return NumColors
* sizeof( RGBQUAD
);
654 //*****************************************************************************
655 //* Function : DIBNumColors() *
656 //* Purpose : This function calculates the number of colors in the DIB's *
657 //* color table by finding the bits per pixel for the DIB (whether *
658 //* Win3.0 or OS/2-style DIB). If bits per pixel is 1: colors=2, *
659 //* if 4: colors=16, if 8: colors=256, if 24, no colors in color *
661 //* Parameters : LPSTR lpbi - pointer to packed-DIB memory block. *
662 //* Returns : The number of colors in the color table. *
663 //*****************************************************************************
665 WORD
DIBNumColors ( LPSTR pv
)
667 BITMAPINFOHEADER
*lpbi
;
668 BITMAPCOREHEADER
*lpbc
;
670 lpbi
= ((BITMAPINFOHEADER
* )pv
); // assume win 3.0 style DIBs
671 lpbc
= ((BITMAPCOREHEADER
* )pv
); // assume OS/2 style DIBs
673 // With the BITMAPINFO format headers, the size of the palette
674 // is in biClrUsed, whereas in the BITMAPCORE - style headers, it
675 // is dependent on the bits per pixel ( = 2 raised to the power of
678 if(lpbi
->biSize
!= sizeof( BITMAPCOREHEADER
))
680 if(lpbi
->biClrUsed
!= 0)
681 return (WORD
)lpbi
->biClrUsed
;
682 bits
= lpbi
->biBitCount
;
685 bits
= lpbc
->bcBitCount
;
696 // A 24 bitcount DIB has no color table
702 // ******************************************************************
703 BOOL
fGetXPixmap( BOOL fIsIcon
, wxChar
*szFileName
, HINSTANCE hInst
,
704 char cData
[], int &width
, int &height
)
717 HCURSOR hIconOrCursor
= fIsIcon
?
718 IconToCursor( szFileName
, hInst
, 0, 0, &w
, &h
)
719 : ReadCursorFile( szFileName
, hInst
, &w
, &h
, 0, 0);
722 if(hIconOrCursor
== 0)
725 hdc
= GetDC( GetDesktopWindow());
726 hdcMemory
= CreateCompatibleDC( hdc
);
727 hbmp
= CreateCompatibleBitmap( hdc
, w
, h
);
728 holdbmp
= SelectObject( hdcMemory
, hbmp
);
729 PatBlt( hdcMemory
, 0, 0, w
, h
, BLACKNESS
); // or use WHITENESS??
730 DrawIcon( hdcMemory
, 0, 0, hIconOrCursor
); //using HCURSOR with DrawIcon is OK
732 // the data retrieval follows:
735 for( j
= 0, s
= (BYTE
*)cData
; j
< h
; ++j
)
736 for( i
= 0 ; i
< w
; ++i
, cMask
>>= 1)
743 rgb
= GetPixel( hdcMemory
, i
, j
);
744 sum
= (int )(rgb
& 0xFFL
);
745 sum
+= (int )((rgb
& 0xFF00L
) >> 8);
746 sum
+= (int )((rgb
& 0xFF0000L
) >> 16);
748 cByte
= cByte
| cMask
;
755 SelectObject( hdcMemory
, holdbmp
);
756 DeleteDC( hdcMemory
);
757 ReleaseDC( GetDesktopWindow(), hdc
);
758 DestroyCursor( hIconOrCursor
);
764 // Added from scavenged internet code, JACS 23/6/95
765 HCURSOR
MakeCursorFromBitmap(HINSTANCE hInst
, HBITMAP hBitmap
, POINT
*pPoint
)
767 HDC hDCColor
, hDCMono
;
778 hDC
= GetDC((HWND
) NULL
);
779 hDCColor
= CreateCompatibleDC(hDC
);
780 hDCMono
= CreateCompatibleDC(hDC
);
781 hAndBmp
= CreateCompatibleBitmap(hDCMono
, 32, 32);
782 hXorBmp
= CreateCompatibleBitmap(hDCMono
, 32, 32);
784 hBmpOld
= (HBITMAP
) SelectObject(hDCColor
, hBitmap
);
785 SelectObject(hDCMono
, hAndBmp
);
786 SetBkColor(hDCColor
, RGB(191, 191, 191));
788 BitBlt(hDCMono
, 0, 0, 32, 32, hDCColor
, 0, 0, SRCCOPY
);
790 // Now we have the AND Mask
792 GetObject(hAndBmp
, sizeof(BITMAP
), (LPSTR
) &bm
);
793 dwBytes
= (bm
.bmWidthBytes
* bm
.bmHeight
);
794 andBits
= (NPSTR
) LocalAlloc(LPTR
, dwBytes
);
795 GetBitmapBits(hAndBmp
, dwBytes
, andBits
);
797 SelectObject(hDCMono
, hXorBmp
);
798 SetBkColor(hDCColor
, RGB(0, 0, 0));
800 BitBlt(hDCMono
, 0, 0, 32, 32, hDCColor
, 0, 0, SRCCOPY
);
802 // Now we have the XOR Mask
804 GetObject(hXorBmp
, sizeof(BITMAP
), (LPSTR
) &bm
);
805 dwBytes
= (bm
.bmWidthBytes
* bm
.bmHeight
);
806 xorBits
= (NPSTR
) LocalAlloc(LPTR
, dwBytes
);
807 GetBitmapBits(hXorBmp
, dwBytes
, xorBits
);
814 hNewCursor
= CreateCursor(hInst
,
815 pPoint
->x
, pPoint
->y
, 32, 32, andBits
, xorBits
);
817 SelectObject(hDCColor
, hBmpOld
);
818 SelectObject(hDCMono
, hBmpOld
);
821 DeleteObject(hAndBmp
);
822 DeleteObject(hXorBmp
);
823 ReleaseDC(NULL
, hDC
);
826 LocalUnlock(LocalHandle((void NEAR
*) andBits
));
827 LocalUnlock(LocalHandle((void NEAR
*) xorBits
));
828 LocalFree(LocalHandle((void NEAR
*) andBits
));
829 LocalFree(LocalHandle((void NEAR
*) xorBits
));
831 LocalUnlock(LocalHandle((WORD
) andBits
));
832 LocalUnlock(LocalHandle((WORD
) xorBits
));
833 LocalFree(LocalHandle((WORD
) andBits
));
834 LocalFree(LocalHandle((WORD
) xorBits
));
837 LocalUnlock(LocalHandle((LPCVOID
) andBits
));
838 LocalUnlock(LocalHandle((LPCVOID
) xorBits
));
839 LocalFree(LocalHandle((LPCVOID
) andBits
));
840 LocalFree(LocalHandle((LPCVOID
) xorBits
));
846 * This doesn't work: just gives us a grey square. Ideas, anyone?
849 HICON
MakeIconFromBitmap(HINSTANCE hInst
, HBITMAP hBitmap
)
851 HDC hDCColor
, hDCMono
;
862 hDC
= GetDC((HWND
) NULL
);
863 hDCColor
= CreateCompatibleDC(hDC
);
864 hDCMono
= CreateCompatibleDC(hDC
);
865 hAndBmp
= CreateCompatibleBitmap(hDCMono
, 32, 32);
866 hXorBmp
= CreateCompatibleBitmap(hDCMono
, 32, 32);
868 hBmpOld
= (HBITMAP
) SelectObject(hDCColor
, hBitmap
);
869 SelectObject(hDCMono
, hAndBmp
);
870 SetBkColor(hDCColor
, RGB(191, 191, 191));
872 BitBlt(hDCMono
, 0, 0, 32, 32, hDCColor
, 0, 0, SRCCOPY
);
874 // Now we have the AND Mask
876 GetObject(hAndBmp
, sizeof(BITMAP
), (LPSTR
) &bm
);
877 dwBytes
= (bm
.bmWidthBytes
* bm
.bmHeight
);
878 andBits
= (NPSTR
) LocalAlloc(LPTR
, dwBytes
);
879 GetBitmapBits(hAndBmp
, dwBytes
, andBits
);
881 SelectObject(hDCMono
, hXorBmp
);
882 SetBkColor(hDCColor
, RGB(0, 0, 0));
884 BitBlt(hDCMono
, 0, 0, 32, 32, hDCColor
, 0, 0, SRCCOPY
);
886 // Now we have the XOR Mask
888 GetObject(hXorBmp
, sizeof(BITMAP
), (LPSTR
) &bm
);
889 dwBytes
= (bm
.bmWidthBytes
* bm
.bmHeight
);
890 xorBits
= (NPSTR
) LocalAlloc(LPTR
, dwBytes
);
891 GetBitmapBits(hXorBmp
, dwBytes
, xorBits
);
893 hNewIcon
= CreateIcon(hInst
, 1, 4, 32, 32, (unsigned char *)andBits
, (unsigned char *)xorBits
);
895 SelectObject(hDCColor
, hBmpOld
);
896 SelectObject(hDCMono
, hBmpOld
);
899 DeleteObject(hAndBmp
);
900 DeleteObject(hXorBmp
);
901 ReleaseDC((HWND
) NULL
, hDC
);
904 LocalUnlock(LocalHandle((void NEAR
*) andBits
));
905 LocalUnlock(LocalHandle((void NEAR
*) xorBits
));
906 LocalFree(LocalHandle((void NEAR
*) andBits
));
907 LocalFree(LocalHandle((void NEAR
*) xorBits
));
909 LocalUnlock(LocalHandle((WORD
) andBits
));
910 LocalUnlock(LocalHandle((WORD
) xorBits
));
911 LocalFree(LocalHandle((WORD
) andBits
));
912 LocalFree(LocalHandle((WORD
) xorBits
));
915 LocalUnlock(LocalHandle((LPCVOID
) andBits
));
916 LocalUnlock(LocalHandle((LPCVOID
) xorBits
));
917 LocalFree(LocalHandle((LPCVOID
) andBits
));
918 LocalFree(LocalHandle((LPCVOID
) xorBits
));