home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / NOTEPAD2.ZIP / MWND.C < prev    next >
C/C++ Source or Header  |  1989-02-08  |  19KB  |  475 lines

  1. /*
  2.  * mwnd.c -- Window management
  3.  *
  4.  * Created by Microsoft Corporation, 1989
  5.  */
  6.  
  7. #define INCL_WIN
  8. #define INCL_GPI
  9. #include <os2.h>
  10. #include <opendlg.h>
  11. #include "mle.h"
  12. #include "mtypes.h"
  13. #include "mfuncs.h"
  14.  
  15. VOID DispVScrollToIpt(PED, IPT, SHORT);
  16.  
  17. /***********************************************************************
  18. * Window procedure for MLE window
  19. ***********************************************************************/
  20.  
  21. MRESULT CALLBACK MleWndProc (HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
  22.     {
  23.     PED     ped;
  24.     RECTL   rcl;
  25.  
  26.  
  27.     if (msg >= WM_MOUSEFIRST && msg <= WM_MOUSELAST) {
  28.  
  29.         ProcessMouse (GETPED (hwnd), msg, (SHORT) LOSHORTFROMMP (mp1), (SHORT) HISHORTFROMMP (mp1));
  30.  
  31.         if (msg == WM_MOUSEMOVE)
  32.             return (TRUE);                // indicate we processed the message
  33.         }
  34.  
  35.     else switch (msg) {
  36.  
  37.         case WM_CREATE:              /* Prepare to edit an empty document */
  38.             InitInstance(hwnd);
  39.             break;
  40.  
  41.         case WM_SIZE:                /* Recalc line breaks, etc. */
  42.             ped = GETPED(hwnd);
  43.             DispChangeSize(ped,LOSHORTFROMMP(mp2),HISHORTFROMMP(mp2));
  44.             break;
  45.  
  46.         case WM_SETFOCUS:            /* Receive or lose input focus */
  47.                 SetFocus(GETPED(hwnd), LOSHORTFROMMP(mp2));
  48.                 break;
  49.  
  50.  
  51.         case WM_PAINT:
  52.             ped = GETPED (hwnd);
  53.             WinBeginPaint(hwnd, ped->hps, &rcl);
  54.             WinEndPaint(ped->hps);
  55.             DispRefresh(ped, TRUE, rcl);
  56.             break;
  57.  
  58.  
  59.         case WM_CHAR:                /* Process keyboard input */
  60.  
  61.             if (! (LONGFROMMP(mp1) & KC_KEYUP)) { // if key's not just being released
  62.  
  63.                 ped = GETPED(hwnd);
  64.                 ProcessKey (ped, HISHORTFROMMP (mp2),
  65.                         LOSHORTFROMMP (mp2), LOSHORTFROMMP(mp1),
  66.                         (SHORT) LOUCHAR (HISHORTFROMMP (mp1)));
  67.                 ZeroRect(rcl);
  68.                 DispRefresh(ped, FALSE, rcl);
  69.                 return (TRUE);  // indicate we processed the message
  70.                 }
  71.                 break;
  72.  
  73.  
  74.         case WM_TIMER:               // timer message
  75.  
  76.             // Timer message for mouse scrolling
  77.             if ((SHORT)LOSHORTFROMMP(mp1) == TID_MOUSESCROLL) {
  78.                 POINTL ptl;
  79.                 WinQueryMsgPos((HAB) NULL, &ptl);
  80.                 WinMapWindowPoints(HWND_DESKTOP, hwnd, &ptl, 1);
  81.                 ProcessMouse(GETPED(hwnd),msg,(SHORT)ptl.x,(SHORT)ptl.y);
  82.             } else // some system timer
  83.                 return WinDefWindowProc(hwnd, msg, mp1, mp2);
  84.  
  85.             break;
  86.  
  87.  
  88.         case WM_HSCROLL:    // scroll bar message, forwarded from frame window
  89.  
  90.             // The rule here is the same as for vertical scroll: we can
  91.             // scroll right until the end of the longest line is about
  92.             // to disappear (i.e., its last character is still visible).
  93.             // The "longest line" here means the longest line in the document
  94.             // that we know about, i.e., with length pixCurMax.
  95.  
  96.             ped = GETPED (hwnd);
  97.             switch (HISHORTFROMMP (mp2)) {       /* which message? */
  98.                 case SB_LINELEFT:
  99.                     DispHScroll(ped, -(DISPLAY_SCROLLACWS*ped->AveCharWidth),
  100.                                 TRUE);
  101.                     break;
  102.                 case SB_LINERIGHT:
  103.                     DispHScroll(ped,DISPLAY_SCROLLACWS*ped->AveCharWidth,TRUE);
  104.                     break;
  105.                 case SB_PAGELEFT:
  106.                     DispHScroll(ped, -(DispWidth(ped)/2), TRUE);
  107.                     break;
  108.                 case SB_PAGERIGHT:
  109.                     DispHScroll(ped, +(DispWidth(ped)/2), TRUE);
  110.                     break;
  111.                 case SB_SLIDERTRACK:
  112.                 case SB_SLIDERPOSITION:
  113.                     DispHScrollTo(ped, ((ped->pixCurMax - ped->AveCharWidth) *
  114.                             (LOSHORTFROMMP (mp2) - SLIDER_MIN)) /
  115.                             (SLIDER_MAX - SLIDER_MIN),
  116.                             (HISHORTFROMMP(mp2) == SB_SLIDERPOSITION));
  117.                     break;
  118.                 default:
  119.                     return (0L);              /* do nothing */
  120.                 }
  121.             break;
  122.  
  123.  
  124.         case WM_VSCROLL:   // scroll bar message, forwarded from frame window
  125.             ped = GETPED (hwnd);
  126.             switch (HISHORTFROMMP (mp2)) {
  127.                 case SB_LINEUP:
  128.                     DispVScroll(ped, (LINE) -1,TRUE);
  129.                     break;
  130.  
  131.                 case SB_LINEDOWN:
  132.                     DispVScroll(ped, (LINE) 1,TRUE);
  133.                     break;
  134.  
  135.                 case SB_PAGEUP:
  136.                     DispVScroll(ped, (LINE)(-DispHeight(ped)+1), TRUE);
  137.                     break;
  138.  
  139.                 case SB_PAGEDOWN:
  140.                     DispVScroll(ped, (LINE)(DispHeight(ped)-1), TRUE);
  141.                     break;
  142.  
  143.                 case SB_SLIDERTRACK:
  144.                 case SB_SLIDERPOSITION:
  145.                     // The user's moved the slider.  If the new slider
  146.                     // position is 75 on a scale of 0 to 100 (for example),
  147.                     // we find the line containing the 75% point of the
  148.                     // document.  Note that this is not quite the inverse of
  149.                     // the method NotifyScroll uses to find the slider
  150.                     // position from the text in the document, since to get
  151.                     // that right we'd need to know the length of the line we
  152.                     // were trying to scroll to.  This is OK because
  153.                     // our method here still has the following properties:
  154.                     // (1) If the slider hasn't moved at all, we're guaranteed
  155.                     // to stay in the same place, and (2) if the slider's
  156.                     // moved to the top or bottom, we're guaranteed to go to
  157.                     // the first or last line of the document.  Anyway, we're
  158.                     // going to send back a new slider position based on the
  159.                     // ipt we actually do move to.
  160.                     {
  161.                             IPT ul;
  162.  
  163.                             ul = (ped->iptMac*(LOSHORTFROMMP(mp2)-SLIDER_MIN))
  164.                                     / (SLIDER_MAX - SLIDER_MIN);
  165.                             DispVScrollToIpt(ped, ul,
  166.                                     (HISHORTFROMMP(mp2)==SB_SLIDERPOSITION));
  167.                             break;
  168.                     }
  169.  
  170.                 default:
  171.                     return (0L);              /* return w/o doing anything */
  172.                 }
  173.             break;
  174.  
  175.         case EM_SETTEXTLIMIT:
  176.                 return(TxtSetLimit(GETPED(hwnd),LONGFROMMP(mp1)));
  177.  
  178.         case EM_QTL:                 /* query text length */
  179.                 return(MRFROMLONG(TxtLength(GETPED (hwnd))));
  180.  
  181.         case EM_CHARFROMLINE:       /* return ipt given absolute line # */
  182.             return(0L);
  183.  
  184.         case EM_LINEFROMCHAR:       /* return abs line # containing ipt */
  185.                 return(0L);
  186.  
  187.         case EM_SETWRAP:             /* turn word wrap on or off */
  188.  
  189.             ped  = GETPED(hwnd);
  190.             TxtSetWordWrap(ped,(BOOL) (!! (LOSHORTFROMMP (mp1))));
  191.             DispRefresh(ped,FALSE,ped->rclWnd);
  192.             break;
  193.  
  194.         case EM_QUERYFONT:           /* Return current font information */
  195.  
  196.             /* Send back the current pfattrs entry to the caller.
  197.                Note that this can be NULL, which indicates the default
  198.                system font, whatever it may be. */
  199.             return (MRESULT) (GETPED (hwnd))->pfattrs;
  200.  
  201.  
  202.         case EM_SETFONT:             /* Set the current font */
  203.  
  204.             /* This sets the font that the MLE window uses, based on
  205.                the font information contained within the fattr that the
  206.                caller provides.  GpiCreateLogFont will be called using this
  207.                fattr, so it should be set up accordingly.  The return value
  208.                is the same as for EM_QUERYFONT, so the caller should compare
  209.                this to the intended result to verify success. */
  210.             ped = GETPED (hwnd);
  211.  
  212.             DispChangeFont(ped, (PFATTRS) PVOIDFROMMP (mp1));
  213.             DispChangeSize(ped, (USHORT) ped->rclWnd.xRight,
  214.                            (USHORT) ped->rclWnd.yTop);
  215.             DispRefresh(ped,TRUE,ped->rclWnd);
  216.             return (MRESULT) ped->pfattrs;
  217.  
  218.  
  219.         case EM_QUERYSEL:            /* What's currently selected? */
  220.  
  221.             /* Based on the last 3 bits of mp1, return:
  222.  
  223.                   0   MAKEULONG (min ipt of selection, max ipt of selection)
  224.                        Rounds down to 65535 if over.  This is the format
  225.                        supported by Windows MLE and PM SLE.
  226.                   1   min ipt of selection
  227.                   2   max ipt of selection
  228.                   3   starting ipt of selection (anchor point)
  229.                   4   ending ipt of selection (cursor point)
  230.                   5   }
  231.                   6   } undefined (reserved)
  232.                   7   }
  233.             */
  234.             {
  235.                 IPT  iptCursor, iptAnchor;
  236.  
  237.                 ped = GETPED (hwnd);
  238.                 iptCursor = TxtQueryCursor(ped);
  239.                 iptAnchor = TxtQueryAnchor(ped);
  240.                 switch ((USHORT) mp1 & 0x0007) {
  241.                     case 0:
  242.                         if (iptCursor > 65535) iptCursor = 65535;
  243.                         if (iptAnchor > 65535) iptAnchor = 65535;
  244.                         if (iptCursor <= iptAnchor)
  245.                             return (MRFROM2SHORT (iptCursor, iptAnchor));
  246.                         else
  247.                             return (MRFROM2SHORT (iptAnchor, iptCursor));
  248.                     case 1:
  249.                         return (MRFROMLONG (min (iptCursor, iptAnchor)));
  250.                     case 2:
  251.                         return (MRFROMLONG (max (iptCursor, iptAnchor)));
  252.                     case 3:
  253.                         return (MRFROMLONG (iptAnchor));
  254.                     case 4:
  255.                         return (MRFROMLONG (iptCursor));
  256.                     default:
  257.                         return ((MRESULT) 0);
  258.                     }
  259.                 }
  260.  
  261.  
  262.         case EM_SETSEL:              /* set the selection */
  263.  
  264.             /* mp1 specifies the anchor point, mp2 the cursor
  265.                point.  If both are valid insertion points, set the selection
  266.                and return TRUE; otherwise return FALSE.
  267.  
  268.                Note that LONGFROMMP actually returns a ULONG.
  269.             */
  270.  
  271.             ped = GETPED (hwnd);
  272.             if (((LONG)(mp1)>ped->iptMac) || ((LONG)(mp2)>ped->iptMac)) {
  273.                     return ((MRESULT) FALSE);
  274.             } else {
  275.                     TxtSetAnchorCursor(ped, (LONG)mp1, (LONG)mp2);
  276.                     ZeroRect(rcl);
  277.                     DispRefresh(ped,FALSE,rcl);
  278.                     return ((MRESULT) TRUE);
  279.             }
  280.  
  281.  
  282.         case EM_QUERYCHANGED:
  283.  
  284.             // If the text has been changed since the last EM_QUERYCHANGED
  285.             // or WM_QUERYWINDOWPARAMS message, return TRUE, otherwise FALSE.
  286.             // As a side effect, set fChanged to FALSE.
  287.  
  288.             return((MRESULT)TxtSetChanged(GETPED(hwnd), FALSE));
  289.  
  290.  
  291.         case EM_SETCHANGED:
  292.                 // sets the 'changed' flag to a particular value.
  293.                 return((MRESULT)TxtSetChanged(GETPED(hwnd), (BOOL)mp1));
  294.  
  295.  
  296.         case EM_QUERYTYPING:
  297.  
  298.                 // returns the 'typing allowed' flag
  299.                 return(QueryTyping(GETPED(hwnd)));
  300.  
  301.         case EM_SETTYPING:
  302.  
  303.                 // sets or clears the 'typing allowed' flag
  304.                 return(SetTyping(GETPED(hwnd),(BOOL)mp1));
  305.  
  306.  
  307.         case EM_QUERYTABSIZE:
  308.  
  309.                 // returns the current tab size
  310.                 return(QueryTabWidth(GETPED(hwnd)));
  311.  
  312.         case EM_SETTABSIZE:
  313.         {
  314.                 PIX TabSize;
  315.  
  316.                 // sets or clears the 'typing allowed' flag
  317.                 ped = GETPED(hwnd);
  318.                 TabSize = SetTabWidth(ped, SHORT1FROMMP(mp1));
  319.                 TxtReformat(ped, ped->pprHead, TRUE);
  320.                 ZeroRect(rcl);
  321.                 DispRefresh(ped,FALSE,rcl);
  322.                 return(MRFROMLONG(TabSize));
  323.         }
  324.  
  325.         case EM_CLEAR:               /* Clear the current selection. */
  326.             ped = GETPED(hwnd);
  327.             return(TxtClipClear(ped,
  328.                             TxtQueryAnchor(ped),
  329.                             TxtQueryCursor(ped)));
  330.  
  331.         case EM_CUT:            /* cut selection to clipboard */
  332.             ped = GETPED(hwnd);
  333.             return(TxtClipCut(ped,
  334.                             TxtQueryAnchor(ped),
  335.                             TxtQueryCursor(ped)));
  336.  
  337.         case EM_COPY:           /* copy selection to clipboard */
  338.             ped = GETPED(hwnd);
  339.             return(TxtClipCopy(ped,
  340.                             TxtQueryAnchor(ped),
  341.                             TxtQueryCursor(ped)));
  342.  
  343.         case EM_PASTE:          /* paste into selection from clipboard */
  344.             ped = GETPED(hwnd);
  345.             return(TxtClipPaste(ped,
  346.                             TxtQueryAnchor(ped),
  347.                             TxtQueryCursor(ped)));
  348.  
  349.         case EM_FORMAT:         // set the transfer format
  350.                 return(BufSetFormat(GETPED(hwnd),SHORT1FROMMP(mp1)));
  351.  
  352.         case EM_SETIMPORTEXPORT:        // set block buffer
  353.                 return(BufSetBuf(GETPED(hwnd),
  354.                                  PVOIDFROMMP(mp1),
  355.                                  SHORT1FROMMP(mp2)));
  356.  
  357.         case EM_IMPORT:        // insert a buffer
  358.  
  359.             /* Insert at mp1 the block of mp2 chars from the block
  360.              * buffer.  Return TRUE iff successful.
  361.              *
  362.              * We don't ensure that the cursor's visible when we're done; the
  363.              * caller may send an EM_SETSEL if it does want the text to be
  364.              * scrolled.
  365.              */
  366.                 ped = GETPED(hwnd);
  367.                 return(BufCopyIn(ped,
  368.                         LONGFROMMP(mp1),
  369.                         LONGFROMMP(mp1),
  370.                         BufQueryBuf(ped),
  371.                         min(SHORT1FROMMP(mp2), BufQueryBufSize(ped))));
  372.  
  373.  
  374.         case EM_EXPORT:        // copy a block of text into the block buffer
  375.  
  376.             /* Copy into the block buffer the block that starts at insertion
  377.              * point mp1 and continues for mp2 characters.  Return
  378.              * TRUE iff successful.
  379.              */
  380.             ped = GETPED (hwnd);
  381.             return(BufCopyOut(ped,
  382.                               LONGFROMMP(mp1),
  383.                               BufQueryFormat(ped),
  384.                               BufQueryBuf(ped),
  385.                               BufQueryBufSize(ped)));
  386.  
  387.  
  388.         case EM_DELETE:       // delete a block
  389.  
  390.             /* Delete the block that starts at the insertion point mp1
  391.              * and continues for mp2 characters.  Return TRUE iff
  392.              * successful.
  393.              *
  394.              * We don't ensure that the cursor's visible when we're done; the
  395.              * caller may send an EM_SETSEL if it does want the text to be
  396.              * scrolled.
  397.              */
  398.                 ped = GETPED(hwnd);
  399.                 if (LONGFROMMP(mp1)+LONGFROMMP(mp2)>TxtLength(ped)) {
  400.                         return(FALSE);
  401.                 }
  402.                 return(TxtChange(ped,
  403.                           LONGFROMMP(mp1),
  404.                           LONGFROMMP(mp1)+LONGFROMMP(mp2),
  405.                           NULL,
  406.                           0));
  407.  
  408.         case EM_REPLACE:   // replace a block with buffer contents
  409.  
  410.             /* replace the block that starts at the insertion point mp1
  411.              * and continues for mp2 characters with the contents of the
  412.              * transfer buffer.  Return TRUE iff successful.
  413.              *
  414.              * We don't ensure that the cursor's visible when we're done; the
  415.              * caller may send an EM_SETSEL if it does want the text to be
  416.              * scrolled.
  417.              */
  418.                 ped = GETPED(hwnd);
  419.                 if (LONGFROMMP(mp1)+LONGFROMMP(mp2)>TxtLength(ped)) {
  420.                         return(FALSE);
  421.                 }
  422.                 return(BufCopyIn(ped,
  423.                                 LONGFROMMP(mp1),
  424.                                 LONGFROMMP(mp1)+LONGFROMMP(mp2),
  425.                                 BufQueryBuf(ped),
  426.                                 BufQueryBufSize(ped)));
  427.  
  428.  
  429.         case EM_GETTEXT:           /* get a block of text */
  430.  
  431.             /* Return a pointer to a block of text.  mp1 specifies the
  432.                ipt of the block beginning; mp2 points to a USHORT in
  433.                which the length of the block will be returned.
  434.  
  435.                If mp1 >= iptMac, the routine will return NULL and
  436.                set *mp2 to 0.  Otherwise *mp2 is guaranteed to be
  437.                at least 1.
  438.  
  439.                Note that LONGFROMMP actually returns a ULONG.
  440.             */
  441.                 ped = GETPED (hwnd);
  442.  
  443.                 if (LONGFROMMP (mp1) >= TxtLength(ped)) {
  444.                         *((PUSHORT) PVOIDFROMMP(mp2)) = 0;
  445.                         return (MRFROMP (NULL));
  446.                 } else {
  447.                         PPR ppr;
  448.                         IPT ipt;
  449.  
  450.                         ipt = LONGFROMMP(mp1);
  451.                         ppr = TxtPPROfIpt(ped, &ipt);
  452.                         if (fIsMarker(ppr)) {
  453.                                 ppr = SkipMarkers(ppr, MARKER_ANY);
  454.                                 ipt = 0;
  455.                         }
  456.                         *((PUSHORT)PVOIDFROMMP(mp2))=ppr->cchText-(USHORT)ipt;
  457.                         return(MRFROMP(ppr->pchText + ipt));
  458.                 }
  459.  
  460.  
  461.         case WM_DESTROY:             /* window is about to be destroyed */
  462.  
  463.             ped = GETPED (hwnd);
  464.  
  465.             GpiDestroyRegion (ped->hps, ped->hrgnT);  /* destroy region temp variable associated with PS */
  466.             GpiDestroyPS (ped->hps);                  /* destroy its PS */
  467.             break;
  468.  
  469.         default:
  470.             return WinDefWindowProc (hwnd, msg, mp1, mp2);
  471.         }
  472.  
  473.     return(0L);
  474.     }
  475.