Leaked source code of windows server 2003
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.

1893 lines
63 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. if(lpMem32 == NULL) {
  703. WOWGLOBALFREE(h32);
  704. return(0);
  705. }
  706. vp = GlobalLock16(LOWORD(lParam), &cb);
  707. GETMISCPTR(vp, lpMem16);
  708. RtlCopyMemory(lpMem32, lpMem16, sizeof(DDEADVISE));
  709. FREEMISCPTR(lpMem16);
  710. GlobalUnlock(h32);
  711. GlobalUnlock16(LOWORD(lParam));
  712. DdeInfo.Msg = wMsg;
  713. DdeInfo.Format = 0;
  714. DdeInfo.Flags = DDE_PACKET;
  715. DdeInfo.h16 = 0;
  716. DDEAddhandle(hwnd16, wParam, (HAND16)LOWORD(lParam), h32, &DdeInfo);
  717. *plParamNew = PackDDElParam(wMsg, (LONG) h32, (LONG) HIWORD(lParam));
  718. }
  719. else {
  720. if (fThunkDDEmsg) {
  721. if (!(h32 = DDEFindPair32(hwnd16, wParam, (HAND16) LOWORD(lParam)))) {
  722. LOGDEBUG (0, ("WOW::WMSG16: WM_DDE_ADVISE : Can't find h32 !\n"));
  723. }
  724. *plParamNew = PackDDElParam(wMsg, (LONG) h32, (LONG) HIWORD(lParam));
  725. }
  726. else {
  727. *plParamNew = W32GetHookDDEMsglParam();
  728. }
  729. }
  730. }
  731. break;
  732. case WM_DDE_DATA:
  733. {
  734. DDEINFO DdeInfo;
  735. HANDLE h32;
  736. HWND16 hwnd16 = lpmpex->Parm16.WndProc.hwnd;
  737. WORD wMsg = lpmpex->Parm16.WndProc.wMsg;
  738. lpmpex->uParam = (LONG) FULLHWND32(wParam);
  739. if (fWhoCalled == WOWDDE_POSTMESSAGE) {
  740. if (h32 = DDEFindPair32(hwnd16, wParam, (HAND16) LOWORD(lParam))) {
  741. DDEDeletehandle(LOWORD(lParam), h32);
  742. WOWGLOBALFREE(h32);
  743. }
  744. if (!LOWORD(lParam)) {
  745. h32 = 0;
  746. }
  747. else {
  748. DdeInfo.Msg = wMsg;
  749. h32 = DDECopyhData32(hwnd16, wParam, (HAND16) LOWORD(lParam), &DdeInfo);
  750. // WARNING: 16-bit memory may have moved
  751. DdeInfo.Flags = DDE_PACKET;
  752. DdeInfo.h16 = 0;
  753. DDEAddhandle(hwnd16, wParam, (HAND16)LOWORD(lParam), h32, &DdeInfo);
  754. }
  755. *plParamNew = PackDDElParam(wMsg, (LONG) h32, (LONG) HIWORD(lParam));
  756. }
  757. else {
  758. if (fThunkDDEmsg) {
  759. if (!LOWORD(lParam)) {
  760. h32 = 0;
  761. }
  762. else {
  763. if (!(h32 = DDEFindPair32(hwnd16, wParam, (HAND16) LOWORD(lParam)))) {
  764. LOGDEBUG (0, ("WOW::WMSG16: WM_DDE_DATA : Can't find h32 !\n"));
  765. }
  766. }
  767. *plParamNew = PackDDElParam(wMsg, (LONG) h32, (LONG) HIWORD(lParam));
  768. }
  769. else {
  770. *plParamNew = W32GetHookDDEMsglParam();
  771. }
  772. }
  773. }
  774. break;
  775. case WM_DDE_EXECUTE:
  776. {
  777. DDEINFO DdeInfo;
  778. HANDLE h32;
  779. HAND16 h16;
  780. INT cb;
  781. VPVOID vp;
  782. VPVOID vp1;
  783. LPBYTE lpMem16;
  784. LPBYTE lpMem32;
  785. HWND16 hwnd16 = lpmpex->Parm16.WndProc.hwnd;
  786. WORD wMsg = lpmpex->Parm16.WndProc.wMsg;
  787. lpmpex->uParam = (LONG) FULLHWND32(wParam);
  788. if (fWhoCalled == WOWDDE_POSTMESSAGE) {
  789. vp = GlobalLock16(HIWORD(lParam), &cb);
  790. GETMISCPTR(vp, lpMem16);
  791. h32 = WOWGLOBALALLOC(GMEM_DDESHARE, cb);
  792. if (h32) {
  793. lpMem32 = GlobalLock(h32);
  794. if(lpMem32 == NULL) {
  795. goto mem1;
  796. }
  797. RtlCopyMemory(lpMem32, lpMem16, cb);
  798. GlobalUnlock(h32);
  799. FREEMISCPTR(lpMem16);
  800. //
  801. // The alias is checked to make bad apps do WM_DDE_EXECUTE
  802. // correctly. One such app is SuperPrint. This app issues
  803. // multiple WM_DDE_EXECUTEs without waiting for WM_DDE_ACK to
  804. // come. Also, it uses the same h16 on these messages.
  805. // We get around this problem by generating a unique h16-h32
  806. // pairing each time. And freeing h16 when the WM_DDE_ACK comes.
  807. // In WM32DDEAck, we need to free this h16 because we allocated
  808. // this one. Apply this hack only if the h16 is valid. Caere
  809. // OmniPage passes hard coded constants in HIWORD(lParam).
  810. //
  811. // SunilP, ChandanC 4-30-93
  812. //
  813. if (vp && DDEFindPair32(hwnd16, wParam, (HAND16) HIWORD(lParam))) {
  814. vp1 = GlobalAllocLock16(GMEM_DDESHARE, cb, &h16);
  815. if (vp1) {
  816. GETMISCPTR(vp1, lpMem16);
  817. RtlCopyMemory(lpMem16, lpMem32, cb);
  818. FLUSHVDMPTR(vp1, cb, lpMem16);
  819. FREEMISCPTR(lpMem16);
  820. GlobalUnlock16(h16);
  821. DdeInfo.Msg = wMsg;
  822. DdeInfo.Format = 0;
  823. DdeInfo.Flags = DDE_EXECUTE_FREE_H16 | DDE_PACKET;
  824. DdeInfo.h16 = (HAND16) HIWORD(lParam);
  825. DDEAddhandle(hwnd16, wParam, h16, h32, &DdeInfo);
  826. }
  827. else {
  828. LOGDEBUG (0, ("WOW::WMSG16: WM_DDE_EXECUTE : Can't allocate h16 !\n"));
  829. }
  830. }
  831. else {
  832. DdeInfo.Msg = wMsg;
  833. DdeInfo.Format = 0;
  834. DdeInfo.Flags = DDE_PACKET;
  835. DdeInfo.h16 = 0;
  836. DDEAddhandle(hwnd16, wParam, (HAND16)HIWORD(lParam), h32, &DdeInfo);
  837. }
  838. }
  839. else {
  840. mem1:
  841. GlobalUnlock16(HIWORD(lParam));
  842. }
  843. GlobalUnlock16(HIWORD(lParam));
  844. }
  845. else {
  846. if (!(h32 = DDEFindPair32(hwnd16, wParam, (HAND16) HIWORD(lParam)))) {
  847. LOGDEBUG (0, ("WOW::WMSG16: WM_DDE_EXECUTE : Can't find h32 !\n"));
  848. }
  849. }
  850. *plParamNew = (ULONG)h32;
  851. }
  852. break;
  853. case WM_COPYDATA:
  854. {
  855. LPBYTE lpMem16;
  856. LPBYTE lpMem32;
  857. PCOPYDATASTRUCT16 lpCDS16;
  858. PCOPYDATASTRUCT lpCDS32 = NULL;
  859. PCPDATA pTemp;
  860. HWND16 hwnd16 = lpmpex->Parm16.WndProc.hwnd;
  861. lpmpex->uParam = (LONG) HWND32(wParam);
  862. if (fWhoCalled == WOWDDE_POSTMESSAGE) {
  863. GETMISCPTR(lParam, lpCDS16);
  864. if (lpCDS32 = (PCOPYDATASTRUCT) malloc_w(sizeof(COPYDATASTRUCT))) {
  865. lpCDS32->dwData = lpCDS16->dwData;
  866. if (lpCDS32->cbData = lpCDS16->cbData) {
  867. if (lpMem32 = malloc_w(lpCDS32->cbData)) {
  868. GETMISCPTR(lpCDS16->lpData, lpMem16);
  869. if (lpMem16) {
  870. RtlCopyMemory(lpMem32, lpMem16, lpCDS32->cbData);
  871. CopyDataAddNode (hwnd16, wParam, (DWORD) lpMem16, (DWORD) lpMem32, COPYDATA_16);
  872. }
  873. FREEMISCPTR(lpMem16);
  874. }
  875. lpCDS32->lpData = lpMem32;
  876. }
  877. else {
  878. lpCDS32->lpData = NULL;
  879. }
  880. }
  881. FREEMISCPTR(lpCDS16);
  882. CopyDataAddNode (hwnd16, wParam, (DWORD) lParam, (DWORD) lpCDS32, COPYDATA_16);
  883. }
  884. else {
  885. pTemp = CopyDataFindData32 (hwnd16, wParam, lParam);
  886. if (pTemp) {
  887. lpCDS32 = (PCOPYDATASTRUCT) pTemp->Mem32;
  888. }
  889. WOW32ASSERTMSGF(lpCDS32, ("WOW::WM_COPYDATA:Can't locate lpCDS32\n"));
  890. }
  891. *plParamNew = (LONG)lpCDS32;
  892. }
  893. break;
  894. // Win 3.1 messages
  895. case WM_DROPFILES:
  896. lpmpex->uParam = (UINT)HDROP32(wParam);
  897. WOW32ASSERT(lpmpex->uParam != 0);
  898. break;
  899. case WM_DROPOBJECT:
  900. case WM_QUERYDROPOBJECT:
  901. case WM_DRAGLOOP:
  902. case WM_DRAGSELECT:
  903. case WM_DRAGMOVE:
  904. {
  905. register LPDROPSTRUCT lpds;
  906. register PDROPSTRUCT16 lpds16;
  907. if (lParam) {
  908. lpds = (LPDROPSTRUCT) lpmpex->MsgBuffer;
  909. GETVDMPTR(lParam, sizeof(DROPSTRUCT16), lpds16);
  910. lpds->hwndSource = HWND32(lpds16->hwndSource);
  911. lpds->hwndSink = HWND32(lpds16->hwndSink);
  912. lpds->wFmt = lpds16->wFmt;
  913. lpds->ptDrop.y = (LONG)lpds16->ptDrop.y;
  914. lpds->ptDrop.x = (LONG)lpds16->ptDrop.x;
  915. lpds->dwControlData = lpds16->dwControlData;
  916. *plParamNew = (LONG) lpds;
  917. FREEVDMPTR(lpds16);
  918. }
  919. }
  920. break;
  921. case WM_NEXTMENU: // Thunk
  922. *plParamNew = (LONG)lpmpex->MsgBuffer;
  923. ((PMDINEXTMENU)(*plParamNew))->hmenuIn = HMENU32(LOWORD(lParam));
  924. break;
  925. case WM_WINDOWPOSCHANGING:
  926. case WM_WINDOWPOSCHANGED:
  927. if (lParam) {
  928. lpmpex->lParam = (LONG) lpmpex->MsgBuffer;
  929. getwindowpos16( (VPWINDOWPOS16)lParam, (LPWINDOWPOS)lpmpex->lParam );
  930. }
  931. break;
  932. case WM_TIMER:
  933. {
  934. HAND16 htask16;
  935. PTMR ptmr;
  936. WORD wIDEvent;
  937. htask16 = CURRENTPTD()->htask16;
  938. wIDEvent = wParam;
  939. ptmr = FindTimer16( lpmpex->Parm16.WndProc.hwnd, htask16, wIDEvent );
  940. if ( !ptmr ) {
  941. if ( lParam == 0L ) {
  942. /*
  943. ** Edit controls have timers which can be sent straight
  944. ** through without thunking... (wParam=1, lParam=0)
  945. */
  946. lpmpex->uParam = (UINT)wIDEvent;
  947. *plParamNew = 0L;
  948. } else {
  949. LOGDEBUG(6,(" ThunkWMMSG16 WARNING: cannot find timer %04x\n", wIDEvent));
  950. }
  951. } else {
  952. lpmpex->uParam = (UINT)wIDEvent;
  953. *plParamNew = ptmr->dwTimerProc32; // 32-bit proc or NULL
  954. }
  955. }
  956. break;
  957. #ifdef FE_IME
  958. case WM_IME_REPORT:
  959. {
  960. INT cb;
  961. INT i;
  962. INT len;
  963. VPVOID vp;
  964. HANDLE hMem32 = 0;
  965. LPBYTE lpMem32 = 0;
  966. LPBYTE lpMem16 = 0;
  967. if ( !lParam )
  968. break;
  969. if (wParam == IR_STRING) {
  970. /*********************** IR_STRING **********************************/
  971. vp = GlobalLock16(FETCHWORD(lParam), &cb);
  972. GETMISCPTR(vp, lpMem16);
  973. if (!(hMem32 = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE | GMEM_ZEROINIT, cb)))
  974. goto Err;
  975. lpMem32 = GlobalLock(hMem32);
  976. if(lpMem32 == NULL)
  977. goto Err;
  978. RtlCopyMemory(lpMem32, lpMem16, cb);
  979. GlobalUnlock( hMem32 );
  980. GlobalUnlock16( FETCHWORD(lParam) );
  981. *plParamNew = (LONG)hMem32;
  982. }
  983. /*********************** IR_STRINGEX ********************************/
  984. else if ( wParam == IR_STRINGEX ) {
  985. LPSTRINGEXSTRUCT pss32;
  986. PSTRINGEXSTRUCT16 pss16;
  987. INT uDetermineDelim = 0;
  988. INT uYomiDelim = 0;
  989. vp = GlobalLock16( FETCHWORD(lParam), &cb );
  990. GETMISCPTR(vp, lpMem16);
  991. pss16 = (PSTRINGEXSTRUCT16)lpMem16;
  992. cb = sizeof(STRINGEXSTRUCT);
  993. /* Get exactry size */
  994. if ( lpMem16[ pss16->uDeterminePos ] ) {
  995. len = lstrlen( &lpMem16[ pss16->uDeterminePos ] );
  996. cb += len + 1;
  997. cb += sizeof(INT) - (cb % sizeof(INT)); // #2259 kksuzuka
  998. // DetermineDelim[0] is everytime NULL
  999. // BAD CODE
  1000. // for ( i = 0; i < len && INTOF( lpMem16[ pss16->uDetermineDelimPos ], i ); i++ )
  1001. // #7253 kksuzuka
  1002. for ( i = 1; (i <= len) && WORDOF( lpMem16[ pss16->uDetermineDelimPos ], i ); i++ )
  1003. // if ( INTOF( lpMem16[ pss16->uDetermineDelimPos ], i ) >= len )
  1004. // #7253 kksuzuka
  1005. if ( WORDOF( lpMem16[ pss16->uDetermineDelimPos ], i ) >= len )
  1006. break;
  1007. if ( i <= len )
  1008. // #7253 kksuzuka
  1009. cb += (i + 1) * sizeof(INT);
  1010. // cb += i * sizeof(INT);
  1011. uDetermineDelim = i;
  1012. }
  1013. if ( lpMem16[ pss16->uYomiPos ] ) {
  1014. len = lstrlen( &lpMem16[ pss16->uYomiPos ] );
  1015. cb += len + 1;
  1016. cb += sizeof(INT) - (cb % sizeof(INT)); // #2259 kksuzuka
  1017. // YomiDelim[0] is everytime NULL
  1018. // BAD CODE
  1019. // for ( i = 0; i < len && INTOF( lpMem16[ pss16->uYomiDelimPos ], i ); i++ )
  1020. // #7253 kksuzuka
  1021. for ( i = 1; (i <= len) && WORDOF( lpMem16[ pss16->uYomiDelimPos ], i ); i++ )
  1022. // if ( INTOF( lpMem16[ pss16->uYomiDelimPos ], i ) >= len )
  1023. // #7253 kksuzuka
  1024. if ( WORDOF( lpMem16[ pss16->uYomiDelimPos ], i ) >= len )
  1025. break;
  1026. if ( i <= len )
  1027. // #7253 kksuzuka
  1028. cb += (i + 1) * sizeof(UINT);
  1029. // cb += i * sizeof(UINT);
  1030. uYomiDelim = i;
  1031. }
  1032. if (!(hMem32 = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE | GMEM_ZEROINIT, cb)))
  1033. goto Err;
  1034. lpMem32 = GlobalLock( hMem32 );
  1035. if(lpMem32 == NULL)
  1036. goto Err;
  1037. pss32 = (LPSTRINGEXSTRUCT)lpMem32;
  1038. pss32->dwSize = cb;
  1039. i = sizeof( STRINGEXSTRUCT );
  1040. if ( pss16->uDeterminePos ) {
  1041. pss32->uDeterminePos = i;
  1042. lstrcpy( &lpMem32[ i ], &lpMem16[ pss16->uDeterminePos ] );
  1043. i += lstrlen( &lpMem16[ pss16->uDeterminePos ] ) + 1;
  1044. i += sizeof(INT) - (i % sizeof(INT)); // kksuzuka #2259
  1045. }
  1046. if ( pss16->uDetermineDelimPos ) {
  1047. pss32->uDetermineDelimPos = i;
  1048. // i += uDetermineDelim * sizeof(UINT);
  1049. // #7253 kksuzuka
  1050. i += (uDetermineDelim + 1)* sizeof(UINT);
  1051. for( ; uDetermineDelim ; uDetermineDelim-- ) {
  1052. INTOF( lpMem32[ pss32->uDetermineDelimPos ], uDetermineDelim ) =
  1053. WORDOF( lpMem16[ pss16->uDetermineDelimPos ], uDetermineDelim );
  1054. }
  1055. }
  1056. if ( pss16->uYomiPos ) {
  1057. pss32->uYomiPos = i;
  1058. lstrcpy( &lpMem32[ i ], &lpMem16[ pss16->uYomiPos ] );
  1059. i += lstrlen( &lpMem16[ pss16->uYomiPos ] ) + 1;
  1060. i += sizeof(INT) - (i % sizeof(INT)); // kksuzuka #2259
  1061. }
  1062. if ( pss16->uYomiDelimPos ) {
  1063. pss32->uYomiDelimPos = i;
  1064. i += uYomiDelim * sizeof(UINT);
  1065. for( ; uYomiDelim ; uYomiDelim-- ) {
  1066. INTOF( lpMem32[ pss32->uYomiDelimPos ], uYomiDelim ) =
  1067. WORDOF( lpMem16[ pss16->uYomiDelimPos ], uYomiDelim );
  1068. }
  1069. }
  1070. *plParamNew = (LONG)hMem32;
  1071. GlobalUnlock16(FETCHWORD(lParam));
  1072. GlobalUnlock( hMem32 );
  1073. }
  1074. else if (wParam == IR_UNDETERMINE) {
  1075. /********************** IR_UNDETERMINE ******************************/
  1076. PUNDETERMINESTRUCT16 pus16;
  1077. LPUNDETERMINESTRUCT pus32;
  1078. vp = GlobalLock16( FETCHWORD(lParam), &cb );
  1079. GETMISCPTR(vp, lpMem16);
  1080. pus16 = (PUNDETERMINESTRUCT16)lpMem16;
  1081. cb = sizeof(UNDETERMINESTRUCT);
  1082. cb += pus16->uDefIMESize;
  1083. cb += (pus16->uUndetTextLen + 1);
  1084. cb += (pus16->uDetermineTextLen + 1);
  1085. cb += (pus16->uYomiTextLen + 1);
  1086. if ( pus16->uUndetAttrPos )
  1087. cb += pus16->uUndetTextLen;
  1088. if ( pus16->uDetermineDelimPos )
  1089. cb += pus16->uDetermineTextLen * sizeof(UINT);
  1090. if ( pus16->uYomiDelimPos )
  1091. cb += pus16->uYomiTextLen * sizeof(UINT);
  1092. if (!(hMem32 = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE | GMEM_ZEROINIT, cb)))
  1093. goto Err;
  1094. lpMem32 = GlobalLock(hMem32);
  1095. if(lpMem32 == NULL)
  1096. goto Err;
  1097. pus32 = (LPUNDETERMINESTRUCT)lpMem32;
  1098. i = sizeof(UNDETERMINESTRUCT);
  1099. if ( pus16->uUndetTextLen ) {
  1100. RtlCopyMemory( &lpMem32[ i ], &lpMem16[ pus16->uUndetTextPos ], pus16->uUndetTextLen + 1 );
  1101. pus32->uUndetTextPos = i;
  1102. i += pus16->uUndetTextLen + 1;
  1103. pus32->uUndetTextLen = pus16->uUndetTextLen;
  1104. }
  1105. if ( pus16->uUndetAttrPos ) {
  1106. RtlCopyMemory( &lpMem32[ i ], &lpMem16[ pus16->uUndetAttrPos ], pus16->uUndetTextLen );
  1107. pus32->uUndetAttrPos = i;
  1108. i += pus16->uUndetTextLen;
  1109. }
  1110. if ( pus16->uDetermineTextLen ) {
  1111. RtlCopyMemory( &lpMem32[ i ], &lpMem16[ pus16->uDetermineTextPos ], pus16->uDetermineTextLen + 1 );
  1112. pus32->uDetermineTextPos = i;
  1113. i += pus16->uDetermineTextLen + 1;
  1114. pus32->uDetermineTextLen = pus16->uDetermineTextLen;
  1115. }
  1116. if ( pus16->uDetermineDelimPos ) {
  1117. INT j;
  1118. pus32->uDetermineDelimPos = i;
  1119. for ( j = 0; j < pus16->uDetermineTextLen; j++ ) {
  1120. if ( WORDOF16( lpMem16[ pus16->uDetermineTextLen ], j ) || pus16->uDetermineTextLen > WORDOF16( lpMem16[ pus16->uDetermineTextLen ], j )) {
  1121. INTOF( lpMem32[ i ], 0 ) = WORDOF16( lpMem16[ pus16->uDetermineTextLen ], j );
  1122. i += sizeof(UINT);
  1123. }
  1124. else
  1125. break;
  1126. }
  1127. }
  1128. if ( pus16->uYomiTextLen ) {
  1129. RtlCopyMemory( &lpMem32[ i ], &lpMem16[ pus16->uYomiTextPos ], pus16->uYomiTextLen + 1 );
  1130. pus32->uYomiTextPos = i;
  1131. pus32->uYomiTextLen = pus16->uYomiTextLen;
  1132. i += pus16->uYomiTextLen + 1;
  1133. }
  1134. if ( pus16->uYomiDelimPos ) {
  1135. INT j;
  1136. pus32->uYomiDelimPos = i;
  1137. for ( j = 0; j < pus16->uYomiTextLen; j++ ) {
  1138. if ( WORDOF16(lpMem16[ pus16->uYomiDelimPos ], j ) || pus16->uYomiTextLen > WORDOF16(lpMem16[ pus16->uYomiDelimPos ], j )) {
  1139. INTOF( lpMem32[ i ], 0 ) = WORDOF16( lpMem16[ pus16->uYomiDelimPos ], j );
  1140. i += sizeof(UINT);
  1141. }
  1142. else
  1143. break;
  1144. }
  1145. }
  1146. if ( pus16->uDefIMESize ) {
  1147. RtlCopyMemory( &lpMem32[ i ], &lpMem16[ pus16->uDefIMEPos ], pus16->uDefIMESize );
  1148. pus32->uDefIMEPos = i;
  1149. }
  1150. *plParamNew = (LONG)hMem32;
  1151. GlobalUnlock16( FETCHWORD(lParam));
  1152. GlobalUnlock( hMem32 );
  1153. }
  1154. break;
  1155. Err:
  1156. if ( lpMem16 && FETCHWORD(lParam ))
  1157. GlobalUnlock16( FETCHWORD(lParam) );
  1158. if (hMem32) {
  1159. GlobalFree(hMem32);
  1160. }
  1161. return FALSE;
  1162. }
  1163. break;
  1164. // MSKK support WM_IMEKEYDOWN message
  1165. // MSKK support WM_IMEKEYUP message
  1166. // MSKK16bit IME support
  1167. // WM_IMEKEYDOWN & WM_IMEKEYUP 16 -> 32
  1168. // 32bit:wParam HIWORD charactor code, LOWORD virtual key
  1169. // 16bit:wParam HIBYTE charactor code, LOBYTE virtual key
  1170. // kksuzuka:#4281 1994.11.19 MSKK V-HIDEKK
  1171. case WM_IMEKEYDOWN:
  1172. case WM_IMEKEYUP:
  1173. #ifdef DEBUG
  1174. LOGDEBUG( 5, ("ThunkWMMsg16:WM_IMEKEY debug\n"));
  1175. #endif
  1176. lpmpex->uParam = MAKELONG( LOBYTE(wParam), HIBYTE(wParam) );
  1177. break;
  1178. #endif // FE_IME
  1179. case WM_PRINT:
  1180. case WM_PRINTCLIENT:
  1181. lpmpex->uParam = (WPARAM)HDC32(wParam);
  1182. break;
  1183. case WM_NOTIFY: // 0x4e
  1184. // wparam is control ID, lparam points to NMHDR or larger struct.
  1185. {
  1186. LONG lParamMap;
  1187. GETVDMPTR(lParam, sizeof(NMHDR), (PSZ)lParamMap);
  1188. *plParamNew = (LONG)AddParamMap(lParamMap, lParam);
  1189. if (lParamMap != *plParamNew) {
  1190. FREEVDMPTR((PSZ)lParamMap);
  1191. }
  1192. }
  1193. break;
  1194. case WM_CHANGEUISTATE: // 0x127
  1195. case WM_UPDATEUISTATE: // 0x128
  1196. case WM_QUERYUISTATE: // 0x129
  1197. // We should only see this message originate from the 32-bit side
  1198. // It will come with both words of uParam used and lPram unused.
  1199. // We 32->16 thunk it (WM32xxxUIState() - wmdisp32.c) by copying
  1200. // uParam32 to lParam16. Now we are just reversing the process.
  1201. lpmpex->uParam = (UINT)lParam;
  1202. *plParamNew = 0;
  1203. break;
  1204. } // end switch
  1205. return TRUE;
  1206. }
  1207. //
  1208. // the WM_CREATE message has already been thunked, but this WM_CREATE
  1209. // is coming from an MDI client window so lParam->lpCreateParams needs
  1210. // special attention
  1211. //
  1212. BOOL FinishThunkingWMCreateMDI16(LONG lParamNew, LPCLIENTCREATESTRUCT lpCCS)
  1213. {
  1214. PCLIENTCREATESTRUCT16 pCCS16;
  1215. GETVDMPTR(((LPCREATESTRUCT)lParamNew)->lpCreateParams,
  1216. sizeof(CLIENTCREATESTRUCT16), pCCS16);
  1217. lpCCS->hWindowMenu = HMENU32(FETCHWORD(pCCS16->hWindowMenu));
  1218. lpCCS->idFirstChild = WORD32(FETCHWORD(pCCS16->idFirstChild));
  1219. ((LPCREATESTRUCT)lParamNew)->lpCreateParams = (LPVOID)lpCCS;
  1220. FREEVDMPTR(pCCS16);
  1221. return TRUE;
  1222. }
  1223. //
  1224. // the WM_CREATE message has already been thunked, but this WM_CREATE
  1225. // is coming from an MDI child window so lParam->lpCreateParams needs
  1226. // special attention
  1227. //
  1228. BOOL FinishThunkingWMCreateMDIChild16(LONG lParamNew, LPMDICREATESTRUCT lpMCS)
  1229. {
  1230. PMDICREATESTRUCT16 pMCS16;
  1231. GETVDMPTR(((LPCREATESTRUCT)lParamNew)->lpCreateParams,
  1232. sizeof(MDICREATESTRUCT16), pMCS16);
  1233. GETPSZIDPTR(pMCS16->vpszClass, lpMCS->szClass);
  1234. GETPSZPTR(pMCS16->vpszTitle, lpMCS->szTitle);
  1235. lpMCS->hOwner = HMODINST32(FETCHWORD(pMCS16->hOwner));
  1236. lpMCS->x = (int)FETCHWORD(pMCS16->x);
  1237. lpMCS->y = (int)FETCHWORD(pMCS16->y);
  1238. lpMCS->cx = (int)FETCHWORD(pMCS16->cx);
  1239. lpMCS->cy = (int)FETCHWORD(pMCS16->cy);
  1240. lpMCS->style = FETCHDWORD(pMCS16->style);
  1241. lpMCS->lParam = FETCHDWORD(pMCS16->lParam);
  1242. ((LPCREATESTRUCT)lParamNew)->lpCreateParams = (LPVOID)lpMCS;
  1243. FREEVDMPTR(pMCS16);
  1244. return TRUE;
  1245. }
  1246. VOID FASTCALL UnThunkWMMsg16(LPMSGPARAMEX lpmpex)
  1247. {
  1248. switch(lpmpex->Parm16.WndProc.wMsg) {
  1249. case WM_SETTEXT: // 00Ch, <SLPre,SLPost >
  1250. case WM_WININICHANGE: // 01Ah, <SLPre, LS>
  1251. case WM_DEVMODECHANGE: // 01Bh, <SLPre, LS>
  1252. {
  1253. BOOL fFreePtr;
  1254. DeleteParamMap(lpmpex->lParam, PARAM_32, &fFreePtr);
  1255. if (fFreePtr) {
  1256. FREEPSZPTR((LPSZ)lpmpex->lParam);
  1257. }
  1258. }
  1259. break;
  1260. case WM_GETTEXT: // 00Dh, <SLPre,SLPost,LS>
  1261. if ((WORD)lpmpex->lReturn > 0) {
  1262. FLUSHVDMPTR(lpmpex->Parm16.WndProc.lParam, lpmpex->Parm16.WndProc.wParam, (LPSZ)lpmpex->lParam);
  1263. FREEPSZPTR((LPSZ)lpmpex->lParam);
  1264. }
  1265. break;
  1266. case WM_GETMINMAXINFO: // 024h, <SLPre,SLPost,LS>,MINMAXINFOSTRUCT
  1267. UnThunkWMGetMinMaxInfo16(lpmpex->Parm16.WndProc.lParam, (LPPOINT)lpmpex->lParam);
  1268. break;
  1269. case WM_DRAWITEM: // 02Bh notused, DRAWITEMSTRUCT
  1270. if (lpmpex->lParam) {
  1271. putdrawitem16((VPDRAWITEMSTRUCT16)lpmpex->Parm16.WndProc.lParam, (PDRAWITEMSTRUCT)lpmpex->lParam);
  1272. }
  1273. break;
  1274. case WM_MEASUREITEM: // 02Ch notused, MEASUREITEMSTRUCT
  1275. if (lpmpex->lParam) {
  1276. putmeasureitem16((VPMEASUREITEMSTRUCT16)lpmpex->Parm16.WndProc.lParam, (PMEASUREITEMSTRUCT)lpmpex->lParam);
  1277. }
  1278. break;
  1279. case WM_DELETEITEM: // 02Dh notused, DELETEITEMSTRUCT
  1280. if (lpmpex->lParam) {
  1281. putdeleteitem16((VPDELETEITEMSTRUCT16)lpmpex->Parm16.WndProc.lParam, (PDELETEITEMSTRUCT)lpmpex->lParam);
  1282. }
  1283. break;
  1284. case WM_GETFONT: // 031h
  1285. lpmpex->lReturn = GETHFONT16(lpmpex->lReturn);
  1286. break;
  1287. case WM_COMPAREITEM: // 039h
  1288. if (lpmpex->lParam) {
  1289. putcompareitem16((VPCOMPAREITEMSTRUCT16)lpmpex->Parm16.WndProc.lParam, (PCOMPAREITEMSTRUCT)lpmpex->lParam);
  1290. }
  1291. break;
  1292. case WM_WINHELP:
  1293. if (lpmpex->lParam && lpmpex->lParam != (LONG)lpmpex->MsgBuffer) {
  1294. free_w((PVOID)lpmpex->lParam);
  1295. }
  1296. break;
  1297. case WM_SIZING: // 214h, <SLPre,SLPost,LS>,RECT
  1298. if (lpmpex->lParam) {
  1299. putrect16((VPRECT16)lpmpex->Parm16.WndProc.lParam, (LPRECT)lpmpex->lParam);
  1300. }
  1301. break;
  1302. case WM_NCCALCSIZE: // 083h, <SLPre,SLPost,LS>,RECT
  1303. if (lpmpex->lParam) {
  1304. putrect16((VPRECT16)lpmpex->Parm16.WndProc.lParam, (LPRECT)lpmpex->lParam);
  1305. if (lpmpex->Parm16.WndProc.wParam) {
  1306. PNCCALCSIZE_PARAMS16 pnc16;
  1307. PNCCALCSIZE_PARAMS16 lpnc16;
  1308. LPNCCALCSIZE_PARAMS lpnc;
  1309. lpnc = (LPNCCALCSIZE_PARAMS)lpmpex->lParam;
  1310. pnc16 = (PNCCALCSIZE_PARAMS16)lpmpex->Parm16.WndProc.lParam;
  1311. putrect16((VPRECT16)(&pnc16->rgrc[1]), &lpnc->rgrc[1]);
  1312. putrect16((VPRECT16)(&pnc16->rgrc[2]), &lpnc->rgrc[2]);
  1313. GETVDMPTR( pnc16, sizeof(NCCALCSIZE_PARAMS16), lpnc16 );
  1314. putwindowpos16( (VPWINDOWPOS16)lpnc16->lppos, lpnc->lppos );
  1315. FREEVDMPTR( lpnc16 );
  1316. }
  1317. }
  1318. break;
  1319. case WM_WINDOWPOSCHANGING:
  1320. case WM_WINDOWPOSCHANGED:
  1321. if (lpmpex->lParam) {
  1322. putwindowpos16( (VPWINDOWPOS16)lpmpex->Parm16.WndProc.lParam, (LPWINDOWPOS)lpmpex->lParam);
  1323. }
  1324. break;
  1325. case WM_CTLCOLOR:
  1326. // see thunking of wm_ctlcolor.
  1327. if ((ULONG)lpmpex->lReturn > COLOR_ENDCOLORS) {
  1328. lpmpex->lReturn = GETHBRUSH16(lpmpex->lReturn);
  1329. }
  1330. break;
  1331. case WM_MDICREATE: // 220h, <SLPre,SLPost,LS>,MDICREATESTRUCT
  1332. UnThunkWMMDICreate16(lpmpex->Parm16.WndProc.lParam, (LPMDICREATESTRUCT)lpmpex->lParam);
  1333. lpmpex->lReturn = GETHWND16(lpmpex->lReturn);
  1334. break;
  1335. case WM_MDIGETACTIVE:
  1336. //
  1337. // LOWORD(lReturn) == hwndMDIActive
  1338. // HIWORD(lReturn) == fMaximized
  1339. //
  1340. LOW(lpmpex->lReturn) = GETHWND16((HWND)(lpmpex->lReturn));
  1341. if (lpmpex->lParam != 0) {
  1342. HIW(lpmpex->lReturn) = (WORD)(*((LPBOOL)lpmpex->lParam) != 0);
  1343. }
  1344. break;
  1345. case WM_MDISETMENU:
  1346. lpmpex->lReturn = GETHMENU16(lpmpex->lReturn);
  1347. break;
  1348. case WM_PAINTCLIPBOARD:
  1349. case WM_SIZECLIPBOARD:
  1350. if (lpmpex->lParam) {
  1351. WOWGLOBALFREE((HANDLE)lpmpex->lParam);
  1352. }
  1353. break;
  1354. case WM_ASKCBFORMATNAME:
  1355. /* BUGBUGBUG -- neither thunk or unthunk should be necessary,
  1356. since the system does not process this message in DefWindowProc
  1357. FritzS */
  1358. if (lpmpex->lParam) {
  1359. putstr16((VPSZ)lpmpex->Parm16.WndProc.lParam, (LPSZ)lpmpex->lParam, lpmpex->Parm16.WndProc.wParam);
  1360. free_w((PBYTE)lpmpex->lParam);
  1361. }
  1362. break;
  1363. case WM_DDE_INITIATE:
  1364. WI32DDEDeleteInitiator((HAND16) lpmpex->Parm16.WndProc.wParam);
  1365. break;
  1366. case WM_NEXTMENU:
  1367. {
  1368. PMDINEXTMENU pT = (PMDINEXTMENU)lpmpex->lParam;
  1369. LOW(lpmpex->lReturn) = GETHMENU16(pT->hmenuNext);
  1370. HIW(lpmpex->lReturn) = GETHWND16(pT->hwndNext);
  1371. }
  1372. break;
  1373. case WM_COPYDATA:
  1374. if (fWhoCalled == WOWDDE_POSTMESSAGE) {
  1375. HWND16 hwnd16 = lpmpex->Parm16.WndProc.hwnd;
  1376. WORD wParam = lpmpex->Parm16.WndProc.wParam;
  1377. LONG lParamNew = lpmpex->lParam;
  1378. if (((PCOPYDATASTRUCT)lParamNew)->lpData) {
  1379. free_w (((PCOPYDATASTRUCT)lParamNew)->lpData);
  1380. CopyDataDeleteNode (hwnd16, wParam, (DWORD) ((PCOPYDATASTRUCT)lParamNew)->lpData);
  1381. }
  1382. if (lParamNew) {
  1383. free_w ((PVOID)lParamNew);
  1384. CopyDataDeleteNode (hwnd16, wParam, lParamNew);
  1385. }
  1386. else {
  1387. LOGDEBUG (LOG_ALWAYS, ("WOW::WM_COPYDATA16:Unthunking - lpCDS32 is NULL\n"));
  1388. }
  1389. }
  1390. break;
  1391. case WM_QUERYDRAGICON:
  1392. lpmpex->lReturn = (LONG)GETHICON16(lpmpex->lReturn);
  1393. break;
  1394. case WM_QUERYDROPOBJECT:
  1395. //
  1396. // Return value is either TRUE, FALSE,
  1397. // or a cursor!
  1398. //
  1399. if (lpmpex->lReturn && lpmpex->lReturn != (LONG)TRUE) {
  1400. lpmpex->lReturn = (LONG)GETHCURSOR16(lpmpex->lReturn);
  1401. }
  1402. break;
  1403. case WM_NOTIFY: // 0x4e
  1404. {
  1405. BOOL fFreePtr;
  1406. DeleteParamMap(lpmpex->lParam, PARAM_32, &fFreePtr);
  1407. if (fFreePtr) {
  1408. FREEVDMPTR((PSZ)lpmpex->lParam);
  1409. }
  1410. }
  1411. break;
  1412. case WM_CHANGEUISTATE: // 0x127
  1413. case WM_UPDATEUISTATE: // 0x128
  1414. case WM_QUERYUISTATE: // 0x129
  1415. {
  1416. // See thunking notes for this message in ThunkWMMsg16() above.
  1417. lpmpex->Parm16.WndProc.lParam = (LONG)lpmpex->uParam;
  1418. lpmpex->Parm16.WndProc.wParam = 0;
  1419. }
  1420. break;
  1421. #ifdef FE_IME
  1422. case WM_IME_REPORT:
  1423. switch( lpmpex->Parm16.WndProc.wParam ) {
  1424. case IR_STRING:
  1425. case IR_STRINGEX:
  1426. case IR_UNDETERMINE:
  1427. if ( lpmpex->lParam ) {
  1428. GlobalFree((HANDLE)lpmpex->lParam);
  1429. }
  1430. break;
  1431. }
  1432. break;
  1433. // MSKK support WM_IMEKEYDOWN message
  1434. // MSKK support WM_IMEKEYUP message
  1435. // MSKK16bit IME support
  1436. case WM_IMEKEYDOWN:
  1437. case WM_IMEKEYUP:
  1438. #ifdef DEBUG
  1439. LOGDEBUG( 5,("UnThunkWMMsg16:WM_IMEKEY debug\n"));
  1440. #endif
  1441. break;
  1442. #endif // FE_IME
  1443. } // end switch
  1444. }
  1445. BOOL ThunkWMGetMinMaxInfo16(VPVOID lParam, LPPOINT *plParamNew)
  1446. {
  1447. register LPPOINT lppt;
  1448. register PPOINT16 ppt16;
  1449. if (lParam) {
  1450. lppt = *plParamNew;
  1451. GETVDMPTR(lParam, sizeof(POINT16)*5, ppt16);
  1452. lppt[0].x = ppt16[0].x;
  1453. lppt[0].y = ppt16[0].y;
  1454. lppt[1].x = ppt16[1].x;
  1455. lppt[1].y = ppt16[1].y;
  1456. lppt[2].x = ppt16[2].x;
  1457. lppt[2].y = ppt16[2].y;
  1458. lppt[3].x = ppt16[3].x;
  1459. lppt[3].y = ppt16[3].y;
  1460. lppt[4].x = ppt16[4].x;
  1461. lppt[4].y = ppt16[4].y;
  1462. FREEVDMPTR(ppt16);
  1463. }
  1464. RETURN(TRUE);
  1465. }
  1466. VOID UnThunkWMGetMinMaxInfo16(VPVOID lParam, register LPPOINT lParamNew)
  1467. {
  1468. register PPOINT16 ppt16;
  1469. if (lParamNew) {
  1470. GETVDMPTR(lParam, sizeof(POINT16)*5, ppt16);
  1471. ppt16[0].x = (SHORT)lParamNew[0].x;
  1472. ppt16[0].y = (SHORT)lParamNew[0].y;
  1473. ppt16[1].x = (SHORT)lParamNew[1].x;
  1474. ppt16[1].y = (SHORT)lParamNew[1].y;
  1475. ppt16[2].x = (SHORT)lParamNew[2].x;
  1476. ppt16[2].y = (SHORT)lParamNew[2].y;
  1477. ppt16[3].x = (SHORT)lParamNew[3].x;
  1478. ppt16[3].y = (SHORT)lParamNew[3].y;
  1479. ppt16[4].x = (SHORT)lParamNew[4].x;
  1480. ppt16[4].y = (SHORT)lParamNew[4].y;
  1481. FLUSHVDMPTR(lParam, sizeof(POINT16)*5, ppt16);
  1482. FREEVDMPTR(ppt16);
  1483. }
  1484. RETURN(NOTHING);
  1485. }
  1486. BOOL ThunkWMMDICreate16(VPVOID lParam, LPMDICREATESTRUCT *plParamNew)
  1487. {
  1488. register LPMDICREATESTRUCT lpmdicreate;
  1489. register PMDICREATESTRUCT16 pmdicreate16;
  1490. if (lParam) {
  1491. lpmdicreate = *plParamNew;
  1492. GETVDMPTR(lParam, sizeof(MDICREATESTRUCT16), pmdicreate16);
  1493. GETPSZIDPTR( pmdicreate16->vpszClass, lpmdicreate->szClass );
  1494. GETPSZPTR( pmdicreate16->vpszTitle, lpmdicreate->szTitle );
  1495. lpmdicreate->hOwner = HMODINST32( pmdicreate16->hOwner );
  1496. lpmdicreate->x = INT32DEFAULT(pmdicreate16->x);
  1497. lpmdicreate->y = INT32DEFAULT(pmdicreate16->y);
  1498. lpmdicreate->cx = INT32DEFAULT(pmdicreate16->cx);
  1499. lpmdicreate->cy = INT32DEFAULT(pmdicreate16->cy);
  1500. lpmdicreate->style = pmdicreate16->style;
  1501. lpmdicreate->lParam = pmdicreate16->lParam;
  1502. FREEVDMPTR(pmdicreate16);
  1503. }
  1504. RETURN(TRUE);
  1505. }
  1506. VOID UnThunkWMMDICreate16(VPVOID lParam, register LPMDICREATESTRUCT lParamNew)
  1507. {
  1508. register PMDICREATESTRUCT16 pmdicreate16;
  1509. if (lParamNew) {
  1510. GETVDMPTR(lParam, sizeof(MDICREATESTRUCT16), pmdicreate16);
  1511. pmdicreate16->hOwner = GETHINST16(lParamNew->hOwner);
  1512. pmdicreate16->x = (SHORT)lParamNew->x;
  1513. pmdicreate16->y = (SHORT)lParamNew->y;
  1514. pmdicreate16->cx = (SHORT)lParamNew->cx;
  1515. pmdicreate16->cy = (SHORT)lParamNew->cy;
  1516. pmdicreate16->style = lParamNew->style;
  1517. pmdicreate16->lParam = lParamNew->lParam;
  1518. FLUSHVDMPTR(lParam, sizeof(MDICREATESTRUCT16), pmdicreate16);
  1519. FREEVDMPTR(pmdicreate16);
  1520. }
  1521. RETURN(NOTHING);
  1522. }
  1523. BOOL FASTCALL ThunkSTMsg16(LPMSGPARAMEX lpmpex)
  1524. {
  1525. WORD wMsg = lpmpex->Parm16.WndProc.wMsg;
  1526. LOGDEBUG(9,(" Thunking 16-bit STM window message %s(%04x)\n", (LPSZ)GetWMMsgName(wMsg), wMsg));
  1527. switch(wMsg) {
  1528. case WIN30_STM_SETICON:
  1529. lpmpex->uMsg = STM_SETICON;
  1530. lpmpex->uParam = (UINT) HICON32(lpmpex->Parm16.WndProc.wParam);
  1531. break;
  1532. case WIN30_STM_GETICON:
  1533. lpmpex->uMsg = STM_GETICON;
  1534. break;
  1535. }
  1536. return (TRUE);
  1537. }
  1538. VOID FASTCALL UnThunkSTMsg16(LPMSGPARAMEX lpmpex)
  1539. {
  1540. WORD wMsg = lpmpex->Parm16.WndProc.wMsg;
  1541. LOGDEBUG(9,(" UnThunking 16-bit STM window message %s(%04x)\n", (LPSZ)GetWMMsgName(wMsg), wMsg));
  1542. switch(wMsg) {
  1543. case WIN30_STM_GETICON:
  1544. case WIN30_STM_SETICON:
  1545. lpmpex->lReturn = GETHICON16(lpmpex->lReturn);
  1546. break;
  1547. }
  1548. }
  1549. BOOL FASTCALL ThunkMNMsg16(LPMSGPARAMEX lpmpex)
  1550. {
  1551. WORD wMsg = lpmpex->Parm16.WndProc.wMsg;
  1552. LOGDEBUG(9,(" Thunking 16-bit MN_ window message %s(%04x)\n", (LPSZ)GetWMMsgName(wMsg), wMsg));
  1553. switch(wMsg) {
  1554. case WIN30_MN_GETHMENU:
  1555. lpmpex->uMsg = MN_GETHMENU;
  1556. break;
  1557. case WIN30_MN_FINDMENUWINDOWFROMPOINT:
  1558. lpmpex->uMsg = MN_FINDMENUWINDOWFROMPOINT;
  1559. lpmpex->uParam = (UINT)lpmpex->MsgBuffer; // enough room for UINT
  1560. *(PUINT)lpmpex->uParam = 0;
  1561. break;
  1562. }
  1563. return (TRUE);
  1564. }
  1565. VOID FASTCALL UnThunkMNMsg16(LPMSGPARAMEX lpmpex)
  1566. {
  1567. WORD wMsg = lpmpex->Parm16.WndProc.wMsg;
  1568. LOGDEBUG(9,(" UnThunking 16-bit MN_ window message %s(%04x)\n", (LPSZ)GetWMMsgName(wMsg), wMsg));
  1569. switch(wMsg) {
  1570. case WIN30_MN_FINDMENUWINDOWFROMPOINT:
  1571. if (lpmpex->uParam) {
  1572. lpmpex->lReturn = MAKELONG((HWND16)lpmpex->lReturn,
  1573. LOWORD(*(PUINT)lpmpex->uParam));
  1574. }
  1575. break;
  1576. }
  1577. }