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"
29 #if defined(__MWERKS__)
34 #ifdef __GNUWIN32_OLD__
35 #include "wx/msw/gnuwin32/extra.h"
38 #include "wx/wxchar.h"
39 #include "wx/msw/curicop.h"
40 #include "wx/msw/curico.h"
41 #include "wx/string.h"
43 //*****************************************************************************
44 //* Function : ReadIconFile() *
45 //* Purpose : Reads an icon resource file and creates an icon based on that *
47 //* Parameters : char *szFileName - The icon resource file. *
48 //* Returns : A handle to an icon. The handle will be NULL if an icon cannot *
49 //* be created for any reason. *
50 //*****************************************************************************
52 HICON
ReadIconFile( wxChar
*szFileName
, HINSTANCE hInst
, int *W
, int *H
)
56 if( (hDIB
= ReadIcon(szFileName
, W
, H
)) == (HANDLE
) NULL
)
57 // read the icon DIB from file
59 hIcon
= MakeIcon( hDIB
, hInst
); // create an icon from DIB
64 //*****************************************************************************
65 //* Function : CursorToIcon() *
66 //* Purpose : Reads a cursor resource file and creates an icon based on that *
68 //* Parameters : char *szFileName - The cursor resource file. *
69 //* Returns : A handle to an icon. The handle will be NULL if an icon cannot *
70 //* be created for any reason. *
71 //* Comments : A cursor is monochrome. So, the resulting icon will also be *
73 //*****************************************************************************
75 HICON
CursorToIcon( wxChar
*szFileName
, HINSTANCE hInst
, int *W
, int *H
)
76 { HANDLE hDIB
; // Handle to DIB memory
77 HICON hIcon
; // Handle to Icon
79 if( (hDIB
= ReadCur( szFileName
, NULL
, W
, H
)) == (HANDLE
) NULL
)
82 hIcon
= MakeIcon( hDIB
, hInst
); // make icon from cursor DIB
87 //*****************************************************************************
88 //* Function : ReadIcon() *
89 //* Purpose : Reads an icon resource file and extracts the DIB information. *
90 //* Parameters : char *szFileName - The icon resource file. *
91 //* Returns : A handle to a DIB. The handle will be NULL if the resource file*
92 //* is corrupt or if memory cannot be allocated for the DIB info. *
93 //*****************************************************************************
95 HANDLE
ReadIcon( wxChar
*szFileName
, int *W
, int *H
)
96 { ICONFILEHEADER iconFileHead
; // ICON file header structure
97 ICONFILERES iconFileRes
; // ICON file resource
100 cbBits
; // Used for reading in file
101 int hFile
; // File handle
102 LPBITMAPINFO lpDIB
; // Pointer to DIB memory
104 int nWidth
= GetSystemMetrics( SM_CXICON
),
105 nHeight
= GetSystemMetrics( SM_CYICON
),
108 // Open and read the .ICO file header and the first ICONFILERES
109 hFile
= _lopen( wxConvertWX2MB(szFileName
), OF_READ
);
110 cbHead
= _lread( hFile
, (LPSTR
)&iconFileHead
, sizeof(ICONFILEHEADER
));
111 cbRes
= _lread( hFile
, (LPSTR
)&iconFileRes
, sizeof(ICONFILERES
));
114 if((cbHead
!= sizeof( ICONFILEHEADER
)) || (cbRes
!= sizeof( ICONFILERES
)))
115 return (HANDLE
) NULL
;
116 // Verify that it's an .ICON file
117 if( iconFileHead
.wResourceType
!= 1)
118 return (HANDLE
) NULL
;
121 while( (nDirEntries
< iconFileHead
.wResourceCount
) &&
122 ((iconFileRes
.bWidth
!= nWidth
) || (iconFileRes
.bHeight
!= nHeight
)))
124 cbRes
= _lread( hFile
, (LPSTR
)&iconFileRes
, sizeof( ICONFILERES
));
125 if(cbRes
!= sizeof( ICONFILERES
))
126 return (HANDLE
) NULL
;
132 *W
= iconFileRes
.bWidth
;
134 *H
= iconFileRes
.bHeight
;
136 // Allocate and lock memory to read in the DIB
137 hDIB
= GlobalAlloc(GHND
, iconFileRes
.dwDIBSize
);
138 if(hDIB
== (HANDLE
) NULL
)
139 return (HANDLE
) NULL
;
141 #ifdef __WINDOWS_386__
142 lpDIB
= (LPBITMAPINFO
)MK_FP32(GlobalLock(hDIB
));
144 lpDIB
= (LPBITMAPINFO
)GlobalLock(hDIB
);
147 // Now read the DIB portion of the file, which follows the
148 // end of icon resource table
149 _llseek( hFile
, iconFileRes
.dwDIBOffset
, 0);
150 cbBits
= _lread( hFile
, (LPSTR
)lpDIB
, (WORD
)iconFileRes
.dwDIBSize
);
157 if( (DWORD
)cbBits
!= iconFileRes
.dwDIBSize
)
160 return (HANDLE
) NULL
;
165 //*****************************************************************************
166 //* Function : MakeIcon() *
167 //* Purpose : Creates an icon based on the DIB info. returned by ReadIcon. *
168 //* Parameters : HANDLE hDIB - A handle to the icon's DIB information. *
169 //* Returns : A handle to an Icon. NULL is returned if an icon cannot be *
170 //* successfully created. *
171 //* Comments : The steps involved in making an icon from a DIB are very *
172 //* similar to those involved in making a cursor from a DIB. *
173 //* Steps : 1) Obtain a pointer to the Icon's DIB bits. *
174 //* 2) Divide the DIB'd height with 2 to account for the fact that the*
175 //* DIB stores both the XOR and the AND masks, one after the other.*
176 //* 3) Determine the offset to the XOR bits. *
177 //* 4) Determine the offset to the AND bits. *
178 //* 5) Create a device dependent bitmap with the XOR bits. *
179 //* 6) Obtain the device dependent XOR bitmask and save in memory. *
180 //* The AND bitmask is monochrome. Monochrome bits are identical *
181 //* in both the device dependent bitmaps and device independent *
182 //* bitmaps. So, no need to convert the AND bitmask. *
183 //* 7) Since a DIB is stored upside down, flip the monochrome AND bits*
185 //* 8) Use the XOR and AND bits and create an icon with CreateIcon. *
186 //*****************************************************************************
188 HICON
MakeIcon( HANDLE hDIB
, HINSTANCE hInst
)
190 lpANDbits
; // Pointer to XOR and AND bits
191 HBITMAP hbmXor
; // handle to XOR bitmap
192 BITMAP bmpXor
; // Used to manipulate XOR bitmap
193 DWORD dwBmpSize
; // Size of XOR bitmap
203 // 1) Obtain a pointer to the Icon's DIB bits.
204 #ifdef __WINDOWS_386__
205 lpDIB
= (LPBITMAPINFO
)MK_FP32(GlobalLock( hDIB
));
207 lpDIB
= (LPBITMAPINFO
)GlobalLock( hDIB
);
210 // 2) Divide the DIB'd height with 2 to account for the fact that the
211 // DIB stores both the XOR and the AND masks, one after the other.
212 lpDIB
->bmiHeader
.biHeight
/= 2;
214 // 3) Determine the offset to the XOR bits.
215 // To obtain this value, we have to skip the header, and color table
216 lpXORbits
= (LPSTR
)lpDIB
+ (int )lpDIB
->bmiHeader
.biSize
+
217 (DIBNumColors( (LPSTR
)lpDIB
) * sizeof( RGBQUAD
));
219 // 4) Determine the offset to the AND bits.
220 // To obtain this value, skip the XOR bits
221 lpANDbits
= lpXORbits
+ (int )(lpDIB
->bmiHeader
.biHeight
*
222 (WIDTHBYTES ( lpDIB
->bmiHeader
.biWidth
*
223 lpDIB
->bmiHeader
.biBitCount
)));
225 // Get a hDC so we can create a bitmap compatible with it
226 hDC
= CreateDC( wxT("DISPLAY"), NULL
, NULL
, NULL
);
228 // 5) Create a device dependent bitmap with the XOR bits.
229 hbmXor
= CreateDIBitmap( hDC
, (LPBITMAPINFOHEADER
)&(lpDIB
->bmiHeader
),
230 CBM_INIT
, lpXORbits
, lpDIB
, DIB_RGB_COLORS
);
232 GetObject( hbmXor
, sizeof(BITMAP
), (LPSTR
)&bmpXor
);
234 dwBmpSize
= (DWORD
)(bmpXor
.bmWidthBytes
* bmpXor
.bmHeight
* bmpXor
.bmPlanes
);
235 hXorDDB
= GlobalAlloc( GHND
, dwBmpSize
);
236 if(hXorDDB
== (HANDLE
) NULL
)
238 // clean up before quitting
239 DeleteObject( hbmXor
);
245 #ifdef __WINDOWS_386__
246 lpXorDDB
= (LPSTR
)MK_FP32(GlobalLock( hXorDDB
));
248 lpXorDDB
= (LPSTR
)GlobalLock( hXorDDB
);
251 // 6) Obtain the device dependent XOR bitmask and save in memory.
252 // The AND bitmask is monochrome. Monochrome bits are identical
253 // in both the device dependent bitmaps and device independent
254 // bitmaps. So, no need to convert the AND bitmask.
255 GetBitmapBits( hbmXor
, dwBmpSize
, lpXorDDB
);
257 // 7) Since a DIB is stored upside down, flip the monochrome AND bits by scanlines.
258 k
= (int )lpDIB
->bmiHeader
.biHeight
;
259 for( j
= 0 ; j
< k
; j
++, lpANDbits
+= sizeof(DWORD
))
260 szFlip
[(k
- 1) - j
] = *(DWORD FAR
*)lpANDbits
;
262 // 8) Use the XOR and AND bits and create an icon with CreateIcon.
263 hIcon
= CreateIcon( hInst
, bmpXor
.bmWidth
, bmpXor
.bmHeight
, (BYTE
)bmpXor
.bmPlanes
,
264 (BYTE
)bmpXor
.bmBitsPixel
, (const BYTE
*)szFlip
, (const BYTE
*)lpXorDDB
);
266 // Clean up before exiting.
267 DeleteObject( hbmXor
);
268 GlobalUnlock( hXorDDB
);
269 GlobalFree( hXorDDB
);
276 // **************************************************************************
278 //*****************************************************************************
279 //* Function : ReadCursorFile() *
280 //* Purpose : Reads a cursor resource file and creates a cursor based on that*
282 //* Parameters : char *szFileName - The cursor resource file. *
283 //* Returns : A handle to a cursor. The handle will be NULL if a cursor can't*
284 //* be created for any reason. *
285 //*****************************************************************************
287 HCURSOR
ReadCursorFile( wxChar
*szFileName
, HINSTANCE hInst
, int *W
, int *H
,
288 int *XHot
, int *YHot
)
289 { HANDLE hDIB
; // Handle to DIB memory
293 // read cur DIB from file
294 if( (hDIB
= ReadCur( szFileName
, (LPPOINT
)&ptHotSpot
, W
, H
)) == (HANDLE
) NULL
)
295 return (HCURSOR
) NULL
;
296 hCursor
= MakeCursor( hDIB
, (LPPOINT
)&ptHotSpot
, hInst
);//create cur from DIB
305 //*****************************************************************************
306 //* Function : IconToCursor() *
307 //* Purpose : Reads an icon resource file and creates a cursor based on that *
309 //* Parameters : char *szFileName - The icon resource file. *
310 //* Returns : A handle to a cursor. The handle will be NULL if a cursor can't*
311 //* be created for any reason. *
312 //* Comments : An icon may be in color. So, the DIB has to be forced to be *
314 //*****************************************************************************
316 HCURSOR
IconToCursor( wxChar
*szFileName
, HINSTANCE hInst
, int XHot
, int YHot
,
322 if( (hDIB
= ReadIcon( szFileName
, W
, H
)) == (HANDLE
) NULL
)
323 //read icon file to get icon DIB
324 return (HCURSOR
) NULL
;
325 // Set the hot spot of the cursor
328 hCursor
= MakeCursor( hDIB
, (LPPOINT
)&ptHotSpot
, hInst
);
329 //create cursor from DIB
334 //*****************************************************************************
335 //* Function : ReadCur() *
336 //* Purpose : Reads a cursor resource file and extracts the DIB information. *
337 //* Parameters : LPSTR szFileName - The cursor resource file. *
338 //* Returns : A handle to a DIB. The handle will be NULL if the resource file*
339 //* is corrupt or if memory cannot be allocated for the DIB info. *
340 //*****************************************************************************
342 HANDLE
ReadCur( wxChar
*szFileName
, LPPOINT lpptHotSpot
, int *W
, int *H
)
343 { CURFILEHEADER curFileHead
; // CURSOR file header structure
344 CURFILERES curFileRes
; // CURSOR file resource
347 cbBits
; // Used for reading in file
348 LPBITMAPINFO lpDIB
; // Pointer to DIB memory
349 int hFile
; // Handle to File
351 int nWidth
= GetSystemMetrics( SM_CXCURSOR
),
352 nHeight
= GetSystemMetrics( SM_CYCURSOR
),
355 // Open and read the .ICO file header and the first ICONFILERES
356 hFile
= _lopen( wxConvertWX2MB(szFileName
), OF_READ
);
357 cbHead
= _lread( hFile
, (LPSTR
)&curFileHead
, sizeof( CURFILEHEADER
));
358 cbRes
= _lread( hFile
, (LPSTR
)&curFileRes
, sizeof( CURFILERES
));
361 if((cbHead
!= sizeof( CURFILEHEADER
)) || (cbRes
!= sizeof( CURFILERES
)))
362 return (HANDLE
) NULL
;
364 // Verify that it's an .CUR file
365 if ((curFileRes
.bReserved1
!= 0) || (curFileHead
.wResourceType
!= 2))
366 return (HANDLE
) NULL
;
368 // following added by P.S.
369 while( (nDirEntries
< curFileHead
.wResourceCount
) &&
370 ((curFileRes
.bWidth
!= nWidth
) || (curFileRes
.bHeight
!= nHeight
)))
372 cbRes
= _lread( hFile
, (LPSTR
)&curFileRes
, sizeof( CURFILERES
));
373 if(cbRes
!= sizeof( CURFILERES
))
374 return (HANDLE
) NULL
;
379 *W
= curFileRes
.bWidth
;
381 *H
= curFileRes
.bHeight
;
384 // Allocate & lock memory to read in the DIB
385 hDIB
= GlobalAlloc(GHND
, curFileRes
.dwDIBSize
);
386 if(hDIB
== (HANDLE
) NULL
)
387 return (HANDLE
) NULL
;
389 #ifdef __WINDOWS_386__
390 lpDIB
= (LPBITMAPINFO
)MK_FP32(GlobalLock(hDIB
));
392 lpDIB
= (LPBITMAPINFO
)GlobalLock(hDIB
);
395 // Now read the DIB portion of the file, which follows the
396 // end of icon resource table
397 _llseek( hFile
, curFileRes
.dwDIBOffset
, 0);
398 cbBits
= _lread( hFile
, (LPSTR
)lpDIB
, (WORD
)curFileRes
.dwDIBSize
);
403 if((DWORD
)cbBits
!= curFileRes
.dwDIBSize
)
407 return (HANDLE
) NULL
;
409 if(lpptHotSpot
!= (LPPOINT
) NULL
) // If it is necessary to know the hot spot
411 lpptHotSpot
->x
= (int )curFileRes
.wXHotspot
;
412 lpptHotSpot
->y
= (int )curFileRes
.wYHotspot
;
418 //*****************************************************************************
419 //* Function : ColorDDBToMonoDDB() *
420 //* Purpose : Converts a color bitmap to a monochrome bitmap. *
421 //* Parameters : HBITMAP hbm - The color bitmap. *
422 //* Returns : A handle to a monochrome bitmap. *
423 //*****************************************************************************
424 HBITMAP
ColorDDBToMonoDDB ( HBITMAP hbm
)
427 LPBITMAPINFOHEADER lpbi
;
434 GetObject( hbm
, sizeof( bm
), (LPSTR
)&bm
);
436 bi
.biSize
= sizeof( BITMAPINFOHEADER
); // size of this structure
437 bi
.biWidth
= bm
.bmWidth
; // bitmap width in pixels
438 bi
.biHeight
= bm
.bmHeight
; // bitmap height in pixels
439 bi
.biPlanes
= 1; // # of planes always 1 for DIBs
440 bi
.biBitCount
= bm
.bmPlanes
* bm
.bmBitsPixel
; // color bits per pixel
441 bi
.biCompression
= BI_RGB
; // no compression
442 bi
.biSizeImage
= 0; // 0 means default size
443 bi
.biXPelsPerMeter
= 0; // not used
444 bi
.biYPelsPerMeter
= 0; // not used
445 bi
.biClrUsed
= 0; // 0 means default colors
446 bi
.biClrImportant
= 0; // 0 means defaults
448 dwLen
= bi
.biSize
+ PaletteSize((LPSTR
)&bi
);
450 hdc
= GetDC( (HWND
) NULL
);
452 hdib
= GlobalAlloc( GHND
, dwLen
);
453 if (hdib
== (HANDLE
) NULL
)
455 ReleaseDC( (HWND
) NULL
, hdc
);
456 return (HBITMAP
) NULL
;
459 #ifdef __WINDOWS_386__
460 lpbi
= (LPBITMAPINFOHEADER
)MK_FP32(GlobalLock( hdib
));
462 lpbi
= (LPBITMAPINFOHEADER
)GlobalLock( hdib
);
467 // Call GetDIBits with a NULL lpBits parameter; it will calculate
468 // the biSizeImage field.
469 GetDIBits( hdc
, hbm
, 0, (WORD
)bi
.biHeight
,
470 NULL
, (LPBITMAPINFO
)lpbi
, DIB_RGB_COLORS
);
475 // If the driver did not fill in the biSizeImage field, make one up.
476 if(bi
.biSizeImage
== 0)
477 bi
.biSizeImage
= WIDTHBYTES( (DWORD
)bm
.bmWidth
* bi
.biBitCount
) * bm
.bmHeight
;
479 // Reallocate the buffer big enough to hold all the bits.
480 dwLen
= bi
.biSize
+ PaletteSize((LPSTR
)&bi
) + bi
.biSizeImage
;
481 if( (h
= GlobalReAlloc( hdib
, dwLen
, 0)) != 0)
486 ReleaseDC( (HWND
) NULL
, hdc
);
487 return (HBITMAP
) NULL
;
490 // Call GetDIBits with a NON-NULL lpBits parameter, to actually
491 // get the bits this time.
493 #ifdef __WINDOWS_386__
494 lpbi
= (LPBITMAPINFOHEADER
)MK_FP32(GlobalLock( hdib
));
496 lpbi
= (LPBITMAPINFOHEADER
)GlobalLock( hdib
);
499 if( GetDIBits( hdc
, hbm
, 0, (WORD
)bi
.biHeight
,
500 (LPSTR
)lpbi
+ (WORD
)lpbi
->biSize
+ PaletteSize((LPSTR
)lpbi
),
501 (LPBITMAPINFO
)lpbi
, DIB_RGB_COLORS
) == 0)
504 hdib
= (HANDLE
) NULL
;
505 ReleaseDC( (HWND
) NULL
, hdc
);
506 return (HBITMAP
) NULL
;
509 // Finally, create a monochrome DDB, and put the DIB into
510 // it. SetDIBits does smart color conversion.
511 hbmMono
= CreateBitmap((WORD
)lpbi
->biWidth
, (WORD
)lpbi
->biHeight
, 1, 1, NULL
);
512 SetDIBits( hdc
, hbmMono
, (WORD
)0, (WORD
)lpbi
->biHeight
,
513 (LPSTR
)lpbi
+ (int )lpbi
->biSize
+ PaletteSize((LPSTR
)lpbi
),
514 (LPBITMAPINFO
)lpbi
, DIB_RGB_COLORS
);
520 ReleaseDC((HWND
) NULL
, hdc
);
524 //*****************************************************************************
525 //* Function : MakeCursor() *
526 //* Purpose : Creates a cursor based on the DIB info. returned by ReadCursor.*
527 //* Parameters : HANDLE hDIB - A handle to the cursor's DIB information. *
528 //* LPPOINT lppt - A pointer to a point struct. indicating the *
529 //* location of the Cursor's hot spot. *
530 //* Returns : A handle to a cursor. NULL is returned if a cursor cannot be *
531 //* successfully created. *
532 //* Comments : The steps involved in making a cursor from a DIB are very *
533 //* similar to those involved in making an icon from a DIB. *
534 //* Steps : 1) Obtain a pointer to the Cursor's DIB bits. *
535 //* 2) Divide the DIB's height with 2 to account for the fact that the*
536 //* DIB stores both the XOR and the AND masks, one after the other.*
537 //* 3) Determine the offset to the XOR bits. *
538 //* 4) Determine the offset to the AND bits. *
539 //* 5) Create a device dependent bitmap with the XOR bits. *
540 //* 6) Obtain the device dependent XOR bitmask and save in memory. *
541 //* The AND bitmask is monochrome. Monochrome bits are identical *
542 //* in both the device dependent bitmaps and device independent *
543 //* bitmaps. So, no need to convert the AND bitmask. *
544 //* 7) Since a DIB is stored upside down, flip the monochrome AND bits*
546 //* 8) Use the XOR and AND bits and create a cursor with CreateCursor.*
547 //*****************************************************************************
549 HCURSOR
MakeCursor( HANDLE hDIB
, LPPOINT lpptHotSpot
, HINSTANCE hInst
)
551 lpANDbits
; // Pointer to XOR and AND bits
552 HBITMAP hbmXor
; // handle to XOR bitmap
553 BITMAP bmpXor
; // Used to manipulate XOR bitmap
554 DWORD dwBmpSize
; // Size of XOR bitmap
564 // 1) Obtain a pointer to the Cursor's DIB bits.
565 #ifdef __WINDOWS_386__
566 lpDIB
= (LPBITMAPINFO
)MK_FP32(GlobalLock( hDIB
));
568 lpDIB
= (LPBITMAPINFO
)GlobalLock( hDIB
);
571 // 2) Divide the DIB's height with 2 to account for the fact that the
572 // DIB stores both the XOR and the AND masks, one after the other.
573 lpDIB
->bmiHeader
.biHeight
/= 2;
575 // 3) Determine the offset to the XOR bits.
576 // To obtain this value, we have to skip the header, and color table
577 lpXORbits
= (LPSTR
)lpDIB
+ (int )lpDIB
->bmiHeader
.biSize
+
578 (DIBNumColors((LPSTR
)lpDIB
) * sizeof(RGBQUAD
));
580 // 4) Determine the offset to the AND bits
581 // To obtain this value, skip the XOR bits
582 lpANDbits
= lpXORbits
+ (int )( lpDIB
->bmiHeader
.biHeight
*
583 (WIDTHBYTES( lpDIB
->bmiHeader
.biWidth
*
584 lpDIB
->bmiHeader
.biBitCount
)));
586 // Get a hDC so we can create a bitmap compatible with it
587 hDC
= CreateDC( wxT("DISPLAY"), NULL
, NULL
, NULL
);
589 // 5) Create a device dependent bitmap with the XOR bits.
590 hbmXor
= CreateBitmap( (int )lpDIB
->bmiHeader
.biWidth
,
591 (int )lpDIB
->bmiHeader
.biHeight
, 1, 1, NULL
);
592 SetDIBits( hDC
, hbmXor
, 0, (WORD
)lpDIB
->bmiHeader
.biHeight
, lpXORbits
,
593 lpDIB
, DIB_RGB_COLORS
);
594 GetObject( hbmXor
, sizeof( BITMAP
), (LPSTR
)&bmpXor
);
596 dwBmpSize
= (DWORD
)(bmpXor
.bmWidthBytes
* bmpXor
.bmHeight
* bmpXor
.bmPlanes
);
597 hXorDDB
= GlobalAlloc( GHND
, dwBmpSize
);
598 if(hXorDDB
== (HANDLE
) NULL
)
599 { // clean up before quitting
600 DeleteObject( hbmXor
);
603 return (HCURSOR
) NULL
;
605 #ifdef __WINDOWS_386__
606 lpXorDDB
= (LPSTR
)MK_FP32(GlobalLock( hXorDDB
));
608 lpXorDDB
= (LPSTR
)GlobalLock( hXorDDB
);
611 // 6) Obtain the device dependent XOR bitmask and save in memory.
612 // The AND bitmask is monochrome. Monochrome bits are identical
613 // in both the device dependent bitmaps and device independent
614 // bitmaps. So, no need to convert the AND bitmask.
615 GetBitmapBits( hbmXor
, dwBmpSize
, lpXorDDB
);
617 // 7) Since a DIB is stored upside down, flip the monochrome AND bits by scanlines.
618 k
= (int)lpDIB
->bmiHeader
.biHeight
;
619 for( j
= 0 ; j
< k
; j
++, lpANDbits
+= sizeof( DWORD
))
620 szFlip
[(k
- 1) - j
] = *(DWORD FAR
*)lpANDbits
;
622 // 8) Use the XOR and AND bits and create a cursor with CreateCursor.
623 hCursor
= CreateCursor( hInst
, lpptHotSpot
->x
, lpptHotSpot
->y
,
624 bmpXor
.bmWidth
, bmpXor
.bmHeight
, (LPSTR
)szFlip
, lpXorDDB
);
626 // Clean up before exiting.
627 DeleteObject( hbmXor
);
628 GlobalUnlock( hXorDDB
);
629 GlobalFree( hXorDDB
);
636 //*****************************************************************************
637 //* Function : PaletteSize() *
638 //* Purpose : Calculates the palette size in bytes. If the info. block is of *
639 //* the BITMAPCOREHEADER type, the number of colors is multiplied *
640 //* by sizeof(RGBTRIPLE) to give the palette size, otherwise the *
641 //* number of colors is multiplied by sizeof(RGBQUAD). *
642 //* Parameters : LPSTR pv - pointer to the BITMAPINFOHEADER *
643 //* Returns : The size of the palette. *
644 //*****************************************************************************
646 WORD
PaletteSize( LPSTR pv
)
647 { LPBITMAPINFOHEADER lpbi
;
650 lpbi
= (LPBITMAPINFOHEADER
)pv
;
651 NumColors
= DIBNumColors((LPSTR
)lpbi
);
653 if(lpbi
->biSize
== sizeof( BITMAPCOREHEADER
)) // OS/2 style DIBs
654 return (WORD
)(NumColors
* sizeof( RGBTRIPLE
));
656 return (WORD
)(NumColors
* sizeof( RGBQUAD
));
659 //*****************************************************************************
660 //* Function : DIBNumColors() *
661 //* Purpose : This function calculates the number of colors in the DIB's *
662 //* color table by finding the bits per pixel for the DIB (whether *
663 //* Win3.0 or OS/2-style DIB). If bits per pixel is 1: colors=2, *
664 //* if 4: colors=16, if 8: colors=256, if 24, no colors in color *
666 //* Parameters : LPSTR lpbi - pointer to packed-DIB memory block. *
667 //* Returns : The number of colors in the color table. *
668 //*****************************************************************************
670 WORD
DIBNumColors ( LPSTR pv
)
672 BITMAPINFOHEADER
*lpbi
;
673 BITMAPCOREHEADER
*lpbc
;
675 lpbi
= ((BITMAPINFOHEADER
* )pv
); // assume win 3.0 style DIBs
676 lpbc
= ((BITMAPCOREHEADER
* )pv
); // assume OS/2 style DIBs
678 // With the BITMAPINFO format headers, the size of the palette
679 // is in biClrUsed, whereas in the BITMAPCORE - style headers, it
680 // is dependent on the bits per pixel ( = 2 raised to the power of
683 if(lpbi
->biSize
!= sizeof( BITMAPCOREHEADER
))
685 if(lpbi
->biClrUsed
!= 0)
686 return (WORD
)lpbi
->biClrUsed
;
687 bits
= lpbi
->biBitCount
;
690 bits
= lpbc
->bcBitCount
;
701 // A 24 bitcount DIB has no color table
707 // ******************************************************************
708 BOOL
fGetXPixmap( BOOL fIsIcon
, wxChar
*szFileName
, HINSTANCE hInst
,
709 char cData
[], int &width
, int &height
)
722 HCURSOR hIconOrCursor
= fIsIcon
?
723 IconToCursor( szFileName
, hInst
, 0, 0, &w
, &h
)
724 : ReadCursorFile( szFileName
, hInst
, &w
, &h
, 0, 0);
727 if(hIconOrCursor
== 0)
730 hdc
= GetDC( GetDesktopWindow());
731 hdcMemory
= CreateCompatibleDC( hdc
);
732 hbmp
= CreateCompatibleBitmap( hdc
, w
, h
);
733 holdbmp
= SelectObject( hdcMemory
, hbmp
);
734 PatBlt( hdcMemory
, 0, 0, w
, h
, BLACKNESS
); // or use WHITENESS??
735 DrawIcon( hdcMemory
, 0, 0, hIconOrCursor
); //using HCURSOR with DrawIcon is OK
737 // the data retrieval follows:
740 for( j
= 0, s
= (BYTE
*)cData
; j
< h
; ++j
)
741 for( i
= 0 ; i
< w
; ++i
, cMask
>>= 1)
748 rgb
= GetPixel( hdcMemory
, i
, j
);
749 sum
= (int )(rgb
& 0xFFL
);
750 sum
+= (int )((rgb
& 0xFF00L
) >> 8);
751 sum
+= (int )((rgb
& 0xFF0000L
) >> 16);
753 cByte
= cByte
| cMask
;
760 SelectObject( hdcMemory
, holdbmp
);
761 DeleteDC( hdcMemory
);
762 ReleaseDC( GetDesktopWindow(), hdc
);
763 DestroyCursor( hIconOrCursor
);
769 // Added from scavenged internet code, JACS 23/6/95
770 HCURSOR
MakeCursorFromBitmap(HINSTANCE hInst
, HBITMAP hBitmap
, POINT
*pPoint
)
772 HDC hDCColor
, hDCMono
;
783 hDC
= GetDC((HWND
) NULL
);
784 hDCColor
= CreateCompatibleDC(hDC
);
785 hDCMono
= CreateCompatibleDC(hDC
);
786 hAndBmp
= CreateCompatibleBitmap(hDCMono
, 32, 32);
787 hXorBmp
= CreateCompatibleBitmap(hDCMono
, 32, 32);
789 hBmpOld
= (HBITMAP
) SelectObject(hDCColor
, hBitmap
);
790 SelectObject(hDCMono
, hAndBmp
);
791 SetBkColor(hDCColor
, RGB(191, 191, 191));
793 BitBlt(hDCMono
, 0, 0, 32, 32, hDCColor
, 0, 0, SRCCOPY
);
795 // Now we have the AND Mask
797 GetObject(hAndBmp
, sizeof(BITMAP
), (LPSTR
) &bm
);
798 dwBytes
= (bm
.bmWidthBytes
* bm
.bmHeight
);
799 andBits
= (NPSTR
) LocalAlloc(LPTR
, dwBytes
);
800 GetBitmapBits(hAndBmp
, dwBytes
, andBits
);
802 SelectObject(hDCMono
, hXorBmp
);
803 SetBkColor(hDCColor
, RGB(0, 0, 0));
805 BitBlt(hDCMono
, 0, 0, 32, 32, hDCColor
, 0, 0, SRCCOPY
);
807 // Now we have the XOR Mask
809 GetObject(hXorBmp
, sizeof(BITMAP
), (LPSTR
) &bm
);
810 dwBytes
= (bm
.bmWidthBytes
* bm
.bmHeight
);
811 xorBits
= (NPSTR
) LocalAlloc(LPTR
, dwBytes
);
812 GetBitmapBits(hXorBmp
, dwBytes
, xorBits
);
819 hNewCursor
= CreateCursor(hInst
,
820 pPoint
->x
, pPoint
->y
, 32, 32, andBits
, xorBits
);
822 SelectObject(hDCColor
, hBmpOld
);
823 SelectObject(hDCMono
, hBmpOld
);
826 DeleteObject(hAndBmp
);
827 DeleteObject(hXorBmp
);
828 ReleaseDC(NULL
, hDC
);
831 LocalUnlock(LocalHandle((void NEAR
*) andBits
));
832 LocalUnlock(LocalHandle((void NEAR
*) xorBits
));
833 LocalFree(LocalHandle((void NEAR
*) andBits
));
834 LocalFree(LocalHandle((void NEAR
*) xorBits
));
836 LocalUnlock(LocalHandle((WORD
) andBits
));
837 LocalUnlock(LocalHandle((WORD
) xorBits
));
838 LocalFree(LocalHandle((WORD
) andBits
));
839 LocalFree(LocalHandle((WORD
) xorBits
));
842 LocalUnlock(LocalHandle((LPCVOID
) andBits
));
843 LocalUnlock(LocalHandle((LPCVOID
) xorBits
));
844 LocalFree(LocalHandle((LPCVOID
) andBits
));
845 LocalFree(LocalHandle((LPCVOID
) xorBits
));
851 * This doesn't work: just gives us a grey square. Ideas, anyone?
854 HICON
MakeIconFromBitmap(HINSTANCE hInst
, HBITMAP hBitmap
)
856 HDC hDCColor
, hDCMono
;
867 hDC
= GetDC((HWND
) NULL
);
868 hDCColor
= CreateCompatibleDC(hDC
);
869 hDCMono
= CreateCompatibleDC(hDC
);
870 hAndBmp
= CreateCompatibleBitmap(hDCMono
, 32, 32);
871 hXorBmp
= CreateCompatibleBitmap(hDCMono
, 32, 32);
873 hBmpOld
= (HBITMAP
) SelectObject(hDCColor
, hBitmap
);
874 SelectObject(hDCMono
, hAndBmp
);
875 SetBkColor(hDCColor
, RGB(191, 191, 191));
877 BitBlt(hDCMono
, 0, 0, 32, 32, hDCColor
, 0, 0, SRCCOPY
);
879 // Now we have the AND Mask
881 GetObject(hAndBmp
, sizeof(BITMAP
), (LPSTR
) &bm
);
882 dwBytes
= (bm
.bmWidthBytes
* bm
.bmHeight
);
883 andBits
= (NPSTR
) LocalAlloc(LPTR
, dwBytes
);
884 GetBitmapBits(hAndBmp
, dwBytes
, andBits
);
886 SelectObject(hDCMono
, hXorBmp
);
887 SetBkColor(hDCColor
, RGB(0, 0, 0));
889 BitBlt(hDCMono
, 0, 0, 32, 32, hDCColor
, 0, 0, SRCCOPY
);
891 // Now we have the XOR Mask
893 GetObject(hXorBmp
, sizeof(BITMAP
), (LPSTR
) &bm
);
894 dwBytes
= (bm
.bmWidthBytes
* bm
.bmHeight
);
895 xorBits
= (NPSTR
) LocalAlloc(LPTR
, dwBytes
);
896 GetBitmapBits(hXorBmp
, dwBytes
, xorBits
);
898 hNewIcon
= CreateIcon(hInst
, 1, 4, 32, 32, (unsigned char *)andBits
, (unsigned char *)xorBits
);
900 SelectObject(hDCColor
, hBmpOld
);
901 SelectObject(hDCMono
, hBmpOld
);
904 DeleteObject(hAndBmp
);
905 DeleteObject(hXorBmp
);
906 ReleaseDC((HWND
) NULL
, hDC
);
909 LocalUnlock(LocalHandle((void NEAR
*) andBits
));
910 LocalUnlock(LocalHandle((void NEAR
*) xorBits
));
911 LocalFree(LocalHandle((void NEAR
*) andBits
));
912 LocalFree(LocalHandle((void NEAR
*) xorBits
));
914 LocalUnlock(LocalHandle((WORD
) andBits
));
915 LocalUnlock(LocalHandle((WORD
) xorBits
));
916 LocalFree(LocalHandle((WORD
) andBits
));
917 LocalFree(LocalHandle((WORD
) xorBits
));
920 LocalUnlock(LocalHandle((LPCVOID
) andBits
));
921 LocalUnlock(LocalHandle((LPCVOID
) xorBits
));
922 LocalFree(LocalHandle((LPCVOID
) andBits
));
923 LocalFree(LocalHandle((LPCVOID
) xorBits
));