]>
Commit | Line | Data |
---|---|---|
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 | 46 | HANDLE 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 | ||
139 | HICON 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 | 238 | HCURSOR 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 | 264 | HANDLE 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 | ||
365 | HCURSOR 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 | ||
463 | WORD 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 |
500 | HCURSOR 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 |