user.exe: Prepend a valid bitmap header when copying a bitmap resource to a file.
[wine.git] / dlls / user.exe16 / user.c
blob7521c54c178e0c93e2d07f96b5e24d16cef45bdb
1 /*
2 * Misc 16-bit USER functions
4 * Copyright 1993, 1996 Alexandre Julliard
5 * Copyright 2002 Patrik Stridvall
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include <stdarg.h>
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <string.h>
27 #define OEMRESOURCE
29 #include "wine/winuser16.h"
30 #include "windef.h"
31 #include "winbase.h"
32 #include "wownt32.h"
33 #include "user_private.h"
34 #include "wine/list.h"
35 #include "wine/debug.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(user);
39 /* handle to handle 16 conversions */
40 #define HANDLE_16(h32) (LOWORD(h32))
41 #define HGDIOBJ_16(h32) (LOWORD(h32))
43 /* handle16 to handle conversions */
44 #define HANDLE_32(h16) ((HANDLE)(ULONG_PTR)(h16))
45 #define HGDIOBJ_32(h16) ((HGDIOBJ)(ULONG_PTR)(h16))
47 #define IS_MENU_STRING_ITEM(flags) \
48 (((flags) & (MF_STRING | MF_BITMAP | MF_OWNERDRAW | MF_SEPARATOR)) == MF_STRING)
50 /* UserSeeUserDo parameters */
51 #define USUD_LOCALALLOC 0x0001
52 #define USUD_LOCALFREE 0x0002
53 #define USUD_LOCALCOMPACT 0x0003
54 #define USUD_LOCALHEAP 0x0004
55 #define USUD_FIRSTCLASS 0x0005
57 #define CID_RESOURCE 0x0001
58 #define CID_WIN32 0x0004
59 #define CID_NONSHARED 0x0008
61 WORD USER_HeapSel = 0; /* USER heap selector */
63 struct gray_string_info
65 GRAYSTRINGPROC16 proc;
66 LPARAM param;
67 char str[1];
70 /* callback for 16-bit gray string proc with opaque pointer */
71 static BOOL CALLBACK gray_string_callback( HDC hdc, LPARAM param, INT len )
73 const struct gray_string_info *info = (struct gray_string_info *)param;
74 WORD args[4];
75 DWORD ret;
77 args[3] = HDC_16(hdc);
78 args[2] = HIWORD(info->param);
79 args[1] = LOWORD(info->param);
80 args[0] = len;
81 WOWCallback16Ex( (DWORD)info->proc, WCB16_PASCAL, sizeof(args), args, &ret );
82 return LOWORD(ret);
85 /* callback for 16-bit gray string proc with string pointer */
86 static BOOL CALLBACK gray_string_callback_ptr( HDC hdc, LPARAM param, INT len )
88 const struct gray_string_info *info;
89 char *str = (char *)param;
91 info = (struct gray_string_info *)(str - offsetof( struct gray_string_info, str ));
92 return gray_string_callback( hdc, (LPARAM)info, len );
95 struct draw_state_info
97 DRAWSTATEPROC16 proc;
98 LPARAM param;
101 /* callback for 16-bit DrawState functions */
102 static BOOL CALLBACK draw_state_callback( HDC hdc, LPARAM lparam, WPARAM wparam, int cx, int cy )
104 const struct draw_state_info *info = (struct draw_state_info *)lparam;
105 WORD args[6];
106 DWORD ret;
108 args[5] = HDC_16(hdc);
109 args[4] = HIWORD(info->param);
110 args[3] = LOWORD(info->param);
111 args[2] = wparam;
112 args[1] = cx;
113 args[0] = cy;
114 WOWCallback16Ex( (DWORD)info->proc, WCB16_PASCAL, sizeof(args), args, &ret );
115 return LOWORD(ret);
118 /* This function is a copy of the one in objects/font.c */
119 static void logfont_32_to_16( const LOGFONTA* font32, LPLOGFONT16 font16 )
121 font16->lfHeight = font32->lfHeight;
122 font16->lfWidth = font32->lfWidth;
123 font16->lfEscapement = font32->lfEscapement;
124 font16->lfOrientation = font32->lfOrientation;
125 font16->lfWeight = font32->lfWeight;
126 font16->lfItalic = font32->lfItalic;
127 font16->lfUnderline = font32->lfUnderline;
128 font16->lfStrikeOut = font32->lfStrikeOut;
129 font16->lfCharSet = font32->lfCharSet;
130 font16->lfOutPrecision = font32->lfOutPrecision;
131 font16->lfClipPrecision = font32->lfClipPrecision;
132 font16->lfQuality = font32->lfQuality;
133 font16->lfPitchAndFamily = font32->lfPitchAndFamily;
134 lstrcpynA( font16->lfFaceName, font32->lfFaceName, LF_FACESIZE );
137 static int get_bitmap_width_bytes( int width, int bpp )
139 switch(bpp)
141 case 1:
142 return 2 * ((width+15) / 16);
143 case 4:
144 return 2 * ((width+3) / 4);
145 case 24:
146 width *= 3;
147 /* fall through */
148 case 8:
149 return width + (width & 1);
150 case 16:
151 case 15:
152 return width * 2;
153 case 32:
154 return width * 4;
155 default:
156 WARN("Unknown depth %d, please report.\n", bpp );
158 return -1;
161 /***********************************************************************
162 * Helper for wsprintf16
165 #define WPRINTF_LEFTALIGN 0x0001 /* Align output on the left ('-' prefix) */
166 #define WPRINTF_PREFIX_HEX 0x0002 /* Prefix hex with 0x ('#' prefix) */
167 #define WPRINTF_ZEROPAD 0x0004 /* Pad with zeros ('0' prefix) */
168 #define WPRINTF_LONG 0x0008 /* Long arg ('l' prefix) */
169 #define WPRINTF_SHORT 0x0010 /* Short arg ('h' prefix) */
170 #define WPRINTF_UPPER_HEX 0x0020 /* Upper-case hex ('X' specifier) */
172 typedef enum
174 WPR_UNKNOWN,
175 WPR_CHAR,
176 WPR_STRING,
177 WPR_SIGNED,
178 WPR_UNSIGNED,
179 WPR_HEXA
180 } WPRINTF_TYPE;
182 typedef struct
184 UINT flags;
185 UINT width;
186 UINT precision;
187 WPRINTF_TYPE type;
188 } WPRINTF_FORMAT;
190 static INT parse_format( LPCSTR format, WPRINTF_FORMAT *res )
192 LPCSTR p = format;
194 res->flags = 0;
195 res->width = 0;
196 res->precision = 0;
197 if (*p == '-') { res->flags |= WPRINTF_LEFTALIGN; p++; }
198 if (*p == '#') { res->flags |= WPRINTF_PREFIX_HEX; p++; }
199 if (*p == '0') { res->flags |= WPRINTF_ZEROPAD; p++; }
200 while ((*p >= '0') && (*p <= '9')) /* width field */
202 res->width = res->width * 10 + *p - '0';
203 p++;
205 if (*p == '.') /* precision field */
207 p++;
208 while ((*p >= '0') && (*p <= '9'))
210 res->precision = res->precision * 10 + *p - '0';
211 p++;
214 if (*p == 'l') { res->flags |= WPRINTF_LONG; p++; }
215 else if (*p == 'h') { res->flags |= WPRINTF_SHORT; p++; }
216 switch(*p)
218 case 'c':
219 case 'C': /* no Unicode in Win16 */
220 res->type = WPR_CHAR;
221 break;
222 case 's':
223 case 'S':
224 res->type = WPR_STRING;
225 break;
226 case 'd':
227 case 'i':
228 res->type = WPR_SIGNED;
229 break;
230 case 'u':
231 res->type = WPR_UNSIGNED;
232 break;
233 case 'p':
234 res->width = 8;
235 res->flags |= WPRINTF_ZEROPAD;
236 /* fall through */
237 case 'X':
238 res->flags |= WPRINTF_UPPER_HEX;
239 /* fall through */
240 case 'x':
241 res->type = WPR_HEXA;
242 break;
243 default: /* unknown format char */
244 res->type = WPR_UNKNOWN;
245 p--; /* print format as normal char */
246 break;
248 return (INT)(p - format) + 1;
252 /**********************************************************************
253 * Management of the 16-bit cursors and icons
256 struct cache_entry
258 struct list entry;
259 HINSTANCE16 inst;
260 HRSRC16 rsrc;
261 HRSRC16 group;
262 HICON16 icon;
263 INT count;
266 static struct list icon_cache = LIST_INIT( icon_cache );
268 static HICON16 alloc_icon_handle( unsigned int size )
270 HGLOBAL16 handle = GlobalAlloc16( GMEM_MOVEABLE, size );
271 FarSetOwner16( handle, 0 );
272 return handle;
275 static CURSORICONINFO *get_icon_ptr( HICON16 handle )
277 return GlobalLock16( handle );
280 static void release_icon_ptr( HICON16 handle, CURSORICONINFO *ptr )
282 GlobalUnlock16( handle );
285 static int free_icon_handle( HICON16 handle )
287 return GlobalFree16( handle );
290 static void add_shared_icon( HINSTANCE16 inst, HRSRC16 rsrc, HRSRC16 group, HICON16 icon )
292 struct cache_entry *cache = HeapAlloc( GetProcessHeap(), 0, sizeof(*cache) );
294 if (!cache) return;
295 cache->inst = inst;
296 cache->rsrc = rsrc;
297 cache->group = group;
298 cache->icon = icon;
299 cache->count = 1;
300 list_add_tail( &icon_cache, &cache->entry );
303 static HICON16 find_shared_icon( HINSTANCE16 inst, HRSRC16 rsrc )
305 struct cache_entry *cache;
307 LIST_FOR_EACH_ENTRY( cache, &icon_cache, struct cache_entry, entry )
309 if (cache->inst != inst || cache->rsrc != rsrc) continue;
310 cache->count++;
311 return cache->icon;
313 return 0;
316 static int release_shared_icon( HICON16 icon )
318 struct cache_entry *cache;
320 LIST_FOR_EACH_ENTRY( cache, &icon_cache, struct cache_entry, entry )
322 if (cache->icon != icon) continue;
323 if (!cache->count) return 0;
324 return --cache->count;
326 return -1;
329 static void free_module_icons( HINSTANCE16 inst )
331 struct cache_entry *cache, *next;
333 LIST_FOR_EACH_ENTRY_SAFE( cache, next, &icon_cache, struct cache_entry, entry )
335 if (cache->inst != inst) continue;
336 list_remove( &cache->entry );
337 free_icon_handle( cache->icon );
338 HeapFree( GetProcessHeap(), 0, cache );
342 /**********************************************************************
343 * Management of the 16-bit clipboard formats
346 struct clipboard_format
348 struct list entry;
349 UINT format;
350 HANDLE16 data;
353 static struct list clipboard_formats = LIST_INIT( clipboard_formats );
355 static void set_clipboard_format( UINT format, HANDLE16 data )
357 struct clipboard_format *fmt;
359 /* replace it if it exists already */
360 LIST_FOR_EACH_ENTRY( fmt, &clipboard_formats, struct clipboard_format, entry )
362 if (fmt->format != format) continue;
363 GlobalFree16( fmt->data );
364 fmt->data = data;
365 return;
368 if ((fmt = HeapAlloc( GetProcessHeap(), 0, sizeof(*fmt) )))
370 fmt->format = format;
371 fmt->data = data;
372 list_add_tail( &clipboard_formats, &fmt->entry );
376 static void free_clipboard_formats(void)
378 struct list *head;
380 while ((head = list_head( &clipboard_formats )))
382 struct clipboard_format *fmt = LIST_ENTRY( head, struct clipboard_format, entry );
383 list_remove( &fmt->entry );
384 GlobalFree16( fmt->data );
385 HeapFree( GetProcessHeap(), 0, fmt );
390 /**********************************************************************
391 * DllMain
393 BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, LPVOID reserved )
395 if (reason == DLL_PROCESS_ATTACH) LoadLibrary16( "user.exe" );
396 return TRUE;
400 /**********************************************************************
401 * InitApp (USER.5)
403 INT16 WINAPI InitApp16( HINSTANCE16 hInstance )
405 /* Create task message queue */
406 return (InitThreadInput16( 0, 0 ) != 0);
410 /***********************************************************************
411 * ExitWindows (USER.7)
413 BOOL16 WINAPI ExitWindows16( DWORD dwReturnCode, UINT16 wReserved )
415 return ExitWindowsEx( EWX_LOGOFF, 0xffffffff );
419 /***********************************************************************
420 * GetTimerResolution (USER.14)
422 LONG WINAPI GetTimerResolution16(void)
424 return (1000);
428 /***********************************************************************
429 * ClipCursor (USER.16)
431 BOOL16 WINAPI ClipCursor16( const RECT16 *rect )
433 RECT rect32;
435 if (!rect) return ClipCursor( NULL );
436 rect32.left = rect->left;
437 rect32.top = rect->top;
438 rect32.right = rect->right;
439 rect32.bottom = rect->bottom;
440 return ClipCursor( &rect32 );
444 /***********************************************************************
445 * GetCursorPos (USER.17)
447 BOOL16 WINAPI GetCursorPos16( POINT16 *pt )
449 POINT pos;
450 if (!pt) return 0;
451 GetCursorPos(&pos);
452 pt->x = pos.x;
453 pt->y = pos.y;
454 return 1;
458 /*******************************************************************
459 * AnyPopup (USER.52)
461 BOOL16 WINAPI AnyPopup16(void)
463 return AnyPopup();
467 /***********************************************************************
468 * SetCursor (USER.69)
470 HCURSOR16 WINAPI SetCursor16(HCURSOR16 hCursor)
472 return HCURSOR_16(SetCursor(HCURSOR_32(hCursor)));
476 /***********************************************************************
477 * SetCursorPos (USER.70)
479 void WINAPI SetCursorPos16( INT16 x, INT16 y )
481 SetCursorPos( x, y );
485 /***********************************************************************
486 * ShowCursor (USER.71)
488 INT16 WINAPI ShowCursor16(BOOL16 bShow)
490 return ShowCursor(bShow);
494 /***********************************************************************
495 * SetRect (USER.72)
497 void WINAPI SetRect16( LPRECT16 rect, INT16 left, INT16 top, INT16 right, INT16 bottom )
499 rect->left = left;
500 rect->right = right;
501 rect->top = top;
502 rect->bottom = bottom;
506 /***********************************************************************
507 * SetRectEmpty (USER.73)
509 void WINAPI SetRectEmpty16( LPRECT16 rect )
511 rect->left = rect->right = rect->top = rect->bottom = 0;
515 /***********************************************************************
516 * CopyRect (USER.74)
518 BOOL16 WINAPI CopyRect16( RECT16 *dest, const RECT16 *src )
520 *dest = *src;
521 return TRUE;
525 /***********************************************************************
526 * IsRectEmpty (USER.75)
528 * Bug compat: Windows checks for 0 or negative width/height.
530 BOOL16 WINAPI IsRectEmpty16( const RECT16 *rect )
532 return ((rect->left >= rect->right) || (rect->top >= rect->bottom));
536 /***********************************************************************
537 * PtInRect (USER.76)
539 BOOL16 WINAPI PtInRect16( const RECT16 *rect, POINT16 pt )
541 return ((pt.x >= rect->left) && (pt.x < rect->right) &&
542 (pt.y >= rect->top) && (pt.y < rect->bottom));
546 /***********************************************************************
547 * OffsetRect (USER.77)
549 void WINAPI OffsetRect16( LPRECT16 rect, INT16 x, INT16 y )
551 rect->left += x;
552 rect->right += x;
553 rect->top += y;
554 rect->bottom += y;
558 /***********************************************************************
559 * InflateRect (USER.78)
561 void WINAPI InflateRect16( LPRECT16 rect, INT16 x, INT16 y )
563 rect->left -= x;
564 rect->top -= y;
565 rect->right += x;
566 rect->bottom += y;
570 /***********************************************************************
571 * IntersectRect (USER.79)
573 BOOL16 WINAPI IntersectRect16( LPRECT16 dest, const RECT16 *src1,
574 const RECT16 *src2 )
576 if (IsRectEmpty16(src1) || IsRectEmpty16(src2) ||
577 (src1->left >= src2->right) || (src2->left >= src1->right) ||
578 (src1->top >= src2->bottom) || (src2->top >= src1->bottom))
580 SetRectEmpty16( dest );
581 return FALSE;
583 dest->left = max( src1->left, src2->left );
584 dest->right = min( src1->right, src2->right );
585 dest->top = max( src1->top, src2->top );
586 dest->bottom = min( src1->bottom, src2->bottom );
587 return TRUE;
591 /***********************************************************************
592 * UnionRect (USER.80)
594 BOOL16 WINAPI UnionRect16( LPRECT16 dest, const RECT16 *src1,
595 const RECT16 *src2 )
597 if (IsRectEmpty16(src1))
599 if (IsRectEmpty16(src2))
601 SetRectEmpty16( dest );
602 return FALSE;
604 else *dest = *src2;
606 else
608 if (IsRectEmpty16(src2)) *dest = *src1;
609 else
611 dest->left = min( src1->left, src2->left );
612 dest->right = max( src1->right, src2->right );
613 dest->top = min( src1->top, src2->top );
614 dest->bottom = max( src1->bottom, src2->bottom );
617 return TRUE;
621 /***********************************************************************
622 * FillRect (USER.81)
623 * NOTE
624 * The Win16 variant doesn't support special color brushes like
625 * the Win32 one, despite the fact that Win16, as well as Win32,
626 * supports special background brushes for a window class.
628 INT16 WINAPI FillRect16( HDC16 hdc, const RECT16 *rect, HBRUSH16 hbrush )
630 HBRUSH prevBrush;
632 /* coordinates are logical so we cannot fast-check 'rect',
633 * it will be done later in the PatBlt().
636 if (!(prevBrush = SelectObject( HDC_32(hdc), HBRUSH_32(hbrush) ))) return 0;
637 PatBlt( HDC_32(hdc), rect->left, rect->top,
638 rect->right - rect->left, rect->bottom - rect->top, PATCOPY );
639 SelectObject( HDC_32(hdc), prevBrush );
640 return 1;
644 /***********************************************************************
645 * InvertRect (USER.82)
647 void WINAPI InvertRect16( HDC16 hdc, const RECT16 *rect )
649 PatBlt( HDC_32(hdc), rect->left, rect->top,
650 rect->right - rect->left, rect->bottom - rect->top, DSTINVERT );
654 /***********************************************************************
655 * FrameRect (USER.83)
657 INT16 WINAPI FrameRect16( HDC16 hdc, const RECT16 *rect16, HBRUSH16 hbrush )
659 RECT rect;
661 rect.left = rect16->left;
662 rect.top = rect16->top;
663 rect.right = rect16->right;
664 rect.bottom = rect16->bottom;
665 return FrameRect( HDC_32(hdc), &rect, HBRUSH_32(hbrush) );
669 /***********************************************************************
670 * DrawIcon (USER.84)
672 BOOL16 WINAPI DrawIcon16(HDC16 hdc, INT16 x, INT16 y, HICON16 hIcon)
674 return DrawIcon(HDC_32(hdc), x, y, HICON_32(hIcon));
678 /***********************************************************************
679 * DrawText (USER.85)
681 INT16 WINAPI DrawText16( HDC16 hdc, LPCSTR str, INT16 count, LPRECT16 rect, UINT16 flags )
683 INT16 ret;
685 if (rect)
687 RECT rect32;
689 rect32.left = rect->left;
690 rect32.top = rect->top;
691 rect32.right = rect->right;
692 rect32.bottom = rect->bottom;
693 ret = DrawTextA( HDC_32(hdc), str, count, &rect32, flags );
694 rect->left = rect32.left;
695 rect->top = rect32.top;
696 rect->right = rect32.right;
697 rect->bottom = rect32.bottom;
699 else ret = DrawTextA( HDC_32(hdc), str, count, NULL, flags);
700 return ret;
704 /***********************************************************************
705 * IconSize (USER.86)
707 * See "Undocumented Windows". Used by W2.0 paint.exe.
709 DWORD WINAPI IconSize16(void)
711 return MAKELONG(GetSystemMetrics(SM_CYICON), GetSystemMetrics(SM_CXICON));
715 /***********************************************************************
716 * AdjustWindowRect (USER.102)
718 BOOL16 WINAPI AdjustWindowRect16( LPRECT16 rect, DWORD style, BOOL16 menu )
720 return AdjustWindowRectEx16( rect, style, menu, 0 );
724 /***********************************************************************
725 * MessageBeep (USER.104)
727 void WINAPI MessageBeep16( UINT16 i )
729 MessageBeep( i );
733 /**************************************************************************
734 * CloseClipboard (USER.138)
736 BOOL16 WINAPI CloseClipboard16(void)
738 BOOL ret = CloseClipboard();
739 if (ret) free_clipboard_formats();
740 return ret;
744 /**************************************************************************
745 * EmptyClipboard (USER.139)
747 BOOL16 WINAPI EmptyClipboard16(void)
749 BOOL ret = EmptyClipboard();
750 if (ret) free_clipboard_formats();
751 return ret;
755 /**************************************************************************
756 * SetClipboardData (USER.141)
758 HANDLE16 WINAPI SetClipboardData16( UINT16 format, HANDLE16 data16 )
760 HANDLE data32 = 0;
762 switch (format)
764 case CF_BITMAP:
765 case CF_PALETTE:
766 data32 = HGDIOBJ_32( data16 );
767 break;
769 case CF_METAFILEPICT:
771 METAHEADER *header;
772 METAFILEPICT *pict32;
773 METAFILEPICT16 *pict16 = GlobalLock16( data16 );
775 if (pict16)
777 if (!(data32 = GlobalAlloc( GMEM_MOVEABLE, sizeof(*pict32) ))) return 0;
778 pict32 = GlobalLock( data32 );
779 pict32->mm = pict16->mm;
780 pict32->xExt = pict16->xExt;
781 pict32->yExt = pict16->yExt;
782 header = GlobalLock16( pict16->hMF );
783 pict32->hMF = SetMetaFileBitsEx( header->mtSize * 2, (BYTE *)header );
784 GlobalUnlock16( pict16->hMF );
785 GlobalUnlock( data32 );
787 set_clipboard_format( format, data16 );
788 break;
791 case CF_ENHMETAFILE:
792 FIXME( "enhmetafile not supported in 16-bit\n" );
793 return 0;
795 default:
796 if (format >= CF_GDIOBJFIRST && format <= CF_GDIOBJLAST)
797 data32 = HGDIOBJ_32( data16 );
798 else if (format >= CF_PRIVATEFIRST && format <= CF_PRIVATELAST)
799 data32 = HANDLE_32( data16 );
800 else
802 UINT size = GlobalSize16( data16 );
803 void *ptr32, *ptr16 = GlobalLock16( data16 );
804 if (ptr16)
806 if (!(data32 = GlobalAlloc( GMEM_MOVEABLE, size ))) return 0;
807 ptr32 = GlobalLock( data32 );
808 memcpy( ptr32, ptr16, size );
809 GlobalUnlock( data32 );
811 set_clipboard_format( format, data16 );
813 break;
816 if (!SetClipboardData( format, data32 )) return 0;
817 return data16;
821 /**************************************************************************
822 * GetClipboardData (USER.142)
824 HANDLE16 WINAPI GetClipboardData16( UINT16 format )
826 HANDLE data32 = GetClipboardData( format );
827 HANDLE16 data16 = 0;
828 UINT size;
829 void *ptr;
831 if (!data32) return 0;
833 switch (format)
835 case CF_BITMAP:
836 case CF_PALETTE:
837 data16 = HGDIOBJ_16( data32 );
838 break;
840 case CF_METAFILEPICT:
842 METAFILEPICT16 *pict16;
843 METAFILEPICT *pict32 = GlobalLock( data32 );
845 if (pict32)
847 if (!(data16 = GlobalAlloc16( GMEM_MOVEABLE, sizeof(*pict16) ))) return 0;
848 pict16 = GlobalLock16( data16 );
849 pict16->mm = pict32->mm;
850 pict16->xExt = pict32->xExt;
851 pict16->yExt = pict32->yExt;
852 size = GetMetaFileBitsEx( pict32->hMF, 0, NULL );
853 pict16->hMF = GlobalAlloc16( GMEM_MOVEABLE, size );
854 ptr = GlobalLock16( pict16->hMF );
855 GetMetaFileBitsEx( pict32->hMF, size, ptr );
856 GlobalUnlock16( pict16->hMF );
857 GlobalUnlock16( data16 );
858 set_clipboard_format( format, data16 );
860 break;
863 case CF_ENHMETAFILE:
864 FIXME( "enhmetafile not supported in 16-bit\n" );
865 return 0;
867 default:
868 if (format >= CF_GDIOBJFIRST && format <= CF_GDIOBJLAST)
869 data16 = HGDIOBJ_16( data32 );
870 else if (format >= CF_PRIVATEFIRST && format <= CF_PRIVATELAST)
871 data16 = HANDLE_16( data32 );
872 else
874 void *ptr16, *ptr32 = GlobalLock( data32 );
875 if (ptr32)
877 size = GlobalSize( data32 );
878 if (!(data16 = GlobalAlloc16( GMEM_MOVEABLE, size ))) return 0;
879 ptr16 = GlobalLock16( data16 );
880 memcpy( ptr16, ptr32, size );
881 GlobalUnlock16( data16 );
882 set_clipboard_format( format, data16 );
885 break;
887 return data16;
891 /**************************************************************************
892 * CountClipboardFormats (USER.143)
894 INT16 WINAPI CountClipboardFormats16(void)
896 return CountClipboardFormats();
900 /**************************************************************************
901 * EnumClipboardFormats (USER.144)
903 UINT16 WINAPI EnumClipboardFormats16( UINT16 id )
905 return EnumClipboardFormats( id );
909 /**************************************************************************
910 * RegisterClipboardFormat (USER.145)
912 UINT16 WINAPI RegisterClipboardFormat16( LPCSTR name )
914 return RegisterClipboardFormatA( name );
918 /**************************************************************************
919 * GetClipboardFormatName (USER.146)
921 INT16 WINAPI GetClipboardFormatName16( UINT16 id, LPSTR buffer, INT16 maxlen )
923 return GetClipboardFormatNameA( id, buffer, maxlen );
927 /**********************************************************************
928 * LoadMenu (USER.150)
930 HMENU16 WINAPI LoadMenu16( HINSTANCE16 instance, LPCSTR name )
932 HRSRC16 hRsrc;
933 HGLOBAL16 handle;
934 HMENU16 hMenu;
936 if (HIWORD(name) && name[0] == '#') name = ULongToPtr(atoi( name + 1 ));
937 if (!name) return 0;
939 instance = GetExePtr( instance );
940 if (!(hRsrc = FindResource16( instance, name, (LPSTR)RT_MENU ))) return 0;
941 if (!(handle = LoadResource16( instance, hRsrc ))) return 0;
942 hMenu = LoadMenuIndirect16(LockResource16(handle));
943 FreeResource16( handle );
944 return hMenu;
948 /**********************************************************************
949 * CreateMenu (USER.151)
951 HMENU16 WINAPI CreateMenu16(void)
953 return HMENU_16( CreateMenu() );
957 /**********************************************************************
958 * DestroyMenu (USER.152)
960 BOOL16 WINAPI DestroyMenu16( HMENU16 hMenu )
962 return DestroyMenu( HMENU_32(hMenu) );
966 /*******************************************************************
967 * ChangeMenu (USER.153)
969 BOOL16 WINAPI ChangeMenu16( HMENU16 hMenu, UINT16 pos, SEGPTR data,
970 UINT16 id, UINT16 flags )
972 if (flags & MF_APPEND) return AppendMenu16( hMenu, flags & ~MF_APPEND, id, data );
974 /* FIXME: Word passes the item id in 'pos' and 0 or 0xffff as id */
975 /* for MF_DELETE. We should check the parameters for all others */
976 /* MF_* actions also (anybody got a doc on ChangeMenu?). */
978 if (flags & MF_DELETE) return DeleteMenu16(hMenu, pos, flags & ~MF_DELETE);
979 if (flags & MF_CHANGE) return ModifyMenu16(hMenu, pos, flags & ~MF_CHANGE, id, data );
980 if (flags & MF_REMOVE) return RemoveMenu16(hMenu, flags & MF_BYPOSITION ? pos : id,
981 flags & ~MF_REMOVE );
982 /* Default: MF_INSERT */
983 return InsertMenu16( hMenu, pos, flags, id, data );
987 /*******************************************************************
988 * CheckMenuItem (USER.154)
990 BOOL16 WINAPI CheckMenuItem16( HMENU16 hMenu, UINT16 id, UINT16 flags )
992 return CheckMenuItem( HMENU_32(hMenu), id, flags );
996 /**********************************************************************
997 * EnableMenuItem (USER.155)
999 BOOL16 WINAPI EnableMenuItem16( HMENU16 hMenu, UINT16 wItemID, UINT16 wFlags )
1001 return EnableMenuItem( HMENU_32(hMenu), wItemID, wFlags );
1005 /**********************************************************************
1006 * GetSubMenu (USER.159)
1008 HMENU16 WINAPI GetSubMenu16( HMENU16 hMenu, INT16 nPos )
1010 return HMENU_16( GetSubMenu( HMENU_32(hMenu), nPos ) );
1014 /*******************************************************************
1015 * GetMenuString (USER.161)
1017 INT16 WINAPI GetMenuString16( HMENU16 hMenu, UINT16 wItemID,
1018 LPSTR str, INT16 nMaxSiz, UINT16 wFlags )
1020 return GetMenuStringA( HMENU_32(hMenu), wItemID, str, nMaxSiz, wFlags );
1024 /**********************************************************************
1025 * WinHelp (USER.171)
1027 BOOL16 WINAPI WinHelp16( HWND16 hWnd, LPCSTR lpHelpFile, UINT16 wCommand,
1028 DWORD dwData )
1030 BOOL ret;
1031 DWORD mutex_count;
1033 /* We might call WinExec() */
1034 ReleaseThunkLock(&mutex_count);
1036 ret = WinHelpA(WIN_Handle32(hWnd), lpHelpFile, wCommand, (DWORD)MapSL(dwData));
1038 RestoreThunkLock(mutex_count);
1039 return ret;
1043 /***********************************************************************
1044 * LoadCursor (USER.173)
1046 HCURSOR16 WINAPI LoadCursor16(HINSTANCE16 hInstance, LPCSTR name)
1048 return LoadImage16( hInstance, name, IMAGE_CURSOR, 0, 0, LR_SHARED | LR_DEFAULTSIZE );
1052 /***********************************************************************
1053 * LoadIcon (USER.174)
1055 HICON16 WINAPI LoadIcon16(HINSTANCE16 hInstance, LPCSTR name)
1057 return LoadImage16( hInstance, name, IMAGE_ICON, 0, 0, LR_SHARED | LR_DEFAULTSIZE );
1060 /**********************************************************************
1061 * LoadBitmap (USER.175)
1063 HBITMAP16 WINAPI LoadBitmap16(HINSTANCE16 hInstance, LPCSTR name)
1065 return LoadImage16( hInstance, name, IMAGE_BITMAP, 0, 0, 0 );
1068 /**********************************************************************
1069 * LoadString (USER.176)
1071 INT16 WINAPI LoadString16( HINSTANCE16 instance, UINT16 resource_id, LPSTR buffer, INT16 buflen )
1073 HGLOBAL16 hmem;
1074 HRSRC16 hrsrc;
1075 unsigned char *p;
1076 int string_num;
1077 int ret;
1079 TRACE("inst=%04x id=%04x buff=%p len=%d\n", instance, resource_id, buffer, buflen);
1081 hrsrc = FindResource16( instance, MAKEINTRESOURCEA((resource_id>>4)+1), (LPSTR)RT_STRING );
1082 if (!hrsrc) return 0;
1083 hmem = LoadResource16( instance, hrsrc );
1084 if (!hmem) return 0;
1086 p = LockResource16(hmem);
1087 string_num = resource_id & 0x000f;
1088 while (string_num--) p += *p + 1;
1090 if (buffer == NULL) ret = *p;
1091 else
1093 ret = min(buflen - 1, *p);
1094 if (ret > 0)
1096 memcpy(buffer, p + 1, ret);
1097 buffer[ret] = '\0';
1099 else if (buflen > 1)
1101 buffer[0] = '\0';
1102 ret = 0;
1104 TRACE( "%s loaded\n", debugstr_a(buffer));
1106 FreeResource16( hmem );
1107 return ret;
1110 /**********************************************************************
1111 * LoadAccelerators (USER.177)
1113 HACCEL16 WINAPI LoadAccelerators16(HINSTANCE16 instance, LPCSTR lpTableName)
1115 HRSRC16 hRsrc;
1116 HGLOBAL16 hMem;
1117 ACCEL16 *table16;
1118 HACCEL ret = 0;
1120 TRACE("%04x %s\n", instance, debugstr_a(lpTableName) );
1122 if (!(hRsrc = FindResource16( instance, lpTableName, (LPSTR)RT_ACCELERATOR )) ||
1123 !(hMem = LoadResource16(instance,hRsrc)))
1125 WARN("couldn't find %04x %s\n", instance, debugstr_a(lpTableName));
1126 return 0;
1128 if ((table16 = LockResource16( hMem )))
1130 DWORD i, count = SizeofResource16( instance, hRsrc ) / sizeof(*table16);
1131 ACCEL *table = HeapAlloc( GetProcessHeap(), 0, count * sizeof(*table) );
1132 if (table)
1134 for (i = 0; i < count; i++)
1136 table[i].fVirt = table16[i].fVirt & 0x7f;
1137 table[i].key = table16[i].key;
1138 table[i].cmd = table16[i].cmd;
1140 ret = CreateAcceleratorTableA( table, count );
1141 HeapFree( GetProcessHeap(), 0, table );
1144 FreeResource16( hMem );
1145 return HACCEL_16(ret);
1148 /***********************************************************************
1149 * GetSystemMetrics (USER.179)
1151 INT16 WINAPI GetSystemMetrics16( INT16 index )
1153 return GetSystemMetrics( index );
1157 /*************************************************************************
1158 * GetSysColor (USER.180)
1160 COLORREF WINAPI GetSysColor16( INT16 index )
1162 return GetSysColor( index );
1166 /*************************************************************************
1167 * SetSysColors (USER.181)
1169 VOID WINAPI SetSysColors16( INT16 count, const INT16 *list16, const COLORREF *values )
1171 INT i, *list;
1173 if ((list = HeapAlloc( GetProcessHeap(), 0, count * sizeof(*list) )))
1175 for (i = 0; i < count; i++) list[i] = list16[i];
1176 SetSysColors( count, list, values );
1177 HeapFree( GetProcessHeap(), 0, list );
1182 /***********************************************************************
1183 * GrayString (USER.185)
1185 BOOL16 WINAPI GrayString16( HDC16 hdc, HBRUSH16 hbr, GRAYSTRINGPROC16 gsprc,
1186 LPARAM lParam, INT16 cch, INT16 x, INT16 y,
1187 INT16 cx, INT16 cy )
1189 BOOL ret;
1191 if (!gsprc) return GrayStringA( HDC_32(hdc), HBRUSH_32(hbr), NULL,
1192 (LPARAM)MapSL(lParam), cch, x, y, cx, cy );
1194 if (cch == -1 || (cch && cx && cy))
1196 /* lParam can be treated as an opaque pointer */
1197 struct gray_string_info info;
1199 info.proc = gsprc;
1200 info.param = lParam;
1201 ret = GrayStringA( HDC_32(hdc), HBRUSH_32(hbr), gray_string_callback,
1202 (LPARAM)&info, cch, x, y, cx, cy );
1204 else /* here we need some string conversions */
1206 char *str16 = MapSL(lParam);
1207 struct gray_string_info *info;
1209 if (!cch) cch = strlen(str16);
1210 if (!(info = HeapAlloc( GetProcessHeap(), 0, sizeof(*info) + cch ))) return FALSE;
1211 info->proc = gsprc;
1212 info->param = lParam;
1213 memcpy( info->str, str16, cch );
1214 ret = GrayStringA( HDC_32(hdc), HBRUSH_32(hbr), gray_string_callback_ptr,
1215 (LPARAM)info->str, cch, x, y, cx, cy );
1216 HeapFree( GetProcessHeap(), 0, info );
1218 return ret;
1222 /***********************************************************************
1223 * SwapMouseButton (USER.186)
1225 BOOL16 WINAPI SwapMouseButton16( BOOL16 fSwap )
1227 return SwapMouseButton( fSwap );
1231 /**************************************************************************
1232 * IsClipboardFormatAvailable (USER.193)
1234 BOOL16 WINAPI IsClipboardFormatAvailable16( UINT16 wFormat )
1236 return IsClipboardFormatAvailable( wFormat );
1240 /***********************************************************************
1241 * TabbedTextOut (USER.196)
1243 LONG WINAPI TabbedTextOut16( HDC16 hdc, INT16 x, INT16 y, LPCSTR lpstr,
1244 INT16 count, INT16 nb_tabs, const INT16 *tabs16, INT16 tab_org )
1246 LONG ret;
1247 INT i, *tabs = HeapAlloc( GetProcessHeap(), 0, nb_tabs * sizeof(tabs) );
1248 if (!tabs) return 0;
1249 for (i = 0; i < nb_tabs; i++) tabs[i] = tabs16[i];
1250 ret = TabbedTextOutA( HDC_32(hdc), x, y, lpstr, count, nb_tabs, tabs, tab_org );
1251 HeapFree( GetProcessHeap(), 0, tabs );
1252 return ret;
1256 /***********************************************************************
1257 * GetTabbedTextExtent (USER.197)
1259 DWORD WINAPI GetTabbedTextExtent16( HDC16 hdc, LPCSTR lpstr, INT16 count,
1260 INT16 nb_tabs, const INT16 *tabs16 )
1262 LONG ret;
1263 INT i, *tabs = HeapAlloc( GetProcessHeap(), 0, nb_tabs * sizeof(tabs) );
1264 if (!tabs) return 0;
1265 for (i = 0; i < nb_tabs; i++) tabs[i] = tabs16[i];
1266 ret = GetTabbedTextExtentA( HDC_32(hdc), lpstr, count, nb_tabs, tabs );
1267 HeapFree( GetProcessHeap(), 0, tabs );
1268 return ret;
1272 /***********************************************************************
1273 * UserSeeUserDo (USER.216)
1275 DWORD WINAPI UserSeeUserDo16(WORD wReqType, WORD wParam1, WORD wParam2, WORD wParam3)
1277 STACK16FRAME* stack16 = MapSL((SEGPTR)NtCurrentTeb()->WOW32Reserved);
1278 HANDLE16 oldDS = stack16->ds;
1279 DWORD ret = (DWORD)-1;
1281 stack16->ds = USER_HeapSel;
1282 switch (wReqType)
1284 case USUD_LOCALALLOC:
1285 ret = LocalAlloc16(wParam1, wParam3);
1286 break;
1287 case USUD_LOCALFREE:
1288 ret = LocalFree16(wParam1);
1289 break;
1290 case USUD_LOCALCOMPACT:
1291 ret = LocalCompact16(wParam3);
1292 break;
1293 case USUD_LOCALHEAP:
1294 ret = USER_HeapSel;
1295 break;
1296 case USUD_FIRSTCLASS:
1297 FIXME("return a pointer to the first window class.\n");
1298 break;
1299 default:
1300 WARN("wReqType %04x (unknown)\n", wReqType);
1302 stack16->ds = oldDS;
1303 return ret;
1307 /***********************************************************************
1308 * LookupMenuHandle (USER.217)
1310 HMENU16 WINAPI LookupMenuHandle16( HMENU16 hmenu, INT16 id )
1312 FIXME( "%04x %04x: stub\n", hmenu, id );
1313 return hmenu;
1317 static LPCSTR parse_menu_resource( LPCSTR res, HMENU hMenu )
1319 WORD flags, id = 0;
1320 LPCSTR str;
1321 BOOL end_flag;
1325 flags = GET_WORD(res);
1326 end_flag = flags & MF_END;
1327 /* Remove MF_END because it has the same value as MF_HILITE */
1328 flags &= ~MF_END;
1329 res += sizeof(WORD);
1330 if (!(flags & MF_POPUP))
1332 id = GET_WORD(res);
1333 res += sizeof(WORD);
1335 str = res;
1336 res += strlen(str) + 1;
1337 if (flags & MF_POPUP)
1339 HMENU hSubMenu = CreatePopupMenu();
1340 if (!hSubMenu) return NULL;
1341 if (!(res = parse_menu_resource( res, hSubMenu ))) return NULL;
1342 AppendMenuA( hMenu, flags, (UINT_PTR)hSubMenu, str );
1344 else /* Not a popup */
1346 AppendMenuA( hMenu, flags, id, *str ? str : NULL );
1348 } while (!end_flag);
1349 return res;
1352 /**********************************************************************
1353 * LoadMenuIndirect (USER.220)
1355 HMENU16 WINAPI LoadMenuIndirect16( LPCVOID template )
1357 HMENU hMenu;
1358 WORD version, offset;
1359 LPCSTR p = template;
1361 TRACE("(%p)\n", template );
1362 version = GET_WORD(p);
1363 p += sizeof(WORD);
1364 if (version)
1366 WARN("version must be 0 for Win16\n" );
1367 return 0;
1369 offset = GET_WORD(p);
1370 p += sizeof(WORD) + offset;
1371 if (!(hMenu = CreateMenu())) return 0;
1372 if (!parse_menu_resource( p, hMenu ))
1374 DestroyMenu( hMenu );
1375 return 0;
1377 return HMENU_16(hMenu);
1381 /*************************************************************************
1382 * ScrollDC (USER.221)
1384 BOOL16 WINAPI ScrollDC16( HDC16 hdc, INT16 dx, INT16 dy, const RECT16 *rect,
1385 const RECT16 *cliprc, HRGN16 hrgnUpdate,
1386 LPRECT16 rcUpdate )
1388 RECT rect32, clipRect32, rcUpdate32;
1389 BOOL16 ret;
1391 if (rect)
1393 rect32.left = rect->left;
1394 rect32.top = rect->top;
1395 rect32.right = rect->right;
1396 rect32.bottom = rect->bottom;
1398 if (cliprc)
1400 clipRect32.left = cliprc->left;
1401 clipRect32.top = cliprc->top;
1402 clipRect32.right = cliprc->right;
1403 clipRect32.bottom = cliprc->bottom;
1405 ret = ScrollDC( HDC_32(hdc), dx, dy, rect ? &rect32 : NULL,
1406 cliprc ? &clipRect32 : NULL, HRGN_32(hrgnUpdate),
1407 &rcUpdate32 );
1408 if (rcUpdate)
1410 rcUpdate->left = rcUpdate32.left;
1411 rcUpdate->top = rcUpdate32.top;
1412 rcUpdate->right = rcUpdate32.right;
1413 rcUpdate->bottom = rcUpdate32.bottom;
1415 return ret;
1419 /***********************************************************************
1420 * GetSystemDebugState (USER.231)
1422 WORD WINAPI GetSystemDebugState16(void)
1424 return 0; /* FIXME */
1428 /***********************************************************************
1429 * EqualRect (USER.244)
1431 BOOL16 WINAPI EqualRect16( const RECT16* rect1, const RECT16* rect2 )
1433 return ((rect1->left == rect2->left) && (rect1->right == rect2->right) &&
1434 (rect1->top == rect2->top) && (rect1->bottom == rect2->bottom));
1438 /***********************************************************************
1439 * ExitWindowsExec (USER.246)
1441 BOOL16 WINAPI ExitWindowsExec16( LPCSTR lpszExe, LPCSTR lpszParams )
1443 TRACE("Should run the following in DOS-mode: \"%s %s\"\n",
1444 lpszExe, lpszParams);
1445 return ExitWindowsEx( EWX_LOGOFF, 0xffffffff );
1449 /***********************************************************************
1450 * GetCursor (USER.247)
1452 HCURSOR16 WINAPI GetCursor16(void)
1454 return HCURSOR_16(GetCursor());
1458 /**********************************************************************
1459 * GetAsyncKeyState (USER.249)
1461 INT16 WINAPI GetAsyncKeyState16( INT16 key )
1463 return GetAsyncKeyState( key );
1467 /**********************************************************************
1468 * GetMenuState (USER.250)
1470 UINT16 WINAPI GetMenuState16( HMENU16 hMenu, UINT16 wItemID, UINT16 wFlags )
1472 return GetMenuState( HMENU_32(hMenu), wItemID, wFlags );
1476 /**************************************************************************
1477 * SendDriverMessage (USER.251)
1479 LRESULT WINAPI SendDriverMessage16(HDRVR16 hDriver, UINT16 msg, LPARAM lParam1,
1480 LPARAM lParam2)
1482 FIXME("(%04x, %04x, %08lx, %08lx): stub\n", hDriver, msg, lParam1, lParam2);
1483 return 0;
1487 /**************************************************************************
1488 * OpenDriver (USER.252)
1490 HDRVR16 WINAPI OpenDriver16(LPCSTR lpDriverName, LPCSTR lpSectionName, LPARAM lParam2)
1492 FIXME( "(%s, %s, %08lx): stub\n", debugstr_a(lpDriverName), debugstr_a(lpSectionName), lParam2);
1493 return 0;
1497 /**************************************************************************
1498 * CloseDriver (USER.253)
1500 LRESULT WINAPI CloseDriver16(HDRVR16 hDrvr, LPARAM lParam1, LPARAM lParam2)
1502 FIXME( "(%04x, %08lx, %08lx): stub\n", hDrvr, lParam1, lParam2);
1503 return FALSE;
1507 /**************************************************************************
1508 * GetDriverModuleHandle (USER.254)
1510 HMODULE16 WINAPI GetDriverModuleHandle16(HDRVR16 hDrvr)
1512 FIXME("(%04x): stub\n", hDrvr);
1513 return 0;
1517 /**************************************************************************
1518 * DefDriverProc (USER.255)
1520 LRESULT WINAPI DefDriverProc16(DWORD dwDevID, HDRVR16 hDriv, UINT16 wMsg,
1521 LPARAM lParam1, LPARAM lParam2)
1523 FIXME( "devID=0x%08x hDrv=0x%04x wMsg=%04x lP1=0x%08lx lP2=0x%08lx: stub\n",
1524 dwDevID, hDriv, wMsg, lParam1, lParam2);
1525 return 0;
1529 /**************************************************************************
1530 * GetDriverInfo (USER.256)
1532 struct DRIVERINFOSTRUCT16;
1533 BOOL16 WINAPI GetDriverInfo16(HDRVR16 hDrvr, struct DRIVERINFOSTRUCT16 *lpDrvInfo)
1535 FIXME( "(%04x, %p): stub\n", hDrvr, lpDrvInfo);
1536 return FALSE;
1540 /**************************************************************************
1541 * GetNextDriver (USER.257)
1543 HDRVR16 WINAPI GetNextDriver16(HDRVR16 hDrvr, DWORD dwFlags)
1545 FIXME( "(%04x, %08x): stub\n", hDrvr, dwFlags);
1546 return 0;
1550 /**********************************************************************
1551 * GetMenuItemCount (USER.263)
1553 INT16 WINAPI GetMenuItemCount16( HMENU16 hMenu )
1555 return GetMenuItemCount( HMENU_32(hMenu) );
1559 /**********************************************************************
1560 * GetMenuItemID (USER.264)
1562 UINT16 WINAPI GetMenuItemID16( HMENU16 hMenu, INT16 nPos )
1564 return GetMenuItemID( HMENU_32(hMenu), nPos );
1568 /***********************************************************************
1569 * GlobalAddAtom (USER.268)
1571 ATOM WINAPI GlobalAddAtom16(LPCSTR lpString)
1573 return GlobalAddAtomA(lpString);
1576 /***********************************************************************
1577 * GlobalDeleteAtom (USER.269)
1579 ATOM WINAPI GlobalDeleteAtom16(ATOM nAtom)
1581 return GlobalDeleteAtom(nAtom);
1584 /***********************************************************************
1585 * GlobalFindAtom (USER.270)
1587 ATOM WINAPI GlobalFindAtom16(LPCSTR lpString)
1589 return GlobalFindAtomA(lpString);
1592 /***********************************************************************
1593 * GlobalGetAtomName (USER.271)
1595 UINT16 WINAPI GlobalGetAtomName16(ATOM nAtom, LPSTR lpBuffer, INT16 nSize)
1597 return GlobalGetAtomNameA(nAtom, lpBuffer, nSize);
1601 /***********************************************************************
1602 * ControlPanelInfo (USER.273)
1604 void WINAPI ControlPanelInfo16( INT16 nInfoType, WORD wData, LPSTR lpBuffer )
1606 FIXME("(%d, %04x, %p): stub.\n", nInfoType, wData, lpBuffer);
1610 /***********************************************************************
1611 * OldSetDeskPattern (USER.279)
1613 BOOL16 WINAPI SetDeskPattern16(void)
1615 return SystemParametersInfoA( SPI_SETDESKPATTERN, -1, NULL, FALSE );
1619 /***********************************************************************
1620 * GetSysColorBrush (USER.281)
1622 HBRUSH16 WINAPI GetSysColorBrush16( INT16 index )
1624 return HBRUSH_16( GetSysColorBrush(index) );
1628 /***********************************************************************
1629 * SelectPalette (USER.282)
1631 HPALETTE16 WINAPI SelectPalette16( HDC16 hdc, HPALETTE16 hpal, BOOL16 bForceBackground )
1633 return HPALETTE_16( SelectPalette( HDC_32(hdc), HPALETTE_32(hpal), bForceBackground ));
1636 /***********************************************************************
1637 * RealizePalette (USER.283)
1639 UINT16 WINAPI RealizePalette16( HDC16 hdc )
1641 return UserRealizePalette( HDC_32(hdc) );
1645 /***********************************************************************
1646 * GetFreeSystemResources (USER.284)
1648 WORD WINAPI GetFreeSystemResources16( WORD resType )
1650 STACK16FRAME* stack16 = MapSL((SEGPTR)NtCurrentTeb()->WOW32Reserved);
1651 HANDLE16 oldDS = stack16->ds;
1652 HINSTANCE16 gdi_inst;
1653 int userPercent, gdiPercent;
1655 if ((gdi_inst = LoadLibrary16( "GDI" )) < 32) return 0;
1657 switch(resType)
1659 case GFSR_USERRESOURCES:
1660 stack16->ds = USER_HeapSel;
1661 userPercent = (int)LocalCountFree16() * 100 / LocalHeapSize16();
1662 gdiPercent = 100;
1663 stack16->ds = oldDS;
1664 break;
1666 case GFSR_GDIRESOURCES:
1667 stack16->ds = gdi_inst;
1668 gdiPercent = (int)LocalCountFree16() * 100 / LocalHeapSize16();
1669 userPercent = 100;
1670 stack16->ds = oldDS;
1671 break;
1673 case GFSR_SYSTEMRESOURCES:
1674 stack16->ds = USER_HeapSel;
1675 userPercent = (int)LocalCountFree16() * 100 / LocalHeapSize16();
1676 stack16->ds = gdi_inst;
1677 gdiPercent = (int)LocalCountFree16() * 100 / LocalHeapSize16();
1678 stack16->ds = oldDS;
1679 break;
1681 default:
1682 userPercent = gdiPercent = 0;
1683 break;
1685 FreeLibrary16( gdi_inst );
1686 TRACE("<- userPercent %d, gdiPercent %d\n", userPercent, gdiPercent);
1687 return (WORD)min( userPercent, gdiPercent );
1691 /***********************************************************************
1692 * SetDeskWallPaper (USER.285)
1694 BOOL16 WINAPI SetDeskWallPaper16( LPCSTR filename )
1696 return SetDeskWallPaper( filename );
1700 /***********************************************************************
1701 * keybd_event (USER.289)
1703 void WINAPI keybd_event16( CONTEXT86 *context )
1705 DWORD dwFlags = 0;
1707 if (HIBYTE(context->Eax) & 0x80) dwFlags |= KEYEVENTF_KEYUP;
1708 if (HIBYTE(context->Ebx) & 0x01) dwFlags |= KEYEVENTF_EXTENDEDKEY;
1710 keybd_event( LOBYTE(context->Eax), LOBYTE(context->Ebx),
1711 dwFlags, MAKELONG(LOWORD(context->Esi), LOWORD(context->Edi)) );
1715 /***********************************************************************
1716 * mouse_event (USER.299)
1718 void WINAPI mouse_event16( CONTEXT86 *context )
1720 mouse_event( LOWORD(context->Eax), LOWORD(context->Ebx), LOWORD(context->Ecx),
1721 LOWORD(context->Edx), MAKELONG(context->Esi, context->Edi) );
1725 /***********************************************************************
1726 * GetClipCursor (USER.309)
1728 void WINAPI GetClipCursor16( RECT16 *rect )
1730 if (rect)
1732 RECT rect32;
1733 GetClipCursor( &rect32 );
1734 rect->left = rect32.left;
1735 rect->top = rect32.top;
1736 rect->right = rect32.right;
1737 rect->bottom = rect32.bottom;
1742 /***********************************************************************
1743 * SignalProc (USER.314)
1745 void WINAPI SignalProc16( HANDLE16 hModule, UINT16 code,
1746 UINT16 uExitFn, HINSTANCE16 hInstance, HQUEUE16 hQueue )
1748 if (code == USIG16_DLL_UNLOAD)
1750 hModule = GetExePtr(hModule);
1751 /* HOOK_FreeModuleHooks( hModule ); */
1752 free_module_classes( hModule );
1753 free_module_icons( hModule );
1758 /***********************************************************************
1759 * SetEventHook (USER.321)
1761 * Used by Turbo Debugger for Windows
1763 FARPROC16 WINAPI SetEventHook16(FARPROC16 lpfnEventHook)
1765 FIXME("(lpfnEventHook=%p): stub\n", lpfnEventHook);
1766 return 0;
1770 /**********************************************************************
1771 * EnableHardwareInput (USER.331)
1773 BOOL16 WINAPI EnableHardwareInput16(BOOL16 bEnable)
1775 FIXME("(%d) - stub\n", bEnable);
1776 return TRUE;
1780 /**********************************************************************
1781 * LoadCursorIconHandler (USER.336)
1783 * Supposed to load resources of Windows 2.x applications.
1785 HGLOBAL16 WINAPI LoadCursorIconHandler16( HGLOBAL16 hResource, HMODULE16 hModule, HRSRC16 hRsrc )
1787 FIXME("(%04x,%04x,%04x): old 2.x resources are not supported!\n", hResource, hModule, hRsrc);
1788 return 0;
1792 /***********************************************************************
1793 * GetMouseEventProc (USER.337)
1795 FARPROC16 WINAPI GetMouseEventProc16(void)
1797 HMODULE16 hmodule = GetModuleHandle16("USER");
1798 return GetProcAddress16( hmodule, "mouse_event" );
1802 /***********************************************************************
1803 * IsUserIdle (USER.333)
1805 BOOL16 WINAPI IsUserIdle16(void)
1807 if ( GetAsyncKeyState( VK_LBUTTON ) & 0x8000 )
1808 return FALSE;
1809 if ( GetAsyncKeyState( VK_RBUTTON ) & 0x8000 )
1810 return FALSE;
1811 if ( GetAsyncKeyState( VK_MBUTTON ) & 0x8000 )
1812 return FALSE;
1813 /* Should check for screen saver activation here ... */
1814 return TRUE;
1818 /**********************************************************************
1819 * LoadDIBIconHandler (USER.357)
1821 * RT_ICON resource loader, installed by USER_SignalProc when module
1822 * is initialized.
1824 HGLOBAL16 WINAPI LoadDIBIconHandler16( HGLOBAL16 hMemObj, HMODULE16 hModule, HRSRC16 hRsrc )
1826 /* If hResource is zero we must allocate a new memory block, if it's
1827 * non-zero but GlobalLock() returns NULL then it was discarded and
1828 * we have to recommit some memory, otherwise we just need to check
1829 * the block size. See LoadProc() in 16-bit SDK for more.
1831 FIXME( "%x %x %x: stub, not supported anymore\n", hMemObj, hModule, hRsrc );
1832 return 0;
1835 /**********************************************************************
1836 * LoadDIBCursorHandler (USER.356)
1838 * RT_CURSOR resource loader. Same as above.
1840 HGLOBAL16 WINAPI LoadDIBCursorHandler16( HGLOBAL16 hMemObj, HMODULE16 hModule, HRSRC16 hRsrc )
1842 FIXME( "%x %x %x: stub, not supported anymore\n", hMemObj, hModule, hRsrc );
1843 return 0;
1847 /**********************************************************************
1848 * IsMenu (USER.358)
1850 BOOL16 WINAPI IsMenu16( HMENU16 hmenu )
1852 return IsMenu( HMENU_32(hmenu) );
1856 /***********************************************************************
1857 * DCHook (USER.362)
1859 BOOL16 WINAPI DCHook16( HDC16 hdc, WORD code, DWORD data, LPARAM lParam )
1861 FIXME( "hDC = %x, %i: stub\n", hdc, code );
1862 return FALSE;
1866 /**********************************************************************
1867 * LookupIconIdFromDirectoryEx (USER.364)
1869 * FIXME: exact parameter sizes
1871 INT16 WINAPI LookupIconIdFromDirectoryEx16( LPBYTE dir, BOOL16 bIcon,
1872 INT16 width, INT16 height, UINT16 cFlag )
1874 return LookupIconIdFromDirectoryEx( dir, bIcon, width, height, cFlag );
1878 /***********************************************************************
1879 * CopyIcon (USER.368)
1881 HICON16 WINAPI CopyIcon16( HINSTANCE16 hInstance, HICON16 hIcon )
1883 CURSORICONINFO *info = get_icon_ptr( hIcon );
1884 void *and_bits = info + 1;
1885 void *xor_bits = (BYTE *)and_bits + info->nHeight * get_bitmap_width_bytes( info->nWidth, 1 );
1886 HGLOBAL16 ret = CreateCursorIconIndirect16( hInstance, info, and_bits, xor_bits );
1887 release_icon_ptr( hIcon, info );
1888 return ret;
1892 /***********************************************************************
1893 * CopyCursor (USER.369)
1895 HCURSOR16 WINAPI CopyCursor16( HINSTANCE16 hInstance, HCURSOR16 hCursor )
1897 CURSORICONINFO *info = get_icon_ptr( hCursor );
1898 void *and_bits = info + 1;
1899 void *xor_bits = (BYTE *)and_bits + info->nHeight * get_bitmap_width_bytes( info->nWidth, 1 );
1900 HGLOBAL16 ret = CreateCursorIconIndirect16( hInstance, info, and_bits, xor_bits );
1901 release_icon_ptr( hCursor, info );
1902 return ret;
1906 /***********************************************************************
1907 * SubtractRect (USER.373)
1909 BOOL16 WINAPI SubtractRect16( LPRECT16 dest, const RECT16 *src1,
1910 const RECT16 *src2 )
1912 RECT16 tmp;
1914 if (IsRectEmpty16( src1 ))
1916 SetRectEmpty16( dest );
1917 return FALSE;
1919 *dest = *src1;
1920 if (IntersectRect16( &tmp, src1, src2 ))
1922 if (EqualRect16( &tmp, dest ))
1924 SetRectEmpty16( dest );
1925 return FALSE;
1927 if ((tmp.top == dest->top) && (tmp.bottom == dest->bottom))
1929 if (tmp.left == dest->left) dest->left = tmp.right;
1930 else if (tmp.right == dest->right) dest->right = tmp.left;
1932 else if ((tmp.left == dest->left) && (tmp.right == dest->right))
1934 if (tmp.top == dest->top) dest->top = tmp.bottom;
1935 else if (tmp.bottom == dest->bottom) dest->bottom = tmp.top;
1938 return TRUE;
1942 /**********************************************************************
1943 * DllEntryPoint (USER.374)
1945 BOOL WINAPI DllEntryPoint( DWORD reason, HINSTANCE16 inst, WORD ds,
1946 WORD heap, DWORD reserved1, WORD reserved2 )
1948 if (reason != DLL_PROCESS_ATTACH) return TRUE;
1949 if (USER_HeapSel) return TRUE; /* already called */
1951 USER_HeapSel = ds;
1952 register_wow_handlers();
1953 LoadLibrary16( "display.drv" );
1954 LoadLibrary16( "keyboard.drv" );
1955 LoadLibrary16( "mouse.drv" );
1956 return TRUE;
1960 /**********************************************************************
1961 * SetMenuContextHelpId (USER.384)
1963 BOOL16 WINAPI SetMenuContextHelpId16( HMENU16 hMenu, DWORD dwContextHelpID)
1965 return SetMenuContextHelpId( HMENU_32(hMenu), dwContextHelpID );
1969 /**********************************************************************
1970 * GetMenuContextHelpId (USER.385)
1972 DWORD WINAPI GetMenuContextHelpId16( HMENU16 hMenu )
1974 return GetMenuContextHelpId( HMENU_32(hMenu) );
1978 /***********************************************************************
1979 * LoadImage (USER.389)
1981 HANDLE16 WINAPI LoadImage16(HINSTANCE16 hinst, LPCSTR name, UINT16 type, INT16 cx, INT16 cy, UINT16 flags)
1983 HGLOBAL16 handle;
1984 HRSRC16 hRsrc, hGroupRsrc;
1986 if (!hinst || (flags & LR_LOADFROMFILE))
1987 return HICON_16( LoadImageA( 0, name, type, cx, cy, flags ));
1989 hinst = GetExePtr( hinst );
1991 if (flags & LR_DEFAULTSIZE)
1993 if (type == IMAGE_ICON)
1995 if (!cx) cx = GetSystemMetrics(SM_CXICON);
1996 if (!cy) cy = GetSystemMetrics(SM_CYICON);
1998 else if (type == IMAGE_CURSOR)
2000 if (!cx) cx = GetSystemMetrics(SM_CXCURSOR);
2001 if (!cy) cy = GetSystemMetrics(SM_CYCURSOR);
2005 switch (type)
2007 case IMAGE_BITMAP:
2009 HBITMAP ret = 0;
2010 char *ptr;
2011 static const WCHAR prefixW[] = {'b','m','p',0};
2012 BITMAPFILEHEADER header;
2013 WCHAR path[MAX_PATH], filename[MAX_PATH];
2014 HANDLE file;
2015 DWORD size;
2017 filename[0] = 0;
2018 if (!(hRsrc = FindResource16( hinst, name, (LPCSTR)RT_BITMAP ))) return 0;
2019 if (!(handle = LoadResource16( hinst, hRsrc ))) return 0;
2020 if (!(ptr = LockResource16( handle ))) goto done;
2021 size = SizeofResource16( hinst, hRsrc );
2023 header.bfType = 0x4d42; /* 'BM' */
2024 header.bfReserved1 = 0;
2025 header.bfReserved2 = 0;
2026 header.bfSize = sizeof(header) + size;
2027 header.bfOffBits = 0; /* not used by the 32-bit loading code */
2029 if (!GetTempPathW( MAX_PATH, path )) goto done;
2030 if (!GetTempFileNameW( path, prefixW, 0, filename )) goto done;
2032 file = CreateFileW( filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0 );
2033 if (file != INVALID_HANDLE_VALUE)
2035 DWORD written;
2036 BOOL ok;
2037 ok = WriteFile( file, &header, sizeof(header), &written, NULL ) && (written == sizeof(header));
2038 if (ok) ok = WriteFile( file, ptr, size, &written, NULL ) && (written == size);
2039 CloseHandle( file );
2040 if (ok) ret = LoadImageW( 0, filename, IMAGE_BITMAP, cx, cy, flags | LR_LOADFROMFILE );
2042 done:
2043 if (filename[0]) DeleteFileW( filename );
2044 FreeResource16( handle );
2045 return HBITMAP_16( ret );
2048 case IMAGE_ICON:
2049 case IMAGE_CURSOR:
2051 HICON16 hIcon = 0;
2052 BYTE *dir, *bits;
2053 INT id = 0;
2055 if (!(hRsrc = FindResource16( hinst, name,
2056 (LPCSTR)(type == IMAGE_ICON ? RT_GROUP_ICON : RT_GROUP_CURSOR ))))
2057 return 0;
2058 hGroupRsrc = hRsrc;
2060 if (!(handle = LoadResource16( hinst, hRsrc ))) return 0;
2061 if ((dir = LockResource16( handle ))) id = LookupIconIdFromDirectory( dir, type == IMAGE_ICON );
2062 FreeResource16( handle );
2063 if (!id) return 0;
2065 if (!(hRsrc = FindResource16( hinst, MAKEINTRESOURCEA(id),
2066 (LPCSTR)(type == IMAGE_ICON ? RT_ICON : RT_CURSOR) ))) return 0;
2068 if ((flags & LR_SHARED) && (hIcon = find_shared_icon( hinst, hRsrc ) ) != 0) return hIcon;
2070 if (!(handle = LoadResource16( hinst, hRsrc ))) return 0;
2071 bits = LockResource16( handle );
2072 hIcon = CreateIconFromResourceEx16( bits, 0, type == IMAGE_ICON, 0x00030000, cx, cy, flags );
2073 FreeResource16( handle );
2075 if (hIcon && (flags & LR_SHARED)) add_shared_icon( hinst, hRsrc, hGroupRsrc, hIcon );
2076 return hIcon;
2078 default:
2079 return 0;
2083 /******************************************************************************
2084 * CopyImage (USER.390) Creates new image and copies attributes to it
2087 HICON16 WINAPI CopyImage16(HANDLE16 hnd, UINT16 type, INT16 desiredx,
2088 INT16 desiredy, UINT16 flags)
2090 if (flags & LR_COPYFROMRESOURCE) FIXME( "LR_COPYFROMRESOURCE not supported\n" );
2092 switch (type)
2094 case IMAGE_BITMAP:
2095 return HBITMAP_16( CopyImage( HBITMAP_32(hnd), type, desiredx, desiredy, flags ));
2096 case IMAGE_ICON:
2097 case IMAGE_CURSOR:
2098 return CopyIcon16( FarGetOwner16(hnd), hnd );
2099 default:
2100 return 0;
2104 /**********************************************************************
2105 * DrawIconEx (USER.394)
2107 BOOL16 WINAPI DrawIconEx16(HDC16 hdc, INT16 xLeft, INT16 yTop, HICON16 hIcon,
2108 INT16 cxWidth, INT16 cyWidth, UINT16 istep,
2109 HBRUSH16 hbr, UINT16 flags)
2111 return DrawIconEx(HDC_32(hdc), xLeft, yTop, HICON_32(hIcon), cxWidth, cyWidth,
2112 istep, HBRUSH_32(hbr), flags);
2115 /**********************************************************************
2116 * GetIconInfo (USER.395)
2118 BOOL16 WINAPI GetIconInfo16(HICON16 hIcon, LPICONINFO16 iconinfo)
2120 ICONINFO ii32;
2121 BOOL16 ret = GetIconInfo(HICON_32(hIcon), &ii32);
2123 iconinfo->fIcon = ii32.fIcon;
2124 iconinfo->xHotspot = ii32.xHotspot;
2125 iconinfo->yHotspot = ii32.yHotspot;
2126 iconinfo->hbmMask = HBITMAP_16(ii32.hbmMask);
2127 iconinfo->hbmColor = HBITMAP_16(ii32.hbmColor);
2128 return ret;
2132 /***********************************************************************
2133 * FinalUserInit (USER.400)
2135 void WINAPI FinalUserInit16( void )
2137 /* FIXME: Should chain to FinalGdiInit */
2141 /***********************************************************************
2142 * CreateCursor (USER.406)
2144 HCURSOR16 WINAPI CreateCursor16(HINSTANCE16 hInstance,
2145 INT16 xHotSpot, INT16 yHotSpot,
2146 INT16 nWidth, INT16 nHeight,
2147 LPCVOID lpANDbits, LPCVOID lpXORbits)
2149 CURSORICONINFO info;
2151 info.ptHotSpot.x = xHotSpot;
2152 info.ptHotSpot.y = yHotSpot;
2153 info.nWidth = nWidth;
2154 info.nHeight = nHeight;
2155 info.nWidthBytes = 0;
2156 info.bPlanes = 1;
2157 info.bBitsPerPixel = 1;
2159 return CreateCursorIconIndirect16(hInstance, &info, lpANDbits, lpXORbits);
2163 /***********************************************************************
2164 * CreateIcon (USER.407)
2166 HICON16 WINAPI CreateIcon16( HINSTANCE16 hInstance, INT16 nWidth,
2167 INT16 nHeight, BYTE bPlanes, BYTE bBitsPixel,
2168 LPCVOID lpANDbits, LPCVOID lpXORbits )
2170 static const WORD ICON_HOTSPOT = 0x4242;
2171 CURSORICONINFO info;
2173 info.ptHotSpot.x = ICON_HOTSPOT;
2174 info.ptHotSpot.y = ICON_HOTSPOT;
2175 info.nWidth = nWidth;
2176 info.nHeight = nHeight;
2177 info.nWidthBytes = 0;
2178 info.bPlanes = bPlanes;
2179 info.bBitsPerPixel = bBitsPixel;
2181 return CreateCursorIconIndirect16( hInstance, &info, lpANDbits, lpXORbits );
2185 /***********************************************************************
2186 * CreateCursorIconIndirect (USER.408)
2188 HGLOBAL16 WINAPI CreateCursorIconIndirect16( HINSTANCE16 hInstance,
2189 CURSORICONINFO *info,
2190 LPCVOID lpANDbits,
2191 LPCVOID lpXORbits )
2193 HICON16 handle;
2194 CURSORICONINFO *ptr;
2195 int sizeAnd, sizeXor;
2197 hInstance = GetExePtr( hInstance ); /* Make it a module handle */
2198 if (!lpXORbits || !lpANDbits || info->bPlanes != 1) return 0;
2199 info->nWidthBytes = get_bitmap_width_bytes(info->nWidth,info->bBitsPerPixel);
2200 sizeXor = info->nHeight * info->nWidthBytes;
2201 sizeAnd = info->nHeight * get_bitmap_width_bytes( info->nWidth, 1 );
2202 if (!(handle = alloc_icon_handle( sizeof(CURSORICONINFO) + sizeXor + sizeAnd )))
2203 return 0;
2204 FarSetOwner16( handle, hInstance );
2205 ptr = get_icon_ptr( handle );
2206 memcpy( ptr, info, sizeof(*info) );
2207 memcpy( ptr + 1, lpANDbits, sizeAnd );
2208 memcpy( (char *)(ptr + 1) + sizeAnd, lpXORbits, sizeXor );
2209 release_icon_ptr( handle, ptr );
2210 return handle;
2214 /***********************************************************************
2215 * InitThreadInput (USER.409)
2217 HQUEUE16 WINAPI InitThreadInput16( WORD unknown, WORD flags )
2219 /* nothing to do here */
2220 return 0xbeef;
2224 /*******************************************************************
2225 * InsertMenu (USER.410)
2227 BOOL16 WINAPI InsertMenu16( HMENU16 hMenu, UINT16 pos, UINT16 flags,
2228 UINT16 id, SEGPTR data )
2230 UINT pos32 = (UINT)pos;
2231 if ((pos == (UINT16)-1) && (flags & MF_BYPOSITION)) pos32 = (UINT)-1;
2232 if (IS_MENU_STRING_ITEM(flags) && data)
2233 return InsertMenuA( HMENU_32(hMenu), pos32, flags, id, MapSL(data) );
2234 return InsertMenuA( HMENU_32(hMenu), pos32, flags, id, (LPSTR)data );
2238 /*******************************************************************
2239 * AppendMenu (USER.411)
2241 BOOL16 WINAPI AppendMenu16(HMENU16 hMenu, UINT16 flags, UINT16 id, SEGPTR data)
2243 return InsertMenu16( hMenu, -1, flags | MF_BYPOSITION, id, data );
2247 /**********************************************************************
2248 * RemoveMenu (USER.412)
2250 BOOL16 WINAPI RemoveMenu16( HMENU16 hMenu, UINT16 nPos, UINT16 wFlags )
2252 return RemoveMenu( HMENU_32(hMenu), nPos, wFlags );
2256 /**********************************************************************
2257 * DeleteMenu (USER.413)
2259 BOOL16 WINAPI DeleteMenu16( HMENU16 hMenu, UINT16 nPos, UINT16 wFlags )
2261 return DeleteMenu( HMENU_32(hMenu), nPos, wFlags );
2265 /*******************************************************************
2266 * ModifyMenu (USER.414)
2268 BOOL16 WINAPI ModifyMenu16( HMENU16 hMenu, UINT16 pos, UINT16 flags,
2269 UINT16 id, SEGPTR data )
2271 if (IS_MENU_STRING_ITEM(flags))
2272 return ModifyMenuA( HMENU_32(hMenu), pos, flags, id, MapSL(data) );
2273 return ModifyMenuA( HMENU_32(hMenu), pos, flags, id, (LPSTR)data );
2277 /**********************************************************************
2278 * CreatePopupMenu (USER.415)
2280 HMENU16 WINAPI CreatePopupMenu16(void)
2282 return HMENU_16( CreatePopupMenu() );
2286 /**********************************************************************
2287 * SetMenuItemBitmaps (USER.418)
2289 BOOL16 WINAPI SetMenuItemBitmaps16( HMENU16 hMenu, UINT16 nPos, UINT16 wFlags,
2290 HBITMAP16 hNewUnCheck, HBITMAP16 hNewCheck)
2292 return SetMenuItemBitmaps( HMENU_32(hMenu), nPos, wFlags,
2293 HBITMAP_32(hNewUnCheck), HBITMAP_32(hNewCheck) );
2297 /***********************************************************************
2298 * wvsprintf (USER.421)
2300 INT16 WINAPI wvsprintf16( LPSTR buffer, LPCSTR spec, VA_LIST16 args )
2302 WPRINTF_FORMAT format;
2303 LPSTR p = buffer;
2304 UINT i, len, sign;
2305 CHAR number[20];
2306 CHAR char_view = 0;
2307 LPCSTR lpcstr_view = NULL;
2308 INT int_view;
2309 SEGPTR seg_str;
2311 while (*spec)
2313 if (*spec != '%') { *p++ = *spec++; continue; }
2314 spec++;
2315 if (*spec == '%') { *p++ = *spec++; continue; }
2316 spec += parse_format( spec, &format );
2317 switch(format.type)
2319 case WPR_CHAR:
2320 char_view = VA_ARG16( args, CHAR );
2321 len = format.precision = 1;
2322 break;
2323 case WPR_STRING:
2324 seg_str = VA_ARG16( args, SEGPTR );
2325 if (IsBadReadPtr16( seg_str, 1 )) lpcstr_view = "";
2326 else lpcstr_view = MapSL( seg_str );
2327 if (!lpcstr_view) lpcstr_view = "(null)";
2328 for (len = 0; !format.precision || (len < format.precision); len++)
2329 if (!lpcstr_view[len]) break;
2330 format.precision = len;
2331 break;
2332 case WPR_SIGNED:
2333 if (format.flags & WPRINTF_LONG) int_view = VA_ARG16( args, INT );
2334 else int_view = VA_ARG16( args, INT16 );
2335 len = sprintf( number, "%d", int_view );
2336 break;
2337 case WPR_UNSIGNED:
2338 if (format.flags & WPRINTF_LONG) int_view = VA_ARG16( args, UINT );
2339 else int_view = VA_ARG16( args, UINT16 );
2340 len = sprintf( number, "%u", int_view );
2341 break;
2342 case WPR_HEXA:
2343 if (format.flags & WPRINTF_LONG) int_view = VA_ARG16( args, UINT );
2344 else int_view = VA_ARG16( args, UINT16 );
2345 len = sprintf( number, (format.flags & WPRINTF_UPPER_HEX) ? "%X" : "%x", int_view);
2346 break;
2347 case WPR_UNKNOWN:
2348 continue;
2350 if (format.precision < len) format.precision = len;
2351 if (format.flags & WPRINTF_LEFTALIGN) format.flags &= ~WPRINTF_ZEROPAD;
2352 if ((format.flags & WPRINTF_ZEROPAD) && (format.width > format.precision))
2353 format.precision = format.width;
2354 if (format.flags & WPRINTF_PREFIX_HEX) len += 2;
2356 sign = 0;
2357 if (!(format.flags & WPRINTF_LEFTALIGN))
2358 for (i = format.precision; i < format.width; i++) *p++ = ' ';
2359 switch(format.type)
2361 case WPR_CHAR:
2362 *p = char_view;
2363 /* wsprintf16 ignores null characters */
2364 if (*p != '\0') p++;
2365 else if (format.width > 1) *p++ = ' ';
2366 else len = 0;
2367 break;
2368 case WPR_STRING:
2369 if (len) memcpy( p, lpcstr_view, len );
2370 p += len;
2371 break;
2372 case WPR_HEXA:
2373 if (format.flags & WPRINTF_PREFIX_HEX)
2375 *p++ = '0';
2376 *p++ = (format.flags & WPRINTF_UPPER_HEX) ? 'X' : 'x';
2377 len -= 2;
2379 /* fall through */
2380 case WPR_SIGNED:
2381 /* Transfer the sign now, just in case it will be zero-padded*/
2382 if (number[0] == '-')
2384 *p++ = '-';
2385 sign = 1;
2387 /* fall through */
2388 case WPR_UNSIGNED:
2389 for (i = len; i < format.precision; i++) *p++ = '0';
2390 if (len > sign) memcpy( p, number + sign, len - sign );
2391 p += len-sign;
2392 break;
2393 case WPR_UNKNOWN:
2394 continue;
2396 if (format.flags & WPRINTF_LEFTALIGN)
2397 for (i = format.precision; i < format.width; i++) *p++ = ' ';
2399 *p = 0;
2400 return p - buffer;
2404 /***********************************************************************
2405 * _wsprintf (USER.420)
2407 INT16 WINAPIV wsprintf16( LPSTR buffer, LPCSTR spec, VA_LIST16 valist )
2409 return wvsprintf16( buffer, spec, valist );
2413 /***********************************************************************
2414 * lstrcmp (USER.430)
2416 INT16 WINAPI lstrcmp16( LPCSTR str1, LPCSTR str2 )
2418 return strcmp( str1, str2 );
2422 /***********************************************************************
2423 * AnsiUpper (USER.431)
2425 SEGPTR WINAPI AnsiUpper16( SEGPTR strOrChar )
2427 /* uppercase only one char if strOrChar < 0x10000 */
2428 if (HIWORD(strOrChar))
2430 CharUpperA( MapSL(strOrChar) );
2431 return strOrChar;
2433 else return (SEGPTR)CharUpperA( (LPSTR)strOrChar );
2437 /***********************************************************************
2438 * AnsiLower (USER.432)
2440 SEGPTR WINAPI AnsiLower16( SEGPTR strOrChar )
2442 /* lowercase only one char if strOrChar < 0x10000 */
2443 if (HIWORD(strOrChar))
2445 CharLowerA( MapSL(strOrChar) );
2446 return strOrChar;
2448 else return (SEGPTR)CharLowerA( (LPSTR)strOrChar );
2452 /***********************************************************************
2453 * AnsiUpperBuff (USER.437)
2455 UINT16 WINAPI AnsiUpperBuff16( LPSTR str, UINT16 len )
2457 CharUpperBuffA( str, len ? len : 65536 );
2458 return len;
2462 /***********************************************************************
2463 * AnsiLowerBuff (USER.438)
2465 UINT16 WINAPI AnsiLowerBuff16( LPSTR str, UINT16 len )
2467 CharLowerBuffA( str, len ? len : 65536 );
2468 return len;
2472 /*******************************************************************
2473 * InsertMenuItem (USER.441)
2475 * FIXME: untested
2477 BOOL16 WINAPI InsertMenuItem16( HMENU16 hmenu, UINT16 pos, BOOL16 byposition,
2478 const MENUITEMINFO16 *mii )
2480 MENUITEMINFOA miia;
2482 miia.cbSize = sizeof(miia);
2483 miia.fMask = mii->fMask;
2484 miia.dwTypeData = (LPSTR)mii->dwTypeData;
2485 miia.fType = mii->fType;
2486 miia.fState = mii->fState;
2487 miia.wID = mii->wID;
2488 miia.hSubMenu = HMENU_32(mii->hSubMenu);
2489 miia.hbmpChecked = HBITMAP_32(mii->hbmpChecked);
2490 miia.hbmpUnchecked = HBITMAP_32(mii->hbmpUnchecked);
2491 miia.dwItemData = mii->dwItemData;
2492 miia.cch = mii->cch;
2493 if (IS_MENU_STRING_ITEM(miia.fType))
2494 miia.dwTypeData = MapSL(mii->dwTypeData);
2495 return InsertMenuItemA( HMENU_32(hmenu), pos, byposition, &miia );
2499 /**********************************************************************
2500 * DrawState (USER.449)
2502 BOOL16 WINAPI DrawState16( HDC16 hdc, HBRUSH16 hbr, DRAWSTATEPROC16 func, LPARAM ldata,
2503 WPARAM16 wdata, INT16 x, INT16 y, INT16 cx, INT16 cy, UINT16 flags )
2505 struct draw_state_info info;
2506 UINT opcode = flags & 0xf;
2508 if (opcode == DST_TEXT || opcode == DST_PREFIXTEXT)
2510 /* make sure DrawStateA doesn't try to use ldata as a pointer */
2511 if (!wdata) wdata = strlen( MapSL(ldata) );
2512 if (!cx || !cy)
2514 SIZE s;
2515 if (!GetTextExtentPoint32A( HDC_32(hdc), MapSL(ldata), wdata, &s )) return FALSE;
2516 if (!cx) cx = s.cx;
2517 if (!cy) cy = s.cy;
2520 info.proc = func;
2521 info.param = ldata;
2522 return DrawStateA( HDC_32(hdc), HBRUSH_32(hbr), draw_state_callback,
2523 (LPARAM)&info, wdata, x, y, cx, cy, flags );
2527 /**********************************************************************
2528 * CreateIconFromResourceEx (USER.450)
2530 * FIXME: not sure about exact parameter types
2532 HICON16 WINAPI CreateIconFromResourceEx16(LPBYTE bits, UINT16 cbSize,
2533 BOOL16 bIcon, DWORD dwVersion,
2534 INT16 width, INT16 height,
2535 UINT16 cFlag)
2537 return HICON_16(CreateIconFromResourceEx(bits, cbSize, bIcon, dwVersion,
2538 width, height, cFlag));
2542 /***********************************************************************
2543 * AdjustWindowRectEx (USER.454)
2545 BOOL16 WINAPI AdjustWindowRectEx16( LPRECT16 rect, DWORD style, BOOL16 menu, DWORD exStyle )
2547 RECT rect32;
2548 BOOL ret;
2550 rect32.left = rect->left;
2551 rect32.top = rect->top;
2552 rect32.right = rect->right;
2553 rect32.bottom = rect->bottom;
2554 ret = AdjustWindowRectEx( &rect32, style, menu, exStyle );
2555 rect->left = rect32.left;
2556 rect->top = rect32.top;
2557 rect->right = rect32.right;
2558 rect->bottom = rect32.bottom;
2559 return ret;
2563 /**********************************************************************
2564 * GetIconID (USER.455)
2566 WORD WINAPI GetIconID16( HGLOBAL16 hResource, DWORD resType )
2568 BYTE *dir = GlobalLock16(hResource);
2570 switch (resType)
2572 case RT_CURSOR:
2573 return LookupIconIdFromDirectoryEx16( dir, FALSE, GetSystemMetrics(SM_CXCURSOR),
2574 GetSystemMetrics(SM_CYCURSOR), LR_MONOCHROME );
2575 case RT_ICON:
2576 return LookupIconIdFromDirectoryEx16( dir, TRUE, GetSystemMetrics(SM_CXICON),
2577 GetSystemMetrics(SM_CYICON), 0 );
2579 return 0;
2583 /**********************************************************************
2584 * LoadIconHandler (USER.456)
2586 HICON16 WINAPI LoadIconHandler16( HGLOBAL16 hResource, BOOL16 bNew )
2588 LPBYTE bits = LockResource16( hResource );
2589 return HICON_16(CreateIconFromResourceEx( bits, 0, TRUE,
2590 bNew ? 0x00030000 : 0x00020000, 0, 0, LR_DEFAULTCOLOR));
2594 /***********************************************************************
2595 * DestroyIcon (USER.457)
2597 BOOL16 WINAPI DestroyIcon16(HICON16 hIcon)
2599 int count;
2601 TRACE("%04x\n", hIcon );
2603 count = release_shared_icon( hIcon );
2604 if (count != -1) return !count;
2605 /* assume non-shared */
2606 free_icon_handle( hIcon );
2607 return TRUE;
2610 /***********************************************************************
2611 * DestroyCursor (USER.458)
2613 BOOL16 WINAPI DestroyCursor16(HCURSOR16 hCursor)
2615 return DestroyIcon16( hCursor );
2619 /***********************************************************************
2620 * DumpIcon (USER.459)
2622 DWORD WINAPI DumpIcon16( SEGPTR pInfo, WORD *lpLen,
2623 SEGPTR *lpXorBits, SEGPTR *lpAndBits )
2625 CURSORICONINFO *info = MapSL( pInfo );
2626 int sizeAnd, sizeXor;
2628 if (!info) return 0;
2629 sizeXor = info->nHeight * info->nWidthBytes;
2630 sizeAnd = info->nHeight * get_bitmap_width_bytes( info->nWidth, 1 );
2631 if (lpAndBits) *lpAndBits = pInfo + sizeof(CURSORICONINFO);
2632 if (lpXorBits) *lpXorBits = pInfo + sizeof(CURSORICONINFO) + sizeAnd;
2633 if (lpLen) *lpLen = sizeof(CURSORICONINFO) + sizeAnd + sizeXor;
2634 return MAKELONG( sizeXor, sizeXor );
2638 /*******************************************************************
2639 * DRAG_QueryUpdate16
2641 * Recursively find a child that contains spDragInfo->pt point
2642 * and send WM_QUERYDROPOBJECT. Helper for DragObject16.
2644 static BOOL DRAG_QueryUpdate16( HWND hQueryWnd, SEGPTR spDragInfo )
2646 BOOL bResult = 0;
2647 WPARAM wParam;
2648 POINT pt, old_pt;
2649 LPDRAGINFO16 ptrDragInfo = MapSL(spDragInfo);
2650 RECT tempRect;
2651 HWND child;
2653 if (!IsWindowEnabled(hQueryWnd)) return FALSE;
2655 old_pt.x = ptrDragInfo->pt.x;
2656 old_pt.y = ptrDragInfo->pt.y;
2657 pt = old_pt;
2658 ScreenToClient( hQueryWnd, &pt );
2659 child = ChildWindowFromPointEx( hQueryWnd, pt, CWP_SKIPINVISIBLE );
2660 if (!child) return FALSE;
2662 if (child != hQueryWnd)
2664 wParam = 0;
2665 if (DRAG_QueryUpdate16( child, spDragInfo )) return TRUE;
2667 else
2669 GetClientRect( hQueryWnd, &tempRect );
2670 wParam = !PtInRect( &tempRect, pt );
2673 ptrDragInfo->pt.x = pt.x;
2674 ptrDragInfo->pt.y = pt.y;
2675 ptrDragInfo->hScope = HWND_16(hQueryWnd);
2677 bResult = SendMessage16( HWND_16(hQueryWnd), WM_QUERYDROPOBJECT, wParam, spDragInfo );
2679 if (!bResult)
2681 ptrDragInfo->pt.x = old_pt.x;
2682 ptrDragInfo->pt.y = old_pt.y;
2684 return bResult;
2688 /******************************************************************************
2689 * DragObject (USER.464)
2691 DWORD WINAPI DragObject16( HWND16 hwndScope, HWND16 hWnd, UINT16 wObj,
2692 HANDLE16 hOfStruct, WORD szList, HCURSOR16 hCursor )
2694 MSG msg;
2695 LPDRAGINFO16 lpDragInfo;
2696 SEGPTR spDragInfo;
2697 HCURSOR hOldCursor=0, hBummer=0;
2698 HGLOBAL16 hDragInfo = GlobalAlloc16( GMEM_SHARE | GMEM_ZEROINIT, 2*sizeof(DRAGINFO16));
2699 HCURSOR hCurrentCursor = 0;
2700 HWND16 hCurrentWnd = 0;
2702 lpDragInfo = (LPDRAGINFO16) GlobalLock16(hDragInfo);
2703 spDragInfo = WOWGlobalLock16(hDragInfo);
2705 if( !lpDragInfo || !spDragInfo ) return 0L;
2707 if (!(hBummer = LoadCursorA(0, MAKEINTRESOURCEA(OCR_NO))))
2709 GlobalFree16(hDragInfo);
2710 return 0L;
2713 if(hCursor) hOldCursor = SetCursor(HCURSOR_32(hCursor));
2715 lpDragInfo->hWnd = hWnd;
2716 lpDragInfo->hScope = 0;
2717 lpDragInfo->wFlags = wObj;
2718 lpDragInfo->hList = szList; /* near pointer! */
2719 lpDragInfo->hOfStruct = hOfStruct;
2720 lpDragInfo->l = 0L;
2722 SetCapture( HWND_32(hWnd) );
2723 ShowCursor( TRUE );
2727 GetMessageW( &msg, 0, WM_MOUSEFIRST, WM_MOUSELAST );
2729 *(lpDragInfo+1) = *lpDragInfo;
2731 lpDragInfo->pt.x = msg.pt.x;
2732 lpDragInfo->pt.y = msg.pt.y;
2734 /* update DRAGINFO struct */
2735 if( DRAG_QueryUpdate16(WIN_Handle32(hwndScope), spDragInfo) > 0 )
2736 hCurrentCursor = HCURSOR_32(hCursor);
2737 else
2739 hCurrentCursor = hBummer;
2740 lpDragInfo->hScope = 0;
2742 if( hCurrentCursor )
2743 SetCursor(hCurrentCursor);
2745 /* send WM_DRAGLOOP */
2746 SendMessage16( hWnd, WM_DRAGLOOP, (WPARAM16)(hCurrentCursor != hBummer),
2747 (LPARAM) spDragInfo );
2748 /* send WM_DRAGSELECT or WM_DRAGMOVE */
2749 if( hCurrentWnd != lpDragInfo->hScope )
2751 if( hCurrentWnd )
2752 SendMessage16( hCurrentWnd, WM_DRAGSELECT, 0,
2753 (LPARAM)MAKELONG(LOWORD(spDragInfo)+sizeof(DRAGINFO16),
2754 HIWORD(spDragInfo)) );
2755 hCurrentWnd = lpDragInfo->hScope;
2756 if( hCurrentWnd )
2757 SendMessage16( hCurrentWnd, WM_DRAGSELECT, 1, (LPARAM)spDragInfo);
2759 else
2760 if( hCurrentWnd )
2761 SendMessage16( hCurrentWnd, WM_DRAGMOVE, 0, (LPARAM)spDragInfo);
2763 } while( msg.message != WM_LBUTTONUP && msg.message != WM_NCLBUTTONUP );
2765 ReleaseCapture();
2766 ShowCursor( FALSE );
2768 if( hCursor ) SetCursor(hOldCursor);
2770 if( hCurrentCursor != hBummer )
2771 msg.lParam = SendMessage16( lpDragInfo->hScope, WM_DROPOBJECT,
2772 (WPARAM16)hWnd, (LPARAM)spDragInfo );
2773 else
2774 msg.lParam = 0;
2775 GlobalFree16(hDragInfo);
2777 return (DWORD)(msg.lParam);
2781 /***********************************************************************
2782 * DrawFocusRect (USER.466)
2784 void WINAPI DrawFocusRect16( HDC16 hdc, const RECT16* rc )
2786 RECT rect32;
2788 rect32.left = rc->left;
2789 rect32.top = rc->top;
2790 rect32.right = rc->right;
2791 rect32.bottom = rc->bottom;
2792 DrawFocusRect( HDC_32(hdc), &rect32 );
2796 /***********************************************************************
2797 * AnsiNext (USER.472)
2799 SEGPTR WINAPI AnsiNext16(SEGPTR current)
2801 char *ptr = MapSL(current);
2802 return current + (CharNextA(ptr) - ptr);
2806 /***********************************************************************
2807 * AnsiPrev (USER.473)
2809 SEGPTR WINAPI AnsiPrev16( LPCSTR start, SEGPTR current )
2811 char *ptr = MapSL(current);
2812 return current - (ptr - CharPrevA( start, ptr ));
2816 /****************************************************************************
2817 * GetKeyboardLayoutName (USER.477)
2819 INT16 WINAPI GetKeyboardLayoutName16( LPSTR name )
2821 return GetKeyboardLayoutNameA( name );
2825 /***********************************************************************
2826 * SystemParametersInfo (USER.483)
2828 BOOL16 WINAPI SystemParametersInfo16( UINT16 uAction, UINT16 uParam,
2829 LPVOID lpvParam, UINT16 fuWinIni )
2831 BOOL16 ret;
2833 TRACE("(%u, %u, %p, %u)\n", uAction, uParam, lpvParam, fuWinIni);
2835 switch (uAction)
2837 case SPI_GETBEEP:
2838 case SPI_GETSCREENSAVEACTIVE:
2839 case SPI_GETICONTITLEWRAP:
2840 case SPI_GETMENUDROPALIGNMENT:
2841 case SPI_GETFASTTASKSWITCH:
2842 case SPI_GETDRAGFULLWINDOWS:
2844 BOOL tmp;
2845 ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
2846 if (ret && lpvParam) *(BOOL16 *)lpvParam = tmp;
2847 break;
2850 case SPI_GETBORDER:
2851 case SPI_ICONHORIZONTALSPACING:
2852 case SPI_GETSCREENSAVETIMEOUT:
2853 case SPI_GETGRIDGRANULARITY:
2854 case SPI_GETKEYBOARDDELAY:
2855 case SPI_ICONVERTICALSPACING:
2857 INT tmp;
2858 ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
2859 if (ret && lpvParam) *(INT16 *)lpvParam = tmp;
2860 break;
2863 case SPI_GETKEYBOARDSPEED:
2864 case SPI_GETMOUSEHOVERWIDTH:
2865 case SPI_GETMOUSEHOVERHEIGHT:
2866 case SPI_GETMOUSEHOVERTIME:
2868 DWORD tmp;
2869 ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
2870 if (ret && lpvParam) *(WORD *)lpvParam = tmp;
2871 break;
2874 case SPI_GETICONTITLELOGFONT:
2876 LOGFONTA tmp;
2877 ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
2878 if (ret && lpvParam) logfont_32_to_16( &tmp, (LPLOGFONT16)lpvParam );
2879 break;
2882 case SPI_GETNONCLIENTMETRICS:
2884 NONCLIENTMETRICSA tmp;
2885 LPNONCLIENTMETRICS16 lpnm16 = (LPNONCLIENTMETRICS16)lpvParam;
2886 if (lpnm16 && lpnm16->cbSize == sizeof(NONCLIENTMETRICS16))
2888 tmp.cbSize = sizeof(NONCLIENTMETRICSA);
2889 ret = SystemParametersInfoA( uAction, uParam, &tmp, fuWinIni );
2890 if (ret)
2892 lpnm16->iBorderWidth = tmp.iBorderWidth;
2893 lpnm16->iScrollWidth = tmp.iScrollWidth;
2894 lpnm16->iScrollHeight = tmp.iScrollHeight;
2895 lpnm16->iCaptionWidth = tmp.iCaptionWidth;
2896 lpnm16->iCaptionHeight = tmp.iCaptionHeight;
2897 lpnm16->iSmCaptionWidth = tmp.iSmCaptionWidth;
2898 lpnm16->iSmCaptionHeight = tmp.iSmCaptionHeight;
2899 lpnm16->iMenuWidth = tmp.iMenuWidth;
2900 lpnm16->iMenuHeight = tmp.iMenuHeight;
2901 logfont_32_to_16( &tmp.lfCaptionFont, &lpnm16->lfCaptionFont );
2902 logfont_32_to_16( &tmp.lfSmCaptionFont, &lpnm16->lfSmCaptionFont );
2903 logfont_32_to_16( &tmp.lfMenuFont, &lpnm16->lfMenuFont );
2904 logfont_32_to_16( &tmp.lfStatusFont, &lpnm16->lfStatusFont );
2905 logfont_32_to_16( &tmp.lfMessageFont, &lpnm16->lfMessageFont );
2908 else /* winfile 95 sets cbSize to 340 */
2909 ret = SystemParametersInfoA( uAction, uParam, lpvParam, fuWinIni );
2910 break;
2913 case SPI_GETWORKAREA:
2915 RECT tmp;
2916 ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
2917 if (ret && lpvParam)
2919 RECT16 *r16 = lpvParam;
2920 r16->left = tmp.left;
2921 r16->top = tmp.top;
2922 r16->right = tmp.right;
2923 r16->bottom = tmp.bottom;
2925 break;
2928 default:
2929 ret = SystemParametersInfoA( uAction, uParam, lpvParam, fuWinIni );
2930 break;
2933 return ret;
2937 /***********************************************************************
2938 * USER_489 (USER.489)
2940 LONG WINAPI stub_USER_489(void)
2942 FIXME("stub\n");
2943 return 0;
2947 /***********************************************************************
2948 * USER_490 (USER.490)
2950 LONG WINAPI stub_USER_490(void)
2952 FIXME("stub\n");
2953 return 0;
2957 /***********************************************************************
2958 * USER_492 (USER.492)
2960 LONG WINAPI stub_USER_492(void)
2962 FIXME("stub\n");
2963 return 0;
2967 /***********************************************************************
2968 * USER_496 (USER.496)
2970 LONG WINAPI stub_USER_496(void)
2972 FIXME("stub\n");
2973 return 0;
2977 /***********************************************************************
2978 * FormatMessage (USER.606)
2980 DWORD WINAPI FormatMessage16(
2981 DWORD dwFlags,
2982 SEGPTR lpSource, /* [in] NOTE: not always a valid pointer */
2983 WORD dwMessageId,
2984 WORD dwLanguageId,
2985 LPSTR lpBuffer, /* [out] NOTE: *((HLOCAL16*)) for FORMAT_MESSAGE_ALLOCATE_BUFFER*/
2986 WORD nSize,
2987 LPDWORD args ) /* [in] NOTE: va_list *args */
2989 /* This implementation is completely dependent on the format of the va_list on x86 CPUs */
2990 LPSTR target,t;
2991 DWORD talloced;
2992 LPSTR from,f;
2993 DWORD width = dwFlags & FORMAT_MESSAGE_MAX_WIDTH_MASK;
2994 BOOL eos = FALSE;
2995 LPSTR allocstring = NULL;
2997 TRACE("(0x%x,%x,%d,0x%x,%p,%d,%p)\n",
2998 dwFlags,lpSource,dwMessageId,dwLanguageId,lpBuffer,nSize,args);
2999 if ((dwFlags & FORMAT_MESSAGE_FROM_SYSTEM)
3000 && (dwFlags & FORMAT_MESSAGE_FROM_HMODULE)) return 0;
3001 if ((dwFlags & FORMAT_MESSAGE_FROM_STRING)
3002 &&((dwFlags & FORMAT_MESSAGE_FROM_SYSTEM)
3003 || (dwFlags & FORMAT_MESSAGE_FROM_HMODULE))) return 0;
3005 if (width && width != FORMAT_MESSAGE_MAX_WIDTH_MASK)
3006 FIXME("line wrapping (%u) not supported.\n", width);
3007 from = NULL;
3008 if (dwFlags & FORMAT_MESSAGE_FROM_STRING)
3010 char *source = MapSL(lpSource);
3011 from = HeapAlloc( GetProcessHeap(), 0, strlen(source)+1 );
3012 strcpy( from, source );
3014 else if (dwFlags & FORMAT_MESSAGE_FROM_SYSTEM) {
3015 from = HeapAlloc( GetProcessHeap(),0,200 );
3016 sprintf(from,"Systemmessage, messageid = 0x%08x\n",dwMessageId);
3018 else if (dwFlags & FORMAT_MESSAGE_FROM_HMODULE) {
3019 INT16 bufsize;
3020 HINSTANCE16 hinst16 = ((HINSTANCE16)lpSource & 0xffff);
3022 dwMessageId &= 0xFFFF;
3023 bufsize=LoadString16(hinst16,dwMessageId,NULL,0);
3024 if (bufsize) {
3025 from = HeapAlloc( GetProcessHeap(), 0, bufsize +1);
3026 LoadString16(hinst16,dwMessageId,from,bufsize+1);
3029 target = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, 100);
3030 t = target;
3031 talloced= 100;
3033 #define ADD_TO_T(c) \
3034 *t++=c;\
3035 if (t-target == talloced) {\
3036 target = HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,target,talloced*2);\
3037 t = target+talloced;\
3038 talloced*=2;\
3041 if (from) {
3042 f=from;
3043 while (*f && !eos) {
3044 if (*f=='%') {
3045 int insertnr;
3046 char *fmtstr,*x,*lastf;
3047 DWORD *argliststart;
3049 fmtstr = NULL;
3050 lastf = f;
3051 f++;
3052 if (!*f) {
3053 ADD_TO_T('%');
3054 continue;
3056 switch (*f) {
3057 case '1':case '2':case '3':case '4':case '5':
3058 case '6':case '7':case '8':case '9':
3059 insertnr=*f-'0';
3060 switch (f[1]) {
3061 case '0':case '1':case '2':case '3':
3062 case '4':case '5':case '6':case '7':
3063 case '8':case '9':
3064 f++;
3065 insertnr=insertnr*10+*f-'0';
3066 f++;
3067 break;
3068 default:
3069 f++;
3070 break;
3072 if (*f=='!') {
3073 f++;
3074 if (NULL!=(x=strchr(f,'!'))) {
3075 *x='\0';
3076 fmtstr=HeapAlloc(GetProcessHeap(),0,strlen(f)+2);
3077 sprintf(fmtstr,"%%%s",f);
3078 f=x+1;
3079 } else {
3080 fmtstr=HeapAlloc(GetProcessHeap(),0,strlen(f)+2);
3081 sprintf(fmtstr,"%%%s",f);
3082 f+=strlen(f); /*at \0*/
3085 else
3087 if(!args) break;
3088 fmtstr=HeapAlloc( GetProcessHeap(), 0, 3 );
3089 strcpy( fmtstr, "%s" );
3091 if (args) {
3092 int ret;
3093 int sz;
3094 LPSTR b = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sz = 100);
3096 argliststart=args+insertnr-1;
3098 /* CMF - This makes a BIG assumption about va_list */
3099 while ((ret = vsnprintf(b, sz, fmtstr, (va_list) argliststart) < 0) || (ret >= sz)) {
3100 sz = (ret == -1 ? sz + 100 : ret + 1);
3101 b = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, b, sz);
3103 for (x=b; *x; x++) ADD_TO_T(*x);
3104 HeapFree(GetProcessHeap(), 0, b);
3105 } else {
3106 /* NULL args - copy formatstr
3107 * (probably wrong)
3109 while ((lastf<f)&&(*lastf)) {
3110 ADD_TO_T(*lastf++);
3113 HeapFree(GetProcessHeap(),0,fmtstr);
3114 break;
3115 case '0': /* Just stop processing format string */
3116 eos = TRUE;
3117 f++;
3118 break;
3119 case 'n': /* 16 bit version just outputs 'n' */
3120 default:
3121 ADD_TO_T(*f++);
3122 break;
3124 } else { /* '\n' or '\r' gets mapped to "\r\n" */
3125 if(*f == '\n' || *f == '\r') {
3126 if (width == 0) {
3127 ADD_TO_T('\r');
3128 ADD_TO_T('\n');
3129 if(*f++ == '\r' && *f == '\n')
3130 f++;
3132 } else {
3133 ADD_TO_T(*f++);
3137 *t='\0';
3139 talloced = strlen(target)+1;
3140 if (nSize && talloced<nSize) {
3141 target = HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,target,nSize);
3143 TRACE("-- %s\n",debugstr_a(target));
3144 if (dwFlags & FORMAT_MESSAGE_ALLOCATE_BUFFER) {
3145 /* nSize is the MINIMUM size */
3146 HLOCAL16 h = LocalAlloc16(LPTR,talloced);
3147 SEGPTR ptr = LocalLock16(h);
3148 allocstring = MapSL( ptr );
3149 memcpy( allocstring,target,talloced);
3150 LocalUnlock16( h );
3151 *((HLOCAL16*)lpBuffer) = h;
3152 } else
3153 lstrcpynA(lpBuffer,target,nSize);
3154 HeapFree(GetProcessHeap(),0,target);
3155 HeapFree(GetProcessHeap(),0,from);
3156 return (dwFlags & FORMAT_MESSAGE_ALLOCATE_BUFFER) ?
3157 strlen(allocstring):
3158 strlen(lpBuffer);
3160 #undef ADD_TO_T
3163 /**********************************************************************
3164 * DestroyIcon32 (USER.610)
3166 * This routine is actually exported from Win95 USER under the name
3167 * DestroyIcon32 ... The behaviour implemented here should mimic
3168 * the Win95 one exactly, especially the return values, which
3169 * depend on the setting of various flags.
3171 WORD WINAPI DestroyIcon32( HGLOBAL16 handle, UINT16 flags )
3173 WORD retv;
3175 /* Check whether destroying active cursor */
3177 if (GetCursor16() == handle)
3179 WARN("Destroying active cursor!\n" );
3180 return FALSE;
3183 /* Try shared cursor/icon first */
3185 if (!(flags & CID_NONSHARED))
3187 INT count = release_shared_icon( handle );
3188 if (count != -1)
3189 return (flags & CID_WIN32) ? TRUE : (count == 0);
3192 /* Now assume non-shared cursor/icon */
3194 retv = free_icon_handle( handle );
3195 return (flags & CID_RESOURCE)? retv : TRUE;
3199 /***********************************************************************
3200 * ChangeDisplaySettings (USER.620)
3202 LONG WINAPI ChangeDisplaySettings16( LPDEVMODEA devmode, DWORD flags )
3204 return ChangeDisplaySettingsA( devmode, flags );
3208 /***********************************************************************
3209 * EnumDisplaySettings (USER.621)
3211 BOOL16 WINAPI EnumDisplaySettings16( LPCSTR name, DWORD n, LPDEVMODEA devmode )
3213 return EnumDisplaySettingsA( name, n, devmode );
3216 /**********************************************************************
3217 * DrawFrameControl (USER.656)
3219 BOOL16 WINAPI DrawFrameControl16( HDC16 hdc, LPRECT16 rc, UINT16 uType, UINT16 uState )
3221 RECT rect32;
3222 BOOL ret;
3224 rect32.left = rc->left;
3225 rect32.top = rc->top;
3226 rect32.right = rc->right;
3227 rect32.bottom = rc->bottom;
3228 ret = DrawFrameControl( HDC_32(hdc), &rect32, uType, uState );
3229 rc->left = rect32.left;
3230 rc->top = rect32.top;
3231 rc->right = rect32.right;
3232 rc->bottom = rect32.bottom;
3233 return ret;
3236 /**********************************************************************
3237 * DrawEdge (USER.659)
3239 BOOL16 WINAPI DrawEdge16( HDC16 hdc, LPRECT16 rc, UINT16 edge, UINT16 flags )
3241 RECT rect32;
3242 BOOL ret;
3244 rect32.left = rc->left;
3245 rect32.top = rc->top;
3246 rect32.right = rc->right;
3247 rect32.bottom = rc->bottom;
3248 ret = DrawEdge( HDC_32(hdc), &rect32, edge, flags );
3249 rc->left = rect32.left;
3250 rc->top = rect32.top;
3251 rc->right = rect32.right;
3252 rc->bottom = rect32.bottom;
3253 return ret;
3256 /**********************************************************************
3257 * CheckMenuRadioItem (USER.666)
3259 BOOL16 WINAPI CheckMenuRadioItem16(HMENU16 hMenu, UINT16 first, UINT16 last,
3260 UINT16 check, BOOL16 bypos)
3262 return CheckMenuRadioItem( HMENU_32(hMenu), first, last, check, bypos );