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
29 #include "wine/winuser16.h"
33 #include "user_private.h"
36 #include "wine/list.h"
37 #include "wine/debug.h"
39 WINE_DEFAULT_DEBUG_CHANNEL(user);
41 /* handle to handle 16 conversions */
42 #define HANDLE_16(h32) (LOWORD(h32))
44 /* handle16 to handle conversions */
45 #define HANDLE_32(h16) ((HANDLE)(ULONG_PTR)(h16))
46 #define HINSTANCE_32(h16) ((HINSTANCE)(ULONG_PTR)(h16))
48 #define IS_MENU_STRING_ITEM(flags) \
49 (((flags) & (MF_STRING | MF_BITMAP | MF_OWNERDRAW | MF_SEPARATOR)) == MF_STRING)
51 /* UserSeeUserDo parameters */
52 #define USUD_LOCALALLOC 0x0001
53 #define USUD_LOCALFREE 0x0002
54 #define USUD_LOCALCOMPACT 0x0003
55 #define USUD_LOCALHEAP 0x0004
56 #define USUD_FIRSTCLASS 0x0005
58 #define CID_RESOURCE 0x0001
59 #define CID_WIN32 0x0004
60 #define CID_NONSHARED 0x0008
62 WORD USER_HeapSel = 0; /* USER heap selector */
64 struct gray_string_info
66 GRAYSTRINGPROC16 proc;
71 /* callback for 16-bit gray string proc with opaque pointer */
72 static BOOL CALLBACK gray_string_callback( HDC hdc, LPARAM param, INT len )
74 const struct gray_string_info *info = (struct gray_string_info *)param;
78 args[3] = HDC_16(hdc);
79 args[2] = HIWORD(info->param);
80 args[1] = LOWORD(info->param);
82 WOWCallback16Ex( (DWORD)info->proc, WCB16_PASCAL, sizeof(args), args, &ret );
86 /* callback for 16-bit gray string proc with string pointer */
87 static BOOL CALLBACK gray_string_callback_ptr( HDC hdc, LPARAM param, INT len )
89 const struct gray_string_info *info;
90 char *str = (char *)param;
92 info = (struct gray_string_info *)(str - offsetof( struct gray_string_info, str ));
93 return gray_string_callback( hdc, (LPARAM)info, len );
96 struct draw_state_info
102 /* callback for 16-bit DrawState functions */
103 static BOOL CALLBACK draw_state_callback( HDC hdc, LPARAM lparam, WPARAM wparam, int cx, int cy )
105 const struct draw_state_info *info = (struct draw_state_info *)lparam;
109 args[5] = HDC_16(hdc);
110 args[4] = HIWORD(info->param);
111 args[3] = LOWORD(info->param);
115 WOWCallback16Ex( (DWORD)info->proc, WCB16_PASCAL, sizeof(args), args, &ret );
119 /* This function is a copy of the one in objects/font.c */
120 static void logfont_32_to_16( const LOGFONTA* font32, LPLOGFONT16 font16 )
122 font16->lfHeight = font32->lfHeight;
123 font16->lfWidth = font32->lfWidth;
124 font16->lfEscapement = font32->lfEscapement;
125 font16->lfOrientation = font32->lfOrientation;
126 font16->lfWeight = font32->lfWeight;
127 font16->lfItalic = font32->lfItalic;
128 font16->lfUnderline = font32->lfUnderline;
129 font16->lfStrikeOut = font32->lfStrikeOut;
130 font16->lfCharSet = font32->lfCharSet;
131 font16->lfOutPrecision = font32->lfOutPrecision;
132 font16->lfClipPrecision = font32->lfClipPrecision;
133 font16->lfQuality = font32->lfQuality;
134 font16->lfPitchAndFamily = font32->lfPitchAndFamily;
135 lstrcpynA( font16->lfFaceName, font32->lfFaceName, LF_FACESIZE );
138 static int get_bitmap_width_bytes( int width, int bpp )
143 return 2 * ((width+15) / 16);
145 return 2 * ((width+3) / 4);
150 return width + (width & 1);
157 WARN("Unknown depth %d, please report.\n", bpp );
162 /***********************************************************************
163 * Helper for wsprintf16
166 #define WPRINTF_LEFTALIGN 0x0001 /* Align output on the left ('-' prefix) */
167 #define WPRINTF_PREFIX_HEX 0x0002 /* Prefix hex with 0x ('#' prefix) */
168 #define WPRINTF_ZEROPAD 0x0004 /* Pad with zeros ('0' prefix) */
169 #define WPRINTF_LONG 0x0008 /* Long arg ('l' prefix) */
170 #define WPRINTF_SHORT 0x0010 /* Short arg ('h' prefix) */
171 #define WPRINTF_UPPER_HEX 0x0020 /* Upper-case hex ('X' specifier) */
191 static INT parse_format( LPCSTR format, WPRINTF_FORMAT *res )
198 if (*p == '-') { res->flags |= WPRINTF_LEFTALIGN; p++; }
199 if (*p == '#') { res->flags |= WPRINTF_PREFIX_HEX; p++; }
200 if (*p == '0') { res->flags |= WPRINTF_ZEROPAD; p++; }
201 while ((*p >= '0') && (*p <= '9')) /* width field */
203 res->width = res->width * 10 + *p - '0';
206 if (*p == '.') /* precision field */
209 while ((*p >= '0') && (*p <= '9'))
211 res->precision = res->precision * 10 + *p - '0';
215 if (*p == 'l') { res->flags |= WPRINTF_LONG; p++; }
216 else if (*p == 'h') { res->flags |= WPRINTF_SHORT; p++; }
220 case 'C': /* no Unicode in Win16 */
221 res->type = WPR_CHAR;
225 res->type = WPR_STRING;
229 res->type = WPR_SIGNED;
232 res->type = WPR_UNSIGNED;
236 res->flags |= WPRINTF_ZEROPAD;
239 res->flags |= WPRINTF_UPPER_HEX;
242 res->type = WPR_HEXA;
244 default: /* unknown format char */
245 res->type = WPR_UNKNOWN;
246 p--; /* print format as normal char */
249 return (INT)(p - format) + 1;
253 /**********************************************************************
254 * Management of the 16-bit cursor/icon cache
267 static struct list icon_cache = LIST_INIT( icon_cache );
269 static void add_shared_icon( HINSTANCE16 inst, HRSRC16 rsrc, HRSRC16 group, HICON16 icon )
271 struct cache_entry *cache = HeapAlloc( GetProcessHeap(), 0, sizeof(*cache) );
276 cache->group = group;
279 list_add_tail( &icon_cache, &cache->entry );
282 static HICON16 find_shared_icon( HINSTANCE16 inst, HRSRC16 rsrc )
284 struct cache_entry *cache;
286 LIST_FOR_EACH_ENTRY( cache, &icon_cache, struct cache_entry, entry )
288 if (cache->inst != inst || cache->rsrc != rsrc) continue;
295 static int release_shared_icon( HICON16 icon )
297 struct cache_entry *cache;
299 LIST_FOR_EACH_ENTRY( cache, &icon_cache, struct cache_entry, entry )
301 if (cache->icon != icon) continue;
302 if (!cache->count) return 0;
303 return --cache->count;
308 static void free_module_icons( HINSTANCE16 inst )
310 struct cache_entry *cache, *next;
312 LIST_FOR_EACH_ENTRY_SAFE( cache, next, &icon_cache, struct cache_entry, entry )
314 if (cache->inst != inst) continue;
315 list_remove( &cache->entry );
316 GlobalFree16( cache->icon );
317 HeapFree( GetProcessHeap(), 0, cache );
322 /**********************************************************************
325 INT16 WINAPI InitApp16( HINSTANCE16 hInstance )
327 /* Create task message queue */
328 return (InitThreadInput16( 0, 0 ) != 0);
332 /***********************************************************************
333 * ExitWindows (USER.7)
335 BOOL16 WINAPI ExitWindows16( DWORD dwReturnCode, UINT16 wReserved )
337 return ExitWindowsEx( EWX_LOGOFF, 0xffffffff );
341 /***********************************************************************
342 * GetTimerResolution (USER.14)
344 LONG WINAPI GetTimerResolution16(void)
350 /***********************************************************************
351 * ClipCursor (USER.16)
353 BOOL16 WINAPI ClipCursor16( const RECT16 *rect )
357 if (!rect) return ClipCursor( NULL );
358 rect32.left = rect->left;
359 rect32.top = rect->top;
360 rect32.right = rect->right;
361 rect32.bottom = rect->bottom;
362 return ClipCursor( &rect32 );
366 /***********************************************************************
367 * GetCursorPos (USER.17)
369 BOOL16 WINAPI GetCursorPos16( POINT16 *pt )
380 /*******************************************************************
383 BOOL16 WINAPI AnyPopup16(void)
389 /***********************************************************************
390 * SetCursor (USER.69)
392 HCURSOR16 WINAPI SetCursor16(HCURSOR16 hCursor)
394 return HCURSOR_16(SetCursor(HCURSOR_32(hCursor)));
398 /***********************************************************************
399 * SetCursorPos (USER.70)
401 void WINAPI SetCursorPos16( INT16 x, INT16 y )
403 SetCursorPos( x, y );
407 /***********************************************************************
408 * ShowCursor (USER.71)
410 INT16 WINAPI ShowCursor16(BOOL16 bShow)
412 return ShowCursor(bShow);
416 /***********************************************************************
419 void WINAPI SetRect16( LPRECT16 rect, INT16 left, INT16 top, INT16 right, INT16 bottom )
424 rect->bottom = bottom;
428 /***********************************************************************
429 * SetRectEmpty (USER.73)
431 void WINAPI SetRectEmpty16( LPRECT16 rect )
433 rect->left = rect->right = rect->top = rect->bottom = 0;
437 /***********************************************************************
440 BOOL16 WINAPI CopyRect16( RECT16 *dest, const RECT16 *src )
447 /***********************************************************************
448 * IsRectEmpty (USER.75)
450 * Bug compat: Windows checks for 0 or negative width/height.
452 BOOL16 WINAPI IsRectEmpty16( const RECT16 *rect )
454 return ((rect->left >= rect->right) || (rect->top >= rect->bottom));
458 /***********************************************************************
461 BOOL16 WINAPI PtInRect16( const RECT16 *rect, POINT16 pt )
463 return ((pt.x >= rect->left) && (pt.x < rect->right) &&
464 (pt.y >= rect->top) && (pt.y < rect->bottom));
468 /***********************************************************************
469 * OffsetRect (USER.77)
471 void WINAPI OffsetRect16( LPRECT16 rect, INT16 x, INT16 y )
480 /***********************************************************************
481 * InflateRect (USER.78)
483 void WINAPI InflateRect16( LPRECT16 rect, INT16 x, INT16 y )
492 /***********************************************************************
493 * IntersectRect (USER.79)
495 BOOL16 WINAPI IntersectRect16( LPRECT16 dest, const RECT16 *src1,
498 if (IsRectEmpty16(src1) || IsRectEmpty16(src2) ||
499 (src1->left >= src2->right) || (src2->left >= src1->right) ||
500 (src1->top >= src2->bottom) || (src2->top >= src1->bottom))
502 SetRectEmpty16( dest );
505 dest->left = max( src1->left, src2->left );
506 dest->right = min( src1->right, src2->right );
507 dest->top = max( src1->top, src2->top );
508 dest->bottom = min( src1->bottom, src2->bottom );
513 /***********************************************************************
514 * UnionRect (USER.80)
516 BOOL16 WINAPI UnionRect16( LPRECT16 dest, const RECT16 *src1,
519 if (IsRectEmpty16(src1))
521 if (IsRectEmpty16(src2))
523 SetRectEmpty16( dest );
530 if (IsRectEmpty16(src2)) *dest = *src1;
533 dest->left = min( src1->left, src2->left );
534 dest->right = max( src1->right, src2->right );
535 dest->top = min( src1->top, src2->top );
536 dest->bottom = max( src1->bottom, src2->bottom );
543 /***********************************************************************
546 * The Win16 variant doesn't support special color brushes like
547 * the Win32 one, despite the fact that Win16, as well as Win32,
548 * supports special background brushes for a window class.
550 INT16 WINAPI FillRect16( HDC16 hdc, const RECT16 *rect, HBRUSH16 hbrush )
554 /* coordinates are logical so we cannot fast-check 'rect',
555 * it will be done later in the PatBlt().
558 if (!(prevBrush = SelectObject( HDC_32(hdc), HBRUSH_32(hbrush) ))) return 0;
559 PatBlt( HDC_32(hdc), rect->left, rect->top,
560 rect->right - rect->left, rect->bottom - rect->top, PATCOPY );
561 SelectObject( HDC_32(hdc), prevBrush );
566 /***********************************************************************
567 * InvertRect (USER.82)
569 void WINAPI InvertRect16( HDC16 hdc, const RECT16 *rect )
571 PatBlt( HDC_32(hdc), rect->left, rect->top,
572 rect->right - rect->left, rect->bottom - rect->top, DSTINVERT );
576 /***********************************************************************
577 * FrameRect (USER.83)
579 INT16 WINAPI FrameRect16( HDC16 hdc, const RECT16 *rect16, HBRUSH16 hbrush )
583 rect.left = rect16->left;
584 rect.top = rect16->top;
585 rect.right = rect16->right;
586 rect.bottom = rect16->bottom;
587 return FrameRect( HDC_32(hdc), &rect, HBRUSH_32(hbrush) );
591 /***********************************************************************
594 BOOL16 WINAPI DrawIcon16(HDC16 hdc, INT16 x, INT16 y, HICON16 hIcon)
596 return DrawIcon(HDC_32(hdc), x, y, HICON_32(hIcon));
600 /***********************************************************************
603 INT16 WINAPI DrawText16( HDC16 hdc, LPCSTR str, INT16 count, LPRECT16 rect, UINT16 flags )
611 rect32.left = rect->left;
612 rect32.top = rect->top;
613 rect32.right = rect->right;
614 rect32.bottom = rect->bottom;
615 ret = DrawTextA( HDC_32(hdc), str, count, &rect32, flags );
616 rect->left = rect32.left;
617 rect->top = rect32.top;
618 rect->right = rect32.right;
619 rect->bottom = rect32.bottom;
621 else ret = DrawTextA( HDC_32(hdc), str, count, NULL, flags);
626 /***********************************************************************
629 * See "Undocumented Windows". Used by W2.0 paint.exe.
631 DWORD WINAPI IconSize16(void)
633 return MAKELONG(GetSystemMetrics(SM_CYICON), GetSystemMetrics(SM_CXICON));
637 /***********************************************************************
638 * AdjustWindowRect (USER.102)
640 BOOL16 WINAPI AdjustWindowRect16( LPRECT16 rect, DWORD style, BOOL16 menu )
642 return AdjustWindowRectEx16( rect, style, menu, 0 );
646 /***********************************************************************
647 * MessageBeep (USER.104)
649 void WINAPI MessageBeep16( UINT16 i )
655 /**************************************************************************
656 * CloseClipboard (USER.138)
658 BOOL16 WINAPI CloseClipboard16(void)
660 return CloseClipboard();
664 /**************************************************************************
665 * EmptyClipboard (USER.139)
667 BOOL16 WINAPI EmptyClipboard16(void)
669 return EmptyClipboard();
673 /**************************************************************************
674 * CountClipboardFormats (USER.143)
676 INT16 WINAPI CountClipboardFormats16(void)
678 return CountClipboardFormats();
682 /**************************************************************************
683 * EnumClipboardFormats (USER.144)
685 UINT16 WINAPI EnumClipboardFormats16( UINT16 id )
687 return EnumClipboardFormats( id );
691 /**************************************************************************
692 * RegisterClipboardFormat (USER.145)
694 UINT16 WINAPI RegisterClipboardFormat16( LPCSTR name )
696 return RegisterClipboardFormatA( name );
700 /**************************************************************************
701 * GetClipboardFormatName (USER.146)
703 INT16 WINAPI GetClipboardFormatName16( UINT16 id, LPSTR buffer, INT16 maxlen )
705 return GetClipboardFormatNameA( id, buffer, maxlen );
709 /**********************************************************************
710 * LoadMenu (USER.150)
712 HMENU16 WINAPI LoadMenu16( HINSTANCE16 instance, LPCSTR name )
718 if (HIWORD(name) && name[0] == '#') name = ULongToPtr(atoi( name + 1 ));
721 instance = GetExePtr( instance );
722 if (!(hRsrc = FindResource16( instance, name, (LPSTR)RT_MENU ))) return 0;
723 if (!(handle = LoadResource16( instance, hRsrc ))) return 0;
724 hMenu = LoadMenuIndirect16(LockResource16(handle));
725 FreeResource16( handle );
730 /**********************************************************************
731 * CreateMenu (USER.151)
733 HMENU16 WINAPI CreateMenu16(void)
735 return HMENU_16( CreateMenu() );
739 /**********************************************************************
740 * DestroyMenu (USER.152)
742 BOOL16 WINAPI DestroyMenu16( HMENU16 hMenu )
744 return DestroyMenu( HMENU_32(hMenu) );
748 /*******************************************************************
749 * ChangeMenu (USER.153)
751 BOOL16 WINAPI ChangeMenu16( HMENU16 hMenu, UINT16 pos, SEGPTR data,
752 UINT16 id, UINT16 flags )
754 if (flags & MF_APPEND) return AppendMenu16( hMenu, flags & ~MF_APPEND, id, data );
756 /* FIXME: Word passes the item id in 'pos' and 0 or 0xffff as id */
757 /* for MF_DELETE. We should check the parameters for all others */
758 /* MF_* actions also (anybody got a doc on ChangeMenu?). */
760 if (flags & MF_DELETE) return DeleteMenu16(hMenu, pos, flags & ~MF_DELETE);
761 if (flags & MF_CHANGE) return ModifyMenu16(hMenu, pos, flags & ~MF_CHANGE, id, data );
762 if (flags & MF_REMOVE) return RemoveMenu16(hMenu, flags & MF_BYPOSITION ? pos : id,
763 flags & ~MF_REMOVE );
764 /* Default: MF_INSERT */
765 return InsertMenu16( hMenu, pos, flags, id, data );
769 /*******************************************************************
770 * CheckMenuItem (USER.154)
772 BOOL16 WINAPI CheckMenuItem16( HMENU16 hMenu, UINT16 id, UINT16 flags )
774 return CheckMenuItem( HMENU_32(hMenu), id, flags );
778 /**********************************************************************
779 * EnableMenuItem (USER.155)
781 BOOL16 WINAPI EnableMenuItem16( HMENU16 hMenu, UINT16 wItemID, UINT16 wFlags )
783 return EnableMenuItem( HMENU_32(hMenu), wItemID, wFlags );
787 /**********************************************************************
788 * GetSubMenu (USER.159)
790 HMENU16 WINAPI GetSubMenu16( HMENU16 hMenu, INT16 nPos )
792 return HMENU_16( GetSubMenu( HMENU_32(hMenu), nPos ) );
796 /*******************************************************************
797 * GetMenuString (USER.161)
799 INT16 WINAPI GetMenuString16( HMENU16 hMenu, UINT16 wItemID,
800 LPSTR str, INT16 nMaxSiz, UINT16 wFlags )
802 return GetMenuStringA( HMENU_32(hMenu), wItemID, str, nMaxSiz, wFlags );
806 /**********************************************************************
809 BOOL16 WINAPI WinHelp16( HWND16 hWnd, LPCSTR lpHelpFile, UINT16 wCommand,
815 /* We might call WinExec() */
816 ReleaseThunkLock(&mutex_count);
818 ret = WinHelpA(WIN_Handle32(hWnd), lpHelpFile, wCommand, (DWORD)MapSL(dwData));
820 RestoreThunkLock(mutex_count);
825 /***********************************************************************
826 * LoadCursor (USER.173)
828 HCURSOR16 WINAPI LoadCursor16(HINSTANCE16 hInstance, LPCSTR name)
830 return LoadImage16( hInstance, name, IMAGE_CURSOR, 0, 0, LR_SHARED | LR_DEFAULTSIZE );
834 /***********************************************************************
835 * LoadIcon (USER.174)
837 HICON16 WINAPI LoadIcon16(HINSTANCE16 hInstance, LPCSTR name)
839 return LoadImage16( hInstance, name, IMAGE_ICON, 0, 0, LR_SHARED | LR_DEFAULTSIZE );
842 /**********************************************************************
843 * LoadBitmap (USER.175)
845 HBITMAP16 WINAPI LoadBitmap16(HINSTANCE16 hInstance, LPCSTR name)
847 return HBITMAP_16(LoadBitmapA(HINSTANCE_32(hInstance), name));
850 /**********************************************************************
851 * LoadString (USER.176)
853 INT16 WINAPI LoadString16( HINSTANCE16 instance, UINT16 resource_id, LPSTR buffer, INT16 buflen )
861 TRACE("inst=%04x id=%04x buff=%p len=%d\n", instance, resource_id, buffer, buflen);
863 hrsrc = FindResource16( instance, MAKEINTRESOURCEA((resource_id>>4)+1), (LPSTR)RT_STRING );
864 if (!hrsrc) return 0;
865 hmem = LoadResource16( instance, hrsrc );
868 p = LockResource16(hmem);
869 string_num = resource_id & 0x000f;
870 while (string_num--) p += *p + 1;
872 if (buffer == NULL) ret = *p;
875 ret = min(buflen - 1, *p);
878 memcpy(buffer, p + 1, ret);
886 TRACE( "%s loaded\n", debugstr_a(buffer));
888 FreeResource16( hmem );
892 /**********************************************************************
893 * LoadAccelerators (USER.177)
895 HACCEL16 WINAPI LoadAccelerators16(HINSTANCE16 instance, LPCSTR lpTableName)
902 TRACE("%04x %s\n", instance, debugstr_a(lpTableName) );
904 if (!(hRsrc = FindResource16( instance, lpTableName, (LPSTR)RT_ACCELERATOR )) ||
905 !(hMem = LoadResource16(instance,hRsrc)))
907 WARN("couldn't find %04x %s\n", instance, debugstr_a(lpTableName));
910 if ((table16 = LockResource16( hMem )))
912 DWORD i, count = SizeofResource16( instance, hRsrc ) / sizeof(*table16);
913 ACCEL *table = HeapAlloc( GetProcessHeap(), 0, count * sizeof(*table) );
916 for (i = 0; i < count; i++)
918 table[i].fVirt = table16[i].fVirt & 0x7f;
919 table[i].key = table16[i].key;
920 table[i].cmd = table16[i].cmd;
922 ret = CreateAcceleratorTableA( table, count );
923 HeapFree( GetProcessHeap(), 0, table );
926 FreeResource16( hMem );
927 return HACCEL_16(ret);
930 /***********************************************************************
931 * GetSystemMetrics (USER.179)
933 INT16 WINAPI GetSystemMetrics16( INT16 index )
935 return GetSystemMetrics( index );
939 /*************************************************************************
940 * GetSysColor (USER.180)
942 COLORREF WINAPI GetSysColor16( INT16 index )
944 return GetSysColor( index );
948 /*************************************************************************
949 * SetSysColors (USER.181)
951 VOID WINAPI SetSysColors16( INT16 count, const INT16 *list16, const COLORREF *values )
955 if ((list = HeapAlloc( GetProcessHeap(), 0, count * sizeof(*list) )))
957 for (i = 0; i < count; i++) list[i] = list16[i];
958 SetSysColors( count, list, values );
959 HeapFree( GetProcessHeap(), 0, list );
964 /***********************************************************************
965 * GrayString (USER.185)
967 BOOL16 WINAPI GrayString16( HDC16 hdc, HBRUSH16 hbr, GRAYSTRINGPROC16 gsprc,
968 LPARAM lParam, INT16 cch, INT16 x, INT16 y,
973 if (!gsprc) return GrayStringA( HDC_32(hdc), HBRUSH_32(hbr), NULL,
974 (LPARAM)MapSL(lParam), cch, x, y, cx, cy );
976 if (cch == -1 || (cch && cx && cy))
978 /* lParam can be treated as an opaque pointer */
979 struct gray_string_info info;
983 ret = GrayStringA( HDC_32(hdc), HBRUSH_32(hbr), gray_string_callback,
984 (LPARAM)&info, cch, x, y, cx, cy );
986 else /* here we need some string conversions */
988 char *str16 = MapSL(lParam);
989 struct gray_string_info *info;
991 if (!cch) cch = strlen(str16);
992 if (!(info = HeapAlloc( GetProcessHeap(), 0, sizeof(*info) + cch ))) return FALSE;
994 info->param = lParam;
995 memcpy( info->str, str16, cch );
996 ret = GrayStringA( HDC_32(hdc), HBRUSH_32(hbr), gray_string_callback_ptr,
997 (LPARAM)info->str, cch, x, y, cx, cy );
998 HeapFree( GetProcessHeap(), 0, info );
1004 /***********************************************************************
1005 * SwapMouseButton (USER.186)
1007 BOOL16 WINAPI SwapMouseButton16( BOOL16 fSwap )
1009 return SwapMouseButton( fSwap );
1013 /**************************************************************************
1014 * IsClipboardFormatAvailable (USER.193)
1016 BOOL16 WINAPI IsClipboardFormatAvailable16( UINT16 wFormat )
1018 return IsClipboardFormatAvailable( wFormat );
1022 /***********************************************************************
1023 * TabbedTextOut (USER.196)
1025 LONG WINAPI TabbedTextOut16( HDC16 hdc, INT16 x, INT16 y, LPCSTR lpstr,
1026 INT16 count, INT16 nb_tabs, const INT16 *tabs16, INT16 tab_org )
1029 INT i, *tabs = HeapAlloc( GetProcessHeap(), 0, nb_tabs * sizeof(tabs) );
1030 if (!tabs) return 0;
1031 for (i = 0; i < nb_tabs; i++) tabs[i] = tabs16[i];
1032 ret = TabbedTextOutA( HDC_32(hdc), x, y, lpstr, count, nb_tabs, tabs, tab_org );
1033 HeapFree( GetProcessHeap(), 0, tabs );
1038 /***********************************************************************
1039 * GetTabbedTextExtent (USER.197)
1041 DWORD WINAPI GetTabbedTextExtent16( HDC16 hdc, LPCSTR lpstr, INT16 count,
1042 INT16 nb_tabs, const INT16 *tabs16 )
1045 INT i, *tabs = HeapAlloc( GetProcessHeap(), 0, nb_tabs * sizeof(tabs) );
1046 if (!tabs) return 0;
1047 for (i = 0; i < nb_tabs; i++) tabs[i] = tabs16[i];
1048 ret = GetTabbedTextExtentA( HDC_32(hdc), lpstr, count, nb_tabs, tabs );
1049 HeapFree( GetProcessHeap(), 0, tabs );
1054 /***********************************************************************
1055 * UserSeeUserDo (USER.216)
1057 DWORD WINAPI UserSeeUserDo16(WORD wReqType, WORD wParam1, WORD wParam2, WORD wParam3)
1059 STACK16FRAME* stack16 = MapSL((SEGPTR)NtCurrentTeb()->WOW32Reserved);
1060 HANDLE16 oldDS = stack16->ds;
1061 DWORD ret = (DWORD)-1;
1063 stack16->ds = USER_HeapSel;
1066 case USUD_LOCALALLOC:
1067 ret = LocalAlloc16(wParam1, wParam3);
1069 case USUD_LOCALFREE:
1070 ret = LocalFree16(wParam1);
1072 case USUD_LOCALCOMPACT:
1073 ret = LocalCompact16(wParam3);
1075 case USUD_LOCALHEAP:
1078 case USUD_FIRSTCLASS:
1079 FIXME("return a pointer to the first window class.\n");
1082 WARN("wReqType %04x (unknown)\n", wReqType);
1084 stack16->ds = oldDS;
1089 /***********************************************************************
1090 * LookupMenuHandle (USER.217)
1092 HMENU16 WINAPI LookupMenuHandle16( HMENU16 hmenu, INT16 id )
1094 FIXME( "%04x %04x: stub\n", hmenu, id );
1099 static LPCSTR parse_menu_resource( LPCSTR res, HMENU hMenu )
1107 flags = GET_WORD(res);
1108 end_flag = flags & MF_END;
1109 /* Remove MF_END because it has the same value as MF_HILITE */
1111 res += sizeof(WORD);
1112 if (!(flags & MF_POPUP))
1115 res += sizeof(WORD);
1118 res += strlen(str) + 1;
1119 if (flags & MF_POPUP)
1121 HMENU hSubMenu = CreatePopupMenu();
1122 if (!hSubMenu) return NULL;
1123 if (!(res = parse_menu_resource( res, hSubMenu ))) return NULL;
1124 AppendMenuA( hMenu, flags, (UINT_PTR)hSubMenu, str );
1126 else /* Not a popup */
1128 AppendMenuA( hMenu, flags, id, *str ? str : NULL );
1130 } while (!end_flag);
1134 /**********************************************************************
1135 * LoadMenuIndirect (USER.220)
1137 HMENU16 WINAPI LoadMenuIndirect16( LPCVOID template )
1140 WORD version, offset;
1141 LPCSTR p = template;
1143 TRACE("(%p)\n", template );
1144 version = GET_WORD(p);
1148 WARN("version must be 0 for Win16\n" );
1151 offset = GET_WORD(p);
1152 p += sizeof(WORD) + offset;
1153 if (!(hMenu = CreateMenu())) return 0;
1154 if (!parse_menu_resource( p, hMenu ))
1156 DestroyMenu( hMenu );
1159 return HMENU_16(hMenu);
1163 /*************************************************************************
1164 * ScrollDC (USER.221)
1166 BOOL16 WINAPI ScrollDC16( HDC16 hdc, INT16 dx, INT16 dy, const RECT16 *rect,
1167 const RECT16 *cliprc, HRGN16 hrgnUpdate,
1170 RECT rect32, clipRect32, rcUpdate32;
1175 rect32.left = rect->left;
1176 rect32.top = rect->top;
1177 rect32.right = rect->right;
1178 rect32.bottom = rect->bottom;
1182 clipRect32.left = cliprc->left;
1183 clipRect32.top = cliprc->top;
1184 clipRect32.right = cliprc->right;
1185 clipRect32.bottom = cliprc->bottom;
1187 ret = ScrollDC( HDC_32(hdc), dx, dy, rect ? &rect32 : NULL,
1188 cliprc ? &clipRect32 : NULL, HRGN_32(hrgnUpdate),
1192 rcUpdate->left = rcUpdate32.left;
1193 rcUpdate->top = rcUpdate32.top;
1194 rcUpdate->right = rcUpdate32.right;
1195 rcUpdate->bottom = rcUpdate32.bottom;
1201 /***********************************************************************
1202 * GetSystemDebugState (USER.231)
1204 WORD WINAPI GetSystemDebugState16(void)
1206 return 0; /* FIXME */
1210 /***********************************************************************
1211 * EqualRect (USER.244)
1213 BOOL16 WINAPI EqualRect16( const RECT16* rect1, const RECT16* rect2 )
1215 return ((rect1->left == rect2->left) && (rect1->right == rect2->right) &&
1216 (rect1->top == rect2->top) && (rect1->bottom == rect2->bottom));
1220 /***********************************************************************
1221 * ExitWindowsExec (USER.246)
1223 BOOL16 WINAPI ExitWindowsExec16( LPCSTR lpszExe, LPCSTR lpszParams )
1225 TRACE("Should run the following in DOS-mode: \"%s %s\"\n",
1226 lpszExe, lpszParams);
1227 return ExitWindowsEx( EWX_LOGOFF, 0xffffffff );
1231 /***********************************************************************
1232 * GetCursor (USER.247)
1234 HCURSOR16 WINAPI GetCursor16(void)
1236 return HCURSOR_16(GetCursor());
1240 /**********************************************************************
1241 * GetAsyncKeyState (USER.249)
1243 INT16 WINAPI GetAsyncKeyState16( INT16 key )
1245 return GetAsyncKeyState( key );
1249 /**********************************************************************
1250 * GetMenuState (USER.250)
1252 UINT16 WINAPI GetMenuState16( HMENU16 hMenu, UINT16 wItemID, UINT16 wFlags )
1254 return GetMenuState( HMENU_32(hMenu), wItemID, wFlags );
1258 /**************************************************************************
1259 * SendDriverMessage (USER.251)
1261 LRESULT WINAPI SendDriverMessage16(HDRVR16 hDriver, UINT16 msg, LPARAM lParam1,
1264 FIXME("(%04x, %04x, %08lx, %08lx): stub\n", hDriver, msg, lParam1, lParam2);
1269 /**************************************************************************
1270 * OpenDriver (USER.252)
1272 HDRVR16 WINAPI OpenDriver16(LPCSTR lpDriverName, LPCSTR lpSectionName, LPARAM lParam2)
1274 FIXME( "(%s, %s, %08lx): stub\n", debugstr_a(lpDriverName), debugstr_a(lpSectionName), lParam2);
1279 /**************************************************************************
1280 * CloseDriver (USER.253)
1282 LRESULT WINAPI CloseDriver16(HDRVR16 hDrvr, LPARAM lParam1, LPARAM lParam2)
1284 FIXME( "(%04x, %08lx, %08lx): stub\n", hDrvr, lParam1, lParam2);
1289 /**************************************************************************
1290 * GetDriverModuleHandle (USER.254)
1292 HMODULE16 WINAPI GetDriverModuleHandle16(HDRVR16 hDrvr)
1294 FIXME("(%04x): stub\n", hDrvr);
1299 /**************************************************************************
1300 * DefDriverProc (USER.255)
1302 LRESULT WINAPI DefDriverProc16(DWORD dwDevID, HDRVR16 hDriv, UINT16 wMsg,
1303 LPARAM lParam1, LPARAM lParam2)
1305 FIXME( "devID=0x%08x hDrv=0x%04x wMsg=%04x lP1=0x%08lx lP2=0x%08lx: stub\n",
1306 dwDevID, hDriv, wMsg, lParam1, lParam2);
1311 /**************************************************************************
1312 * GetDriverInfo (USER.256)
1314 struct DRIVERINFOSTRUCT16;
1315 BOOL16 WINAPI GetDriverInfo16(HDRVR16 hDrvr, struct DRIVERINFOSTRUCT16 *lpDrvInfo)
1317 FIXME( "(%04x, %p): stub\n", hDrvr, lpDrvInfo);
1322 /**************************************************************************
1323 * GetNextDriver (USER.257)
1325 HDRVR16 WINAPI GetNextDriver16(HDRVR16 hDrvr, DWORD dwFlags)
1327 FIXME( "(%04x, %08x): stub\n", hDrvr, dwFlags);
1332 /**********************************************************************
1333 * GetMenuItemCount (USER.263)
1335 INT16 WINAPI GetMenuItemCount16( HMENU16 hMenu )
1337 return GetMenuItemCount( HMENU_32(hMenu) );
1341 /**********************************************************************
1342 * GetMenuItemID (USER.264)
1344 UINT16 WINAPI GetMenuItemID16( HMENU16 hMenu, INT16 nPos )
1346 return GetMenuItemID( HMENU_32(hMenu), nPos );
1350 /***********************************************************************
1351 * GlobalAddAtom (USER.268)
1353 ATOM WINAPI GlobalAddAtom16(LPCSTR lpString)
1355 return GlobalAddAtomA(lpString);
1358 /***********************************************************************
1359 * GlobalDeleteAtom (USER.269)
1361 ATOM WINAPI GlobalDeleteAtom16(ATOM nAtom)
1363 return GlobalDeleteAtom(nAtom);
1366 /***********************************************************************
1367 * GlobalFindAtom (USER.270)
1369 ATOM WINAPI GlobalFindAtom16(LPCSTR lpString)
1371 return GlobalFindAtomA(lpString);
1374 /***********************************************************************
1375 * GlobalGetAtomName (USER.271)
1377 UINT16 WINAPI GlobalGetAtomName16(ATOM nAtom, LPSTR lpBuffer, INT16 nSize)
1379 return GlobalGetAtomNameA(nAtom, lpBuffer, nSize);
1383 /***********************************************************************
1384 * ControlPanelInfo (USER.273)
1386 void WINAPI ControlPanelInfo16( INT16 nInfoType, WORD wData, LPSTR lpBuffer )
1388 FIXME("(%d, %04x, %p): stub.\n", nInfoType, wData, lpBuffer);
1392 /***********************************************************************
1393 * OldSetDeskPattern (USER.279)
1395 BOOL16 WINAPI SetDeskPattern16(void)
1397 return SystemParametersInfoA( SPI_SETDESKPATTERN, -1, NULL, FALSE );
1401 /***********************************************************************
1402 * GetSysColorBrush (USER.281)
1404 HBRUSH16 WINAPI GetSysColorBrush16( INT16 index )
1406 return HBRUSH_16( GetSysColorBrush(index) );
1410 /***********************************************************************
1411 * SelectPalette (USER.282)
1413 HPALETTE16 WINAPI SelectPalette16( HDC16 hdc, HPALETTE16 hpal, BOOL16 bForceBackground )
1415 return HPALETTE_16( SelectPalette( HDC_32(hdc), HPALETTE_32(hpal), bForceBackground ));
1418 /***********************************************************************
1419 * RealizePalette (USER.283)
1421 UINT16 WINAPI RealizePalette16( HDC16 hdc )
1423 return UserRealizePalette( HDC_32(hdc) );
1427 /***********************************************************************
1428 * GetFreeSystemResources (USER.284)
1430 WORD WINAPI GetFreeSystemResources16( WORD resType )
1432 STACK16FRAME* stack16 = MapSL((SEGPTR)NtCurrentTeb()->WOW32Reserved);
1433 HANDLE16 oldDS = stack16->ds;
1434 HINSTANCE16 gdi_inst;
1435 int userPercent, gdiPercent;
1437 if ((gdi_inst = LoadLibrary16( "GDI" )) < 32) return 0;
1441 case GFSR_USERRESOURCES:
1442 stack16->ds = USER_HeapSel;
1443 userPercent = (int)LocalCountFree16() * 100 / LocalHeapSize16();
1445 stack16->ds = oldDS;
1448 case GFSR_GDIRESOURCES:
1449 stack16->ds = gdi_inst;
1450 gdiPercent = (int)LocalCountFree16() * 100 / LocalHeapSize16();
1452 stack16->ds = oldDS;
1455 case GFSR_SYSTEMRESOURCES:
1456 stack16->ds = USER_HeapSel;
1457 userPercent = (int)LocalCountFree16() * 100 / LocalHeapSize16();
1458 stack16->ds = gdi_inst;
1459 gdiPercent = (int)LocalCountFree16() * 100 / LocalHeapSize16();
1460 stack16->ds = oldDS;
1464 userPercent = gdiPercent = 0;
1467 FreeLibrary16( gdi_inst );
1468 TRACE("<- userPercent %d, gdiPercent %d\n", userPercent, gdiPercent);
1469 return (WORD)min( userPercent, gdiPercent );
1473 /***********************************************************************
1474 * SetDeskWallPaper (USER.285)
1476 BOOL16 WINAPI SetDeskWallPaper16( LPCSTR filename )
1478 return SetDeskWallPaper( filename );
1482 /***********************************************************************
1483 * keybd_event (USER.289)
1485 void WINAPI keybd_event16( CONTEXT86 *context )
1489 if (HIBYTE(context->Eax) & 0x80) dwFlags |= KEYEVENTF_KEYUP;
1490 if (HIBYTE(context->Ebx) & 0x01) dwFlags |= KEYEVENTF_EXTENDEDKEY;
1492 keybd_event( LOBYTE(context->Eax), LOBYTE(context->Ebx),
1493 dwFlags, MAKELONG(LOWORD(context->Esi), LOWORD(context->Edi)) );
1497 /***********************************************************************
1498 * mouse_event (USER.299)
1500 void WINAPI mouse_event16( CONTEXT86 *context )
1502 mouse_event( LOWORD(context->Eax), LOWORD(context->Ebx), LOWORD(context->Ecx),
1503 LOWORD(context->Edx), MAKELONG(context->Esi, context->Edi) );
1507 /***********************************************************************
1508 * GetClipCursor (USER.309)
1510 void WINAPI GetClipCursor16( RECT16 *rect )
1515 GetClipCursor( &rect32 );
1516 rect->left = rect32.left;
1517 rect->top = rect32.top;
1518 rect->right = rect32.right;
1519 rect->bottom = rect32.bottom;
1524 /***********************************************************************
1525 * SignalProc (USER.314)
1527 void WINAPI SignalProc16( HANDLE16 hModule, UINT16 code,
1528 UINT16 uExitFn, HINSTANCE16 hInstance, HQUEUE16 hQueue )
1530 if (code == USIG16_DLL_UNLOAD)
1532 hModule = GetExePtr(hModule);
1533 /* HOOK_FreeModuleHooks( hModule ); */
1534 free_module_classes( hModule );
1535 free_module_icons( hModule );
1540 /***********************************************************************
1541 * SetEventHook (USER.321)
1543 * Used by Turbo Debugger for Windows
1545 FARPROC16 WINAPI SetEventHook16(FARPROC16 lpfnEventHook)
1547 FIXME("(lpfnEventHook=%p): stub\n", lpfnEventHook);
1552 /**********************************************************************
1553 * EnableHardwareInput (USER.331)
1555 BOOL16 WINAPI EnableHardwareInput16(BOOL16 bEnable)
1557 FIXME("(%d) - stub\n", bEnable);
1562 /**********************************************************************
1563 * LoadCursorIconHandler (USER.336)
1565 * Supposed to load resources of Windows 2.x applications.
1567 HGLOBAL16 WINAPI LoadCursorIconHandler16( HGLOBAL16 hResource, HMODULE16 hModule, HRSRC16 hRsrc )
1569 FIXME("(%04x,%04x,%04x): old 2.x resources are not supported!\n", hResource, hModule, hRsrc);
1574 /***********************************************************************
1575 * GetMouseEventProc (USER.337)
1577 FARPROC16 WINAPI GetMouseEventProc16(void)
1579 HMODULE16 hmodule = GetModuleHandle16("USER");
1580 return GetProcAddress16( hmodule, "mouse_event" );
1584 /***********************************************************************
1585 * IsUserIdle (USER.333)
1587 BOOL16 WINAPI IsUserIdle16(void)
1589 if ( GetAsyncKeyState( VK_LBUTTON ) & 0x8000 )
1591 if ( GetAsyncKeyState( VK_RBUTTON ) & 0x8000 )
1593 if ( GetAsyncKeyState( VK_MBUTTON ) & 0x8000 )
1595 /* Should check for screen saver activation here ... */
1600 /**********************************************************************
1601 * LoadDIBIconHandler (USER.357)
1603 * RT_ICON resource loader, installed by USER_SignalProc when module
1606 HGLOBAL16 WINAPI LoadDIBIconHandler16( HGLOBAL16 hMemObj, HMODULE16 hModule, HRSRC16 hRsrc )
1608 /* If hResource is zero we must allocate a new memory block, if it's
1609 * non-zero but GlobalLock() returns NULL then it was discarded and
1610 * we have to recommit some memory, otherwise we just need to check
1611 * the block size. See LoadProc() in 16-bit SDK for more.
1613 FIXME( "%x %x %x: stub, not supported anymore\n", hMemObj, hModule, hRsrc );
1617 /**********************************************************************
1618 * LoadDIBCursorHandler (USER.356)
1620 * RT_CURSOR resource loader. Same as above.
1622 HGLOBAL16 WINAPI LoadDIBCursorHandler16( HGLOBAL16 hMemObj, HMODULE16 hModule, HRSRC16 hRsrc )
1624 FIXME( "%x %x %x: stub, not supported anymore\n", hMemObj, hModule, hRsrc );
1629 /**********************************************************************
1632 BOOL16 WINAPI IsMenu16( HMENU16 hmenu )
1634 return IsMenu( HMENU_32(hmenu) );
1638 /***********************************************************************
1641 BOOL16 WINAPI DCHook16( HDC16 hdc, WORD code, DWORD data, LPARAM lParam )
1643 FIXME( "hDC = %x, %i: stub\n", hdc, code );
1648 /**********************************************************************
1649 * LookupIconIdFromDirectoryEx (USER.364)
1651 * FIXME: exact parameter sizes
1653 INT16 WINAPI LookupIconIdFromDirectoryEx16( LPBYTE dir, BOOL16 bIcon,
1654 INT16 width, INT16 height, UINT16 cFlag )
1656 return LookupIconIdFromDirectoryEx( dir, bIcon, width, height, cFlag );
1660 /***********************************************************************
1661 * CopyIcon (USER.368)
1663 HICON16 WINAPI CopyIcon16( HINSTANCE16 hInstance, HICON16 hIcon )
1665 CURSORICONINFO *info = GlobalLock16( hIcon );
1666 void *and_bits = info + 1;
1667 void *xor_bits = (BYTE *)and_bits + info->nHeight * get_bitmap_width_bytes( info->nWidth, 1 );
1668 HGLOBAL16 ret = CreateCursorIconIndirect16( hInstance, info, and_bits, xor_bits );
1669 GlobalUnlock16( hIcon );
1674 /***********************************************************************
1675 * CopyCursor (USER.369)
1677 HCURSOR16 WINAPI CopyCursor16( HINSTANCE16 hInstance, HCURSOR16 hCursor )
1679 CURSORICONINFO *info = GlobalLock16( hCursor );
1680 void *and_bits = info + 1;
1681 void *xor_bits = (BYTE *)and_bits + info->nHeight * get_bitmap_width_bytes( info->nWidth, 1 );
1682 HGLOBAL16 ret = CreateCursorIconIndirect16( hInstance, info, and_bits, xor_bits );
1683 GlobalUnlock16( hCursor );
1688 /***********************************************************************
1689 * SubtractRect (USER.373)
1691 BOOL16 WINAPI SubtractRect16( LPRECT16 dest, const RECT16 *src1,
1692 const RECT16 *src2 )
1696 if (IsRectEmpty16( src1 ))
1698 SetRectEmpty16( dest );
1702 if (IntersectRect16( &tmp, src1, src2 ))
1704 if (EqualRect16( &tmp, dest ))
1706 SetRectEmpty16( dest );
1709 if ((tmp.top == dest->top) && (tmp.bottom == dest->bottom))
1711 if (tmp.left == dest->left) dest->left = tmp.right;
1712 else if (tmp.right == dest->right) dest->right = tmp.left;
1714 else if ((tmp.left == dest->left) && (tmp.right == dest->right))
1716 if (tmp.top == dest->top) dest->top = tmp.bottom;
1717 else if (tmp.bottom == dest->bottom) dest->bottom = tmp.top;
1724 /**********************************************************************
1725 * DllEntryPoint (USER.374)
1727 BOOL WINAPI DllEntryPoint( DWORD reason, HINSTANCE16 inst, WORD ds,
1728 WORD heap, DWORD reserved1, WORD reserved2 )
1730 if (reason != DLL_PROCESS_ATTACH) return TRUE;
1731 if (USER_HeapSel) return TRUE; /* already called */
1734 register_wow_handlers();
1739 /**********************************************************************
1740 * SetMenuContextHelpId (USER.384)
1742 BOOL16 WINAPI SetMenuContextHelpId16( HMENU16 hMenu, DWORD dwContextHelpID)
1744 return SetMenuContextHelpId( HMENU_32(hMenu), dwContextHelpID );
1748 /**********************************************************************
1749 * GetMenuContextHelpId (USER.385)
1751 DWORD WINAPI GetMenuContextHelpId16( HMENU16 hMenu )
1753 return GetMenuContextHelpId( HMENU_32(hMenu) );
1757 /***********************************************************************
1758 * LoadImage (USER.389)
1761 HANDLE16 WINAPI LoadImage16(HINSTANCE16 hinst, LPCSTR name, UINT16 type, INT16 cx, INT16 cy, UINT16 flags)
1763 if (!hinst || (flags & LR_LOADFROMFILE))
1764 return HICON_16( LoadImageA( 0, name, type, cx, cy, flags ));
1766 hinst = GetExePtr( hinst );
1768 if (flags & LR_DEFAULTSIZE)
1770 if (type == IMAGE_ICON)
1772 if (!cx) cx = GetSystemMetrics(SM_CXICON);
1773 if (!cy) cy = GetSystemMetrics(SM_CYICON);
1775 else if (type == IMAGE_CURSOR)
1777 if (!cx) cx = GetSystemMetrics(SM_CXCURSOR);
1778 if (!cy) cy = GetSystemMetrics(SM_CYCURSOR);
1785 return HBITMAP_16( LoadImageA( HINSTANCE_32(hinst), name, type, cx, cy, flags ));
1792 HRSRC16 hRsrc, hGroupRsrc;
1796 if (!(hRsrc = FindResource16( hinst, name,
1797 (LPCSTR)(type == IMAGE_ICON ? RT_GROUP_ICON : RT_GROUP_CURSOR ))))
1801 if (!(handle = LoadResource16( hinst, hRsrc ))) return 0;
1802 if ((dir = LockResource16( handle ))) id = LookupIconIdFromDirectory( dir, type == IMAGE_ICON );
1803 FreeResource16( handle );
1806 if (!(hRsrc = FindResource16( hinst, MAKEINTRESOURCEA(id),
1807 (LPCSTR)(type == IMAGE_ICON ? RT_ICON : RT_CURSOR) ))) return 0;
1809 if ((flags & LR_SHARED) && (hIcon = find_shared_icon( hinst, hRsrc ) ) != 0) return hIcon;
1811 if (!(handle = LoadResource16( hinst, hRsrc ))) return 0;
1812 bits = LockResource16( handle );
1813 hIcon = CreateIconFromResourceEx16( bits, 0, type == IMAGE_ICON, 0x00030000, cx, cy, flags );
1814 FreeResource16( handle );
1816 if (hIcon && (flags & LR_SHARED)) add_shared_icon( hinst, hRsrc, hGroupRsrc, hIcon );
1824 /******************************************************************************
1825 * CopyImage (USER.390) Creates new image and copies attributes to it
1828 HICON16 WINAPI CopyImage16(HANDLE16 hnd, UINT16 type, INT16 desiredx,
1829 INT16 desiredy, UINT16 flags)
1831 return HICON_16(CopyImage(HANDLE_32(hnd), (UINT)type, (INT)desiredx,
1832 (INT)desiredy, (UINT)flags));
1835 /**********************************************************************
1836 * DrawIconEx (USER.394)
1838 BOOL16 WINAPI DrawIconEx16(HDC16 hdc, INT16 xLeft, INT16 yTop, HICON16 hIcon,
1839 INT16 cxWidth, INT16 cyWidth, UINT16 istep,
1840 HBRUSH16 hbr, UINT16 flags)
1842 return DrawIconEx(HDC_32(hdc), xLeft, yTop, HICON_32(hIcon), cxWidth, cyWidth,
1843 istep, HBRUSH_32(hbr), flags);
1846 /**********************************************************************
1847 * GetIconInfo (USER.395)
1849 BOOL16 WINAPI GetIconInfo16(HICON16 hIcon, LPICONINFO16 iconinfo)
1852 BOOL16 ret = GetIconInfo(HICON_32(hIcon), &ii32);
1854 iconinfo->fIcon = ii32.fIcon;
1855 iconinfo->xHotspot = ii32.xHotspot;
1856 iconinfo->yHotspot = ii32.yHotspot;
1857 iconinfo->hbmMask = HBITMAP_16(ii32.hbmMask);
1858 iconinfo->hbmColor = HBITMAP_16(ii32.hbmColor);
1863 /***********************************************************************
1864 * FinalUserInit (USER.400)
1866 void WINAPI FinalUserInit16( void )
1868 /* FIXME: Should chain to FinalGdiInit */
1872 /***********************************************************************
1873 * CreateCursor (USER.406)
1875 HCURSOR16 WINAPI CreateCursor16(HINSTANCE16 hInstance,
1876 INT16 xHotSpot, INT16 yHotSpot,
1877 INT16 nWidth, INT16 nHeight,
1878 LPCVOID lpANDbits, LPCVOID lpXORbits)
1880 CURSORICONINFO info;
1882 info.ptHotSpot.x = xHotSpot;
1883 info.ptHotSpot.y = yHotSpot;
1884 info.nWidth = nWidth;
1885 info.nHeight = nHeight;
1886 info.nWidthBytes = 0;
1888 info.bBitsPerPixel = 1;
1890 return CreateCursorIconIndirect16(hInstance, &info, lpANDbits, lpXORbits);
1894 /***********************************************************************
1895 * CreateIcon (USER.407)
1897 HICON16 WINAPI CreateIcon16( HINSTANCE16 hInstance, INT16 nWidth,
1898 INT16 nHeight, BYTE bPlanes, BYTE bBitsPixel,
1899 LPCVOID lpANDbits, LPCVOID lpXORbits )
1901 static const WORD ICON_HOTSPOT = 0x4242;
1902 CURSORICONINFO info;
1904 info.ptHotSpot.x = ICON_HOTSPOT;
1905 info.ptHotSpot.y = ICON_HOTSPOT;
1906 info.nWidth = nWidth;
1907 info.nHeight = nHeight;
1908 info.nWidthBytes = 0;
1909 info.bPlanes = bPlanes;
1910 info.bBitsPerPixel = bBitsPixel;
1912 return CreateCursorIconIndirect16( hInstance, &info, lpANDbits, lpXORbits );
1916 /***********************************************************************
1917 * CreateCursorIconIndirect (USER.408)
1919 HGLOBAL16 WINAPI CreateCursorIconIndirect16( HINSTANCE16 hInstance,
1920 CURSORICONINFO *info,
1926 int sizeAnd, sizeXor;
1928 hInstance = GetExePtr( hInstance ); /* Make it a module handle */
1929 if (!lpXORbits || !lpANDbits || info->bPlanes != 1) return 0;
1930 info->nWidthBytes = get_bitmap_width_bytes(info->nWidth,info->bBitsPerPixel);
1931 sizeXor = info->nHeight * info->nWidthBytes;
1932 sizeAnd = info->nHeight * get_bitmap_width_bytes( info->nWidth, 1 );
1933 if (!(handle = GlobalAlloc16( GMEM_MOVEABLE,
1934 sizeof(CURSORICONINFO) + sizeXor + sizeAnd)))
1936 FarSetOwner16( handle, hInstance );
1937 ptr = GlobalLock16( handle );
1938 memcpy( ptr, info, sizeof(*info) );
1939 memcpy( ptr + sizeof(CURSORICONINFO), lpANDbits, sizeAnd );
1940 memcpy( ptr + sizeof(CURSORICONINFO) + sizeAnd, lpXORbits, sizeXor );
1941 GlobalUnlock16( handle );
1946 /***********************************************************************
1947 * InitThreadInput (USER.409)
1949 HQUEUE16 WINAPI InitThreadInput16( WORD unknown, WORD flags )
1951 /* nothing to do here */
1956 /*******************************************************************
1957 * InsertMenu (USER.410)
1959 BOOL16 WINAPI InsertMenu16( HMENU16 hMenu, UINT16 pos, UINT16 flags,
1960 UINT16 id, SEGPTR data )
1962 UINT pos32 = (UINT)pos;
1963 if ((pos == (UINT16)-1) && (flags & MF_BYPOSITION)) pos32 = (UINT)-1;
1964 if (IS_MENU_STRING_ITEM(flags) && data)
1965 return InsertMenuA( HMENU_32(hMenu), pos32, flags, id, MapSL(data) );
1966 return InsertMenuA( HMENU_32(hMenu), pos32, flags, id, (LPSTR)data );
1970 /*******************************************************************
1971 * AppendMenu (USER.411)
1973 BOOL16 WINAPI AppendMenu16(HMENU16 hMenu, UINT16 flags, UINT16 id, SEGPTR data)
1975 return InsertMenu16( hMenu, -1, flags | MF_BYPOSITION, id, data );
1979 /**********************************************************************
1980 * RemoveMenu (USER.412)
1982 BOOL16 WINAPI RemoveMenu16( HMENU16 hMenu, UINT16 nPos, UINT16 wFlags )
1984 return RemoveMenu( HMENU_32(hMenu), nPos, wFlags );
1988 /**********************************************************************
1989 * DeleteMenu (USER.413)
1991 BOOL16 WINAPI DeleteMenu16( HMENU16 hMenu, UINT16 nPos, UINT16 wFlags )
1993 return DeleteMenu( HMENU_32(hMenu), nPos, wFlags );
1997 /*******************************************************************
1998 * ModifyMenu (USER.414)
2000 BOOL16 WINAPI ModifyMenu16( HMENU16 hMenu, UINT16 pos, UINT16 flags,
2001 UINT16 id, SEGPTR data )
2003 if (IS_MENU_STRING_ITEM(flags))
2004 return ModifyMenuA( HMENU_32(hMenu), pos, flags, id, MapSL(data) );
2005 return ModifyMenuA( HMENU_32(hMenu), pos, flags, id, (LPSTR)data );
2009 /**********************************************************************
2010 * CreatePopupMenu (USER.415)
2012 HMENU16 WINAPI CreatePopupMenu16(void)
2014 return HMENU_16( CreatePopupMenu() );
2018 /**********************************************************************
2019 * SetMenuItemBitmaps (USER.418)
2021 BOOL16 WINAPI SetMenuItemBitmaps16( HMENU16 hMenu, UINT16 nPos, UINT16 wFlags,
2022 HBITMAP16 hNewUnCheck, HBITMAP16 hNewCheck)
2024 return SetMenuItemBitmaps( HMENU_32(hMenu), nPos, wFlags,
2025 HBITMAP_32(hNewUnCheck), HBITMAP_32(hNewCheck) );
2029 /***********************************************************************
2030 * wvsprintf (USER.421)
2032 INT16 WINAPI wvsprintf16( LPSTR buffer, LPCSTR spec, VA_LIST16 args )
2034 WPRINTF_FORMAT format;
2039 LPCSTR lpcstr_view = NULL;
2045 if (*spec != '%') { *p++ = *spec++; continue; }
2047 if (*spec == '%') { *p++ = *spec++; continue; }
2048 spec += parse_format( spec, &format );
2052 char_view = VA_ARG16( args, CHAR );
2053 len = format.precision = 1;
2056 seg_str = VA_ARG16( args, SEGPTR );
2057 if (IsBadReadPtr16( seg_str, 1 )) lpcstr_view = "";
2058 else lpcstr_view = MapSL( seg_str );
2059 if (!lpcstr_view) lpcstr_view = "(null)";
2060 for (len = 0; !format.precision || (len < format.precision); len++)
2061 if (!lpcstr_view[len]) break;
2062 format.precision = len;
2065 if (format.flags & WPRINTF_LONG) int_view = VA_ARG16( args, INT );
2066 else int_view = VA_ARG16( args, INT16 );
2067 len = sprintf( number, "%d", int_view );
2070 if (format.flags & WPRINTF_LONG) int_view = VA_ARG16( args, UINT );
2071 else int_view = VA_ARG16( args, UINT16 );
2072 len = sprintf( number, "%u", int_view );
2075 if (format.flags & WPRINTF_LONG) int_view = VA_ARG16( args, UINT );
2076 else int_view = VA_ARG16( args, UINT16 );
2077 len = sprintf( number, (format.flags & WPRINTF_UPPER_HEX) ? "%X" : "%x", int_view);
2082 if (format.precision < len) format.precision = len;
2083 if (format.flags & WPRINTF_LEFTALIGN) format.flags &= ~WPRINTF_ZEROPAD;
2084 if ((format.flags & WPRINTF_ZEROPAD) && (format.width > format.precision))
2085 format.precision = format.width;
2086 if (format.flags & WPRINTF_PREFIX_HEX) len += 2;
2089 if (!(format.flags & WPRINTF_LEFTALIGN))
2090 for (i = format.precision; i < format.width; i++) *p++ = ' ';
2095 /* wsprintf16 ignores null characters */
2096 if (*p != '\0') p++;
2097 else if (format.width > 1) *p++ = ' ';
2101 if (len) memcpy( p, lpcstr_view, len );
2105 if (format.flags & WPRINTF_PREFIX_HEX)
2108 *p++ = (format.flags & WPRINTF_UPPER_HEX) ? 'X' : 'x';
2113 /* Transfer the sign now, just in case it will be zero-padded*/
2114 if (number[0] == '-')
2121 for (i = len; i < format.precision; i++) *p++ = '0';
2122 if (len > sign) memcpy( p, number + sign, len - sign );
2128 if (format.flags & WPRINTF_LEFTALIGN)
2129 for (i = format.precision; i < format.width; i++) *p++ = ' ';
2136 /***********************************************************************
2137 * _wsprintf (USER.420)
2139 INT16 WINAPIV wsprintf16( LPSTR buffer, LPCSTR spec, VA_LIST16 valist )
2141 return wvsprintf16( buffer, spec, valist );
2145 /***********************************************************************
2146 * lstrcmp (USER.430)
2148 INT16 WINAPI lstrcmp16( LPCSTR str1, LPCSTR str2 )
2150 return strcmp( str1, str2 );
2154 /***********************************************************************
2155 * AnsiUpper (USER.431)
2157 SEGPTR WINAPI AnsiUpper16( SEGPTR strOrChar )
2159 /* uppercase only one char if strOrChar < 0x10000 */
2160 if (HIWORD(strOrChar))
2162 CharUpperA( MapSL(strOrChar) );
2165 else return (SEGPTR)CharUpperA( (LPSTR)strOrChar );
2169 /***********************************************************************
2170 * AnsiLower (USER.432)
2172 SEGPTR WINAPI AnsiLower16( SEGPTR strOrChar )
2174 /* lowercase only one char if strOrChar < 0x10000 */
2175 if (HIWORD(strOrChar))
2177 CharLowerA( MapSL(strOrChar) );
2180 else return (SEGPTR)CharLowerA( (LPSTR)strOrChar );
2184 /***********************************************************************
2185 * AnsiUpperBuff (USER.437)
2187 UINT16 WINAPI AnsiUpperBuff16( LPSTR str, UINT16 len )
2189 CharUpperBuffA( str, len ? len : 65536 );
2194 /***********************************************************************
2195 * AnsiLowerBuff (USER.438)
2197 UINT16 WINAPI AnsiLowerBuff16( LPSTR str, UINT16 len )
2199 CharLowerBuffA( str, len ? len : 65536 );
2204 /*******************************************************************
2205 * InsertMenuItem (USER.441)
2209 BOOL16 WINAPI InsertMenuItem16( HMENU16 hmenu, UINT16 pos, BOOL16 byposition,
2210 const MENUITEMINFO16 *mii )
2214 miia.cbSize = sizeof(miia);
2215 miia.fMask = mii->fMask;
2216 miia.dwTypeData = (LPSTR)mii->dwTypeData;
2217 miia.fType = mii->fType;
2218 miia.fState = mii->fState;
2219 miia.wID = mii->wID;
2220 miia.hSubMenu = HMENU_32(mii->hSubMenu);
2221 miia.hbmpChecked = HBITMAP_32(mii->hbmpChecked);
2222 miia.hbmpUnchecked = HBITMAP_32(mii->hbmpUnchecked);
2223 miia.dwItemData = mii->dwItemData;
2224 miia.cch = mii->cch;
2225 if (IS_MENU_STRING_ITEM(miia.fType))
2226 miia.dwTypeData = MapSL(mii->dwTypeData);
2227 return InsertMenuItemA( HMENU_32(hmenu), pos, byposition, &miia );
2231 /**********************************************************************
2232 * DrawState (USER.449)
2234 BOOL16 WINAPI DrawState16( HDC16 hdc, HBRUSH16 hbr, DRAWSTATEPROC16 func, LPARAM ldata,
2235 WPARAM16 wdata, INT16 x, INT16 y, INT16 cx, INT16 cy, UINT16 flags )
2237 struct draw_state_info info;
2238 UINT opcode = flags & 0xf;
2240 if (opcode == DST_TEXT || opcode == DST_PREFIXTEXT)
2242 /* make sure DrawStateA doesn't try to use ldata as a pointer */
2243 if (!wdata) wdata = strlen( MapSL(ldata) );
2247 if (!GetTextExtentPoint32A( HDC_32(hdc), MapSL(ldata), wdata, &s )) return FALSE;
2254 return DrawStateA( HDC_32(hdc), HBRUSH_32(hbr), draw_state_callback,
2255 (LPARAM)&info, wdata, x, y, cx, cy, flags );
2259 /**********************************************************************
2260 * CreateIconFromResourceEx (USER.450)
2262 * FIXME: not sure about exact parameter types
2264 HICON16 WINAPI CreateIconFromResourceEx16(LPBYTE bits, UINT16 cbSize,
2265 BOOL16 bIcon, DWORD dwVersion,
2266 INT16 width, INT16 height,
2269 return HICON_16(CreateIconFromResourceEx(bits, cbSize, bIcon, dwVersion,
2270 width, height, cFlag));
2274 /***********************************************************************
2275 * AdjustWindowRectEx (USER.454)
2277 BOOL16 WINAPI AdjustWindowRectEx16( LPRECT16 rect, DWORD style, BOOL16 menu, DWORD exStyle )
2282 rect32.left = rect->left;
2283 rect32.top = rect->top;
2284 rect32.right = rect->right;
2285 rect32.bottom = rect->bottom;
2286 ret = AdjustWindowRectEx( &rect32, style, menu, exStyle );
2287 rect->left = rect32.left;
2288 rect->top = rect32.top;
2289 rect->right = rect32.right;
2290 rect->bottom = rect32.bottom;
2295 /**********************************************************************
2296 * GetIconID (USER.455)
2298 WORD WINAPI GetIconID16( HGLOBAL16 hResource, DWORD resType )
2300 BYTE *dir = GlobalLock16(hResource);
2305 return LookupIconIdFromDirectoryEx16( dir, FALSE, GetSystemMetrics(SM_CXCURSOR),
2306 GetSystemMetrics(SM_CYCURSOR), LR_MONOCHROME );
2308 return LookupIconIdFromDirectoryEx16( dir, TRUE, GetSystemMetrics(SM_CXICON),
2309 GetSystemMetrics(SM_CYICON), 0 );
2315 /**********************************************************************
2316 * LoadIconHandler (USER.456)
2318 HICON16 WINAPI LoadIconHandler16( HGLOBAL16 hResource, BOOL16 bNew )
2320 LPBYTE bits = LockResource16( hResource );
2321 return HICON_16(CreateIconFromResourceEx( bits, 0, TRUE,
2322 bNew ? 0x00030000 : 0x00020000, 0, 0, LR_DEFAULTCOLOR));
2326 /***********************************************************************
2327 * DestroyIcon (USER.457)
2329 BOOL16 WINAPI DestroyIcon16(HICON16 hIcon)
2333 TRACE("%04x\n", hIcon );
2335 count = release_shared_icon( hIcon );
2336 if (count != -1) return !count;
2337 /* assume non-shared */
2338 GlobalFree16( hIcon );
2342 /***********************************************************************
2343 * DestroyCursor (USER.458)
2345 BOOL16 WINAPI DestroyCursor16(HCURSOR16 hCursor)
2347 return DestroyIcon16( hCursor );
2351 /***********************************************************************
2352 * DumpIcon (USER.459)
2354 DWORD WINAPI DumpIcon16( SEGPTR pInfo, WORD *lpLen,
2355 SEGPTR *lpXorBits, SEGPTR *lpAndBits )
2357 CURSORICONINFO *info = MapSL( pInfo );
2358 int sizeAnd, sizeXor;
2360 if (!info) return 0;
2361 sizeXor = info->nHeight * info->nWidthBytes;
2362 sizeAnd = info->nHeight * get_bitmap_width_bytes( info->nWidth, 1 );
2363 if (lpAndBits) *lpAndBits = pInfo + sizeof(CURSORICONINFO);
2364 if (lpXorBits) *lpXorBits = pInfo + sizeof(CURSORICONINFO) + sizeAnd;
2365 if (lpLen) *lpLen = sizeof(CURSORICONINFO) + sizeAnd + sizeXor;
2366 return MAKELONG( sizeXor, sizeXor );
2370 /*******************************************************************
2371 * DRAG_QueryUpdate16
2373 * Recursively find a child that contains spDragInfo->pt point
2374 * and send WM_QUERYDROPOBJECT. Helper for DragObject16.
2376 static BOOL DRAG_QueryUpdate16( HWND hQueryWnd, SEGPTR spDragInfo )
2381 LPDRAGINFO16 ptrDragInfo = MapSL(spDragInfo);
2385 if (!IsWindowEnabled(hQueryWnd)) return FALSE;
2387 old_pt.x = ptrDragInfo->pt.x;
2388 old_pt.y = ptrDragInfo->pt.y;
2390 ScreenToClient( hQueryWnd, &pt );
2391 child = ChildWindowFromPointEx( hQueryWnd, pt, CWP_SKIPINVISIBLE );
2392 if (!child) return FALSE;
2394 if (child != hQueryWnd)
2397 if (DRAG_QueryUpdate16( child, spDragInfo )) return TRUE;
2401 GetClientRect( hQueryWnd, &tempRect );
2402 wParam = !PtInRect( &tempRect, pt );
2405 ptrDragInfo->pt.x = pt.x;
2406 ptrDragInfo->pt.y = pt.y;
2407 ptrDragInfo->hScope = HWND_16(hQueryWnd);
2409 bResult = SendMessage16( HWND_16(hQueryWnd), WM_QUERYDROPOBJECT, wParam, spDragInfo );
2413 ptrDragInfo->pt.x = old_pt.x;
2414 ptrDragInfo->pt.y = old_pt.y;
2420 /******************************************************************************
2421 * DragObject (USER.464)
2423 DWORD WINAPI DragObject16( HWND16 hwndScope, HWND16 hWnd, UINT16 wObj,
2424 HANDLE16 hOfStruct, WORD szList, HCURSOR16 hCursor )
2427 LPDRAGINFO16 lpDragInfo;
2429 HCURSOR hOldCursor=0, hBummer=0;
2430 HGLOBAL16 hDragInfo = GlobalAlloc16( GMEM_SHARE | GMEM_ZEROINIT, 2*sizeof(DRAGINFO16));
2431 HCURSOR hCurrentCursor = 0;
2432 HWND16 hCurrentWnd = 0;
2434 lpDragInfo = (LPDRAGINFO16) GlobalLock16(hDragInfo);
2435 spDragInfo = WOWGlobalLock16(hDragInfo);
2437 if( !lpDragInfo || !spDragInfo ) return 0L;
2439 if (!(hBummer = LoadCursorA(0, MAKEINTRESOURCEA(OCR_NO))))
2441 GlobalFree16(hDragInfo);
2445 if(hCursor) hOldCursor = SetCursor(HCURSOR_32(hCursor));
2447 lpDragInfo->hWnd = hWnd;
2448 lpDragInfo->hScope = 0;
2449 lpDragInfo->wFlags = wObj;
2450 lpDragInfo->hList = szList; /* near pointer! */
2451 lpDragInfo->hOfStruct = hOfStruct;
2454 SetCapture( HWND_32(hWnd) );
2459 GetMessageW( &msg, 0, WM_MOUSEFIRST, WM_MOUSELAST );
2461 *(lpDragInfo+1) = *lpDragInfo;
2463 lpDragInfo->pt.x = msg.pt.x;
2464 lpDragInfo->pt.y = msg.pt.y;
2466 /* update DRAGINFO struct */
2467 if( DRAG_QueryUpdate16(WIN_Handle32(hwndScope), spDragInfo) > 0 )
2468 hCurrentCursor = HCURSOR_32(hCursor);
2471 hCurrentCursor = hBummer;
2472 lpDragInfo->hScope = 0;
2474 if( hCurrentCursor )
2475 SetCursor(hCurrentCursor);
2477 /* send WM_DRAGLOOP */
2478 SendMessage16( hWnd, WM_DRAGLOOP, (WPARAM16)(hCurrentCursor != hBummer),
2479 (LPARAM) spDragInfo );
2480 /* send WM_DRAGSELECT or WM_DRAGMOVE */
2481 if( hCurrentWnd != lpDragInfo->hScope )
2484 SendMessage16( hCurrentWnd, WM_DRAGSELECT, 0,
2485 (LPARAM)MAKELONG(LOWORD(spDragInfo)+sizeof(DRAGINFO16),
2486 HIWORD(spDragInfo)) );
2487 hCurrentWnd = lpDragInfo->hScope;
2489 SendMessage16( hCurrentWnd, WM_DRAGSELECT, 1, (LPARAM)spDragInfo);
2493 SendMessage16( hCurrentWnd, WM_DRAGMOVE, 0, (LPARAM)spDragInfo);
2495 } while( msg.message != WM_LBUTTONUP && msg.message != WM_NCLBUTTONUP );
2498 ShowCursor( FALSE );
2500 if( hCursor ) SetCursor(hOldCursor);
2502 if( hCurrentCursor != hBummer )
2503 msg.lParam = SendMessage16( lpDragInfo->hScope, WM_DROPOBJECT,
2504 (WPARAM16)hWnd, (LPARAM)spDragInfo );
2507 GlobalFree16(hDragInfo);
2509 return (DWORD)(msg.lParam);
2513 /***********************************************************************
2514 * DrawFocusRect (USER.466)
2516 void WINAPI DrawFocusRect16( HDC16 hdc, const RECT16* rc )
2520 rect32.left = rc->left;
2521 rect32.top = rc->top;
2522 rect32.right = rc->right;
2523 rect32.bottom = rc->bottom;
2524 DrawFocusRect( HDC_32(hdc), &rect32 );
2528 /***********************************************************************
2529 * AnsiNext (USER.472)
2531 SEGPTR WINAPI AnsiNext16(SEGPTR current)
2533 char *ptr = MapSL(current);
2534 return current + (CharNextA(ptr) - ptr);
2538 /***********************************************************************
2539 * AnsiPrev (USER.473)
2541 SEGPTR WINAPI AnsiPrev16( LPCSTR start, SEGPTR current )
2543 char *ptr = MapSL(current);
2544 return current - (ptr - CharPrevA( start, ptr ));
2548 /****************************************************************************
2549 * GetKeyboardLayoutName (USER.477)
2551 INT16 WINAPI GetKeyboardLayoutName16( LPSTR name )
2553 return GetKeyboardLayoutNameA( name );
2557 /***********************************************************************
2558 * SystemParametersInfo (USER.483)
2560 BOOL16 WINAPI SystemParametersInfo16( UINT16 uAction, UINT16 uParam,
2561 LPVOID lpvParam, UINT16 fuWinIni )
2565 TRACE("(%u, %u, %p, %u)\n", uAction, uParam, lpvParam, fuWinIni);
2570 case SPI_GETSCREENSAVEACTIVE:
2571 case SPI_GETICONTITLEWRAP:
2572 case SPI_GETMENUDROPALIGNMENT:
2573 case SPI_GETFASTTASKSWITCH:
2574 case SPI_GETDRAGFULLWINDOWS:
2577 ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
2578 if (ret && lpvParam) *(BOOL16 *)lpvParam = tmp;
2583 case SPI_ICONHORIZONTALSPACING:
2584 case SPI_GETSCREENSAVETIMEOUT:
2585 case SPI_GETGRIDGRANULARITY:
2586 case SPI_GETKEYBOARDDELAY:
2587 case SPI_ICONVERTICALSPACING:
2590 ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
2591 if (ret && lpvParam) *(INT16 *)lpvParam = tmp;
2595 case SPI_GETKEYBOARDSPEED:
2596 case SPI_GETMOUSEHOVERWIDTH:
2597 case SPI_GETMOUSEHOVERHEIGHT:
2598 case SPI_GETMOUSEHOVERTIME:
2601 ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
2602 if (ret && lpvParam) *(WORD *)lpvParam = tmp;
2606 case SPI_GETICONTITLELOGFONT:
2609 ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
2610 if (ret && lpvParam) logfont_32_to_16( &tmp, (LPLOGFONT16)lpvParam );
2614 case SPI_GETNONCLIENTMETRICS:
2616 NONCLIENTMETRICSA tmp;
2617 LPNONCLIENTMETRICS16 lpnm16 = (LPNONCLIENTMETRICS16)lpvParam;
2618 if (lpnm16 && lpnm16->cbSize == sizeof(NONCLIENTMETRICS16))
2620 tmp.cbSize = sizeof(NONCLIENTMETRICSA);
2621 ret = SystemParametersInfoA( uAction, uParam, &tmp, fuWinIni );
2624 lpnm16->iBorderWidth = tmp.iBorderWidth;
2625 lpnm16->iScrollWidth = tmp.iScrollWidth;
2626 lpnm16->iScrollHeight = tmp.iScrollHeight;
2627 lpnm16->iCaptionWidth = tmp.iCaptionWidth;
2628 lpnm16->iCaptionHeight = tmp.iCaptionHeight;
2629 lpnm16->iSmCaptionWidth = tmp.iSmCaptionWidth;
2630 lpnm16->iSmCaptionHeight = tmp.iSmCaptionHeight;
2631 lpnm16->iMenuWidth = tmp.iMenuWidth;
2632 lpnm16->iMenuHeight = tmp.iMenuHeight;
2633 logfont_32_to_16( &tmp.lfCaptionFont, &lpnm16->lfCaptionFont );
2634 logfont_32_to_16( &tmp.lfSmCaptionFont, &lpnm16->lfSmCaptionFont );
2635 logfont_32_to_16( &tmp.lfMenuFont, &lpnm16->lfMenuFont );
2636 logfont_32_to_16( &tmp.lfStatusFont, &lpnm16->lfStatusFont );
2637 logfont_32_to_16( &tmp.lfMessageFont, &lpnm16->lfMessageFont );
2640 else /* winfile 95 sets cbSize to 340 */
2641 ret = SystemParametersInfoA( uAction, uParam, lpvParam, fuWinIni );
2645 case SPI_GETWORKAREA:
2648 ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
2649 if (ret && lpvParam)
2651 RECT16 *r16 = lpvParam;
2652 r16->left = tmp.left;
2654 r16->right = tmp.right;
2655 r16->bottom = tmp.bottom;
2661 ret = SystemParametersInfoA( uAction, uParam, lpvParam, fuWinIni );
2669 /***********************************************************************
2670 * FormatMessage (USER.606)
2672 DWORD WINAPI FormatMessage16(
2674 SEGPTR lpSource, /* [in] NOTE: not always a valid pointer */
2677 LPSTR lpBuffer, /* [out] NOTE: *((HLOCAL16*)) for FORMAT_MESSAGE_ALLOCATE_BUFFER*/
2679 LPDWORD args ) /* [in] NOTE: va_list *args */
2682 /* This implementation is completely dependent on the format of the va_list on x86 CPUs */
2686 DWORD width = dwFlags & FORMAT_MESSAGE_MAX_WIDTH_MASK;
2688 LPSTR allocstring = NULL;
2690 TRACE("(0x%x,%x,%d,0x%x,%p,%d,%p)\n",
2691 dwFlags,lpSource,dwMessageId,dwLanguageId,lpBuffer,nSize,args);
2692 if ((dwFlags & FORMAT_MESSAGE_FROM_SYSTEM)
2693 && (dwFlags & FORMAT_MESSAGE_FROM_HMODULE)) return 0;
2694 if ((dwFlags & FORMAT_MESSAGE_FROM_STRING)
2695 &&((dwFlags & FORMAT_MESSAGE_FROM_SYSTEM)
2696 || (dwFlags & FORMAT_MESSAGE_FROM_HMODULE))) return 0;
2698 if (width && width != FORMAT_MESSAGE_MAX_WIDTH_MASK)
2699 FIXME("line wrapping (%u) not supported.\n", width);
2701 if (dwFlags & FORMAT_MESSAGE_FROM_STRING)
2703 char *source = MapSL(lpSource);
2704 from = HeapAlloc( GetProcessHeap(), 0, strlen(source)+1 );
2705 strcpy( from, source );
2707 else if (dwFlags & FORMAT_MESSAGE_FROM_SYSTEM) {
2708 from = HeapAlloc( GetProcessHeap(),0,200 );
2709 sprintf(from,"Systemmessage, messageid = 0x%08x\n",dwMessageId);
2711 else if (dwFlags & FORMAT_MESSAGE_FROM_HMODULE) {
2713 HINSTANCE16 hinst16 = ((HINSTANCE16)lpSource & 0xffff);
2715 dwMessageId &= 0xFFFF;
2716 bufsize=LoadString16(hinst16,dwMessageId,NULL,0);
2718 from = HeapAlloc( GetProcessHeap(), 0, bufsize +1);
2719 LoadString16(hinst16,dwMessageId,from,bufsize+1);
2722 target = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, 100);
2726 #define ADD_TO_T(c) \
2728 if (t-target == talloced) {\
2729 target = HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,target,talloced*2);\
2730 t = target+talloced;\
2736 while (*f && !eos) {
2739 char *fmtstr,*x,*lastf;
2740 DWORD *argliststart;
2750 case '1':case '2':case '3':case '4':case '5':
2751 case '6':case '7':case '8':case '9':
2754 case '0':case '1':case '2':case '3':
2755 case '4':case '5':case '6':case '7':
2758 insertnr=insertnr*10+*f-'0';
2767 if (NULL!=(x=strchr(f,'!'))) {
2769 fmtstr=HeapAlloc(GetProcessHeap(),0,strlen(f)+2);
2770 sprintf(fmtstr,"%%%s",f);
2773 fmtstr=HeapAlloc(GetProcessHeap(),0,strlen(f)+2);
2774 sprintf(fmtstr,"%%%s",f);
2775 f+=strlen(f); /*at \0*/
2781 fmtstr=HeapAlloc( GetProcessHeap(), 0, 3 );
2782 strcpy( fmtstr, "%s" );
2787 LPSTR b = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sz = 100);
2789 argliststart=args+insertnr-1;
2791 /* CMF - This makes a BIG assumption about va_list */
2792 while ((ret = vsnprintf(b, sz, fmtstr, (va_list) argliststart) < 0) || (ret >= sz)) {
2793 sz = (ret == -1 ? sz + 100 : ret + 1);
2794 b = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, b, sz);
2796 for (x=b; *x; x++) ADD_TO_T(*x);
2797 HeapFree(GetProcessHeap(), 0, b);
2799 /* NULL args - copy formatstr
2802 while ((lastf<f)&&(*lastf)) {
2806 HeapFree(GetProcessHeap(),0,fmtstr);
2808 case '0': /* Just stop processing format string */
2812 case 'n': /* 16 bit version just outputs 'n' */
2817 } else { /* '\n' or '\r' gets mapped to "\r\n" */
2818 if(*f == '\n' || *f == '\r') {
2822 if(*f++ == '\r' && *f == '\n')
2832 talloced = strlen(target)+1;
2833 if (nSize && talloced<nSize) {
2834 target = HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,target,nSize);
2836 TRACE("-- %s\n",debugstr_a(target));
2837 if (dwFlags & FORMAT_MESSAGE_ALLOCATE_BUFFER) {
2838 /* nSize is the MINIMUM size */
2839 HLOCAL16 h = LocalAlloc16(LPTR,talloced);
2840 SEGPTR ptr = LocalLock16(h);
2841 allocstring = MapSL( ptr );
2842 memcpy( allocstring,target,talloced);
2844 *((HLOCAL16*)lpBuffer) = h;
2846 lstrcpynA(lpBuffer,target,nSize);
2847 HeapFree(GetProcessHeap(),0,target);
2848 HeapFree(GetProcessHeap(),0,from);
2849 return (dwFlags & FORMAT_MESSAGE_ALLOCATE_BUFFER) ?
2850 strlen(allocstring):
2854 #endif /* __i386__ */
2859 /**********************************************************************
2860 * DestroyIcon32 (USER.610)
2862 * This routine is actually exported from Win95 USER under the name
2863 * DestroyIcon32 ... The behaviour implemented here should mimic
2864 * the Win95 one exactly, especially the return values, which
2865 * depend on the setting of various flags.
2867 WORD WINAPI DestroyIcon32( HGLOBAL16 handle, UINT16 flags )
2871 /* Check whether destroying active cursor */
2873 if (GetCursor16() == handle)
2875 WARN("Destroying active cursor!\n" );
2879 /* Try shared cursor/icon first */
2881 if (!(flags & CID_NONSHARED))
2883 INT count = release_shared_icon( handle );
2885 return (flags & CID_WIN32) ? TRUE : (count == 0);
2888 /* Now assume non-shared cursor/icon */
2890 retv = GlobalFree16( handle );
2891 return (flags & CID_RESOURCE)? retv : TRUE;
2895 /***********************************************************************
2896 * ChangeDisplaySettings (USER.620)
2898 LONG WINAPI ChangeDisplaySettings16( LPDEVMODEA devmode, DWORD flags )
2900 return ChangeDisplaySettingsA( devmode, flags );
2904 /***********************************************************************
2905 * EnumDisplaySettings (USER.621)
2907 BOOL16 WINAPI EnumDisplaySettings16( LPCSTR name, DWORD n, LPDEVMODEA devmode )
2909 return EnumDisplaySettingsA( name, n, devmode );
2912 /**********************************************************************
2913 * DrawFrameControl (USER.656)
2915 BOOL16 WINAPI DrawFrameControl16( HDC16 hdc, LPRECT16 rc, UINT16 uType, UINT16 uState )
2920 rect32.left = rc->left;
2921 rect32.top = rc->top;
2922 rect32.right = rc->right;
2923 rect32.bottom = rc->bottom;
2924 ret = DrawFrameControl( HDC_32(hdc), &rect32, uType, uState );
2925 rc->left = rect32.left;
2926 rc->top = rect32.top;
2927 rc->right = rect32.right;
2928 rc->bottom = rect32.bottom;
2932 /**********************************************************************
2933 * DrawEdge (USER.659)
2935 BOOL16 WINAPI DrawEdge16( HDC16 hdc, LPRECT16 rc, UINT16 edge, UINT16 flags )
2940 rect32.left = rc->left;
2941 rect32.top = rc->top;
2942 rect32.right = rc->right;
2943 rect32.bottom = rc->bottom;
2944 ret = DrawEdge( HDC_32(hdc), &rect32, edge, flags );
2945 rc->left = rect32.left;
2946 rc->top = rect32.top;
2947 rc->right = rect32.right;
2948 rc->bottom = rect32.bottom;
2952 /**********************************************************************
2953 * CheckMenuRadioItem (USER.666)
2955 BOOL16 WINAPI CheckMenuRadioItem16(HMENU16 hMenu, UINT16 first, UINT16 last,
2956 UINT16 check, BOOL16 bypos)
2958 return CheckMenuRadioItem( HMENU_32(hMenu), first, last, check, bypos );