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.

276 lines
9.2 KiB

  1. /*++
  2. *
  3. * WOW v1.0
  4. *
  5. * Copyright (c) 1991, Microsoft Corporation
  6. *
  7. * WMSGEM.C
  8. * WOW32 16-bit message thunks
  9. *
  10. * History:
  11. * Created 11-Mar-1991 by Jeff Parsons (jeffpar)
  12. --*/
  13. #include "precomp.h"
  14. #pragma hdrstop
  15. MODNAME(wmsgem.c);
  16. VPVOID WordBreakProc16 = 0;
  17. extern WBP W32WordBreakProc;
  18. #ifdef DEBUG
  19. MSGINFO amiEM[] = {
  20. {OLDEM_GETSEL, "EM_GETSEL"}, // 0x0400
  21. {OLDEM_SETSEL, "EM_SETSEL"}, // 0x0401
  22. {OLDEM_GETRECT, "EM_GETRECT"}, // 0x0402
  23. {OLDEM_SETRECT, "EM_SETRECT"}, // 0x0403
  24. {OLDEM_SETRECTNP, "EM_SETRECTNP"}, // 0x0404
  25. {OLDEM_SCROLL, "EM_SCROLL"}, // 0x0405
  26. {OLDEM_LINESCROLL, "EM_LINESCROLL"}, // 0x0406
  27. {OLDEM_GETMODIFY, "EM_GETMODIFY"}, // 0x0408
  28. {OLDEM_SETMODIFY, "EM_SETMODIFY"}, // 0x0409
  29. {OLDEM_GETLINECOUNT, "EM_GETLINECOUNT"}, // 0x040A
  30. {OLDEM_LINEINDEX, "EM_LINEINDEX"}, // 0x040B
  31. {OLDEM_SETHANDLE, "EM_SETHANDLE"}, // 0x040C
  32. {OLDEM_GETHANDLE, "EM_GETHANDLE"}, // 0x040D
  33. {OLDEM_GETTHUMB, "EM_GETTHUMB"}, // 0x040E
  34. {OLDEM_LINELENGTH, "EM_LINELENGTH"}, // 0x0411
  35. {OLDEM_REPLACESEL, "EM_REPLACESEL"}, // 0x0412
  36. {OLDEM_SETFONT, "EM_SETFONT"}, // 0x0413
  37. {OLDEM_GETLINE, "EM_GETLINE"}, // 0x0414
  38. {OLDEM_LIMITTEXT, "EM_LIMITTEXT"}, // 0x0415
  39. {OLDEM_CANUNDO, "EM_CANUNDO"}, // 0x0416
  40. {OLDEM_UNDO, "EM_UNDO"}, // 0x0417
  41. {OLDEM_FMTLINES, "EM_FMTLINES"}, // 0x0418
  42. {OLDEM_LINEFROMCHAR, "EM_LINEFROMCHAR"}, // 0x0419
  43. {OLDEM_SETWORDBREAK, "EM_SETWORDBREAK"}, // 0x041A
  44. {OLDEM_SETTABSTOPS, "EM_SETTABSTOPS"}, // 0x041B
  45. {OLDEM_SETPASSWORDCHAR, "EM_SETPASSWORDCHAR"}, // 0x041C
  46. {OLDEM_EMPTYUNDOBUFFER, "EM_EMPTYUNDOBUFFER"}, // 0x041D
  47. {OLDEM_GETFIRSTVISIBLELINE, "EM_GETFIRSTVISIBLELINE"}, // 0x041E
  48. {OLDEM_SETREADONLY, "EM_SETREADONLY"}, // 0x041F
  49. {OLDEM_SETWORDBREAKPROC, "EM_SETWORDBREAKPROC"}, // 0x0420
  50. {OLDEM_GETWORDBREAKPROC, "EM_GETWORDBREAKPROC"}, // 0x0421
  51. {OLDEM_GETPASSWORDCHAR, "EM_GETPASSWORDCHAR"} // 0x0422
  52. };
  53. PSZ GetEMMsgName(WORD wMsg)
  54. {
  55. INT i;
  56. register PMSGINFO pmi;
  57. for (pmi=amiEM,i=NUMEL(amiEM); i>0; i--,pmi++) {
  58. if ((WORD)pmi->uMsg == wMsg)
  59. return pmi->pszMsgName;
  60. }
  61. return GetWMMsgName(wMsg);
  62. }
  63. #endif
  64. BOOL FASTCALL ThunkEMMsg16(LPMSGPARAMEX lpmpex)
  65. {
  66. WORD wMsg = lpmpex->Parm16.WndProc.wMsg;
  67. LOGDEBUG(7,(" Thunking 16-bit edit control message %s(%04x)\n", (LPSZ)GetEMMsgName(wMsg), wMsg));
  68. wMsg -= WM_USER;
  69. //
  70. // For app defined (control) messages that are out of range
  71. // return TRUE.
  72. //
  73. // ChandanC Sept-15-1992
  74. //
  75. if (wMsg < (EM_GETPASSWORDCHAR - EM_GETSEL + 1)) {
  76. switch(lpmpex->uMsg = wMsg + EM_GETSEL) {
  77. case EM_GETSEL:
  78. // 16 bit apps cannot pass non-zero values in wParam or lParam for this
  79. // message to NT since they will be considered long pointers.
  80. // This is a hack for ReportWin - MarkRi
  81. // NOTE: There is a case possible where the app is trying to pass
  82. // thru a GETSEL msg that NT has sent it in which case things get more
  83. // complicated but we haven't found an app YET that has this problem.
  84. lpmpex->uParam = 0 ;
  85. lpmpex->lParam = 0 ;
  86. break ;
  87. case EM_SETSEL:
  88. lpmpex->uParam = LOWORD(lpmpex->Parm16.WndProc.lParam);
  89. lpmpex->lParam = HIWORD(lpmpex->Parm16.WndProc.lParam);
  90. break;
  91. case EM_GETLINE:
  92. GETMISCPTR(lpmpex->Parm16.WndProc.lParam, (LPSZ)lpmpex->lParam);
  93. break;
  94. case EM_GETRECT:
  95. lpmpex->lParam = (LONG)lpmpex->MsgBuffer;
  96. break;
  97. case EM_LINESCROLL:
  98. lpmpex->uParam = INT32(HIWORD(lpmpex->Parm16.WndProc.lParam));
  99. lpmpex->lParam = INT32(LOWORD(lpmpex->Parm16.WndProc.lParam));
  100. break;
  101. case EM_SETHANDLE:
  102. lpmpex->uParam = (UINT)MAKELONG(lpmpex->Parm16.WndProc.wParam,
  103. LOWORD(lpmpex->pww->hModule) | 1);
  104. break;
  105. case EM_REPLACESEL:
  106. { PSZ psz;
  107. int i;
  108. GETPSZPTR(lpmpex->Parm16.WndProc.lParam, psz);
  109. if (psz) {
  110. i = strlen(psz)+1;
  111. lpmpex->lParam = (LONG) LocalAlloc (LMEM_FIXED, i);
  112. if (lpmpex->lParam ) {
  113. RtlCopyMemory ((PSZ)lpmpex->lParam, psz, i);
  114. }
  115. else {
  116. LOGDEBUG (0, ("WOW::WMSGEM.C: EM_REPLACESEL: Out of Memory Failure/n"));
  117. }
  118. }
  119. FREEPSZPTR(psz);
  120. }
  121. break;
  122. case EM_SETRECT:
  123. case EM_SETRECTNP:
  124. if (lpmpex->Parm16.WndProc.lParam) {
  125. lpmpex->lParam = (LONG)lpmpex->MsgBuffer;
  126. getrect16((VPRECT16)lpmpex->Parm16.WndProc.lParam, (LPRECT)lpmpex->lParam);
  127. }
  128. break;
  129. case EM_SETTABSTOPS:
  130. {
  131. INT cItems = INT32(lpmpex->Parm16.WndProc.wParam);
  132. if (cItems > 0) {
  133. (PVOID)lpmpex->lParam = STACKORHEAPALLOC(cItems * sizeof(INT),
  134. sizeof(lpmpex->MsgBuffer), lpmpex->MsgBuffer);
  135. getintarray16((VPINT16)lpmpex->Parm16.WndProc.lParam, cItems, (LPINT)lpmpex->lParam);
  136. }
  137. }
  138. break;
  139. case EM_SETWORDBREAKPROC:
  140. if (lpmpex->Parm16.WndProc.lParam) {
  141. LONG l;
  142. l = lpmpex->Parm16.WndProc.lParam;
  143. // mark the proc as WOW proc and save the high bits in the RPL
  144. MarkWOWProc (l,lpmpex->lParam);
  145. LOGDEBUG (0, ("WOW::WMSGEM.C: EM_SETWORDBREAKPROC: lpmpex->Parm16.WndProc.lParam = %08lx, new lpmpex->Parm16.WndProc.lParam = %08lx\n", lpmpex->Parm16.WndProc.lParam, lpmpex->lParam));
  146. }
  147. break;
  148. case EM_GETSEL + 0x07:
  149. case EM_GETSEL + 0x0F:
  150. case EM_GETSEL + 0x10:
  151. lpmpex->uMsg = 0;
  152. break;
  153. } // switch
  154. }
  155. return TRUE;
  156. }
  157. VOID FASTCALL UnThunkEMMsg16(LPMSGPARAMEX lpmpex)
  158. {
  159. LPARAM lParam = lpmpex->Parm16.WndProc.lParam;
  160. LPARAM lParamNew = lpmpex->lParam;
  161. switch(lpmpex->uMsg) {
  162. case EM_SETSEL:
  163. // EM_SETSEL no longer positions the caret on NT as Win3.1 did. The new
  164. // procedure is to post or send an EM_SETSEL message and then if you
  165. // want the caret to be scrolled into view you send an EM_SCROLLCARET
  166. // message. This code will do this to emulate the Win 3.1 EM_SETSEL
  167. // correctly on NT.
  168. if (!lpmpex->Parm16.WndProc.wParam) {
  169. DWORD dwT;
  170. if (POSTMSG(dwT))
  171. PostMessage(lpmpex->hwnd, EM_SCROLLCARET, 0, 0 );
  172. else
  173. SendMessage(lpmpex->hwnd, EM_SCROLLCARET, 0, 0 );
  174. }
  175. break;
  176. case EM_GETHANDLE:
  177. lpmpex->lReturn = GETHMEM16(lpmpex->lReturn);
  178. break;
  179. case EM_GETRECT:
  180. if (lParamNew) {
  181. putrect16((VPRECT16)lParam, (LPRECT)lParamNew);
  182. }
  183. break;
  184. case EM_REPLACESEL:
  185. if (lParamNew) {
  186. LocalFree ((HLOCAL)lParamNew);
  187. }
  188. break;
  189. case EM_SETTABSTOPS:
  190. if (lpmpex->Parm16.WndProc.wParam > 0) {
  191. STACKORHEAPFREE((LPINT)lParamNew, lpmpex->MsgBuffer);
  192. }
  193. break;
  194. case EM_GETWORDBREAKPROC:
  195. if (lpmpex->lReturn) {
  196. if (IsWOWProc (lpmpex->lReturn)) {
  197. LOGDEBUG (0, ("WOW::WMSGEM.C: EM_GETWORDBREAKPROC: lReturn = %08lx ", lpmpex->lReturn));
  198. //Unmark the proc and restore the high bits from rpl field
  199. UnMarkWOWProc (lpmpex->lReturn,lpmpex->lReturn);
  200. LOGDEBUG (0, (" and new lReturn = %08lx\n", lpmpex->lReturn));
  201. }
  202. else {
  203. PARM16 Parm16;
  204. LONG lReturn;
  205. if (!WordBreakProc16) {
  206. W32WordBreakProc = (WBP)(lpmpex->lReturn);
  207. Parm16.SubClassProc.iOrdinal = FUN_WOWWORDBREAKPROC;
  208. if (!CallBack16(RET_SUBCLASSPROC, &Parm16, (VPPROC)NULL,
  209. (PVPVOID)&lReturn)) {
  210. WOW32ASSERT(FALSE);
  211. WordBreakProc16 = lpmpex->lReturn;
  212. }
  213. }
  214. else {
  215. lpmpex->lReturn = WordBreakProc16;
  216. }
  217. }
  218. }
  219. break;
  220. }
  221. }