Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 1 | /* |
| 2 | * Cursor and icon support |
| 3 | * |
| 4 | * Copyright 1995 Alexandre Julliard |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 5 | * 1996 Martin Von Loewis |
| 6 | * 1997 Alex Korobka |
Turchanov Sergey | 62d6e98 | 1998-10-18 13:42:55 +0000 | [diff] [blame] | 7 | * 1998 Turchanov Sergey |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 8 | */ |
| 9 | |
| 10 | /* |
| 11 | * Theory: |
| 12 | * |
Alexandre Julliard | 7ff1c41 | 1997-05-25 13:58:18 +0000 | [diff] [blame] | 13 | * http://www.microsoft.com/win32dev/ui/icons.htm |
| 14 | * |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 15 | * Cursors and icons are stored in a global heap block, with the |
| 16 | * following layout: |
| 17 | * |
| 18 | * CURSORICONINFO info; |
| 19 | * BYTE[] ANDbits; |
| 20 | * BYTE[] XORbits; |
| 21 | * |
| 22 | * The bits structures are in the format of a device-dependent bitmap. |
| 23 | * |
| 24 | * This layout is very sub-optimal, as the bitmap bits are stored in |
| 25 | * the X client instead of in the server like other bitmaps; however, |
| 26 | * some programs (notably Paint Brush) expect to be able to manipulate |
| 27 | * the bits directly :-( |
Turchanov Sergey | 62d6e98 | 1998-10-18 13:42:55 +0000 | [diff] [blame] | 28 | * |
| 29 | * FIXME: what are we going to do with animation and color (bpp > 1) cursors ?! |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 30 | */ |
| 31 | |
| 32 | #include <string.h> |
| 33 | #include <stdlib.h> |
Patrik Stridvall | b87fe2e | 1999-04-01 08:16:08 +0000 | [diff] [blame] | 34 | |
Jeremy White | d3e22d9 | 2000-02-10 19:03:02 +0000 | [diff] [blame] | 35 | #include "windef.h" |
| 36 | #include "wingdi.h" |
Marcus Meissner | 61afa33 | 1999-02-22 10:16:00 +0000 | [diff] [blame] | 37 | #include "wine/winbase16.h" |
Patrik Stridvall | b87fe2e | 1999-04-01 08:16:08 +0000 | [diff] [blame] | 38 | #include "wine/winuser16.h" |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 39 | #include "heap.h" |
Alexandre Julliard | 5ab9d86 | 2000-08-09 22:35:05 +0000 | [diff] [blame] | 40 | #include "palette.h" |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 41 | #include "bitmap.h" |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 42 | #include "cursoricon.h" |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 43 | #include "module.h" |
Alexandre Julliard | 06c275a | 1999-05-02 14:32:27 +0000 | [diff] [blame] | 44 | #include "debugtools.h" |
Alexandre Julliard | 44ed71f | 1997-12-21 19:17:50 +0000 | [diff] [blame] | 45 | #include "user.h" |
Ulrich Weigand | a11ce32 | 1998-11-08 12:27:26 +0000 | [diff] [blame] | 46 | #include "input.h" |
Ulrich Weigand | 431d1a0 | 1998-11-14 18:57:47 +0000 | [diff] [blame] | 47 | #include "message.h" |
Alexandre Julliard | f90efa9 | 1998-06-14 15:24:15 +0000 | [diff] [blame] | 48 | #include "winerror.h" |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 49 | |
Alexandre Julliard | b52aed4 | 2000-03-24 21:40:30 +0000 | [diff] [blame] | 50 | DECLARE_DEBUG_CHANNEL(cursor); |
| 51 | DECLARE_DEBUG_CHANNEL(icon); |
| 52 | DECLARE_DEBUG_CHANNEL(resource); |
Patrik Stridvall | b4b9fae | 1999-04-19 14:56:29 +0000 | [diff] [blame] | 53 | |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 54 | static HCURSOR hActiveCursor = 0; /* Active cursor */ |
| 55 | static INT CURSOR_ShowCount = 0; /* Cursor display count */ |
| 56 | static RECT CURSOR_ClipRect; /* Cursor clipping rect */ |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 57 | |
Alexandre Julliard | 16cbf40 | 2001-01-18 20:32:01 +0000 | [diff] [blame] | 58 | static HDC screen_dc; |
Ulrich Weigand | 50a0915 | 1999-03-10 14:00:29 +0000 | [diff] [blame] | 59 | |
| 60 | /********************************************************************** |
| 61 | * ICONCACHE for cursors/icons loaded with LR_SHARED. |
| 62 | * |
| 63 | * FIXME: This should not be allocated on the system heap, but on a |
| 64 | * subsystem-global heap (i.e. one for all Win16 processes, |
François Gouget | 4188fbc | 2001-02-14 21:43:06 +0000 | [diff] [blame] | 65 | * and one for each Win32 process). |
Ulrich Weigand | 50a0915 | 1999-03-10 14:00:29 +0000 | [diff] [blame] | 66 | */ |
| 67 | typedef struct tagICONCACHE |
| 68 | { |
| 69 | struct tagICONCACHE *next; |
| 70 | |
| 71 | HMODULE hModule; |
| 72 | HRSRC hRsrc; |
Pierre Mageau | 4ac8db7 | 1999-09-04 11:16:48 +0000 | [diff] [blame] | 73 | HRSRC hGroupRsrc; |
Ulrich Weigand | 50a0915 | 1999-03-10 14:00:29 +0000 | [diff] [blame] | 74 | HANDLE handle; |
| 75 | |
| 76 | INT count; |
| 77 | |
| 78 | } ICONCACHE; |
| 79 | |
| 80 | static ICONCACHE *IconAnchor = NULL; |
Alexandre Julliard | 301df6b | 2001-08-16 18:12:56 +0000 | [diff] [blame] | 81 | static CRITICAL_SECTION IconCrst = CRITICAL_SECTION_INIT("IconCrst"); |
Dave Hawkes | dbb6ab2 | 2000-07-09 12:16:58 +0000 | [diff] [blame] | 82 | static WORD ICON_HOTSPOT = 0x4242; |
Ulrich Weigand | 50a0915 | 1999-03-10 14:00:29 +0000 | [diff] [blame] | 83 | |
Alexandre Julliard | 982a223 | 2000-12-13 20:20:09 +0000 | [diff] [blame] | 84 | |
| 85 | /*********************************************************************** |
| 86 | * map_fileW |
| 87 | * |
| 88 | * Helper function to map a file to memory: |
| 89 | * name - file name |
| 90 | * [RETURN] ptr - pointer to mapped file |
| 91 | */ |
| 92 | static void *map_fileW( LPCWSTR name ) |
| 93 | { |
| 94 | HANDLE hFile, hMapping; |
| 95 | LPVOID ptr = NULL; |
| 96 | |
| 97 | hFile = CreateFileW( name, GENERIC_READ, FILE_SHARE_READ, NULL, |
| 98 | OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS, 0 ); |
| 99 | if (hFile != INVALID_HANDLE_VALUE) |
| 100 | { |
| 101 | hMapping = CreateFileMappingA( hFile, NULL, PAGE_READONLY, 0, 0, NULL ); |
| 102 | CloseHandle( hFile ); |
| 103 | if (hMapping) |
| 104 | { |
| 105 | ptr = MapViewOfFile( hMapping, FILE_MAP_READ, 0, 0, 0 ); |
| 106 | CloseHandle( hMapping ); |
| 107 | } |
| 108 | } |
| 109 | return ptr; |
| 110 | } |
| 111 | |
| 112 | |
Ulrich Weigand | 50a0915 | 1999-03-10 14:00:29 +0000 | [diff] [blame] | 113 | /********************************************************************** |
Ulrich Weigand | 50a0915 | 1999-03-10 14:00:29 +0000 | [diff] [blame] | 114 | * CURSORICON_FindSharedIcon |
| 115 | */ |
| 116 | static HANDLE CURSORICON_FindSharedIcon( HMODULE hModule, HRSRC hRsrc ) |
| 117 | { |
| 118 | HANDLE handle = 0; |
| 119 | ICONCACHE *ptr; |
| 120 | |
| 121 | EnterCriticalSection( &IconCrst ); |
| 122 | |
| 123 | for ( ptr = IconAnchor; ptr; ptr = ptr->next ) |
| 124 | if ( ptr->hModule == hModule && ptr->hRsrc == hRsrc ) |
| 125 | { |
| 126 | ptr->count++; |
| 127 | handle = ptr->handle; |
| 128 | break; |
| 129 | } |
| 130 | |
| 131 | LeaveCriticalSection( &IconCrst ); |
| 132 | |
| 133 | return handle; |
| 134 | } |
| 135 | |
Pierre Mageau | 4ac8db7 | 1999-09-04 11:16:48 +0000 | [diff] [blame] | 136 | /************************************************************************* |
| 137 | * CURSORICON_FindCache |
| 138 | * |
Andreas Mohr | a59324d | 2000-11-25 01:40:10 +0000 | [diff] [blame] | 139 | * Given a handle, find the corresponding cache element |
Pierre Mageau | 4ac8db7 | 1999-09-04 11:16:48 +0000 | [diff] [blame] | 140 | * |
| 141 | * PARAMS |
| 142 | * Handle [I] handle to an Image |
| 143 | * |
| 144 | * RETURNS |
| 145 | * Success: The cache entry |
| 146 | * Failure: NULL |
| 147 | * |
| 148 | */ |
| 149 | static ICONCACHE* CURSORICON_FindCache(HANDLE handle) |
| 150 | { |
| 151 | ICONCACHE *ptr; |
| 152 | ICONCACHE *pRet=NULL; |
| 153 | BOOL IsFound = FALSE; |
| 154 | int count; |
| 155 | |
| 156 | EnterCriticalSection( &IconCrst ); |
| 157 | |
| 158 | for (count = 0, ptr = IconAnchor; ptr != NULL && !IsFound; ptr = ptr->next, count++ ) |
| 159 | { |
| 160 | if ( handle == ptr->handle ) |
| 161 | { |
| 162 | IsFound = TRUE; |
| 163 | pRet = ptr; |
| 164 | } |
| 165 | } |
| 166 | |
| 167 | LeaveCriticalSection( &IconCrst ); |
| 168 | |
| 169 | return pRet; |
| 170 | } |
| 171 | |
Ulrich Weigand | 50a0915 | 1999-03-10 14:00:29 +0000 | [diff] [blame] | 172 | /********************************************************************** |
| 173 | * CURSORICON_AddSharedIcon |
| 174 | */ |
Pierre Mageau | 4ac8db7 | 1999-09-04 11:16:48 +0000 | [diff] [blame] | 175 | static void CURSORICON_AddSharedIcon( HMODULE hModule, HRSRC hRsrc, HRSRC hGroupRsrc, HANDLE handle ) |
Ulrich Weigand | 50a0915 | 1999-03-10 14:00:29 +0000 | [diff] [blame] | 176 | { |
Alexandre Julliard | da2892c | 2001-02-23 01:13:42 +0000 | [diff] [blame] | 177 | ICONCACHE *ptr = HeapAlloc( GetProcessHeap(), 0, sizeof(ICONCACHE) ); |
Ulrich Weigand | 50a0915 | 1999-03-10 14:00:29 +0000 | [diff] [blame] | 178 | if ( !ptr ) return; |
| 179 | |
| 180 | ptr->hModule = hModule; |
| 181 | ptr->hRsrc = hRsrc; |
| 182 | ptr->handle = handle; |
Pierre Mageau | 4ac8db7 | 1999-09-04 11:16:48 +0000 | [diff] [blame] | 183 | ptr->hGroupRsrc = hGroupRsrc; |
Ulrich Weigand | 50a0915 | 1999-03-10 14:00:29 +0000 | [diff] [blame] | 184 | ptr->count = 1; |
| 185 | |
| 186 | EnterCriticalSection( &IconCrst ); |
| 187 | ptr->next = IconAnchor; |
| 188 | IconAnchor = ptr; |
| 189 | LeaveCriticalSection( &IconCrst ); |
| 190 | } |
| 191 | |
| 192 | /********************************************************************** |
| 193 | * CURSORICON_DelSharedIcon |
| 194 | */ |
| 195 | static INT CURSORICON_DelSharedIcon( HANDLE handle ) |
| 196 | { |
| 197 | INT count = -1; |
| 198 | ICONCACHE *ptr; |
| 199 | |
| 200 | EnterCriticalSection( &IconCrst ); |
| 201 | |
| 202 | for ( ptr = IconAnchor; ptr; ptr = ptr->next ) |
| 203 | if ( ptr->handle == handle ) |
| 204 | { |
| 205 | if ( ptr->count > 0 ) ptr->count--; |
| 206 | count = ptr->count; |
| 207 | break; |
| 208 | } |
| 209 | |
| 210 | LeaveCriticalSection( &IconCrst ); |
| 211 | |
| 212 | return count; |
| 213 | } |
| 214 | |
| 215 | /********************************************************************** |
| 216 | * CURSORICON_FreeModuleIcons |
| 217 | */ |
| 218 | void CURSORICON_FreeModuleIcons( HMODULE hModule ) |
| 219 | { |
| 220 | ICONCACHE **ptr = &IconAnchor; |
| 221 | |
| 222 | if ( HIWORD( hModule ) ) |
| 223 | hModule = MapHModuleLS( hModule ); |
| 224 | else |
| 225 | hModule = GetExePtr( hModule ); |
| 226 | |
| 227 | EnterCriticalSection( &IconCrst ); |
| 228 | |
| 229 | while ( *ptr ) |
| 230 | { |
| 231 | if ( (*ptr)->hModule == hModule ) |
| 232 | { |
| 233 | ICONCACHE *freePtr = *ptr; |
| 234 | *ptr = freePtr->next; |
| 235 | |
| 236 | GlobalFree16( freePtr->handle ); |
Alexandre Julliard | da2892c | 2001-02-23 01:13:42 +0000 | [diff] [blame] | 237 | HeapFree( GetProcessHeap(), 0, freePtr ); |
Ulrich Weigand | 50a0915 | 1999-03-10 14:00:29 +0000 | [diff] [blame] | 238 | continue; |
| 239 | } |
| 240 | ptr = &(*ptr)->next; |
| 241 | } |
| 242 | |
| 243 | LeaveCriticalSection( &IconCrst ); |
| 244 | } |
| 245 | |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 246 | /********************************************************************** |
| 247 | * CURSORICON_FindBestIcon |
| 248 | * |
| 249 | * Find the icon closest to the requested size and number of colors. |
| 250 | */ |
Juergen Schmied | c45bbee | 1999-04-11 11:46:32 +0000 | [diff] [blame] | 251 | static CURSORICONDIRENTRY *CURSORICON_FindBestIcon( CURSORICONDIR *dir, int width, |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 252 | int height, int colors ) |
| 253 | { |
Pierre Mageau | 4ac8db7 | 1999-09-04 11:16:48 +0000 | [diff] [blame] | 254 | int i; |
Juergen Schmied | c45bbee | 1999-04-11 11:46:32 +0000 | [diff] [blame] | 255 | CURSORICONDIRENTRY *entry, *bestEntry = NULL; |
Pierre Mageau | 4ac8db7 | 1999-09-04 11:16:48 +0000 | [diff] [blame] | 256 | UINT iTotalDiff, iXDiff=0, iYDiff=0, iColorDiff; |
| 257 | UINT iTempXDiff, iTempYDiff, iTempColorDiff; |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 258 | |
| 259 | if (dir->idCount < 1) |
| 260 | { |
Alexandre Julliard | 06c275a | 1999-05-02 14:32:27 +0000 | [diff] [blame] | 261 | WARN_(icon)("Empty directory!\n" ); |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 262 | return NULL; |
| 263 | } |
Juergen Schmied | c45bbee | 1999-04-11 11:46:32 +0000 | [diff] [blame] | 264 | if (dir->idCount == 1) return &dir->idEntries[0]; /* No choice... */ |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 265 | |
Pierre Mageau | 4ac8db7 | 1999-09-04 11:16:48 +0000 | [diff] [blame] | 266 | /* Find Best Fit */ |
| 267 | iTotalDiff = 0xFFFFFFFF; |
| 268 | iColorDiff = 0xFFFFFFFF; |
Juergen Schmied | c45bbee | 1999-04-11 11:46:32 +0000 | [diff] [blame] | 269 | for (i = 0, entry = &dir->idEntries[0]; i < dir->idCount; i++,entry++) |
Pierre Mageau | 4ac8db7 | 1999-09-04 11:16:48 +0000 | [diff] [blame] | 270 | { |
| 271 | iTempXDiff = abs(width - entry->ResInfo.icon.bWidth); |
| 272 | iTempYDiff = abs(height - entry->ResInfo.icon.bHeight); |
| 273 | |
| 274 | if(iTotalDiff > (iTempXDiff + iTempYDiff)) |
| 275 | { |
| 276 | iXDiff = iTempXDiff; |
| 277 | iYDiff = iTempYDiff; |
| 278 | iTotalDiff = iXDiff + iYDiff; |
| 279 | } |
| 280 | } |
| 281 | |
| 282 | /* Find Best Colors for Best Fit */ |
| 283 | for (i = 0, entry = &dir->idEntries[0]; i < dir->idCount; i++,entry++) |
| 284 | { |
| 285 | if(abs(width - entry->ResInfo.icon.bWidth) == iXDiff && |
| 286 | abs(height - entry->ResInfo.icon.bHeight) == iYDiff) |
| 287 | { |
| 288 | iTempColorDiff = abs(colors - entry->ResInfo.icon.bColorCount); |
| 289 | if(iColorDiff > iTempColorDiff) |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 290 | { |
| 291 | bestEntry = entry; |
Pierre Mageau | 4ac8db7 | 1999-09-04 11:16:48 +0000 | [diff] [blame] | 292 | iColorDiff = iTempColorDiff; |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 293 | } |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 294 | } |
Pierre Mageau | 4ac8db7 | 1999-09-04 11:16:48 +0000 | [diff] [blame] | 295 | } |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 296 | |
| 297 | return bestEntry; |
| 298 | } |
| 299 | |
| 300 | |
| 301 | /********************************************************************** |
| 302 | * CURSORICON_FindBestCursor |
| 303 | * |
| 304 | * Find the cursor closest to the requested size. |
Turchanov Sergey | 62d6e98 | 1998-10-18 13:42:55 +0000 | [diff] [blame] | 305 | * FIXME: parameter 'color' ignored and entries with more than 1 bpp |
| 306 | * ignored too |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 307 | */ |
Juergen Schmied | c45bbee | 1999-04-11 11:46:32 +0000 | [diff] [blame] | 308 | static CURSORICONDIRENTRY *CURSORICON_FindBestCursor( CURSORICONDIR *dir, |
Turchanov Sergey | 62d6e98 | 1998-10-18 13:42:55 +0000 | [diff] [blame] | 309 | int width, int height, int color) |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 310 | { |
| 311 | int i, maxwidth, maxheight; |
Juergen Schmied | c45bbee | 1999-04-11 11:46:32 +0000 | [diff] [blame] | 312 | CURSORICONDIRENTRY *entry, *bestEntry = NULL; |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 313 | |
| 314 | if (dir->idCount < 1) |
| 315 | { |
Alexandre Julliard | 06c275a | 1999-05-02 14:32:27 +0000 | [diff] [blame] | 316 | WARN_(cursor)("Empty directory!\n" ); |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 317 | return NULL; |
| 318 | } |
Juergen Schmied | c45bbee | 1999-04-11 11:46:32 +0000 | [diff] [blame] | 319 | if (dir->idCount == 1) return &dir->idEntries[0]; /* No choice... */ |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 320 | |
Steve Tibbett | 85692c8 | 1999-08-15 16:35:21 +0000 | [diff] [blame] | 321 | /* Double height to account for AND and XOR masks */ |
| 322 | |
| 323 | height *= 2; |
| 324 | |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 325 | /* First find the largest one smaller than or equal to the requested size*/ |
| 326 | |
| 327 | maxwidth = maxheight = 0; |
Juergen Schmied | c45bbee | 1999-04-11 11:46:32 +0000 | [diff] [blame] | 328 | for(i = 0,entry = &dir->idEntries[0]; i < dir->idCount; i++,entry++) |
| 329 | if ((entry->ResInfo.cursor.wWidth <= width) && (entry->ResInfo.cursor.wHeight <= height) && |
| 330 | (entry->ResInfo.cursor.wWidth > maxwidth) && (entry->ResInfo.cursor.wHeight > maxheight) && |
Turchanov Sergey | 62d6e98 | 1998-10-18 13:42:55 +0000 | [diff] [blame] | 331 | (entry->wBitCount == 1)) |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 332 | { |
| 333 | bestEntry = entry; |
Juergen Schmied | c45bbee | 1999-04-11 11:46:32 +0000 | [diff] [blame] | 334 | maxwidth = entry->ResInfo.cursor.wWidth; |
| 335 | maxheight = entry->ResInfo.cursor.wHeight; |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 336 | } |
| 337 | if (bestEntry) return bestEntry; |
| 338 | |
| 339 | /* Now find the smallest one larger than the requested size */ |
| 340 | |
| 341 | maxwidth = maxheight = 255; |
Juergen Schmied | c45bbee | 1999-04-11 11:46:32 +0000 | [diff] [blame] | 342 | for(i = 0,entry = &dir->idEntries[0]; i < dir->idCount; i++,entry++) |
| 343 | if ((entry->ResInfo.cursor.wWidth < maxwidth) && (entry->ResInfo.cursor.wHeight < maxheight) && |
Turchanov Sergey | 62d6e98 | 1998-10-18 13:42:55 +0000 | [diff] [blame] | 344 | (entry->wBitCount == 1)) |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 345 | { |
| 346 | bestEntry = entry; |
Juergen Schmied | c45bbee | 1999-04-11 11:46:32 +0000 | [diff] [blame] | 347 | maxwidth = entry->ResInfo.cursor.wWidth; |
| 348 | maxheight = entry->ResInfo.cursor.wHeight; |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 349 | } |
| 350 | |
| 351 | return bestEntry; |
| 352 | } |
| 353 | |
Turchanov Sergey | 62d6e98 | 1998-10-18 13:42:55 +0000 | [diff] [blame] | 354 | /********************************************************************* |
| 355 | * The main purpose of this function is to create fake resource directory |
| 356 | * and fake resource entries. There are several reasons for this: |
| 357 | * - CURSORICONDIR and CURSORICONFILEDIR differ in sizes and their |
| 358 | * fields |
| 359 | * There are some "bad" cursor files which do not have |
| 360 | * bColorCount initialized but instead one must read this info |
| 361 | * directly from corresponding DIB sections |
| 362 | * Note: wResId is index to array of pointer returned in ptrs (origin is 1) |
| 363 | */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 364 | BOOL CURSORICON_SimulateLoadingFromResourceW( LPWSTR filename, BOOL fCursor, |
Turchanov Sergey | 62d6e98 | 1998-10-18 13:42:55 +0000 | [diff] [blame] | 365 | CURSORICONDIR **res, LPBYTE **ptr) |
| 366 | { |
| 367 | LPBYTE _free; |
| 368 | CURSORICONFILEDIR *bits; |
| 369 | int entries, size, i; |
| 370 | |
| 371 | *res = NULL; |
| 372 | *ptr = NULL; |
Alexandre Julliard | 982a223 | 2000-12-13 20:20:09 +0000 | [diff] [blame] | 373 | if (!(bits = map_fileW( filename ))) return FALSE; |
Juergen Schmied | 4493a74 | 1998-11-30 17:29:28 +0000 | [diff] [blame] | 374 | |
| 375 | /* FIXME: test for inimated icons |
| 376 | * hack to load the first icon from the *.ani file |
| 377 | */ |
| 378 | if ( *(LPDWORD)bits==0x46464952 ) /* "RIFF" */ |
| 379 | { LPBYTE pos = (LPBYTE) bits; |
Alexandre Julliard | 06c275a | 1999-05-02 14:32:27 +0000 | [diff] [blame] | 380 | FIXME_(cursor)("Animated icons not correctly implemented! %p \n", bits); |
Juergen Schmied | 4493a74 | 1998-11-30 17:29:28 +0000 | [diff] [blame] | 381 | |
| 382 | for (;;) |
| 383 | { if (*(LPDWORD)pos==0x6e6f6369) /* "icon" */ |
Alexandre Julliard | 06c275a | 1999-05-02 14:32:27 +0000 | [diff] [blame] | 384 | { FIXME_(cursor)("icon entry found! %p\n", bits); |
Juergen Schmied | 4493a74 | 1998-11-30 17:29:28 +0000 | [diff] [blame] | 385 | pos+=4; |
| 386 | if ( !*(LPWORD) pos==0x2fe) /* iconsize */ |
| 387 | { goto fail; |
| 388 | } |
Juergen Schmied | cb2e4d3 | 1999-09-19 18:56:40 +0000 | [diff] [blame] | 389 | bits=(CURSORICONFILEDIR*)(pos+4); |
| 390 | FIXME_(cursor)("icon size ok. offset=%p \n", bits); |
Juergen Schmied | 4493a74 | 1998-11-30 17:29:28 +0000 | [diff] [blame] | 391 | break; |
| 392 | } |
| 393 | pos+=2; |
| 394 | if (pos>=(LPBYTE)bits+766) goto fail; |
| 395 | } |
| 396 | } |
Turchanov Sergey | 62d6e98 | 1998-10-18 13:42:55 +0000 | [diff] [blame] | 397 | if (!(entries = bits->idCount)) goto fail; |
Patrik Stridvall | a9a671d | 1999-04-25 19:01:52 +0000 | [diff] [blame] | 398 | size = sizeof(CURSORICONDIR) + sizeof(CURSORICONDIRENTRY) * (entries - 1); |
| 399 | _free = (LPBYTE) size; |
| 400 | |
Turchanov Sergey | 62d6e98 | 1998-10-18 13:42:55 +0000 | [diff] [blame] | 401 | for (i=0; i < entries; i++) |
| 402 | size += bits->idEntries[i].dwDIBSize + (fCursor ? sizeof(POINT16): 0); |
| 403 | |
| 404 | if (!(*ptr = HeapAlloc( GetProcessHeap(), 0, |
| 405 | entries * sizeof (CURSORICONDIRENTRY*)))) goto fail; |
| 406 | if (!(*res = HeapAlloc( GetProcessHeap(), 0, size))) goto fail; |
| 407 | |
| 408 | _free = (LPBYTE)(*res) + (int)_free; |
| 409 | memcpy((*res), bits, 6); |
| 410 | for (i=0; i<entries; i++) |
| 411 | { |
| 412 | ((LPBYTE*)(*ptr))[i] = _free; |
| 413 | if (fCursor) { |
Juergen Schmied | c45bbee | 1999-04-11 11:46:32 +0000 | [diff] [blame] | 414 | (*res)->idEntries[i].ResInfo.cursor.wWidth=bits->idEntries[i].bWidth; |
| 415 | (*res)->idEntries[i].ResInfo.cursor.wHeight=bits->idEntries[i].bHeight; |
Turchanov Sergey | 62d6e98 | 1998-10-18 13:42:55 +0000 | [diff] [blame] | 416 | ((LPPOINT16)_free)->x=bits->idEntries[i].xHotspot; |
| 417 | ((LPPOINT16)_free)->y=bits->idEntries[i].yHotspot; |
| 418 | _free+=sizeof(POINT16); |
| 419 | } else { |
Juergen Schmied | c45bbee | 1999-04-11 11:46:32 +0000 | [diff] [blame] | 420 | (*res)->idEntries[i].ResInfo.icon.bWidth=bits->idEntries[i].bWidth; |
| 421 | (*res)->idEntries[i].ResInfo.icon.bHeight=bits->idEntries[i].bHeight; |
| 422 | (*res)->idEntries[i].ResInfo.icon.bColorCount = bits->idEntries[i].bColorCount; |
Turchanov Sergey | 62d6e98 | 1998-10-18 13:42:55 +0000 | [diff] [blame] | 423 | } |
Juergen Schmied | c45bbee | 1999-04-11 11:46:32 +0000 | [diff] [blame] | 424 | (*res)->idEntries[i].wPlanes=1; |
| 425 | (*res)->idEntries[i].wBitCount = ((LPBITMAPINFOHEADER)((LPBYTE)bits + |
| 426 | bits->idEntries[i].dwDIBOffset))->biBitCount; |
| 427 | (*res)->idEntries[i].dwBytesInRes = bits->idEntries[i].dwDIBSize; |
| 428 | (*res)->idEntries[i].wResId=i+1; |
| 429 | |
Turchanov Sergey | 62d6e98 | 1998-10-18 13:42:55 +0000 | [diff] [blame] | 430 | memcpy(_free,(LPBYTE)bits +bits->idEntries[i].dwDIBOffset, |
Juergen Schmied | c45bbee | 1999-04-11 11:46:32 +0000 | [diff] [blame] | 431 | (*res)->idEntries[i].dwBytesInRes); |
| 432 | _free += (*res)->idEntries[i].dwBytesInRes; |
Turchanov Sergey | 62d6e98 | 1998-10-18 13:42:55 +0000 | [diff] [blame] | 433 | } |
| 434 | UnmapViewOfFile( bits ); |
| 435 | return TRUE; |
| 436 | fail: |
| 437 | if (*res) HeapFree( GetProcessHeap(), 0, *res ); |
| 438 | if (*ptr) HeapFree( GetProcessHeap(), 0, *ptr ); |
| 439 | UnmapViewOfFile( bits ); |
| 440 | return FALSE; |
| 441 | } |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 442 | |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 443 | |
| 444 | /********************************************************************** |
| 445 | * CURSORICON_CreateFromResource |
| 446 | * |
| 447 | * Create a cursor or icon from in-memory resource template. |
| 448 | * |
Turchanov Sergey | 62d6e98 | 1998-10-18 13:42:55 +0000 | [diff] [blame] | 449 | * FIXME: Convert to mono when cFlag is LR_MONOCHROME. Do something |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 450 | * with cbSize parameter as well. |
| 451 | */ |
Alexandre Julliard | 46ea8b3 | 1998-05-03 19:01:20 +0000 | [diff] [blame] | 452 | static HGLOBAL16 CURSORICON_CreateFromResource( HINSTANCE16 hInstance, HGLOBAL16 hObj, LPBYTE bits, |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 453 | UINT cbSize, BOOL bIcon, DWORD dwVersion, |
| 454 | INT width, INT height, UINT loadflags ) |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 455 | { |
Alexandre Julliard | 16cbf40 | 2001-01-18 20:32:01 +0000 | [diff] [blame] | 456 | static HDC hdcMem; |
Alexandre Julliard | 7ff1c41 | 1997-05-25 13:58:18 +0000 | [diff] [blame] | 457 | int sizeAnd, sizeXor; |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 458 | HBITMAP hAndBits = 0, hXorBits = 0; /* error condition for later */ |
Alexandre Julliard | b0efe28 | 2000-08-04 04:18:04 +0000 | [diff] [blame] | 459 | BITMAP bmpXor, bmpAnd; |
Patrik Stridvall | e92331f | 1999-09-20 18:52:06 +0000 | [diff] [blame] | 460 | POINT16 hotspot; |
Alexandre Julliard | 7ff1c41 | 1997-05-25 13:58:18 +0000 | [diff] [blame] | 461 | BITMAPINFO *bmi; |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 462 | BOOL DoStretch; |
| 463 | INT size; |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 464 | |
Patrik Stridvall | e92331f | 1999-09-20 18:52:06 +0000 | [diff] [blame] | 465 | hotspot.x = ICON_HOTSPOT; |
| 466 | hotspot.y = ICON_HOTSPOT; |
| 467 | |
Alexandre Julliard | 06c275a | 1999-05-02 14:32:27 +0000 | [diff] [blame] | 468 | TRACE_(cursor)("%08x (%u bytes), ver %08x, %ix%i %s %s\n", |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 469 | (unsigned)bits, cbSize, (unsigned)dwVersion, width, height, |
Turchanov Sergey | 62d6e98 | 1998-10-18 13:42:55 +0000 | [diff] [blame] | 470 | bIcon ? "icon" : "cursor", (loadflags & LR_MONOCHROME) ? "mono" : "" ); |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 471 | if (dwVersion == 0x00020000) |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 472 | { |
Alexandre Julliard | 06c275a | 1999-05-02 14:32:27 +0000 | [diff] [blame] | 473 | FIXME_(cursor)("\t2.xx resources are not supported\n"); |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 474 | return 0; |
| 475 | } |
| 476 | |
| 477 | if (bIcon) |
| 478 | bmi = (BITMAPINFO *)bits; |
| 479 | else /* get the hotspot */ |
| 480 | { |
| 481 | POINT16 *pt = (POINT16 *)bits; |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 482 | hotspot = *pt; |
| 483 | bmi = (BITMAPINFO *)(pt + 1); |
| 484 | } |
Turchanov Sergey | 62d6e98 | 1998-10-18 13:42:55 +0000 | [diff] [blame] | 485 | size = DIB_BitmapInfoSize( bmi, DIB_RGB_COLORS ); |
| 486 | |
| 487 | if (!width) width = bmi->bmiHeader.biWidth; |
| 488 | if (!height) height = bmi->bmiHeader.biHeight/2; |
| 489 | DoStretch = (bmi->bmiHeader.biHeight/2 != height) || |
| 490 | (bmi->bmiHeader.biWidth != width); |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 491 | |
Alexandre Julliard | 7ff1c41 | 1997-05-25 13:58:18 +0000 | [diff] [blame] | 492 | /* Check bitmap header */ |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 493 | |
Alexandre Julliard | 7ff1c41 | 1997-05-25 13:58:18 +0000 | [diff] [blame] | 494 | if ( (bmi->bmiHeader.biSize != sizeof(BITMAPCOREHEADER)) && |
| 495 | (bmi->bmiHeader.biSize != sizeof(BITMAPINFOHEADER) || |
| 496 | bmi->bmiHeader.biCompression != BI_RGB) ) |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 497 | { |
Alexandre Julliard | 06c275a | 1999-05-02 14:32:27 +0000 | [diff] [blame] | 498 | WARN_(cursor)("\tinvalid resource bitmap header.\n"); |
Alexandre Julliard | 7ff1c41 | 1997-05-25 13:58:18 +0000 | [diff] [blame] | 499 | return 0; |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 500 | } |
Alexandre Julliard | 7ff1c41 | 1997-05-25 13:58:18 +0000 | [diff] [blame] | 501 | |
Alexandre Julliard | 16cbf40 | 2001-01-18 20:32:01 +0000 | [diff] [blame] | 502 | if (!screen_dc) screen_dc = CreateDCA( "DISPLAY", NULL, NULL, NULL ); |
| 503 | if (screen_dc) |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 504 | { |
Alexandre Julliard | 7ff1c41 | 1997-05-25 13:58:18 +0000 | [diff] [blame] | 505 | BITMAPINFO* pInfo; |
Alexandre Julliard | 7ff1c41 | 1997-05-25 13:58:18 +0000 | [diff] [blame] | 506 | |
| 507 | /* Make sure we have room for the monochrome bitmap later on. |
| 508 | * Note that BITMAPINFOINFO and BITMAPCOREHEADER are the same |
| 509 | * up to and including the biBitCount. In-memory icon resource |
| 510 | * format is as follows: |
| 511 | * |
| 512 | * BITMAPINFOHEADER icHeader // DIB header |
| 513 | * RGBQUAD icColors[] // Color table |
| 514 | * BYTE icXOR[] // DIB bits for XOR mask |
| 515 | * BYTE icAND[] // DIB bits for AND mask |
| 516 | */ |
| 517 | |
Turchanov Sergey | 62d6e98 | 1998-10-18 13:42:55 +0000 | [diff] [blame] | 518 | if ((pInfo = (BITMAPINFO *)HeapAlloc( GetProcessHeap(), 0, |
Francois Gouget | 6d77d3a | 2000-03-25 21:44:35 +0000 | [diff] [blame] | 519 | max(size, sizeof(BITMAPINFOHEADER) + 2*sizeof(RGBQUAD))))) |
Alexandre Julliard | 7ff1c41 | 1997-05-25 13:58:18 +0000 | [diff] [blame] | 520 | { |
| 521 | memcpy( pInfo, bmi, size ); |
| 522 | pInfo->bmiHeader.biHeight /= 2; |
| 523 | |
| 524 | /* Create the XOR bitmap */ |
| 525 | |
Turchanov Sergey | 62d6e98 | 1998-10-18 13:42:55 +0000 | [diff] [blame] | 526 | if (DoStretch) { |
Pierre Mageau | 4ac8db7 | 1999-09-04 11:16:48 +0000 | [diff] [blame] | 527 | if(bIcon) |
| 528 | { |
Alexandre Julliard | 16cbf40 | 2001-01-18 20:32:01 +0000 | [diff] [blame] | 529 | hXorBits = CreateCompatibleBitmap(screen_dc, width, height); |
Pierre Mageau | 4ac8db7 | 1999-09-04 11:16:48 +0000 | [diff] [blame] | 530 | } |
| 531 | else |
| 532 | { |
| 533 | hXorBits = CreateBitmap(width, height, 1, 1, NULL); |
| 534 | } |
| 535 | if(hXorBits) |
| 536 | { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 537 | HBITMAP hOld; |
Alexandre Julliard | 16cbf40 | 2001-01-18 20:32:01 +0000 | [diff] [blame] | 538 | BOOL res = FALSE; |
Turchanov Sergey | 62d6e98 | 1998-10-18 13:42:55 +0000 | [diff] [blame] | 539 | |
Alexandre Julliard | 16cbf40 | 2001-01-18 20:32:01 +0000 | [diff] [blame] | 540 | if (!hdcMem) hdcMem = CreateCompatibleDC(screen_dc); |
| 541 | if (hdcMem) { |
| 542 | hOld = SelectObject(hdcMem, hXorBits); |
| 543 | res = StretchDIBits(hdcMem, 0, 0, width, height, 0, 0, |
| 544 | bmi->bmiHeader.biWidth, bmi->bmiHeader.biHeight/2, |
| 545 | (char*)bmi + size, pInfo, DIB_RGB_COLORS, SRCCOPY); |
| 546 | SelectObject(hdcMem, hOld); |
| 547 | } |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 548 | if (!res) { DeleteObject(hXorBits); hXorBits = 0; } |
Turchanov Sergey | 62d6e98 | 1998-10-18 13:42:55 +0000 | [diff] [blame] | 549 | } |
Alexandre Julliard | 16cbf40 | 2001-01-18 20:32:01 +0000 | [diff] [blame] | 550 | } else hXorBits = CreateDIBitmap( screen_dc, &pInfo->bmiHeader, |
Turchanov Sergey | 62d6e98 | 1998-10-18 13:42:55 +0000 | [diff] [blame] | 551 | CBM_INIT, (char*)bmi + size, pInfo, DIB_RGB_COLORS ); |
Alexandre Julliard | 7ff1c41 | 1997-05-25 13:58:18 +0000 | [diff] [blame] | 552 | if( hXorBits ) |
| 553 | { |
Marcus Meissner | 64c86ffe | 2000-08-07 04:16:43 +0000 | [diff] [blame] | 554 | char* xbits = (char *)bmi + size + |
Huw D M Davies | 608629b | 1999-04-18 12:07:00 +0000 | [diff] [blame] | 555 | DIB_GetDIBImageBytes(bmi->bmiHeader.biWidth, |
| 556 | bmi->bmiHeader.biHeight, |
| 557 | bmi->bmiHeader.biBitCount) / 2; |
Alexandre Julliard | 7ff1c41 | 1997-05-25 13:58:18 +0000 | [diff] [blame] | 558 | |
| 559 | pInfo->bmiHeader.biBitCount = 1; |
| 560 | if (pInfo->bmiHeader.biSize == sizeof(BITMAPINFOHEADER)) |
| 561 | { |
| 562 | RGBQUAD *rgb = pInfo->bmiColors; |
| 563 | |
| 564 | pInfo->bmiHeader.biClrUsed = pInfo->bmiHeader.biClrImportant = 2; |
| 565 | rgb[0].rgbBlue = rgb[0].rgbGreen = rgb[0].rgbRed = 0x00; |
| 566 | rgb[1].rgbBlue = rgb[1].rgbGreen = rgb[1].rgbRed = 0xff; |
| 567 | rgb[0].rgbReserved = rgb[1].rgbReserved = 0; |
| 568 | } |
| 569 | else |
| 570 | { |
| 571 | RGBTRIPLE *rgb = (RGBTRIPLE *)(((BITMAPCOREHEADER *)pInfo) + 1); |
| 572 | |
| 573 | rgb[0].rgbtBlue = rgb[0].rgbtGreen = rgb[0].rgbtRed = 0x00; |
| 574 | rgb[1].rgbtBlue = rgb[1].rgbtGreen = rgb[1].rgbtRed = 0xff; |
| 575 | } |
| 576 | |
| 577 | /* Create the AND bitmap */ |
| 578 | |
Turchanov Sergey | 62d6e98 | 1998-10-18 13:42:55 +0000 | [diff] [blame] | 579 | if (DoStretch) { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 580 | if ((hAndBits = CreateBitmap(width, height, 1, 1, NULL))) { |
| 581 | HBITMAP hOld; |
Alexandre Julliard | 16cbf40 | 2001-01-18 20:32:01 +0000 | [diff] [blame] | 582 | BOOL res = FALSE; |
Turchanov Sergey | 62d6e98 | 1998-10-18 13:42:55 +0000 | [diff] [blame] | 583 | |
Alexandre Julliard | 16cbf40 | 2001-01-18 20:32:01 +0000 | [diff] [blame] | 584 | if (!hdcMem) hdcMem = CreateCompatibleDC(screen_dc); |
| 585 | if (hdcMem) { |
| 586 | hOld = SelectObject(hdcMem, hAndBits); |
| 587 | res = StretchDIBits(hdcMem, 0, 0, width, height, 0, 0, |
| 588 | pInfo->bmiHeader.biWidth, pInfo->bmiHeader.biHeight, |
| 589 | xbits, pInfo, DIB_RGB_COLORS, SRCCOPY); |
| 590 | SelectObject(hdcMem, hOld); |
| 591 | } |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 592 | if (!res) { DeleteObject(hAndBits); hAndBits = 0; } |
Turchanov Sergey | 62d6e98 | 1998-10-18 13:42:55 +0000 | [diff] [blame] | 593 | } |
Alexandre Julliard | 16cbf40 | 2001-01-18 20:32:01 +0000 | [diff] [blame] | 594 | } else hAndBits = CreateDIBitmap( screen_dc, &pInfo->bmiHeader, |
Marcus Meissner | 64c86ffe | 2000-08-07 04:16:43 +0000 | [diff] [blame] | 595 | CBM_INIT, xbits, pInfo, DIB_RGB_COLORS ); |
Turchanov Sergey | 62d6e98 | 1998-10-18 13:42:55 +0000 | [diff] [blame] | 596 | |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 597 | if( !hAndBits ) DeleteObject( hXorBits ); |
Alexandre Julliard | 7ff1c41 | 1997-05-25 13:58:18 +0000 | [diff] [blame] | 598 | } |
| 599 | HeapFree( GetProcessHeap(), 0, pInfo ); |
| 600 | } |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 601 | } |
Alexandre Julliard | 7ff1c41 | 1997-05-25 13:58:18 +0000 | [diff] [blame] | 602 | |
| 603 | if( !hXorBits || !hAndBits ) |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 604 | { |
Alexandre Julliard | 06c275a | 1999-05-02 14:32:27 +0000 | [diff] [blame] | 605 | WARN_(cursor)("\tunable to create an icon bitmap.\n"); |
Alexandre Julliard | 7ff1c41 | 1997-05-25 13:58:18 +0000 | [diff] [blame] | 606 | return 0; |
Alexandre Julliard | f0cbfa0 | 1997-02-15 14:29:56 +0000 | [diff] [blame] | 607 | } |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 608 | |
| 609 | /* Now create the CURSORICONINFO structure */ |
Alexandre Julliard | b0efe28 | 2000-08-04 04:18:04 +0000 | [diff] [blame] | 610 | GetObjectA( hXorBits, sizeof(bmpXor), &bmpXor ); |
| 611 | GetObjectA( hAndBits, sizeof(bmpAnd), &bmpAnd ); |
| 612 | sizeXor = bmpXor.bmHeight * bmpXor.bmWidthBytes; |
| 613 | sizeAnd = bmpAnd.bmHeight * bmpAnd.bmWidthBytes; |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 614 | |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 615 | if (hObj) hObj = GlobalReAlloc16( hObj, |
| 616 | sizeof(CURSORICONINFO) + sizeXor + sizeAnd, GMEM_MOVEABLE ); |
| 617 | if (!hObj) hObj = GlobalAlloc16( GMEM_MOVEABLE, |
| 618 | sizeof(CURSORICONINFO) + sizeXor + sizeAnd ); |
| 619 | if (hObj) |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 620 | { |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 621 | CURSORICONINFO *info; |
| 622 | |
| 623 | /* Make it owned by the module */ |
Alexandre Julliard | 7d5bc5c | 2001-01-15 20:09:09 +0000 | [diff] [blame] | 624 | if (hInstance) hInstance = GetExePtr(hInstance); |
| 625 | FarSetOwner16( hObj, hInstance ); |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 626 | |
| 627 | info = (CURSORICONINFO *)GlobalLock16( hObj ); |
| 628 | info->ptHotSpot.x = hotspot.x; |
| 629 | info->ptHotSpot.y = hotspot.y; |
Alexandre Julliard | b0efe28 | 2000-08-04 04:18:04 +0000 | [diff] [blame] | 630 | info->nWidth = bmpXor.bmWidth; |
| 631 | info->nHeight = bmpXor.bmHeight; |
| 632 | info->nWidthBytes = bmpXor.bmWidthBytes; |
| 633 | info->bPlanes = bmpXor.bmPlanes; |
| 634 | info->bBitsPerPixel = bmpXor.bmBitsPixel; |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 635 | |
| 636 | /* Transfer the bitmap bits to the CURSORICONINFO structure */ |
| 637 | |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 638 | GetBitmapBits( hAndBits, sizeAnd, (char *)(info + 1) ); |
| 639 | GetBitmapBits( hXorBits, sizeXor, (char *)(info + 1) + sizeAnd ); |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 640 | GlobalUnlock16( hObj ); |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 641 | } |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 642 | |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 643 | DeleteObject( hAndBits ); |
Alexandre Julliard | 2a2321b | 2000-08-19 21:38:55 +0000 | [diff] [blame] | 644 | DeleteObject( hXorBits ); |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 645 | return hObj; |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 646 | } |
| 647 | |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 648 | |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 649 | /********************************************************************** |
Patrik Stridvall | 2ece70e | 2000-12-22 01:38:01 +0000 | [diff] [blame] | 650 | * CreateIconFromResourceEx (USER.450) |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 651 | * |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 652 | * FIXME: not sure about exact parameter types |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 653 | */ |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 654 | HICON16 WINAPI CreateIconFromResourceEx16( LPBYTE bits, UINT16 cbSize, BOOL16 bIcon, |
| 655 | DWORD dwVersion, INT16 width, INT16 height, UINT16 cFlag ) |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 656 | { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 657 | return CreateIconFromResourceEx(bits, cbSize, bIcon, dwVersion, |
Turchanov Sergey | 62d6e98 | 1998-10-18 13:42:55 +0000 | [diff] [blame] | 658 | width, height, cFlag); |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 659 | } |
| 660 | |
| 661 | |
Alexandre Julliard | a69b88b | 1998-03-15 20:29:56 +0000 | [diff] [blame] | 662 | /********************************************************************** |
Patrik Stridvall | 2ece70e | 2000-12-22 01:38:01 +0000 | [diff] [blame] | 663 | * CreateIconFromResource (USER32.@) |
Alexandre Julliard | 44ed71f | 1997-12-21 19:17:50 +0000 | [diff] [blame] | 664 | */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 665 | HICON WINAPI CreateIconFromResource( LPBYTE bits, UINT cbSize, |
| 666 | BOOL bIcon, DWORD dwVersion) |
Alexandre Julliard | 44ed71f | 1997-12-21 19:17:50 +0000 | [diff] [blame] | 667 | { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 668 | return CreateIconFromResourceEx( bits, cbSize, bIcon, dwVersion, 0,0,0); |
Alexandre Julliard | 44ed71f | 1997-12-21 19:17:50 +0000 | [diff] [blame] | 669 | } |
| 670 | |
| 671 | |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 672 | /********************************************************************** |
Patrik Stridvall | 2ece70e | 2000-12-22 01:38:01 +0000 | [diff] [blame] | 673 | * CreateIconFromResourceEx (USER32.@) |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 674 | */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 675 | HICON WINAPI CreateIconFromResourceEx( LPBYTE bits, UINT cbSize, |
| 676 | BOOL bIcon, DWORD dwVersion, |
| 677 | INT width, INT height, |
| 678 | UINT cFlag ) |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 679 | { |
Alexandre Julliard | 7d5bc5c | 2001-01-15 20:09:09 +0000 | [diff] [blame] | 680 | return CURSORICON_CreateFromResource( 0, 0, bits, cbSize, bIcon, dwVersion, |
| 681 | width, height, cFlag ); |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 682 | } |
| 683 | |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 684 | /********************************************************************** |
Ulrich Weigand | 50a0915 | 1999-03-10 14:00:29 +0000 | [diff] [blame] | 685 | * CURSORICON_Load |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 686 | * |
Ulrich Weigand | 50a0915 | 1999-03-10 14:00:29 +0000 | [diff] [blame] | 687 | * Load a cursor or icon from resource or file. |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 688 | */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 689 | HGLOBAL CURSORICON_Load( HINSTANCE hInstance, LPCWSTR name, |
Ulrich Weigand | 50a0915 | 1999-03-10 14:00:29 +0000 | [diff] [blame] | 690 | INT width, INT height, INT colors, |
| 691 | BOOL fCursor, UINT loadflags ) |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 692 | { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 693 | HANDLE handle = 0, h = 0; |
| 694 | HANDLE hRsrc; |
Ulrich Weigand | 50a0915 | 1999-03-10 14:00:29 +0000 | [diff] [blame] | 695 | CURSORICONDIR *dir; |
| 696 | CURSORICONDIRENTRY *dirEntry; |
Turchanov Sergey | 62d6e98 | 1998-10-18 13:42:55 +0000 | [diff] [blame] | 697 | LPBYTE bits; |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 698 | |
Ulrich Weigand | 50a0915 | 1999-03-10 14:00:29 +0000 | [diff] [blame] | 699 | if ( loadflags & LR_LOADFROMFILE ) /* Load from file */ |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 700 | { |
Ulrich Weigand | 50a0915 | 1999-03-10 14:00:29 +0000 | [diff] [blame] | 701 | LPBYTE *ptr; |
| 702 | if (!CURSORICON_SimulateLoadingFromResourceW((LPWSTR)name, fCursor, &dir, &ptr)) |
| 703 | return 0; |
| 704 | if (fCursor) |
| 705 | dirEntry = (CURSORICONDIRENTRY *)CURSORICON_FindBestCursor(dir, width, height, 1); |
| 706 | else |
| 707 | dirEntry = (CURSORICONDIRENTRY *)CURSORICON_FindBestIcon(dir, width, height, colors); |
Juergen Schmied | c45bbee | 1999-04-11 11:46:32 +0000 | [diff] [blame] | 708 | bits = ptr[dirEntry->wResId-1]; |
| 709 | h = CURSORICON_CreateFromResource( 0, 0, bits, dirEntry->dwBytesInRes, |
Ulrich Weigand | 50a0915 | 1999-03-10 14:00:29 +0000 | [diff] [blame] | 710 | !fCursor, 0x00030000, width, height, loadflags); |
| 711 | HeapFree( GetProcessHeap(), 0, dir ); |
| 712 | HeapFree( GetProcessHeap(), 0, ptr ); |
| 713 | } |
Ulrich Weigand | 50a0915 | 1999-03-10 14:00:29 +0000 | [diff] [blame] | 714 | else /* Load from resource */ |
| 715 | { |
Pierre Mageau | 4ac8db7 | 1999-09-04 11:16:48 +0000 | [diff] [blame] | 716 | HANDLE hGroupRsrc; |
Ulrich Weigand | 50a0915 | 1999-03-10 14:00:29 +0000 | [diff] [blame] | 717 | WORD wResId; |
| 718 | DWORD dwBytesInRes; |
| 719 | |
Alexandre Julliard | 16cbf40 | 2001-01-18 20:32:01 +0000 | [diff] [blame] | 720 | if (!hInstance) /* Load OEM cursor/icon */ |
| 721 | { |
| 722 | if (!(hInstance = GetModuleHandleA( "user32.dll" ))) return 0; |
| 723 | } |
| 724 | |
Ulrich Weigand | 50a0915 | 1999-03-10 14:00:29 +0000 | [diff] [blame] | 725 | /* Normalize hInstance (must be uniquely represented for icon cache) */ |
| 726 | |
| 727 | if ( HIWORD( hInstance ) ) |
| 728 | hInstance = MapHModuleLS( hInstance ); |
| 729 | else |
| 730 | hInstance = GetExePtr( hInstance ); |
| 731 | |
| 732 | /* Get directory resource ID */ |
| 733 | |
| 734 | if (!(hRsrc = FindResourceW( hInstance, name, |
| 735 | fCursor ? RT_GROUP_CURSORW : RT_GROUP_ICONW ))) |
| 736 | return 0; |
Pierre Mageau | 4ac8db7 | 1999-09-04 11:16:48 +0000 | [diff] [blame] | 737 | hGroupRsrc = hRsrc; |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 738 | |
Turchanov Sergey | 62d6e98 | 1998-10-18 13:42:55 +0000 | [diff] [blame] | 739 | /* Find the best entry in the directory */ |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 740 | |
Ulrich Weigand | 50a0915 | 1999-03-10 14:00:29 +0000 | [diff] [blame] | 741 | if (!(handle = LoadResource( hInstance, hRsrc ))) return 0; |
| 742 | if (!(dir = (CURSORICONDIR*)LockResource( handle ))) return 0; |
| 743 | if (fCursor) |
| 744 | dirEntry = (CURSORICONDIRENTRY *)CURSORICON_FindBestCursor( dir, |
| 745 | width, height, 1); |
| 746 | else |
| 747 | dirEntry = (CURSORICONDIRENTRY *)CURSORICON_FindBestIcon( dir, |
| 748 | width, height, colors ); |
| 749 | if (!dirEntry) return 0; |
Juergen Schmied | c45bbee | 1999-04-11 11:46:32 +0000 | [diff] [blame] | 750 | wResId = dirEntry->wResId; |
| 751 | dwBytesInRes = dirEntry->dwBytesInRes; |
Ulrich Weigand | 50a0915 | 1999-03-10 14:00:29 +0000 | [diff] [blame] | 752 | FreeResource( handle ); |
| 753 | |
Turchanov Sergey | 62d6e98 | 1998-10-18 13:42:55 +0000 | [diff] [blame] | 754 | /* Load the resource */ |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 755 | |
Ulrich Weigand | 50a0915 | 1999-03-10 14:00:29 +0000 | [diff] [blame] | 756 | if (!(hRsrc = FindResourceW(hInstance,MAKEINTRESOURCEW(wResId), |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 757 | fCursor ? RT_CURSORW : RT_ICONW ))) return 0; |
Alexandre Julliard | b4c6872 | 2000-06-08 00:39:16 +0000 | [diff] [blame] | 758 | |
| 759 | /* If shared icon, check whether it was already loaded */ |
| 760 | if ( (loadflags & LR_SHARED) |
| 761 | && (h = CURSORICON_FindSharedIcon( hInstance, hRsrc ) ) != 0 ) |
| 762 | return h; |
| 763 | |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 764 | if (!(handle = LoadResource( hInstance, hRsrc ))) return 0; |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 765 | bits = (LPBYTE)LockResource( handle ); |
Ulrich Weigand | 50a0915 | 1999-03-10 14:00:29 +0000 | [diff] [blame] | 766 | h = CURSORICON_CreateFromResource( 0, 0, bits, dwBytesInRes, |
Turchanov Sergey | 62d6e98 | 1998-10-18 13:42:55 +0000 | [diff] [blame] | 767 | !fCursor, 0x00030000, width, height, loadflags); |
Ulrich Weigand | 50a0915 | 1999-03-10 14:00:29 +0000 | [diff] [blame] | 768 | FreeResource( handle ); |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 769 | |
Ulrich Weigand | 50a0915 | 1999-03-10 14:00:29 +0000 | [diff] [blame] | 770 | /* If shared icon, add to icon cache */ |
| 771 | |
| 772 | if ( h && (loadflags & LR_SHARED) ) |
Pierre Mageau | 4ac8db7 | 1999-09-04 11:16:48 +0000 | [diff] [blame] | 773 | CURSORICON_AddSharedIcon( hInstance, hRsrc, hGroupRsrc, h ); |
Ulrich Weigand | 50a0915 | 1999-03-10 14:00:29 +0000 | [diff] [blame] | 774 | } |
| 775 | |
| 776 | return h; |
| 777 | } |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 778 | |
| 779 | /*********************************************************************** |
| 780 | * CURSORICON_Copy |
| 781 | * |
| 782 | * Make a copy of a cursor or icon. |
| 783 | */ |
Alexandre Julliard | bf9130a | 1996-10-13 17:45:47 +0000 | [diff] [blame] | 784 | static HGLOBAL16 CURSORICON_Copy( HINSTANCE16 hInstance, HGLOBAL16 handle ) |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 785 | { |
| 786 | char *ptrOld, *ptrNew; |
| 787 | int size; |
Alexandre Julliard | bf9130a | 1996-10-13 17:45:47 +0000 | [diff] [blame] | 788 | HGLOBAL16 hNew; |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 789 | |
Alexandre Julliard | 1285c2f | 1996-05-06 16:06:24 +0000 | [diff] [blame] | 790 | if (!(ptrOld = (char *)GlobalLock16( handle ))) return 0; |
Alexandre Julliard | 7d5bc5c | 2001-01-15 20:09:09 +0000 | [diff] [blame] | 791 | if (hInstance && !(hInstance = GetExePtr( hInstance ))) return 0; |
Alexandre Julliard | 1285c2f | 1996-05-06 16:06:24 +0000 | [diff] [blame] | 792 | size = GlobalSize16( handle ); |
| 793 | hNew = GlobalAlloc16( GMEM_MOVEABLE, size ); |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 794 | FarSetOwner16( hNew, hInstance ); |
Alexandre Julliard | 1285c2f | 1996-05-06 16:06:24 +0000 | [diff] [blame] | 795 | ptrNew = (char *)GlobalLock16( hNew ); |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 796 | memcpy( ptrNew, ptrOld, size ); |
Alexandre Julliard | 1285c2f | 1996-05-06 16:06:24 +0000 | [diff] [blame] | 797 | GlobalUnlock16( handle ); |
| 798 | GlobalUnlock16( hNew ); |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 799 | return hNew; |
| 800 | } |
| 801 | |
Pierre Mageau | 4ac8db7 | 1999-09-04 11:16:48 +0000 | [diff] [blame] | 802 | /************************************************************************* |
| 803 | * CURSORICON_ExtCopy |
| 804 | * |
| 805 | * Copies an Image from the Cache if LR_COPYFROMRESOURCE is specified |
| 806 | * |
| 807 | * PARAMS |
| 808 | * Handle [I] handle to an Image |
| 809 | * nType [I] Type of Handle (IMAGE_CURSOR | IMAGE_ICON) |
| 810 | * iDesiredCX [I] The Desired width of the Image |
| 811 | * iDesiredCY [I] The desired height of the Image |
| 812 | * nFlags [I] The flags from CopyImage |
| 813 | * |
| 814 | * RETURNS |
| 815 | * Success: The new handle of the Image |
| 816 | * |
| 817 | * NOTES |
| 818 | * LR_COPYDELETEORG and LR_MONOCHROME are currently not implemented. |
| 819 | * LR_MONOCHROME should be implemented by CURSORICON_CreateFromResource. |
| 820 | * LR_COPYFROMRESOURCE will only work if the Image is in the Cache. |
| 821 | * |
| 822 | * |
| 823 | */ |
| 824 | |
| 825 | HGLOBAL CURSORICON_ExtCopy(HGLOBAL Handle, UINT nType, |
| 826 | INT iDesiredCX, INT iDesiredCY, |
| 827 | UINT nFlags) |
| 828 | { |
| 829 | HGLOBAL16 hNew=0; |
| 830 | |
| 831 | TRACE_(icon)("Handle %u, uType %u, iDesiredCX %i, iDesiredCY %i, nFlags %u\n", |
| 832 | Handle, nType, iDesiredCX, iDesiredCY, nFlags); |
| 833 | |
| 834 | if(Handle == 0) |
| 835 | { |
| 836 | return 0; |
| 837 | } |
| 838 | |
| 839 | /* Best Fit or Monochrome */ |
| 840 | if( (nFlags & LR_COPYFROMRESOURCE |
| 841 | && (iDesiredCX > 0 || iDesiredCY > 0)) |
| 842 | || nFlags & LR_MONOCHROME) |
| 843 | { |
| 844 | ICONCACHE* pIconCache = CURSORICON_FindCache(Handle); |
| 845 | |
François Gouget | 4188fbc | 2001-02-14 21:43:06 +0000 | [diff] [blame] | 846 | /* Not Found in Cache, then do a straight copy |
Pierre Mageau | 4ac8db7 | 1999-09-04 11:16:48 +0000 | [diff] [blame] | 847 | */ |
| 848 | if(pIconCache == NULL) |
| 849 | { |
Alexandre Julliard | 7d5bc5c | 2001-01-15 20:09:09 +0000 | [diff] [blame] | 850 | hNew = CURSORICON_Copy(0, Handle); |
Pierre Mageau | 4ac8db7 | 1999-09-04 11:16:48 +0000 | [diff] [blame] | 851 | if(nFlags & LR_COPYFROMRESOURCE) |
| 852 | { |
| 853 | TRACE_(icon)("LR_COPYFROMRESOURCE: Failed to load from cache\n"); |
| 854 | } |
| 855 | } |
| 856 | else |
| 857 | { |
Juergen Schmied | 4401684 | 2000-02-25 20:52:01 +0000 | [diff] [blame] | 858 | int iTargetCY = iDesiredCY, iTargetCX = iDesiredCX; |
Pierre Mageau | 4ac8db7 | 1999-09-04 11:16:48 +0000 | [diff] [blame] | 859 | LPBYTE pBits; |
| 860 | HANDLE hMem; |
| 861 | HRSRC hRsrc; |
| 862 | DWORD dwBytesInRes; |
| 863 | WORD wResId; |
| 864 | CURSORICONDIR *pDir; |
| 865 | CURSORICONDIRENTRY *pDirEntry; |
| 866 | BOOL bIsIcon = (nType == IMAGE_ICON); |
| 867 | |
| 868 | /* Completing iDesiredCX CY for Monochrome Bitmaps if needed |
| 869 | */ |
| 870 | if(((nFlags & LR_MONOCHROME) && !(nFlags & LR_COPYFROMRESOURCE)) |
| 871 | || (iDesiredCX == 0 && iDesiredCY == 0)) |
| 872 | { |
| 873 | iDesiredCY = GetSystemMetrics(bIsIcon ? |
| 874 | SM_CYICON : SM_CYCURSOR); |
| 875 | iDesiredCX = GetSystemMetrics(bIsIcon ? |
| 876 | SM_CXICON : SM_CXCURSOR); |
| 877 | } |
| 878 | |
François Gouget | 4188fbc | 2001-02-14 21:43:06 +0000 | [diff] [blame] | 879 | /* Retrieve the CURSORICONDIRENTRY |
Pierre Mageau | 4ac8db7 | 1999-09-04 11:16:48 +0000 | [diff] [blame] | 880 | */ |
| 881 | if (!(hMem = LoadResource( pIconCache->hModule , |
| 882 | pIconCache->hGroupRsrc))) |
| 883 | { |
| 884 | return 0; |
| 885 | } |
| 886 | if (!(pDir = (CURSORICONDIR*)LockResource( hMem ))) |
| 887 | { |
| 888 | return 0; |
| 889 | } |
| 890 | |
| 891 | /* Find Best Fit |
| 892 | */ |
| 893 | if(bIsIcon) |
| 894 | { |
| 895 | pDirEntry = (CURSORICONDIRENTRY *)CURSORICON_FindBestIcon( |
| 896 | pDir, iDesiredCX, iDesiredCY, 256); |
| 897 | } |
| 898 | else |
| 899 | { |
| 900 | pDirEntry = (CURSORICONDIRENTRY *)CURSORICON_FindBestCursor( |
| 901 | pDir, iDesiredCX, iDesiredCY, 1); |
| 902 | } |
| 903 | |
| 904 | wResId = pDirEntry->wResId; |
| 905 | dwBytesInRes = pDirEntry->dwBytesInRes; |
| 906 | FreeResource(hMem); |
| 907 | |
| 908 | TRACE_(icon)("ResID %u, BytesInRes %lu, Width %d, Height %d DX %d, DY %d\n", |
| 909 | wResId, dwBytesInRes, pDirEntry->ResInfo.icon.bWidth, |
| 910 | pDirEntry->ResInfo.icon.bHeight, iDesiredCX, iDesiredCY); |
| 911 | |
| 912 | /* Get the Best Fit |
| 913 | */ |
| 914 | if (!(hRsrc = FindResourceW(pIconCache->hModule , |
| 915 | MAKEINTRESOURCEW(wResId), bIsIcon ? RT_ICONW : RT_CURSORW))) |
| 916 | { |
| 917 | return 0; |
| 918 | } |
| 919 | if (!(hMem = LoadResource( pIconCache->hModule , hRsrc ))) |
| 920 | { |
| 921 | return 0; |
| 922 | } |
| 923 | |
| 924 | pBits = (LPBYTE)LockResource( hMem ); |
| 925 | |
Juergen Schmied | 4401684 | 2000-02-25 20:52:01 +0000 | [diff] [blame] | 926 | if(nFlags & LR_DEFAULTSIZE) |
| 927 | { |
| 928 | iTargetCY = GetSystemMetrics(SM_CYICON); |
| 929 | iTargetCX = GetSystemMetrics(SM_CXICON); |
| 930 | } |
Pierre Mageau | 4ac8db7 | 1999-09-04 11:16:48 +0000 | [diff] [blame] | 931 | |
| 932 | /* Create a New Icon with the proper dimension |
| 933 | */ |
| 934 | hNew = CURSORICON_CreateFromResource( 0, 0, pBits, dwBytesInRes, |
| 935 | bIsIcon, 0x00030000, iTargetCX, iTargetCY, nFlags); |
| 936 | FreeResource(hMem); |
| 937 | } |
| 938 | } |
Alexandre Julliard | 7d5bc5c | 2001-01-15 20:09:09 +0000 | [diff] [blame] | 939 | else hNew = CURSORICON_Copy(0, Handle); |
Pierre Mageau | 4ac8db7 | 1999-09-04 11:16:48 +0000 | [diff] [blame] | 940 | return hNew; |
| 941 | } |
| 942 | |
Alexandre Julliard | ade697e | 1995-11-26 13:59:11 +0000 | [diff] [blame] | 943 | /*********************************************************************** |
| 944 | * CURSORICON_IconToCursor |
| 945 | * |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 946 | * Converts bitmap to mono and truncates if icon is too large (should |
| 947 | * probably do StretchBlt() instead). |
Alexandre Julliard | ade697e | 1995-11-26 13:59:11 +0000 | [diff] [blame] | 948 | */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 949 | HCURSOR16 CURSORICON_IconToCursor(HICON16 hIcon, BOOL bSemiTransparent) |
Alexandre Julliard | ade697e | 1995-11-26 13:59:11 +0000 | [diff] [blame] | 950 | { |
Alexandre Julliard | 75d86e1 | 1996-11-17 18:59:11 +0000 | [diff] [blame] | 951 | HCURSOR16 hRet = 0; |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 952 | CURSORICONINFO *pIcon = NULL; |
Alexandre Julliard | ade697e | 1995-11-26 13:59:11 +0000 | [diff] [blame] | 953 | |
Alexandre Julliard | 7d5bc5c | 2001-01-15 20:09:09 +0000 | [diff] [blame] | 954 | if(hIcon) |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 955 | if (!(pIcon = (CURSORICONINFO*)GlobalLock16( hIcon ))) return FALSE; |
| 956 | if (pIcon->bPlanes * pIcon->bBitsPerPixel == 1) |
Francis Beaudet | 699900b | 1999-09-05 12:15:49 +0000 | [diff] [blame] | 957 | { |
Alexandre Julliard | 7d5bc5c | 2001-01-15 20:09:09 +0000 | [diff] [blame] | 958 | hRet = CURSORICON_Copy( 0, hIcon ); |
Francis Beaudet | 699900b | 1999-09-05 12:15:49 +0000 | [diff] [blame] | 959 | |
| 960 | |
| 961 | pIcon = GlobalLock16(hRet); |
| 962 | |
| 963 | pIcon->ptHotSpot.x = pIcon->ptHotSpot.y = 15; |
| 964 | |
Serge Ivanov | 15f8646 | 2000-03-04 19:07:08 +0000 | [diff] [blame] | 965 | GlobalUnlock16(hRet); |
Francis Beaudet | 699900b | 1999-09-05 12:15:49 +0000 | [diff] [blame] | 966 | } |
Alexandre Julliard | 75d86e1 | 1996-11-17 18:59:11 +0000 | [diff] [blame] | 967 | else |
Alexandre Julliard | 7ff1c41 | 1997-05-25 13:58:18 +0000 | [diff] [blame] | 968 | { |
Alexandre Julliard | 75d86e1 | 1996-11-17 18:59:11 +0000 | [diff] [blame] | 969 | BYTE pAndBits[128]; |
| 970 | BYTE pXorBits[128]; |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 971 | int maxx, maxy, ix, iy, bpp = pIcon->bBitsPerPixel; |
| 972 | BYTE* psPtr, *pxbPtr = pXorBits; |
| 973 | unsigned xor_width, and_width, val_base = 0xffffffff >> (32 - bpp); |
Alexandre Julliard | 75d86e1 | 1996-11-17 18:59:11 +0000 | [diff] [blame] | 974 | BYTE* pbc = NULL; |
| 975 | |
Alexandre Julliard | 75d86e1 | 1996-11-17 18:59:11 +0000 | [diff] [blame] | 976 | CURSORICONINFO cI; |
| 977 | |
Alexandre Julliard | 06c275a | 1999-05-02 14:32:27 +0000 | [diff] [blame] | 978 | TRACE_(icon)("[%04x] %ix%i %ibpp (bogus %ibps)\n", |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 979 | hIcon, pIcon->nWidth, pIcon->nHeight, pIcon->bBitsPerPixel, pIcon->nWidthBytes ); |
| 980 | |
Huw D M Davies | 8261736 | 1998-11-01 16:35:42 +0000 | [diff] [blame] | 981 | xor_width = BITMAP_GetWidthBytes( pIcon->nWidth, bpp ); |
| 982 | and_width = BITMAP_GetWidthBytes( pIcon->nWidth, 1 ); |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 983 | psPtr = (BYTE *)(pIcon + 1) + pIcon->nHeight * and_width; |
| 984 | |
Alexandre Julliard | 75d86e1 | 1996-11-17 18:59:11 +0000 | [diff] [blame] | 985 | memset(pXorBits, 0, 128); |
| 986 | cI.bBitsPerPixel = 1; cI.bPlanes = 1; |
| 987 | cI.ptHotSpot.x = cI.ptHotSpot.y = 15; |
| 988 | cI.nWidth = 32; cI.nHeight = 32; |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 989 | cI.nWidthBytes = 4; /* 32x1bpp */ |
Alexandre Julliard | 75d86e1 | 1996-11-17 18:59:11 +0000 | [diff] [blame] | 990 | |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 991 | maxx = (pIcon->nWidth > 32) ? 32 : pIcon->nWidth; |
| 992 | maxy = (pIcon->nHeight > 32) ? 32 : pIcon->nHeight; |
Alexandre Julliard | 75d86e1 | 1996-11-17 18:59:11 +0000 | [diff] [blame] | 993 | |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 994 | for( iy = 0; iy < maxy; iy++ ) |
Alexandre Julliard | 75d86e1 | 1996-11-17 18:59:11 +0000 | [diff] [blame] | 995 | { |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 996 | unsigned shift = iy % 2; |
Alexandre Julliard | 75d86e1 | 1996-11-17 18:59:11 +0000 | [diff] [blame] | 997 | |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 998 | memcpy( pAndBits + iy * 4, (BYTE *)(pIcon + 1) + iy * and_width, |
| 999 | (and_width > 4) ? 4 : and_width ); |
| 1000 | for( ix = 0; ix < maxx; ix++ ) |
Alexandre Julliard | 75d86e1 | 1996-11-17 18:59:11 +0000 | [diff] [blame] | 1001 | { |
| 1002 | if( bSemiTransparent && ((ix+shift)%2) ) |
| 1003 | { |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 1004 | /* set AND bit, XOR bit stays 0 */ |
| 1005 | |
Alexandre Julliard | 75d86e1 | 1996-11-17 18:59:11 +0000 | [diff] [blame] | 1006 | pbc = pAndBits + iy * 4 + ix/8; |
| 1007 | *pbc |= 0x80 >> (ix%8); |
| 1008 | } |
| 1009 | else |
| 1010 | { |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 1011 | /* keep AND bit, set XOR bit */ |
| 1012 | |
| 1013 | unsigned *psc = (unsigned*)(psPtr + (ix * bpp)/8); |
| 1014 | unsigned val = ((*psc) >> (ix * bpp)%8) & val_base; |
Patrik Stridvall | b87fe2e | 1999-04-01 08:16:08 +0000 | [diff] [blame] | 1015 | if(!PALETTE_Driver->pIsDark(val)) |
Alexandre Julliard | 75d86e1 | 1996-11-17 18:59:11 +0000 | [diff] [blame] | 1016 | { |
| 1017 | pbc = pxbPtr + ix/8; |
| 1018 | *pbc |= 0x80 >> (ix%8); |
| 1019 | } |
| 1020 | } |
| 1021 | } |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 1022 | psPtr += xor_width; |
Alexandre Julliard | 75d86e1 | 1996-11-17 18:59:11 +0000 | [diff] [blame] | 1023 | pxbPtr += 4; |
| 1024 | } |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 1025 | |
Alexandre Julliard | 7d5bc5c | 2001-01-15 20:09:09 +0000 | [diff] [blame] | 1026 | hRet = CreateCursorIconIndirect16( 0 , &cI, pAndBits, pXorBits); |
Alexandre Julliard | 75d86e1 | 1996-11-17 18:59:11 +0000 | [diff] [blame] | 1027 | |
| 1028 | if( !hRet ) /* fall back on default drag cursor */ |
Alexandre Julliard | 7d5bc5c | 2001-01-15 20:09:09 +0000 | [diff] [blame] | 1029 | hRet = CURSORICON_Copy( 0 , |
Ulrich Weigand | 50a0915 | 1999-03-10 14:00:29 +0000 | [diff] [blame] | 1030 | CURSORICON_Load(0,MAKEINTRESOURCEW(OCR_DRAGOBJECT), |
Marcus Meissner | ddca315 | 1999-05-22 11:33:23 +0000 | [diff] [blame] | 1031 | GetSystemMetrics(SM_CXCURSOR), |
| 1032 | GetSystemMetrics(SM_CYCURSOR), 1, TRUE, 0) ); |
Alexandre Julliard | 7ff1c41 | 1997-05-25 13:58:18 +0000 | [diff] [blame] | 1033 | } |
Alexandre Julliard | ade697e | 1995-11-26 13:59:11 +0000 | [diff] [blame] | 1034 | |
Alexandre Julliard | 75d86e1 | 1996-11-17 18:59:11 +0000 | [diff] [blame] | 1035 | return hRet; |
Alexandre Julliard | ade697e | 1995-11-26 13:59:11 +0000 | [diff] [blame] | 1036 | } |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 1037 | |
Alexandre Julliard | f0cbfa0 | 1997-02-15 14:29:56 +0000 | [diff] [blame] | 1038 | |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 1039 | /*********************************************************************** |
Patrik Stridvall | 2ece70e | 2000-12-22 01:38:01 +0000 | [diff] [blame] | 1040 | * LoadCursor (USER.173) |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 1041 | */ |
Alexandre Julliard | ac7efef | 2000-11-27 21:54:01 +0000 | [diff] [blame] | 1042 | HCURSOR16 WINAPI LoadCursor16( HINSTANCE16 hInstance, LPCSTR name ) |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 1043 | { |
Alexandre Julliard | ac7efef | 2000-11-27 21:54:01 +0000 | [diff] [blame] | 1044 | return LoadCursorA( hInstance, name ); |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 1045 | } |
| 1046 | |
| 1047 | |
| 1048 | /*********************************************************************** |
Patrik Stridvall | 2ece70e | 2000-12-22 01:38:01 +0000 | [diff] [blame] | 1049 | * LoadIcon (USER.174) |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 1050 | */ |
Alexandre Julliard | ac7efef | 2000-11-27 21:54:01 +0000 | [diff] [blame] | 1051 | HICON16 WINAPI LoadIcon16( HINSTANCE16 hInstance, LPCSTR name ) |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 1052 | { |
Alexandre Julliard | ac7efef | 2000-11-27 21:54:01 +0000 | [diff] [blame] | 1053 | return LoadIconA( hInstance, name ); |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 1054 | } |
| 1055 | |
| 1056 | |
| 1057 | /*********************************************************************** |
Patrik Stridvall | 2ece70e | 2000-12-22 01:38:01 +0000 | [diff] [blame] | 1058 | * CreateCursor (USER.406) |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 1059 | */ |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 1060 | HCURSOR16 WINAPI CreateCursor16( HINSTANCE16 hInstance, |
| 1061 | INT16 xHotSpot, INT16 yHotSpot, |
| 1062 | INT16 nWidth, INT16 nHeight, |
| 1063 | LPCVOID lpANDbits, LPCVOID lpXORbits ) |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 1064 | { |
Patrik Stridvall | a9a671d | 1999-04-25 19:01:52 +0000 | [diff] [blame] | 1065 | CURSORICONINFO info; |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 1066 | |
Alexandre Julliard | 06c275a | 1999-05-02 14:32:27 +0000 | [diff] [blame] | 1067 | TRACE_(cursor)("%dx%d spot=%d,%d xor=%p and=%p\n", |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 1068 | nWidth, nHeight, xHotSpot, yHotSpot, lpXORbits, lpANDbits); |
Patrik Stridvall | a9a671d | 1999-04-25 19:01:52 +0000 | [diff] [blame] | 1069 | |
| 1070 | info.ptHotSpot.x = xHotSpot; |
| 1071 | info.ptHotSpot.y = yHotSpot; |
| 1072 | info.nWidth = nWidth; |
| 1073 | info.nHeight = nHeight; |
| 1074 | info.nWidthBytes = 0; |
| 1075 | info.bPlanes = 1; |
| 1076 | info.bBitsPerPixel = 1; |
| 1077 | |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1078 | return CreateCursorIconIndirect16( hInstance, &info, lpANDbits, lpXORbits ); |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 1079 | } |
| 1080 | |
| 1081 | |
| 1082 | /*********************************************************************** |
Patrik Stridvall | 2ece70e | 2000-12-22 01:38:01 +0000 | [diff] [blame] | 1083 | * CreateCursor (USER32.@) |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 1084 | */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1085 | HCURSOR WINAPI CreateCursor( HINSTANCE hInstance, |
| 1086 | INT xHotSpot, INT yHotSpot, |
| 1087 | INT nWidth, INT nHeight, |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 1088 | LPCVOID lpANDbits, LPCVOID lpXORbits ) |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 1089 | { |
Patrik Stridvall | a9a671d | 1999-04-25 19:01:52 +0000 | [diff] [blame] | 1090 | CURSORICONINFO info; |
Alexandre Julliard | f0cbfa0 | 1997-02-15 14:29:56 +0000 | [diff] [blame] | 1091 | |
Alexandre Julliard | 06c275a | 1999-05-02 14:32:27 +0000 | [diff] [blame] | 1092 | TRACE_(cursor)("%dx%d spot=%d,%d xor=%p and=%p\n", |
Alexandre Julliard | f0cbfa0 | 1997-02-15 14:29:56 +0000 | [diff] [blame] | 1093 | nWidth, nHeight, xHotSpot, yHotSpot, lpXORbits, lpANDbits); |
Patrik Stridvall | a9a671d | 1999-04-25 19:01:52 +0000 | [diff] [blame] | 1094 | |
| 1095 | info.ptHotSpot.x = xHotSpot; |
| 1096 | info.ptHotSpot.y = yHotSpot; |
| 1097 | info.nWidth = nWidth; |
| 1098 | info.nHeight = nHeight; |
| 1099 | info.nWidthBytes = 0; |
| 1100 | info.bPlanes = 1; |
| 1101 | info.bBitsPerPixel = 1; |
| 1102 | |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1103 | return CreateCursorIconIndirect16( 0, &info, lpANDbits, lpXORbits ); |
Alexandre Julliard | f0cbfa0 | 1997-02-15 14:29:56 +0000 | [diff] [blame] | 1104 | } |
| 1105 | |
| 1106 | |
| 1107 | /*********************************************************************** |
Patrik Stridvall | 2ece70e | 2000-12-22 01:38:01 +0000 | [diff] [blame] | 1108 | * CreateIcon (USER.407) |
Alexandre Julliard | f0cbfa0 | 1997-02-15 14:29:56 +0000 | [diff] [blame] | 1109 | */ |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 1110 | HICON16 WINAPI CreateIcon16( HINSTANCE16 hInstance, INT16 nWidth, |
| 1111 | INT16 nHeight, BYTE bPlanes, BYTE bBitsPixel, |
| 1112 | LPCVOID lpANDbits, LPCVOID lpXORbits ) |
Alexandre Julliard | f0cbfa0 | 1997-02-15 14:29:56 +0000 | [diff] [blame] | 1113 | { |
Patrik Stridvall | a9a671d | 1999-04-25 19:01:52 +0000 | [diff] [blame] | 1114 | CURSORICONINFO info; |
Alexandre Julliard | f0cbfa0 | 1997-02-15 14:29:56 +0000 | [diff] [blame] | 1115 | |
Alexandre Julliard | 06c275a | 1999-05-02 14:32:27 +0000 | [diff] [blame] | 1116 | TRACE_(icon)("%dx%dx%d, xor=%p, and=%p\n", |
Alexandre Julliard | f0cbfa0 | 1997-02-15 14:29:56 +0000 | [diff] [blame] | 1117 | nWidth, nHeight, bPlanes * bBitsPixel, lpXORbits, lpANDbits); |
Patrik Stridvall | a9a671d | 1999-04-25 19:01:52 +0000 | [diff] [blame] | 1118 | |
Francis Beaudet | 699900b | 1999-09-05 12:15:49 +0000 | [diff] [blame] | 1119 | info.ptHotSpot.x = ICON_HOTSPOT; |
| 1120 | info.ptHotSpot.y = ICON_HOTSPOT; |
Patrik Stridvall | a9a671d | 1999-04-25 19:01:52 +0000 | [diff] [blame] | 1121 | info.nWidth = nWidth; |
| 1122 | info.nHeight = nHeight; |
| 1123 | info.nWidthBytes = 0; |
| 1124 | info.bPlanes = bPlanes; |
| 1125 | info.bBitsPerPixel = bBitsPixel; |
| 1126 | |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1127 | return CreateCursorIconIndirect16( hInstance, &info, lpANDbits, lpXORbits ); |
Alexandre Julliard | f0cbfa0 | 1997-02-15 14:29:56 +0000 | [diff] [blame] | 1128 | } |
| 1129 | |
| 1130 | |
| 1131 | /*********************************************************************** |
Patrik Stridvall | 2ece70e | 2000-12-22 01:38:01 +0000 | [diff] [blame] | 1132 | * CreateIcon (USER32.@) |
François Gouget | 2c86506 | 2001-02-13 01:48:14 +0000 | [diff] [blame] | 1133 | * |
| 1134 | * Creates an icon based on the specified bitmaps. The bitmaps must be |
| 1135 | * provided in a device dependent format and will be resized to |
| 1136 | * (SM_CXICON,SM_CYICON) and depth converted to match the screen's color |
| 1137 | * depth. The provided bitmaps must be top-down bitmaps. |
| 1138 | * Although Windows does not support 15bpp(*) this API must support it |
| 1139 | * for Winelib applications. |
| 1140 | * |
| 1141 | * (*) Windows does not support 15bpp but it supports the 555 RGB 16bpp |
| 1142 | * format! |
| 1143 | * |
| 1144 | * BUGS |
| 1145 | * |
| 1146 | * - The provided bitmaps are not resized! |
| 1147 | * - The documentation says the lpXORbits bitmap must be in a device |
| 1148 | * dependent format. But we must still resize it and perform depth |
| 1149 | * conversions if necessary. |
| 1150 | * - I'm a bit unsure about the how the 'device dependent format' thing works. |
| 1151 | * I did some tests on windows and found that if you provide a 16bpp bitmap |
| 1152 | * in lpXORbits, then its format but be 565 RGB if the screen's bit depth |
| 1153 | * is 16bpp but it must be 555 RGB if the screen's bit depth is anything |
| 1154 | * else. I don't know if this is part of the GDI specs or if this is a |
| 1155 | * quirk of the graphics card driver. |
| 1156 | * - You may think that we check whether the bit depths match or not |
| 1157 | * as an optimization. But the truth is that the conversion using |
| 1158 | * CreateDIBitmap does not work for some bit depth (e.g. 8bpp) and I have |
| 1159 | * no idea why. |
| 1160 | * - I'm pretty sure that all the things we do in CreateIcon should |
| 1161 | * also be done in CreateIconIndirect... |
Alexandre Julliard | f0cbfa0 | 1997-02-15 14:29:56 +0000 | [diff] [blame] | 1162 | */ |
François Gouget | 2c86506 | 2001-02-13 01:48:14 +0000 | [diff] [blame] | 1163 | HICON WINAPI CreateIcon( |
Patrik Stridvall | b3086a7 | 2001-04-25 19:54:21 +0000 | [diff] [blame] | 1164 | HINSTANCE hInstance, /* [in] the application's hInstance, currently unused */ |
| 1165 | INT nWidth, /* [in] the width of the provided bitmaps */ |
| 1166 | INT nHeight, /* [in] the height of the provided bitmaps */ |
| 1167 | BYTE bPlanes, /* [in] the number of planes in the provided bitmaps */ |
| 1168 | BYTE bBitsPixel, /* [in] the number of bits per pixel of the lpXORbits bitmap */ |
| 1169 | LPCVOID lpANDbits, /* [in] a monochrome bitmap representing the icon's mask */ |
| 1170 | LPCVOID lpXORbits) /* [in] the icon's 'color' bitmap */ |
Alexandre Julliard | f0cbfa0 | 1997-02-15 14:29:56 +0000 | [diff] [blame] | 1171 | { |
François Gouget | 2c86506 | 2001-02-13 01:48:14 +0000 | [diff] [blame] | 1172 | HICON hIcon; |
| 1173 | HDC hdc; |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 1174 | |
Alexandre Julliard | 06c275a | 1999-05-02 14:32:27 +0000 | [diff] [blame] | 1175 | TRACE_(icon)("%dx%dx%d, xor=%p, and=%p\n", |
François Gouget | 2c86506 | 2001-02-13 01:48:14 +0000 | [diff] [blame] | 1176 | nWidth, nHeight, bPlanes * bBitsPixel, lpXORbits, lpANDbits); |
Patrik Stridvall | a9a671d | 1999-04-25 19:01:52 +0000 | [diff] [blame] | 1177 | |
François Gouget | 2c86506 | 2001-02-13 01:48:14 +0000 | [diff] [blame] | 1178 | hdc=GetDC(0); |
| 1179 | if (!hdc) |
| 1180 | return 0; |
Patrik Stridvall | a9a671d | 1999-04-25 19:01:52 +0000 | [diff] [blame] | 1181 | |
François Gouget | 2c86506 | 2001-02-13 01:48:14 +0000 | [diff] [blame] | 1182 | if (GetDeviceCaps(hdc,BITSPIXEL)==bBitsPixel) { |
| 1183 | CURSORICONINFO info; |
| 1184 | |
| 1185 | info.ptHotSpot.x = ICON_HOTSPOT; |
| 1186 | info.ptHotSpot.y = ICON_HOTSPOT; |
| 1187 | info.nWidth = nWidth; |
| 1188 | info.nHeight = nHeight; |
| 1189 | info.nWidthBytes = 0; |
| 1190 | info.bPlanes = bPlanes; |
| 1191 | info.bBitsPerPixel = bBitsPixel; |
| 1192 | |
| 1193 | hIcon=CreateCursorIconIndirect16( 0, &info, lpANDbits, lpXORbits ); |
| 1194 | } else { |
| 1195 | ICONINFO iinfo; |
| 1196 | BITMAPINFO bmi; |
| 1197 | |
| 1198 | iinfo.fIcon=TRUE; |
| 1199 | iinfo.xHotspot=ICON_HOTSPOT; |
| 1200 | iinfo.yHotspot=ICON_HOTSPOT; |
| 1201 | iinfo.hbmMask=CreateBitmap(nWidth,nHeight,1,1,lpANDbits); |
| 1202 | |
| 1203 | bmi.bmiHeader.biSize=sizeof(bmi.bmiHeader); |
| 1204 | bmi.bmiHeader.biWidth=nWidth; |
| 1205 | bmi.bmiHeader.biHeight=-nHeight; |
| 1206 | bmi.bmiHeader.biPlanes=bPlanes; |
| 1207 | bmi.bmiHeader.biBitCount=bBitsPixel; |
| 1208 | bmi.bmiHeader.biCompression=BI_RGB; |
| 1209 | bmi.bmiHeader.biSizeImage=0; |
| 1210 | bmi.bmiHeader.biXPelsPerMeter=0; |
| 1211 | bmi.bmiHeader.biYPelsPerMeter=0; |
| 1212 | bmi.bmiHeader.biClrUsed=0; |
| 1213 | bmi.bmiHeader.biClrImportant=0; |
| 1214 | |
| 1215 | iinfo.hbmColor = CreateDIBitmap( hdc, &bmi.bmiHeader, |
| 1216 | CBM_INIT, lpXORbits, |
| 1217 | &bmi, DIB_RGB_COLORS ); |
| 1218 | |
| 1219 | hIcon=CreateIconIndirect(&iinfo); |
| 1220 | DeleteObject(iinfo.hbmMask); |
| 1221 | DeleteObject(iinfo.hbmColor); |
| 1222 | } |
| 1223 | ReleaseDC(0,hdc); |
| 1224 | return hIcon; |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 1225 | } |
| 1226 | |
| 1227 | |
| 1228 | /*********************************************************************** |
Patrik Stridvall | 2ece70e | 2000-12-22 01:38:01 +0000 | [diff] [blame] | 1229 | * CreateCursorIconIndirect (USER.408) |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 1230 | */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1231 | HGLOBAL16 WINAPI CreateCursorIconIndirect16( HINSTANCE16 hInstance, |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 1232 | CURSORICONINFO *info, |
| 1233 | LPCVOID lpANDbits, |
| 1234 | LPCVOID lpXORbits ) |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 1235 | { |
Alexandre Julliard | bf9130a | 1996-10-13 17:45:47 +0000 | [diff] [blame] | 1236 | HGLOBAL16 handle; |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 1237 | char *ptr; |
| 1238 | int sizeAnd, sizeXor; |
| 1239 | |
| 1240 | hInstance = GetExePtr( hInstance ); /* Make it a module handle */ |
Alexandre Julliard | dadf78f | 1998-05-17 17:13:43 +0000 | [diff] [blame] | 1241 | if (!lpXORbits || !lpANDbits || info->bPlanes != 1) return 0; |
Huw D M Davies | 8261736 | 1998-11-01 16:35:42 +0000 | [diff] [blame] | 1242 | info->nWidthBytes = BITMAP_GetWidthBytes(info->nWidth,info->bBitsPerPixel); |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 1243 | sizeXor = info->nHeight * info->nWidthBytes; |
Huw D M Davies | 8261736 | 1998-11-01 16:35:42 +0000 | [diff] [blame] | 1244 | sizeAnd = info->nHeight * BITMAP_GetWidthBytes( info->nWidth, 1 ); |
Alexandre Julliard | dadf78f | 1998-05-17 17:13:43 +0000 | [diff] [blame] | 1245 | if (!(handle = GlobalAlloc16( GMEM_MOVEABLE, |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 1246 | sizeof(CURSORICONINFO) + sizeXor + sizeAnd))) |
| 1247 | return 0; |
Alexandre Julliard | 7d5bc5c | 2001-01-15 20:09:09 +0000 | [diff] [blame] | 1248 | FarSetOwner16( handle, hInstance ); |
Alexandre Julliard | 1285c2f | 1996-05-06 16:06:24 +0000 | [diff] [blame] | 1249 | ptr = (char *)GlobalLock16( handle ); |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 1250 | memcpy( ptr, info, sizeof(*info) ); |
| 1251 | memcpy( ptr + sizeof(CURSORICONINFO), lpANDbits, sizeAnd ); |
| 1252 | memcpy( ptr + sizeof(CURSORICONINFO) + sizeAnd, lpXORbits, sizeXor ); |
Alexandre Julliard | 1285c2f | 1996-05-06 16:06:24 +0000 | [diff] [blame] | 1253 | GlobalUnlock16( handle ); |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 1254 | return handle; |
| 1255 | } |
| 1256 | |
| 1257 | |
| 1258 | /*********************************************************************** |
Patrik Stridvall | 2ece70e | 2000-12-22 01:38:01 +0000 | [diff] [blame] | 1259 | * CopyIcon (USER.368) |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 1260 | */ |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 1261 | HICON16 WINAPI CopyIcon16( HINSTANCE16 hInstance, HICON16 hIcon ) |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 1262 | { |
Alexandre Julliard | 06c275a | 1999-05-02 14:32:27 +0000 | [diff] [blame] | 1263 | TRACE_(icon)("%04x %04x\n", hInstance, hIcon ); |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 1264 | return CURSORICON_Copy( hInstance, hIcon ); |
| 1265 | } |
| 1266 | |
| 1267 | |
| 1268 | /*********************************************************************** |
Patrik Stridvall | 2ece70e | 2000-12-22 01:38:01 +0000 | [diff] [blame] | 1269 | * CopyIcon (USER32.@) |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 1270 | */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1271 | HICON WINAPI CopyIcon( HICON hIcon ) |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 1272 | { |
Alexandre Julliard | 06c275a | 1999-05-02 14:32:27 +0000 | [diff] [blame] | 1273 | TRACE_(icon)("%04x\n", hIcon ); |
Alexandre Julliard | 7d5bc5c | 2001-01-15 20:09:09 +0000 | [diff] [blame] | 1274 | return CURSORICON_Copy( 0, hIcon ); |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 1275 | } |
Alexandre Julliard | ca22b33 | 1996-07-12 19:02:39 +0000 | [diff] [blame] | 1276 | |
| 1277 | |
| 1278 | /*********************************************************************** |
Patrik Stridvall | 2ece70e | 2000-12-22 01:38:01 +0000 | [diff] [blame] | 1279 | * CopyCursor (USER.369) |
Alexandre Julliard | ca22b33 | 1996-07-12 19:02:39 +0000 | [diff] [blame] | 1280 | */ |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 1281 | HCURSOR16 WINAPI CopyCursor16( HINSTANCE16 hInstance, HCURSOR16 hCursor ) |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 1282 | { |
Alexandre Julliard | 06c275a | 1999-05-02 14:32:27 +0000 | [diff] [blame] | 1283 | TRACE_(cursor)("%04x %04x\n", hInstance, hCursor ); |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 1284 | return CURSORICON_Copy( hInstance, hCursor ); |
| 1285 | } |
| 1286 | |
Ulrich Weigand | 50a0915 | 1999-03-10 14:00:29 +0000 | [diff] [blame] | 1287 | /********************************************************************** |
Patrik Stridvall | 2ece70e | 2000-12-22 01:38:01 +0000 | [diff] [blame] | 1288 | * DestroyIcon32 (USER.610) |
Ulrich Weigand | 50a0915 | 1999-03-10 14:00:29 +0000 | [diff] [blame] | 1289 | * |
| 1290 | * This routine is actually exported from Win95 USER under the name |
| 1291 | * DestroyIcon32 ... The behaviour implemented here should mimic |
| 1292 | * the Win95 one exactly, especially the return values, which |
| 1293 | * depend on the setting of various flags. |
| 1294 | */ |
Marcus Meissner | c600afb | 1999-03-24 14:55:37 +0000 | [diff] [blame] | 1295 | WORD WINAPI CURSORICON_Destroy( HGLOBAL16 handle, UINT16 flags ) |
Ulrich Weigand | 50a0915 | 1999-03-10 14:00:29 +0000 | [diff] [blame] | 1296 | { |
| 1297 | WORD retv; |
| 1298 | |
Alexandre Julliard | 06c275a | 1999-05-02 14:32:27 +0000 | [diff] [blame] | 1299 | TRACE_(icon)("(%04x, %04x)\n", handle, flags ); |
Ulrich Weigand | 50a0915 | 1999-03-10 14:00:29 +0000 | [diff] [blame] | 1300 | |
| 1301 | /* Check whether destroying active cursor */ |
| 1302 | |
| 1303 | if ( hActiveCursor == handle ) |
| 1304 | { |
Alexandre Julliard | 06c275a | 1999-05-02 14:32:27 +0000 | [diff] [blame] | 1305 | ERR_(cursor)("Destroying active cursor!\n" ); |
Ulrich Weigand | 50a0915 | 1999-03-10 14:00:29 +0000 | [diff] [blame] | 1306 | SetCursor( 0 ); |
| 1307 | } |
| 1308 | |
| 1309 | /* Try shared cursor/icon first */ |
| 1310 | |
| 1311 | if ( !(flags & CID_NONSHARED) ) |
| 1312 | { |
| 1313 | INT count = CURSORICON_DelSharedIcon( handle ); |
| 1314 | |
| 1315 | if ( count != -1 ) |
| 1316 | return (flags & CID_WIN32)? TRUE : (count == 0); |
| 1317 | |
| 1318 | /* FIXME: OEM cursors/icons should be recognized */ |
| 1319 | } |
| 1320 | |
| 1321 | /* Now assume non-shared cursor/icon */ |
| 1322 | |
| 1323 | retv = GlobalFree16( handle ); |
| 1324 | return (flags & CID_RESOURCE)? retv : TRUE; |
| 1325 | } |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 1326 | |
| 1327 | /*********************************************************************** |
Patrik Stridvall | 0c61028 | 2001-01-25 22:22:21 +0000 | [diff] [blame] | 1328 | * DestroyIcon (USER.457) |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 1329 | */ |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 1330 | BOOL16 WINAPI DestroyIcon16( HICON16 hIcon ) |
Alexandre Julliard | f0cbfa0 | 1997-02-15 14:29:56 +0000 | [diff] [blame] | 1331 | { |
Ulrich Weigand | 50a0915 | 1999-03-10 14:00:29 +0000 | [diff] [blame] | 1332 | return CURSORICON_Destroy( hIcon, 0 ); |
Alexandre Julliard | f0cbfa0 | 1997-02-15 14:29:56 +0000 | [diff] [blame] | 1333 | } |
| 1334 | |
Alexandre Julliard | f0cbfa0 | 1997-02-15 14:29:56 +0000 | [diff] [blame] | 1335 | /*********************************************************************** |
Patrik Stridvall | 2ece70e | 2000-12-22 01:38:01 +0000 | [diff] [blame] | 1336 | * DestroyIcon (USER32.@) |
Alexandre Julliard | f0cbfa0 | 1997-02-15 14:29:56 +0000 | [diff] [blame] | 1337 | */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1338 | BOOL WINAPI DestroyIcon( HICON hIcon ) |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 1339 | { |
Ulrich Weigand | 50a0915 | 1999-03-10 14:00:29 +0000 | [diff] [blame] | 1340 | return CURSORICON_Destroy( hIcon, CID_WIN32 ); |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 1341 | } |
| 1342 | |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 1343 | /*********************************************************************** |
Patrik Stridvall | 2ece70e | 2000-12-22 01:38:01 +0000 | [diff] [blame] | 1344 | * DestroyCursor (USER.458) |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 1345 | */ |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 1346 | BOOL16 WINAPI DestroyCursor16( HCURSOR16 hCursor ) |
Alexandre Julliard | f0cbfa0 | 1997-02-15 14:29:56 +0000 | [diff] [blame] | 1347 | { |
Ulrich Weigand | 50a0915 | 1999-03-10 14:00:29 +0000 | [diff] [blame] | 1348 | return CURSORICON_Destroy( hCursor, 0 ); |
Alexandre Julliard | f0cbfa0 | 1997-02-15 14:29:56 +0000 | [diff] [blame] | 1349 | } |
| 1350 | |
Alexandre Julliard | f0cbfa0 | 1997-02-15 14:29:56 +0000 | [diff] [blame] | 1351 | /*********************************************************************** |
Patrik Stridvall | 2ece70e | 2000-12-22 01:38:01 +0000 | [diff] [blame] | 1352 | * DestroyCursor (USER32.@) |
Alexandre Julliard | f0cbfa0 | 1997-02-15 14:29:56 +0000 | [diff] [blame] | 1353 | */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1354 | BOOL WINAPI DestroyCursor( HCURSOR hCursor ) |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 1355 | { |
Ulrich Weigand | 50a0915 | 1999-03-10 14:00:29 +0000 | [diff] [blame] | 1356 | return CURSORICON_Destroy( hCursor, CID_WIN32 ); |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 1357 | } |
| 1358 | |
| 1359 | |
| 1360 | /*********************************************************************** |
Patrik Stridvall | 2ece70e | 2000-12-22 01:38:01 +0000 | [diff] [blame] | 1361 | * DrawIcon (USER.84) |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 1362 | */ |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 1363 | BOOL16 WINAPI DrawIcon16( HDC16 hdc, INT16 x, INT16 y, HICON16 hIcon ) |
Alexandre Julliard | f0cbfa0 | 1997-02-15 14:29:56 +0000 | [diff] [blame] | 1364 | { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1365 | return DrawIcon( hdc, x, y, hIcon ); |
Alexandre Julliard | f0cbfa0 | 1997-02-15 14:29:56 +0000 | [diff] [blame] | 1366 | } |
| 1367 | |
| 1368 | |
| 1369 | /*********************************************************************** |
Patrik Stridvall | 2ece70e | 2000-12-22 01:38:01 +0000 | [diff] [blame] | 1370 | * DrawIcon (USER32.@) |
Alexandre Julliard | f0cbfa0 | 1997-02-15 14:29:56 +0000 | [diff] [blame] | 1371 | */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1372 | BOOL WINAPI DrawIcon( HDC hdc, INT x, INT y, HICON hIcon ) |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 1373 | { |
| 1374 | CURSORICONINFO *ptr; |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1375 | HDC hMemDC; |
| 1376 | HBITMAP hXorBits, hAndBits; |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 1377 | COLORREF oldFg, oldBg; |
| 1378 | |
Alexandre Julliard | 1285c2f | 1996-05-06 16:06:24 +0000 | [diff] [blame] | 1379 | if (!(ptr = (CURSORICONINFO *)GlobalLock16( hIcon ))) return FALSE; |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1380 | if (!(hMemDC = CreateCompatibleDC( hdc ))) return FALSE; |
| 1381 | hAndBits = CreateBitmap( ptr->nWidth, ptr->nHeight, 1, 1, |
Alexandre Julliard | 2197901 | 1997-03-05 08:22:35 +0000 | [diff] [blame] | 1382 | (char *)(ptr+1) ); |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1383 | hXorBits = CreateBitmap( ptr->nWidth, ptr->nHeight, ptr->bPlanes, |
Alexandre Julliard | 2197901 | 1997-03-05 08:22:35 +0000 | [diff] [blame] | 1384 | ptr->bBitsPerPixel, (char *)(ptr + 1) |
Huw D M Davies | 8261736 | 1998-11-01 16:35:42 +0000 | [diff] [blame] | 1385 | + ptr->nHeight * BITMAP_GetWidthBytes(ptr->nWidth,1) ); |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1386 | oldFg = SetTextColor( hdc, RGB(0,0,0) ); |
| 1387 | oldBg = SetBkColor( hdc, RGB(255,255,255) ); |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 1388 | |
| 1389 | if (hXorBits && hAndBits) |
| 1390 | { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1391 | HBITMAP hBitTemp = SelectObject( hMemDC, hAndBits ); |
| 1392 | BitBlt( hdc, x, y, ptr->nWidth, ptr->nHeight, hMemDC, 0, 0, SRCAND ); |
| 1393 | SelectObject( hMemDC, hXorBits ); |
| 1394 | BitBlt(hdc, x, y, ptr->nWidth, ptr->nHeight, hMemDC, 0, 0,SRCINVERT); |
| 1395 | SelectObject( hMemDC, hBitTemp ); |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 1396 | } |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1397 | DeleteDC( hMemDC ); |
| 1398 | if (hXorBits) DeleteObject( hXorBits ); |
| 1399 | if (hAndBits) DeleteObject( hAndBits ); |
Alexandre Julliard | 1285c2f | 1996-05-06 16:06:24 +0000 | [diff] [blame] | 1400 | GlobalUnlock16( hIcon ); |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1401 | SetTextColor( hdc, oldFg ); |
| 1402 | SetBkColor( hdc, oldBg ); |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 1403 | return TRUE; |
| 1404 | } |
| 1405 | |
| 1406 | |
| 1407 | /*********************************************************************** |
Patrik Stridvall | 2ece70e | 2000-12-22 01:38:01 +0000 | [diff] [blame] | 1408 | * IconSize (USER.86) |
Andreas Mohr | 1f0c216 | 2000-06-24 12:54:00 +0000 | [diff] [blame] | 1409 | * |
| 1410 | * See "Undocumented Windows". Used by W2.0 paint.exe. |
| 1411 | */ |
| 1412 | DWORD WINAPI IconSize16( void ) |
| 1413 | { |
| 1414 | return MAKELONG(GetSystemMetrics(SM_CYICON), GetSystemMetrics(SM_CXICON)); |
| 1415 | } |
| 1416 | |
| 1417 | |
| 1418 | /*********************************************************************** |
Patrik Stridvall | 2ece70e | 2000-12-22 01:38:01 +0000 | [diff] [blame] | 1419 | * DumpIcon (USER.459) |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 1420 | */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1421 | DWORD WINAPI DumpIcon16( SEGPTR pInfo, WORD *lpLen, |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 1422 | SEGPTR *lpXorBits, SEGPTR *lpAndBits ) |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 1423 | { |
Alexandre Julliard | 982a223 | 2000-12-13 20:20:09 +0000 | [diff] [blame] | 1424 | CURSORICONINFO *info = MapSL( pInfo ); |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 1425 | int sizeAnd, sizeXor; |
| 1426 | |
| 1427 | if (!info) return 0; |
| 1428 | sizeXor = info->nHeight * info->nWidthBytes; |
Huw D M Davies | 8261736 | 1998-11-01 16:35:42 +0000 | [diff] [blame] | 1429 | sizeAnd = info->nHeight * BITMAP_GetWidthBytes( info->nWidth, 1 ); |
Alexandre Julliard | ade697e | 1995-11-26 13:59:11 +0000 | [diff] [blame] | 1430 | if (lpAndBits) *lpAndBits = pInfo + sizeof(CURSORICONINFO); |
| 1431 | if (lpXorBits) *lpXorBits = pInfo + sizeof(CURSORICONINFO) + sizeAnd; |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 1432 | if (lpLen) *lpLen = sizeof(CURSORICONINFO) + sizeAnd + sizeXor; |
| 1433 | return MAKELONG( sizeXor, sizeXor ); |
| 1434 | } |
| 1435 | |
| 1436 | |
| 1437 | /*********************************************************************** |
Patrik Stridvall | 2ece70e | 2000-12-22 01:38:01 +0000 | [diff] [blame] | 1438 | * SetCursor (USER.69) |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 1439 | */ |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 1440 | HCURSOR16 WINAPI SetCursor16( HCURSOR16 hCursor ) |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 1441 | { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1442 | return (HCURSOR16)SetCursor( hCursor ); |
Alexandre Julliard | f0cbfa0 | 1997-02-15 14:29:56 +0000 | [diff] [blame] | 1443 | } |
| 1444 | |
| 1445 | |
| 1446 | /*********************************************************************** |
Patrik Stridvall | 2ece70e | 2000-12-22 01:38:01 +0000 | [diff] [blame] | 1447 | * SetCursor (USER32.@) |
Alexandre Julliard | a69b88b | 1998-03-15 20:29:56 +0000 | [diff] [blame] | 1448 | * RETURNS: |
| 1449 | * A handle to the previous cursor shape. |
Alexandre Julliard | f0cbfa0 | 1997-02-15 14:29:56 +0000 | [diff] [blame] | 1450 | */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1451 | HCURSOR WINAPI SetCursor( |
Patrik Stridvall | 2b3aa61 | 2000-12-01 23:58:28 +0000 | [diff] [blame] | 1452 | HCURSOR hCursor /* [in] Handle of cursor to show */ |
Alexandre Julliard | a69b88b | 1998-03-15 20:29:56 +0000 | [diff] [blame] | 1453 | ) { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1454 | HCURSOR hOldCursor; |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 1455 | |
| 1456 | if (hCursor == hActiveCursor) return hActiveCursor; /* No change */ |
Alexandre Julliard | 06c275a | 1999-05-02 14:32:27 +0000 | [diff] [blame] | 1457 | TRACE_(cursor)("%04x\n", hCursor ); |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 1458 | hOldCursor = hActiveCursor; |
| 1459 | hActiveCursor = hCursor; |
| 1460 | /* Change the cursor shape only if it is visible */ |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 1461 | if (CURSOR_ShowCount >= 0) |
Alexandre Julliard | 03468f7 | 1998-02-15 19:40:49 +0000 | [diff] [blame] | 1462 | { |
Alexandre Julliard | 42d20f9 | 2000-08-10 01:16:19 +0000 | [diff] [blame] | 1463 | USER_Driver.pSetCursor( (CURSORICONINFO*)GlobalLock16( hActiveCursor ) ); |
Ulrich Weigand | 431d1a0 | 1998-11-14 18:57:47 +0000 | [diff] [blame] | 1464 | GlobalUnlock16( hActiveCursor ); |
Alexandre Julliard | 03468f7 | 1998-02-15 19:40:49 +0000 | [diff] [blame] | 1465 | } |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 1466 | return hOldCursor; |
| 1467 | } |
| 1468 | |
| 1469 | |
| 1470 | /*********************************************************************** |
Patrik Stridvall | 2ece70e | 2000-12-22 01:38:01 +0000 | [diff] [blame] | 1471 | * ShowCursor (USER.71) |
Alexandre Julliard | f0cbfa0 | 1997-02-15 14:29:56 +0000 | [diff] [blame] | 1472 | */ |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 1473 | INT16 WINAPI ShowCursor16( BOOL16 bShow ) |
Alexandre Julliard | f0cbfa0 | 1997-02-15 14:29:56 +0000 | [diff] [blame] | 1474 | { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1475 | return ShowCursor( bShow ); |
Alexandre Julliard | f0cbfa0 | 1997-02-15 14:29:56 +0000 | [diff] [blame] | 1476 | } |
| 1477 | |
| 1478 | |
| 1479 | /*********************************************************************** |
Patrik Stridvall | 2ece70e | 2000-12-22 01:38:01 +0000 | [diff] [blame] | 1480 | * ShowCursor (USER32.@) |
Alexandre Julliard | f0cbfa0 | 1997-02-15 14:29:56 +0000 | [diff] [blame] | 1481 | */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1482 | INT WINAPI ShowCursor( BOOL bShow ) |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 1483 | { |
Alexandre Julliard | 06c275a | 1999-05-02 14:32:27 +0000 | [diff] [blame] | 1484 | TRACE_(cursor)("%d, count=%d\n", |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 1485 | bShow, CURSOR_ShowCount ); |
| 1486 | |
| 1487 | if (bShow) |
| 1488 | { |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 1489 | if (++CURSOR_ShowCount == 0) /* Show it */ |
Ulrich Weigand | 431d1a0 | 1998-11-14 18:57:47 +0000 | [diff] [blame] | 1490 | { |
Alexandre Julliard | 42d20f9 | 2000-08-10 01:16:19 +0000 | [diff] [blame] | 1491 | USER_Driver.pSetCursor( (CURSORICONINFO*)GlobalLock16( hActiveCursor ) ); |
Ulrich Weigand | 431d1a0 | 1998-11-14 18:57:47 +0000 | [diff] [blame] | 1492 | GlobalUnlock16( hActiveCursor ); |
| 1493 | } |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 1494 | } |
| 1495 | else |
| 1496 | { |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 1497 | if (--CURSOR_ShowCount == -1) /* Hide it */ |
Alexandre Julliard | 42d20f9 | 2000-08-10 01:16:19 +0000 | [diff] [blame] | 1498 | USER_Driver.pSetCursor( NULL ); |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 1499 | } |
| 1500 | return CURSOR_ShowCount; |
| 1501 | } |
| 1502 | |
| 1503 | |
| 1504 | /*********************************************************************** |
Patrik Stridvall | 2ece70e | 2000-12-22 01:38:01 +0000 | [diff] [blame] | 1505 | * GetCursor (USER.247) |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 1506 | */ |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 1507 | HCURSOR16 WINAPI GetCursor16(void) |
Alexandre Julliard | f0cbfa0 | 1997-02-15 14:29:56 +0000 | [diff] [blame] | 1508 | { |
| 1509 | return hActiveCursor; |
| 1510 | } |
| 1511 | |
| 1512 | |
| 1513 | /*********************************************************************** |
Patrik Stridvall | 2ece70e | 2000-12-22 01:38:01 +0000 | [diff] [blame] | 1514 | * GetCursor (USER32.@) |
Alexandre Julliard | f0cbfa0 | 1997-02-15 14:29:56 +0000 | [diff] [blame] | 1515 | */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1516 | HCURSOR WINAPI GetCursor(void) |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 1517 | { |
| 1518 | return hActiveCursor; |
| 1519 | } |
| 1520 | |
| 1521 | |
| 1522 | /*********************************************************************** |
Patrik Stridvall | 2ece70e | 2000-12-22 01:38:01 +0000 | [diff] [blame] | 1523 | * ClipCursor (USER.16) |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 1524 | */ |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 1525 | BOOL16 WINAPI ClipCursor16( const RECT16 *rect ) |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 1526 | { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1527 | if (!rect) SetRectEmpty( &CURSOR_ClipRect ); |
Alexandre Julliard | e2bfa4c | 1996-05-16 18:21:06 +0000 | [diff] [blame] | 1528 | else CONV_RECT16TO32( rect, &CURSOR_ClipRect ); |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 1529 | return TRUE; |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 1530 | } |
| 1531 | |
| 1532 | |
| 1533 | /*********************************************************************** |
Patrik Stridvall | 2ece70e | 2000-12-22 01:38:01 +0000 | [diff] [blame] | 1534 | * ClipCursor (USER32.@) |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 1535 | */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1536 | BOOL WINAPI ClipCursor( const RECT *rect ) |
Alexandre Julliard | e2bfa4c | 1996-05-16 18:21:06 +0000 | [diff] [blame] | 1537 | { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1538 | if (!rect) SetRectEmpty( &CURSOR_ClipRect ); |
| 1539 | else CopyRect( &CURSOR_ClipRect, rect ); |
Alexandre Julliard | e2bfa4c | 1996-05-16 18:21:06 +0000 | [diff] [blame] | 1540 | return TRUE; |
| 1541 | } |
| 1542 | |
| 1543 | |
| 1544 | /*********************************************************************** |
Patrik Stridvall | 2ece70e | 2000-12-22 01:38:01 +0000 | [diff] [blame] | 1545 | * GetClipCursor (USER.309) |
Alexandre Julliard | e2bfa4c | 1996-05-16 18:21:06 +0000 | [diff] [blame] | 1546 | */ |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 1547 | void WINAPI GetClipCursor16( RECT16 *rect ) |
Alexandre Julliard | e2bfa4c | 1996-05-16 18:21:06 +0000 | [diff] [blame] | 1548 | { |
| 1549 | if (rect) CONV_RECT32TO16( &CURSOR_ClipRect, rect ); |
| 1550 | } |
| 1551 | |
| 1552 | |
| 1553 | /*********************************************************************** |
Patrik Stridvall | 2ece70e | 2000-12-22 01:38:01 +0000 | [diff] [blame] | 1554 | * GetClipCursor (USER32.@) |
Alexandre Julliard | e2bfa4c | 1996-05-16 18:21:06 +0000 | [diff] [blame] | 1555 | */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1556 | BOOL WINAPI GetClipCursor( RECT *rect ) |
Alexandre Julliard | e2bfa4c | 1996-05-16 18:21:06 +0000 | [diff] [blame] | 1557 | { |
Eric Pouech | b9544f1 | 1999-02-14 14:09:42 +0000 | [diff] [blame] | 1558 | if (rect) |
| 1559 | { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1560 | CopyRect( rect, &CURSOR_ClipRect ); |
Eric Pouech | b9544f1 | 1999-02-14 14:09:42 +0000 | [diff] [blame] | 1561 | return TRUE; |
| 1562 | } |
| 1563 | return FALSE; |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 1564 | } |
| 1565 | |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 1566 | /********************************************************************** |
Patrik Stridvall | 2ece70e | 2000-12-22 01:38:01 +0000 | [diff] [blame] | 1567 | * LookupIconIdFromDirectoryEx (USER.364) |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 1568 | * |
| 1569 | * FIXME: exact parameter sizes |
| 1570 | */ |
Alexandre Julliard | e658d82 | 1997-11-30 17:45:40 +0000 | [diff] [blame] | 1571 | INT16 WINAPI LookupIconIdFromDirectoryEx16( LPBYTE xdir, BOOL16 bIcon, |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 1572 | INT16 width, INT16 height, UINT16 cFlag ) |
| 1573 | { |
Alexandre Julliard | e658d82 | 1997-11-30 17:45:40 +0000 | [diff] [blame] | 1574 | CURSORICONDIR *dir = (CURSORICONDIR*)xdir; |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 1575 | UINT16 retVal = 0; |
| 1576 | if( dir && !dir->idReserved && (dir->idType & 3) ) |
| 1577 | { |
Juergen Schmied | c45bbee | 1999-04-11 11:46:32 +0000 | [diff] [blame] | 1578 | CURSORICONDIRENTRY* entry; |
Pavel Roskin | 5b14b53 | 1999-04-18 09:34:51 +0000 | [diff] [blame] | 1579 | HDC hdc; |
| 1580 | UINT palEnts; |
| 1581 | int colors; |
| 1582 | hdc = GetDC(0); |
| 1583 | palEnts = GetSystemPaletteEntries(hdc, 0, 0, NULL); |
| 1584 | if (palEnts == 0) |
| 1585 | palEnts = 256; |
| 1586 | colors = (cFlag & LR_MONOCHROME) ? 2 : palEnts; |
Juergen Schmied | c45bbee | 1999-04-11 11:46:32 +0000 | [diff] [blame] | 1587 | |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1588 | ReleaseDC(0, hdc); |
Huw D M Davies | a38d84d | 1998-11-30 11:18:26 +0000 | [diff] [blame] | 1589 | |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 1590 | if( bIcon ) |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 1591 | entry = CURSORICON_FindBestIcon( dir, width, height, colors ); |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 1592 | else |
Turchanov Sergey | 62d6e98 | 1998-10-18 13:42:55 +0000 | [diff] [blame] | 1593 | entry = CURSORICON_FindBestCursor( dir, width, height, 1); |
Juergen Schmied | c45bbee | 1999-04-11 11:46:32 +0000 | [diff] [blame] | 1594 | |
| 1595 | if( entry ) retVal = entry->wResId; |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 1596 | } |
Alexandre Julliard | 06c275a | 1999-05-02 14:32:27 +0000 | [diff] [blame] | 1597 | else WARN_(cursor)("invalid resource directory\n"); |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 1598 | return retVal; |
| 1599 | } |
| 1600 | |
| 1601 | /********************************************************************** |
Patrik Stridvall | 2ece70e | 2000-12-22 01:38:01 +0000 | [diff] [blame] | 1602 | * LookupIconIdFromDirectoryEx (USER32.@) |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 1603 | */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1604 | INT WINAPI LookupIconIdFromDirectoryEx( LPBYTE dir, BOOL bIcon, |
| 1605 | INT width, INT height, UINT cFlag ) |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 1606 | { |
| 1607 | return LookupIconIdFromDirectoryEx16( dir, bIcon, width, height, cFlag ); |
| 1608 | } |
| 1609 | |
| 1610 | /********************************************************************** |
Patrik Stridvall | 044855c | 2001-07-11 18:56:41 +0000 | [diff] [blame] | 1611 | * LookupIconIdFromDirectory (USER.?) |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 1612 | */ |
Alexandre Julliard | e658d82 | 1997-11-30 17:45:40 +0000 | [diff] [blame] | 1613 | INT16 WINAPI LookupIconIdFromDirectory16( LPBYTE dir, BOOL16 bIcon ) |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 1614 | { |
| 1615 | return LookupIconIdFromDirectoryEx16( dir, bIcon, |
Marcus Meissner | ddca315 | 1999-05-22 11:33:23 +0000 | [diff] [blame] | 1616 | bIcon ? GetSystemMetrics(SM_CXICON) : GetSystemMetrics(SM_CXCURSOR), |
| 1617 | bIcon ? GetSystemMetrics(SM_CYICON) : GetSystemMetrics(SM_CYCURSOR), bIcon ? 0 : LR_MONOCHROME ); |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 1618 | } |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 1619 | |
| 1620 | /********************************************************************** |
Patrik Stridvall | 2ece70e | 2000-12-22 01:38:01 +0000 | [diff] [blame] | 1621 | * LookupIconIdFromDirectory (USER32.@) |
Alexandre Julliard | e658d82 | 1997-11-30 17:45:40 +0000 | [diff] [blame] | 1622 | */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1623 | INT WINAPI LookupIconIdFromDirectory( LPBYTE dir, BOOL bIcon ) |
Alexandre Julliard | e658d82 | 1997-11-30 17:45:40 +0000 | [diff] [blame] | 1624 | { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1625 | return LookupIconIdFromDirectoryEx( dir, bIcon, |
Marcus Meissner | ddca315 | 1999-05-22 11:33:23 +0000 | [diff] [blame] | 1626 | bIcon ? GetSystemMetrics(SM_CXICON) : GetSystemMetrics(SM_CXCURSOR), |
| 1627 | bIcon ? GetSystemMetrics(SM_CYICON) : GetSystemMetrics(SM_CYCURSOR), bIcon ? 0 : LR_MONOCHROME ); |
Alexandre Julliard | e658d82 | 1997-11-30 17:45:40 +0000 | [diff] [blame] | 1628 | } |
| 1629 | |
| 1630 | /********************************************************************** |
Patrik Stridvall | 2ece70e | 2000-12-22 01:38:01 +0000 | [diff] [blame] | 1631 | * GetIconID (USER.455) |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 1632 | */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1633 | WORD WINAPI GetIconID16( HGLOBAL16 hResource, DWORD resType ) |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 1634 | { |
Alexandre Julliard | e658d82 | 1997-11-30 17:45:40 +0000 | [diff] [blame] | 1635 | LPBYTE lpDir = (LPBYTE)GlobalLock16(hResource); |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 1636 | |
Alexandre Julliard | 06c275a | 1999-05-02 14:32:27 +0000 | [diff] [blame] | 1637 | TRACE_(cursor)("hRes=%04x, entries=%i\n", |
Alexandre Julliard | e658d82 | 1997-11-30 17:45:40 +0000 | [diff] [blame] | 1638 | hResource, lpDir ? ((CURSORICONDIR*)lpDir)->idCount : 0); |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 1639 | |
| 1640 | switch(resType) |
| 1641 | { |
Alexandre Julliard | c7c217b | 1998-04-13 12:21:30 +0000 | [diff] [blame] | 1642 | case RT_CURSOR16: |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 1643 | return (WORD)LookupIconIdFromDirectoryEx16( lpDir, FALSE, |
Marcus Meissner | ddca315 | 1999-05-22 11:33:23 +0000 | [diff] [blame] | 1644 | GetSystemMetrics(SM_CXCURSOR), GetSystemMetrics(SM_CYCURSOR), LR_MONOCHROME ); |
Alexandre Julliard | c7c217b | 1998-04-13 12:21:30 +0000 | [diff] [blame] | 1645 | case RT_ICON16: |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 1646 | return (WORD)LookupIconIdFromDirectoryEx16( lpDir, TRUE, |
Marcus Meissner | ddca315 | 1999-05-22 11:33:23 +0000 | [diff] [blame] | 1647 | GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON), 0 ); |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 1648 | default: |
Alexandre Julliard | 06c275a | 1999-05-02 14:32:27 +0000 | [diff] [blame] | 1649 | WARN_(cursor)("invalid res type %ld\n", resType ); |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 1650 | } |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 1651 | return 0; |
| 1652 | } |
| 1653 | |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 1654 | /********************************************************************** |
Patrik Stridvall | 2ece70e | 2000-12-22 01:38:01 +0000 | [diff] [blame] | 1655 | * LoadCursorIconHandler (USER.336) |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 1656 | * |
| 1657 | * Supposed to load resources of Windows 2.x applications. |
| 1658 | */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1659 | HGLOBAL16 WINAPI LoadCursorIconHandler16( HGLOBAL16 hResource, HMODULE16 hModule, HRSRC16 hRsrc ) |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 1660 | { |
Alexandre Julliard | 06c275a | 1999-05-02 14:32:27 +0000 | [diff] [blame] | 1661 | FIXME_(cursor)("(%04x,%04x,%04x): old 2.x resources are not supported!\n", |
Alexandre Julliard | 54c2711 | 1998-03-29 19:44:57 +0000 | [diff] [blame] | 1662 | hResource, hModule, hRsrc); |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 1663 | return (HGLOBAL16)0; |
| 1664 | } |
| 1665 | |
| 1666 | /********************************************************************** |
Patrik Stridvall | 2ece70e | 2000-12-22 01:38:01 +0000 | [diff] [blame] | 1667 | * LoadDIBIconHandler (USER.357) |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 1668 | * |
| 1669 | * RT_ICON resource loader, installed by USER_SignalProc when module |
| 1670 | * is initialized. |
| 1671 | */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1672 | HGLOBAL16 WINAPI LoadDIBIconHandler16( HGLOBAL16 hMemObj, HMODULE16 hModule, HRSRC16 hRsrc ) |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 1673 | { |
| 1674 | /* If hResource is zero we must allocate a new memory block, if it's |
| 1675 | * non-zero but GlobalLock() returns NULL then it was discarded and |
| 1676 | * we have to recommit some memory, otherwise we just need to check |
| 1677 | * the block size. See LoadProc() in 16-bit SDK for more. |
| 1678 | */ |
| 1679 | |
Ulrich Weigand | 50a0915 | 1999-03-10 14:00:29 +0000 | [diff] [blame] | 1680 | hMemObj = NE_DefResourceHandler( hMemObj, hModule, hRsrc ); |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 1681 | if( hMemObj ) |
| 1682 | { |
| 1683 | LPBYTE bits = (LPBYTE)GlobalLock16( hMemObj ); |
| 1684 | hMemObj = CURSORICON_CreateFromResource( hModule, hMemObj, bits, |
| 1685 | SizeofResource16(hModule, hRsrc), TRUE, 0x00030000, |
Marcus Meissner | ddca315 | 1999-05-22 11:33:23 +0000 | [diff] [blame] | 1686 | GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON), LR_DEFAULTCOLOR ); |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 1687 | } |
| 1688 | return hMemObj; |
| 1689 | } |
| 1690 | |
| 1691 | /********************************************************************** |
Patrik Stridvall | 2ece70e | 2000-12-22 01:38:01 +0000 | [diff] [blame] | 1692 | * LoadDIBCursorHandler (USER.356) |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 1693 | * |
| 1694 | * RT_CURSOR resource loader. Same as above. |
| 1695 | */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1696 | HGLOBAL16 WINAPI LoadDIBCursorHandler16( HGLOBAL16 hMemObj, HMODULE16 hModule, HRSRC16 hRsrc ) |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 1697 | { |
Ulrich Weigand | 50a0915 | 1999-03-10 14:00:29 +0000 | [diff] [blame] | 1698 | hMemObj = NE_DefResourceHandler( hMemObj, hModule, hRsrc ); |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 1699 | if( hMemObj ) |
| 1700 | { |
| 1701 | LPBYTE bits = (LPBYTE)GlobalLock16( hMemObj ); |
| 1702 | hMemObj = CURSORICON_CreateFromResource( hModule, hMemObj, bits, |
| 1703 | SizeofResource16(hModule, hRsrc), FALSE, 0x00030000, |
Marcus Meissner | ddca315 | 1999-05-22 11:33:23 +0000 | [diff] [blame] | 1704 | GetSystemMetrics(SM_CXCURSOR), GetSystemMetrics(SM_CYCURSOR), LR_MONOCHROME ); |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 1705 | } |
| 1706 | return hMemObj; |
| 1707 | } |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 1708 | |
| 1709 | /********************************************************************** |
Patrik Stridvall | 2ece70e | 2000-12-22 01:38:01 +0000 | [diff] [blame] | 1710 | * LoadIconHandler (USER.456) |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 1711 | */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1712 | HICON16 WINAPI LoadIconHandler16( HGLOBAL16 hResource, BOOL16 bNew ) |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 1713 | { |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 1714 | LPBYTE bits = (LPBYTE)LockResource16( hResource ); |
| 1715 | |
Alexandre Julliard | 06c275a | 1999-05-02 14:32:27 +0000 | [diff] [blame] | 1716 | TRACE_(cursor)("hRes=%04x\n",hResource); |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 1717 | |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 1718 | return CURSORICON_CreateFromResource( 0, 0, bits, 0, TRUE, |
| 1719 | bNew ? 0x00030000 : 0x00020000, 0, 0, LR_DEFAULTCOLOR ); |
| 1720 | } |
| 1721 | |
| 1722 | /*********************************************************************** |
Patrik Stridvall | 2ece70e | 2000-12-22 01:38:01 +0000 | [diff] [blame] | 1723 | * LoadCursorW (USER32.@) |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 1724 | */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1725 | HCURSOR WINAPI LoadCursorW(HINSTANCE hInstance, LPCWSTR name) |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 1726 | { |
Ulrich Weigand | 50a0915 | 1999-03-10 14:00:29 +0000 | [diff] [blame] | 1727 | return LoadImageW( hInstance, name, IMAGE_CURSOR, 0, 0, |
| 1728 | LR_SHARED | LR_DEFAULTSIZE ); |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 1729 | } |
| 1730 | |
| 1731 | /*********************************************************************** |
Patrik Stridvall | 2ece70e | 2000-12-22 01:38:01 +0000 | [diff] [blame] | 1732 | * LoadCursorA (USER32.@) |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 1733 | */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1734 | HCURSOR WINAPI LoadCursorA(HINSTANCE hInstance, LPCSTR name) |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 1735 | { |
Ulrich Weigand | 50a0915 | 1999-03-10 14:00:29 +0000 | [diff] [blame] | 1736 | return LoadImageA( hInstance, name, IMAGE_CURSOR, 0, 0, |
| 1737 | LR_SHARED | LR_DEFAULTSIZE ); |
Alexandre Julliard | f90efa9 | 1998-06-14 15:24:15 +0000 | [diff] [blame] | 1738 | } |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 1739 | |
| 1740 | /*********************************************************************** |
Patrik Stridvall | 2ece70e | 2000-12-22 01:38:01 +0000 | [diff] [blame] | 1741 | * LoadCursorFromFileW (USER32.@) |
| 1742 | */ |
Ulrich Weigand | 50a0915 | 1999-03-10 14:00:29 +0000 | [diff] [blame] | 1743 | HCURSOR WINAPI LoadCursorFromFileW (LPCWSTR name) |
| 1744 | { |
| 1745 | return LoadImageW( 0, name, IMAGE_CURSOR, 0, 0, |
| 1746 | LR_LOADFROMFILE | LR_DEFAULTSIZE ); |
| 1747 | } |
| 1748 | |
| 1749 | /*********************************************************************** |
Patrik Stridvall | 2ece70e | 2000-12-22 01:38:01 +0000 | [diff] [blame] | 1750 | * LoadCursorFromFileA (USER32.@) |
| 1751 | */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1752 | HCURSOR WINAPI LoadCursorFromFileA (LPCSTR name) |
Turchanov Sergey | 62d6e98 | 1998-10-18 13:42:55 +0000 | [diff] [blame] | 1753 | { |
Ulrich Weigand | 50a0915 | 1999-03-10 14:00:29 +0000 | [diff] [blame] | 1754 | return LoadImageA( 0, name, IMAGE_CURSOR, 0, 0, |
| 1755 | LR_LOADFROMFILE | LR_DEFAULTSIZE ); |
Alexandre Julliard | f90efa9 | 1998-06-14 15:24:15 +0000 | [diff] [blame] | 1756 | } |
| 1757 | |
| 1758 | /*********************************************************************** |
Patrik Stridvall | 2ece70e | 2000-12-22 01:38:01 +0000 | [diff] [blame] | 1759 | * LoadIconW (USER32.@) |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 1760 | */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1761 | HICON WINAPI LoadIconW(HINSTANCE hInstance, LPCWSTR name) |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 1762 | { |
Ulrich Weigand | 50a0915 | 1999-03-10 14:00:29 +0000 | [diff] [blame] | 1763 | return LoadImageW( hInstance, name, IMAGE_ICON, 0, 0, |
| 1764 | LR_SHARED | LR_DEFAULTSIZE ); |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 1765 | } |
| 1766 | |
| 1767 | /*********************************************************************** |
Patrik Stridvall | 2ece70e | 2000-12-22 01:38:01 +0000 | [diff] [blame] | 1768 | * LoadIconA (USER32.@) |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 1769 | */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1770 | HICON WINAPI LoadIconA(HINSTANCE hInstance, LPCSTR name) |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 1771 | { |
Ulrich Weigand | 50a0915 | 1999-03-10 14:00:29 +0000 | [diff] [blame] | 1772 | return LoadImageA( hInstance, name, IMAGE_ICON, 0, 0, |
| 1773 | LR_SHARED | LR_DEFAULTSIZE ); |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 1774 | } |
Alexandre Julliard | 7ff1c41 | 1997-05-25 13:58:18 +0000 | [diff] [blame] | 1775 | |
| 1776 | /********************************************************************** |
Patrik Stridvall | 2ece70e | 2000-12-22 01:38:01 +0000 | [diff] [blame] | 1777 | * GetIconInfo (USER.395) |
Alexandre Julliard | 7ff1c41 | 1997-05-25 13:58:18 +0000 | [diff] [blame] | 1778 | */ |
Marcus Meissner | ffb912e | 1999-01-28 09:14:38 +0000 | [diff] [blame] | 1779 | BOOL16 WINAPI GetIconInfo16(HICON16 hIcon,LPICONINFO16 iconinfo) |
Andreas Mohr | 22c904d | 1999-01-26 14:56:01 +0000 | [diff] [blame] | 1780 | { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1781 | ICONINFO ii32; |
| 1782 | BOOL16 ret = GetIconInfo((HICON)hIcon, &ii32); |
Marcus Meissner | ffb912e | 1999-01-28 09:14:38 +0000 | [diff] [blame] | 1783 | |
| 1784 | iconinfo->fIcon = ii32.fIcon; |
| 1785 | iconinfo->xHotspot = ii32.xHotspot; |
| 1786 | iconinfo->yHotspot = ii32.yHotspot; |
| 1787 | iconinfo->hbmMask = ii32.hbmMask; |
| 1788 | iconinfo->hbmColor = ii32.hbmColor; |
| 1789 | return ret; |
Andreas Mohr | 22c904d | 1999-01-26 14:56:01 +0000 | [diff] [blame] | 1790 | } |
| 1791 | |
| 1792 | /********************************************************************** |
Patrik Stridvall | 2ece70e | 2000-12-22 01:38:01 +0000 | [diff] [blame] | 1793 | * GetIconInfo (USER32.@) |
Andreas Mohr | 22c904d | 1999-01-26 14:56:01 +0000 | [diff] [blame] | 1794 | */ |
Francois Gouget | 67c9691 | 2000-10-12 23:18:55 +0000 | [diff] [blame] | 1795 | BOOL WINAPI GetIconInfo(HICON hIcon,PICONINFO iconinfo) { |
Alexandre Julliard | 491502b | 1997-11-01 19:08:16 +0000 | [diff] [blame] | 1796 | CURSORICONINFO *ciconinfo; |
Alexandre Julliard | 7ff1c41 | 1997-05-25 13:58:18 +0000 | [diff] [blame] | 1797 | |
Alexandre Julliard | 491502b | 1997-11-01 19:08:16 +0000 | [diff] [blame] | 1798 | ciconinfo = GlobalLock16(hIcon); |
| 1799 | if (!ciconinfo) |
| 1800 | return FALSE; |
Francis Beaudet | 699900b | 1999-09-05 12:15:49 +0000 | [diff] [blame] | 1801 | |
| 1802 | if ( (ciconinfo->ptHotSpot.x == ICON_HOTSPOT) && |
| 1803 | (ciconinfo->ptHotSpot.y == ICON_HOTSPOT) ) |
| 1804 | { |
| 1805 | iconinfo->fIcon = TRUE; |
Dave Hawkes | dbb6ab2 | 2000-07-09 12:16:58 +0000 | [diff] [blame] | 1806 | iconinfo->xHotspot = ciconinfo->nWidth / 2; |
| 1807 | iconinfo->yHotspot = ciconinfo->nHeight / 2; |
Francis Beaudet | 699900b | 1999-09-05 12:15:49 +0000 | [diff] [blame] | 1808 | } |
| 1809 | else |
| 1810 | { |
| 1811 | iconinfo->fIcon = FALSE; |
| 1812 | iconinfo->xHotspot = ciconinfo->ptHotSpot.x; |
| 1813 | iconinfo->yHotspot = ciconinfo->ptHotSpot.y; |
| 1814 | } |
Alexandre Julliard | 829fe32 | 1998-07-26 14:27:39 +0000 | [diff] [blame] | 1815 | |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1816 | iconinfo->hbmColor = CreateBitmap ( ciconinfo->nWidth, ciconinfo->nHeight, |
Alexandre Julliard | 829fe32 | 1998-07-26 14:27:39 +0000 | [diff] [blame] | 1817 | ciconinfo->bPlanes, ciconinfo->bBitsPerPixel, |
| 1818 | (char *)(ciconinfo + 1) |
| 1819 | + ciconinfo->nHeight * |
Huw D M Davies | 8261736 | 1998-11-01 16:35:42 +0000 | [diff] [blame] | 1820 | BITMAP_GetWidthBytes (ciconinfo->nWidth,1) ); |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1821 | iconinfo->hbmMask = CreateBitmap ( ciconinfo->nWidth, ciconinfo->nHeight, |
Alexandre Julliard | 829fe32 | 1998-07-26 14:27:39 +0000 | [diff] [blame] | 1822 | 1, 1, (char *)(ciconinfo + 1)); |
| 1823 | |
| 1824 | GlobalUnlock16(hIcon); |
| 1825 | |
Alexandre Julliard | 491502b | 1997-11-01 19:08:16 +0000 | [diff] [blame] | 1826 | return TRUE; |
| 1827 | } |
| 1828 | |
| 1829 | /********************************************************************** |
Patrik Stridvall | 2ece70e | 2000-12-22 01:38:01 +0000 | [diff] [blame] | 1830 | * CreateIconIndirect (USER32.@) |
Alexandre Julliard | 491502b | 1997-11-01 19:08:16 +0000 | [diff] [blame] | 1831 | */ |
Francois Gouget | 67c9691 | 2000-10-12 23:18:55 +0000 | [diff] [blame] | 1832 | HICON WINAPI CreateIconIndirect(PICONINFO iconinfo) |
Alexandre Julliard | b0efe28 | 2000-08-04 04:18:04 +0000 | [diff] [blame] | 1833 | { |
| 1834 | BITMAP bmpXor,bmpAnd; |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1835 | HICON hObj; |
Alexandre Julliard | 491502b | 1997-11-01 19:08:16 +0000 | [diff] [blame] | 1836 | int sizeXor,sizeAnd; |
| 1837 | |
Alexandre Julliard | b0efe28 | 2000-08-04 04:18:04 +0000 | [diff] [blame] | 1838 | GetObjectA( iconinfo->hbmColor, sizeof(bmpXor), &bmpXor ); |
| 1839 | GetObjectA( iconinfo->hbmMask, sizeof(bmpAnd), &bmpAnd ); |
Alexandre Julliard | 491502b | 1997-11-01 19:08:16 +0000 | [diff] [blame] | 1840 | |
Alexandre Julliard | b0efe28 | 2000-08-04 04:18:04 +0000 | [diff] [blame] | 1841 | sizeXor = bmpXor.bmHeight * bmpXor.bmWidthBytes; |
| 1842 | sizeAnd = bmpAnd.bmHeight * bmpAnd.bmWidthBytes; |
Alexandre Julliard | 491502b | 1997-11-01 19:08:16 +0000 | [diff] [blame] | 1843 | |
| 1844 | hObj = GlobalAlloc16( GMEM_MOVEABLE, |
| 1845 | sizeof(CURSORICONINFO) + sizeXor + sizeAnd ); |
| 1846 | if (hObj) |
| 1847 | { |
| 1848 | CURSORICONINFO *info; |
| 1849 | |
| 1850 | info = (CURSORICONINFO *)GlobalLock16( hObj ); |
Francis Beaudet | 699900b | 1999-09-05 12:15:49 +0000 | [diff] [blame] | 1851 | |
| 1852 | /* If we are creating an icon, the hotspot is unused */ |
| 1853 | if (iconinfo->fIcon) |
| 1854 | { |
| 1855 | info->ptHotSpot.x = ICON_HOTSPOT; |
| 1856 | info->ptHotSpot.y = ICON_HOTSPOT; |
| 1857 | } |
| 1858 | else |
| 1859 | { |
| 1860 | info->ptHotSpot.x = iconinfo->xHotspot; |
| 1861 | info->ptHotSpot.y = iconinfo->yHotspot; |
| 1862 | } |
| 1863 | |
Alexandre Julliard | b0efe28 | 2000-08-04 04:18:04 +0000 | [diff] [blame] | 1864 | info->nWidth = bmpXor.bmWidth; |
| 1865 | info->nHeight = bmpXor.bmHeight; |
| 1866 | info->nWidthBytes = bmpXor.bmWidthBytes; |
| 1867 | info->bPlanes = bmpXor.bmPlanes; |
| 1868 | info->bBitsPerPixel = bmpXor.bmBitsPixel; |
Alexandre Julliard | 491502b | 1997-11-01 19:08:16 +0000 | [diff] [blame] | 1869 | |
| 1870 | /* Transfer the bitmap bits to the CURSORICONINFO structure */ |
| 1871 | |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1872 | GetBitmapBits( iconinfo->hbmMask ,sizeAnd,(char*)(info + 1) ); |
| 1873 | GetBitmapBits( iconinfo->hbmColor,sizeXor,(char*)(info + 1) +sizeAnd); |
Alexandre Julliard | 491502b | 1997-11-01 19:08:16 +0000 | [diff] [blame] | 1874 | GlobalUnlock16( hObj ); |
| 1875 | } |
| 1876 | return hObj; |
| 1877 | } |
Alexandre Julliard | a0b2b1d | 1997-11-16 17:38:29 +0000 | [diff] [blame] | 1878 | |
Alexandre Julliard | 46ea8b3 | 1998-05-03 19:01:20 +0000 | [diff] [blame] | 1879 | |
Alexandre Julliard | a0b2b1d | 1997-11-16 17:38:29 +0000 | [diff] [blame] | 1880 | /********************************************************************** |
Patrik Stridvall | 2ece70e | 2000-12-22 01:38:01 +0000 | [diff] [blame] | 1881 | * DrawIconEx (USER.394) |
Alexandre Julliard | a0b2b1d | 1997-11-16 17:38:29 +0000 | [diff] [blame] | 1882 | */ |
Alexandre Julliard | a0b2b1d | 1997-11-16 17:38:29 +0000 | [diff] [blame] | 1883 | BOOL16 WINAPI DrawIconEx16 (HDC16 hdc, INT16 xLeft, INT16 yTop, HICON16 hIcon, |
| 1884 | INT16 cxWidth, INT16 cyWidth, UINT16 istep, |
| 1885 | HBRUSH16 hbr, UINT16 flags) |
| 1886 | { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1887 | return DrawIconEx(hdc, xLeft, yTop, hIcon, cxWidth, cyWidth, |
Alexandre Julliard | 46ea8b3 | 1998-05-03 19:01:20 +0000 | [diff] [blame] | 1888 | istep, hbr, flags); |
Alexandre Julliard | a0b2b1d | 1997-11-16 17:38:29 +0000 | [diff] [blame] | 1889 | } |
| 1890 | |
Alexandre Julliard | a0b2b1d | 1997-11-16 17:38:29 +0000 | [diff] [blame] | 1891 | |
Alexandre Julliard | 46ea8b3 | 1998-05-03 19:01:20 +0000 | [diff] [blame] | 1892 | /****************************************************************************** |
Patrik Stridvall | 2ece70e | 2000-12-22 01:38:01 +0000 | [diff] [blame] | 1893 | * DrawIconEx (USER32.@) Draws an icon or cursor on device context |
Alexandre Julliard | 46ea8b3 | 1998-05-03 19:01:20 +0000 | [diff] [blame] | 1894 | * |
| 1895 | * NOTES |
| 1896 | * Why is this using SM_CXICON instead of SM_CXCURSOR? |
| 1897 | * |
| 1898 | * PARAMS |
| 1899 | * hdc [I] Handle to device context |
| 1900 | * x0 [I] X coordinate of upper left corner |
| 1901 | * y0 [I] Y coordinate of upper left corner |
| 1902 | * hIcon [I] Handle to icon to draw |
| 1903 | * cxWidth [I] Width of icon |
| 1904 | * cyWidth [I] Height of icon |
| 1905 | * istep [I] Index of frame in animated cursor |
| 1906 | * hbr [I] Handle to background brush |
| 1907 | * flags [I] Icon-drawing flags |
| 1908 | * |
| 1909 | * RETURNS |
| 1910 | * Success: TRUE |
| 1911 | * Failure: FALSE |
| 1912 | */ |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1913 | BOOL WINAPI DrawIconEx( HDC hdc, INT x0, INT y0, HICON hIcon, |
| 1914 | INT cxWidth, INT cyWidth, UINT istep, |
| 1915 | HBRUSH hbr, UINT flags ) |
Alexandre Julliard | a0b2b1d | 1997-11-16 17:38:29 +0000 | [diff] [blame] | 1916 | { |
| 1917 | CURSORICONINFO *ptr = (CURSORICONINFO *)GlobalLock16 (hIcon); |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1918 | HDC hDC_off = 0, hMemDC = CreateCompatibleDC (hdc); |
Alexandre Julliard | 2a2321b | 2000-08-19 21:38:55 +0000 | [diff] [blame] | 1919 | BOOL result = FALSE, DoOffscreen; |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1920 | HBITMAP hB_off = 0, hOld = 0; |
Turchanov Sergey | 62d6e98 | 1998-10-18 13:42:55 +0000 | [diff] [blame] | 1921 | |
| 1922 | if (!ptr) return FALSE; |
Marcus Meissner | 9199f4a | 2000-11-01 21:36:35 +0000 | [diff] [blame] | 1923 | TRACE_(icon)("(hdc=%x,pos=%d.%d,hicon=%x,extend=%d.%d,istep=%d,br=%x,flags=0x%08x)\n", |
| 1924 | hdc,x0,y0,hIcon,cxWidth,cyWidth,istep,hbr,flags |
| 1925 | ); |
Alexandre Julliard | a0b2b1d | 1997-11-16 17:38:29 +0000 | [diff] [blame] | 1926 | |
Alexandre Julliard | 46ea8b3 | 1998-05-03 19:01:20 +0000 | [diff] [blame] | 1927 | if (istep) |
Alexandre Julliard | 06c275a | 1999-05-02 14:32:27 +0000 | [diff] [blame] | 1928 | FIXME_(icon)("Ignoring istep=%d\n", istep); |
Alexandre Julliard | 46ea8b3 | 1998-05-03 19:01:20 +0000 | [diff] [blame] | 1929 | if (flags & DI_COMPAT) |
Alexandre Julliard | 06c275a | 1999-05-02 14:32:27 +0000 | [diff] [blame] | 1930 | FIXME_(icon)("Ignoring flag DI_COMPAT\n"); |
Alexandre Julliard | a0b2b1d | 1997-11-16 17:38:29 +0000 | [diff] [blame] | 1931 | |
Marcus Meissner | 9199f4a | 2000-11-01 21:36:35 +0000 | [diff] [blame] | 1932 | if (!flags) { |
| 1933 | FIXME_(icon)("no flags set? setting to DI_NORMAL\n"); |
| 1934 | flags = DI_NORMAL; |
| 1935 | } |
| 1936 | |
Turchanov Sergey | 62d6e98 | 1998-10-18 13:42:55 +0000 | [diff] [blame] | 1937 | /* Calculate the size of the destination image. */ |
| 1938 | if (cxWidth == 0) |
Jesper Skov | 5c3e457 | 1998-11-01 19:27:22 +0000 | [diff] [blame] | 1939 | { |
Turchanov Sergey | 62d6e98 | 1998-10-18 13:42:55 +0000 | [diff] [blame] | 1940 | if (flags & DI_DEFAULTSIZE) |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1941 | cxWidth = GetSystemMetrics (SM_CXICON); |
Turchanov Sergey | 62d6e98 | 1998-10-18 13:42:55 +0000 | [diff] [blame] | 1942 | else |
| 1943 | cxWidth = ptr->nWidth; |
Jesper Skov | 5c3e457 | 1998-11-01 19:27:22 +0000 | [diff] [blame] | 1944 | } |
Turchanov Sergey | 62d6e98 | 1998-10-18 13:42:55 +0000 | [diff] [blame] | 1945 | if (cyWidth == 0) |
Jesper Skov | 5c3e457 | 1998-11-01 19:27:22 +0000 | [diff] [blame] | 1946 | { |
Turchanov Sergey | 62d6e98 | 1998-10-18 13:42:55 +0000 | [diff] [blame] | 1947 | if (flags & DI_DEFAULTSIZE) |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1948 | cyWidth = GetSystemMetrics (SM_CYICON); |
Turchanov Sergey | 62d6e98 | 1998-10-18 13:42:55 +0000 | [diff] [blame] | 1949 | else |
| 1950 | cyWidth = ptr->nHeight; |
Jesper Skov | 5c3e457 | 1998-11-01 19:27:22 +0000 | [diff] [blame] | 1951 | } |
Turchanov Sergey | 62d6e98 | 1998-10-18 13:42:55 +0000 | [diff] [blame] | 1952 | |
Alexandre Julliard | 2a2321b | 2000-08-19 21:38:55 +0000 | [diff] [blame] | 1953 | DoOffscreen = (GetObjectType( hbr ) == OBJ_BRUSH); |
| 1954 | |
Turchanov Sergey | 62d6e98 | 1998-10-18 13:42:55 +0000 | [diff] [blame] | 1955 | if (DoOffscreen) { |
Patrik Stridvall | a9a671d | 1999-04-25 19:01:52 +0000 | [diff] [blame] | 1956 | RECT r; |
| 1957 | |
| 1958 | r.left = 0; |
| 1959 | r.top = 0; |
| 1960 | r.right = cxWidth; |
| 1961 | r.bottom = cxWidth; |
Turchanov Sergey | 62d6e98 | 1998-10-18 13:42:55 +0000 | [diff] [blame] | 1962 | |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1963 | hDC_off = CreateCompatibleDC(hdc); |
| 1964 | hB_off = CreateCompatibleBitmap(hdc, cxWidth, cyWidth); |
Turchanov Sergey | 62d6e98 | 1998-10-18 13:42:55 +0000 | [diff] [blame] | 1965 | if (hDC_off && hB_off) { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1966 | hOld = SelectObject(hDC_off, hB_off); |
| 1967 | FillRect(hDC_off, &r, hbr); |
Turchanov Sergey | 62d6e98 | 1998-10-18 13:42:55 +0000 | [diff] [blame] | 1968 | } |
Alexandre Julliard | 2a2321b | 2000-08-19 21:38:55 +0000 | [diff] [blame] | 1969 | } |
Turchanov Sergey | 62d6e98 | 1998-10-18 13:42:55 +0000 | [diff] [blame] | 1970 | |
| 1971 | if (hMemDC && (!DoOffscreen || (hDC_off && hB_off))) |
Alexandre Julliard | a0b2b1d | 1997-11-16 17:38:29 +0000 | [diff] [blame] | 1972 | { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1973 | HBITMAP hXorBits, hAndBits; |
Alexandre Julliard | ebfc0fe | 1998-06-28 18:40:26 +0000 | [diff] [blame] | 1974 | COLORREF oldFg, oldBg; |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1975 | INT nStretchMode; |
Alexandre Julliard | a0b2b1d | 1997-11-16 17:38:29 +0000 | [diff] [blame] | 1976 | |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1977 | nStretchMode = SetStretchBltMode (hdc, STRETCH_DELETESCANS); |
Alexandre Julliard | ebfc0fe | 1998-06-28 18:40:26 +0000 | [diff] [blame] | 1978 | |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1979 | hXorBits = CreateBitmap ( ptr->nWidth, ptr->nHeight, |
Alexandre Julliard | a0b2b1d | 1997-11-16 17:38:29 +0000 | [diff] [blame] | 1980 | ptr->bPlanes, ptr->bBitsPerPixel, |
| 1981 | (char *)(ptr + 1) |
| 1982 | + ptr->nHeight * |
Huw D M Davies | 8261736 | 1998-11-01 16:35:42 +0000 | [diff] [blame] | 1983 | BITMAP_GetWidthBytes(ptr->nWidth,1) ); |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1984 | hAndBits = CreateBitmap ( ptr->nWidth, ptr->nHeight, |
Alexandre Julliard | a0b2b1d | 1997-11-16 17:38:29 +0000 | [diff] [blame] | 1985 | 1, 1, (char *)(ptr+1) ); |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1986 | oldFg = SetTextColor( hdc, RGB(0,0,0) ); |
| 1987 | oldBg = SetBkColor( hdc, RGB(255,255,255) ); |
Alexandre Julliard | a0b2b1d | 1997-11-16 17:38:29 +0000 | [diff] [blame] | 1988 | |
| 1989 | if (hXorBits && hAndBits) |
| 1990 | { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1991 | HBITMAP hBitTemp = SelectObject( hMemDC, hAndBits ); |
Alexandre Julliard | a0b2b1d | 1997-11-16 17:38:29 +0000 | [diff] [blame] | 1992 | if (flags & DI_MASK) |
Jesper Skov | 5c3e457 | 1998-11-01 19:27:22 +0000 | [diff] [blame] | 1993 | { |
Turchanov Sergey | 62d6e98 | 1998-10-18 13:42:55 +0000 | [diff] [blame] | 1994 | if (DoOffscreen) |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1995 | StretchBlt (hDC_off, 0, 0, cxWidth, cyWidth, |
Turchanov Sergey | 62d6e98 | 1998-10-18 13:42:55 +0000 | [diff] [blame] | 1996 | hMemDC, 0, 0, ptr->nWidth, ptr->nHeight, SRCAND); |
| 1997 | else |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 1998 | StretchBlt (hdc, x0, y0, cxWidth, cyWidth, |
Alexandre Julliard | ebfc0fe | 1998-06-28 18:40:26 +0000 | [diff] [blame] | 1999 | hMemDC, 0, 0, ptr->nWidth, ptr->nHeight, SRCAND); |
Jesper Skov | 5c3e457 | 1998-11-01 19:27:22 +0000 | [diff] [blame] | 2000 | } |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 2001 | SelectObject( hMemDC, hXorBits ); |
Alexandre Julliard | a0b2b1d | 1997-11-16 17:38:29 +0000 | [diff] [blame] | 2002 | if (flags & DI_IMAGE) |
Jesper Skov | 5c3e457 | 1998-11-01 19:27:22 +0000 | [diff] [blame] | 2003 | { |
Turchanov Sergey | 62d6e98 | 1998-10-18 13:42:55 +0000 | [diff] [blame] | 2004 | if (DoOffscreen) |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 2005 | StretchBlt (hDC_off, 0, 0, cxWidth, cyWidth, |
Turchanov Sergey | 62d6e98 | 1998-10-18 13:42:55 +0000 | [diff] [blame] | 2006 | hMemDC, 0, 0, ptr->nWidth, ptr->nHeight, SRCPAINT); |
| 2007 | else |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 2008 | StretchBlt (hdc, x0, y0, cxWidth, cyWidth, |
Eric Kohl | 1b1bf2b | 1998-10-11 13:10:08 +0000 | [diff] [blame] | 2009 | hMemDC, 0, 0, ptr->nWidth, ptr->nHeight, SRCPAINT); |
Jesper Skov | 5c3e457 | 1998-11-01 19:27:22 +0000 | [diff] [blame] | 2010 | } |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 2011 | SelectObject( hMemDC, hBitTemp ); |
Alexandre Julliard | a0b2b1d | 1997-11-16 17:38:29 +0000 | [diff] [blame] | 2012 | result = TRUE; |
| 2013 | } |
| 2014 | |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 2015 | SetTextColor( hdc, oldFg ); |
| 2016 | SetBkColor( hdc, oldBg ); |
| 2017 | if (hXorBits) DeleteObject( hXorBits ); |
| 2018 | if (hAndBits) DeleteObject( hAndBits ); |
| 2019 | SetStretchBltMode (hdc, nStretchMode); |
Turchanov Sergey | 62d6e98 | 1998-10-18 13:42:55 +0000 | [diff] [blame] | 2020 | if (DoOffscreen) { |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 2021 | BitBlt(hdc, x0, y0, cxWidth, cyWidth, hDC_off, 0, 0, SRCCOPY); |
| 2022 | SelectObject(hDC_off, hOld); |
Turchanov Sergey | 62d6e98 | 1998-10-18 13:42:55 +0000 | [diff] [blame] | 2023 | } |
Alexandre Julliard | a0b2b1d | 1997-11-16 17:38:29 +0000 | [diff] [blame] | 2024 | } |
Alexandre Julliard | a396029 | 1999-02-26 11:11:13 +0000 | [diff] [blame] | 2025 | if (hMemDC) DeleteDC( hMemDC ); |
| 2026 | if (hDC_off) DeleteDC(hDC_off); |
| 2027 | if (hB_off) DeleteObject(hB_off); |
Alexandre Julliard | a0b2b1d | 1997-11-16 17:38:29 +0000 | [diff] [blame] | 2028 | GlobalUnlock16( hIcon ); |
| 2029 | return result; |
| 2030 | } |
Alexandre Julliard | b52aed4 | 2000-03-24 21:40:30 +0000 | [diff] [blame] | 2031 | |
Alexandre Julliard | a660c79 | 2000-06-03 20:45:20 +0000 | [diff] [blame] | 2032 | /*********************************************************************** |
| 2033 | * DIB_FixColorsToLoadflags |
| 2034 | * |
| 2035 | * Change color table entries when LR_LOADTRANSPARENT or LR_LOADMAP3DCOLORS |
| 2036 | * are in loadflags |
| 2037 | */ |
| 2038 | static void DIB_FixColorsToLoadflags(BITMAPINFO * bmi, UINT loadflags, BYTE pix) |
| 2039 | { |
| 2040 | int colors; |
| 2041 | COLORREF c_W, c_S, c_F, c_L, c_C; |
| 2042 | int incr,i; |
| 2043 | RGBQUAD *ptr; |
| 2044 | |
| 2045 | if (bmi->bmiHeader.biBitCount > 8) return; |
| 2046 | if (bmi->bmiHeader.biSize == sizeof(BITMAPINFOHEADER)) incr = 4; |
| 2047 | else if (bmi->bmiHeader.biSize == sizeof(BITMAPCOREHEADER)) incr = 3; |
| 2048 | else { |
| 2049 | WARN_(resource)("Wrong bitmap header size!\n"); |
| 2050 | return; |
| 2051 | } |
| 2052 | colors = bmi->bmiHeader.biClrUsed; |
| 2053 | if (!colors && (bmi->bmiHeader.biBitCount <= 8)) |
| 2054 | colors = 1 << bmi->bmiHeader.biBitCount; |
| 2055 | c_W = GetSysColor(COLOR_WINDOW); |
| 2056 | c_S = GetSysColor(COLOR_3DSHADOW); |
| 2057 | c_F = GetSysColor(COLOR_3DFACE); |
| 2058 | c_L = GetSysColor(COLOR_3DLIGHT); |
| 2059 | if (loadflags & LR_LOADTRANSPARENT) { |
| 2060 | switch (bmi->bmiHeader.biBitCount) { |
| 2061 | case 1: pix = pix >> 7; break; |
| 2062 | case 4: pix = pix >> 4; break; |
| 2063 | case 8: break; |
| 2064 | default: |
| 2065 | WARN_(resource)("(%d): Unsupported depth\n", bmi->bmiHeader.biBitCount); |
| 2066 | return; |
| 2067 | } |
| 2068 | if (pix >= colors) { |
| 2069 | WARN_(resource)("pixel has color index greater than biClrUsed!\n"); |
| 2070 | return; |
| 2071 | } |
| 2072 | if (loadflags & LR_LOADMAP3DCOLORS) c_W = c_F; |
| 2073 | ptr = (RGBQUAD*)((char*)bmi->bmiColors+pix*incr); |
| 2074 | ptr->rgbBlue = GetBValue(c_W); |
| 2075 | ptr->rgbGreen = GetGValue(c_W); |
| 2076 | ptr->rgbRed = GetRValue(c_W); |
| 2077 | } |
| 2078 | if (loadflags & LR_LOADMAP3DCOLORS) |
| 2079 | for (i=0; i<colors; i++) { |
| 2080 | ptr = (RGBQUAD*)((char*)bmi->bmiColors+i*incr); |
| 2081 | c_C = RGB(ptr->rgbRed, ptr->rgbGreen, ptr->rgbBlue); |
| 2082 | if (c_C == RGB(128, 128, 128)) { |
| 2083 | ptr->rgbRed = GetRValue(c_S); |
| 2084 | ptr->rgbGreen = GetGValue(c_S); |
| 2085 | ptr->rgbBlue = GetBValue(c_S); |
| 2086 | } else if (c_C == RGB(192, 192, 192)) { |
| 2087 | ptr->rgbRed = GetRValue(c_F); |
| 2088 | ptr->rgbGreen = GetGValue(c_F); |
| 2089 | ptr->rgbBlue = GetBValue(c_F); |
| 2090 | } else if (c_C == RGB(223, 223, 223)) { |
| 2091 | ptr->rgbRed = GetRValue(c_L); |
| 2092 | ptr->rgbGreen = GetGValue(c_L); |
| 2093 | ptr->rgbBlue = GetBValue(c_L); |
| 2094 | } |
| 2095 | } |
| 2096 | } |
| 2097 | |
| 2098 | |
Alexandre Julliard | b52aed4 | 2000-03-24 21:40:30 +0000 | [diff] [blame] | 2099 | /********************************************************************** |
| 2100 | * BITMAP_Load |
| 2101 | */ |
| 2102 | static HBITMAP BITMAP_Load( HINSTANCE instance,LPCWSTR name, UINT loadflags ) |
| 2103 | { |
| 2104 | HBITMAP hbitmap = 0; |
Alexandre Julliard | b52aed4 | 2000-03-24 21:40:30 +0000 | [diff] [blame] | 2105 | HRSRC hRsrc; |
| 2106 | HGLOBAL handle; |
| 2107 | char *ptr = NULL; |
| 2108 | BITMAPINFO *info, *fix_info=NULL; |
| 2109 | HGLOBAL hFix; |
| 2110 | int size; |
| 2111 | |
| 2112 | if (!(loadflags & LR_LOADFROMFILE)) { |
| 2113 | if (!instance) /* OEM bitmap */ |
| 2114 | { |
Alexandre Julliard | b52aed4 | 2000-03-24 21:40:30 +0000 | [diff] [blame] | 2115 | if (HIWORD((int)name)) return 0; |
Alexandre Julliard | 42d20f9 | 2000-08-10 01:16:19 +0000 | [diff] [blame] | 2116 | return USER_Driver.pLoadOEMResource( LOWORD((int)name), OEM_BITMAP ); |
Alexandre Julliard | b52aed4 | 2000-03-24 21:40:30 +0000 | [diff] [blame] | 2117 | } |
| 2118 | |
| 2119 | if (!(hRsrc = FindResourceW( instance, name, RT_BITMAPW ))) return 0; |
| 2120 | if (!(handle = LoadResource( instance, hRsrc ))) return 0; |
| 2121 | |
| 2122 | if ((info = (BITMAPINFO *)LockResource( handle )) == NULL) return 0; |
| 2123 | } |
| 2124 | else |
| 2125 | { |
Alexandre Julliard | 982a223 | 2000-12-13 20:20:09 +0000 | [diff] [blame] | 2126 | if (!(ptr = map_fileW( name ))) return 0; |
Alexandre Julliard | b52aed4 | 2000-03-24 21:40:30 +0000 | [diff] [blame] | 2127 | info = (BITMAPINFO *)(ptr + sizeof(BITMAPFILEHEADER)); |
| 2128 | } |
| 2129 | size = DIB_BitmapInfoSize(info, DIB_RGB_COLORS); |
| 2130 | if ((hFix = GlobalAlloc(0, size))) fix_info=GlobalLock(hFix); |
| 2131 | if (fix_info) { |
| 2132 | BYTE pix; |
| 2133 | |
| 2134 | memcpy(fix_info, info, size); |
| 2135 | pix = *((LPBYTE)info+DIB_BitmapInfoSize(info, DIB_RGB_COLORS)); |
| 2136 | DIB_FixColorsToLoadflags(fix_info, loadflags, pix); |
Alexandre Julliard | 16cbf40 | 2001-01-18 20:32:01 +0000 | [diff] [blame] | 2137 | if (!screen_dc) screen_dc = CreateDCA( "DISPLAY", NULL, NULL, NULL ); |
| 2138 | if (screen_dc) |
| 2139 | { |
Alexandre Julliard | b52aed4 | 2000-03-24 21:40:30 +0000 | [diff] [blame] | 2140 | char *bits = (char *)info + size; |
| 2141 | if (loadflags & LR_CREATEDIBSECTION) { |
| 2142 | DIBSECTION dib; |
Alexandre Julliard | 16cbf40 | 2001-01-18 20:32:01 +0000 | [diff] [blame] | 2143 | hbitmap = CreateDIBSection(screen_dc, fix_info, DIB_RGB_COLORS, NULL, 0, 0); |
Alexandre Julliard | b52aed4 | 2000-03-24 21:40:30 +0000 | [diff] [blame] | 2144 | GetObjectA(hbitmap, sizeof(DIBSECTION), &dib); |
Alexandre Julliard | 16cbf40 | 2001-01-18 20:32:01 +0000 | [diff] [blame] | 2145 | SetDIBits(screen_dc, hbitmap, 0, dib.dsBm.bmHeight, bits, info, |
Alexandre Julliard | b52aed4 | 2000-03-24 21:40:30 +0000 | [diff] [blame] | 2146 | DIB_RGB_COLORS); |
| 2147 | } |
| 2148 | else { |
Alexandre Julliard | 16cbf40 | 2001-01-18 20:32:01 +0000 | [diff] [blame] | 2149 | hbitmap = CreateDIBitmap( screen_dc, &fix_info->bmiHeader, CBM_INIT, |
Alexandre Julliard | b52aed4 | 2000-03-24 21:40:30 +0000 | [diff] [blame] | 2150 | bits, fix_info, DIB_RGB_COLORS ); |
| 2151 | } |
Alexandre Julliard | b52aed4 | 2000-03-24 21:40:30 +0000 | [diff] [blame] | 2152 | } |
| 2153 | GlobalUnlock(hFix); |
| 2154 | GlobalFree(hFix); |
| 2155 | } |
| 2156 | if (loadflags & LR_LOADFROMFILE) UnmapViewOfFile( ptr ); |
| 2157 | return hbitmap; |
| 2158 | } |
| 2159 | |
| 2160 | |
| 2161 | /*********************************************************************** |
Patrik Stridvall | 0c61028 | 2001-01-25 22:22:21 +0000 | [diff] [blame] | 2162 | * LoadImage (USER.389) |
Alexandre Julliard | b52aed4 | 2000-03-24 21:40:30 +0000 | [diff] [blame] | 2163 | * |
| 2164 | */ |
| 2165 | HANDLE16 WINAPI LoadImage16( HINSTANCE16 hinst, LPCSTR name, UINT16 type, |
| 2166 | INT16 desiredx, INT16 desiredy, UINT16 loadflags) |
| 2167 | { |
Alexandre Julliard | a67369e | 2000-12-12 00:48:06 +0000 | [diff] [blame] | 2168 | return LoadImageA( hinst, name, type, desiredx, desiredy, loadflags ); |
Alexandre Julliard | b52aed4 | 2000-03-24 21:40:30 +0000 | [diff] [blame] | 2169 | } |
| 2170 | |
| 2171 | /********************************************************************** |
Patrik Stridvall | 2ece70e | 2000-12-22 01:38:01 +0000 | [diff] [blame] | 2172 | * LoadImageA (USER32.@) |
Alexandre Julliard | b52aed4 | 2000-03-24 21:40:30 +0000 | [diff] [blame] | 2173 | * |
| 2174 | * FIXME: implementation lacks some features, see LR_ defines in windows.h |
| 2175 | */ |
| 2176 | |
| 2177 | HANDLE WINAPI LoadImageA( HINSTANCE hinst, LPCSTR name, UINT type, |
| 2178 | INT desiredx, INT desiredy, UINT loadflags) |
| 2179 | { |
| 2180 | HANDLE res; |
| 2181 | LPWSTR u_name; |
| 2182 | |
| 2183 | if (HIWORD(name)) u_name = HEAP_strdupAtoW(GetProcessHeap(), 0, name); |
| 2184 | else u_name=(LPWSTR)name; |
| 2185 | res = LoadImageW(hinst, u_name, type, desiredx, desiredy, loadflags); |
| 2186 | if (HIWORD(name)) HeapFree(GetProcessHeap(), 0, u_name); |
| 2187 | return res; |
| 2188 | } |
| 2189 | |
| 2190 | |
| 2191 | /****************************************************************************** |
Patrik Stridvall | 2ece70e | 2000-12-22 01:38:01 +0000 | [diff] [blame] | 2192 | * LoadImageW (USER32.@) Loads an icon, cursor, or bitmap |
Alexandre Julliard | b52aed4 | 2000-03-24 21:40:30 +0000 | [diff] [blame] | 2193 | * |
| 2194 | * PARAMS |
| 2195 | * hinst [I] Handle of instance that contains image |
| 2196 | * name [I] Name of image |
| 2197 | * type [I] Type of image |
| 2198 | * desiredx [I] Desired width |
| 2199 | * desiredy [I] Desired height |
| 2200 | * loadflags [I] Load flags |
| 2201 | * |
| 2202 | * RETURNS |
| 2203 | * Success: Handle to newly loaded image |
| 2204 | * Failure: NULL |
| 2205 | * |
| 2206 | * FIXME: Implementation lacks some features, see LR_ defines in windows.h |
| 2207 | */ |
| 2208 | HANDLE WINAPI LoadImageW( HINSTANCE hinst, LPCWSTR name, UINT type, |
| 2209 | INT desiredx, INT desiredy, UINT loadflags ) |
| 2210 | { |
| 2211 | if (HIWORD(name)) { |
| 2212 | TRACE_(resource)("(0x%04x,%p,%d,%d,%d,0x%08x)\n", |
| 2213 | hinst,name,type,desiredx,desiredy,loadflags); |
| 2214 | } else { |
| 2215 | TRACE_(resource)("(0x%04x,%p,%d,%d,%d,0x%08x)\n", |
| 2216 | hinst,name,type,desiredx,desiredy,loadflags); |
| 2217 | } |
| 2218 | if (loadflags & LR_DEFAULTSIZE) { |
| 2219 | if (type == IMAGE_ICON) { |
| 2220 | if (!desiredx) desiredx = GetSystemMetrics(SM_CXICON); |
| 2221 | if (!desiredy) desiredy = GetSystemMetrics(SM_CYICON); |
| 2222 | } else if (type == IMAGE_CURSOR) { |
| 2223 | if (!desiredx) desiredx = GetSystemMetrics(SM_CXCURSOR); |
| 2224 | if (!desiredy) desiredy = GetSystemMetrics(SM_CYCURSOR); |
| 2225 | } |
| 2226 | } |
| 2227 | if (loadflags & LR_LOADFROMFILE) loadflags &= ~LR_SHARED; |
| 2228 | switch (type) { |
| 2229 | case IMAGE_BITMAP: |
| 2230 | return BITMAP_Load( hinst, name, loadflags ); |
| 2231 | |
| 2232 | case IMAGE_ICON: |
Alexandre Julliard | 16cbf40 | 2001-01-18 20:32:01 +0000 | [diff] [blame] | 2233 | if (!screen_dc) screen_dc = CreateDCA( "DISPLAY", NULL, NULL, NULL ); |
| 2234 | if (screen_dc) |
Alexandre Julliard | b52aed4 | 2000-03-24 21:40:30 +0000 | [diff] [blame] | 2235 | { |
Alexandre Julliard | 16cbf40 | 2001-01-18 20:32:01 +0000 | [diff] [blame] | 2236 | UINT palEnts = GetSystemPaletteEntries(screen_dc, 0, 0, NULL); |
| 2237 | if (palEnts == 0) palEnts = 256; |
| 2238 | return CURSORICON_Load(hinst, name, desiredx, desiredy, |
| 2239 | palEnts, FALSE, loadflags); |
| 2240 | } |
| 2241 | break; |
Alexandre Julliard | b52aed4 | 2000-03-24 21:40:30 +0000 | [diff] [blame] | 2242 | |
| 2243 | case IMAGE_CURSOR: |
| 2244 | return CURSORICON_Load(hinst, name, desiredx, desiredy, |
| 2245 | 1, TRUE, loadflags); |
| 2246 | } |
| 2247 | return 0; |
| 2248 | } |
| 2249 | |
| 2250 | |
| 2251 | /****************************************************************************** |
Patrik Stridvall | 2ece70e | 2000-12-22 01:38:01 +0000 | [diff] [blame] | 2252 | * CopyImage (USER.390) Creates new image and copies attributes to it |
Alexandre Julliard | b52aed4 | 2000-03-24 21:40:30 +0000 | [diff] [blame] | 2253 | * |
| 2254 | */ |
| 2255 | HICON16 WINAPI CopyImage16( HANDLE16 hnd, UINT16 type, INT16 desiredx, |
| 2256 | INT16 desiredy, UINT16 flags ) |
| 2257 | { |
| 2258 | return (HICON16)CopyImage((HANDLE)hnd, (UINT)type, (INT)desiredx, |
| 2259 | (INT)desiredy, (UINT)flags); |
| 2260 | } |
| 2261 | |
| 2262 | /****************************************************************************** |
Patrik Stridvall | 2ece70e | 2000-12-22 01:38:01 +0000 | [diff] [blame] | 2263 | * CopyImage (USER32.@) Creates new image and copies attributes to it |
Alexandre Julliard | b52aed4 | 2000-03-24 21:40:30 +0000 | [diff] [blame] | 2264 | * |
| 2265 | * PARAMS |
| 2266 | * hnd [I] Handle to image to copy |
| 2267 | * type [I] Type of image to copy |
| 2268 | * desiredx [I] Desired width of new image |
| 2269 | * desiredy [I] Desired height of new image |
| 2270 | * flags [I] Copy flags |
| 2271 | * |
| 2272 | * RETURNS |
| 2273 | * Success: Handle to newly created image |
| 2274 | * Failure: NULL |
| 2275 | * |
| 2276 | * FIXME: implementation still lacks nearly all features, see LR_* |
| 2277 | * defines in windows.h |
| 2278 | */ |
| 2279 | HICON WINAPI CopyImage( HANDLE hnd, UINT type, INT desiredx, |
| 2280 | INT desiredy, UINT flags ) |
| 2281 | { |
| 2282 | switch (type) |
| 2283 | { |
| 2284 | case IMAGE_BITMAP: |
| 2285 | return BITMAP_CopyBitmap(hnd); |
| 2286 | case IMAGE_ICON: |
| 2287 | return CURSORICON_ExtCopy(hnd,type, desiredx, desiredy, flags); |
| 2288 | case IMAGE_CURSOR: |
| 2289 | /* Should call CURSORICON_ExtCopy but more testing |
| 2290 | * needs to be done before we change this |
| 2291 | */ |
| 2292 | return CopyCursor(hnd); |
| 2293 | } |
| 2294 | return 0; |
| 2295 | } |
| 2296 | |
| 2297 | |
| 2298 | /****************************************************************************** |
Patrik Stridvall | 2ece70e | 2000-12-22 01:38:01 +0000 | [diff] [blame] | 2299 | * LoadBitmapW (USER32.@) Loads bitmap from the executable file |
Alexandre Julliard | b52aed4 | 2000-03-24 21:40:30 +0000 | [diff] [blame] | 2300 | * |
| 2301 | * RETURNS |
| 2302 | * Success: Handle to specified bitmap |
| 2303 | * Failure: NULL |
| 2304 | */ |
| 2305 | HBITMAP WINAPI LoadBitmapW( |
| 2306 | HINSTANCE instance, /* [in] Handle to application instance */ |
| 2307 | LPCWSTR name) /* [in] Address of bitmap resource name */ |
| 2308 | { |
| 2309 | return LoadImageW( instance, name, IMAGE_BITMAP, 0, 0, 0 ); |
| 2310 | } |
| 2311 | |
| 2312 | /********************************************************************** |
Patrik Stridvall | 2ece70e | 2000-12-22 01:38:01 +0000 | [diff] [blame] | 2313 | * LoadBitmapA (USER32.@) |
Alexandre Julliard | b52aed4 | 2000-03-24 21:40:30 +0000 | [diff] [blame] | 2314 | */ |
| 2315 | HBITMAP WINAPI LoadBitmapA( HINSTANCE instance, LPCSTR name ) |
| 2316 | { |
| 2317 | return LoadImageA( instance, name, IMAGE_BITMAP, 0, 0, 0 ); |
| 2318 | } |
| 2319 | |
| 2320 | /********************************************************************** |
Patrik Stridvall | 2ece70e | 2000-12-22 01:38:01 +0000 | [diff] [blame] | 2321 | * LoadBitmap (USER.175) |
Alexandre Julliard | b52aed4 | 2000-03-24 21:40:30 +0000 | [diff] [blame] | 2322 | */ |
Alexandre Julliard | ac7efef | 2000-11-27 21:54:01 +0000 | [diff] [blame] | 2323 | HBITMAP16 WINAPI LoadBitmap16( HINSTANCE16 instance, LPCSTR name ) |
Alexandre Julliard | b52aed4 | 2000-03-24 21:40:30 +0000 | [diff] [blame] | 2324 | { |
Alexandre Julliard | ac7efef | 2000-11-27 21:54:01 +0000 | [diff] [blame] | 2325 | return LoadBitmapA( instance, name ); |
Alexandre Julliard | b52aed4 | 2000-03-24 21:40:30 +0000 | [diff] [blame] | 2326 | } |