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__)
27 #ifdef __GNUWIN32_OLD__
28 #include "wx/msw/gnuwin32/extra.h"
31 #include "wx/wxchar.h"
32 #include "wx/msw/curicop.h"
33 #include "wx/msw/curico.h"
34 #include "wx/string.h"
36 //*****************************************************************************
37 //* Function : ReadIconFile() *
38 //* Purpose : Reads an icon resource file and creates an icon based on that *
40 //* Parameters : char *szFileName - The icon resource file. *
41 //* Returns : A handle to an icon. The handle will be NULL if an icon cannot *
42 //* be created for any reason. *
43 //*****************************************************************************
45 HICON
ReadIconFile( wxChar
*szFileName
, HINSTANCE hInst
, int *W
, int *H
)
49 if( (hDIB
= ReadIcon(szFileName
, W
, H
)) == (HANDLE
) NULL
)
50 // read the icon DIB from file
52 hIcon
= MakeIcon( hDIB
, hInst
); // create an icon from DIB
57 //*****************************************************************************
58 //* Function : CursorToIcon() *
59 //* Purpose : Reads a cursor resource file and creates an icon based on that *
61 //* Parameters : char *szFileName - The cursor resource file. *
62 //* Returns : A handle to an icon. The handle will be NULL if an icon cannot *
63 //* be created for any reason. *
64 //* Comments : A cursor is monochrome. So, the resulting icon will also be *
66 //*****************************************************************************
68 HICON
CursorToIcon( wxChar
*szFileName
, HINSTANCE hInst
, int *W
, int *H
)
69 { HANDLE hDIB
; // Handle to DIB memory
70 HICON hIcon
; // Handle to Icon
72 if( (hDIB
= ReadCur( szFileName
, NULL
, W
, H
)) == (HANDLE
) NULL
)
75 hIcon
= MakeIcon( hDIB
, hInst
); // make icon from cursor DIB
80 //*****************************************************************************
81 //* Function : ReadIcon() *
82 //* Purpose : Reads an icon resource file and extracts the DIB information. *
83 //* Parameters : char *szFileName - The icon resource file. *
84 //* Returns : A handle to a DIB. The handle will be NULL if the resource file*
85 //* is corrupt or if memory cannot be allocated for the DIB info. *
86 //*****************************************************************************
88 HANDLE
ReadIcon( wxChar
*szFileName
, int *W
, int *H
)
89 { ICONFILEHEADER iconFileHead
; // ICON file header structure
90 ICONFILERES iconFileRes
; // ICON file resource
93 cbBits
; // Used for reading in file
94 int hFile
; // File handle
95 LPBITMAPINFO lpDIB
; // Pointer to DIB memory
97 int nWidth
= GetSystemMetrics( SM_CXICON
),
98 nHeight
= GetSystemMetrics( SM_CYICON
),
101 // Open and read the .ICO file header and the first ICONFILERES
102 hFile
= _lopen( wxConvertWX2MB(szFileName
), OF_READ
);
103 cbHead
= _lread( hFile
, (LPSTR
)&iconFileHead
, sizeof(ICONFILEHEADER
));
104 cbRes
= _lread( hFile
, (LPSTR
)&iconFileRes
, sizeof(ICONFILERES
));
107 if((cbHead
!= sizeof( ICONFILEHEADER
)) || (cbRes
!= sizeof( ICONFILERES
)))
108 return (HANDLE
) NULL
;
109 // Verify that it's an .ICON file
110 if( iconFileHead
.wResourceType
!= 1)
111 return (HANDLE
) NULL
;
114 while( (nDirEntries
< iconFileHead
.wResourceCount
) &&
115 ((iconFileRes
.bWidth
!= nWidth
) || (iconFileRes
.bHeight
!= nHeight
)))
117 cbRes
= _lread( hFile
, (LPSTR
)&iconFileRes
, sizeof( ICONFILERES
));
118 if(cbRes
!= sizeof( ICONFILERES
))
119 return (HANDLE
) NULL
;
125 *W
= iconFileRes
.bWidth
;
127 *H
= iconFileRes
.bHeight
;
129 // Allocate and lock memory to read in the DIB
130 hDIB
= GlobalAlloc(GHND
, iconFileRes
.dwDIBSize
);
131 if(hDIB
== (HANDLE
) NULL
)
132 return (HANDLE
) NULL
;
134 #ifdef __WINDOWS_386__
135 lpDIB
= (LPBITMAPINFO
)MK_FP32(GlobalLock(hDIB
));
137 lpDIB
= (LPBITMAPINFO
)GlobalLock(hDIB
);
140 // Now read the DIB portion of the file, which follows the
141 // end of icon resource table
142 _llseek( hFile
, iconFileRes
.dwDIBOffset
, 0);
143 cbBits
= _lread( hFile
, (LPSTR
)lpDIB
, (WORD
)iconFileRes
.dwDIBSize
);
150 if( (DWORD
)cbBits
!= iconFileRes
.dwDIBSize
)
153 return (HANDLE
) NULL
;
158 //*****************************************************************************
159 //* Function : MakeIcon() *
160 //* Purpose : Creates an icon based on the DIB info. returned by ReadIcon. *
161 //* Parameters : HANDLE hDIB - A handle to the icon's DIB information. *
162 //* Returns : A handle to an Icon. NULL is returned if an icon cannot be *
163 //* successfully created. *
164 //* Comments : The steps involved in making an icon from a DIB are very *
165 //* similar to those involved in making a cursor from a DIB. *
166 //* Steps : 1) Obtain a pointer to the Icon's DIB bits. *
167 //* 2) Divide the DIB'd height with 2 to account for the fact that the*
168 //* DIB stores both the XOR and the AND masks, one after the other.*
169 //* 3) Determine the offset to the XOR bits. *
170 //* 4) Determine the offset to the AND bits. *
171 //* 5) Create a device dependent bitmap with the XOR bits. *
172 //* 6) Obtain the device dependent XOR bitmask and save in memory. *
173 //* The AND bitmask is monochrome. Monochrome bits are identical *
174 //* in both the device dependent bitmaps and device independent *
175 //* bitmaps. So, no need to convert the AND bitmask. *
176 //* 7) Since a DIB is stored upside down, flip the monochrome AND bits*
178 //* 8) Use the XOR and AND bits and create an icon with CreateIcon. *
179 //*****************************************************************************
181 HICON
MakeIcon( HANDLE hDIB
, HINSTANCE hInst
)
183 lpANDbits
; // Pointer to XOR and AND bits
184 HBITMAP hbmXor
; // handle to XOR bitmap
185 BITMAP bmpXor
; // Used to manipulate XOR bitmap
186 DWORD dwBmpSize
; // Size of XOR bitmap
196 // 1) Obtain a pointer to the Icon's DIB bits.
197 #ifdef __WINDOWS_386__
198 lpDIB
= (LPBITMAPINFO
)MK_FP32(GlobalLock( hDIB
));
200 lpDIB
= (LPBITMAPINFO
)GlobalLock( hDIB
);
203 // 2) Divide the DIB'd height with 2 to account for the fact that the
204 // DIB stores both the XOR and the AND masks, one after the other.
205 lpDIB
->bmiHeader
.biHeight
/= 2;
207 // 3) Determine the offset to the XOR bits.
208 // To obtain this value, we have to skip the header, and color table
209 lpXORbits
= (LPSTR
)lpDIB
+ (int )lpDIB
->bmiHeader
.biSize
+
210 (DIBNumColors( (LPSTR
)lpDIB
) * sizeof( RGBQUAD
));
212 // 4) Determine the offset to the AND bits.
213 // To obtain this value, skip the XOR bits
214 lpANDbits
= lpXORbits
+ (int )(lpDIB
->bmiHeader
.biHeight
*
215 (WIDTHBYTES ( lpDIB
->bmiHeader
.biWidth
*
216 lpDIB
->bmiHeader
.biBitCount
)));
218 // Get a hDC so we can create a bitmap compatible with it
219 hDC
= CreateDC( wxT("DISPLAY"), NULL
, NULL
, NULL
);
221 // 5) Create a device dependent bitmap with the XOR bits.
222 hbmXor
= CreateDIBitmap( hDC
, (LPBITMAPINFOHEADER
)&(lpDIB
->bmiHeader
),
223 CBM_INIT
, lpXORbits
, lpDIB
, DIB_RGB_COLORS
);
225 GetObject( hbmXor
, sizeof(BITMAP
), (LPSTR
)&bmpXor
);
227 dwBmpSize
= (DWORD
)(bmpXor
.bmWidthBytes
* bmpXor
.bmHeight
* bmpXor
.bmPlanes
);
228 hXorDDB
= GlobalAlloc( GHND
, dwBmpSize
);
229 if(hXorDDB
== (HANDLE
) NULL
)
231 // clean up before quitting
232 DeleteObject( hbmXor
);
238 #ifdef __WINDOWS_386__
239 lpXorDDB
= (LPSTR
)MK_FP32(GlobalLock( hXorDDB
));
241 lpXorDDB
= (LPSTR
)GlobalLock( hXorDDB
);
244 // 6) Obtain the device dependent XOR bitmask and save in memory.
245 // The AND bitmask is monochrome. Monochrome bits are identical
246 // in both the device dependent bitmaps and device independent
247 // bitmaps. So, no need to convert the AND bitmask.
248 GetBitmapBits( hbmXor
, dwBmpSize
, lpXorDDB
);
250 // 7) Since a DIB is stored upside down, flip the monochrome AND bits by scanlines.
251 k
= (int )lpDIB
->bmiHeader
.biHeight
;
252 for( j
= 0 ; j
< k
; j
++, lpANDbits
+= sizeof(DWORD
))
253 szFlip
[(k
- 1) - j
] = *(DWORD FAR
*)lpANDbits
;
255 // 8) Use the XOR and AND bits and create an icon with CreateIcon.
256 hIcon
= CreateIcon( hInst
, bmpXor
.bmWidth
, bmpXor
.bmHeight
, (BYTE
)bmpXor
.bmPlanes
,
257 (BYTE
)bmpXor
.bmBitsPixel
, (const BYTE
*)szFlip
, (const BYTE
*)lpXorDDB
);
259 // Clean up before exiting.
260 DeleteObject( hbmXor
);
261 GlobalUnlock( hXorDDB
);
262 GlobalFree( hXorDDB
);
269 // **************************************************************************
271 //*****************************************************************************
272 //* Function : ReadCursorFile() *
273 //* Purpose : Reads a cursor resource file and creates a cursor based on that*
275 //* Parameters : char *szFileName - The cursor resource file. *
276 //* Returns : A handle to a cursor. The handle will be NULL if a cursor can't*
277 //* be created for any reason. *
278 //*****************************************************************************
280 HCURSOR
ReadCursorFile( wxChar
*szFileName
, HINSTANCE hInst
, int *W
, int *H
,
281 int *XHot
, int *YHot
)
282 { HANDLE hDIB
; // Handle to DIB memory
286 // read cur DIB from file
287 if( (hDIB
= ReadCur( szFileName
, (LPPOINT
)&ptHotSpot
, W
, H
)) == (HANDLE
) NULL
)
288 return (HCURSOR
) NULL
;
289 hCursor
= MakeCursor( hDIB
, (LPPOINT
)&ptHotSpot
, hInst
);//create cur from DIB
298 //*****************************************************************************
299 //* Function : IconToCursor() *
300 //* Purpose : Reads an icon resource file and creates a cursor based on that *
302 //* Parameters : char *szFileName - The icon resource file. *
303 //* Returns : A handle to a cursor. The handle will be NULL if a cursor can't*
304 //* be created for any reason. *
305 //* Comments : An icon may be in color. So, the DIB has to be forced to be *
307 //*****************************************************************************
309 HCURSOR
IconToCursor( wxChar
*szFileName
, HINSTANCE hInst
, int XHot
, int YHot
,
315 if( (hDIB
= ReadIcon( szFileName
, W
, H
)) == (HANDLE
) NULL
)
316 //read icon file to get icon DIB
317 return (HCURSOR
) NULL
;
318 // Set the hot spot of the cursor
321 hCursor
= MakeCursor( hDIB
, (LPPOINT
)&ptHotSpot
, hInst
);
322 //create cursor from DIB
327 //*****************************************************************************
328 //* Function : ReadCur() *
329 //* Purpose : Reads a cursor resource file and extracts the DIB information. *
330 //* Parameters : LPSTR szFileName - The cursor resource file. *
331 //* Returns : A handle to a DIB. The handle will be NULL if the resource file*
332 //* is corrupt or if memory cannot be allocated for the DIB info. *
333 //*****************************************************************************
335 HANDLE
ReadCur( wxChar
*szFileName
, LPPOINT lpptHotSpot
, int *W
, int *H
)
336 { CURFILEHEADER curFileHead
; // CURSOR file header structure
337 CURFILERES curFileRes
; // CURSOR file resource
340 cbBits
; // Used for reading in file
341 LPBITMAPINFO lpDIB
; // Pointer to DIB memory
342 int hFile
; // Handle to File
344 int nWidth
= GetSystemMetrics( SM_CXCURSOR
),
345 nHeight
= GetSystemMetrics( SM_CYCURSOR
),
348 // Open and read the .ICO file header and the first ICONFILERES
349 hFile
= _lopen( wxConvertWX2MB(szFileName
), OF_READ
);
350 cbHead
= _lread( hFile
, (LPSTR
)&curFileHead
, sizeof( CURFILEHEADER
));
351 cbRes
= _lread( hFile
, (LPSTR
)&curFileRes
, sizeof( CURFILERES
));
354 if((cbHead
!= sizeof( CURFILEHEADER
)) || (cbRes
!= sizeof( CURFILERES
)))
355 return (HANDLE
) NULL
;
357 // Verify that it's an .CUR file
358 if ((curFileRes
.bReserved1
!= 0) || (curFileHead
.wResourceType
!= 2))
359 return (HANDLE
) NULL
;
361 // following added by P.S.
362 while( (nDirEntries
< curFileHead
.wResourceCount
) &&
363 ((curFileRes
.bWidth
!= nWidth
) || (curFileRes
.bHeight
!= nHeight
)))
365 cbRes
= _lread( hFile
, (LPSTR
)&curFileRes
, sizeof( CURFILERES
));
366 if(cbRes
!= sizeof( CURFILERES
))
367 return (HANDLE
) NULL
;
372 *W
= curFileRes
.bWidth
;
374 *H
= curFileRes
.bHeight
;
377 // Allocate & lock memory to read in the DIB
378 hDIB
= GlobalAlloc(GHND
, curFileRes
.dwDIBSize
);
379 if(hDIB
== (HANDLE
) NULL
)
380 return (HANDLE
) NULL
;
382 #ifdef __WINDOWS_386__
383 lpDIB
= (LPBITMAPINFO
)MK_FP32(GlobalLock(hDIB
));
385 lpDIB
= (LPBITMAPINFO
)GlobalLock(hDIB
);
388 // Now read the DIB portion of the file, which follows the
389 // end of icon resource table
390 _llseek( hFile
, curFileRes
.dwDIBOffset
, 0);
391 cbBits
= _lread( hFile
, (LPSTR
)lpDIB
, (WORD
)curFileRes
.dwDIBSize
);
396 if((DWORD
)cbBits
!= curFileRes
.dwDIBSize
)
400 return (HANDLE
) NULL
;
402 if(lpptHotSpot
!= (LPPOINT
) NULL
) // If it is necessary to know the hot spot
404 lpptHotSpot
->x
= (int )curFileRes
.wXHotspot
;
405 lpptHotSpot
->y
= (int )curFileRes
.wYHotspot
;
411 //*****************************************************************************
412 //* Function : ColorDDBToMonoDDB() *
413 //* Purpose : Converts a color bitmap to a monochrome bitmap. *
414 //* Parameters : HBITMAP hbm - The color bitmap. *
415 //* Returns : A handle to a monochrome bitmap. *
416 //*****************************************************************************
417 HBITMAP
ColorDDBToMonoDDB ( HBITMAP hbm
)
420 LPBITMAPINFOHEADER lpbi
;
427 GetObject( hbm
, sizeof( bm
), (LPSTR
)&bm
);
429 bi
.biSize
= sizeof( BITMAPINFOHEADER
); // size of this structure
430 bi
.biWidth
= bm
.bmWidth
; // bitmap width in pixels
431 bi
.biHeight
= bm
.bmHeight
; // bitmap height in pixels
432 bi
.biPlanes
= 1; // # of planes always 1 for DIBs
433 bi
.biBitCount
= bm
.bmPlanes
* bm
.bmBitsPixel
; // color bits per pixel
434 bi
.biCompression
= BI_RGB
; // no compression
435 bi
.biSizeImage
= 0; // 0 means default size
436 bi
.biXPelsPerMeter
= 0; // not used
437 bi
.biYPelsPerMeter
= 0; // not used
438 bi
.biClrUsed
= 0; // 0 means default colors
439 bi
.biClrImportant
= 0; // 0 means defaults
441 dwLen
= bi
.biSize
+ PaletteSize((LPSTR
)&bi
);
443 hdc
= GetDC( (HWND
) NULL
);
445 hdib
= GlobalAlloc( GHND
, dwLen
);
446 if (hdib
== (HANDLE
) NULL
)
448 ReleaseDC( (HWND
) NULL
, hdc
);
449 return (HBITMAP
) NULL
;
452 #ifdef __WINDOWS_386__
453 lpbi
= (LPBITMAPINFOHEADER
)MK_FP32(GlobalLock( hdib
));
455 lpbi
= (LPBITMAPINFOHEADER
)GlobalLock( hdib
);
460 // Call GetDIBits with a NULL lpBits parameter; it will calculate
461 // the biSizeImage field.
462 GetDIBits( hdc
, hbm
, 0, (WORD
)bi
.biHeight
,
463 NULL
, (LPBITMAPINFO
)lpbi
, DIB_RGB_COLORS
);
468 // If the driver did not fill in the biSizeImage field, make one up.
469 if(bi
.biSizeImage
== 0)
470 bi
.biSizeImage
= WIDTHBYTES( (DWORD
)bm
.bmWidth
* bi
.biBitCount
) * bm
.bmHeight
;
472 // Reallocate the buffer big enough to hold all the bits.
473 dwLen
= bi
.biSize
+ PaletteSize((LPSTR
)&bi
) + bi
.biSizeImage
;
474 if( (h
= GlobalReAlloc( hdib
, dwLen
, 0)) != 0)
479 ReleaseDC( (HWND
) NULL
, hdc
);
480 return (HBITMAP
) NULL
;
483 // Call GetDIBits with a NON-NULL lpBits parameter, to actually
484 // get the bits this time.
486 #ifdef __WINDOWS_386__
487 lpbi
= (LPBITMAPINFOHEADER
)MK_FP32(GlobalLock( hdib
));
489 lpbi
= (LPBITMAPINFOHEADER
)GlobalLock( hdib
);
492 if( GetDIBits( hdc
, hbm
, 0, (WORD
)bi
.biHeight
,
493 (LPSTR
)lpbi
+ (WORD
)lpbi
->biSize
+ PaletteSize((LPSTR
)lpbi
),
494 (LPBITMAPINFO
)lpbi
, DIB_RGB_COLORS
) == 0)
497 hdib
= (HANDLE
) NULL
;
498 ReleaseDC( (HWND
) NULL
, hdc
);
499 return (HBITMAP
) NULL
;
502 // Finally, create a monochrome DDB, and put the DIB into
503 // it. SetDIBits does smart color conversion.
504 hbmMono
= CreateBitmap((WORD
)lpbi
->biWidth
, (WORD
)lpbi
->biHeight
, 1, 1, NULL
);
505 SetDIBits( hdc
, hbmMono
, (WORD
)0, (WORD
)lpbi
->biHeight
,
506 (LPSTR
)lpbi
+ (int )lpbi
->biSize
+ PaletteSize((LPSTR
)lpbi
),
507 (LPBITMAPINFO
)lpbi
, DIB_RGB_COLORS
);
513 ReleaseDC((HWND
) NULL
, hdc
);
517 //*****************************************************************************
518 //* Function : MakeCursor() *
519 //* Purpose : Creates a cursor based on the DIB info. returned by ReadCursor.*
520 //* Parameters : HANDLE hDIB - A handle to the cursor's DIB information. *
521 //* LPPOINT lppt - A pointer to a point struct. indicating the *
522 //* location of the Cursor's hot spot. *
523 //* Returns : A handle to a cursor. NULL is returned if a cursor cannot be *
524 //* successfully created. *
525 //* Comments : The steps involved in making a cursor from a DIB are very *
526 //* similar to those involved in making an icon from a DIB. *
527 //* Steps : 1) Obtain a pointer to the Cursor's DIB bits. *
528 //* 2) Divide the DIB's height with 2 to account for the fact that the*
529 //* DIB stores both the XOR and the AND masks, one after the other.*
530 //* 3) Determine the offset to the XOR bits. *
531 //* 4) Determine the offset to the AND bits. *
532 //* 5) Create a device dependent bitmap with the XOR bits. *
533 //* 6) Obtain the device dependent XOR bitmask and save in memory. *
534 //* The AND bitmask is monochrome. Monochrome bits are identical *
535 //* in both the device dependent bitmaps and device independent *
536 //* bitmaps. So, no need to convert the AND bitmask. *
537 //* 7) Since a DIB is stored upside down, flip the monochrome AND bits*
539 //* 8) Use the XOR and AND bits and create a cursor with CreateCursor.*
540 //*****************************************************************************
542 HCURSOR
MakeCursor( HANDLE hDIB
, LPPOINT lpptHotSpot
, HINSTANCE hInst
)
544 lpANDbits
; // Pointer to XOR and AND bits
545 HBITMAP hbmXor
; // handle to XOR bitmap
546 BITMAP bmpXor
; // Used to manipulate XOR bitmap
547 DWORD dwBmpSize
; // Size of XOR bitmap
557 // 1) Obtain a pointer to the Cursor's DIB bits.
558 #ifdef __WINDOWS_386__
559 lpDIB
= (LPBITMAPINFO
)MK_FP32(GlobalLock( hDIB
));
561 lpDIB
= (LPBITMAPINFO
)GlobalLock( hDIB
);
564 // 2) Divide the DIB's height with 2 to account for the fact that the
565 // DIB stores both the XOR and the AND masks, one after the other.
566 lpDIB
->bmiHeader
.biHeight
/= 2;
568 // 3) Determine the offset to the XOR bits.
569 // To obtain this value, we have to skip the header, and color table
570 lpXORbits
= (LPSTR
)lpDIB
+ (int )lpDIB
->bmiHeader
.biSize
+
571 (DIBNumColors((LPSTR
)lpDIB
) * sizeof(RGBQUAD
));
573 // 4) Determine the offset to the AND bits
574 // To obtain this value, skip the XOR bits
575 lpANDbits
= lpXORbits
+ (int )( lpDIB
->bmiHeader
.biHeight
*
576 (WIDTHBYTES( lpDIB
->bmiHeader
.biWidth
*
577 lpDIB
->bmiHeader
.biBitCount
)));
579 // Get a hDC so we can create a bitmap compatible with it
580 hDC
= CreateDC( wxT("DISPLAY"), NULL
, NULL
, NULL
);
582 // 5) Create a device dependent bitmap with the XOR bits.
583 hbmXor
= CreateBitmap( (int )lpDIB
->bmiHeader
.biWidth
,
584 (int )lpDIB
->bmiHeader
.biHeight
, 1, 1, NULL
);
585 SetDIBits( hDC
, hbmXor
, 0, (WORD
)lpDIB
->bmiHeader
.biHeight
, lpXORbits
,
586 lpDIB
, DIB_RGB_COLORS
);
587 GetObject( hbmXor
, sizeof( BITMAP
), (LPSTR
)&bmpXor
);
589 dwBmpSize
= (DWORD
)(bmpXor
.bmWidthBytes
* bmpXor
.bmHeight
* bmpXor
.bmPlanes
);
590 hXorDDB
= GlobalAlloc( GHND
, dwBmpSize
);
591 if(hXorDDB
== (HANDLE
) NULL
)
592 { // clean up before quitting
593 DeleteObject( hbmXor
);
596 return (HCURSOR
) NULL
;
598 #ifdef __WINDOWS_386__
599 lpXorDDB
= (LPSTR
)MK_FP32(GlobalLock( hXorDDB
));
601 lpXorDDB
= (LPSTR
)GlobalLock( hXorDDB
);
604 // 6) Obtain the device dependent XOR bitmask and save in memory.
605 // The AND bitmask is monochrome. Monochrome bits are identical
606 // in both the device dependent bitmaps and device independent
607 // bitmaps. So, no need to convert the AND bitmask.
608 GetBitmapBits( hbmXor
, dwBmpSize
, lpXorDDB
);
610 // 7) Since a DIB is stored upside down, flip the monochrome AND bits by scanlines.
611 k
= (int)lpDIB
->bmiHeader
.biHeight
;
612 for( j
= 0 ; j
< k
; j
++, lpANDbits
+= sizeof( DWORD
))
613 szFlip
[(k
- 1) - j
] = *(DWORD FAR
*)lpANDbits
;
615 // 8) Use the XOR and AND bits and create a cursor with CreateCursor.
616 hCursor
= CreateCursor( hInst
, lpptHotSpot
->x
, lpptHotSpot
->y
,
617 bmpXor
.bmWidth
, bmpXor
.bmHeight
, (LPSTR
)szFlip
, lpXorDDB
);
619 // Clean up before exiting.
620 DeleteObject( hbmXor
);
621 GlobalUnlock( hXorDDB
);
622 GlobalFree( hXorDDB
);
629 //*****************************************************************************
630 //* Function : PaletteSize() *
631 //* Purpose : Calculates the palette size in bytes. If the info. block is of *
632 //* the BITMAPCOREHEADER type, the number of colors is multiplied *
633 //* by sizeof(RGBTRIPLE) to give the palette size, otherwise the *
634 //* number of colors is multiplied by sizeof(RGBQUAD). *
635 //* Parameters : LPSTR pv - pointer to the BITMAPINFOHEADER *
636 //* Returns : The size of the palette. *
637 //*****************************************************************************
639 WORD
PaletteSize( LPSTR pv
)
640 { LPBITMAPINFOHEADER lpbi
;
643 lpbi
= (LPBITMAPINFOHEADER
)pv
;
644 NumColors
= DIBNumColors((LPSTR
)lpbi
);
646 if(lpbi
->biSize
== sizeof( BITMAPCOREHEADER
)) // OS/2 style DIBs
647 return (WORD
)(NumColors
* sizeof( RGBTRIPLE
));
649 return (WORD
)(NumColors
* sizeof( RGBQUAD
));
652 //*****************************************************************************
653 //* Function : DIBNumColors() *
654 //* Purpose : This function calculates the number of colors in the DIB's *
655 //* color table by finding the bits per pixel for the DIB (whether *
656 //* Win3.0 or OS/2-style DIB). If bits per pixel is 1: colors=2, *
657 //* if 4: colors=16, if 8: colors=256, if 24, no colors in color *
659 //* Parameters : LPSTR lpbi - pointer to packed-DIB memory block. *
660 //* Returns : The number of colors in the color table. *
661 //*****************************************************************************
663 WORD
DIBNumColors ( LPSTR pv
)
665 BITMAPINFOHEADER
*lpbi
;
666 BITMAPCOREHEADER
*lpbc
;
668 lpbi
= ((BITMAPINFOHEADER
* )pv
); // assume win 3.0 style DIBs
669 lpbc
= ((BITMAPCOREHEADER
* )pv
); // assume OS/2 style DIBs
671 // With the BITMAPINFO format headers, the size of the palette
672 // is in biClrUsed, whereas in the BITMAPCORE - style headers, it
673 // is dependent on the bits per pixel ( = 2 raised to the power of
676 if(lpbi
->biSize
!= sizeof( BITMAPCOREHEADER
))
678 if(lpbi
->biClrUsed
!= 0)
679 return (WORD
)lpbi
->biClrUsed
;
680 bits
= lpbi
->biBitCount
;
683 bits
= lpbc
->bcBitCount
;
694 // A 24 bitcount DIB has no color table
700 // ******************************************************************
701 BOOL
fGetXPixmap( BOOL fIsIcon
, wxChar
*szFileName
, HINSTANCE hInst
,
702 char cData
[], int &width
, int &height
)
715 HCURSOR hIconOrCursor
= fIsIcon
?
716 IconToCursor( szFileName
, hInst
, 0, 0, &w
, &h
)
717 : ReadCursorFile( szFileName
, hInst
, &w
, &h
, 0, 0);
720 if(hIconOrCursor
== 0)
723 hdc
= GetDC( GetDesktopWindow());
724 hdcMemory
= CreateCompatibleDC( hdc
);
725 hbmp
= CreateCompatibleBitmap( hdc
, w
, h
);
726 holdbmp
= SelectObject( hdcMemory
, hbmp
);
727 PatBlt( hdcMemory
, 0, 0, w
, h
, BLACKNESS
); // or use WHITENESS??
728 DrawIcon( hdcMemory
, 0, 0, hIconOrCursor
); //using HCURSOR with DrawIcon is OK
730 // the data retrieval follows:
733 for( j
= 0, s
= (BYTE
*)cData
; j
< h
; ++j
)
734 for( i
= 0 ; i
< w
; ++i
, cMask
>>= 1)
741 rgb
= GetPixel( hdcMemory
, i
, j
);
742 sum
= (int )(rgb
& 0xFFL
);
743 sum
+= (int )((rgb
& 0xFF00L
) >> 8);
744 sum
+= (int )((rgb
& 0xFF0000L
) >> 16);
746 cByte
= cByte
| cMask
;
753 SelectObject( hdcMemory
, holdbmp
);
754 DeleteDC( hdcMemory
);
755 ReleaseDC( GetDesktopWindow(), hdc
);
756 DestroyCursor( hIconOrCursor
);
762 // Added from scavenged internet code, JACS 23/6/95
763 HCURSOR
MakeCursorFromBitmap(HINSTANCE hInst
, HBITMAP hBitmap
, POINT
*pPoint
)
765 HDC hDCColor
, hDCMono
;
776 hDC
= GetDC((HWND
) NULL
);
777 hDCColor
= CreateCompatibleDC(hDC
);
778 hDCMono
= CreateCompatibleDC(hDC
);
779 hAndBmp
= CreateCompatibleBitmap(hDCMono
, 32, 32);
780 hXorBmp
= CreateCompatibleBitmap(hDCMono
, 32, 32);
782 hBmpOld
= (HBITMAP
) SelectObject(hDCColor
, hBitmap
);
783 SelectObject(hDCMono
, hAndBmp
);
784 SetBkColor(hDCColor
, RGB(191, 191, 191));
786 BitBlt(hDCMono
, 0, 0, 32, 32, hDCColor
, 0, 0, SRCCOPY
);
788 // Now we have the AND Mask
790 GetObject(hAndBmp
, sizeof(BITMAP
), (LPSTR
) &bm
);
791 dwBytes
= (bm
.bmWidthBytes
* bm
.bmHeight
);
792 andBits
= (NPSTR
) LocalAlloc(LPTR
, dwBytes
);
793 GetBitmapBits(hAndBmp
, dwBytes
, andBits
);
795 SelectObject(hDCMono
, hXorBmp
);
796 SetBkColor(hDCColor
, RGB(0, 0, 0));
798 BitBlt(hDCMono
, 0, 0, 32, 32, hDCColor
, 0, 0, SRCCOPY
);
800 // Now we have the XOR Mask
802 GetObject(hXorBmp
, sizeof(BITMAP
), (LPSTR
) &bm
);
803 dwBytes
= (bm
.bmWidthBytes
* bm
.bmHeight
);
804 xorBits
= (NPSTR
) LocalAlloc(LPTR
, dwBytes
);
805 GetBitmapBits(hXorBmp
, dwBytes
, xorBits
);
812 hNewCursor
= CreateCursor(hInst
,
813 pPoint
->x
, pPoint
->y
, 32, 32, andBits
, xorBits
);
815 SelectObject(hDCColor
, hBmpOld
);
816 SelectObject(hDCMono
, hBmpOld
);
819 DeleteObject(hAndBmp
);
820 DeleteObject(hXorBmp
);
821 ReleaseDC(NULL
, hDC
);
824 LocalUnlock(LocalHandle((void NEAR
*) andBits
));
825 LocalUnlock(LocalHandle((void NEAR
*) xorBits
));
826 LocalFree(LocalHandle((void NEAR
*) andBits
));
827 LocalFree(LocalHandle((void NEAR
*) xorBits
));
829 LocalUnlock(LocalHandle((WORD
) andBits
));
830 LocalUnlock(LocalHandle((WORD
) xorBits
));
831 LocalFree(LocalHandle((WORD
) andBits
));
832 LocalFree(LocalHandle((WORD
) xorBits
));
835 LocalUnlock(LocalHandle((LPCVOID
) andBits
));
836 LocalUnlock(LocalHandle((LPCVOID
) xorBits
));
837 LocalFree(LocalHandle((LPCVOID
) andBits
));
838 LocalFree(LocalHandle((LPCVOID
) xorBits
));
844 * This doesn't work: just gives us a grey square. Ideas, anyone?
847 HICON
MakeIconFromBitmap(HINSTANCE hInst
, HBITMAP hBitmap
)
849 HDC hDCColor
, hDCMono
;
860 hDC
= GetDC((HWND
) NULL
);
861 hDCColor
= CreateCompatibleDC(hDC
);
862 hDCMono
= CreateCompatibleDC(hDC
);
863 hAndBmp
= CreateCompatibleBitmap(hDCMono
, 32, 32);
864 hXorBmp
= CreateCompatibleBitmap(hDCMono
, 32, 32);
866 hBmpOld
= (HBITMAP
) SelectObject(hDCColor
, hBitmap
);
867 SelectObject(hDCMono
, hAndBmp
);
868 SetBkColor(hDCColor
, RGB(191, 191, 191));
870 BitBlt(hDCMono
, 0, 0, 32, 32, hDCColor
, 0, 0, SRCCOPY
);
872 // Now we have the AND Mask
874 GetObject(hAndBmp
, sizeof(BITMAP
), (LPSTR
) &bm
);
875 dwBytes
= (bm
.bmWidthBytes
* bm
.bmHeight
);
876 andBits
= (NPSTR
) LocalAlloc(LPTR
, dwBytes
);
877 GetBitmapBits(hAndBmp
, dwBytes
, andBits
);
879 SelectObject(hDCMono
, hXorBmp
);
880 SetBkColor(hDCColor
, RGB(0, 0, 0));
882 BitBlt(hDCMono
, 0, 0, 32, 32, hDCColor
, 0, 0, SRCCOPY
);
884 // Now we have the XOR Mask
886 GetObject(hXorBmp
, sizeof(BITMAP
), (LPSTR
) &bm
);
887 dwBytes
= (bm
.bmWidthBytes
* bm
.bmHeight
);
888 xorBits
= (NPSTR
) LocalAlloc(LPTR
, dwBytes
);
889 GetBitmapBits(hXorBmp
, dwBytes
, xorBits
);
891 hNewIcon
= CreateIcon(hInst
, 1, 4, 32, 32, (unsigned char *)andBits
, (unsigned char *)xorBits
);
893 SelectObject(hDCColor
, hBmpOld
);
894 SelectObject(hDCMono
, hBmpOld
);
897 DeleteObject(hAndBmp
);
898 DeleteObject(hXorBmp
);
899 ReleaseDC((HWND
) NULL
, hDC
);
902 LocalUnlock(LocalHandle((void NEAR
*) andBits
));
903 LocalUnlock(LocalHandle((void NEAR
*) xorBits
));
904 LocalFree(LocalHandle((void NEAR
*) andBits
));
905 LocalFree(LocalHandle((void NEAR
*) xorBits
));
907 LocalUnlock(LocalHandle((WORD
) andBits
));
908 LocalUnlock(LocalHandle((WORD
) xorBits
));
909 LocalFree(LocalHandle((WORD
) andBits
));
910 LocalFree(LocalHandle((WORD
) xorBits
));
913 LocalUnlock(LocalHandle((LPCVOID
) andBits
));
914 LocalUnlock(LocalHandle((LPCVOID
) xorBits
));
915 LocalFree(LocalHandle((LPCVOID
) andBits
));
916 LocalFree(LocalHandle((LPCVOID
) xorBits
));