home *** CD-ROM | disk | FTP | other *** search
/ BUG 4 / BUGCD1997_05.BIN / aplic / clip4win / clip4win.exe / C4W30E.HUF / SOURCE / EDIT.PRG < prev    next >
Text File  |  1994-04-22  |  13KB  |  557 lines

  1. ////////////////////////////
  2. //
  3. //    Clip-4-Win edit control demo
  4. //
  5. //    Copyright (C) 1992,1993 Skelton Software, Kendal Cottage, Hillam, Leeds, UK.
  6. //    All Rights Reserved.
  7. //
  8. //    Compile:    edit /n /w
  9. //    Link:        /se:600 edit,,,clip4win,edit.def
  10. //
  11. //    Be sure to specify "heapsize n" (e.g. n = 2048) in the .def file,
  12. //    so there's some memory for the control to use.
  13. //
  14. //    In a dialog, you can get a handle like this:
  15. //        hEdit = GetDlgItem(hWndDlg, ID_EDIT)
  16. //
  17. //    (Actually, you can do that in an ordinary window, too.  Maybe
  18. //    the function should really be called GetWndItem().)
  19. //
  20. ////////////////////////////
  21.  
  22. #define    WIN_WANT_EN            // optional Edit Notification messages
  23. #define    WIN_WANT_CLIPBOARD
  24. #define    WIN_WANT_ALL
  25. #include "windows.ch"
  26.  
  27.  
  28. #define    MAKELPARAM(nLow, nHigh)        ((nLow) + (nHigh) * 65536)
  29.  
  30. #define    CR    chr(13)
  31. #define    CRLF    chr(13) + chr(10)
  32.  
  33. #ifndef    LIB_ONLY
  34.  
  35. #define    ID_EDIT    1            // unique id (used for the edit control)
  36.  
  37. static    hWnd, hInst, cText, hEdit, cAppName := "Clip-4-Win"
  38.  
  39.  
  40. function main()
  41. local    hMenu, nEvent
  42.  
  43. hWnd = WinSetup(cAppName, "Clip-4-Win Edit Control Demo")
  44. hInst = _GetInstance()
  45. hMenu = MenuSetup()
  46. HideCaret(hWnd)
  47.  
  48. do while .t.
  49.     do while (nEvent := ChkEvent()) == EVENT_NONE
  50.         // some "background" processing could go here
  51.     enddo
  52.     HandleEvent(nEvent)        // give the event to the right handler
  53. enddo
  54.  
  55. return 0
  56.  
  57.  
  58. static procedure DoAbout()
  59. MessageBox( , "Written by John Skelton.", "Info", MB_OK)
  60. return
  61.  
  62.  
  63. static procedure DoExit()
  64. quit
  65. return
  66.  
  67.  
  68. // Single-line edit control
  69.  
  70. static procedure DoSEdit()
  71. local    cEdit := "Initial Text"
  72. if hEdit != nil
  73.     ? "Edit text (line 0) was:", EditGetLine(hEdit, 0)
  74.     DestroyWindow(hEdit)        // remove previous edit control
  75. endif
  76. hEdit = CreateWindow("edit",        ;    // window class
  77.              cEdit,         ;    // initial buffer
  78.              WS_CHILD        ;    // child window
  79.              + WS_VISIBLE    ;    // ... that can be seen
  80.              + WS_BORDER    ;    // ... with a border
  81.              + ES_LEFT        ;    // ... left justified
  82.              + ES_AUTOHSCROLL,    ;    // ... auto horiz. scroll
  83.              50, 50,        ;    // x,y position
  84.              250, 30,        ;    // width, height
  85.              hWnd,        ;    // parent window
  86.              ID_EDIT,        ;    // id for child control to use
  87.              hInst)            // our own app instance
  88. // In a dialog, get the handle like this:
  89. //    hEdit = GetDlgItem(hWndDlg, ID_EDIT)
  90. EditLimitText(hEdit, 15)        // just for testing
  91. SetFocus(hEdit)
  92. AddHandler(hWnd, {|nEvent| EditEvent(nEvent)})
  93. return
  94.  
  95.  
  96. // Multi-line edit control
  97.  
  98. static procedure DoMEdit()
  99. local    cEdit := "Some strings" + CRLF + "for an Edit Control" + CRLF    ;
  100.          + "as an example" + CRLF + "for you"
  101. if hEdit != nil
  102.     ? "Edit text (line 0) was:", EditGetLine(hEdit, 0)
  103.     DestroyWindow(hEdit)        // remove previous edit control
  104. endif
  105. hEdit = CreateWindow("edit",        ;    // window class
  106.              cEdit,         ;    // initial buffer
  107.              WS_CHILD        ;    // child window
  108.              + WS_VISIBLE    ;    // ... that can be seen
  109.              + WS_HSCROLL    ;    // ... horiz. scroll bar
  110.              + WS_VSCROLL    ;    // ... vert. scroll bar
  111.              + WS_BORDER    ;    // ... with a border
  112.              + ES_LEFT        ;    // ... left justified
  113.              + ES_MULTILINE    ;    // ... allow several lines
  114.              + ES_AUTOHSCROLL    ;    // ... auto horiz. scroll
  115.              + ES_AUTOVSCROLL,    ;    // ... auto vert. scroll
  116.              50, 50,        ;    // x,y position
  117.              250, 200,        ;    // width, height
  118.              hWnd,        ;    // parent window
  119.              ID_EDIT,        ;    // id for child control to use
  120.              hInst)            // our own app instance
  121. SetFocus(hEdit)
  122. AddHandler(hWnd, {|nEvent| EditEvent(nEvent)})
  123. return
  124.  
  125.  
  126. static procedure EditEvent(nEvent)
  127. local    nEN, nLen
  128. do case
  129. case nEvent == EVENT_CONTROL
  130.     if _LastwParam() == ID_EDIT    // child id
  131.         // we've been sent a message by the edit control
  132.         nEN = _LastHilParam()    // get the reason for the msg
  133.         if nEN == EN_MAXTEXT .or. nEN == EN_ERRSPACE
  134.             // char(s) did not fit in the space available
  135.             nLen = SendMessage(hEdit, WM_GETTEXTLENGTH, 0, 0)
  136.             MessageBox( , "No more room" + CR        ;
  137.                       + "Length = " + ltrim(str(nLen)),    ;
  138.                       "Edit control", MB_OK)
  139.         elseif nEN == EN_CHANGE
  140.             // contents have (probably) been changed
  141.         //elseif ...
  142.         endif
  143.     endif
  144. case nEvent == EVENT_SETFOCUS
  145.     SetFocus(hEdit)            // let edit control keep input focus
  146. endcase
  147. return
  148.  
  149.  
  150. static function DoCut()
  151. local    aSel
  152. if hEdit != nil
  153.     aSel = EditGetSel(hEdit)
  154.     if aSel[1] == aSel[2]
  155.         MessageBox( , "Nothing to Cut!  (Try selecting some text.)", ;
  156.                "Warning")
  157.     endif
  158.     EditCut(hEdit)
  159. endif
  160. return nil
  161.  
  162.  
  163. static function DoCopy()
  164. local    aSel
  165. if hEdit != nil
  166.     aSel = EditGetSel(hEdit)
  167.     if aSel[1] == aSel[2]
  168.         MessageBox( , "Nothing to Copy!  (Try selecting some text.)", ;
  169.                "Warning")
  170.     endif
  171.     EditCopy(hEdit)
  172. endif
  173. return nil
  174.  
  175.  
  176. static function DoPaste()
  177. if hEdit != nil
  178.     EditPaste(hEdit)
  179. endif
  180. return nil
  181.  
  182.  
  183. #endif // !LIB_ONLY
  184.  
  185.  
  186.  
  187. /////////
  188. //
  189. //    EditCanUndo( <hEdit> )  -->  lCanUndo
  190. //
  191. //    Returns .t. if the last edit control operation can be undone
  192. //
  193. /////////
  194.  
  195. function EditCanUndo(hEdit)
  196. return SendMessage(hEdit, EM_CANUNDO, 0, 0) != 0
  197.  
  198.  
  199. /////////
  200. //
  201. //    EditCopy( <hEdit> )  -->  nil
  202. //
  203. //    Copy the edit control contents to the Windows clipboard.
  204. //
  205. //    NOTE: Uses EM_SETSEL internally.
  206. //
  207. /////////
  208.  
  209. procedure EditCopy(hEdit)
  210. SendMessage(hEdit, WM_COPY, 0, 0)
  211. return
  212.  
  213.  
  214. /////////
  215. //
  216. //    EditCut( <hEdit> )  -->  nil
  217. //
  218. //    Cut the edit control contents to the Windows clipboard.
  219. //
  220. //    NOTE: You can use the EM_UNDO message to restore the contents
  221. //          (still leaving a copy in the clipboard).
  222. //
  223. /////////
  224.  
  225. procedure EditCut(hEdit)
  226. SendMessage(hEdit, WM_CUT, 0, 0)
  227. return
  228.  
  229.  
  230. /////////
  231. //
  232. //    EditEmptyUndoBuffer( <hEdit> )  -->  nil
  233. //
  234. //    Clears the edit control undo buffer
  235. //
  236. /////////
  237.  
  238. procedure EditEmptyUndoBuffer(hEdit)
  239. SendMessage(hEdit, EM_EMPTYUNDOBUFFER, 0, 0)
  240. return
  241.  
  242.  
  243. /////////
  244. //
  245. //    EditGetFirstVisibleLine( <hEdit> )  -->  nLine
  246. //
  247. //    Returns the number of the top line that's visible
  248. //
  249. /////////
  250.  
  251. function EditGetFirstVisibleLine(hEdit)
  252. return SendMessage(hEdit, EM_GETFIRSTVISIBLELINE, 0, 0)
  253.  
  254.  
  255. /////////
  256. //
  257. //    EditGetLine( <hEdit>, <nLine> )  -->  cLine
  258. //
  259. //    Returns the specified line from within an edit control
  260. //    (<nLine> starts at 0, and is ignored for a single-line edit control)
  261. //
  262. /////////
  263.  
  264. function EditGetLine(hEdit, nLine)
  265. local    nLen, cBuf := space(200)    // seems generous
  266. cBuf = c4w_i2bin(len(cBuf)) + cBuf
  267. nLen = SendMessage(hEdit, EM_GETLINE, nLine, @cBuf)
  268. return left(cBuf, nLen)
  269.  
  270.  
  271. /////////
  272. //
  273. //    EditGLineCount( <hEdit> )  -->  nCount
  274. //
  275. //    Returns the number of lines within a multi-line edit control
  276. //
  277. /////////
  278.  
  279. function EditGLineCount(hEdit)
  280. return SendMessage(hEdit, EM_GETLINECOUNT, 0, 0)
  281.  
  282.  
  283. /////////
  284. //
  285. //    EditGetModify( <hEdit> )  -->  lModify
  286. //
  287. //    Returns .t. if the contents of the edit control have been changed
  288. //
  289. /////////
  290.  
  291. function EditGetModify(hEdit)
  292. return SendMessage(hEdit, EM_GETMODIFY, 0, 0) != 0
  293.  
  294.  
  295. /////////
  296. //
  297. //    EditGetPasswordChar( <hEdit> )  -->  nChar
  298. //
  299. //    Returns the character displayed when the user enters text in an
  300. //    edit control (returns 0 if no password char exists)
  301. //
  302. /////////
  303.  
  304. function EditGetPasswordChar(hEdit)
  305. return SendMessage(hEdit, EM_GETPASSWORDCHAR, 0, 0)
  306.  
  307.  
  308. /////////
  309. //
  310. //    EditGetSel( <hEdit> )  -->  aSel
  311. //
  312. //    Returns the start and end of the selected part of an edit control
  313. //
  314. //    aSel is in the form { start, end }
  315. //
  316. /////////
  317.  
  318. function EditGetSel(hEdit)
  319. return bin2a(c4w_l2bin(SendMessage(hEdit, EM_GETSEL, 0, 0)), "int[2]")
  320.  
  321.  
  322. /////////
  323. //
  324. //    EditGetText( <hEdit> )  -->  cText
  325. //
  326. //    Get all the text in an edit control.
  327. //
  328. /////////
  329.  
  330. function EditGetText(hEdit)
  331. local    nLen, cBuf
  332. // get the length, and include room for the trailing null that Windows
  333. // wants to add (even though we don't want it!)
  334. nLen = SendMessage(hEdit, WM_GETTEXTLENGTH, 0, 0) + 1
  335. cBuf = space(nLen)
  336. nLen = SendMessage(hEdit, WM_GETTEXT, nLen, @cBuf)    // note: not an EM_ msg
  337. return left(cBuf, nLen)
  338.  
  339.  
  340. /////////
  341. //
  342. //    EditLimitText( <hEdit>, <nMax> )  -->  nil
  343. //
  344. //    Sets the maximum number of characters allowed in the edit control
  345. //    (in the range 0-nnnn, where nnnn is limited by the heapsize
  346. //    specified in the .def file for the linker)
  347. //
  348. /////////
  349.  
  350. procedure EditLimitText(hEdit, nMax)
  351. SendMessage(hEdit, EM_LIMITTEXT, nMax, 0)
  352. return
  353.  
  354.  
  355. /////////
  356. //
  357. //    EditLineFromChar( <hEdit>, <nPos> )  -->  nLine
  358. //
  359. //    Returns the line number indicated by the character position
  360. //
  361. //    <nPos> counts from zero.
  362. //
  363. /////////
  364.  
  365. function EditLineFromChar(hEdit, nPos)
  366. return SendMessage(hEdit, EM_LINEFROMCHAR, nPos, 0)
  367.  
  368.  
  369. /////////
  370. //
  371. //    EditLineIndex( <hEdit>, <nLine> )  -->  nPos
  372. //
  373. //    Returns the character position of a line within a multi-line
  374. //    edit control.
  375. //
  376. //    <nLine> counts from zero.  Use -1 for the current line.
  377. //
  378. /////////
  379.  
  380. function EditLineIndex(hEdit, nLine)
  381. return SendMessage(hEdit, EM_LINEINDEX, nLine, 0)
  382.  
  383.  
  384. /////////
  385. //
  386. //    EditLineLength( <hEdit>, <nPos> )  -->  nLen
  387. //
  388. //    Returns the length of the line indicated by the character position
  389. //
  390. //    <nPos> counts from zero.
  391. //
  392. /////////
  393.  
  394. function EditLineLength(hEdit, nPos)
  395. return SendMessage(hEdit, EM_LINELENGTH, nPos, 0)
  396.  
  397.  
  398. /////////
  399. //
  400. //    EditPaste( <hEdit> )  -->  nil
  401. //
  402. //    Paste the contents of the Windows clipboard into an edit control.
  403. //
  404. /////////
  405.  
  406. procedure EditPaste(hEdit)
  407. SendMessage(hEdit, WM_PASTE, 0, 0)
  408. return
  409.  
  410.  
  411. /////////
  412. //
  413. //    EditReplaceSel( <hEdit>, <cNewStr> )  -->  nil
  414. //
  415. //    Replace the currently selected text in an edit control
  416. //    (the new string may be a different length, of course).
  417. //
  418. //    To replace all the text, use EditSetText(), below.
  419. //
  420. /////////
  421.  
  422. procedure EditReplaceSel(hEdit, cNewStr)
  423. SendMessage(hEdit, EM_REPLACESEL, 0, cNewStr)
  424. return
  425.  
  426.  
  427. /////////
  428. //
  429. //    EditSetModify( <hEdit>, <lModify> )  -->  nil
  430. //
  431. //    Sets/clears the flag that indicates whether the contents of the
  432. //    edit control have been changed
  433. //
  434. /////////
  435.  
  436. procedure EditSetModify(hEdit, lModify)
  437. SendMessage(hEdit, EM_SETMODIFY, iif(lModify, 1, 0), 0)
  438. return
  439.  
  440.  
  441. /////////
  442. //
  443. //    EditSetPasswordChar( <hEdit>, <nNewChar> )  -->  nil
  444. //
  445. //    Sets the character displayed when the user enters text in a
  446. //    single-line edit control
  447. //
  448. /////////
  449.  
  450. procedure EditSetPasswordChar(hEdit, nChar)
  451. SendMessage(hEdit, EM_SETPASSWORDCHAR, nChar, 0)
  452. return
  453.  
  454.  
  455. /////////
  456. //
  457. //    EditSetReadOnly( <hEdit>, <lReadOnly> )  -->  lSuccess
  458. //
  459. //    Makes the contents of the edit control read-write or read-only
  460. //
  461. /////////
  462.  
  463. function EditSetReadOnly(hEdit, lReadOnly)
  464. return SendMessage(hEdit, EM_SETREADONLY, iif(lReadOnly, 1, 0), 0) != 0
  465.  
  466.  
  467. /////////
  468. //
  469. //    EditSetSel( <hEdit>, <nStart>, <nEnd>, <lMakeCaretVisible> )  -->  nil
  470. //
  471. //    Sets the start and end of the selected part of an edit control.
  472. //    The caret is placed at the end, and optionally brought into
  473. //    sight (by scrolling as needed).
  474. //
  475. //    Special values:
  476. //
  477. //        nStart = 0, and nEnd = -1    all the text is selected
  478. //        nStart = -1            nothing selected
  479. //
  480. /////////
  481.  
  482. procedure EditSetSel(hEdit, nStart, nEnd, lMakeCaretVisible)
  483. if lMakeCaretVisible == nil
  484.     lMakeCaretVisible = .t.
  485. endif
  486. SendMessage(hEdit, EM_SETSEL,            ;
  487.         iif(lMakeCaretVisible, 0, 1),    ;  // note the order
  488.         MAKELPARAM(nStart, nEnd))
  489. return
  490.  
  491.  
  492. /////////
  493. //
  494. //    EditSetText( <hEdit>, <cNewStr> )  -->  nil
  495. //
  496. //    Change all the text in an edit control.
  497. //
  498. //    To replace part of the text, use EditReplaceSel(), above.
  499. //
  500. /////////
  501.  
  502. procedure EditSetText(hEdit, cNewStr)
  503. SendMessage(hEdit, WM_SETTEXT, 0, cNewStr)    // note: not an EM_ msg
  504. return
  505.  
  506.  
  507. /////////
  508. //
  509. //    EditUndo( <hEdit> )  -->  lUndone
  510. //
  511. //    Attempts to undo the last edit control operation, and
  512. //    returns .t. if it was undone ok
  513. //
  514. /////////
  515.  
  516. function EditUndo(hEdit)
  517. return SendMessage(hEdit, EM_UNDO, 0, 0) != 0
  518.  
  519.  
  520. #ifndef    LIB_ONLY
  521.  
  522.  
  523. function nstr(n)
  524. return alltrim(str(n)) + " "
  525.  
  526.  
  527.  
  528. static function MenuSetup()
  529. local    hWnd := SelectWindow(), hMenu, hPopupMenu
  530.  
  531. if (hMenu := GetMenu(hWnd)) != nil
  532.     DestroyMenu(hMenu)
  533. endif
  534.  
  535. // do new one (forget old value)
  536. hMenu = CreateMenu()
  537. hPopupMenu = CreatePopupMenu()
  538. AppendMenu(hMenu, "file", MF_ENABLED + MF_POPUP, "&File", hPopupMenu)
  539. AppendMenu(hPopupMenu, "exit", MF_ENABLED + MF_STRING, "E&xit", {|| Alert("Thanks for running this demo"), DoExit()})
  540. hPopupMenu = CreatePopupMenu()
  541. AppendMenu(hMenu, "edit", MF_ENABLED + MF_POPUP, "&Edit", hPopupMenu)
  542. AppendMenu(hPopupMenu, "cut",   MF_ENABLED + MF_STRING, "Cu&t",  {|c| DoCut()})
  543. AppendMenu(hPopupMenu, "copy",  MF_ENABLED + MF_STRING, "&Copy", {|c| DoCopy()})
  544. AppendMenu(hPopupMenu, "paste", MF_ENABLED + MF_STRING, "&Paste", {|| DoPaste()})
  545. hPopupMenu = CreatePopupMenu()
  546. AppendMenu(hMenu, "demo", MF_ENABLED + MF_POPUP, "&Demo", hPopupMenu)
  547. AppendMenu(hPopupMenu, "edit1", MF_ENABLED + MF_STRING, "&Single-line", {|c| DoSEdit()})
  548. AppendMenu(hPopupMenu, "medit", MF_ENABLED + MF_STRING, "&Multi-line", {|c| DoMEdit()})
  549. hPopupMenu = CreatePopupMenu()
  550. AppendMenu(hMenu, "help", MF_ENABLED + MF_POPUP, "&Help", hPopupMenu)
  551. AppendMenu(hPopupMenu, "about", MF_ENABLED + MF_STRING, "&About", {|| DoAbout()})
  552. SetMenu(hWnd, hMenu)
  553.  
  554. return hMenu
  555.  
  556. #endif // !LIB_ONLY
  557.