]> git.saurik.com Git - wxWidgets.git/blame - src/msw/curico.cpp
Copyright corrections
[wxWidgets.git] / src / msw / curico.cpp
CommitLineData
2bda0e17
KB
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.
9
10// Modified by Petr Smilauer, March 1994 for wxWin library purposes!
11
12// For compilers that support precompilation, includes "wx.h".
13#include "wx/wxprec.h"
14
15#ifdef __BORLANDC__
16#pragma hdrstop
17#endif
18
2e38557f
JS
19#ifndef __UNIX__
20 #include <io.h>
21#endif
2bda0e17
KB
22#include <windows.h>
23
e3065973
JS
24#if defined(__MWERKS__)
25#include <wingdi.h>
26#include <winuser.h>
27#endif
28
c42404a5
VZ
29#ifdef __GNUWIN32_OLD__
30 #include "wx/msw/gnuwin32/extra.h"
57c208c5 31#endif
2bda0e17 32
2662e49e 33#include "wx/wxchar.h"
2bda0e17
KB
34#include "wx/msw/curicop.h"
35#include "wx/msw/curico.h"
4e938f5b 36#include "wx/string.h"
2bda0e17 37
2bda0e17
KB
38//*****************************************************************************
39//* Function : ReadIcon() *
40//* Purpose : Reads an icon resource file and extracts the DIB information. *
41//* Parameters : char *szFileName - The icon resource file. *
42//* Returns : A handle to a DIB. The handle will be NULL if the resource file*
43//* is corrupt or if memory cannot be allocated for the DIB info. *
44//*****************************************************************************
45
73c022c9 46HANDLE ReadIcon( wxChar *szFileName, int *W, int *H)
2bda0e17
KB
47{ ICONFILEHEADER iconFileHead; // ICON file header structure
48 ICONFILERES iconFileRes; // ICON file resource
33ac7e6f 49 UINT cbHead,
2bda0e17
KB
50 cbRes,
51 cbBits; // Used for reading in file
52 int hFile; // File handle
53 LPBITMAPINFO lpDIB; // Pointer to DIB memory
54 HANDLE hDIB;
55 int nWidth = GetSystemMetrics( SM_CXICON),
56 nHeight = GetSystemMetrics( SM_CYICON),
57 nDirEntries = 0;
58
59 // Open and read the .ICO file header and the first ICONFILERES
f6bcfd97 60 hFile = _lopen( wxConvertWX2MB(szFileName), OF_READ);
2bda0e17
KB
61 cbHead = _lread( hFile, (LPSTR)&iconFileHead, sizeof(ICONFILEHEADER));
62 cbRes = _lread( hFile, (LPSTR)&iconFileRes, sizeof(ICONFILERES));
63 ++nDirEntries;
64
65 if((cbHead != sizeof( ICONFILEHEADER)) || (cbRes != sizeof( ICONFILERES)))
57c208c5 66 return (HANDLE) NULL;
2bda0e17
KB
67 // Verify that it's an .ICON file
68 if( iconFileHead.wResourceType != 1)
57c208c5 69 return (HANDLE) NULL;
2bda0e17
KB
70
71 // inserted by P.S.
3897b707 72 while( (nDirEntries < iconFileHead.wResourceCount) &&
2bda0e17
KB
73 ((iconFileRes.bWidth != nWidth) || (iconFileRes.bHeight != nHeight)))
74 {
75 cbRes = _lread( hFile, (LPSTR )&iconFileRes, sizeof( ICONFILERES));
76 if(cbRes != sizeof( ICONFILERES))
57c208c5 77 return (HANDLE) NULL;
2bda0e17
KB
78 else
79 ++nDirEntries;
80 }
81
82 if(W != 0)
83 *W = iconFileRes.bWidth;
84 if(H != 0)
85 *H = iconFileRes.bHeight;
86
87 // Allocate and lock memory to read in the DIB
88 hDIB = GlobalAlloc(GHND, iconFileRes.dwDIBSize);
57c208c5
JS
89 if(hDIB == (HANDLE) NULL)
90 return (HANDLE) NULL;
91
2bda0e17
KB
92#ifdef __WINDOWS_386__
93 lpDIB = (LPBITMAPINFO)MK_FP32(GlobalLock(hDIB));
94#else
95 lpDIB = (LPBITMAPINFO)GlobalLock(hDIB);
96#endif
97
98 // Now read the DIB portion of the file, which follows the
99 // end of icon resource table
100 _llseek( hFile, iconFileRes.dwDIBOffset, 0);
101 cbBits = _lread( hFile, (LPSTR )lpDIB, (WORD )iconFileRes.dwDIBSize);
102
103 // Done reading file
104 _lclose(hFile);
105
106 GlobalUnlock( hDIB);
107
108 if( (DWORD )cbBits != iconFileRes.dwDIBSize)
109 {
110 GlobalFree( hDIB);
57c208c5 111 return (HANDLE) NULL;
2bda0e17
KB
112 }
113 return hDIB;
114}
115
116//*****************************************************************************
117//* Function : MakeIcon() *
118//* Purpose : Creates an icon based on the DIB info. returned by ReadIcon. *
119//* Parameters : HANDLE hDIB - A handle to the icon's DIB information. *
120//* Returns : A handle to an Icon. NULL is returned if an icon cannot be *
121//* successfully created. *
122//* Comments : The steps involved in making an icon from a DIB are very *
123//* similar to those involved in making a cursor from a DIB. *
124//* Steps : 1) Obtain a pointer to the Icon's DIB bits. *
125//* 2) Divide the DIB'd height with 2 to account for the fact that the*
126//* DIB stores both the XOR and the AND masks, one after the other.*
127//* 3) Determine the offset to the XOR bits. *
128//* 4) Determine the offset to the AND bits. *
129//* 5) Create a device dependent bitmap with the XOR bits. *
130//* 6) Obtain the device dependent XOR bitmask and save in memory. *
131//* The AND bitmask is monochrome. Monochrome bits are identical *
132//* in both the device dependent bitmaps and device independent *
133//* bitmaps. So, no need to convert the AND bitmask. *
134//* 7) Since a DIB is stored upside down, flip the monochrome AND bits*
135//* by scanlines. *
33ac7e6f 136//* 8) Use the XOR and AND bits and create an icon with CreateIcon. *
2bda0e17
KB
137//*****************************************************************************
138
139HICON MakeIcon( HANDLE hDIB, HINSTANCE hInst)
140{ LPSTR lpXORbits,
141 lpANDbits; // Pointer to XOR and AND bits
142 HBITMAP hbmXor; // handle to XOR bitmap
143 BITMAP bmpXor; // Used to manipulate XOR bitmap
144 DWORD dwBmpSize; // Size of XOR bitmap
145 HANDLE hXorDDB;
146 LPSTR lpXorDDB;
147 LONG szFlip[32];
148 int j,
149 k;
150 HDC hDC;
151 HICON hIcon;
152 LPBITMAPINFO lpDIB;
153
154 // 1) Obtain a pointer to the Icon's DIB bits.
155#ifdef __WINDOWS_386__
156 lpDIB = (LPBITMAPINFO )MK_FP32(GlobalLock( hDIB));
157#else
158 lpDIB = (LPBITMAPINFO )GlobalLock( hDIB);
159#endif
160
161 // 2) Divide the DIB'd height with 2 to account for the fact that the
162 // DIB stores both the XOR and the AND masks, one after the other.
163 lpDIB->bmiHeader.biHeight /= 2;
164
165 // 3) Determine the offset to the XOR bits.
166 // To obtain this value, we have to skip the header, and color table
167 lpXORbits = (LPSTR )lpDIB + (int )lpDIB->bmiHeader.biSize +
168 (DIBNumColors( (LPSTR )lpDIB) * sizeof( RGBQUAD));
169
170 // 4) Determine the offset to the AND bits.
171 // To obtain this value, skip the XOR bits
172 lpANDbits = lpXORbits + (int )(lpDIB->bmiHeader.biHeight *
173 (WIDTHBYTES ( lpDIB->bmiHeader.biWidth *
174 lpDIB->bmiHeader.biBitCount)));
175
176 // Get a hDC so we can create a bitmap compatible with it
223d09f6 177 hDC = CreateDC( wxT("DISPLAY"), NULL, NULL, NULL);
2bda0e17
KB
178
179 // 5) Create a device dependent bitmap with the XOR bits.
180 hbmXor = CreateDIBitmap( hDC, (LPBITMAPINFOHEADER)&(lpDIB->bmiHeader),
181 CBM_INIT, lpXORbits, lpDIB, DIB_RGB_COLORS);
182
183 GetObject( hbmXor, sizeof(BITMAP), (LPSTR)&bmpXor);
184
185 dwBmpSize = (DWORD )(bmpXor.bmWidthBytes * bmpXor.bmHeight * bmpXor.bmPlanes);
186 hXorDDB = GlobalAlloc( GHND, dwBmpSize);
57c208c5 187 if(hXorDDB == (HANDLE) NULL)
2bda0e17
KB
188 {
189 // clean up before quitting
190 DeleteObject( hbmXor);
191 DeleteDC( hDC);
192 GlobalUnlock( hDIB);
57c208c5 193 return (HICON) NULL;
2bda0e17
KB
194 }
195
196#ifdef __WINDOWS_386__
197 lpXorDDB = (LPSTR)MK_FP32(GlobalLock( hXorDDB));
198#else
199 lpXorDDB = (LPSTR)GlobalLock( hXorDDB);
200#endif
201
202 // 6) Obtain the device dependent XOR bitmask and save in memory.
203 // The AND bitmask is monochrome. Monochrome bits are identical
204 // in both the device dependent bitmaps and device independent
205 // bitmaps. So, no need to convert the AND bitmask.
206 GetBitmapBits( hbmXor, dwBmpSize, lpXorDDB);
207
208 // 7) Since a DIB is stored upside down, flip the monochrome AND bits by scanlines.
209 k = (int )lpDIB->bmiHeader.biHeight;
210 for( j = 0 ; j < k ; j++, lpANDbits += sizeof(DWORD))
211 szFlip[(k - 1) - j] = *(DWORD FAR *)lpANDbits;
212
213 // 8) Use the XOR and AND bits and create an icon with CreateIcon.
33ac7e6f
KB
214 hIcon = CreateIcon( hInst, bmpXor.bmWidth, bmpXor.bmHeight, (BYTE)bmpXor.bmPlanes,
215 (BYTE)bmpXor.bmBitsPixel, (const BYTE *)szFlip, (const BYTE *)lpXorDDB);
2bda0e17
KB
216
217 // Clean up before exiting.
218 DeleteObject( hbmXor);
219 GlobalUnlock( hXorDDB);
220 GlobalFree( hXorDDB);
221 DeleteDC( hDC);
222 GlobalUnlock( hDIB);
223
224 return hIcon;
225}
226
2bda0e17
KB
227//*****************************************************************************
228//* Function : IconToCursor() *
229//* Purpose : Reads an icon resource file and creates a cursor based on that *
230//* information. *
231//* Parameters : char *szFileName - The icon resource file. *
232//* Returns : A handle to a cursor. The handle will be NULL if a cursor can't*
233//* be created for any reason. *
234//* Comments : An icon may be in color. So, the DIB has to be forced to be *
235//* monochrome. *
236//*****************************************************************************
237
73c022c9 238HCURSOR IconToCursor( wxChar *szFileName, HINSTANCE hInst, int XHot, int YHot,
2bda0e17
KB
239 int *W, int *H)
240{ HCURSOR hCursor;
241 HANDLE hDIB;
242 POINT ptHotSpot;
243
57c208c5 244 if( (hDIB = ReadIcon( szFileName, W, H)) == (HANDLE) NULL)
2bda0e17 245 //read icon file to get icon DIB
57c208c5 246 return (HCURSOR) NULL;
2bda0e17
KB
247 // Set the hot spot of the cursor
248 ptHotSpot.x = XHot;
249 ptHotSpot.y = YHot;
250 hCursor = MakeCursor( hDIB, (LPPOINT )&ptHotSpot, hInst);
251 //create cursor from DIB
252 GlobalFree( hDIB);
253 return hCursor;
254}
255
256//*****************************************************************************
257//* Function : ReadCur() *
258//* Purpose : Reads a cursor resource file and extracts the DIB information. *
259//* Parameters : LPSTR szFileName - The cursor resource file. *
260//* Returns : A handle to a DIB. The handle will be NULL if the resource file*
261//* is corrupt or if memory cannot be allocated for the DIB info. *
262//*****************************************************************************
263
73c022c9 264HANDLE ReadCur( wxChar *szFileName, LPPOINT lpptHotSpot, int *W, int *H)
2bda0e17
KB
265{ CURFILEHEADER curFileHead; // CURSOR file header structure
266 CURFILERES curFileRes; // CURSOR file resource
33ac7e6f 267 UINT cbHead,
2bda0e17
KB
268 cbRes,
269 cbBits; // Used for reading in file
270 LPBITMAPINFO lpDIB; // Pointer to DIB memory
271 int hFile; // Handle to File
272 HANDLE hDIB;
273 int nWidth = GetSystemMetrics( SM_CXCURSOR),
274 nHeight = GetSystemMetrics( SM_CYCURSOR),
275 nDirEntries = 0;
276
277 // Open and read the .ICO file header and the first ICONFILERES
f6bcfd97 278 hFile = _lopen( wxConvertWX2MB(szFileName), OF_READ);
2bda0e17
KB
279 cbHead = _lread( hFile, (LPSTR )&curFileHead, sizeof( CURFILEHEADER));
280 cbRes = _lread( hFile, (LPSTR )&curFileRes, sizeof( CURFILERES));
281 ++nDirEntries;
282
283 if((cbHead != sizeof( CURFILEHEADER)) || (cbRes != sizeof( CURFILERES)))
57c208c5 284 return (HANDLE) NULL;
2bda0e17
KB
285
286 // Verify that it's an .CUR file
287 if ((curFileRes.bReserved1 != 0) || (curFileHead.wResourceType != 2))
57c208c5 288 return (HANDLE) NULL;
2bda0e17
KB
289
290 // following added by P.S.
3897b707 291 while( (nDirEntries < curFileHead.wResourceCount) &&
2bda0e17
KB
292 ((curFileRes.bWidth != nWidth) || (curFileRes.bHeight != nHeight)))
293 {
294 cbRes = _lread( hFile, (LPSTR )&curFileRes, sizeof( CURFILERES));
295 if(cbRes != sizeof( CURFILERES))
57c208c5 296 return (HANDLE) NULL;
2bda0e17
KB
297 else
298 ++nDirEntries;
299 }
300 if(W != 0)
301 *W = curFileRes.bWidth;
302 if(H != 0)
303 *H = curFileRes.bHeight;
304
305
306 // Allocate & lock memory to read in the DIB
307 hDIB = GlobalAlloc(GHND, curFileRes.dwDIBSize);
57c208c5
JS
308 if(hDIB == (HANDLE) NULL)
309 return (HANDLE) NULL;
2bda0e17
KB
310
311#ifdef __WINDOWS_386__
312 lpDIB = (LPBITMAPINFO )MK_FP32(GlobalLock(hDIB));
313#else
314 lpDIB = (LPBITMAPINFO )GlobalLock(hDIB);
315#endif
316
317 // Now read the DIB portion of the file, which follows the
318 // end of icon resource table
319 _llseek( hFile, curFileRes.dwDIBOffset, 0);
320 cbBits = _lread( hFile, (LPSTR )lpDIB, (WORD )curFileRes.dwDIBSize);
321
322 // Done reading file
323 _lclose(hFile);
324
325 if((DWORD)cbBits != curFileRes.dwDIBSize)
326 {
327 GlobalUnlock( hDIB);
328 GlobalFree( hDIB);
57c208c5 329 return (HANDLE) NULL;
2bda0e17 330 }
57c208c5 331 if(lpptHotSpot != (LPPOINT) NULL) // If it is necessary to know the hot spot
2bda0e17
KB
332 {
333 lpptHotSpot->x = (int )curFileRes.wXHotspot;
334 lpptHotSpot->y = (int )curFileRes.wYHotspot;
335 }
336 GlobalUnlock( hDIB);
337 return( hDIB);
338}
339
2bda0e17
KB
340//*****************************************************************************
341//* Function : MakeCursor() *
342//* Purpose : Creates a cursor based on the DIB info. returned by ReadCursor.*
343//* Parameters : HANDLE hDIB - A handle to the cursor's DIB information. *
344//* LPPOINT lppt - A pointer to a point struct. indicating the *
345//* location of the Cursor's hot spot. *
346//* Returns : A handle to a cursor. NULL is returned if a cursor cannot be *
347//* successfully created. *
348//* Comments : The steps involved in making a cursor from a DIB are very *
349//* similar to those involved in making an icon from a DIB. *
350//* Steps : 1) Obtain a pointer to the Cursor's DIB bits. *
351//* 2) Divide the DIB's height with 2 to account for the fact that the*
352//* DIB stores both the XOR and the AND masks, one after the other.*
353//* 3) Determine the offset to the XOR bits. *
354//* 4) Determine the offset to the AND bits. *
355//* 5) Create a device dependent bitmap with the XOR bits. *
356//* 6) Obtain the device dependent XOR bitmask and save in memory. *
357//* The AND bitmask is monochrome. Monochrome bits are identical *
358//* in both the device dependent bitmaps and device independent *
359//* bitmaps. So, no need to convert the AND bitmask. *
360//* 7) Since a DIB is stored upside down, flip the monochrome AND bits*
361//* by scanlines. *
362//* 8) Use the XOR and AND bits and create a cursor with CreateCursor.*
363//*****************************************************************************
364
365HCURSOR MakeCursor( HANDLE hDIB, LPPOINT lpptHotSpot, HINSTANCE hInst)
366{ LPSTR lpXORbits,
367 lpANDbits; // Pointer to XOR and AND bits
368 HBITMAP hbmXor; // handle to XOR bitmap
369 BITMAP bmpXor; // Used to manipulate XOR bitmap
370 DWORD dwBmpSize; // Size of XOR bitmap
371 HCURSOR hCursor;
372 HANDLE hXorDDB;
373 LPSTR lpXorDDB;
374 LONG szFlip[32];
375 int j,
376 k;
377 HDC hDC;
378 LPBITMAPINFO lpDIB;
379
380 // 1) Obtain a pointer to the Cursor's DIB bits.
381#ifdef __WINDOWS_386__
382 lpDIB = (LPBITMAPINFO )MK_FP32(GlobalLock( hDIB));
383#else
384 lpDIB = (LPBITMAPINFO )GlobalLock( hDIB);
385#endif
386
387 // 2) Divide the DIB's height with 2 to account for the fact that the
388 // DIB stores both the XOR and the AND masks, one after the other.
389 lpDIB->bmiHeader.biHeight /= 2;
390
391 // 3) Determine the offset to the XOR bits.
392 // To obtain this value, we have to skip the header, and color table
393 lpXORbits = (LPSTR )lpDIB + (int )lpDIB->bmiHeader.biSize +
394 (DIBNumColors((LPSTR)lpDIB) * sizeof(RGBQUAD));
395
396 // 4) Determine the offset to the AND bits
397 // To obtain this value, skip the XOR bits
398 lpANDbits = lpXORbits + (int )( lpDIB->bmiHeader.biHeight *
399 (WIDTHBYTES( lpDIB->bmiHeader.biWidth *
400 lpDIB->bmiHeader.biBitCount)));
401
402 // Get a hDC so we can create a bitmap compatible with it
223d09f6 403 hDC = CreateDC( wxT("DISPLAY"), NULL, NULL, NULL);
2bda0e17
KB
404
405 // 5) Create a device dependent bitmap with the XOR bits.
406 hbmXor = CreateBitmap( (int )lpDIB->bmiHeader.biWidth,
407 (int )lpDIB->bmiHeader.biHeight, 1, 1, NULL);
408 SetDIBits( hDC, hbmXor, 0, (WORD)lpDIB->bmiHeader.biHeight, lpXORbits,
409 lpDIB, DIB_RGB_COLORS);
410 GetObject( hbmXor, sizeof( BITMAP), (LPSTR )&bmpXor);
411
412 dwBmpSize = (DWORD )(bmpXor.bmWidthBytes * bmpXor.bmHeight * bmpXor.bmPlanes);
413 hXorDDB = GlobalAlloc( GHND, dwBmpSize);
57c208c5 414 if(hXorDDB == (HANDLE) NULL)
2bda0e17
KB
415 { // clean up before quitting
416 DeleteObject( hbmXor);
417 DeleteDC( hDC);
418 GlobalUnlock( hDIB);
57c208c5 419 return (HCURSOR) NULL;
2bda0e17
KB
420 }
421#ifdef __WINDOWS_386__
422 lpXorDDB = (LPSTR)MK_FP32(GlobalLock( hXorDDB));
423#else
424 lpXorDDB = (LPSTR)GlobalLock( hXorDDB);
425#endif
426
427 // 6) Obtain the device dependent XOR bitmask and save in memory.
428 // The AND bitmask is monochrome. Monochrome bits are identical
429 // in both the device dependent bitmaps and device independent
430 // bitmaps. So, no need to convert the AND bitmask.
431 GetBitmapBits( hbmXor, dwBmpSize, lpXorDDB);
432
433 // 7) Since a DIB is stored upside down, flip the monochrome AND bits by scanlines.
434 k = (int)lpDIB->bmiHeader.biHeight;
435 for( j = 0 ; j < k; j++, lpANDbits += sizeof( DWORD))
436 szFlip[(k - 1) - j] = *(DWORD FAR *)lpANDbits;
437
438 // 8) Use the XOR and AND bits and create a cursor with CreateCursor.
439 hCursor = CreateCursor( hInst, lpptHotSpot->x, lpptHotSpot->y,
440 bmpXor.bmWidth, bmpXor.bmHeight, (LPSTR)szFlip, lpXorDDB);
441
442 // Clean up before exiting.
443 DeleteObject( hbmXor);
444 GlobalUnlock( hXorDDB);
445 GlobalFree( hXorDDB);
446 DeleteDC( hDC);
447 GlobalUnlock( hDIB);
448
449 return hCursor;
450}
451
2bda0e17
KB
452//*****************************************************************************
453//* Function : DIBNumColors() *
454//* Purpose : This function calculates the number of colors in the DIB's *
455//* color table by finding the bits per pixel for the DIB (whether *
456//* Win3.0 or OS/2-style DIB). If bits per pixel is 1: colors=2, *
457//* if 4: colors=16, if 8: colors=256, if 24, no colors in color *
458//* table. *
459//* Parameters : LPSTR lpbi - pointer to packed-DIB memory block. *
460//* Returns : The number of colors in the color table. *
461//*****************************************************************************
462
463WORD DIBNumColors ( LPSTR pv)
464{ int bits;
465 BITMAPINFOHEADER *lpbi;
466 BITMAPCOREHEADER *lpbc;
467
468 lpbi = ((BITMAPINFOHEADER* )pv); // assume win 3.0 style DIBs
469 lpbc = ((BITMAPCOREHEADER* )pv); // assume OS/2 style DIBs
470
471 // With the BITMAPINFO format headers, the size of the palette
472 // is in biClrUsed, whereas in the BITMAPCORE - style headers, it
473 // is dependent on the bits per pixel ( = 2 raised to the power of
474 // bits/pixel).
33ac7e6f 475
2bda0e17
KB
476 if(lpbi->biSize != sizeof( BITMAPCOREHEADER))
477 {
478 if(lpbi->biClrUsed != 0)
479 return (WORD)lpbi->biClrUsed;
480 bits = lpbi->biBitCount;
481 }
482 else
483 bits = lpbc->bcBitCount;
484
485 switch( bits)
486 {
487 case 1:
488 return 2;
489 case 4:
490 return 16;
491 case 8:
492 return 256;
493 default:
494 // A 24 bitcount DIB has no color table
495 return 0;
496 }
497}
498
1cfa5d8e 499// Added JACS 23/6/95
2bda0e17
KB
500HCURSOR MakeCursorFromBitmap(HINSTANCE hInst, HBITMAP hBitmap, POINT *pPoint)
501{
502 HDC hDCColor, hDCMono;
503 HDC hDC;
504 HBITMAP hBmpOld;
505 HBITMAP hAndBmp;
506 HBITMAP hXorBmp;
507 HCURSOR hNewCursor;
508 BITMAP bm;
509 DWORD dwBytes;
510 NPSTR andBits;
511 NPSTR xorBits;
512
57c208c5 513 hDC = GetDC((HWND) NULL);
2bda0e17
KB
514 hDCColor = CreateCompatibleDC(hDC);
515 hDCMono = CreateCompatibleDC(hDC);
516 hAndBmp = CreateCompatibleBitmap(hDCMono, 32, 32);
517 hXorBmp = CreateCompatibleBitmap(hDCMono, 32, 32);
518
c4e7c2aa 519 hBmpOld = (HBITMAP) SelectObject(hDCColor, hBitmap);
2bda0e17
KB
520 SelectObject(hDCMono, hAndBmp);
521 SetBkColor(hDCColor, RGB(191, 191, 191));
522
523 BitBlt(hDCMono, 0, 0, 32, 32, hDCColor, 0, 0, SRCCOPY);
524
525 // Now we have the AND Mask
526
527 GetObject(hAndBmp, sizeof(BITMAP), (LPSTR) &bm);
528 dwBytes = (bm.bmWidthBytes * bm.bmHeight);
529 andBits = (NPSTR) LocalAlloc(LPTR, dwBytes);
530 GetBitmapBits(hAndBmp, dwBytes, andBits);
531
532 SelectObject(hDCMono, hXorBmp);
533 SetBkColor(hDCColor, RGB(0, 0, 0));
534
535 BitBlt(hDCMono, 0, 0, 32, 32, hDCColor, 0, 0, SRCCOPY);
536
537 // Now we have the XOR Mask
538
539 GetObject(hXorBmp, sizeof(BITMAP), (LPSTR) &bm);
540 dwBytes = (bm.bmWidthBytes * bm.bmHeight);
541 xorBits = (NPSTR) LocalAlloc(LPTR, dwBytes);
542 GetBitmapBits(hXorBmp, dwBytes, xorBits);
543
544 if (pPoint->x > 32)
545 pPoint->x = 32;
546 if (pPoint->y > 32)
547 pPoint->y = 32;
548
549 hNewCursor = CreateCursor(hInst,
550 pPoint->x, pPoint->y, 32, 32, andBits, xorBits);
551
552 SelectObject(hDCColor, hBmpOld);
553 SelectObject(hDCMono, hBmpOld);
554 DeleteDC(hDCColor);
555 DeleteDC(hDCMono);
556 DeleteObject(hAndBmp);
557 DeleteObject(hXorBmp);
558 ReleaseDC(NULL, hDC);
559#ifndef __WIN32__
27a9bd48
PA
560#ifdef STRICT
561 LocalUnlock(LocalHandle((void NEAR*) andBits));
562 LocalUnlock(LocalHandle((void NEAR*) xorBits));
563 LocalFree(LocalHandle((void NEAR*) andBits));
564 LocalFree(LocalHandle((void NEAR*) xorBits));
565#else
2bda0e17
KB
566 LocalUnlock(LocalHandle((WORD) andBits));
567 LocalUnlock(LocalHandle((WORD) xorBits));
568 LocalFree(LocalHandle((WORD) andBits));
569 LocalFree(LocalHandle((WORD) xorBits));
27a9bd48 570#endif
2bda0e17
KB
571#else
572 LocalUnlock(LocalHandle((LPCVOID) andBits));
573 LocalUnlock(LocalHandle((LPCVOID) xorBits));
574 LocalFree(LocalHandle((LPCVOID) andBits));
575 LocalFree(LocalHandle((LPCVOID) xorBits));
576#endif
577 return hNewCursor;
578}
579