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"
24 #include "wx/msw/gnuwin32/extra.h"
28 #include "wx/msw/curicop.h"
29 #include "wx/msw/curico.h"
31 //*****************************************************************************
32 //* Function : ReadIconFile() *
33 //* Purpose : Reads an icon resource file and creates an icon based on that *
35 //* Parameters : char *szFileName - The icon resource file. *
36 //* Returns : A handle to an icon. The handle will be NULL if an icon cannot *
37 //* be created for any reason. *
38 //*****************************************************************************
40 HICON
ReadIconFile( char *szFileName
, HINSTANCE hInst
, int *W
, int *H
)
44 if( (hDIB
= ReadIcon(szFileName
, W
, H
)) == (HANDLE
) NULL
)
45 // read the icon DIB from file
47 hIcon
= MakeIcon( hDIB
, hInst
); // create an icon from DIB
52 //*****************************************************************************
53 //* Function : CursorToIcon() *
54 //* Purpose : Reads a cursor resource file and creates an icon based on that *
56 //* Parameters : char *szFileName - The cursor resource file. *
57 //* Returns : A handle to an icon. The handle will be NULL if an icon cannot *
58 //* be created for any reason. *
59 //* Comments : A cursor is monochrome. So, the resulting icon will also be *
61 //*****************************************************************************
63 HICON
CursorToIcon( char *szFileName
, HINSTANCE hInst
, int *W
, int *H
)
64 { HANDLE hDIB
; // Handle to DIB memory
65 HICON hIcon
; // Handle to Icon
67 if( (hDIB
= ReadCur( szFileName
, NULL
, W
, H
)) == (HANDLE
) NULL
)
70 hIcon
= MakeIcon( hDIB
, hInst
); // make icon from cursor DIB
75 //*****************************************************************************
76 //* Function : ReadIcon() *
77 //* Purpose : Reads an icon resource file and extracts the DIB information. *
78 //* Parameters : char *szFileName - The icon resource file. *
79 //* Returns : A handle to a DIB. The handle will be NULL if the resource file*
80 //* is corrupt or if memory cannot be allocated for the DIB info. *
81 //*****************************************************************************
83 HANDLE
ReadIcon( char *szFileName
, int *W
, int *H
)
84 { ICONFILEHEADER iconFileHead
; // ICON file header structure
85 ICONFILERES iconFileRes
; // ICON file resource
88 cbBits
; // Used for reading in file
89 int hFile
; // File handle
90 LPBITMAPINFO lpDIB
; // Pointer to DIB memory
92 int nWidth
= GetSystemMetrics( SM_CXICON
),
93 nHeight
= GetSystemMetrics( SM_CYICON
),
96 // Open and read the .ICO file header and the first ICONFILERES
97 hFile
= _lopen( szFileName
, OF_READ
);
98 cbHead
= _lread( hFile
, (LPSTR
)&iconFileHead
, sizeof(ICONFILEHEADER
));
99 cbRes
= _lread( hFile
, (LPSTR
)&iconFileRes
, sizeof(ICONFILERES
));
102 if((cbHead
!= sizeof( ICONFILEHEADER
)) || (cbRes
!= sizeof( ICONFILERES
)))
103 return (HANDLE
) NULL
;
104 // Verify that it's an .ICON file
105 if( iconFileHead
.wResourceType
!= 1)
106 return (HANDLE
) NULL
;
109 while( (nDirEntries
< iconFileHead
.wResourceCount
) &&
110 ((iconFileRes
.bWidth
!= nWidth
) || (iconFileRes
.bHeight
!= nHeight
)))
112 cbRes
= _lread( hFile
, (LPSTR
)&iconFileRes
, sizeof( ICONFILERES
));
113 if(cbRes
!= sizeof( ICONFILERES
))
114 return (HANDLE
) NULL
;
120 *W
= iconFileRes
.bWidth
;
122 *H
= iconFileRes
.bHeight
;
124 // Allocate and lock memory to read in the DIB
125 hDIB
= GlobalAlloc(GHND
, iconFileRes
.dwDIBSize
);
126 if(hDIB
== (HANDLE
) NULL
)
127 return (HANDLE
) NULL
;
129 #ifdef __WINDOWS_386__
130 lpDIB
= (LPBITMAPINFO
)MK_FP32(GlobalLock(hDIB
));
132 lpDIB
= (LPBITMAPINFO
)GlobalLock(hDIB
);
135 // Now read the DIB portion of the file, which follows the
136 // end of icon resource table
137 _llseek( hFile
, iconFileRes
.dwDIBOffset
, 0);
138 cbBits
= _lread( hFile
, (LPSTR
)lpDIB
, (WORD
)iconFileRes
.dwDIBSize
);
145 if( (DWORD
)cbBits
!= iconFileRes
.dwDIBSize
)
148 return (HANDLE
) NULL
;
153 //*****************************************************************************
154 //* Function : MakeIcon() *
155 //* Purpose : Creates an icon based on the DIB info. returned by ReadIcon. *
156 //* Parameters : HANDLE hDIB - A handle to the icon's DIB information. *
157 //* Returns : A handle to an Icon. NULL is returned if an icon cannot be *
158 //* successfully created. *
159 //* Comments : The steps involved in making an icon from a DIB are very *
160 //* similar to those involved in making a cursor from a DIB. *
161 //* Steps : 1) Obtain a pointer to the Icon's DIB bits. *
162 //* 2) Divide the DIB'd height with 2 to account for the fact that the*
163 //* DIB stores both the XOR and the AND masks, one after the other.*
164 //* 3) Determine the offset to the XOR bits. *
165 //* 4) Determine the offset to the AND bits. *
166 //* 5) Create a device dependent bitmap with the XOR bits. *
167 //* 6) Obtain the device dependent XOR bitmask and save in memory. *
168 //* The AND bitmask is monochrome. Monochrome bits are identical *
169 //* in both the device dependent bitmaps and device independent *
170 //* bitmaps. So, no need to convert the AND bitmask. *
171 //* 7) Since a DIB is stored upside down, flip the monochrome AND bits*
173 //* 8) Use the XOR and AND bits and create an icon with CreateIcon. *
174 //*****************************************************************************
176 HICON
MakeIcon( HANDLE hDIB
, HINSTANCE hInst
)
178 lpANDbits
; // Pointer to XOR and AND bits
179 HBITMAP hbmXor
; // handle to XOR bitmap
180 BITMAP bmpXor
; // Used to manipulate XOR bitmap
181 DWORD dwBmpSize
; // Size of XOR bitmap
191 // 1) Obtain a pointer to the Icon's DIB bits.
192 #ifdef __WINDOWS_386__
193 lpDIB
= (LPBITMAPINFO
)MK_FP32(GlobalLock( hDIB
));
195 lpDIB
= (LPBITMAPINFO
)GlobalLock( hDIB
);
198 // 2) Divide the DIB'd height with 2 to account for the fact that the
199 // DIB stores both the XOR and the AND masks, one after the other.
200 lpDIB
->bmiHeader
.biHeight
/= 2;
202 // 3) Determine the offset to the XOR bits.
203 // To obtain this value, we have to skip the header, and color table
204 lpXORbits
= (LPSTR
)lpDIB
+ (int )lpDIB
->bmiHeader
.biSize
+
205 (DIBNumColors( (LPSTR
)lpDIB
) * sizeof( RGBQUAD
));
207 // 4) Determine the offset to the AND bits.
208 // To obtain this value, skip the XOR bits
209 lpANDbits
= lpXORbits
+ (int )(lpDIB
->bmiHeader
.biHeight
*
210 (WIDTHBYTES ( lpDIB
->bmiHeader
.biWidth
*
211 lpDIB
->bmiHeader
.biBitCount
)));
213 // Get a hDC so we can create a bitmap compatible with it
214 hDC
= CreateDC( "DISPLAY", NULL
, NULL
, NULL
);
216 // 5) Create a device dependent bitmap with the XOR bits.
217 hbmXor
= CreateDIBitmap( hDC
, (LPBITMAPINFOHEADER
)&(lpDIB
->bmiHeader
),
218 CBM_INIT
, lpXORbits
, lpDIB
, DIB_RGB_COLORS
);
220 GetObject( hbmXor
, sizeof(BITMAP
), (LPSTR
)&bmpXor
);
222 dwBmpSize
= (DWORD
)(bmpXor
.bmWidthBytes
* bmpXor
.bmHeight
* bmpXor
.bmPlanes
);
223 hXorDDB
= GlobalAlloc( GHND
, dwBmpSize
);
224 if(hXorDDB
== (HANDLE
) NULL
)
226 // clean up before quitting
227 DeleteObject( hbmXor
);
233 #ifdef __WINDOWS_386__
234 lpXorDDB
= (LPSTR
)MK_FP32(GlobalLock( hXorDDB
));
236 lpXorDDB
= (LPSTR
)GlobalLock( hXorDDB
);
239 // 6) Obtain the device dependent XOR bitmask and save in memory.
240 // The AND bitmask is monochrome. Monochrome bits are identical
241 // in both the device dependent bitmaps and device independent
242 // bitmaps. So, no need to convert the AND bitmask.
243 GetBitmapBits( hbmXor
, dwBmpSize
, lpXorDDB
);
245 // 7) Since a DIB is stored upside down, flip the monochrome AND bits by scanlines.
246 k
= (int )lpDIB
->bmiHeader
.biHeight
;
247 for( j
= 0 ; j
< k
; j
++, lpANDbits
+= sizeof(DWORD
))
248 szFlip
[(k
- 1) - j
] = *(DWORD FAR
*)lpANDbits
;
250 // 8) Use the XOR and AND bits and create an icon with CreateIcon.
251 hIcon
= CreateIcon( hInst
, bmpXor
.bmWidth
, bmpXor
.bmHeight
, bmpXor
.bmPlanes
,
252 bmpXor
.bmBitsPixel
, (const BYTE
*)szFlip
, (const BYTE
*)lpXorDDB
);
254 // Clean up before exiting.
255 DeleteObject( hbmXor
);
256 GlobalUnlock( hXorDDB
);
257 GlobalFree( hXorDDB
);
264 // **************************************************************************
266 //*****************************************************************************
267 //* Function : ReadCursorFile() *
268 //* Purpose : Reads a cursor resource file and creates a cursor based on that*
270 //* Parameters : char *szFileName - The cursor resource file. *
271 //* Returns : A handle to a cursor. The handle will be NULL if a cursor can't*
272 //* be created for any reason. *
273 //*****************************************************************************
275 HCURSOR
ReadCursorFile( char *szFileName
, HINSTANCE hInst
, int *W
, int *H
,
276 int *XHot
, int *YHot
)
277 { HANDLE hDIB
; // Handle to DIB memory
281 // read cur DIB from file
282 if( (hDIB
= ReadCur( szFileName
, (LPPOINT
)&ptHotSpot
, W
, H
)) == (HANDLE
) NULL
)
283 return (HCURSOR
) NULL
;
284 hCursor
= MakeCursor( hDIB
, (LPPOINT
)&ptHotSpot
, hInst
);//create cur from DIB
293 //*****************************************************************************
294 //* Function : IconToCursor() *
295 //* Purpose : Reads an icon resource file and creates a cursor based on that *
297 //* Parameters : char *szFileName - The icon resource file. *
298 //* Returns : A handle to a cursor. The handle will be NULL if a cursor can't*
299 //* be created for any reason. *
300 //* Comments : An icon may be in color. So, the DIB has to be forced to be *
302 //*****************************************************************************
304 HCURSOR
IconToCursor( char *szFileName
, HINSTANCE hInst
, int XHot
, int YHot
,
310 if( (hDIB
= ReadIcon( szFileName
, W
, H
)) == (HANDLE
) NULL
)
311 //read icon file to get icon DIB
312 return (HCURSOR
) NULL
;
313 // Set the hot spot of the cursor
316 hCursor
= MakeCursor( hDIB
, (LPPOINT
)&ptHotSpot
, hInst
);
317 //create cursor from DIB
322 //*****************************************************************************
323 //* Function : ReadCur() *
324 //* Purpose : Reads a cursor resource file and extracts the DIB information. *
325 //* Parameters : LPSTR szFileName - The cursor resource file. *
326 //* Returns : A handle to a DIB. The handle will be NULL if the resource file*
327 //* is corrupt or if memory cannot be allocated for the DIB info. *
328 //*****************************************************************************
330 HANDLE
ReadCur( char *szFileName
, LPPOINT lpptHotSpot
, int *W
, int *H
)
331 { CURFILEHEADER curFileHead
; // CURSOR file header structure
332 CURFILERES curFileRes
; // CURSOR file resource
335 cbBits
; // Used for reading in file
336 LPBITMAPINFO lpDIB
; // Pointer to DIB memory
337 int hFile
; // Handle to File
339 int nWidth
= GetSystemMetrics( SM_CXCURSOR
),
340 nHeight
= GetSystemMetrics( SM_CYCURSOR
),
343 // Open and read the .ICO file header and the first ICONFILERES
344 hFile
= _lopen( szFileName
, OF_READ
);
345 cbHead
= _lread( hFile
, (LPSTR
)&curFileHead
, sizeof( CURFILEHEADER
));
346 cbRes
= _lread( hFile
, (LPSTR
)&curFileRes
, sizeof( CURFILERES
));
349 if((cbHead
!= sizeof( CURFILEHEADER
)) || (cbRes
!= sizeof( CURFILERES
)))
350 return (HANDLE
) NULL
;
352 // Verify that it's an .CUR file
353 if ((curFileRes
.bReserved1
!= 0) || (curFileHead
.wResourceType
!= 2))
354 return (HANDLE
) NULL
;
356 // following added by P.S.
357 while( (nDirEntries
< curFileHead
.wResourceCount
) &&
358 ((curFileRes
.bWidth
!= nWidth
) || (curFileRes
.bHeight
!= nHeight
)))
360 cbRes
= _lread( hFile
, (LPSTR
)&curFileRes
, sizeof( CURFILERES
));
361 if(cbRes
!= sizeof( CURFILERES
))
362 return (HANDLE
) NULL
;
367 *W
= curFileRes
.bWidth
;
369 *H
= curFileRes
.bHeight
;
372 // Allocate & lock memory to read in the DIB
373 hDIB
= GlobalAlloc(GHND
, curFileRes
.dwDIBSize
);
374 if(hDIB
== (HANDLE
) NULL
)
375 return (HANDLE
) NULL
;
377 #ifdef __WINDOWS_386__
378 lpDIB
= (LPBITMAPINFO
)MK_FP32(GlobalLock(hDIB
));
380 lpDIB
= (LPBITMAPINFO
)GlobalLock(hDIB
);
383 // Now read the DIB portion of the file, which follows the
384 // end of icon resource table
385 _llseek( hFile
, curFileRes
.dwDIBOffset
, 0);
386 cbBits
= _lread( hFile
, (LPSTR
)lpDIB
, (WORD
)curFileRes
.dwDIBSize
);
391 if((DWORD
)cbBits
!= curFileRes
.dwDIBSize
)
395 return (HANDLE
) NULL
;
397 if(lpptHotSpot
!= (LPPOINT
) NULL
) // If it is necessary to know the hot spot
399 lpptHotSpot
->x
= (int )curFileRes
.wXHotspot
;
400 lpptHotSpot
->y
= (int )curFileRes
.wYHotspot
;
406 //*****************************************************************************
407 //* Function : ColorDDBToMonoDDB() *
408 //* Purpose : Converts a color bitmap to a monochrome bitmap. *
409 //* Parameters : HBITMAP hbm - The color bitmap. *
410 //* Returns : A handle to a monochrome bitmap. *
411 //*****************************************************************************
412 HBITMAP
ColorDDBToMonoDDB ( HBITMAP hbm
)
415 LPBITMAPINFOHEADER lpbi
;
422 GetObject( hbm
, sizeof( bm
), (LPSTR
)&bm
);
424 bi
.biSize
= sizeof( BITMAPINFOHEADER
); // size of this structure
425 bi
.biWidth
= bm
.bmWidth
; // bitmap width in pixels
426 bi
.biHeight
= bm
.bmHeight
; // bitmap height in pixels
427 bi
.biPlanes
= 1; // # of planes always 1 for DIBs
428 bi
.biBitCount
= bm
.bmPlanes
* bm
.bmBitsPixel
; // color bits per pixel
429 bi
.biCompression
= BI_RGB
; // no compression
430 bi
.biSizeImage
= 0; // 0 means default size
431 bi
.biXPelsPerMeter
= 0; // not used
432 bi
.biYPelsPerMeter
= 0; // not used
433 bi
.biClrUsed
= 0; // 0 means default colors
434 bi
.biClrImportant
= 0; // 0 means defaults
436 dwLen
= bi
.biSize
+ PaletteSize((LPSTR
)&bi
);
438 hdc
= GetDC( (HWND
) NULL
);
440 hdib
= GlobalAlloc( GHND
, dwLen
);
441 if (hdib
== (HANDLE
) NULL
)
443 ReleaseDC( (HWND
) NULL
, hdc
);
444 return (HBITMAP
) NULL
;
447 #ifdef __WINDOWS_386__
448 lpbi
= (LPBITMAPINFOHEADER
)MK_FP32(GlobalLock( hdib
));
450 lpbi
= (LPBITMAPINFOHEADER
)GlobalLock( hdib
);
455 // Call GetDIBits with a NULL lpBits parameter; it will calculate
456 // the biSizeImage field.
457 GetDIBits( hdc
, hbm
, 0, (WORD
)bi
.biHeight
,
458 NULL
, (LPBITMAPINFO
)lpbi
, DIB_RGB_COLORS
);
463 // If the driver did not fill in the biSizeImage field, make one up.
464 if(bi
.biSizeImage
== 0)
465 bi
.biSizeImage
= WIDTHBYTES( (DWORD
)bm
.bmWidth
* bi
.biBitCount
) * bm
.bmHeight
;
467 // Reallocate the buffer big enough to hold all the bits.
468 dwLen
= bi
.biSize
+ PaletteSize((LPSTR
)&bi
) + bi
.biSizeImage
;
469 if( (h
= GlobalReAlloc( hdib
, dwLen
, 0)) != 0)
474 ReleaseDC( (HWND
) NULL
, hdc
);
475 return (HBITMAP
) NULL
;
478 // Call GetDIBits with a NON-NULL lpBits parameter, to actually
479 // get the bits this time.
481 #ifdef __WINDOWS_386__
482 lpbi
= (LPBITMAPINFOHEADER
)MK_FP32(GlobalLock( hdib
));
484 lpbi
= (LPBITMAPINFOHEADER
)GlobalLock( hdib
);
487 if( GetDIBits( hdc
, hbm
, 0, (WORD
)bi
.biHeight
,
488 (LPSTR
)lpbi
+ (WORD
)lpbi
->biSize
+ PaletteSize((LPSTR
)lpbi
),
489 (LPBITMAPINFO
)lpbi
, DIB_RGB_COLORS
) == 0)
492 hdib
= (HANDLE
) NULL
;
493 ReleaseDC( (HWND
) NULL
, hdc
);
494 return (HBITMAP
) NULL
;
497 // Finally, create a monochrome DDB, and put the DIB into
498 // it. SetDIBits does smart color conversion.
499 hbmMono
= CreateBitmap((WORD
)lpbi
->biWidth
, (WORD
)lpbi
->biHeight
, 1, 1, NULL
);
500 SetDIBits( hdc
, hbmMono
, (WORD
)0, (WORD
)lpbi
->biHeight
,
501 (LPSTR
)lpbi
+ (int )lpbi
->biSize
+ PaletteSize((LPSTR
)lpbi
),
502 (LPBITMAPINFO
)lpbi
, DIB_RGB_COLORS
);
508 ReleaseDC((HWND
) NULL
, hdc
);
512 //*****************************************************************************
513 //* Function : MakeCursor() *
514 //* Purpose : Creates a cursor based on the DIB info. returned by ReadCursor.*
515 //* Parameters : HANDLE hDIB - A handle to the cursor's DIB information. *
516 //* LPPOINT lppt - A pointer to a point struct. indicating the *
517 //* location of the Cursor's hot spot. *
518 //* Returns : A handle to a cursor. NULL is returned if a cursor cannot be *
519 //* successfully created. *
520 //* Comments : The steps involved in making a cursor from a DIB are very *
521 //* similar to those involved in making an icon from a DIB. *
522 //* Steps : 1) Obtain a pointer to the Cursor's DIB bits. *
523 //* 2) Divide the DIB's height with 2 to account for the fact that the*
524 //* DIB stores both the XOR and the AND masks, one after the other.*
525 //* 3) Determine the offset to the XOR bits. *
526 //* 4) Determine the offset to the AND bits. *
527 //* 5) Create a device dependent bitmap with the XOR bits. *
528 //* 6) Obtain the device dependent XOR bitmask and save in memory. *
529 //* The AND bitmask is monochrome. Monochrome bits are identical *
530 //* in both the device dependent bitmaps and device independent *
531 //* bitmaps. So, no need to convert the AND bitmask. *
532 //* 7) Since a DIB is stored upside down, flip the monochrome AND bits*
534 //* 8) Use the XOR and AND bits and create a cursor with CreateCursor.*
535 //*****************************************************************************
537 HCURSOR
MakeCursor( HANDLE hDIB
, LPPOINT lpptHotSpot
, HINSTANCE hInst
)
539 lpANDbits
; // Pointer to XOR and AND bits
540 HBITMAP hbmXor
; // handle to XOR bitmap
541 BITMAP bmpXor
; // Used to manipulate XOR bitmap
542 DWORD dwBmpSize
; // Size of XOR bitmap
552 // 1) Obtain a pointer to the Cursor's DIB bits.
553 #ifdef __WINDOWS_386__
554 lpDIB
= (LPBITMAPINFO
)MK_FP32(GlobalLock( hDIB
));
556 lpDIB
= (LPBITMAPINFO
)GlobalLock( hDIB
);
559 // 2) Divide the DIB's height with 2 to account for the fact that the
560 // DIB stores both the XOR and the AND masks, one after the other.
561 lpDIB
->bmiHeader
.biHeight
/= 2;
563 // 3) Determine the offset to the XOR bits.
564 // To obtain this value, we have to skip the header, and color table
565 lpXORbits
= (LPSTR
)lpDIB
+ (int )lpDIB
->bmiHeader
.biSize
+
566 (DIBNumColors((LPSTR
)lpDIB
) * sizeof(RGBQUAD
));
568 // 4) Determine the offset to the AND bits
569 // To obtain this value, skip the XOR bits
570 lpANDbits
= lpXORbits
+ (int )( lpDIB
->bmiHeader
.biHeight
*
571 (WIDTHBYTES( lpDIB
->bmiHeader
.biWidth
*
572 lpDIB
->bmiHeader
.biBitCount
)));
574 // Get a hDC so we can create a bitmap compatible with it
575 hDC
= CreateDC( "DISPLAY", NULL
, NULL
, NULL
);
577 // 5) Create a device dependent bitmap with the XOR bits.
578 hbmXor
= CreateBitmap( (int )lpDIB
->bmiHeader
.biWidth
,
579 (int )lpDIB
->bmiHeader
.biHeight
, 1, 1, NULL
);
580 SetDIBits( hDC
, hbmXor
, 0, (WORD
)lpDIB
->bmiHeader
.biHeight
, lpXORbits
,
581 lpDIB
, DIB_RGB_COLORS
);
582 GetObject( hbmXor
, sizeof( BITMAP
), (LPSTR
)&bmpXor
);
584 dwBmpSize
= (DWORD
)(bmpXor
.bmWidthBytes
* bmpXor
.bmHeight
* bmpXor
.bmPlanes
);
585 hXorDDB
= GlobalAlloc( GHND
, dwBmpSize
);
586 if(hXorDDB
== (HANDLE
) NULL
)
587 { // clean up before quitting
588 DeleteObject( hbmXor
);
591 return (HCURSOR
) NULL
;
593 #ifdef __WINDOWS_386__
594 lpXorDDB
= (LPSTR
)MK_FP32(GlobalLock( hXorDDB
));
596 lpXorDDB
= (LPSTR
)GlobalLock( hXorDDB
);
599 // 6) Obtain the device dependent XOR bitmask and save in memory.
600 // The AND bitmask is monochrome. Monochrome bits are identical
601 // in both the device dependent bitmaps and device independent
602 // bitmaps. So, no need to convert the AND bitmask.
603 GetBitmapBits( hbmXor
, dwBmpSize
, lpXorDDB
);
605 // 7) Since a DIB is stored upside down, flip the monochrome AND bits by scanlines.
606 k
= (int)lpDIB
->bmiHeader
.biHeight
;
607 for( j
= 0 ; j
< k
; j
++, lpANDbits
+= sizeof( DWORD
))
608 szFlip
[(k
- 1) - j
] = *(DWORD FAR
*)lpANDbits
;
610 // 8) Use the XOR and AND bits and create a cursor with CreateCursor.
611 hCursor
= CreateCursor( hInst
, lpptHotSpot
->x
, lpptHotSpot
->y
,
612 bmpXor
.bmWidth
, bmpXor
.bmHeight
, (LPSTR
)szFlip
, lpXorDDB
);
614 // Clean up before exiting.
615 DeleteObject( hbmXor
);
616 GlobalUnlock( hXorDDB
);
617 GlobalFree( hXorDDB
);
624 //*****************************************************************************
625 //* Function : PaletteSize() *
626 //* Purpose : Calculates the palette size in bytes. If the info. block is of *
627 //* the BITMAPCOREHEADER type, the number of colors is multiplied *
628 //* by sizeof(RGBTRIPLE) to give the palette size, otherwise the *
629 //* number of colors is multiplied by sizeof(RGBQUAD). *
630 //* Parameters : LPSTR pv - pointer to the BITMAPINFOHEADER *
631 //* Returns : The size of the palette. *
632 //*****************************************************************************
634 WORD
PaletteSize( LPSTR pv
)
635 { LPBITMAPINFOHEADER lpbi
;
638 lpbi
= (LPBITMAPINFOHEADER
)pv
;
639 NumColors
= DIBNumColors((LPSTR
)lpbi
);
641 if(lpbi
->biSize
== sizeof( BITMAPCOREHEADER
)) // OS/2 style DIBs
642 return NumColors
* sizeof( RGBTRIPLE
);
644 return NumColors
* sizeof( RGBQUAD
);
647 //*****************************************************************************
648 //* Function : DIBNumColors() *
649 //* Purpose : This function calculates the number of colors in the DIB's *
650 //* color table by finding the bits per pixel for the DIB (whether *
651 //* Win3.0 or OS/2-style DIB). If bits per pixel is 1: colors=2, *
652 //* if 4: colors=16, if 8: colors=256, if 24, no colors in color *
654 //* Parameters : LPSTR lpbi - pointer to packed-DIB memory block. *
655 //* Returns : The number of colors in the color table. *
656 //*****************************************************************************
658 WORD
DIBNumColors ( LPSTR pv
)
660 BITMAPINFOHEADER
*lpbi
;
661 BITMAPCOREHEADER
*lpbc
;
663 lpbi
= ((BITMAPINFOHEADER
* )pv
); // assume win 3.0 style DIBs
664 lpbc
= ((BITMAPCOREHEADER
* )pv
); // assume OS/2 style DIBs
666 // With the BITMAPINFO format headers, the size of the palette
667 // is in biClrUsed, whereas in the BITMAPCORE - style headers, it
668 // is dependent on the bits per pixel ( = 2 raised to the power of
671 if(lpbi
->biSize
!= sizeof( BITMAPCOREHEADER
))
673 if(lpbi
->biClrUsed
!= 0)
674 return (WORD
)lpbi
->biClrUsed
;
675 bits
= lpbi
->biBitCount
;
678 bits
= lpbc
->bcBitCount
;
689 // A 24 bitcount DIB has no color table
695 // ******************************************************************
696 BOOL
fGetXPixmap( BOOL fIsIcon
, char *szFileName
, HINSTANCE hInst
,
697 char cData
[], int &width
, int &height
)
710 HCURSOR hIconOrCursor
= fIsIcon
?
711 IconToCursor( szFileName
, hInst
, 0, 0, &w
, &h
)
712 : ReadCursorFile( szFileName
, hInst
, &w
, &h
, 0, 0);
715 if(hIconOrCursor
== 0)
718 hdc
= GetDC( GetDesktopWindow());
719 hdcMemory
= CreateCompatibleDC( hdc
);
720 hbmp
= CreateCompatibleBitmap( hdc
, w
, h
);
721 holdbmp
= SelectObject( hdcMemory
, hbmp
);
722 PatBlt( hdcMemory
, 0, 0, w
, h
, BLACKNESS
); // or use WHITENESS??
723 DrawIcon( hdcMemory
, 0, 0, hIconOrCursor
); //using HCURSOR with DrawIcon is OK
725 // the data retrieval follows:
728 for( j
= 0, s
= (BYTE
*)cData
; j
< h
; ++j
)
729 for( i
= 0 ; i
< w
; ++i
, cMask
>>= 1)
736 rgb
= GetPixel( hdcMemory
, i
, j
);
737 sum
= (int )(rgb
& 0xFFL
);
738 sum
+= (int )((rgb
& 0xFF00L
) >> 8);
739 sum
+= (int )((rgb
& 0xFF0000L
) >> 16);
741 cByte
= cByte
| cMask
;
748 SelectObject( hdcMemory
, holdbmp
);
749 DeleteDC( hdcMemory
);
750 ReleaseDC( GetDesktopWindow(), hdc
);
751 DestroyCursor( hIconOrCursor
);
757 // Added from scavenged internet code, JACS 23/6/95
758 HCURSOR
MakeCursorFromBitmap(HINSTANCE hInst
, HBITMAP hBitmap
, POINT
*pPoint
)
760 HDC hDCColor
, hDCMono
;
771 hDC
= GetDC((HWND
) NULL
);
772 hDCColor
= CreateCompatibleDC(hDC
);
773 hDCMono
= CreateCompatibleDC(hDC
);
774 hAndBmp
= CreateCompatibleBitmap(hDCMono
, 32, 32);
775 hXorBmp
= CreateCompatibleBitmap(hDCMono
, 32, 32);
777 hBmpOld
= (HBITMAP
) SelectObject(hDCColor
, hBitmap
);
778 SelectObject(hDCMono
, hAndBmp
);
779 SetBkColor(hDCColor
, RGB(191, 191, 191));
781 BitBlt(hDCMono
, 0, 0, 32, 32, hDCColor
, 0, 0, SRCCOPY
);
783 // Now we have the AND Mask
785 GetObject(hAndBmp
, sizeof(BITMAP
), (LPSTR
) &bm
);
786 dwBytes
= (bm
.bmWidthBytes
* bm
.bmHeight
);
787 andBits
= (NPSTR
) LocalAlloc(LPTR
, dwBytes
);
788 GetBitmapBits(hAndBmp
, dwBytes
, andBits
);
790 SelectObject(hDCMono
, hXorBmp
);
791 SetBkColor(hDCColor
, RGB(0, 0, 0));
793 BitBlt(hDCMono
, 0, 0, 32, 32, hDCColor
, 0, 0, SRCCOPY
);
795 // Now we have the XOR Mask
797 GetObject(hXorBmp
, sizeof(BITMAP
), (LPSTR
) &bm
);
798 dwBytes
= (bm
.bmWidthBytes
* bm
.bmHeight
);
799 xorBits
= (NPSTR
) LocalAlloc(LPTR
, dwBytes
);
800 GetBitmapBits(hXorBmp
, dwBytes
, xorBits
);
807 hNewCursor
= CreateCursor(hInst
,
808 pPoint
->x
, pPoint
->y
, 32, 32, andBits
, xorBits
);
810 SelectObject(hDCColor
, hBmpOld
);
811 SelectObject(hDCMono
, hBmpOld
);
814 DeleteObject(hAndBmp
);
815 DeleteObject(hXorBmp
);
816 ReleaseDC(NULL
, hDC
);
818 LocalUnlock(LocalHandle((WORD
) andBits
));
819 LocalUnlock(LocalHandle((WORD
) xorBits
));
820 LocalFree(LocalHandle((WORD
) andBits
));
821 LocalFree(LocalHandle((WORD
) xorBits
));
823 LocalUnlock(LocalHandle((LPCVOID
) andBits
));
824 LocalUnlock(LocalHandle((LPCVOID
) xorBits
));
825 LocalFree(LocalHandle((LPCVOID
) andBits
));
826 LocalFree(LocalHandle((LPCVOID
) xorBits
));
832 * This doesn't work: just gives us a grey square. Ideas, anyone?
835 HICON
MakeIconFromBitmap(HINSTANCE hInst
, HBITMAP hBitmap
)
837 HDC hDCColor
, hDCMono
;
848 hDC
= GetDC((HWND
) NULL
);
849 hDCColor
= CreateCompatibleDC(hDC
);
850 hDCMono
= CreateCompatibleDC(hDC
);
851 hAndBmp
= CreateCompatibleBitmap(hDCMono
, 32, 32);
852 hXorBmp
= CreateCompatibleBitmap(hDCMono
, 32, 32);
854 hBmpOld
= (HBITMAP
) SelectObject(hDCColor
, hBitmap
);
855 SelectObject(hDCMono
, hAndBmp
);
856 SetBkColor(hDCColor
, RGB(191, 191, 191));
858 BitBlt(hDCMono
, 0, 0, 32, 32, hDCColor
, 0, 0, SRCCOPY
);
860 // Now we have the AND Mask
862 GetObject(hAndBmp
, sizeof(BITMAP
), (LPSTR
) &bm
);
863 dwBytes
= (bm
.bmWidthBytes
* bm
.bmHeight
);
864 andBits
= (NPSTR
) LocalAlloc(LPTR
, dwBytes
);
865 GetBitmapBits(hAndBmp
, dwBytes
, andBits
);
867 SelectObject(hDCMono
, hXorBmp
);
868 SetBkColor(hDCColor
, RGB(0, 0, 0));
870 BitBlt(hDCMono
, 0, 0, 32, 32, hDCColor
, 0, 0, SRCCOPY
);
872 // Now we have the XOR Mask
874 GetObject(hXorBmp
, sizeof(BITMAP
), (LPSTR
) &bm
);
875 dwBytes
= (bm
.bmWidthBytes
* bm
.bmHeight
);
876 xorBits
= (NPSTR
) LocalAlloc(LPTR
, dwBytes
);
877 GetBitmapBits(hXorBmp
, dwBytes
, xorBits
);
879 hNewIcon
= CreateIcon(hInst
, 1, 4, 32, 32, (unsigned char *)andBits
, (unsigned char *)xorBits
);
881 SelectObject(hDCColor
, hBmpOld
);
882 SelectObject(hDCMono
, hBmpOld
);
885 DeleteObject(hAndBmp
);
886 DeleteObject(hXorBmp
);
887 ReleaseDC((HWND
) NULL
, hDC
);
889 LocalUnlock(LocalHandle((WORD
) andBits
));
890 LocalUnlock(LocalHandle((WORD
) xorBits
));
891 LocalFree(LocalHandle((WORD
) andBits
));
892 LocalFree(LocalHandle((WORD
) xorBits
));
894 LocalUnlock(LocalHandle((LPCVOID
) andBits
));
895 LocalUnlock(LocalHandle((LPCVOID
) xorBits
));
896 LocalFree(LocalHandle((LPCVOID
) andBits
));
897 LocalFree(LocalHandle((LPCVOID
) xorBits
));