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