Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1876 lines
61 KiB

  1. /*++
  2. *
  3. * WOW v1.0
  4. *
  5. * Copyright (c) 1991, Microsoft Corporation
  6. *
  7. * WMSG16.C
  8. * WOW32 16-bit message thunks
  9. *
  10. * History:
  11. * Created 11-Mar-1991 by Jeff Parsons (jeffpar)
  12. * Changed 12-May-1992 by Mike Tricker (miketri) to add MultiMedia (un)thunks and messages
  13. --*/
  14. #include "precomp.h"
  15. #pragma hdrstop
  16. #include "wmtbl32.h"
  17. #ifdef FE_IME
  18. #include "wownls.h"
  19. #include "ime.h"
  20. #endif // FE_IME
  21. MODNAME(wmsg16.c);
  22. #define WIN30_STM_SETICON 0x400
  23. #define WIN30_STM_GETICON 0x401
  24. #define WIN30_EM_LINESCROLL 0x406 // WM_USER+6
  25. #define WIN30_EM_GETTHUMB 0x40e // WM_USER+14
  26. // See WARNING below!
  27. LPFNTHUNKMSG16 apfnThunkMsg16[] = {
  28. ThunkWMMsg16, // WOWCLASS_WIN16
  29. ThunkWMMsg16, // WOWCLASS_WIN16
  30. ThunkBMMsg16, // WOWCLASS_BUTTON
  31. ThunkCBMsg16, // WOWCLASS_COMBOBOX
  32. ThunkEMMsg16, // WOWCLASS_EDIT
  33. ThunkLBMsg16, // WOWCLASS_LISTBOX
  34. ThunkWMMsg16, // WOWCLASS_MDICLIENT
  35. ThunkSBMMsg16, // WOWCLASS_SCROLLBAR
  36. ThunkSTMsg16, // WOWCLASS_STATIC (presumably no messages generated)
  37. ThunkWMMsg16, // WOWCLASS_DESKTOP
  38. ThunkWMMsg16, // WOWCLASS_DIALOG
  39. ThunkWMMsg16, // WOWCLASS_ICONTITLE
  40. ThunkMNMsg16, // WOWCLASS_MENU
  41. ThunkWMMsg16, // WOWCLASS_SWITCHWND
  42. ThunkLBMsg16 // WOWCLASS_COMBOLBOX
  43. };
  44. // See WARNING below!
  45. LPFNUNTHUNKMSG16 apfnUnThunkMsg16[] = {
  46. UnThunkWMMsg16, // WOWCLASS_WIN16
  47. UnThunkWMMsg16, // WOWCLASS_WIN16
  48. UnThunkBMMsg16, // WOWCLASS_BUTTON
  49. UnThunkCBMsg16, // WOWCLASS_COMBOBOX
  50. UnThunkEMMsg16, // WOWCLASS_EDIT
  51. UnThunkLBMsg16, // WOWCLASS_LISTBOX
  52. UnThunkWMMsg16, // WOWCLASS_MDICLIENT
  53. UnThunkSBMMsg16,// WOWCLASS_SCROLLBAR
  54. UnThunkSTMsg16, // WOWCLASS_STATIC (presumably no messages generated)
  55. UnThunkWMMsg16, // WOWCLASS_DESKTOP
  56. UnThunkWMMsg16, // WOWCLASS_DIALOG
  57. UnThunkWMMsg16, // WOWCLASS_ICONTITLE
  58. UnThunkMNMsg16, // WOWCLASS_MENU
  59. UnThunkWMMsg16, // WOWCLASS_SWITCHWND
  60. UnThunkLBMsg16 // WOWCLASS_COMBOLBOX
  61. };
  62. //
  63. // WARNING! The above sequence and values must be maintained otherwise the
  64. // #defines in WALIAS.H must be changed. Same goes for table in WALIAS.C.
  65. //
  66. #ifdef DEBUG
  67. //
  68. // This function returns a pointer to a static buffer containing a generated
  69. // string. If the function is called twice and generates a string in both
  70. // cases, the second call will overwrite the buffer of the first call. If
  71. // this becomes a problem for us it would be easy to use an array of N
  72. // static buffers which are cycled through.
  73. //
  74. PSZ GetWMMsgName(UINT uMsg)
  75. {
  76. static char szStaticBuf[128];
  77. PSZ pszMsgName;
  78. uMsg = LOWORD(uMsg);
  79. pszMsgName = (uMsg < (unsigned)iMsgMax) ? aw32Msg[uMsg].lpszW32 : NULL;
  80. if (!pszMsgName) {
  81. if (uMsg < WM_USER) {
  82. sprintf(szStaticBuf, "(Unknown 0x%x)", uMsg);
  83. } else if (uMsg < 0xc000) {
  84. sprintf(szStaticBuf, "(WM_USER+0x%x)", uMsg - WM_USER);
  85. } else {
  86. char szAtomName[100];
  87. if ( ! GlobalGetAtomName((ATOM)uMsg, szAtomName, sizeof szAtomName) &&
  88. ! GetAtomName((ATOM)uMsg, szAtomName, sizeof szAtomName) ) {
  89. szAtomName[0] = 0;
  90. }
  91. sprintf(szStaticBuf, "(Atom 0x%x '%s')", uMsg, szAtomName);
  92. }
  93. pszMsgName = szStaticBuf;
  94. }
  95. return pszMsgName;
  96. }
  97. #endif
  98. // WARNING: This function may cause 16-bit memory movement, invalidating
  99. // flat pointers.
  100. HWND FASTCALL ThunkMsg16(LPMSGPARAMEX lpmpex)
  101. {
  102. BOOL f;
  103. register PWW pww = NULL;
  104. INT iClass;
  105. WORD wMsg = lpmpex->Parm16.WndProc.wMsg;
  106. lpmpex->uMsg = wMsg;
  107. lpmpex->uParam = INT32(lpmpex->Parm16.WndProc.wParam); // Sign extend
  108. lpmpex->lParam =lpmpex->Parm16.WndProc.lParam;
  109. lpmpex->hwnd = HWND32(lpmpex->Parm16.WndProc.hwnd);
  110. if (wMsg < WM_USER) {
  111. iClass = (aw32Msg[wMsg].lpfnM32 == WM32NoThunking) ?
  112. WOWCLASS_NOTHUNK : WOWCLASS_WIN16;
  113. }
  114. else {
  115. pww = FindPWW(lpmpex->hwnd);
  116. if (pww) {
  117. if (lpmpex->iMsgThunkClass) {
  118. iClass = lpmpex->iMsgThunkClass;
  119. } else {
  120. iClass = GETICLASS(pww, lpmpex->hwnd);
  121. }
  122. }
  123. else {
  124. iClass = 0;
  125. }
  126. }
  127. lpmpex->iClass = iClass;
  128. if (iClass == WOWCLASS_NOTHUNK) {
  129. f = TRUE;
  130. }
  131. else {
  132. lpmpex->lpfnUnThunk16 = apfnUnThunkMsg16[iClass]; // for optimization
  133. lpmpex->pww = pww;
  134. WOW32ASSERT(iClass <= NUMEL(apfnThunkMsg16));
  135. f = (apfnThunkMsg16[iClass])(lpmpex);
  136. }
  137. WOW32ASSERTMSG(f, " WARNING Will Robinson: 16-bit message thunk failure\n");
  138. return (f) ? lpmpex->hwnd : (HWND)NULL;
  139. }
  140. VOID FASTCALL UnThunkMsg16(LPMSGPARAMEX lpmpex)
  141. {
  142. if (MSG16NEEDSTHUNKING(lpmpex)) {
  143. (lpmpex->lpfnUnThunk16)(lpmpex);
  144. }
  145. return;
  146. }
  147. BOOL FASTCALL ThunkWMMsg16(LPMSGPARAMEX lpmpex)
  148. {
  149. WORD wParam = lpmpex->Parm16.WndProc.wParam;
  150. LONG lParam = lpmpex->Parm16.WndProc.lParam;
  151. PLONG plParamNew = &lpmpex->lParam;
  152. LOGDEBUG(6,(" Thunking 16-bit window message %s(%04x)\n", (LPSZ)GetWMMsgName(lpmpex->Parm16.WndProc.wMsg), lpmpex->Parm16.WndProc.wMsg));
  153. switch(lpmpex->Parm16.WndProc.wMsg) {
  154. case WM_ACTIVATE: // 006h, <SLPre, LS>
  155. case WM_VKEYTOITEM: // 02Eh, <SLPre,SLPost,LS>
  156. case WM_CHARTOITEM: // 02Fh, <SLPre,SLPost,LS>
  157. case WM_NCACTIVATE: // 086h, <SLPre, LS>
  158. case WM_BEGINDRAG: // 22Ch, <SLPre, LS>
  159. HIW(lpmpex->uParam) = HIWORD(lParam);
  160. *plParamNew = (LONG)HWND32(LOWORD(lParam));
  161. break;
  162. case WM_COMMAND: // 111h, <SLPre, LS>
  163. {
  164. LONG lParamNew;
  165. /*
  166. ** Some messages cannot be translated into 32-bit messages. If they
  167. ** cannot, we leave the lParam as it is, else we replace lParam with
  168. ** the correct HWND.
  169. */
  170. HIW(lpmpex->uParam) = HIWORD(lParam);
  171. lParamNew = FULLHWND32(LOWORD(lParam));
  172. if (lParamNew) {
  173. *plParamNew = lParamNew;
  174. }
  175. }
  176. break;
  177. case WM_SETFONT:
  178. lpmpex->uParam = (LONG) HFONT32(wParam);
  179. break;
  180. case WM_SYSTIMER:
  181. lpmpex->uParam = UINT32(wParam); // un-sign extend the timer ID
  182. break;
  183. case WM_SETTEXT: // 00Ch, <SLPre,SLPost >
  184. case WM_WININICHANGE: // 01Ah, <SLPre, LS>
  185. case WM_DEVMODECHANGE: // 01Bh, <SLPre, LS>
  186. {
  187. LONG lParamMap;
  188. GETPSZPTR(lParam, (LPSZ)lParamMap);
  189. *plParamNew = (LONG)AddParamMap(lParamMap, lParam);
  190. if (lParamMap != *plParamNew) {
  191. FREEPSZPTR((LPSZ)lParamMap);
  192. }
  193. }
  194. break;
  195. case WM_ACTIVATEAPP: // 01Ch
  196. if (lParam) {
  197. *plParamNew = (LONG)HTASK32(LOWORD(lParam));
  198. }
  199. break;
  200. case WM_GETTEXT: // 00Dh, <SLPre,SLPost,LS>
  201. //
  202. // SDM (standard dialog manager) used by WinRaid among others
  203. // has a bug where it claims it has 0x7fff bytes available
  204. // in the buffer on WM_GETTEXT, when in fact it has much less.
  205. // Below we intentionally defeat the limit check if the
  206. // sender claims 0x7fff bytes as the size. This is done on
  207. // the checked build only since the free build doesn't perform
  208. // limit checks.
  209. // DaveHart/ChandanC 9-Nov-93
  210. //
  211. #ifdef DEBUG
  212. GETVDMPTR(lParam, (wParam == 0x7fff) ? 0 : wParam, (LPSZ)*plParamNew);
  213. #else
  214. GETVDMPTR(lParam, wParam, (LPSZ)*plParamNew);
  215. #endif
  216. break;
  217. case WM_GETMINMAXINFO: // 024h, <SLPre,SLPost,LS>,MINMAXINFOSTRUCT
  218. *plParamNew = (LONG)lpmpex->MsgBuffer;
  219. ThunkWMGetMinMaxInfo16(lParam, (LPPOINT *)plParamNew);
  220. break;
  221. case WM_MDIGETACTIVE:
  222. //
  223. // not extremely important if it fails
  224. //
  225. *plParamNew = (LONG)&(lpmpex->MsgBuffer[0].msg.lParam);
  226. lpmpex->uParam = 0;
  227. break;
  228. case WM_GETDLGCODE:
  229. // NTRaid1 #9949 - Excel passes ptr to msg struct in lparam
  230. // Approach 3.1 also does this a-craigj
  231. if (lParam) {
  232. *plParamNew = (LONG)lpmpex->MsgBuffer;
  233. W32CopyMsgStruct( (VPMSG16)lParam,(LPMSG)*plParamNew, TRUE);
  234. }
  235. break;
  236. case WM_NEXTDLGCTL: // 028h
  237. if (lParam)
  238. lpmpex->uParam = (UINT) HWND32(wParam);
  239. break;
  240. case WM_DRAWITEM: // 02Bh notused, DRAWITEMSTRUCT
  241. if (lParam) {
  242. *plParamNew = (LONG)lpmpex->MsgBuffer;
  243. getdrawitem16((VPDRAWITEMSTRUCT16)lParam, (PDRAWITEMSTRUCT)*plParamNew);
  244. }
  245. break;
  246. case WM_MEASUREITEM: // 02Ch notused, MEASUREITEMSTRUCT
  247. if (lParam) {
  248. *plParamNew = (LONG)lpmpex->MsgBuffer;
  249. getmeasureitem16((VPMEASUREITEMSTRUCT16)lParam, (PMEASUREITEMSTRUCT)*plParamNew, lpmpex->Parm16.WndProc.hwnd);
  250. }
  251. break;
  252. case WM_DELETEITEM: // 02Dh notused, DELETEITEMSTRUCT
  253. if (lParam) {
  254. *plParamNew = (LONG)lpmpex->MsgBuffer;
  255. getdeleteitem16((VPDELETEITEMSTRUCT16)lParam, (PDELETEITEMSTRUCT)*plParamNew);
  256. }
  257. break;
  258. case WM_COMPAREITEM: // 039h
  259. if (lParam) {
  260. *plParamNew = (LONG)lpmpex->MsgBuffer;
  261. getcompareitem16((VPCOMPAREITEMSTRUCT16)lParam, (PCOMPAREITEMSTRUCT)*plParamNew);
  262. }
  263. break;
  264. case WM_WINHELP: // 038h private internal message
  265. if (lParam) {
  266. // lparam is LPHLP16, but we need only the size of data, the first word.
  267. // lparam32 is LPHLP. LPHLP and LPHLP16 are identical.
  268. PWORD16 lpT;
  269. GETVDMPTR(lParam, 0, lpT);
  270. if (lpT) {
  271. // assert: cbData is a WORD and is the 1st field in LPHLP struct
  272. WOW32ASSERT((OFFSETOF(HLP,cbData) == 0) &&
  273. (sizeof(((LPHLP)NULL)->cbData) == sizeof(WORD)));
  274. *plParamNew = (LONG)((*lpT > sizeof(lpmpex->MsgBuffer)) ?
  275. malloc_w(*lpT) : lpmpex->MsgBuffer);
  276. if (*plParamNew) {
  277. RtlCopyMemory((PVOID)*plParamNew, lpT, *lpT);
  278. }
  279. }
  280. FREEVDMPTR(lpT);
  281. }
  282. break;
  283. case WM_SIZING: // 0214h, <SLPre,SLPost,LS>,RECT
  284. if (lParam) {
  285. *plParamNew = (LONG)lpmpex->MsgBuffer;
  286. getrect16((VPRECT16)lParam, (LPRECT)*plParamNew);
  287. }
  288. break;
  289. case WM_NCCALCSIZE: // 083h, <SLPre,SLPost,LS>,RECT
  290. if (lParam) {
  291. *plParamNew = (LONG)lpmpex->MsgBuffer;
  292. getrect16((VPRECT16)lParam, (LPRECT)*plParamNew);
  293. if (wParam) {
  294. PNCCALCSIZE_PARAMS16 pnc16;
  295. PNCCALCSIZE_PARAMS16 lpnc16;
  296. LPNCCALCSIZE_PARAMS lpnc;
  297. lpnc = (LPNCCALCSIZE_PARAMS)*plParamNew;
  298. pnc16 = (PNCCALCSIZE_PARAMS16)lParam;
  299. getrect16((VPRECT16)(&pnc16->rgrc[1]), &lpnc->rgrc[1]);
  300. getrect16((VPRECT16)(&pnc16->rgrc[2]), &lpnc->rgrc[2]);
  301. lpnc->lppos = (LPWINDOWPOS)(lpnc+1);
  302. GETVDMPTR( pnc16, sizeof(NCCALCSIZE_PARAMS16), lpnc16 );
  303. getwindowpos16( (VPWINDOWPOS16)lpnc16->lppos, lpnc->lppos );
  304. FREEVDMPTR( lpnc16 );
  305. }
  306. }
  307. break;
  308. case WM_HSCROLL:
  309. case WM_VSCROLL:
  310. *plParamNew = (LONG) HWND32(HIWORD(lParam));
  311. #if 0
  312. if ((wParam == SB_THUMBPOSITION) || (wParam == SB_THUMBTRACK)) {
  313. HIW(lpmpex->uParam) = LOWORD(lParam);
  314. }
  315. else if (wParam > SB_ENDSCROLL) {
  316. // adding this '}' to balance the opening brace above.
  317. #else
  318. //
  319. // Ventura Publisher v4.1 setup program uses nPos on messages other
  320. // than SB_THUMBPOSITION and SB_THUMBTRACK. it doesn't hurt to
  321. // carry this word over.
  322. //
  323. if (wParam <= SB_ENDSCROLL) {
  324. HIW(lpmpex->uParam) = LOWORD(lParam);
  325. } else {
  326. #endif
  327. // implies wParam is NOT an SB_* scrollbar code.
  328. // this could be EM_GETTHUMB or EM_LINESCROLL
  329. // expensive way would be to check for class etc. Instead we
  330. // assume that wParam is one of the above EM_message and verify
  331. // that it is indeed so.
  332. if (wParam == WIN30_EM_GETTHUMB)
  333. lpmpex->uParam = EM_GETTHUMB;
  334. else if (wParam == WIN30_EM_LINESCROLL)
  335. lpmpex->uParam = EM_LINESCROLL;
  336. }
  337. break;
  338. case WM_PARENTNOTIFY:
  339. if ((wParam == WM_CREATE) || (wParam == WM_DESTROY)) {
  340. HIW(lpmpex->uParam) = HIWORD(lParam);
  341. *plParamNew = (LONG) HWND32(LOWORD(lParam));
  342. }
  343. break;
  344. case WM_MENUCHAR: // 120h
  345. LOW(lpmpex->uParam) = wParam;
  346. HIW(lpmpex->uParam) = LOWORD(lParam);
  347. *plParamNew = (LONG) HMENU32(HIWORD(lParam));
  348. break;
  349. case WM_SETFOCUS: // 007h, <SLPre, LS>
  350. case WM_KILLFOCUS: // 008h, <SLPre, LS>
  351. case WM_SETCURSOR: // 020h, <SLPre, LS>
  352. case WM_INITDIALOG: // 110h, <SLPre,SLPost,LS>
  353. case WM_MOUSEACTIVATE: // 021h, <SLPre,SLPost,LS>
  354. case WM_MDIDESTROY: // 221h, <SLPre, LS>
  355. case WM_MDIRESTORE: // 223h, <SLPre, LS>
  356. case WM_MDINEXT: // 224h, <SLPre, LS>
  357. case WM_MDIMAXIMIZE: // 225h, <SLPre, LS>
  358. case WM_VSCROLLCLIPBOARD: // 30Ah, <SLPre, LS>
  359. case WM_HSCROLLCLIPBOARD: // 30Eh, <SLPre, LS>
  360. case WM_PALETTECHANGED: // 311h, <SLPre, LS>
  361. case WM_PALETTEISCHANGING:
  362. lpmpex->uParam = (UINT)HWND32(wParam);
  363. break;
  364. case WM_DDE_REQUEST:
  365. case WM_DDE_TERMINATE:
  366. case WM_DDE_UNADVISE:
  367. lpmpex->uParam = (UINT)FULLHWND32(wParam);
  368. break;
  369. case WM_ASKCBFORMATNAME:
  370. /* BUGBUGBUG -- neither thunk or unthunk should be necessary,
  371. since the system does not process this message in DefWindowProc
  372. FritzS */
  373. lpmpex->uParam = (UINT) wParam;
  374. if (!(*plParamNew = (LPARAM)malloc_w(wParam))) {
  375. LOGDEBUG (0, ("WOW::WMSG16: WM_ASKCBFORMAT : Couldn't allocate 32 bit memory !\n"));
  376. WOW32ASSERT (FALSE);
  377. return FALSE;
  378. } else {
  379. getstr16((VPSZ)lParam, (LPSZ)(*plParamNew), wParam);
  380. }
  381. break;
  382. case WM_PAINTCLIPBOARD:
  383. case WM_SIZECLIPBOARD:
  384. {
  385. HANDLE hMem32 = NULL;
  386. VPVOID vp = 0;
  387. HAND16 hMem16 = 0;
  388. LPVOID lpMem32 = NULL;
  389. WORD wMsg = lpmpex->Parm16.WndProc.wMsg;
  390. lpmpex->uParam = (UINT) HWND32(wParam);
  391. hMem16 = LOWORD(lParam);
  392. vp = GlobalLock16(hMem16, NULL);
  393. if (vp) {
  394. hMem32 = WOWGLOBALALLOC(GMEM_DDESHARE, (wMsg == WM_SIZECLIPBOARD) ?
  395. sizeof(RECT) : sizeof(PAINTSTRUCT));
  396. if (hMem32) {
  397. if (lpMem32 = GlobalLock(hMem32)) {
  398. if (wMsg == WM_SIZECLIPBOARD) {
  399. GETRECT16(vp, (LPRECT)lpMem32);
  400. }
  401. else {
  402. getpaintstruct16(vp, (LPPAINTSTRUCT)lpMem32);
  403. }
  404. GlobalUnlock((HANDLE) hMem32);
  405. }
  406. else {
  407. WOWGLOBALFREE(hMem32);
  408. hMem32 = NULL;
  409. LOGDEBUG (0, ("WOW::WMSG16: WM_SIZE/PAINTCLIPBOARD : Couldn't lock 32 bit handle !\n"));
  410. WOW32ASSERT (FALSE);
  411. }
  412. }
  413. else {
  414. LOGDEBUG (0, ("WOW::WMSG16: WM_SIZE/PAINTCLIPBOARD : Couldn't allocate memory !\n"));
  415. WOW32ASSERT (FALSE);
  416. }
  417. GlobalUnlock16(hMem16);
  418. }
  419. else {
  420. LOGDEBUG (0, ("WOW::WMSG16: WM_SIZE/PAINTCLIPBOARD : Couldn't lock 16 bit handle !\n"));
  421. WOW32ASSERT (FALSE);
  422. }
  423. *plParamNew = (LONG) hMem32;
  424. }
  425. break;
  426. case WM_MDIACTIVATE:
  427. {
  428. BOOL fHwndIsMdiChild;
  429. if (lpmpex->iMsgThunkClass != WOWCLASS_MDICLIENT) {
  430. PWW pww;
  431. HWND hwnd32;
  432. // AMIPRO sends this message to its own window. If we thunk the
  433. // message the usual way, we will lose the information in
  434. // wParam and won't be able to regenerate the original message
  435. // when it comes back via w32win16wndproc. So the solution is
  436. // to determine this case and not thunk the message at all.
  437. // - nanduri
  438. // HYPERION sends this to its own DIALOG window. Added
  439. // WOWCLASS_DIALOG check. - sanfords
  440. //
  441. // Expensive checks.
  442. // No thunking If hwnd16 is of WOWCLASS and NOT MDICHILD.
  443. //
  444. hwnd32 = HWND32(lpmpex->Parm16.WndProc.hwnd);
  445. if (pww = (PWW)GetWindowLong(hwnd32, GWL_WOWWORDS)) {
  446. INT wClass;
  447. wClass = GETICLASS(pww, hwnd32);
  448. if ((wClass == WOWCLASS_WIN16 ||
  449. wClass == WOWCLASS_DIALOG)
  450. && (!(pww->ExStyle & WS_EX_MDICHILD))) {
  451. lpmpex->uMsg = WM_MDIACTIVATE | WOWPRIVATEMSG;
  452. break;
  453. }
  454. }
  455. }
  456. //
  457. // see the comment in 32-16 thunk for this message.
  458. //
  459. if (lParam) {
  460. //
  461. // Corel Chart doesn't set lParam to zero.
  462. // Instead HIWORD(lParam) = 0 and LOWORD(lParam) = wParam
  463. // If we do the normal child window processing, focus won't
  464. // change, because the wrong window handle will be in the
  465. // wParam for the 32 bit message. This would not be a problem,
  466. // except that win32 swapped the positions of the activate and
  467. // deactivate handles for the WM_MDIACTIVATE messages sent
  468. // to the child window. Under win31, the non-zero lParam is
  469. // ignored.
  470. //
  471. if ((CURRENTPTD()->dwWOWCompatFlags & WOWCF_WMMDIACTIVATEBUG) && (HIWORD(lParam) == 0) && (wParam == LOWORD(lParam))){
  472. fHwndIsMdiChild = FALSE;
  473. } else {
  474. fHwndIsMdiChild = TRUE;
  475. }
  476. }
  477. else {
  478. if (wParam && (lpmpex->Parm16.WndProc.hwnd == (HWND16)wParam)) {
  479. fHwndIsMdiChild = TRUE;
  480. }
  481. else {
  482. fHwndIsMdiChild = FALSE;
  483. }
  484. }
  485. if (fHwndIsMdiChild) {
  486. lpmpex->uParam = (UINT)FULLHWND32(HIWORD(lParam));
  487. *plParamNew = (UINT)FULLHWND32(LOWORD(lParam));
  488. }
  489. else {
  490. lpmpex->uParam = (UINT)FULLHWND32(wParam);
  491. *plParamNew = (UINT)0;
  492. }
  493. }
  494. break;
  495. case WM_MDISETMENU: // 230h
  496. // Refresh if wParam of WM_MDISETMENU is TRUE (the refresh flag)
  497. //
  498. if (wParam) {
  499. lpmpex->uMsg = WM_MDIREFRESHMENU;
  500. }
  501. lpmpex->uParam = (UINT)HMENU32(LOWORD(lParam));
  502. *plParamNew = (UINT)HMENU32(HIWORD(lParam));
  503. break;
  504. case WIN31_MM_CALCSCROLL: // 10ACh
  505. if (lpmpex->iClass == WOWCLASS_MDICLIENT) {
  506. lpmpex->uMsg = MM_CALCSCROLL;
  507. }
  508. break;
  509. case WM_MDITILE: // 226h
  510. /* if wParam contains garbage from Win3.0 apps */
  511. if(wParam & ~(MDITILE_VERTICAL|MDITILE_HORIZONTAL|MDITILE_SKIPDISABLED))
  512. lpmpex->uParam = MDITILE_SKIPDISABLED;
  513. break;
  514. case WM_MDICASCADE: // 227h
  515. lpmpex->uParam = MDITILE_SKIPDISABLED;
  516. break;
  517. case WM_ERASEBKGND: // 014h, < SLPost >
  518. case WM_ICONERASEBKGND: // 027h
  519. lpmpex->uParam = (UINT)HDC32(wParam);
  520. break;
  521. case WM_CTLCOLOR:
  522. // HIWORD(lParam) need not be a standard index. The app can pass any
  523. // value (PowerBuilder does so. MSGolf passes this message to
  524. // DefDlgProc() with HIWORD(lParam) == 62,66,67).
  525. //
  526. // If not in known range, leave it as WM_CTLCOLOR. There is code in
  527. // xxxDefWindowProc() & xxxDefDlgProc() that recognize this & return
  528. // us the value returned by the app when it processed this message.
  529. if (HIWORD(lParam) <= (WORD)(WM_CTLCOLORSTATIC - WM_CTLCOLORMSGBOX)) {
  530. lpmpex->hwnd = (HWND)FULLHWND32(GETHWND16(lpmpex->hwnd));
  531. lpmpex->uMsg = WM_CTLCOLORMSGBOX + HIWORD(lParam);
  532. lpmpex->uParam = (UINT)HDC32(wParam);
  533. *plParamNew = (LONG)HWND32(LOWORD(lParam));
  534. }
  535. break;
  536. case WM_SYSCOMMAND:
  537. case WM_SETREDRAW: // 027h
  538. lpmpex->uParam = wParam;
  539. break;
  540. case WM_INITMENU:
  541. case WM_INITMENUPOPUP: // 117h
  542. lpmpex->uParam = (UINT)HMENU32(wParam);
  543. break;
  544. case WM_NCCREATE:
  545. case WM_CREATE:
  546. {
  547. register LPCREATESTRUCT lpCreateStruct;
  548. register PCREATESTRUCT16 lpCreateStruct16;
  549. if (HIWORD(lParam)) {
  550. HWND hwnd32;
  551. PWW pww = NULL;
  552. lpCreateStruct = (LPCREATESTRUCT) lpmpex->MsgBuffer;
  553. // ChandanC check the return value !!!
  554. GETVDMPTR(lParam, sizeof(CREATESTRUCT16), lpCreateStruct16);
  555. lpCreateStruct->lpCreateParams = (LPSTR)FETCHDWORD(lpCreateStruct16->vpCreateParams);
  556. lpCreateStruct->hInstance = HMODINST32(lpCreateStruct16->hInstance);
  557. lpCreateStruct->hMenu = HMENU32(lpCreateStruct16->hMenu);
  558. lpCreateStruct->hwndParent = HWND32(lpCreateStruct16->hwndParent);
  559. lpCreateStruct->cy = (SHORT) lpCreateStruct16->cy;
  560. lpCreateStruct->cx = (SHORT) lpCreateStruct16->cx;
  561. lpCreateStruct->y = (SHORT) lpCreateStruct16->y;
  562. lpCreateStruct->x = (SHORT) lpCreateStruct16->x;
  563. lpCreateStruct->style = lpCreateStruct16->dwStyle;
  564. GETPSZPTR(lpCreateStruct16->vpszWindow, lpCreateStruct->lpszName);
  565. GETPSZIDPTR(lpCreateStruct16->vpszClass, lpCreateStruct->lpszClass);
  566. lpCreateStruct->dwExStyle = lpCreateStruct16->dwExStyle;
  567. *plParamNew = (LONG) lpCreateStruct;
  568. FREEVDMPTR(lpCreateStruct16);
  569. hwnd32 = HWND32(lpmpex->Parm16.WndProc.hwnd);
  570. pww = (PWW)GetWindowLong(hwnd32, GWL_WOWWORDS);
  571. if (lpCreateStruct->lpCreateParams && pww && (pww->ExStyle & WS_EX_MDICHILD)) {
  572. FinishThunkingWMCreateMDIChild16(*plParamNew,
  573. (LPMDICREATESTRUCT)(lpCreateStruct+1));
  574. }
  575. }
  576. }
  577. break;
  578. case WM_PAINT:
  579. case WM_NCPAINT:
  580. // 1 is MAXREGION special code in Win 3.1
  581. lpmpex->uParam = (wParam == 1) ? 1 : (UINT)HDC32(wParam);
  582. break;
  583. case WM_ENTERIDLE:
  584. if ((wParam == MSGF_DIALOGBOX) || (wParam == MSGF_MENU)) {
  585. *plParamNew = (LONG) HWND32(LOWORD(lParam));
  586. }
  587. break;
  588. case WM_MENUSELECT:
  589. // Copy menu flags
  590. HIW(lpmpex->uParam) = LOWORD(lParam);
  591. // Copy "main" menu
  592. *plParamNew = (LONG) HMENU32(HIWORD(lParam));
  593. if (LOWORD(lParam) == 0xFFFF || !(LOWORD(lParam) & MF_POPUP)) {
  594. LOW(lpmpex->uParam) = wParam; // copy ID
  595. } else {
  596. // convert menu to index
  597. LOW(lpmpex->uParam) =
  598. (WORD)(pfnOut.pfnGetMenuIndex)((HMENU)*plParamNew, HMENU32(wParam));
  599. }
  600. break;
  601. case WM_MDICREATE: // 220h, <SLPre,SLPost,LS>
  602. *plParamNew = (LONG)lpmpex->MsgBuffer;
  603. ThunkWMMDICreate16(lParam, (LPMDICREATESTRUCT *)plParamNew);
  604. break;
  605. // BUGBUG 25-Aug-91 JeffPar: Use of the Kludge variables was a temporary
  606. // measure, and only works for messages sent by Win32; for any WM
  607. // messages sent by 16-bit apps themselves, this will not work. Ultimately,
  608. // any messages you see being thunked in wmsg32.c will need equivalent
  609. // thunks here as well.
  610. case WM_DDE_INITIATE:
  611. lpmpex->uParam = (LONG) FULLHWND32(wParam);
  612. WI32DDEAddInitiator((HAND16) wParam);
  613. break;
  614. case WM_DDE_ACK:
  615. {
  616. WORD wMsg = lpmpex->Parm16.WndProc.wMsg;
  617. HWND16 hwnd16 = lpmpex->Parm16.WndProc.hwnd;
  618. lpmpex->uParam = (LONG) FULLHWND32(wParam);
  619. if (WI32DDEInitiate((HWND16) hwnd16)) {
  620. *plParamNew = lParam;
  621. }
  622. else {
  623. HANDLE h32;
  624. if (fWhoCalled == WOWDDE_POSTMESSAGE) {
  625. if (h32 = DDEFindPair32(wParam, hwnd16, (HAND16) HIWORD(lParam))) {
  626. *plParamNew = PackDDElParam(wMsg, (LONG) (DWORD) LOWORD(lParam), (LONG) h32);
  627. }
  628. else {
  629. *plParamNew = PackDDElParam(wMsg, (LONG) (DWORD) LOWORD(lParam), (LONG) (DWORD) HIWORD(lParam));
  630. }
  631. }
  632. else {
  633. if (fThunkDDEmsg) {
  634. if (h32 = DDEFindPair32(wParam, hwnd16, (HAND16) HIWORD(lParam))) {
  635. *plParamNew = PackDDElParam(wMsg, (LONG) (DWORD) LOWORD(lParam), (LONG) h32);
  636. }
  637. else {
  638. *plParamNew = PackDDElParam(wMsg, (LONG) (DWORD) LOWORD(lParam), (LONG) (DWORD) HIWORD(lParam));
  639. }
  640. }
  641. else {
  642. *plParamNew = W32GetHookDDEMsglParam();
  643. }
  644. }
  645. }
  646. }
  647. break;
  648. case WM_DDE_POKE:
  649. {
  650. DDEINFO DdeInfo;
  651. HANDLE h32;
  652. HWND16 hwnd16 = lpmpex->Parm16.WndProc.hwnd;
  653. WORD wMsg = lpmpex->Parm16.WndProc.wMsg;
  654. lpmpex->uParam = (LONG) FULLHWND32(wParam);
  655. if (fWhoCalled == WOWDDE_POSTMESSAGE) {
  656. if (h32 = DDEFindPair32(hwnd16, wParam, (HAND16) LOWORD(lParam))) {
  657. DDEDeletehandle(LOWORD(lParam), h32);
  658. WOWGLOBALFREE(h32);
  659. }
  660. DdeInfo.Msg = wMsg;
  661. h32 = DDECopyhData32(hwnd16, wParam, (HAND16) LOWORD(lParam), &DdeInfo);
  662. // WARNING: 16-bit memory may have moved
  663. DdeInfo.Flags = DDE_PACKET;
  664. DdeInfo.h16 = 0;
  665. DDEAddhandle(hwnd16, wParam, (HAND16)LOWORD(lParam), h32, &DdeInfo);
  666. *plParamNew = PackDDElParam(wMsg, (LONG) h32, (LONG) HIWORD(lParam));
  667. }
  668. else {
  669. if (fThunkDDEmsg) {
  670. if (!(h32 = DDEFindPair32(hwnd16, wParam, (HAND16) LOWORD(lParam)))) {
  671. LOGDEBUG (0, ("WOW::WMSG16: WM_DDE_POKE : Can't find h32 !\n"));
  672. }
  673. *plParamNew = PackDDElParam(wMsg, (LONG) h32, (LONG) HIWORD(lParam));
  674. }
  675. else {
  676. *plParamNew = W32GetHookDDEMsglParam();
  677. }
  678. }
  679. }
  680. break;
  681. case WM_DDE_ADVISE:
  682. {
  683. DDEINFO DdeInfo;
  684. HANDLE h32;
  685. INT cb;
  686. VPVOID vp;
  687. LPBYTE lpMem16;
  688. LPBYTE lpMem32;
  689. HWND16 hwnd16 = lpmpex->Parm16.WndProc.hwnd;
  690. WORD wMsg = lpmpex->Parm16.WndProc.wMsg;
  691. lpmpex->uParam = (LONG) FULLHWND32(wParam);
  692. if (fWhoCalled == WOWDDE_POSTMESSAGE) {
  693. if (h32 = DDEFindPair32(hwnd16, wParam, (HAND16) LOWORD(lParam))) {
  694. DDEDeletehandle(LOWORD(lParam), h32);
  695. WOWGLOBALFREE(h32);
  696. }
  697. h32 = WOWGLOBALALLOC(GMEM_DDESHARE, sizeof(DDEADVISE));
  698. if (h32 == NULL) {
  699. return 0;
  700. }
  701. lpMem32 = GlobalLock(h32);
  702. vp = GlobalLock16(LOWORD(lParam), &cb);
  703. GETMISCPTR(vp, lpMem16);
  704. RtlCopyMemory(lpMem32, lpMem16, sizeof(DDEADVISE));
  705. FREEMISCPTR(lpMem16);
  706. GlobalUnlock(h32);
  707. GlobalUnlock16(LOWORD(lParam));
  708. DdeInfo.Msg = wMsg;
  709. DdeInfo.Format = 0;
  710. DdeInfo.Flags = DDE_PACKET;
  711. DdeInfo.h16 = 0;
  712. DDEAddhandle(hwnd16, wParam, (HAND16)LOWORD(lParam), h32, &DdeInfo);
  713. *plParamNew = PackDDElParam(wMsg, (LONG) h32, (LONG) HIWORD(lParam));
  714. }
  715. else {
  716. if (fThunkDDEmsg) {
  717. if (!(h32 = DDEFindPair32(hwnd16, wParam, (HAND16) LOWORD(lParam)))) {
  718. LOGDEBUG (0, ("WOW::WMSG16: WM_DDE_ADVISE : Can't find h32 !\n"));
  719. }
  720. *plParamNew = PackDDElParam(wMsg, (LONG) h32, (LONG) HIWORD(lParam));
  721. }
  722. else {
  723. *plParamNew = W32GetHookDDEMsglParam();
  724. }
  725. }
  726. }
  727. break;
  728. case WM_DDE_DATA:
  729. {
  730. DDEINFO DdeInfo;
  731. HANDLE h32;
  732. HWND16 hwnd16 = lpmpex->Parm16.WndProc.hwnd;
  733. WORD wMsg = lpmpex->Parm16.WndProc.wMsg;
  734. lpmpex->uParam = (LONG) FULLHWND32(wParam);
  735. if (fWhoCalled == WOWDDE_POSTMESSAGE) {
  736. if (h32 = DDEFindPair32(hwnd16, wParam, (HAND16) LOWORD(lParam))) {
  737. DDEDeletehandle(LOWORD(lParam), h32);
  738. WOWGLOBALFREE(h32);
  739. }
  740. if (!LOWORD(lParam)) {
  741. h32 = 0;
  742. }
  743. else {
  744. DdeInfo.Msg = wMsg;
  745. h32 = DDECopyhData32(hwnd16, wParam, (HAND16) LOWORD(lParam), &DdeInfo);
  746. // WARNING: 16-bit memory may have moved
  747. DdeInfo.Flags = DDE_PACKET;
  748. DdeInfo.h16 = 0;
  749. DDEAddhandle(hwnd16, wParam, (HAND16)LOWORD(lParam), h32, &DdeInfo);
  750. }
  751. *plParamNew = PackDDElParam(wMsg, (LONG) h32, (LONG) HIWORD(lParam));
  752. }
  753. else {
  754. if (fThunkDDEmsg) {
  755. if (!LOWORD(lParam)) {
  756. h32 = 0;
  757. }
  758. else {
  759. if (!(h32 = DDEFindPair32(hwnd16, wParam, (HAND16) LOWORD(lParam)))) {
  760. LOGDEBUG (0, ("WOW::WMSG16: WM_DDE_DATA : Can't find h32 !\n"));
  761. }
  762. }
  763. *plParamNew = PackDDElParam(wMsg, (LONG) h32, (LONG) HIWORD(lParam));
  764. }
  765. else {
  766. *plParamNew = W32GetHookDDEMsglParam();
  767. }
  768. }
  769. }
  770. break;
  771. case WM_DDE_EXECUTE:
  772. {
  773. DDEINFO DdeInfo;
  774. HANDLE h32;
  775. HAND16 h16;
  776. INT cb;
  777. VPVOID vp;
  778. VPVOID vp1;
  779. LPBYTE lpMem16;
  780. LPBYTE lpMem32;
  781. HWND16 hwnd16 = lpmpex->Parm16.WndProc.hwnd;
  782. WORD wMsg = lpmpex->Parm16.WndProc.wMsg;
  783. lpmpex->uParam = (LONG) FULLHWND32(wParam);
  784. if (fWhoCalled == WOWDDE_POSTMESSAGE) {
  785. vp = GlobalLock16(HIWORD(lParam), &cb);
  786. GETMISCPTR(vp, lpMem16);
  787. h32 = WOWGLOBALALLOC(GMEM_DDESHARE, cb);
  788. if (h32) {
  789. lpMem32 = GlobalLock(h32);
  790. RtlCopyMemory(lpMem32, lpMem16, cb);
  791. GlobalUnlock(h32);
  792. FREEMISCPTR(lpMem16);
  793. //
  794. // The alias is checked to make bad apps do WM_DDE_EXECUTE
  795. // correctly. One such app is SuperPrint. This app issues
  796. // multiple WM_DDE_EXECUTEs without waiting for WM_DDE_ACK to
  797. // come. Also, it uses the same h16 on these messages.
  798. // We get around this problem by generating a unique h16-h32
  799. // pairing each time. And freeing h16 when the WM_DDE_ACK comes.
  800. // In WM32DDEAck, we need to free this h16 because we allocated
  801. // this one. Apply this hack only if the h16 is valid. Caere
  802. // OmniPage passes hard coded constants in HIWORD(lParam).
  803. //
  804. // SunilP, ChandanC 4-30-93
  805. //
  806. if (vp && DDEFindPair32(hwnd16, wParam, (HAND16) HIWORD(lParam))) {
  807. vp1 = GlobalAllocLock16(GMEM_DDESHARE, cb, &h16);
  808. if (vp1) {
  809. GETMISCPTR(vp1, lpMem16);
  810. RtlCopyMemory(lpMem16, lpMem32, cb);
  811. FLUSHVDMPTR(vp1, cb, lpMem16);
  812. FREEMISCPTR(lpMem16);
  813. GlobalUnlock16(h16);
  814. DdeInfo.Msg = wMsg;
  815. DdeInfo.Format = 0;
  816. DdeInfo.Flags = DDE_EXECUTE_FREE_H16 | DDE_PACKET;
  817. DdeInfo.h16 = (HAND16) HIWORD(lParam);
  818. DDEAddhandle(hwnd16, wParam, h16, h32, &DdeInfo);
  819. }
  820. else {
  821. LOGDEBUG (0, ("WOW::WMSG16: WM_DDE_EXECUTE : Can't allocate h16 !\n"));
  822. }
  823. }
  824. else {
  825. DdeInfo.Msg = wMsg;
  826. DdeInfo.Format = 0;
  827. DdeInfo.Flags = DDE_PACKET;
  828. DdeInfo.h16 = 0;
  829. DDEAddhandle(hwnd16, wParam, (HAND16)HIWORD(lParam), h32, &DdeInfo);
  830. }
  831. }
  832. else {
  833. GlobalUnlock16(HIWORD(lParam));
  834. }
  835. GlobalUnlock16(HIWORD(lParam));
  836. }
  837. else {
  838. if (!(h32 = DDEFindPair32(hwnd16, wParam, (HAND16) HIWORD(lParam)))) {
  839. LOGDEBUG (0, ("WOW::WMSG16: WM_DDE_EXECUTE : Can't find h32 !\n"));
  840. }
  841. }
  842. *plParamNew = (ULONG)h32;
  843. }
  844. break;
  845. case WM_COPYDATA:
  846. {
  847. LPBYTE lpMem16;
  848. LPBYTE lpMem32;
  849. PCOPYDATASTRUCT16 lpCDS16;
  850. PCOPYDATASTRUCT lpCDS32 = NULL;
  851. PCPDATA pTemp;
  852. HWND16 hwnd16 = lpmpex->Parm16.WndProc.hwnd;
  853. lpmpex->uParam = (LONG) HWND32(wParam);
  854. if (fWhoCalled == WOWDDE_POSTMESSAGE) {
  855. GETMISCPTR(lParam, lpCDS16);
  856. if (lpCDS32 = (PCOPYDATASTRUCT) malloc_w(sizeof(COPYDATASTRUCT))) {
  857. lpCDS32->dwData = lpCDS16->dwData;
  858. if (lpCDS32->cbData = lpCDS16->cbData) {
  859. if (lpMem32 = malloc_w(lpCDS32->cbData)) {
  860. GETMISCPTR(lpCDS16->lpData, lpMem16);
  861. if (lpMem16) {
  862. RtlCopyMemory(lpMem32, lpMem16, lpCDS32->cbData);
  863. CopyDataAddNode (hwnd16, wParam, (DWORD) lpMem16, (DWORD) lpMem32, COPYDATA_16);
  864. }
  865. FREEMISCPTR(lpMem16);
  866. }
  867. lpCDS32->lpData = lpMem32;
  868. }
  869. else {
  870. lpCDS32->lpData = NULL;
  871. }
  872. }
  873. FREEMISCPTR(lpCDS16);
  874. CopyDataAddNode (hwnd16, wParam, (DWORD) lParam, (DWORD) lpCDS32, COPYDATA_16);
  875. }
  876. else {
  877. pTemp = CopyDataFindData32 (hwnd16, wParam, lParam);
  878. if (pTemp) {
  879. lpCDS32 = (PCOPYDATASTRUCT) pTemp->Mem32;
  880. }
  881. WOW32ASSERTMSGF(lpCDS32, ("WOW::WM_COPYDATA:Can't locate lpCDS32\n"));
  882. }
  883. *plParamNew = (LONG)lpCDS32;
  884. }
  885. break;
  886. // Win 3.1 messages
  887. case WM_DROPFILES:
  888. lpmpex->uParam = (UINT)HDROP32(wParam);
  889. WOW32ASSERT(lpmpex->uParam != 0);
  890. break;
  891. case WM_DROPOBJECT:
  892. case WM_QUERYDROPOBJECT:
  893. case WM_DRAGLOOP:
  894. case WM_DRAGSELECT:
  895. case WM_DRAGMOVE:
  896. {
  897. register LPDROPSTRUCT lpds;
  898. register PDROPSTRUCT16 lpds16;
  899. if (lParam) {
  900. lpds = (LPDROPSTRUCT) lpmpex->MsgBuffer;
  901. GETVDMPTR(lParam, sizeof(DROPSTRUCT16), lpds16);
  902. lpds->hwndSource = HWND32(lpds16->hwndSource);
  903. lpds->hwndSink = HWND32(lpds16->hwndSink);
  904. lpds->wFmt = lpds16->wFmt;
  905. lpds->ptDrop.y = (LONG)lpds16->ptDrop.y;
  906. lpds->ptDrop.x = (LONG)lpds16->ptDrop.x;
  907. lpds->dwControlData = lpds16->dwControlData;
  908. *plParamNew = (LONG) lpds;
  909. FREEVDMPTR(lpds16);
  910. }
  911. }
  912. break;
  913. case WM_NEXTMENU: // Thunk
  914. *plParamNew = (LONG)lpmpex->MsgBuffer;
  915. ((PMDINEXTMENU)(*plParamNew))->hmenuIn = HMENU32(LOWORD(lParam));
  916. break;
  917. case WM_WINDOWPOSCHANGING:
  918. case WM_WINDOWPOSCHANGED:
  919. if (lParam) {
  920. lpmpex->lParam = (LONG) lpmpex->MsgBuffer;
  921. getwindowpos16( (VPWINDOWPOS16)lParam, (LPWINDOWPOS)lpmpex->lParam );
  922. }
  923. break;
  924. case WM_TIMER:
  925. {
  926. HAND16 htask16;
  927. PTMR ptmr;
  928. WORD wIDEvent;
  929. htask16 = CURRENTPTD()->htask16;
  930. wIDEvent = wParam;
  931. ptmr = FindTimer16( lpmpex->Parm16.WndProc.hwnd, htask16, wIDEvent );
  932. if ( !ptmr ) {
  933. if ( lParam == 0L ) {
  934. /*
  935. ** Edit controls have timers which can be sent straight
  936. ** through without thunking... (wParam=1, lParam=0)
  937. */
  938. lpmpex->uParam = (UINT)wIDEvent;
  939. *plParamNew = 0L;
  940. } else {
  941. LOGDEBUG(6,(" ThunkWMMSG16 WARNING: cannot find timer %04x\n", wIDEvent));
  942. }
  943. } else {
  944. lpmpex->uParam = (UINT)wIDEvent;
  945. *plParamNew = ptmr->dwTimerProc32; // 32-bit proc or NULL
  946. }
  947. }
  948. break;
  949. #ifdef FE_IME
  950. case WM_IME_REPORT:
  951. {
  952. INT cb;
  953. INT i;
  954. INT len;
  955. VPVOID vp;
  956. HANDLE hMem32 = 0;
  957. LPBYTE lpMem32 = 0;
  958. LPBYTE lpMem16 = 0;
  959. if ( !lParam )
  960. break;
  961. if (wParam == IR_STRING) {
  962. /*********************** IR_STRING **********************************/
  963. vp = GlobalLock16(FETCHWORD(lParam), &cb);
  964. GETMISCPTR(vp, lpMem16);
  965. if (!(hMem32 = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE | GMEM_ZEROINIT, cb)))
  966. goto Err;
  967. lpMem32 = GlobalLock(hMem32);
  968. RtlCopyMemory(lpMem32, lpMem16, cb);
  969. GlobalUnlock( hMem32 );
  970. GlobalUnlock16( FETCHWORD(lParam) );
  971. *plParamNew = (LONG)hMem32;
  972. }
  973. /*********************** IR_STRINGEX ********************************/
  974. else if ( wParam == IR_STRINGEX ) {
  975. LPSTRINGEXSTRUCT pss32;
  976. PSTRINGEXSTRUCT16 pss16;
  977. INT uDetermineDelim = 0;
  978. INT uYomiDelim = 0;
  979. vp = GlobalLock16( FETCHWORD(lParam), &cb );
  980. GETMISCPTR(vp, lpMem16);
  981. pss16 = (PSTRINGEXSTRUCT16)lpMem16;
  982. cb = sizeof(STRINGEXSTRUCT);
  983. /* Get exactry size */
  984. if ( lpMem16[ pss16->uDeterminePos ] ) {
  985. len = lstrlen( &lpMem16[ pss16->uDeterminePos ] );
  986. cb += len + 1;
  987. cb += sizeof(INT) - (cb % sizeof(INT)); // #2259 kksuzuka
  988. // DetermineDelim[0] is everytime NULL
  989. // BAD CODE
  990. // for ( i = 0; i < len && INTOF( lpMem16[ pss16->uDetermineDelimPos ], i ); i++ )
  991. // #7253 kksuzuka
  992. for ( i = 1; (i <= len) && WORDOF( lpMem16[ pss16->uDetermineDelimPos ], i ); i++ )
  993. // if ( INTOF( lpMem16[ pss16->uDetermineDelimPos ], i ) >= len )
  994. // #7253 kksuzuka
  995. if ( WORDOF( lpMem16[ pss16->uDetermineDelimPos ], i ) >= len )
  996. break;
  997. if ( i <= len )
  998. // #7253 kksuzuka
  999. cb += (i + 1) * sizeof(INT);
  1000. // cb += i * sizeof(INT);
  1001. uDetermineDelim = i;
  1002. }
  1003. if ( lpMem16[ pss16->uYomiPos ] ) {
  1004. len = lstrlen( &lpMem16[ pss16->uYomiPos ] );
  1005. cb += len + 1;
  1006. cb += sizeof(INT) - (cb % sizeof(INT)); // #2259 kksuzuka
  1007. // YomiDelim[0] is everytime NULL
  1008. // BAD CODE
  1009. // for ( i = 0; i < len && INTOF( lpMem16[ pss16->uYomiDelimPos ], i ); i++ )
  1010. // #7253 kksuzuka
  1011. for ( i = 1; (i <= len) && WORDOF( lpMem16[ pss16->uYomiDelimPos ], i ); i++ )
  1012. // if ( INTOF( lpMem16[ pss16->uYomiDelimPos ], i ) >= len )
  1013. // #7253 kksuzuka
  1014. if ( WORDOF( lpMem16[ pss16->uYomiDelimPos ], i ) >= len )
  1015. break;
  1016. if ( i <= len )
  1017. // #7253 kksuzuka
  1018. cb += (i + 1) * sizeof(UINT);
  1019. // cb += i * sizeof(UINT);
  1020. uYomiDelim = i;
  1021. }
  1022. if (!(hMem32 = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE | GMEM_ZEROINIT, cb)))
  1023. goto Err;
  1024. lpMem32 = GlobalLock( hMem32 );
  1025. pss32 = (LPSTRINGEXSTRUCT)lpMem32;
  1026. pss32->dwSize = cb;
  1027. i = sizeof( STRINGEXSTRUCT );
  1028. if ( pss16->uDeterminePos ) {
  1029. pss32->uDeterminePos = i;
  1030. lstrcpy( &lpMem32[ i ], &lpMem16[ pss16->uDeterminePos ] );
  1031. i += lstrlen( &lpMem16[ pss16->uDeterminePos ] ) + 1;
  1032. i += sizeof(INT) - (i % sizeof(INT)); // kksuzuka #2259
  1033. }
  1034. if ( pss16->uDetermineDelimPos ) {
  1035. pss32->uDetermineDelimPos = i;
  1036. // i += uDetermineDelim * sizeof(UINT);
  1037. // #7253 kksuzuka
  1038. i += (uDetermineDelim + 1)* sizeof(UINT);
  1039. for( ; uDetermineDelim ; uDetermineDelim-- ) {
  1040. INTOF( lpMem32[ pss32->uDetermineDelimPos ], uDetermineDelim ) =
  1041. WORDOF( lpMem16[ pss16->uDetermineDelimPos ], uDetermineDelim );
  1042. }
  1043. }
  1044. if ( pss16->uYomiPos ) {
  1045. pss32->uYomiPos = i;
  1046. lstrcpy( &lpMem32[ i ], &lpMem16[ pss16->uYomiPos ] );
  1047. i += lstrlen( &lpMem16[ pss16->uYomiPos ] ) + 1;
  1048. i += sizeof(INT) - (i % sizeof(INT)); // kksuzuka #2259
  1049. }
  1050. if ( pss16->uYomiDelimPos ) {
  1051. pss32->uYomiDelimPos = i;
  1052. i += uYomiDelim * sizeof(UINT);
  1053. for( ; uYomiDelim ; uYomiDelim-- ) {
  1054. INTOF( lpMem32[ pss32->uYomiDelimPos ], uYomiDelim ) =
  1055. WORDOF( lpMem16[ pss16->uYomiDelimPos ], uYomiDelim );
  1056. }
  1057. }
  1058. *plParamNew = (LONG)hMem32;
  1059. GlobalUnlock16(FETCHWORD(lParam));
  1060. GlobalUnlock( hMem32 );
  1061. }
  1062. else if (wParam == IR_UNDETERMINE) {
  1063. /********************** IR_UNDETERMINE ******************************/
  1064. PUNDETERMINESTRUCT16 pus16;
  1065. LPUNDETERMINESTRUCT pus32;
  1066. vp = GlobalLock16( FETCHWORD(lParam), &cb );
  1067. GETMISCPTR(vp, lpMem16);
  1068. pus16 = (PUNDETERMINESTRUCT16)lpMem16;
  1069. cb = sizeof(UNDETERMINESTRUCT);
  1070. cb += pus16->uDefIMESize;
  1071. cb += (pus16->uUndetTextLen + 1);
  1072. cb += (pus16->uDetermineTextLen + 1);
  1073. cb += (pus16->uYomiTextLen + 1);
  1074. if ( pus16->uUndetAttrPos )
  1075. cb += pus16->uUndetTextLen;
  1076. if ( pus16->uDetermineDelimPos )
  1077. cb += pus16->uDetermineTextLen * sizeof(UINT);
  1078. if ( pus16->uYomiDelimPos )
  1079. cb += pus16->uYomiTextLen * sizeof(UINT);
  1080. if (!(hMem32 = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE | GMEM_ZEROINIT, cb)))
  1081. goto Err;
  1082. lpMem32 = GlobalLock(hMem32);
  1083. pus32 = (LPUNDETERMINESTRUCT)lpMem32;
  1084. i = sizeof(UNDETERMINESTRUCT);
  1085. if ( pus16->uUndetTextLen ) {
  1086. RtlCopyMemory( &lpMem32[ i ], &lpMem16[ pus16->uUndetTextPos ], pus16->uUndetTextLen + 1 );
  1087. pus32->uUndetTextPos = i;
  1088. i += pus16->uUndetTextLen + 1;
  1089. pus32->uUndetTextLen = pus16->uUndetTextLen;
  1090. }
  1091. if ( pus16->uUndetAttrPos ) {
  1092. RtlCopyMemory( &lpMem32[ i ], &lpMem16[ pus16->uUndetAttrPos ], pus16->uUndetTextLen );
  1093. pus32->uUndetAttrPos = i;
  1094. i += pus16->uUndetTextLen;
  1095. }
  1096. if ( pus16->uDetermineTextLen ) {
  1097. RtlCopyMemory( &lpMem32[ i ], &lpMem16[ pus16->uDetermineTextPos ], pus16->uDetermineTextLen + 1 );
  1098. pus32->uDetermineTextPos = i;
  1099. i += pus16->uDetermineTextLen + 1;
  1100. pus32->uDetermineTextLen = pus16->uDetermineTextLen;
  1101. }
  1102. if ( pus16->uDetermineDelimPos ) {
  1103. INT j;
  1104. pus32->uDetermineDelimPos = i;
  1105. for ( j = 0; j < pus16->uDetermineTextLen; j++ ) {
  1106. if ( WORDOF16( lpMem16[ pus16->uDetermineTextLen ], j ) || pus16->uDetermineTextLen > WORDOF16( lpMem16[ pus16->uDetermineTextLen ], j )) {
  1107. INTOF( lpMem32[ i ], 0 ) = WORDOF16( lpMem16[ pus16->uDetermineTextLen ], j );
  1108. i += sizeof(UINT);
  1109. }
  1110. else
  1111. break;
  1112. }
  1113. }
  1114. if ( pus16->uYomiTextLen ) {
  1115. RtlCopyMemory( &lpMem32[ i ], &lpMem16[ pus16->uYomiTextPos ], pus16->uYomiTextLen + 1 );
  1116. pus32->uYomiTextPos = i;
  1117. pus32->uYomiTextLen = pus16->uYomiTextLen;
  1118. i += pus16->uYomiTextLen + 1;
  1119. }
  1120. if ( pus16->uYomiDelimPos ) {
  1121. INT j;
  1122. pus32->uYomiDelimPos = i;
  1123. for ( j = 0; j < pus16->uYomiTextLen; j++ ) {
  1124. if ( WORDOF16(lpMem16[ pus16->uYomiDelimPos ], j ) || pus16->uYomiTextLen > WORDOF16(lpMem16[ pus16->uYomiDelimPos ], j )) {
  1125. INTOF( lpMem32[ i ], 0 ) = WORDOF16( lpMem16[ pus16->uYomiDelimPos ], j );
  1126. i += sizeof(UINT);
  1127. }
  1128. else
  1129. break;
  1130. }
  1131. }
  1132. if ( pus16->uDefIMESize ) {
  1133. RtlCopyMemory( &lpMem32[ i ], &lpMem16[ pus16->uDefIMEPos ], pus16->uDefIMESize );
  1134. pus32->uDefIMEPos = i;
  1135. }
  1136. *plParamNew = (LONG)hMem32;
  1137. GlobalUnlock16( FETCHWORD(lParam));
  1138. GlobalUnlock( hMem32 );
  1139. }
  1140. break;
  1141. Err:
  1142. if ( lpMem16 && FETCHWORD(lParam ))
  1143. GlobalUnlock16( FETCHWORD(lParam) );
  1144. return FALSE;
  1145. }
  1146. break;
  1147. // MSKK support WM_IMEKEYDOWN message
  1148. // MSKK support WM_IMEKEYUP message
  1149. // MSKK16bit IME support
  1150. // WM_IMEKEYDOWN & WM_IMEKEYUP 16 -> 32
  1151. // 32bit:wParam HIWORD charactor code, LOWORD virtual key
  1152. // 16bit:wParam HIBYTE charactor code, LOBYTE virtual key
  1153. // kksuzuka:#4281 1994.11.19 MSKK V-HIDEKK
  1154. case WM_IMEKEYDOWN:
  1155. case WM_IMEKEYUP:
  1156. #ifdef DEBUG
  1157. LOGDEBUG( 5, ("ThunkWMMsg16:WM_IMEKEY debug\n"));
  1158. #endif
  1159. lpmpex->uParam = MAKELONG( LOBYTE(wParam), HIBYTE(wParam) );
  1160. break;
  1161. #endif // FE_IME
  1162. case WM_PRINT:
  1163. case WM_PRINTCLIENT:
  1164. lpmpex->uParam = (WPARAM)HDC32(wParam);
  1165. break;
  1166. case WM_NOTIFY: // 0x4e
  1167. // wparam is control ID, lparam points to NMHDR or larger struct.
  1168. {
  1169. LONG lParamMap;
  1170. GETVDMPTR(lParam, sizeof(NMHDR), (PSZ)lParamMap);
  1171. *plParamNew = (LONG)AddParamMap(lParamMap, lParam);
  1172. if (lParamMap != *plParamNew) {
  1173. FREEVDMPTR((PSZ)lParamMap);
  1174. }
  1175. }
  1176. break;
  1177. case WM_CHANGEUISTATE: // 0x127
  1178. case WM_UPDATEUISTATE: // 0x128
  1179. case WM_QUERYUISTATE: // 0x129
  1180. // We should only see this message originate from the 32-bit side
  1181. // It will come with both words of uParam used and lPram unused.
  1182. // We 32->16 thunk it (WM32xxxUIState() - wmdisp32.c) by copying
  1183. // uParam32 to lParam16. Now we are just reversing the process.
  1184. lpmpex->uParam = (UINT)lParam;
  1185. *plParamNew = 0;
  1186. break;
  1187. } // end switch
  1188. return TRUE;
  1189. }
  1190. //
  1191. // the WM_CREATE message has already been thunked, but this WM_CREATE
  1192. // is coming from an MDI client window so lParam->lpCreateParams needs
  1193. // special attention
  1194. //
  1195. BOOL FinishThunkingWMCreateMDI16(LONG lParamNew, LPCLIENTCREATESTRUCT lpCCS)
  1196. {
  1197. PCLIENTCREATESTRUCT16 pCCS16;
  1198. GETVDMPTR(((LPCREATESTRUCT)lParamNew)->lpCreateParams,
  1199. sizeof(CLIENTCREATESTRUCT16), pCCS16);
  1200. lpCCS->hWindowMenu = HMENU32(FETCHWORD(pCCS16->hWindowMenu));
  1201. lpCCS->idFirstChild = WORD32(FETCHWORD(pCCS16->idFirstChild));
  1202. ((LPCREATESTRUCT)lParamNew)->lpCreateParams = (LPVOID)lpCCS;
  1203. FREEVDMPTR(pCCS16);
  1204. return TRUE;
  1205. }
  1206. //
  1207. // the WM_CREATE message has already been thunked, but this WM_CREATE
  1208. // is coming from an MDI child window so lParam->lpCreateParams needs
  1209. // special attention
  1210. //
  1211. BOOL FinishThunkingWMCreateMDIChild16(LONG lParamNew, LPMDICREATESTRUCT lpMCS)
  1212. {
  1213. PMDICREATESTRUCT16 pMCS16;
  1214. GETVDMPTR(((LPCREATESTRUCT)lParamNew)->lpCreateParams,
  1215. sizeof(MDICREATESTRUCT16), pMCS16);
  1216. GETPSZIDPTR(pMCS16->vpszClass, lpMCS->szClass);
  1217. GETPSZPTR(pMCS16->vpszTitle, lpMCS->szTitle);
  1218. lpMCS->hOwner = HMODINST32(FETCHWORD(pMCS16->hOwner));
  1219. lpMCS->x = (int)FETCHWORD(pMCS16->x);
  1220. lpMCS->y = (int)FETCHWORD(pMCS16->y);
  1221. lpMCS->cx = (int)FETCHWORD(pMCS16->cx);
  1222. lpMCS->cy = (int)FETCHWORD(pMCS16->cy);
  1223. lpMCS->style = FETCHDWORD(pMCS16->style);
  1224. lpMCS->lParam = FETCHDWORD(pMCS16->lParam);
  1225. ((LPCREATESTRUCT)lParamNew)->lpCreateParams = (LPVOID)lpMCS;
  1226. FREEVDMPTR(pMCS16);
  1227. return TRUE;
  1228. }
  1229. VOID FASTCALL UnThunkWMMsg16(LPMSGPARAMEX lpmpex)
  1230. {
  1231. switch(lpmpex->Parm16.WndProc.wMsg) {
  1232. case WM_SETTEXT: // 00Ch, <SLPre,SLPost >
  1233. case WM_WININICHANGE: // 01Ah, <SLPre, LS>
  1234. case WM_DEVMODECHANGE: // 01Bh, <SLPre, LS>
  1235. {
  1236. BOOL fFreePtr;
  1237. DeleteParamMap(lpmpex->lParam, PARAM_32, &fFreePtr);
  1238. if (fFreePtr) {
  1239. FREEPSZPTR((LPSZ)lpmpex->lParam);
  1240. }
  1241. }
  1242. break;
  1243. case WM_GETTEXT: // 00Dh, <SLPre,SLPost,LS>
  1244. if ((WORD)lpmpex->lReturn > 0) {
  1245. FLUSHVDMPTR(lpmpex->Parm16.WndProc.lParam, lpmpex->Parm16.WndProc.wParam, (LPSZ)lpmpex->lParam);
  1246. FREEPSZPTR((LPSZ)lpmpex->lParam);
  1247. }
  1248. break;
  1249. case WM_GETMINMAXINFO: // 024h, <SLPre,SLPost,LS>,MINMAXINFOSTRUCT
  1250. UnThunkWMGetMinMaxInfo16(lpmpex->Parm16.WndProc.lParam, (LPPOINT)lpmpex->lParam);
  1251. break;
  1252. case WM_DRAWITEM: // 02Bh notused, DRAWITEMSTRUCT
  1253. if (lpmpex->lParam) {
  1254. putdrawitem16((VPDRAWITEMSTRUCT16)lpmpex->Parm16.WndProc.lParam, (PDRAWITEMSTRUCT)lpmpex->lParam);
  1255. }
  1256. break;
  1257. case WM_MEASUREITEM: // 02Ch notused, MEASUREITEMSTRUCT
  1258. if (lpmpex->lParam) {
  1259. putmeasureitem16((VPMEASUREITEMSTRUCT16)lpmpex->Parm16.WndProc.lParam, (PMEASUREITEMSTRUCT)lpmpex->lParam);
  1260. }
  1261. break;
  1262. case WM_DELETEITEM: // 02Dh notused, DELETEITEMSTRUCT
  1263. if (lpmpex->lParam) {
  1264. putdeleteitem16((VPDELETEITEMSTRUCT16)lpmpex->Parm16.WndProc.lParam, (PDELETEITEMSTRUCT)lpmpex->lParam);
  1265. }
  1266. break;
  1267. case WM_GETFONT: // 031h
  1268. lpmpex->lReturn = GETHFONT16(lpmpex->lReturn);
  1269. break;
  1270. case WM_COMPAREITEM: // 039h
  1271. if (lpmpex->lParam) {
  1272. putcompareitem16((VPCOMPAREITEMSTRUCT16)lpmpex->Parm16.WndProc.lParam, (PCOMPAREITEMSTRUCT)lpmpex->lParam);
  1273. }
  1274. break;
  1275. case WM_WINHELP:
  1276. if (lpmpex->lParam && lpmpex->lParam != (LONG)lpmpex->MsgBuffer) {
  1277. free_w((PVOID)lpmpex->lParam);
  1278. }
  1279. break;
  1280. case WM_SIZING: // 214h, <SLPre,SLPost,LS>,RECT
  1281. if (lpmpex->lParam) {
  1282. putrect16((VPRECT16)lpmpex->Parm16.WndProc.lParam, (LPRECT)lpmpex->lParam);
  1283. }
  1284. break;
  1285. case WM_NCCALCSIZE: // 083h, <SLPre,SLPost,LS>,RECT
  1286. if (lpmpex->lParam) {
  1287. putrect16((VPRECT16)lpmpex->Parm16.WndProc.lParam, (LPRECT)lpmpex->lParam);
  1288. if (lpmpex->Parm16.WndProc.wParam) {
  1289. PNCCALCSIZE_PARAMS16 pnc16;
  1290. PNCCALCSIZE_PARAMS16 lpnc16;
  1291. LPNCCALCSIZE_PARAMS lpnc;
  1292. lpnc = (LPNCCALCSIZE_PARAMS)lpmpex->lParam;
  1293. pnc16 = (PNCCALCSIZE_PARAMS16)lpmpex->Parm16.WndProc.lParam;
  1294. putrect16((VPRECT16)(&pnc16->rgrc[1]), &lpnc->rgrc[1]);
  1295. putrect16((VPRECT16)(&pnc16->rgrc[2]), &lpnc->rgrc[2]);
  1296. GETVDMPTR( pnc16, sizeof(NCCALCSIZE_PARAMS16), lpnc16 );
  1297. putwindowpos16( (VPWINDOWPOS16)lpnc16->lppos, lpnc->lppos );
  1298. FREEVDMPTR( lpnc16 );
  1299. }
  1300. }
  1301. break;
  1302. case WM_WINDOWPOSCHANGING:
  1303. case WM_WINDOWPOSCHANGED:
  1304. if (lpmpex->lParam) {
  1305. putwindowpos16( (VPWINDOWPOS16)lpmpex->Parm16.WndProc.lParam, (LPWINDOWPOS)lpmpex->lParam);
  1306. }
  1307. break;
  1308. case WM_CTLCOLOR:
  1309. // see thunking of wm_ctlcolor.
  1310. if ((ULONG)lpmpex->lReturn > COLOR_ENDCOLORS) {
  1311. lpmpex->lReturn = GETHBRUSH16(lpmpex->lReturn);
  1312. }
  1313. break;
  1314. case WM_MDICREATE: // 220h, <SLPre,SLPost,LS>,MDICREATESTRUCT
  1315. UnThunkWMMDICreate16(lpmpex->Parm16.WndProc.lParam, (LPMDICREATESTRUCT)lpmpex->lParam);
  1316. lpmpex->lReturn = GETHWND16(lpmpex->lReturn);
  1317. break;
  1318. case WM_MDIGETACTIVE:
  1319. //
  1320. // LOWORD(lReturn) == hwndMDIActive
  1321. // HIWORD(lReturn) == fMaximized
  1322. //
  1323. LOW(lpmpex->lReturn) = GETHWND16((HWND)(lpmpex->lReturn));
  1324. if (lpmpex->lParam != 0) {
  1325. HIW(lpmpex->lReturn) = (WORD)(*((LPBOOL)lpmpex->lParam) != 0);
  1326. }
  1327. break;
  1328. case WM_MDISETMENU:
  1329. lpmpex->lReturn = GETHMENU16(lpmpex->lReturn);
  1330. break;
  1331. case WM_PAINTCLIPBOARD:
  1332. case WM_SIZECLIPBOARD:
  1333. if (lpmpex->lParam) {
  1334. WOWGLOBALFREE((HANDLE)lpmpex->lParam);
  1335. }
  1336. break;
  1337. case WM_ASKCBFORMATNAME:
  1338. /* BUGBUGBUG -- neither thunk or unthunk should be necessary,
  1339. since the system does not process this message in DefWindowProc
  1340. FritzS */
  1341. if (lpmpex->lParam) {
  1342. putstr16((VPSZ)lpmpex->Parm16.WndProc.lParam, (LPSZ)lpmpex->lParam, lpmpex->Parm16.WndProc.wParam);
  1343. free_w((PBYTE)lpmpex->lParam);
  1344. }
  1345. break;
  1346. case WM_DDE_INITIATE:
  1347. WI32DDEDeleteInitiator((HAND16) lpmpex->Parm16.WndProc.wParam);
  1348. break;
  1349. case WM_NEXTMENU:
  1350. {
  1351. PMDINEXTMENU pT = (PMDINEXTMENU)lpmpex->lParam;
  1352. LOW(lpmpex->lReturn) = GETHMENU16(pT->hmenuNext);
  1353. HIW(lpmpex->lReturn) = GETHWND16(pT->hwndNext);
  1354. }
  1355. break;
  1356. case WM_COPYDATA:
  1357. if (fWhoCalled == WOWDDE_POSTMESSAGE) {
  1358. HWND16 hwnd16 = lpmpex->Parm16.WndProc.hwnd;
  1359. WORD wParam = lpmpex->Parm16.WndProc.wParam;
  1360. LONG lParamNew = lpmpex->lParam;
  1361. if (((PCOPYDATASTRUCT)lParamNew)->lpData) {
  1362. free_w (((PCOPYDATASTRUCT)lParamNew)->lpData);
  1363. CopyDataDeleteNode (hwnd16, wParam, (DWORD) ((PCOPYDATASTRUCT)lParamNew)->lpData);
  1364. }
  1365. if (lParamNew) {
  1366. free_w ((PVOID)lParamNew);
  1367. CopyDataDeleteNode (hwnd16, wParam, lParamNew);
  1368. }
  1369. else {
  1370. LOGDEBUG (LOG_ALWAYS, ("WOW::WM_COPYDATA16:Unthunking - lpCDS32 is NULL\n"));
  1371. }
  1372. }
  1373. break;
  1374. case WM_QUERYDRAGICON:
  1375. lpmpex->lReturn = (LONG)GETHICON16(lpmpex->lReturn);
  1376. break;
  1377. case WM_QUERYDROPOBJECT:
  1378. //
  1379. // Return value is either TRUE, FALSE,
  1380. // or a cursor!
  1381. //
  1382. if (lpmpex->lReturn && lpmpex->lReturn != (LONG)TRUE) {
  1383. lpmpex->lReturn = (LONG)GETHCURSOR16(lpmpex->lReturn);
  1384. }
  1385. break;
  1386. case WM_NOTIFY: // 0x4e
  1387. {
  1388. BOOL fFreePtr;
  1389. DeleteParamMap(lpmpex->lParam, PARAM_32, &fFreePtr);
  1390. if (fFreePtr) {
  1391. FREEVDMPTR((PSZ)lpmpex->lParam);
  1392. }
  1393. }
  1394. break;
  1395. case WM_CHANGEUISTATE: // 0x127
  1396. case WM_UPDATEUISTATE: // 0x128
  1397. case WM_QUERYUISTATE: // 0x129
  1398. {
  1399. // See thunking notes for this message in ThunkWMMsg16() above.
  1400. lpmpex->Parm16.WndProc.lParam = (LONG)lpmpex->uParam;
  1401. lpmpex->Parm16.WndProc.wParam = 0;
  1402. }
  1403. break;
  1404. #ifdef FE_IME
  1405. case WM_IME_REPORT:
  1406. switch( lpmpex->Parm16.WndProc.wParam ) {
  1407. case IR_STRING:
  1408. case IR_STRINGEX:
  1409. case IR_UNDETERMINE:
  1410. if ( lpmpex->lParam ) {
  1411. GlobalFree((HANDLE)lpmpex->lParam);
  1412. }
  1413. break;
  1414. }
  1415. break;
  1416. // MSKK support WM_IMEKEYDOWN message
  1417. // MSKK support WM_IMEKEYUP message
  1418. // MSKK16bit IME support
  1419. case WM_IMEKEYDOWN:
  1420. case WM_IMEKEYUP:
  1421. #ifdef DEBUG
  1422. LOGDEBUG( 5,("UnThunkWMMsg16:WM_IMEKEY debug\n"));
  1423. #endif
  1424. break;
  1425. #endif // FE_IME
  1426. } // end switch
  1427. }
  1428. BOOL ThunkWMGetMinMaxInfo16(VPVOID lParam, LPPOINT *plParamNew)
  1429. {
  1430. register LPPOINT lppt;
  1431. register PPOINT16 ppt16;
  1432. if (lParam) {
  1433. lppt = *plParamNew;
  1434. GETVDMPTR(lParam, sizeof(POINT16)*5, ppt16);
  1435. lppt[0].x = ppt16[0].x;
  1436. lppt[0].y = ppt16[0].y;
  1437. lppt[1].x = ppt16[1].x;
  1438. lppt[1].y = ppt16[1].y;
  1439. lppt[2].x = ppt16[2].x;
  1440. lppt[2].y = ppt16[2].y;
  1441. lppt[3].x = ppt16[3].x;
  1442. lppt[3].y = ppt16[3].y;
  1443. lppt[4].x = ppt16[4].x;
  1444. lppt[4].y = ppt16[4].y;
  1445. FREEVDMPTR(ppt16);
  1446. }
  1447. RETURN(TRUE);
  1448. }
  1449. VOID UnThunkWMGetMinMaxInfo16(VPVOID lParam, register LPPOINT lParamNew)
  1450. {
  1451. register PPOINT16 ppt16;
  1452. if (lParamNew) {
  1453. GETVDMPTR(lParam, sizeof(POINT16)*5, ppt16);
  1454. ppt16[0].x = (SHORT)lParamNew[0].x;
  1455. ppt16[0].y = (SHORT)lParamNew[0].y;
  1456. ppt16[1].x = (SHORT)lParamNew[1].x;
  1457. ppt16[1].y = (SHORT)lParamNew[1].y;
  1458. ppt16[2].x = (SHORT)lParamNew[2].x;
  1459. ppt16[2].y = (SHORT)lParamNew[2].y;
  1460. ppt16[3].x = (SHORT)lParamNew[3].x;
  1461. ppt16[3].y = (SHORT)lParamNew[3].y;
  1462. ppt16[4].x = (SHORT)lParamNew[4].x;
  1463. ppt16[4].y = (SHORT)lParamNew[4].y;
  1464. FLUSHVDMPTR(lParam, sizeof(POINT16)*5, ppt16);
  1465. FREEVDMPTR(ppt16);
  1466. }
  1467. RETURN(NOTHING);
  1468. }
  1469. BOOL ThunkWMMDICreate16(VPVOID lParam, LPMDICREATESTRUCT *plParamNew)
  1470. {
  1471. register LPMDICREATESTRUCT lpmdicreate;
  1472. register PMDICREATESTRUCT16 pmdicreate16;
  1473. if (lParam) {
  1474. lpmdicreate = *plParamNew;
  1475. GETVDMPTR(lParam, sizeof(MDICREATESTRUCT16), pmdicreate16);
  1476. GETPSZIDPTR( pmdicreate16->vpszClass, lpmdicreate->szClass );
  1477. GETPSZPTR( pmdicreate16->vpszTitle, lpmdicreate->szTitle );
  1478. lpmdicreate->hOwner = HMODINST32( pmdicreate16->hOwner );
  1479. lpmdicreate->x = INT32DEFAULT(pmdicreate16->x);
  1480. lpmdicreate->y = INT32DEFAULT(pmdicreate16->y);
  1481. lpmdicreate->cx = INT32DEFAULT(pmdicreate16->cx);
  1482. lpmdicreate->cy = INT32DEFAULT(pmdicreate16->cy);
  1483. lpmdicreate->style = pmdicreate16->style;
  1484. lpmdicreate->lParam = pmdicreate16->lParam;
  1485. FREEVDMPTR(pmdicreate16);
  1486. }
  1487. RETURN(TRUE);
  1488. }
  1489. VOID UnThunkWMMDICreate16(VPVOID lParam, register LPMDICREATESTRUCT lParamNew)
  1490. {
  1491. register PMDICREATESTRUCT16 pmdicreate16;
  1492. if (lParamNew) {
  1493. GETVDMPTR(lParam, sizeof(MDICREATESTRUCT16), pmdicreate16);
  1494. pmdicreate16->hOwner = GETHINST16(lParamNew->hOwner);
  1495. pmdicreate16->x = (SHORT)lParamNew->x;
  1496. pmdicreate16->y = (SHORT)lParamNew->y;
  1497. pmdicreate16->cx = (SHORT)lParamNew->cx;
  1498. pmdicreate16->cy = (SHORT)lParamNew->cy;
  1499. pmdicreate16->style = lParamNew->style;
  1500. pmdicreate16->lParam = lParamNew->lParam;
  1501. FLUSHVDMPTR(lParam, sizeof(MDICREATESTRUCT16), pmdicreate16);
  1502. FREEVDMPTR(pmdicreate16);
  1503. }
  1504. RETURN(NOTHING);
  1505. }
  1506. BOOL FASTCALL ThunkSTMsg16(LPMSGPARAMEX lpmpex)
  1507. {
  1508. WORD wMsg = lpmpex->Parm16.WndProc.wMsg;
  1509. LOGDEBUG(9,(" Thunking 16-bit STM window message %s(%04x)\n", (LPSZ)GetWMMsgName(wMsg), wMsg));
  1510. switch(wMsg) {
  1511. case WIN30_STM_SETICON:
  1512. lpmpex->uMsg = STM_SETICON;
  1513. lpmpex->uParam = (UINT) HICON32(lpmpex->Parm16.WndProc.wParam);
  1514. break;
  1515. case WIN30_STM_GETICON:
  1516. lpmpex->uMsg = STM_GETICON;
  1517. break;
  1518. }
  1519. return (TRUE);
  1520. }
  1521. VOID FASTCALL UnThunkSTMsg16(LPMSGPARAMEX lpmpex)
  1522. {
  1523. WORD wMsg = lpmpex->Parm16.WndProc.wMsg;
  1524. LOGDEBUG(9,(" UnThunking 16-bit STM window message %s(%04x)\n", (LPSZ)GetWMMsgName(wMsg), wMsg));
  1525. switch(wMsg) {
  1526. case WIN30_STM_GETICON:
  1527. case WIN30_STM_SETICON:
  1528. lpmpex->lReturn = GETHICON16(lpmpex->lReturn);
  1529. break;
  1530. }
  1531. }
  1532. BOOL FASTCALL ThunkMNMsg16(LPMSGPARAMEX lpmpex)
  1533. {
  1534. WORD wMsg = lpmpex->Parm16.WndProc.wMsg;
  1535. LOGDEBUG(9,(" Thunking 16-bit MN_ window message %s(%04x)\n", (LPSZ)GetWMMsgName(wMsg), wMsg));
  1536. switch(wMsg) {
  1537. case WIN30_MN_GETHMENU:
  1538. lpmpex->uMsg = MN_GETHMENU;
  1539. break;
  1540. case WIN30_MN_FINDMENUWINDOWFROMPOINT:
  1541. lpmpex->uMsg = MN_FINDMENUWINDOWFROMPOINT;
  1542. lpmpex->uParam = (UINT)lpmpex->MsgBuffer; // enough room for UINT
  1543. *(PUINT)lpmpex->uParam = 0;
  1544. break;
  1545. }
  1546. return (TRUE);
  1547. }
  1548. VOID FASTCALL UnThunkMNMsg16(LPMSGPARAMEX lpmpex)
  1549. {
  1550. WORD wMsg = lpmpex->Parm16.WndProc.wMsg;
  1551. LOGDEBUG(9,(" UnThunking 16-bit MN_ window message %s(%04x)\n", (LPSZ)GetWMMsgName(wMsg), wMsg));
  1552. switch(wMsg) {
  1553. case WIN30_MN_FINDMENUWINDOWFROMPOINT:
  1554. if (lpmpex->uParam) {
  1555. lpmpex->lReturn = MAKELONG((HWND16)lpmpex->lReturn,
  1556. LOWORD(*(PUINT)lpmpex->uParam));
  1557. }
  1558. break;
  1559. }
  1560. }