home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / sa104os2.zip / SATHR104.ZIP / SATHER / SYSTEM / GC / CORD / DE_WIN.C < prev    next >
C/C++ Source or Header  |  1994-05-19  |  11KB  |  366 lines

  1. /*
  2.  * Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
  3.  *
  4.  * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
  5.  * OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
  6.  *
  7.  * Permission is hereby granted to use or copy this program
  8.  * for any purpose,  provided the above notices are retained on all copies.
  9.  * Permission to modify the code and to distribute modified code is granted,
  10.  * provided the above notices are retained, and a notice that the code was
  11.  * modified is included with the above copyright notice.
  12.  */
  13. /* Boehm, May 19, 1994 2:21 pm PDT */
  14.  
  15. /*
  16.  * The MS Windows specific part of de.  
  17.  * This started as the generic Windows application template
  18.  * made available by Rob Haack (rhaack@polaris.unm.edu), but
  19.  * significant parts didn't survive to the final version.
  20.  *
  21.  * This was written by a nonexpert windows programmer.
  22.  */
  23.  
  24.  
  25. #include "windows.h"
  26. #include "gc.h"
  27. #include "cord.h"
  28. #include "de_cmds.h"
  29. #include "de_win.h"
  30.  
  31. int LINES = 0;
  32. int COLS = 0;
  33.  
  34. char       szAppName[]     = "DE";
  35. char       FullAppName[]   = "Demonstration Editor";
  36.  
  37. HWND        hwnd;
  38.  
  39. void de_error(char *s)
  40. {
  41.     MessageBox( hwnd, (LPSTR) s,
  42.                 (LPSTR) FullAppName,
  43.                 MB_ICONINFORMATION | MB_OK );
  44.     InvalidateRect(hwnd, NULL, TRUE);
  45. }
  46.  
  47. int APIENTRY WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
  48.                       LPSTR command_line, int nCmdShow)
  49. {
  50.    MSG         msg;
  51.    WNDCLASS    wndclass;
  52.    HANDLE      hAccel;
  53.  
  54.    if (!hPrevInstance)
  55.    {
  56.       wndclass.style          = CS_HREDRAW | CS_VREDRAW;
  57.       wndclass.lpfnWndProc    = WndProc;
  58.       wndclass.cbClsExtra     = 0;
  59.       wndclass.cbWndExtra     = DLGWINDOWEXTRA;
  60.       wndclass.hInstance      = hInstance;
  61.       wndclass.hIcon          = LoadIcon (hInstance, szAppName);
  62.       wndclass.hCursor        = LoadCursor (NULL, IDC_ARROW);
  63.       wndclass.hbrBackground  = GetStockObject(WHITE_BRUSH);
  64.       wndclass.lpszMenuName   = "DE";
  65.       wndclass.lpszClassName  = szAppName;
  66.  
  67.       if (RegisterClass (&wndclass) == 0) {
  68.           char buf[50];
  69.        
  70.          sprintf(buf, "RegisterClass: error code: 0x%X", GetLastError());
  71.          de_error(buf);
  72.          return(0);
  73.       }
  74.    }
  75.    
  76.    /* Empirically, the command line does not include the command name ...
  77.    if (command_line != 0) {
  78.        while (isspace(*command_line)) command_line++;
  79.        while (*command_line != 0 && !isspace(*command_line)) command_line++;
  80.        while (isspace(*command_line)) command_line++;
  81.    } */
  82.    
  83.    if (command_line == 0 || *command_line == 0) {
  84.         de_error("File name argument required");
  85.         return( 0 );
  86.    } else {
  87.         char *p = command_line;
  88.         
  89.         while (*p != 0 && !isspace(*p)) p++;
  90.        arg_file_name = CORD_to_char_star(
  91.                    CORD_substr(command_line, 0, p - command_line));
  92.    }
  93.  
  94.    hwnd = CreateWindow (szAppName,
  95.                FullAppName,
  96.                WS_OVERLAPPEDWINDOW | WS_CAPTION, /* Window style */
  97.                CW_USEDEFAULT, 0, /* default pos. */,
  98.                CW_USEDEFAULT, 0, /* default width, height */,
  99.                NULL,    /* No parent */
  100.                NULL,     /* Window class menu */
  101.                hInstance, NULL);
  102.    if (hwnd == NULL) {
  103.        char buf[50];
  104.        
  105.        sprintf(buf, "CreateWindow: error code: 0x%X", GetLastError());
  106.        de_error(buf);
  107.        return(0);
  108.    }
  109.  
  110.    ShowWindow (hwnd, nCmdShow);
  111.  
  112.    hAccel = LoadAccelerators( hInstance, szAppName );
  113.    
  114.    while (GetMessage (&msg, NULL, 0, 0))
  115.    {
  116.       if( !TranslateAccelerator( hwnd, hAccel, &msg ) )
  117.       {
  118.          TranslateMessage (&msg);
  119.          DispatchMessage (&msg);
  120.       }
  121.    }
  122.    return msg.wParam;
  123. }
  124.  
  125. /* Return the argument with all control characters replaced by blanks.    */
  126. char * plain_chars(char * text, size_t len)
  127. {
  128.     char * result = GC_MALLOC_ATOMIC(len + 1);
  129.     register size_t i;
  130.     
  131.     for (i = 0; i < len; i++) {
  132.        if (iscntrl(text[i])) {
  133.            result[i] = ' ';
  134.        } else {
  135.            result[i] = text[i];
  136.        }
  137.     }
  138.     result[len] = '\0';
  139.     return(result);
  140. }
  141.  
  142. /* Return the argument with all non-control-characters replaced by     */
  143. /* blank, and all control characters c replaced by c + 32.        */
  144. char * control_chars(char * text, size_t len)
  145. {
  146.     char * result = GC_MALLOC_ATOMIC(len + 1);
  147.     register size_t i;
  148.     
  149.     for (i = 0; i < len; i++) {
  150.        if (iscntrl(text[i])) {
  151.            result[i] = text[i] + 0x40;
  152.        } else {
  153.            result[i] = ' ';
  154.        }
  155.     }
  156.     result[len] = '\0';
  157.     return(result);
  158. }
  159.  
  160. int char_width;
  161. int char_height;
  162.  
  163. void get_line_rect(int line, int win_width, RECT * rectp)
  164. {
  165.     rectp -> top = line * char_height;
  166.     rectp -> bottom = rectp->top + char_height;
  167.     rectp -> left = 0;
  168.     rectp -> right = win_width;
  169. }
  170.  
  171. int caret_visible = 0;    /* Caret is currently visible.    */
  172.  
  173. int screen_was_painted = 0;/* Screen has been painted at least once.    */
  174.  
  175. void update_cursor(void);
  176.  
  177. LRESULT CALLBACK WndProc (HWND hwnd, UINT message,
  178.                           WPARAM wParam, LPARAM lParam)
  179. {
  180.    static FARPROC lpfnAboutBox;
  181.    static HANDLE  hInstance;
  182.    HDC dc;
  183.    PAINTSTRUCT ps;
  184.    RECT client_area;
  185.    RECT this_line;
  186.    RECT dummy;
  187.    TEXTMETRIC tm;
  188.    register int i;
  189.    int id;
  190.  
  191.    switch (message)
  192.    {
  193.       case WM_CREATE:
  194.            hInstance = ( (LPCREATESTRUCT) lParam)->hInstance;
  195.            lpfnAboutBox = MakeProcInstance( (FARPROC) AboutBox, hInstance );
  196.            dc = GetDC(hwnd);
  197.            SelectObject(dc, GetStockObject(SYSTEM_FIXED_FONT));
  198.            GetTextMetrics(dc, &tm);
  199.            ReleaseDC(hwnd, dc);
  200.            char_width = tm.tmAveCharWidth;
  201.            char_height = tm.tmHeight + tm.tmExternalLeading;
  202.            GetClientRect(hwnd, &client_area);
  203.              COLS = (client_area.right - client_area.left)/char_width;
  204.              LINES = (client_area.bottom - client_area.top)/char_height;
  205.              generic_init();
  206.            return(0);
  207.  
  208.       case WM_CHAR:
  209.              if (wParam == QUIT) {
  210.                  SendMessage( hwnd, WM_CLOSE, 0, 0L );
  211.              } else {
  212.                  do_command(wParam);
  213.              }
  214.              return(0);
  215.       
  216.       case WM_SETFOCUS:
  217.              CreateCaret(hwnd, NULL, char_width, char_height);
  218.              ShowCaret(hwnd);
  219.              caret_visible = 1;
  220.              update_cursor();
  221.              return(0);
  222.              
  223.       case WM_KILLFOCUS:
  224.              HideCaret(hwnd);
  225.              DestroyCaret();
  226.              caret_visible = 0;
  227.              return(0);
  228.              
  229.       case WM_LBUTTONUP:
  230.              {
  231.                  unsigned xpos = LOWORD(lParam);    /* From left    */
  232.                  unsigned ypos = HIWORD(lParam);    /* from top */
  233.                  
  234.                  set_position( xpos/char_width, ypos/char_height );
  235.                  return(0);
  236.              }
  237.              
  238.       case WM_COMMAND:
  239.              id = LOWORD(wParam);
  240.              if (id & EDIT_CMD_FLAG) {
  241.                if (id & REPEAT_FLAG) do_command(REPEAT);
  242.                do_command(CHAR_CMD(id));
  243.                return( 0 );
  244.            } else {
  245.              switch(id) {
  246.                case IDM_FILEEXIT:
  247.                   SendMessage( hwnd, WM_CLOSE, 0, 0L );
  248.                   return( 0 );
  249.  
  250.                case IDM_HELPABOUT:
  251.                   if( DialogBox( hInstance, "ABOUTBOX",
  252.                                  hwnd, lpfnAboutBox ) );
  253.                      InvalidateRect( hwnd, NULL, TRUE );
  254.                   return( 0 );
  255.            case IDM_HELPCONTENTS:
  256.                de_error(
  257.                     "Cursor keys: ^B(left) ^F(right) ^P(up) ^N(down)\n"
  258.                     "Undo: ^U    Write: ^W   Quit:^D  Repeat count: ^R[n]\n"
  259.                     "Top: ^T   Locate (search, find): ^L text ^L\n");
  260.                return( 0 );
  261.          }
  262.        }
  263.            break;
  264.  
  265.       case WM_CLOSE:
  266.            DestroyWindow( hwnd );
  267.            return 0;
  268.  
  269.       case WM_DESTROY:
  270.            PostQuitMessage (0);
  271.            return 0;
  272.       
  273.       case WM_PAINT:
  274.              dc = BeginPaint(hwnd, &ps);
  275.              GetClientRect(hwnd, &client_area);
  276.              COLS = (client_area.right - client_area.left)/char_width;
  277.              LINES = (client_area.bottom - client_area.top)/char_height;
  278.              SelectObject(dc, GetStockObject(SYSTEM_FIXED_FONT));
  279.              for (i = 0; i < LINES; i++) {
  280.                  get_line_rect(i, client_area.right, &this_line);
  281.                  if (IntersectRect(&dummy, &this_line, &ps.rcPaint)) {
  282.                      CORD raw_line = retrieve_screen_line(i);
  283.                      size_t len = CORD_len(raw_line);
  284.                      char * text = CORD_to_char_star(raw_line);
  285.                              /* May contain embedded NULLs    */
  286.                      char * plain = plain_chars(text, len);
  287.                      char * blanks = CORD_to_char_star(CORD_chars(' ',
  288.                                                      COLS - len));
  289.                      char * control = control_chars(text, len);
  290. #           define RED RGB(255,0,0)
  291.                      
  292.                      SetBkMode(dc, OPAQUE);
  293.                      SetTextColor(dc, GetSysColor(COLOR_WINDOWTEXT));
  294.                      
  295.                      TextOut(dc, this_line.left, this_line.top,
  296.                             plain, len);
  297.                      TextOut(dc, this_line.left + len * char_width, this_line.top,
  298.                             blanks, COLS - len);
  299.                      SetBkMode(dc, TRANSPARENT);
  300.                      SetTextColor(dc, RED);
  301.                      TextOut(dc, this_line.left, this_line.top,
  302.                             control, strlen(control));
  303.                  }
  304.              }
  305.              EndPaint(hwnd, &ps);
  306.              screen_was_painted = 1;
  307.              return 0;
  308.    }
  309.    return DefWindowProc (hwnd, message, wParam, lParam);
  310. }
  311.  
  312. int last_col;
  313. int last_line;
  314.  
  315. void move_cursor(int c, int l)
  316. {
  317.     last_col = c;
  318.     last_line = l;
  319.     
  320.     if (caret_visible) update_cursor();
  321. }
  322.  
  323. void update_cursor(void)
  324. {
  325.     SetCaretPos(last_col * char_width, last_line * char_height);
  326.     ShowCaret(hwnd);
  327. }
  328.  
  329. void invalidate_line(int i)
  330. {
  331.     RECT line;
  332.     
  333.     if (!screen_was_painted) return;
  334.         /* Invalidating a rectangle before painting seems result in a    */
  335.         /* major performance problem.                    */
  336.     get_line_rect(i, COLS*char_width, &line);
  337.     InvalidateRect(hwnd, &line, FALSE);
  338. }
  339.  
  340. LRESULT CALLBACK AboutBox( HWND hDlg, UINT message,
  341.                            WPARAM wParam, LPARAM lParam )
  342. {
  343.    switch( message )
  344.    {
  345.       case WM_INITDIALOG:
  346.            SetFocus( GetDlgItem( hDlg, IDOK ) );
  347.            break;
  348.  
  349.       case WM_COMMAND:
  350.            switch( wParam )
  351.            {
  352.               case IDOK:
  353.                    EndDialog( hDlg, TRUE );
  354.                    break;
  355.            }
  356.            break;
  357.  
  358.       case WM_CLOSE:
  359.            EndDialog( hDlg, TRUE );
  360.            return TRUE;
  361.  
  362.    }
  363.    return FALSE;
  364. }
  365.  
  366.