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.

407 lines
12 KiB

  1. /*++
  2. *
  3. * WOW v1.0
  4. *
  5. * Copyright (c) 1991, Microsoft Corporation
  6. *
  7. * EDECRARE.C
  8. * Win16 edit control code
  9. *
  10. * History:
  11. *
  12. * Created 28-May-1991 by Jeff Parsons (jeffpar)
  13. * Copied from WIN31 and edited (as little as possible) for WOW16.
  14. --*/
  15. /****************************************************************************/
  16. /* edECRare.c - EC Edit controls Routines Called rarely are to be */
  17. /* put in a seperate segment _EDECRare. This file contains */
  18. /* these routines. */
  19. /* */
  20. /* Created: 02-08-89 sankar */
  21. /****************************************************************************/
  22. #define NO_LOCALOBJ_TAGS
  23. #include "user.h"
  24. #include "edit.h"
  25. /****************************************************************************/
  26. /* Support Routines common to Single-line and Multi-Line edit controls */
  27. /* called Rarely. */
  28. /****************************************************************************/
  29. ICH FAR PASCAL ECGetTextHandler(ped, maxCchToCopy, lpBuffer)
  30. register PED ped;
  31. register ICH maxCchToCopy;
  32. LPSTR lpBuffer;
  33. /* effects: Copies at most maxCchToCopy bytes to the buffer lpBuffer. Returns
  34. * how many bytes were actually copied. Null terminates the string thus at
  35. * most maxCchToCopy-1 characters will be returned.
  36. */
  37. {
  38. PSTR pText;
  39. if (maxCchToCopy)
  40. {
  41. #ifdef DEBUG
  42. /* In debug mode, trash their buffer so that we can catch
  43. * stack/allocation problems early.
  44. */
  45. DebugFillStruct(lpBuffer, maxCchToCopy);
  46. #endif
  47. /* Zero terminator takes the extra byte */
  48. maxCchToCopy = umin(maxCchToCopy-1, ped->cch);
  49. /* Zero terminate the string */
  50. *(LPSTR)(lpBuffer+maxCchToCopy) = 0;
  51. pText = LocalLock(ped->hText);
  52. LCopyStruct((LPSTR)pText, lpBuffer, maxCchToCopy);
  53. LocalUnlock(ped->hText);
  54. }
  55. return(maxCchToCopy);
  56. }
  57. BOOL FAR PASCAL ECNcCreate(hwnd, lpCreateStruct)
  58. HWND hwnd;
  59. LPCREATESTRUCT lpCreateStruct;
  60. {
  61. LONG windowStyle;
  62. register PED ped;
  63. /* Initially no ped for the window. In case of no memory error, we can
  64. * return with a -1 for the window's PED
  65. */
  66. SetWindowWord(hwnd, 0, (WORD)-1); /* No ped for this window */
  67. /* If pLocalHeap = 0, then we need to LocalInit our "new" data segment for
  68. * dialog boxes.
  69. */
  70. if (!pLocalHeap)
  71. {
  72. LocalInit((WORD) NULL,
  73. (WORD) 0,
  74. (WORD) GlobalSize(lpCreateStruct->hInstance)-64);
  75. /* Since LocalInit locked the segment (and it was locked previously, we
  76. * will unlock it to prevent lock count from being greater than 1).
  77. */
  78. UnlockSegment((WORD)-1);
  79. }
  80. windowStyle = GetWindowLong(hwnd, GWL_STYLE);
  81. /* Try to allocate space for the ped. HACK: Note that the handle to a fixed
  82. * local object is the same as a near pointer to the object.
  83. */
  84. SwapHandle(&lpCreateStruct->lpszName);
  85. SwapHandle(&lpCreateStruct);
  86. if (!(ped = (PED) LocalAlloc(LPTR, sizeof(ED))))
  87. /* Error, no memory */
  88. return(NULL);
  89. if (windowStyle & ES_MULTILINE)
  90. /* Allocate memory for a char width buffer if we can get it. If we can't
  91. * we'll just be a little slower...
  92. */
  93. ped->charWidthBuffer = LocalAlloc(LHND, sizeof(int)*256);
  94. if (windowStyle & ES_READONLY)
  95. ped->fReadOnly = 1;
  96. /* Allocate storage for the text for the edit controls. Storage for single
  97. * line edit controls will always get allocated in the local data segment.
  98. * Multiline will allocate in the local ds but the app may free this and
  99. * allocate storage elsewhere...
  100. */
  101. ped->hText = LocalAlloc(LHND, CCHALLOCEXTRA);
  102. if (!ped->hText) /* If no_memory error */
  103. return(FALSE);
  104. ped->cchAlloc = CCHALLOCEXTRA;
  105. SwapHandle(&lpCreateStruct);
  106. SwapHandle(&lpCreateStruct->lpszName);
  107. /* Set a field in the window to point to the ped so that we can recover the
  108. * edit structure in later messages when we are only given the window
  109. * handle.
  110. */
  111. SetWindowWord(hwnd, 0, (WORD)ped);
  112. ped->hwnd = hwnd;
  113. ped->hwndParent = lpCreateStruct->hwndParent;
  114. if (windowStyle & WS_BORDER)
  115. {
  116. ped->fBorder = 1;
  117. /*
  118. * Strip the border bit from the window style since we draw the border
  119. * ourselves.
  120. */
  121. windowStyle = windowStyle & ~WS_BORDER;
  122. SetWindowLong(hwnd, GWL_STYLE, windowStyle);
  123. }
  124. return((BOOL)DefWindowProc(hwnd, WM_NCCREATE, 0, (LONG)lpCreateStruct));
  125. }
  126. BOOL FAR PASCAL ECCreate(hwnd, ped, lpCreateStruct)
  127. HWND hwnd;
  128. register PED ped;
  129. LPCREATESTRUCT lpCreateStruct;
  130. /* effects: Creates the edit control for the window hwnd by allocating memory
  131. * as required from the application's heap. Notifies parent if no memory
  132. * error (after cleaning up if needed). Returns PED if no error else returns
  133. * NULL. Just does the stuff which is independent of the style of the edit
  134. * control. LocalAllocs done here may cause memory to move...
  135. */
  136. {
  137. LONG windowStyle;
  138. /*
  139. * Get values from the window instance data structure and put them in the
  140. * ped so that we can access them easier.
  141. */
  142. windowStyle = GetWindowLong(hwnd, GWL_STYLE);
  143. if (windowStyle & ES_AUTOHSCROLL)
  144. ped->fAutoHScroll = 1;
  145. if (windowStyle & ES_NOHIDESEL)
  146. ped->fNoHideSel = 1;
  147. ped->cchTextMax = MAXTEXT; /* Max # chars we will initially allow */
  148. /* Set up undo initial conditions... (ie. nothing to undo) */
  149. ped->ichDeleted = -1;
  150. ped->ichInsStart = -1;
  151. ped->ichInsEnd = -1;
  152. /* Initialize the hilite attributes */
  153. #ifdef WOW
  154. ped->hbrHiliteBk = CreateSolidBrush(GetSysColor(COLOR_HIGHLIGHT));
  155. #else
  156. ped->hbrHiliteBk = GetSysClrObject(COLOR_HIGHLIGHT);
  157. #endif
  158. ped->rgbHiliteBk = GetSysColor(COLOR_HIGHLIGHT);
  159. ped->rgbHiliteText = GetSysColor(COLOR_HIGHLIGHTTEXT);
  160. return(TRUE);
  161. }
  162. void FAR PASCAL ECNcDestroyHandler(hwnd,ped,wParam,lParam)
  163. HWND hwnd;
  164. register PED ped;
  165. WORD wParam;
  166. LONG lParam;
  167. /*
  168. * effects: Destroys the edit control ped by freeing up all memory used by it.
  169. */
  170. {
  171. if (ped)
  172. /* ped could be NULL if WM_NCCREATE failed to create it... */
  173. {
  174. if (ped->fFocus)
  175. /* Destroy the caret if we have the focus and we are being
  176. killed */
  177. DestroyCaret();
  178. LocalFree(ped->hText);
  179. #ifdef WOW
  180. DeleteObject(ped->hbrHiliteBk);
  181. #endif
  182. /* Free up undo buffer and line start array (if present) */
  183. GlobalFree(ped->hDeletedText);
  184. LocalFree((HANDLE)ped->chLines);
  185. LocalFree((HANDLE)ped->charWidthBuffer);
  186. if (ped->pTabStops)
  187. /* Free tab stop buffer if it exists.
  188. */
  189. LocalFree((HANDLE)ped->pTabStops);
  190. /* Since a pointer and a handle to a fixed local object are the same */
  191. LocalFree((HANDLE)ped);
  192. }
  193. /* In case rogue messages float through after we have freed the ped, set the
  194. * handle in the window structure to FFFF and test for this value at the top
  195. * of EdWndProc.
  196. */
  197. SetWindowWord(hwnd,0,(WORD)-1);
  198. /* Call DefWindowProc to free all little chunks of memory such as szName and
  199. * rgwScroll.
  200. */
  201. DefWindowProc(hwnd,WM_NCDESTROY,wParam,lParam);
  202. }
  203. void FAR PASCAL ECSetPasswordChar(ped, pwchar)
  204. register PED ped;
  205. WORD pwchar;
  206. /* Sets the password char to display. */
  207. {
  208. HDC hdc;
  209. LONG style;
  210. ped->charPasswordChar = pwchar;
  211. if (pwchar)
  212. {
  213. hdc = ECGetEditDC(ped, TRUE);
  214. ped->cPasswordCharWidth = max(LOWORD(GetTextExtent(hdc,
  215. (LPSTR)&pwchar,
  216. 1)),
  217. 1);
  218. ECReleaseEditDC(ped, hdc, TRUE);
  219. }
  220. style = GetWindowLong(ped->hwnd, GWL_STYLE);
  221. if (pwchar)
  222. style |= ES_PASSWORD;
  223. else
  224. style = style & (~ES_PASSWORD);
  225. SetWindowLong(ped->hwnd, GWL_STYLE, style);
  226. }
  227. void FAR PASCAL ECSetFont(ped, hfont, fRedraw)
  228. register PED ped;
  229. HANDLE hfont;
  230. BOOL fRedraw;
  231. /* effects: Sets the edit control to use the font hfont. warning: Memory
  232. * compaction may occur if hfont wasn't previously loaded. If hfont == NULL,
  233. * then assume the system font is being used.
  234. */
  235. {
  236. register short i;
  237. TEXTMETRIC TextMetrics;
  238. HDC hdc;
  239. HANDLE hOldFont=NULL;
  240. RECT rc;
  241. PINT charWidth;
  242. #ifdef FE_SB
  243. unsigned short LangID;
  244. #endif
  245. hdc = GetDC(ped->hwnd);
  246. ped->hFont = hfont;
  247. if (hfont)
  248. {
  249. /* Since the default font is the system font, no need to select it in if
  250. * that's what the user wants.
  251. */
  252. if (!(hOldFont = SelectObject(hdc, hfont)))
  253. {
  254. hfont = ped->hFont = NULL;
  255. }
  256. }
  257. /* Get the metrics and ave char width for the currently selected font */
  258. ped->aveCharWidth = GetCharDimensions(hdc, (TEXTMETRIC FAR *)&TextMetrics);
  259. ped->lineHeight = TextMetrics.tmHeight;
  260. ped->charOverhang = TextMetrics.tmOverhang;
  261. /* Check if Proportional Width Font */
  262. ped->fNonPropFont = !(TextMetrics.tmPitchAndFamily & 1);
  263. /* Get char widths */
  264. if (ped->charWidthBuffer)
  265. {
  266. charWidth = (PINT)LocalLock(ped->charWidthBuffer);
  267. if (!GetCharWidth(hdc, 0, 0xff, (LPINT)charWidth))
  268. {
  269. LocalUnlock(ped->charWidthBuffer);
  270. LocalFree((HANDLE)ped->charWidthBuffer);
  271. ped->charWidthBuffer=NULL;
  272. }
  273. else
  274. {
  275. /* We need to subtract out the overhang associated with each
  276. * character since GetCharWidth includes it...
  277. */
  278. for (i=0;i<=0xff;i++)
  279. charWidth[i] -= ped->charOverhang;
  280. LocalUnlock(ped->charWidthBuffer);
  281. }
  282. }
  283. #ifdef FE_SB
  284. /* In DBCS Windows, Edit Control must handle Double Byte Character
  285. * in case of charset of the font is 128(Japan) or 129(Korea).
  286. */
  287. LangID = GetSystemDefaultLangID();
  288. if (LangID == 0x411 || LangID == 0x412 || LangID == 0x404 || LangID == 0x804 || LangID == 0xC04)
  289. {
  290. ped->charSet = TextMetrics.tmCharSet;
  291. ECGetDBCSVector( ped );
  292. ped->fDBCS = 1;
  293. }
  294. #endif
  295. if (!hfont)
  296. {
  297. /* We are getting the statitics for the system font so update the system
  298. * font fields in the ed structure since we use these when determining
  299. * the border size of the edit control.
  300. */
  301. ped->cxSysCharWidth = ped->aveCharWidth;
  302. ped->cySysCharHeight= ped->lineHeight;
  303. }
  304. else
  305. SelectObject(hdc, hOldFont);
  306. if (ped->fFocus)
  307. {
  308. /* Fix the caret size to the new font if we have the focus. */
  309. CreateCaret(ped->hwnd, (HBITMAP)NULL, 2, ped->lineHeight);
  310. ShowCaret(ped->hwnd);
  311. }
  312. ReleaseDC(ped->hwnd,hdc);
  313. if (ped->charPasswordChar)
  314. /* Update the password char metrics to match the new font. */
  315. ECSetPasswordChar(ped, ped->charPasswordChar);
  316. if (ped->fSingle)
  317. SLSizeHandler(ped);
  318. else
  319. {
  320. MLSizeHandler(ped);
  321. /* If word-wrap is not there, then we must calculate the maxPixelWidth
  322. * It is done by calling MLBuildChLines;
  323. * Also, reposition the scroll bar thumbs.
  324. * Fix for Bug #5141 --SANKAR-- 03/14/91 --
  325. */
  326. if(!ped->fWrap)
  327. MLBuildchLines(ped, 0, 0, FALSE);
  328. SetScrollPos(ped->hwnd, SB_VERT,
  329. (int)MLThumbPosFromPed(ped,TRUE), fRedraw);
  330. SetScrollPos(ped->hwnd, SB_HORZ,
  331. (int)MLThumbPosFromPed(ped,FALSE), fRedraw);
  332. }
  333. if (fRedraw)
  334. {
  335. GetWindowRect(ped->hwnd, (LPRECT)&rc);
  336. ScreenToClient(ped->hwnd, (LPPOINT)&rc.left);
  337. ScreenToClient(ped->hwnd, (LPPOINT)&rc.right);
  338. InvalidateRect(ped->hwnd, (LPRECT)&rc, TRUE);
  339. UpdateWindow(ped->hwnd);
  340. }
  341. }