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.

452 lines
18 KiB

  1. /*----------------------------------------------------------------------------*\
  2. | edit.c - routines for dealing with multi-line edit controls |
  3. | |
  4. | |
  5. | History: |
  6. | 01/01/88 toddla Created |
  7. | 11/04/90 w-dougb Commented & formatted the code to look pretty |
  8. | |
  9. \*----------------------------------------------------------------------------*/
  10. /*----------------------------------------------------------------------------*\
  11. | |
  12. | i n c l u d e f i l e s |
  13. | |
  14. \*----------------------------------------------------------------------------*/
  15. #include <windows.h>
  16. #include "gmem.h"
  17. #include "edit.h"
  18. #include "mcitest.h"
  19. /*----------------------------------------------------------------------------*\
  20. | |
  21. | c o n s t a n t a n d m a c r o d e f i n i t i o n s |
  22. | |
  23. \*----------------------------------------------------------------------------*/
  24. #define ISSPACE(c) ((c) == ' ' || (c) == '\t')
  25. #define ISEOL(c) ((c) == '\n'|| (c) == '\r')
  26. #define ISWHITE(c) (ISSPACE(c) || ISEOL(c))
  27. /*----------------------------------------------------------------------------*\
  28. | EditOpenFile(hwndEdit, lszFile) |
  29. | |
  30. | Description: |
  31. | This function opens the file <lszFile>, copies the contents of the |
  32. | file into the edit control with the handle <hwndEdit>, and then closes |
  33. | the file. |
  34. | |
  35. | Arguments: |
  36. | hwndEdit window handle of the edit box control |
  37. | lszFile filename of the file to be opened |
  38. | |
  39. | Returns: |
  40. | TRUE if the operation was successful, else FALSE |
  41. | |
  42. \*----------------------------------------------------------------------------*/
  43. BOOL EditOpenFile(
  44. HWND hwndEdit,
  45. LPTSTR lszFile)
  46. {
  47. #ifdef UNICODE
  48. HANDLE fh; /* DOS file handle returned by OpenFile */
  49. #else
  50. HFILE fh; /* DOS file handle returned by OpenFile */
  51. OFSTRUCT of; /* structure used by the OpenFile routine */
  52. #endif
  53. LPTSTR lszText; /* pointer to the opened file's text */
  54. UINT nFileLen; /* length, in bytes, of the opened file */
  55. HCURSOR hcur; /* handle to the pre-hourglass cursor */
  56. /* If a valid window handle or a filename was not specified, then exit.
  57. */
  58. if (!hwndEdit || !lszFile) {
  59. dprintf1((TEXT("EditOpenFile: Invalid window or filename")));
  60. return FALSE;
  61. }
  62. /* Open the file for reading */
  63. #ifdef UNICODE
  64. fh = CreateFile(lszFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
  65. if (fh == INVALID_HANDLE_VALUE) {
  66. dprintf1((TEXT("Failed to open: %s"), lszFile));
  67. return FALSE;
  68. }
  69. #else
  70. fh = OpenFile(lszFile, &of, OF_READ);
  71. if (fh == HFILE_ERROR) {
  72. dprintf1((TEXT("Failed to open: %s"), lszFile));
  73. return FALSE;
  74. }
  75. #endif
  76. nFileLen = (UINT)GetFileSize((HANDLE)fh, NULL);
  77. if (HFILE_ERROR == nFileLen) {
  78. dprintf1((TEXT("Failed to find file size: %s"), lszFile));
  79. return FALSE;
  80. }
  81. /*
  82. * Create a pointer to a region of memory large enough to hold the entire
  83. * contents of the file. If this was successful, then read the file into
  84. * this region, and use this region as the text for the edit control.
  85. * Finally, free up the region and its pointer, and close the file.
  86. *
  87. */
  88. lszText = (LPTSTR)GAllocPtr(nFileLen+1); // Note: no *sizeof(TCHAR)
  89. if (NULL != lszText) {
  90. BOOL fReturn;
  91. /* This could take a while - show the hourglass cursor */
  92. hcur = SetCursor(LoadCursor(NULL, IDC_WAIT));
  93. /* Read the file and copy the contents into the edit control */
  94. dprintf3((TEXT("reading file...")));
  95. #ifdef UNICODE
  96. {
  97. DWORD bytesRead;
  98. if (ReadFile(fh, lszText, nFileLen, &bytesRead, NULL)) {
  99. lszText[bytesRead]=0;
  100. dprintf2((TEXT("File loaded ok")));
  101. SetWindowTextA(hwndEdit, (LPSTR)lszText); // Until we have UNICODE files
  102. fReturn = TRUE;
  103. } else {
  104. dprintf2((TEXT("Error loading file")));
  105. fReturn = FALSE;
  106. }
  107. }
  108. /* Free up the memory, close the file, and restore the cursor */
  109. GFreePtr(lszText);
  110. CloseHandle(fh);
  111. #else
  112. if ((_lread((HFILE)fh, lszText, nFileLen)) == nFileLen) {
  113. lszText[nFileLen/sizeof(TCHAR)]=0;
  114. dprintf2((TEXT("File loaded ok")));
  115. SetWindowText(hwndEdit, lszText);
  116. fReturn = TRUE;
  117. } else {
  118. dprintf2((TEXT("Error loading file")));
  119. fReturn = FALSE;
  120. }
  121. /* Free up the memory, close the file, and restore the cursor */
  122. GFreePtr(lszText);
  123. _lclose((HFILE)fh);
  124. #endif
  125. SetCursor(hcur);
  126. return fReturn;
  127. }
  128. /*
  129. * We couldn't allocate the required memory, so close the file and
  130. * return FALSE.
  131. *
  132. */
  133. dprintf1((TEXT("Failed memory allocation for file")));
  134. #ifdef UNICODE
  135. CloseHandle(fh);
  136. #else
  137. _lclose((HFILE)fh);
  138. #endif
  139. return FALSE;
  140. }
  141. /*----------------------------------------------------------------------------*\
  142. | EditSaveFile(hwndEdit, lszFile) |
  143. | |
  144. | Description: |
  145. | This function saves the contents of the edit control with the handle |
  146. | <hwndEdit> into the file <lszFile>, creating the file if required. |
  147. | |
  148. | Arguments: |
  149. | hwndEdit window handle of the edit box control |
  150. | lszFile filename of the file to be saved |
  151. | |
  152. | Returns: |
  153. | TRUE if the operation was successful, else FALSE |
  154. | |
  155. \*----------------------------------------------------------------------------*/
  156. BOOL EditSaveFile(
  157. HWND hwndEdit,
  158. LPTSTR lszFile)
  159. {
  160. #ifdef UNICODE
  161. HANDLE fh; /* DOS file handle returned by OpenFile */
  162. DWORD dwBytesWritten;
  163. #else
  164. OFSTRUCT of; /* structure used by the OpenFile routine */
  165. HFILE fh; /* DOS file handle returned by OpenFile */
  166. #endif
  167. LPTSTR lszText; /* pointer to the saved file's text */
  168. int nFileLen; /* length, in bytes, of the saved file */
  169. HCURSOR hcur; /* handle to the pre-hourglass cursor */
  170. /* If a valid window handle or a filename was not specified, then exit */
  171. dprintf2((TEXT("EditSaveFile: Saving %s"), lszFile));
  172. if (!hwndEdit || !lszFile) {
  173. dprintf1((TEXT("EditSaveFile: Invalid window or filename")));
  174. return FALSE;
  175. }
  176. /* Create (or overwrite) the save file */
  177. #ifdef UNICODE
  178. fh = CreateFile(lszFile, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, 0, 0);
  179. if (fh == INVALID_HANDLE_VALUE) {
  180. dprintf1((TEXT("EditSaveFile: Error opening file")));
  181. return FALSE;
  182. }
  183. #else
  184. fh = OpenFile(lszFile, &of, OF_CREATE);
  185. if (fh == HFILE_ERROR) {
  186. dprintf1((TEXT("EditSaveFile: Error opening file")));
  187. return FALSE;
  188. }
  189. #endif
  190. /* Find out how big the contents of the edit box are */
  191. nFileLen = GetWindowTextLength(hwndEdit);
  192. // nFileLen = nFileLen*sizeof(TCHAR); We write ASCII
  193. /*
  194. * Create a pointer to a region of memory large enough to hold the entire
  195. * contents of the edit box. If this was successful, then read the contents
  196. * of the edit box into this region, and write the contents of this region
  197. * into the save file. Finally, free up the region and its pointer, and
  198. * close the file.
  199. *
  200. */
  201. lszText = (LPTSTR)GAllocPtr(nFileLen);
  202. if (NULL != lszText) {
  203. /* This could take a while - show the hourglass cursor */
  204. hcur = SetCursor(LoadCursor(NULL, IDC_WAIT));
  205. /* Read the contents of the edit box, and write it to the save file */
  206. GetWindowTextA(hwndEdit, (LPSTR)lszText, nFileLen); // Save ASCII file
  207. #ifdef UNICODE
  208. WriteFile(fh, lszText, nFileLen, &dwBytesWritten, NULL);
  209. #else
  210. _lwrite(fh, lszText, nFileLen);
  211. #endif
  212. /* Free up the memory, close the file, and restore the cursor */
  213. GFreePtr(lszText);
  214. #ifdef UNICODE
  215. CloseHandle(fh);
  216. #else
  217. _lclose(fh);
  218. #endif
  219. SetCursor(hcur);
  220. return TRUE;
  221. }
  222. /*
  223. * We couldn't allocate the required memory, so close the file and
  224. * return FALSE.
  225. */
  226. _lclose((HFILE)fh);
  227. return FALSE;
  228. }
  229. /*----------------------------------------------------------------------------*\
  230. | EditGetLineCount(hwndEdit) |
  231. | |
  232. | Description: |
  233. | This function finds out how many lines of text are in the edit box and |
  234. | returns this value. |
  235. | |
  236. | Arguments: |
  237. | hwndEdit window handle of the edit box control |
  238. | |
  239. | Returns: |
  240. | The number of lines of text in the edit control. |
  241. | |
  242. \*----------------------------------------------------------------------------*/
  243. DWORD EditGetLineCount(
  244. HWND hwndEdit)
  245. {
  246. return SendMessage(hwndEdit, EM_GETLINECOUNT, 0, 0L);
  247. }
  248. /*----------------------------------------------------------------------------*\
  249. | EditGetLine(hwndEdit, iLine, lszLineBuffer, cch) |
  250. | |
  251. | Description: |
  252. | This function retrieves the contents of line # <iLine> from the edit |
  253. | box control with handle <hwndEdit>. If <iLine> is out of range (that |
  254. | number line does not exist in the multi line edit field) then FALSE is |
  255. | returned. Otherwise the line is copied into the buffer pointed to by |
  256. | <lszLineBuffer> with white space removed. |
  257. | The string is also null terminated even if it means truncation. |
  258. | |
  259. | Arguments: |
  260. | hwndEdit window handle of the edit box control |
  261. | iLine line # to get the contents of |
  262. | lszLineBuffer pointer to the buffer to copy the line to |
  263. | cch max # of characters to copy (MIN value on entry==2) |
  264. | |
  265. | Returns: |
  266. | TRUE. |
  267. | |
  268. \*----------------------------------------------------------------------------*/
  269. BOOL EditGetLine(
  270. HWND hwndEdit,
  271. int iLine,
  272. LPTSTR lszLineBuffer,
  273. int cch)
  274. {
  275. int nLines; /* total number of lines in the edit box */
  276. /*
  277. * Find out how many lines are in the edit control. If the requested line
  278. * is out of range, then return.
  279. */
  280. nLines = (int)EditGetLineCount(hwndEdit);
  281. if (iLine < 0 || iLine >= nLines) {
  282. if (iLine!= nLines) { // Probably because the user pressed Enter
  283. // and the line number is beyond the end
  284. dprintf1((TEXT("Requested line count %d is out of range (%d)"), iLine, nLines));
  285. }
  286. return *lszLineBuffer = 0;
  287. /* This sets the buffer to null and returns FALSE */
  288. }
  289. /* Read the requested line into the string pointed to by <lszLineBuffer> */
  290. /* NOTE: This routine is always called with cch at least TWO */
  291. *((LPWORD)lszLineBuffer) = (WORD)cch;
  292. cch = (int)SendMessage(hwndEdit, EM_GETLINE, iLine, (LONG)(LPTSTR)lszLineBuffer);
  293. /* The returned string is NOT null terminated */
  294. /* Strip trailing white spaces from the string, and null-terminate it */
  295. while(cch > 0 && ISWHITE(lszLineBuffer[cch-1])) {
  296. cch--;
  297. }
  298. lszLineBuffer[cch] = 0;
  299. return TRUE;
  300. }
  301. /*----------------------------------------------------------------------------*\
  302. | EditGetCurLine(hwndEdit) |
  303. | |
  304. | Description: |
  305. | This function retrieves the line number of the current line in the |
  306. | edit box control with handle <hwndEdit>. It returns this line number. |
  307. | |
  308. | Arguments: |
  309. | hwndEdit window handle of the edit box control |
  310. | |
  311. | Returns: |
  312. | The line number of the current line. |
  313. | |
  314. \*----------------------------------------------------------------------------*/
  315. int EditGetCurLine(
  316. HWND hwndEdit)
  317. {
  318. int iLine; /* Line number of the currently active line */
  319. iLine = (int)SendMessage(hwndEdit, EM_LINEFROMCHAR, (WPARAM)-1, 0L);
  320. if (iLine < 0) {
  321. iLine = 0;
  322. }
  323. return iLine;
  324. }
  325. /*----------------------------------------------------------------------------*\
  326. | EditSetCurLine(hwndEdit, iLine) |
  327. | |
  328. | Description: |
  329. | This function sets the current line in the edit box control with |
  330. | handle <hwndEdit> to the number given in <iLine>. |
  331. | |
  332. | Arguments: |
  333. | hwndEdit window handle of the edit box control |
  334. | iLine the line number to be made the current line |
  335. | |
  336. | Returns: |
  337. | void |
  338. | |
  339. \*----------------------------------------------------------------------------*/
  340. void EditSetCurLine(
  341. HWND hwndEdit,
  342. int iLine)
  343. {
  344. int off;
  345. off = (int)SendMessage(hwndEdit, EM_LINEINDEX, iLine, 0L);
  346. SendMessage(hwndEdit, EM_SETSEL, off, off);
  347. }
  348. /*----------------------------------------------------------------------------*\
  349. | EditSelectLine(hwndEdit, iLine) |
  350. | |
  351. | Description: |
  352. | This function selects line # <iLine> in the edit box control with |
  353. | handle <hwndEdit>. |
  354. | |
  355. | Arguments: |
  356. | hwndEdit window handle of the edit box control |
  357. | iLine the line number to be selected |
  358. | |
  359. | Returns: |
  360. | void |
  361. | |
  362. \*----------------------------------------------------------------------------*/
  363. void EditSelectLine(
  364. HWND hwndEdit,
  365. int iLine)
  366. {
  367. int offS;
  368. int offE;
  369. offS = (int)SendMessage(hwndEdit, EM_LINEINDEX, iLine, 0L);
  370. offE = (int)SendMessage(hwndEdit, EM_LINEINDEX, iLine+1, 0L);
  371. if (offE < offS) { /* Select to the end */
  372. offE = -1;
  373. }
  374. SendMessage(hwndEdit, EM_SETSEL, offS, offE);
  375. }