home *** CD-ROM | disk | FTP | other *** search
/ Black Box 4 / BlackBox.cdr / w3_prog / zap.arj / Z3.C < prev    next >
Encoding:
C/C++ Source or Header  |  1992-02-01  |  12.3 KB  |  394 lines

  1. /***********************************************************************
  2. * Zap                                                                  *
  3. * ===                                                                  *
  4. *                                                                      *
  5. * Windows 3 Text Editor                                                *
  6. *                                                                      *
  7. * Sub-classing function                                                *
  8. *   long FAR PASCAL NewEditWndProc(HWND, unsigned, WORD, LONG);        *
  9. *   BOOL IsSeparator(char);                                            *
  10. *   BOOL IsNotSeparator(char);                                         *
  11. *                                                                      *
  12. * This programme was developed using Microsoft C6.0 and the Microsoft  *
  13. * SDK, however any ANSI C could be used if suitable libraries and the  *
  14. * Windows header are available.                                        *
  15. ***********************************************************************/
  16.  
  17. #include <windows.h>
  18. #include <string.h>
  19. #include "zap.h"
  20. #include "zapdlg.h"
  21.  
  22.  
  23. /***********************************************************************
  24. * External variables                                                   *
  25. ***********************************************************************/
  26.  
  27. extern HANDLE hInst;
  28. extern HWND   hMainWnd;
  29.  
  30. extern EDIT_WND EditWnd[MAX_FILES];
  31. extern int NumFiles, CurrentFile;
  32.  
  33. extern FARPROC lpNewEditWndProc;
  34.  
  35. extern LPSTR TransBuf;
  36.  
  37. extern int  CharWd, CharDp;
  38.  
  39. extern char WorkStr[WORK_STR_LEN];
  40.  
  41.  
  42. /***********************************************************************
  43. * Global variables                                                     *
  44. ***********************************************************************/
  45.  
  46. char LastDelete[WORK_STR_LEN];
  47.  
  48.  
  49. /***********************************************************************
  50. * Subclass procedure for the edit control.                             *
  51. ***********************************************************************/
  52.  
  53. long FAR PASCAL NewEditWndProc(HWND hWnd, unsigned message, WORD wParam, LONG lParam )
  54. { int  w_id, i;
  55.   long curpos, endpos, maxpos, iL;
  56.   char c;
  57.   BOOL b;
  58.   BYTE key_state[256];
  59.   FARPROC lp_proc;
  60.  
  61. /*** First identify the edit window */
  62.  
  63.   for (w_id = 0; w_id < NumFiles; w_id++)
  64.     if (EditWnd[w_id].hwnd == hWnd) break;
  65.  
  66.   if (w_id == NumFiles)
  67.   { MessageBeep(0);
  68.     return(0L);
  69.   }
  70.  
  71. /*** Now process the message */
  72.  
  73.   switch (message)
  74.   { case WM_KEYDOWN:
  75.       GetKeyboardState((BYTE FAR *) key_state);
  76.  
  77.       switch (wParam)
  78.       {
  79.  
  80. /*** The word left action is modified */
  81.  
  82.         case VK_LEFT:
  83.           if (CONTROL_DOWN)
  84.           { GetWindowText(EditWnd[w_id].hwnd, TransBuf, TRANS_BUF_SIZE);
  85.  
  86.             iL = CallWindowProc(EditWnd[w_id].proc, hWnd, EM_GETSEL, 0, 0L);
  87.             if ((curpos = LOWORD(iL)) == 0) return(0L);
  88.             endpos = HIWORD(iL);
  89.             curpos--;
  90.  
  91.             if (TransBuf[curpos] == '\n' && TransBuf[curpos-1] == '\r')
  92.             { curpos--;
  93.             }
  94.             else 
  95.             { while (curpos > 0 && !IsNotSeparator(TransBuf[curpos]))
  96.                 curpos--;
  97.               while (curpos > 0 && IsNotSeparator(TransBuf[curpos]))
  98.                 curpos--;
  99.               curpos++;
  100.             }
  101.  
  102.             if (!(SHIFT_DOWN)) endpos = curpos;
  103.             CallWindowProc(EditWnd[w_id].proc, hWnd, EM_SETSEL, 0, MAKELONG(curpos, endpos));
  104.             return(0L);
  105.           }
  106.           break;
  107.  
  108. /*** The word right action is modified */
  109.  
  110.         case VK_RIGHT:
  111.           if (CONTROL_DOWN)
  112.           { GetWindowText(EditWnd[w_id].hwnd, TransBuf, TRANS_BUF_SIZE);
  113.             maxpos = lstrlen(TransBuf);
  114.  
  115.             iL = CallWindowProc(EditWnd[w_id].proc, hWnd, EM_GETSEL, 0, 0L);
  116.             if ((curpos = HIWORD(iL)) == maxpos - 1) return(0L);
  117.             endpos = LOWORD(iL);
  118.             curpos++;
  119.  
  120.             if (TransBuf[curpos] == '\r' && TransBuf[curpos+1] == '\n')
  121.             { curpos++;
  122.             }
  123.             else 
  124.             { while (curpos > 0 && IsNotSeparator(TransBuf[curpos]))
  125.                 curpos++;
  126.               while (curpos > 0 && !IsNotSeparator(TransBuf[curpos]))
  127.                 curpos++;
  128.             }
  129.  
  130.             if (!(SHIFT_DOWN)) endpos = curpos;
  131.             CallWindowProc(EditWnd[w_id].proc, hWnd, EM_SETSEL, 0, MAKELONG(endpos, curpos));
  132.             return(0L);
  133.           }
  134.           break;
  135.  
  136. /*** Control Up or Down means goto line number */
  137.  
  138.         case VK_DOWN:
  139.         case VK_UP:
  140.           if (CONTROL_DOWN)
  141.           { lp_proc = MakeProcInstance(GotoLineProc, hInst);
  142.             iL = DialogBoxParam(hInst, "GotoBox", hMainWnd, lp_proc, (LONG)w_id);
  143.             FreeProcInstance(lp_proc);
  144.  
  145.             GotoLine(w_id, iL);
  146.  
  147.             return(0L);
  148.           }
  149.           break;
  150.  
  151. /*** Control Page Up or Down means change window */
  152.  
  153.         case VK_NEXT:
  154.           if (CONTROL_DOWN)
  155.           { if (NumFiles > 1)
  156.             { CurrentFile++;
  157.               if (CurrentFile == NumFiles) CurrentFile = 0;
  158.               SetFocus(CurWnd);
  159.             }
  160.  
  161.             return(0L);
  162.           }
  163.           break;
  164.  
  165.         case VK_PRIOR:
  166.           if (CONTROL_DOWN)
  167.           { if (NumFiles > 1)
  168.             { CurrentFile--;
  169.               if (CurrentFile < 0) CurrentFile = NumFiles - 1;
  170.               SetFocus(CurWnd);
  171.             }
  172.  
  173.             return(0L);
  174.           }
  175.           break;
  176.  
  177. /*** Control-Shift-Insert means insert the last deletion */
  178.  
  179.         case VK_INSERT:
  180.           if (CONTROL_DOWN && SHIFT_DOWN)
  181.           { if (LastDelete[0] != '\0')
  182.             { if (SendToClipboard(LastDelete))
  183.               { CallWindowProc(EditWnd[w_id].proc, hWnd, WM_PASTE, 0, 0L);
  184.               }
  185.             }
  186.  
  187.             return(0L);
  188.           }
  189.           break;
  190.  
  191. /*** The delete key has a variety of meanings depending on control and shift */
  192.  
  193.         case VK_DELETE:
  194.           if (CONTROL_DOWN)
  195.           {
  196.  
  197. /*** Control-Shift-Delete deletes the current line */
  198.  
  199.             if (SHIFT_DOWN)
  200.             { GetWindowText(EditWnd[w_id].hwnd, TransBuf, TRANS_BUF_SIZE);
  201.               maxpos = lstrlen(TransBuf);
  202.               curpos = LOWORD(CallWindowProc(EditWnd[w_id].proc, hWnd, EM_GETSEL, 0, 0L));
  203.  
  204.               while (curpos > 0)
  205.               { if (TransBuf[curpos-1] == '\n')
  206.                   if (TransBuf[curpos-2] == '\r')
  207.                     break;
  208.                 curpos--;
  209.               }
  210.  
  211.               endpos = curpos;
  212.               while (endpos < maxpos)
  213.               { if (TransBuf[endpos] == '\r')
  214.                 { if (TransBuf[endpos+1] == '\n')
  215.                   { endpos += 2;
  216.                     break;
  217.                   }
  218.                 }
  219.  
  220.                 endpos++;
  221.               }
  222.  
  223.               CallWindowProc(EditWnd[w_id].proc, hWnd, EM_SETSEL, 0, MAKELONG(curpos, endpos));
  224.               CallWindowProc(EditWnd[w_id].proc, hWnd, WM_CLEAR, 0, 0L);
  225.  
  226.               for (i = 0; i < endpos - curpos; i++) 
  227.                 LastDelete[i] = TransBuf[curpos + i];
  228.               LastDelete[i] = '\0';
  229.  
  230.               return(0L);
  231.             }
  232.  
  233. /*** Control-Delete deletes word right */
  234.  
  235.             else
  236.             { GetWindowText(EditWnd[w_id].hwnd, TransBuf, TRANS_BUF_SIZE);
  237.               maxpos = lstrlen(TransBuf);
  238.               curpos = LOWORD(CallWindowProc(EditWnd[w_id].proc, hWnd, EM_GETSEL, 0, 0L));
  239.               if (curpos == maxpos) return(0L);
  240.  
  241.               if (TransBuf[curpos] == '\r' && TransBuf[curpos + 1] == '\n')
  242.               { endpos = curpos + 2;
  243.               }
  244.               else if (!IsSeparator(TransBuf[curpos]) && !IsNotSeparator(TransBuf[curpos]))
  245.               { endpos = curpos + 1;
  246.               }
  247.               else
  248.               { endpos = curpos;
  249.                 while (endpos < maxpos && IsNotSeparator(TransBuf[endpos]))
  250.                   endpos++;
  251.                 while (endpos < maxpos && IsSeparator(TransBuf[endpos]))
  252.                   endpos++;
  253.               }
  254.  
  255.               CallWindowProc(EditWnd[w_id].proc, hWnd, EM_SETSEL, 0, MAKELONG(curpos, endpos));
  256.               CallWindowProc(EditWnd[w_id].proc, hWnd, WM_CLEAR, 0, 0L);
  257.  
  258.               for (i = 0; i < endpos - curpos; i++) 
  259.                 LastDelete[i] = TransBuf[curpos + i];
  260.               LastDelete[i] = '\0';
  261.  
  262.               return(0L);
  263.             }
  264.           }
  265.       }
  266.       break;
  267.  
  268. /*** Some keypresses can be trapped via WM_CHAR messages */
  269.  
  270.     case WM_CHAR:
  271.       GetKeyboardState((BYTE FAR *) key_state);
  272.  
  273.       switch (wParam)
  274.       {
  275.  
  276. /*** Tab character is expanded to spaces */
  277.  
  278.         case VK_TAB:
  279.           GetWindowText(EditWnd[w_id].hwnd, TransBuf, TRANS_BUF_SIZE);
  280.           curpos = LOWORD(CallWindowProc(EditWnd[w_id].proc, hWnd, EM_GETSEL, 0, 0L));
  281.  
  282.           i = 0;
  283.           while (curpos - i > 0 && TransBuf[curpos - (i + 1)] != '\n') i++;
  284.           i = 8 - (i % 8);
  285.  
  286.           for (; i > 0; i--)
  287.             CallWindowProc(EditWnd[w_id].proc, hWnd, WM_CHAR, (WORD) ' ', 0L);
  288.           return(0L);
  289.  
  290. /*** Return inserts spaces to match previous line */
  291.  
  292.         case VK_RETURN:
  293.           GetWindowText(EditWnd[w_id].hwnd, TransBuf, TRANS_BUF_SIZE);
  294.           curpos = LOWORD(CallWindowProc(EditWnd[w_id].proc, hWnd, EM_GETSEL, 0, 0L));
  295.  
  296.           while (curpos > 0 && TransBuf[curpos - 1] != '\n') curpos--;
  297.           i = 0;
  298.           while (TransBuf[curpos + i] == ' ') i++;
  299.  
  300.           CallWindowProc(EditWnd[w_id].proc, hWnd, WM_CHAR, VK_RETURN, lParam);
  301.           for (; i > 0; i--)
  302.             CallWindowProc(EditWnd[w_id].proc, hWnd, WM_CHAR, (WORD) ' ', 0L);
  303.           return(0L);
  304.  
  305. /*** 0x1A results from ^Z */
  306.  
  307.         case 0x1A:
  308.           GetWindowText(EditWnd[w_id].hwnd, TransBuf, TRANS_BUF_SIZE);
  309.           curpos = LOWORD(CallWindowProc(EditWnd[w_id].proc, hWnd, EM_GETSEL, 0, 0L));
  310.  
  311.           c = TransBuf[curpos];
  312.           if (IsCharUpper(c))
  313.           { AnsiLowerBuff(&c, 1);
  314.           }
  315.           else if (IsCharLower(c))
  316.           { AnsiUpperBuff(&c, 1);;
  317.           }
  318.           else
  319.           { CallWindowProc(EditWnd[w_id].proc, hWnd, EM_SETSEL, 0, MAKELONG(curpos + 1, curpos + 1));
  320.             return(0L);
  321.           }
  322.  
  323.           WorkStr[0] = c;
  324.           WorkStr[1] = '\0';
  325.           CallWindowProc(EditWnd[w_id].proc, hWnd, EM_SETSEL, 0, MAKELONG(curpos, curpos + 1));
  326.           CallWindowProc(EditWnd[w_id].proc, hWnd, EM_REPLACESEL, 0, (LONG)WorkStr);
  327.           CallWindowProc(EditWnd[w_id].proc, hWnd, EM_SETSEL, 0, MAKELONG(curpos + 1, curpos + 1));
  328.  
  329.           return(0L);
  330.  
  331. /*** 0x7F results from ^BackSpace */
  332.  
  333.         case 0x7F:
  334.           if (CONTROL_DOWN && !(SHIFT_DOWN))
  335.           { endpos = LOWORD(CallWindowProc(EditWnd[w_id].proc, hWnd, EM_GETSEL, 0, 0L));
  336.             if (endpos == 0) return(0L);
  337.  
  338.             GetWindowText(EditWnd[w_id].hwnd, TransBuf, TRANS_BUF_SIZE);
  339.  
  340.             curpos = endpos - 1;
  341.             if (TransBuf[curpos] == '\n' && TransBuf[curpos-1] == '\r')
  342.             { curpos--;
  343.             }
  344.             else if (IsSeparator(TransBuf[curpos]) || IsNotSeparator(TransBuf[curpos]))
  345.             { while (curpos > 0 && IsSeparator(TransBuf[curpos]))
  346.                 curpos--;
  347.               while (curpos > 0 && IsNotSeparator(TransBuf[curpos]))
  348.                 curpos--;
  349.               curpos++;
  350.             }
  351.  
  352.             CallWindowProc(EditWnd[w_id].proc, hWnd, EM_SETSEL, 0, MAKELONG(curpos, endpos));
  353.             CallWindowProc(EditWnd[w_id].proc, hWnd, WM_CLEAR, 0, 0L);
  354.  
  355.             for (i = 0; i < endpos - curpos; i++)
  356.               LastDelete[i] = TransBuf[curpos + i];
  357.             LastDelete[i] = '\0';
  358.  
  359.             return(0L);
  360.           }
  361.           break;
  362.  
  363.       }
  364.       break;
  365.   }
  366.  
  367.   return(CallWindowProc(EditWnd[w_id].proc, hWnd, message, wParam, lParam));
  368. }
  369.  
  370.  
  371. /***********************************************************************
  372. * Routines for changing key states                                     *
  373. ***********************************************************************/
  374.  
  375. BOOL IsSeparator(char c)
  376. {
  377.   if (c == ' ')
  378.     return(TRUE);
  379.   else
  380.     return(FALSE);
  381. }
  382.  
  383.  
  384. BOOL IsNotSeparator(char c)
  385. {
  386.   if (c >= 'A' && c <= 'Z')
  387.     return(TRUE);
  388.   else if (c >= 'a' && c <= 'z')
  389.     return(TRUE);
  390.   else
  391.     return(FALSE);
  392. }
  393.  
  394.