Added version information.
[wine] / dlls / user / user16.c
1 /*
2  * Misc 16-bit USER functions
3  *
4  * Copyright 2002 Patrik Stridvall
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include <stdlib.h>
22 #include "wine/winuser16.h"
23 #include "winbase.h"
24 #include "wownt32.h"
25 #include "user.h"
26 #include "win.h"
27
28 /* handle to handle 16 conversions */
29 #define HANDLE_16(h32)          (LOWORD(h32))
30
31 /* handle16 to handle conversions */
32 #define HANDLE_32(h16)          ((HANDLE)(ULONG_PTR)(h16))
33 #define HINSTANCE_32(h16)       ((HINSTANCE)(ULONG_PTR)(h16))
34
35 #define IS_MENU_STRING_ITEM(flags) \
36     (((flags) & (MF_STRING | MF_BITMAP | MF_OWNERDRAW | MF_SEPARATOR)) == MF_STRING)
37
38 WORD WINAPI DestroyIcon32(HGLOBAL16, UINT16);
39
40
41 struct gray_string_info
42 {
43     GRAYSTRINGPROC16 proc;
44     LPARAM           param;
45     char             str[1];
46 };
47
48 /* callback for 16-bit gray string proc with opaque pointer */
49 static BOOL CALLBACK gray_string_callback( HDC hdc, LPARAM param, INT len )
50 {
51     const struct gray_string_info *info = (struct gray_string_info *)param;
52     WORD args[4];
53     DWORD ret;
54
55     args[3] = HDC_16(hdc);
56     args[2] = HIWORD(info->param);
57     args[1] = LOWORD(info->param);
58     args[0] = len;
59     WOWCallback16Ex( (DWORD)info->proc, WCB16_PASCAL, sizeof(args), args, &ret );
60     return LOWORD(ret);
61 }
62
63 /* callback for 16-bit gray string proc with string pointer */
64 static BOOL CALLBACK gray_string_callback_ptr( HDC hdc, LPARAM param, INT len )
65 {
66     const struct gray_string_info *info;
67     char *str = (char *)param;
68
69     info = (struct gray_string_info *)(str - offsetof( struct gray_string_info, str ));
70     return gray_string_callback( hdc, (LPARAM)info, len );
71 }
72
73 struct draw_state_info
74 {
75     DRAWSTATEPROC16 proc;
76     LPARAM          param;
77 };
78
79 /* callback for 16-bit DrawState functions */
80 static BOOL CALLBACK draw_state_callback( HDC hdc, LPARAM lparam, WPARAM wparam, int cx, int cy )
81 {
82     const struct draw_state_info *info = (struct draw_state_info *)lparam;
83     WORD args[6];
84     DWORD ret;
85
86     args[5] = HDC_16(hdc);
87     args[4] = HIWORD(info->param);
88     args[3] = LOWORD(info->param);
89     args[2] = wparam;
90     args[1] = cx;
91     args[0] = cy;
92     WOWCallback16Ex( (DWORD)info->proc, WCB16_PASCAL, sizeof(args), args, &ret );
93     return LOWORD(ret);
94 }
95
96 /***********************************************************************
97  *              SetCursor (USER.69)
98  */
99 HCURSOR16 WINAPI SetCursor16(HCURSOR16 hCursor)
100 {
101   return HCURSOR_16(SetCursor(HCURSOR_32(hCursor)));
102 }
103
104 /***********************************************************************
105  *              ShowCursor (USER.71)
106  */
107 INT16 WINAPI ShowCursor16(BOOL16 bShow)
108 {
109   return ShowCursor(bShow);
110 }
111
112 /***********************************************************************
113  *              DrawIcon (USER.84)
114  */
115 BOOL16 WINAPI DrawIcon16(HDC16 hdc, INT16 x, INT16 y, HICON16 hIcon)
116 {
117   return DrawIcon(HDC_32(hdc), x, y, HICON_32(hIcon));
118 }
119
120
121 /***********************************************************************
122  *           DrawText    (USER.85)
123  */
124 INT16 WINAPI DrawText16( HDC16 hdc, LPCSTR str, INT16 count, LPRECT16 rect, UINT16 flags )
125 {
126     INT16 ret;
127
128     if (rect)
129     {
130         RECT rect32;
131         CONV_RECT16TO32( rect, &rect32 );
132         ret = DrawTextA( HDC_32(hdc), str, count, &rect32, flags );
133         CONV_RECT32TO16( &rect32, rect );
134     }
135     else ret = DrawTextA( HDC_32(hdc), str, count, NULL, flags);
136     return ret;
137 }
138
139
140 /***********************************************************************
141  *              IconSize (USER.86)
142  *
143  * See "Undocumented Windows". Used by W2.0 paint.exe.
144  */
145 DWORD WINAPI IconSize16(void)
146 {
147   return MAKELONG(GetSystemMetrics(SM_CYICON), GetSystemMetrics(SM_CXICON));
148 }
149
150
151 /**********************************************************************
152  *         CreateMenu    (USER.151)
153  */
154 HMENU16 WINAPI CreateMenu16(void)
155 {
156     return HMENU_16( CreateMenu() );
157 }
158
159
160 /**********************************************************************
161  *         DestroyMenu    (USER.152)
162  */
163 BOOL16 WINAPI DestroyMenu16( HMENU16 hMenu )
164 {
165     return DestroyMenu( HMENU_32(hMenu) );
166 }
167
168
169 /*******************************************************************
170  *         ChangeMenu    (USER.153)
171  */
172 BOOL16 WINAPI ChangeMenu16( HMENU16 hMenu, UINT16 pos, SEGPTR data,
173                             UINT16 id, UINT16 flags )
174 {
175     if (flags & MF_APPEND) return AppendMenu16( hMenu, flags & ~MF_APPEND, id, data );
176
177     /* FIXME: Word passes the item id in 'pos' and 0 or 0xffff as id */
178     /* for MF_DELETE. We should check the parameters for all others */
179     /* MF_* actions also (anybody got a doc on ChangeMenu?). */
180
181     if (flags & MF_DELETE) return DeleteMenu16(hMenu, pos, flags & ~MF_DELETE);
182     if (flags & MF_CHANGE) return ModifyMenu16(hMenu, pos, flags & ~MF_CHANGE, id, data );
183     if (flags & MF_REMOVE) return RemoveMenu16(hMenu, flags & MF_BYPOSITION ? pos : id,
184                                                flags & ~MF_REMOVE );
185     /* Default: MF_INSERT */
186     return InsertMenu16( hMenu, pos, flags, id, data );
187 }
188
189
190 /*******************************************************************
191  *         CheckMenuItem    (USER.154)
192  */
193 BOOL16 WINAPI CheckMenuItem16( HMENU16 hMenu, UINT16 id, UINT16 flags )
194 {
195     return CheckMenuItem( HMENU_32(hMenu), id, flags );
196 }
197
198
199 /**********************************************************************
200  *         EnableMenuItem    (USER.155)
201  */
202 UINT16 WINAPI EnableMenuItem16( HMENU16 hMenu, UINT16 wItemID, UINT16 wFlags )
203 {
204     return EnableMenuItem( HMENU_32(hMenu), wItemID, wFlags );
205 }
206
207
208 /**********************************************************************
209  *         GetSubMenu    (USER.159)
210  */
211 HMENU16 WINAPI GetSubMenu16( HMENU16 hMenu, INT16 nPos )
212 {
213     return HMENU_16( GetSubMenu( HMENU_32(hMenu), nPos ) );
214 }
215
216
217 /*******************************************************************
218  *         GetMenuString    (USER.161)
219  */
220 INT16 WINAPI GetMenuString16( HMENU16 hMenu, UINT16 wItemID,
221                               LPSTR str, INT16 nMaxSiz, UINT16 wFlags )
222 {
223     return GetMenuStringA( HMENU_32(hMenu), wItemID, str, nMaxSiz, wFlags );
224 }
225
226
227 /**********************************************************************
228  *              WinHelp (USER.171)
229  */
230 BOOL16 WINAPI WinHelp16( HWND16 hWnd, LPCSTR lpHelpFile, UINT16 wCommand,
231                          DWORD dwData )
232 {
233     BOOL ret;
234     DWORD mutex_count;
235
236     /* We might call WinExec() */
237     ReleaseThunkLock(&mutex_count);
238
239     ret = WinHelpA(WIN_Handle32(hWnd), lpHelpFile, wCommand, (DWORD)MapSL(dwData));
240
241     RestoreThunkLock(mutex_count);
242     return ret;
243 }
244
245
246 /***********************************************************************
247  *              LoadCursor (USER.173)
248  */
249 HCURSOR16 WINAPI LoadCursor16(HINSTANCE16 hInstance, LPCSTR name)
250 {
251   return HCURSOR_16(LoadCursorA(HINSTANCE_32(hInstance), name));
252 }
253
254
255 /***********************************************************************
256  *              LoadIcon (USER.174)
257  */
258 HICON16 WINAPI LoadIcon16(HINSTANCE16 hInstance, LPCSTR name)
259 {
260   return HICON_16(LoadIconA(HINSTANCE_32(hInstance), name));
261 }
262
263 /**********************************************************************
264  *              LoadBitmap (USER.175)
265  */
266 HBITMAP16 WINAPI LoadBitmap16(HINSTANCE16 hInstance, LPCSTR name)
267 {
268   return HBITMAP_16(LoadBitmapA(HINSTANCE_32(hInstance), name));
269 }
270
271
272 /***********************************************************************
273  *           GrayString   (USER.185)
274  */
275 BOOL16 WINAPI GrayString16( HDC16 hdc, HBRUSH16 hbr, GRAYSTRINGPROC16 gsprc,
276                             LPARAM lParam, INT16 cch, INT16 x, INT16 y,
277                             INT16 cx, INT16 cy )
278 {
279     BOOL ret;
280
281     if (!gsprc) return GrayStringA( HDC_32(hdc), HBRUSH_32(hbr), NULL,
282                                     (LPARAM)MapSL(lParam), cch, x, y, cx, cy );
283
284     if (cch == -1 || (cch && cx && cy))
285     {
286         /* lParam can be treated as an opaque pointer */
287         struct gray_string_info info;
288
289         info.proc  = gsprc;
290         info.param = lParam;
291         ret = GrayStringA( HDC_32(hdc), HBRUSH_32(hbr), gray_string_callback,
292                            (LPARAM)&info, cch, x, y, cx, cy );
293     }
294     else  /* here we need some string conversions */
295     {
296         char *str16 = MapSL(lParam);
297         struct gray_string_info *info;
298
299         if (!cch) cch = strlen(str16);
300         if (!(info = HeapAlloc( GetProcessHeap(), 0, sizeof(*info) + cch ))) return FALSE;
301         info->proc  = gsprc;
302         info->param = lParam;
303         memcpy( info->str, str16, cch );
304         ret = GrayStringA( HDC_32(hdc), HBRUSH_32(hbr), gray_string_callback_ptr,
305                            (LPARAM)info->str, cch, x, y, cx, cy );
306         HeapFree( GetProcessHeap(), 0, info );
307     }
308     return ret;
309 }
310
311
312 /***********************************************************************
313  *           TabbedTextOut    (USER.196)
314  */
315 LONG WINAPI TabbedTextOut16( HDC16 hdc, INT16 x, INT16 y, LPCSTR lpstr,
316                              INT16 count, INT16 nb_tabs, const INT16 *tabs16, INT16 tab_org )
317 {
318     LONG ret;
319     INT i, *tabs = HeapAlloc( GetProcessHeap(), 0, nb_tabs * sizeof(tabs) );
320     if (!tabs) return 0;
321     for (i = 0; i < nb_tabs; i++) tabs[i] = tabs16[i];
322     ret = TabbedTextOutA( HDC_32(hdc), x, y, lpstr, count, nb_tabs, tabs, tab_org );
323     HeapFree( GetProcessHeap(), 0, tabs );
324     return ret;
325 }
326
327
328 /***********************************************************************
329  *           GetTabbedTextExtent    (USER.197)
330  */
331 DWORD WINAPI GetTabbedTextExtent16( HDC16 hdc, LPCSTR lpstr, INT16 count,
332                                     INT16 nb_tabs, const INT16 *tabs16 )
333 {
334     LONG ret;
335     INT i, *tabs = HeapAlloc( GetProcessHeap(), 0, nb_tabs * sizeof(tabs) );
336     if (!tabs) return 0;
337     for (i = 0; i < nb_tabs; i++) tabs[i] = tabs16[i];
338     ret = GetTabbedTextExtentA( HDC_32(hdc), lpstr, count, nb_tabs, tabs );
339     HeapFree( GetProcessHeap(), 0, tabs );
340     return ret;
341 }
342
343
344 /*************************************************************************
345  *              ScrollDC (USER.221)
346  */
347 BOOL16 WINAPI ScrollDC16( HDC16 hdc, INT16 dx, INT16 dy, const RECT16 *rect,
348                           const RECT16 *cliprc, HRGN16 hrgnUpdate,
349                           LPRECT16 rcUpdate )
350 {
351     RECT rect32, clipRect32, rcUpdate32;
352     BOOL16 ret;
353
354     if (rect) CONV_RECT16TO32( rect, &rect32 );
355     if (cliprc) CONV_RECT16TO32( cliprc, &clipRect32 );
356     ret = ScrollDC( HDC_32(hdc), dx, dy, rect ? &rect32 : NULL,
357                     cliprc ? &clipRect32 : NULL, HRGN_32(hrgnUpdate),
358                     &rcUpdate32 );
359     if (rcUpdate) CONV_RECT32TO16( &rcUpdate32, rcUpdate );
360     return ret;
361 }
362
363 /***********************************************************************
364  *              GetCursor (USER.247)
365  */
366 HCURSOR16 WINAPI GetCursor16(void)
367 {
368   return HCURSOR_16(GetCursor());
369 }
370
371
372 /**********************************************************************
373  *         GetMenuState    (USER.250)
374  */
375 UINT16 WINAPI GetMenuState16( HMENU16 hMenu, UINT16 wItemID, UINT16 wFlags )
376 {
377     return GetMenuState( HMENU_32(hMenu), wItemID, wFlags );
378 }
379
380
381 /**********************************************************************
382  *         GetMenuItemCount    (USER.263)
383  */
384 INT16 WINAPI GetMenuItemCount16( HMENU16 hMenu )
385 {
386     return GetMenuItemCount( HMENU_32(hMenu) );
387 }
388
389
390 /**********************************************************************
391  *         GetMenuItemID    (USER.264)
392  */
393 UINT16 WINAPI GetMenuItemID16( HMENU16 hMenu, INT16 nPos )
394 {
395     return GetMenuItemID( HMENU_32(hMenu), nPos );
396 }
397
398
399 /***********************************************************************
400  *              GlobalAddAtom (USER.268)
401  */
402 ATOM WINAPI GlobalAddAtom16(LPCSTR lpString)
403 {
404   return GlobalAddAtomA(lpString);
405 }
406
407 /***********************************************************************
408  *              GlobalDeleteAtom (USER.269)
409  */
410 ATOM WINAPI GlobalDeleteAtom16(ATOM nAtom)
411 {
412   return GlobalDeleteAtom(nAtom);
413 }
414
415 /***********************************************************************
416  *              GlobalFindAtom (USER.270)
417  */
418 ATOM WINAPI GlobalFindAtom16(LPCSTR lpString)
419 {
420   return GlobalFindAtomA(lpString);
421 }
422
423 /***********************************************************************
424  *              GlobalGetAtomName (USER.271)
425  */
426 UINT16 WINAPI GlobalGetAtomName16(ATOM nAtom, LPSTR lpBuffer, INT16 nSize)
427 {
428   return GlobalGetAtomNameA(nAtom, lpBuffer, nSize);
429 }
430
431
432 /***********************************************************************
433  *              GetSysColorBrush (USER.281)
434  */
435 HBRUSH16 WINAPI GetSysColorBrush16( INT16 index )
436 {
437     return HBRUSH_16( GetSysColorBrush(index) );
438 }
439
440
441 /***********************************************************************
442  *              SelectPalette (USER.282)
443  */
444 HPALETTE16 WINAPI SelectPalette16( HDC16 hdc, HPALETTE16 hpal, BOOL16 bForceBackground )
445 {
446     return HPALETTE_16( SelectPalette( HDC_32(hdc), HPALETTE_32(hpal), bForceBackground ));
447 }
448
449 /***********************************************************************
450  *              RealizePalette (USER.283)
451  */
452 UINT16 WINAPI RealizePalette16( HDC16 hdc )
453 {
454     return UserRealizePalette( HDC_32(hdc) );
455 }
456
457
458 /**********************************************************************
459  *              IsMenu    (USER.358)
460  */
461 BOOL16 WINAPI IsMenu16( HMENU16 hmenu )
462 {
463     return IsMenu( HMENU_32(hmenu) );
464 }
465
466
467 /**********************************************************************
468  *         SetMenuContextHelpId    (USER.384)
469  */
470 BOOL16 WINAPI SetMenuContextHelpId16( HMENU16 hMenu, DWORD dwContextHelpID)
471 {
472     return SetMenuContextHelpId( HMENU_32(hMenu), dwContextHelpID );
473 }
474
475
476 /**********************************************************************
477  *         GetMenuContextHelpId    (USER.385)
478  */
479 DWORD WINAPI GetMenuContextHelpId16( HMENU16 hMenu )
480 {
481     return GetMenuContextHelpId( HMENU_32(hMenu) );
482 }
483
484
485 /***********************************************************************
486  *              LoadImage (USER.389)
487  *
488  */
489 HANDLE16 WINAPI LoadImage16(HINSTANCE16 hinst, LPCSTR name, UINT16 type,
490                             INT16 desiredx, INT16 desiredy, UINT16 loadflags)
491 {
492   return HANDLE_16(LoadImageA(HINSTANCE_32(hinst), name, type, desiredx,
493                               desiredy, loadflags));
494 }
495
496 /******************************************************************************
497  *              CopyImage (USER.390) Creates new image and copies attributes to it
498  *
499  */
500 HICON16 WINAPI CopyImage16(HANDLE16 hnd, UINT16 type, INT16 desiredx,
501                            INT16 desiredy, UINT16 flags)
502 {
503   return HICON_16(CopyImage(HANDLE_32(hnd), (UINT)type, (INT)desiredx,
504                             (INT)desiredy, (UINT)flags));
505 }
506
507 /**********************************************************************
508  *              DrawIconEx (USER.394)
509  */
510 BOOL16 WINAPI DrawIconEx16(HDC16 hdc, INT16 xLeft, INT16 yTop, HICON16 hIcon,
511                            INT16 cxWidth, INT16 cyWidth, UINT16 istep,
512                            HBRUSH16 hbr, UINT16 flags)
513 {
514   return DrawIconEx(HDC_32(hdc), xLeft, yTop, HICON_32(hIcon), cxWidth, cyWidth,
515                     istep, HBRUSH_32(hbr), flags);
516 }
517
518 /**********************************************************************
519  *              GetIconInfo (USER.395)
520  */
521 BOOL16 WINAPI GetIconInfo16(HICON16 hIcon, LPICONINFO16 iconinfo)
522 {
523   ICONINFO ii32;
524   BOOL16 ret = GetIconInfo(HICON_32(hIcon), &ii32);
525
526   iconinfo->fIcon = ii32.fIcon;
527   iconinfo->xHotspot = ii32.xHotspot;
528   iconinfo->yHotspot = ii32.yHotspot;
529   iconinfo->hbmMask  = HBITMAP_16(ii32.hbmMask);
530   iconinfo->hbmColor = HBITMAP_16(ii32.hbmColor);
531   return ret;
532 }
533
534 /***********************************************************************
535  *              CreateCursor (USER.406)
536  */
537 HCURSOR16 WINAPI CreateCursor16(HINSTANCE16 hInstance,
538                                 INT16 xHotSpot, INT16 yHotSpot,
539                                 INT16 nWidth, INT16 nHeight,
540                                 LPCVOID lpANDbits, LPCVOID lpXORbits)
541 {
542   CURSORICONINFO info;
543
544   info.ptHotSpot.x = xHotSpot;
545   info.ptHotSpot.y = yHotSpot;
546   info.nWidth = nWidth;
547   info.nHeight = nHeight;
548   info.nWidthBytes = 0;
549   info.bPlanes = 1;
550   info.bBitsPerPixel = 1;
551
552   return CreateCursorIconIndirect16(hInstance, &info, lpANDbits, lpXORbits);
553 }
554
555
556 /*******************************************************************
557  *         InsertMenu    (USER.410)
558  */
559 BOOL16 WINAPI InsertMenu16( HMENU16 hMenu, UINT16 pos, UINT16 flags,
560                             UINT16 id, SEGPTR data )
561 {
562     UINT pos32 = (UINT)pos;
563     if ((pos == (UINT16)-1) && (flags & MF_BYPOSITION)) pos32 = (UINT)-1;
564     if (IS_MENU_STRING_ITEM(flags) && data)
565         return InsertMenuA( HMENU_32(hMenu), pos32, flags, id, MapSL(data) );
566     return InsertMenuA( HMENU_32(hMenu), pos32, flags, id, (LPSTR)data );
567 }
568
569
570 /*******************************************************************
571  *         AppendMenu    (USER.411)
572  */
573 BOOL16 WINAPI AppendMenu16(HMENU16 hMenu, UINT16 flags, UINT16 id, SEGPTR data)
574 {
575     return InsertMenu16( hMenu, -1, flags | MF_BYPOSITION, id, data );
576 }
577
578
579 /**********************************************************************
580  *         RemoveMenu   (USER.412)
581  */
582 BOOL16 WINAPI RemoveMenu16( HMENU16 hMenu, UINT16 nPos, UINT16 wFlags )
583 {
584     return RemoveMenu( HMENU_32(hMenu), nPos, wFlags );
585 }
586
587
588 /**********************************************************************
589  *         DeleteMenu    (USER.413)
590  */
591 BOOL16 WINAPI DeleteMenu16( HMENU16 hMenu, UINT16 nPos, UINT16 wFlags )
592 {
593     return DeleteMenu( HMENU_32(hMenu), nPos, wFlags );
594 }
595
596
597 /*******************************************************************
598  *         ModifyMenu    (USER.414)
599  */
600 BOOL16 WINAPI ModifyMenu16( HMENU16 hMenu, UINT16 pos, UINT16 flags,
601                             UINT16 id, SEGPTR data )
602 {
603     if (IS_MENU_STRING_ITEM(flags))
604         return ModifyMenuA( HMENU_32(hMenu), pos, flags, id, MapSL(data) );
605     return ModifyMenuA( HMENU_32(hMenu), pos, flags, id, (LPSTR)data );
606 }
607
608
609 /**********************************************************************
610  *         CreatePopupMenu    (USER.415)
611  */
612 HMENU16 WINAPI CreatePopupMenu16(void)
613 {
614     return HMENU_16( CreatePopupMenu() );
615 }
616
617
618 /**********************************************************************
619  *         SetMenuItemBitmaps    (USER.418)
620  */
621 BOOL16 WINAPI SetMenuItemBitmaps16( HMENU16 hMenu, UINT16 nPos, UINT16 wFlags,
622                                     HBITMAP16 hNewUnCheck, HBITMAP16 hNewCheck)
623 {
624     return SetMenuItemBitmaps( HMENU_32(hMenu), nPos, wFlags,
625                                HBITMAP_32(hNewUnCheck), HBITMAP_32(hNewCheck) );
626 }
627
628
629 /*******************************************************************
630  *              InsertMenuItem   (USER.441)
631  *
632  * FIXME: untested
633  */
634 BOOL16 WINAPI InsertMenuItem16( HMENU16 hmenu, UINT16 pos, BOOL16 byposition,
635                                 const MENUITEMINFO16 *mii )
636 {
637     MENUITEMINFOA miia;
638
639     miia.cbSize        = sizeof(miia);
640     miia.fMask         = mii->fMask;
641     miia.dwTypeData    = (LPSTR)mii->dwTypeData;
642     miia.fType         = mii->fType;
643     miia.fState        = mii->fState;
644     miia.wID           = mii->wID;
645     miia.hSubMenu      = HMENU_32(mii->hSubMenu);
646     miia.hbmpChecked   = HBITMAP_32(mii->hbmpChecked);
647     miia.hbmpUnchecked = HBITMAP_32(mii->hbmpUnchecked);
648     miia.dwItemData    = mii->dwItemData;
649     miia.cch           = mii->cch;
650     if (IS_MENU_STRING_ITEM(miia.fType))
651         miia.dwTypeData = MapSL(mii->dwTypeData);
652     return InsertMenuItemA( HMENU_32(hmenu), pos, byposition, &miia );
653 }
654
655
656 /**********************************************************************
657  *           DrawState    (USER.449)
658  */
659 BOOL16 WINAPI DrawState16( HDC16 hdc, HBRUSH16 hbr, DRAWSTATEPROC16 func, LPARAM ldata,
660                            WPARAM16 wdata, INT16 x, INT16 y, INT16 cx, INT16 cy, UINT16 flags )
661 {
662     struct draw_state_info info;
663     UINT opcode = flags & 0xf;
664
665     if (opcode == DST_TEXT || opcode == DST_PREFIXTEXT)
666     {
667         /* make sure DrawStateA doesn't try to use ldata as a pointer */
668         if (!wdata) wdata = strlen( MapSL(ldata) );
669         if (!cx || !cy)
670         {
671             SIZE s;
672             if (!GetTextExtentPoint32A( HDC_32(hdc), MapSL(ldata), wdata, &s )) return FALSE;
673             if (!cx) cx = s.cx;
674             if (!cy) cy = s.cy;
675         }
676     }
677     info.proc  = func;
678     info.param = ldata;
679     return DrawStateA( HDC_32(hdc), HBRUSH_32(hbr), draw_state_callback,
680                        (LPARAM)&info, wdata, x, y, cx, cy, flags );
681 }
682
683
684 /**********************************************************************
685  *              CreateIconFromResourceEx (USER.450)
686  *
687  * FIXME: not sure about exact parameter types
688  */
689 HICON16 WINAPI CreateIconFromResourceEx16(LPBYTE bits, UINT16 cbSize,
690                                           BOOL16 bIcon, DWORD dwVersion,
691                                           INT16 width, INT16 height,
692                                           UINT16 cFlag)
693 {
694   return HICON_16(CreateIconFromResourceEx(bits, cbSize, bIcon, dwVersion,
695                                            width, height, cFlag));
696 }
697
698 /***********************************************************************
699  *              DestroyIcon (USER.457)
700  */
701 BOOL16 WINAPI DestroyIcon16(HICON16 hIcon)
702 {
703   return DestroyIcon32(hIcon, 0);
704 }
705
706 /***********************************************************************
707  *              DestroyCursor (USER.458)
708  */
709 BOOL16 WINAPI DestroyCursor16(HCURSOR16 hCursor)
710 {
711   return DestroyIcon32(hCursor, 0);
712 }
713
714 /*******************************************************************
715  *                      DRAG_QueryUpdate16
716  *
717  * Recursively find a child that contains spDragInfo->pt point
718  * and send WM_QUERYDROPOBJECT. Helper for DragObject16.
719  */
720 static BOOL DRAG_QueryUpdate16( HWND hQueryWnd, SEGPTR spDragInfo )
721 {
722     BOOL bResult = 0;
723     WPARAM wParam;
724     POINT pt, old_pt;
725     LPDRAGINFO16 ptrDragInfo = MapSL(spDragInfo);
726     RECT tempRect;
727     HWND child;
728
729     if (!IsWindowEnabled(hQueryWnd)) return FALSE;
730
731     old_pt.x = ptrDragInfo->pt.x;
732     old_pt.y = ptrDragInfo->pt.y;
733     pt = old_pt;
734     ScreenToClient( hQueryWnd, &pt );
735     child = ChildWindowFromPointEx( hQueryWnd, pt, CWP_SKIPINVISIBLE );
736     if (!child) return FALSE;
737
738     if (child != hQueryWnd)
739     {
740         wParam = 0;
741         if (DRAG_QueryUpdate16( child, spDragInfo )) return TRUE;
742     }
743     else
744     {
745         GetClientRect( hQueryWnd, &tempRect );
746         wParam = !PtInRect( &tempRect, pt );
747     }
748
749     ptrDragInfo->pt.x = pt.x;
750     ptrDragInfo->pt.y = pt.y;
751     ptrDragInfo->hScope = HWND_16(hQueryWnd);
752
753     bResult = SendMessage16( HWND_16(hQueryWnd), WM_QUERYDROPOBJECT, wParam, spDragInfo );
754
755     if (!bResult)
756     {
757         ptrDragInfo->pt.x = old_pt.x;
758         ptrDragInfo->pt.y = old_pt.y;
759     }
760     return bResult;
761 }
762
763
764 /******************************************************************************
765  *              DragObject (USER.464)
766  */
767 DWORD WINAPI DragObject16( HWND16 hwndScope, HWND16 hWnd, UINT16 wObj,
768                            HANDLE16 hOfStruct, WORD szList, HCURSOR16 hCursor )
769 {
770     MSG msg;
771     LPDRAGINFO16 lpDragInfo;
772     SEGPTR      spDragInfo;
773     HCURSOR     hOldCursor=0, hBummer=0;
774     HGLOBAL16   hDragInfo  = GlobalAlloc16( GMEM_SHARE | GMEM_ZEROINIT, 2*sizeof(DRAGINFO16));
775     HCURSOR     hCurrentCursor = 0;
776     HWND16      hCurrentWnd = 0;
777
778     lpDragInfo = (LPDRAGINFO16) GlobalLock16(hDragInfo);
779     spDragInfo = K32WOWGlobalLock16(hDragInfo);
780
781     if( !lpDragInfo || !spDragInfo ) return 0L;
782
783     if (!(hBummer = LoadCursorA(0, MAKEINTRESOURCEA(OCR_NO))))
784     {
785         GlobalFree16(hDragInfo);
786         return 0L;
787     }
788
789     if(hCursor) hOldCursor = SetCursor(HCURSOR_32(hCursor));
790
791     lpDragInfo->hWnd   = hWnd;
792     lpDragInfo->hScope = 0;
793     lpDragInfo->wFlags = wObj;
794     lpDragInfo->hList  = szList; /* near pointer! */
795     lpDragInfo->hOfStruct = hOfStruct;
796     lpDragInfo->l = 0L;
797
798     SetCapture( HWND_32(hWnd) );
799     ShowCursor( TRUE );
800
801     do
802     {
803         GetMessageW( &msg, 0, WM_MOUSEFIRST, WM_MOUSELAST );
804
805        *(lpDragInfo+1) = *lpDragInfo;
806
807         lpDragInfo->pt.x = msg.pt.x;
808         lpDragInfo->pt.y = msg.pt.y;
809
810         /* update DRAGINFO struct */
811         if( DRAG_QueryUpdate16(WIN_Handle32(hwndScope), spDragInfo) > 0 )
812             hCurrentCursor = HCURSOR_32(hCursor);
813         else
814         {
815             hCurrentCursor = hBummer;
816             lpDragInfo->hScope = 0;
817         }
818         if( hCurrentCursor )
819             SetCursor(hCurrentCursor);
820
821         /* send WM_DRAGLOOP */
822         SendMessage16( hWnd, WM_DRAGLOOP, (WPARAM16)(hCurrentCursor != hBummer),
823                                           (LPARAM) spDragInfo );
824         /* send WM_DRAGSELECT or WM_DRAGMOVE */
825         if( hCurrentWnd != lpDragInfo->hScope )
826         {
827             if( hCurrentWnd )
828                 SendMessage16( hCurrentWnd, WM_DRAGSELECT, 0,
829                        (LPARAM)MAKELONG(LOWORD(spDragInfo)+sizeof(DRAGINFO16),
830                                         HIWORD(spDragInfo)) );
831             hCurrentWnd = lpDragInfo->hScope;
832             if( hCurrentWnd )
833                 SendMessage16( hCurrentWnd, WM_DRAGSELECT, 1, (LPARAM)spDragInfo);
834         }
835         else
836             if( hCurrentWnd )
837                 SendMessage16( hCurrentWnd, WM_DRAGMOVE, 0, (LPARAM)spDragInfo);
838
839     } while( msg.message != WM_LBUTTONUP && msg.message != WM_NCLBUTTONUP );
840
841     ReleaseCapture();
842     ShowCursor( FALSE );
843
844     if( hCursor ) SetCursor(hOldCursor);
845
846     if( hCurrentCursor != hBummer )
847         msg.lParam = SendMessage16( lpDragInfo->hScope, WM_DROPOBJECT,
848                                    (WPARAM16)hWnd, (LPARAM)spDragInfo );
849     else
850         msg.lParam = 0;
851     GlobalFree16(hDragInfo);
852
853     return (DWORD)(msg.lParam);
854 }
855
856
857 /**********************************************************************
858  *          DrawFrameControl  (USER.656)
859  */
860 BOOL16 WINAPI DrawFrameControl16( HDC16 hdc, LPRECT16 rc, UINT16 uType, UINT16 uState )
861 {
862     RECT rect32;
863     BOOL ret;
864
865     CONV_RECT16TO32( rc, &rect32 );
866     ret = DrawFrameControl( HDC_32(hdc), &rect32, uType, uState );
867     CONV_RECT32TO16( &rect32, rc );
868     return ret;
869 }
870
871 /**********************************************************************
872  *          DrawEdge   (USER.659)
873  */
874 BOOL16 WINAPI DrawEdge16( HDC16 hdc, LPRECT16 rc, UINT16 edge, UINT16 flags )
875 {
876     RECT rect32;
877     BOOL ret;
878
879     CONV_RECT16TO32( rc, &rect32 );
880     ret = DrawEdge( HDC_32(hdc), &rect32, edge, flags );
881     CONV_RECT32TO16( &rect32, rc );
882     return ret;
883 }
884
885 /**********************************************************************
886  *              CheckMenuRadioItem (USER.666)
887  */
888 BOOL16 WINAPI CheckMenuRadioItem16(HMENU16 hMenu, UINT16 first, UINT16 last,
889                                    UINT16 check, BOOL16 bypos)
890 {
891      return CheckMenuRadioItem( HMENU_32(hMenu), first, last, check, bypos );
892 }