home *** CD-ROM | disk | FTP | other *** search
/ Microsoft Programmer's Library 1.3 / Microsoft-Programers-Library-v1.3.iso / sampcode / prog_pm / chap15 / typeclip.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-01-09  |  14.4 KB  |  371 lines

  1. /*--------------------------------------------
  2.    TYPECLIP.C -- Clipboard Text Demonstration
  3.   --------------------------------------------*/
  4.  
  5. #define INCL_WIN
  6. #define INCL_VIO
  7. #define INCL_AVIO
  8. #include <os2.h>
  9. #include <stdlib.h>
  10. #include "typeclip.h"
  11.  
  12. #define WM_ADJUST_ORG     (WM_USER + 0)
  13. #define WM_SET_BLOCKOUT   (WM_USER + 1)
  14. #define WM_CLEAR_BLOCKOUT (WM_USER + 2)
  15.  
  16. MRESULT EXPENTRY ClientWndProc (HWND, USHORT, MPARAM, MPARAM) ;
  17.  
  18. HAB  hab ;
  19.  
  20. int main (void)
  21.      {
  22.      static CHAR  szClientClass [] = "TypeClip" ;
  23.      static ULONG flFrameFlags = FCF_TITLEBAR      | FCF_SYSMENU  |
  24.                                  FCF_SIZEBORDER    | FCF_MINMAX   |
  25.                                  FCF_SHELLPOSITION | FCF_TASKLIST |
  26.                                  FCF_MENU          | FCF_ACCELTABLE ;
  27.      HMQ          hmq ;
  28.      HWND         hwndFrame, hwndClient ;
  29.      QMSG         qmsg ;
  30.  
  31.      hab = WinInitialize (0) ;
  32.      hmq = WinCreateMsgQueue (hab, 0) ;
  33.  
  34.      WinRegisterClass (hab, szClientClass, ClientWndProc, 0L, 0) ;
  35.  
  36.      hwndFrame = WinCreateStdWindow (HWND_DESKTOP, WS_VISIBLE,
  37.                                      &flFrameFlags, szClientClass, NULL,
  38.                                      0L, NULL, ID_RESOURCE, &hwndClient) ;
  39.  
  40.      WinSendMsg (hwndFrame, WM_SETICON,
  41.                  WinQuerySysPointer (HWND_DESKTOP, SPTR_APPICON, FALSE),
  42.                  NULL) ;
  43.  
  44.      while (WinGetMsg (hab, &qmsg, NULL, 0, 0))
  45.           WinDispatchMsg (hab, &qmsg) ;
  46.  
  47.      WinDestroyWindow (hwndFrame) ;
  48.      WinDestroyMsgQueue (hmq) ;
  49.      WinTerminate (hab) ;
  50.      return 0 ;
  51.      }
  52.  
  53. MRESULT EXPENTRY ClientWndProc (HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
  54.      {
  55.      static BOOL  fCapture, fValidBlock ;
  56.      static HPS   hps ;
  57.      static HVPS  hvps ;
  58.      static HWND  hwndMenu ;
  59.      static LONG  cxChar, cyChar ;
  60.      static SHORT cxClient, cyClient, cxVioSize, cyVioSize,
  61.                   xBlockBeg, yBlockBeg, xBlockEnd, yBlockEnd,
  62.                   xBeg , yBeg, xEnd, yEnd ;
  63.      CHAR         *pchText ;
  64.      HDC          hdc ;
  65.      PCHAR        pchClipText ;
  66.      RECTL        rcl ;
  67.      SEL          selClipText ;
  68.      SHORT        sRep, sLen, x, y, s,
  69.                   xCursor, yCursor, xOrigin, yOrigin ;
  70.      SIZEL        sizl ;
  71.      USHORT       usfInfo ;
  72.  
  73.      switch (msg)
  74.           {
  75.                               /*---------------------------------------
  76.                                  Create, paint, and destroy processing
  77.                                 ---------------------------------------*/
  78.           case WM_CREATE:
  79.                hdc = WinOpenWindowDC (hwnd) ;
  80.  
  81.                DevQueryCaps (hdc, CAPS_CHAR_WIDTH,  1L, &cxChar) ;
  82.                DevQueryCaps (hdc, CAPS_CHAR_HEIGHT, 1L, &cyChar) ;
  83.  
  84.                cxVioSize = (SHORT) (WinQuerySysValue (HWND_DESKTOP,
  85.                                         SV_CXFULLSCREEN) / cxChar) ;
  86.  
  87.                cyVioSize = (SHORT) (WinQuerySysValue (HWND_DESKTOP,
  88.                                         SV_CYFULLSCREEN) / cyChar) ;
  89.  
  90.                sizl.cx = sizl.cy = 0 ;
  91.                hps = GpiCreatePS (hab, hdc, &sizl, PU_PELS    | GPIF_DEFAULT |
  92.                                                    GPIT_MICRO | GPIA_ASSOC) ;
  93.  
  94.                VioCreatePS (&hvps, cyVioSize, cxVioSize, 0, 1, NULL) ;
  95.                VioAssociate (hdc, hvps) ;
  96.  
  97.                hwndMenu = WinWindowFromID (
  98.                                 WinQueryWindow (hwnd, QW_PARENT, FALSE),
  99.                                 FID_MENU) ;
  100.                return 0 ;
  101.  
  102.           case WM_PAINT:
  103.                WinBeginPaint (hwnd, hps, NULL) ;
  104.  
  105.                WinQueryWindowRect (hwnd, &rcl) ;
  106.                WinFillRect (hps, &rcl, CLR_BLACK) ;
  107.  
  108.                VioShowBuf (0, cxVioSize * cyVioSize * 2, hvps) ;
  109.  
  110.                WinEndPaint (hps) ;
  111.                return 0 ;
  112.  
  113.           case WM_DESTROY:
  114.                VioAssociate (NULL, hvps) ;
  115.                VioDestroyPS (hvps) ;
  116.                GpiDestroyPS (hps) ;
  117.                return 0 ;
  118.                               /*-------------------------------------------
  119.                                  Window size, keyboard and origin handling
  120.                                 -------------------------------------------*/
  121.           case WM_SIZE:
  122.                WinDefAVioWindowProc (hwnd, msg, mp1, mp2) ;
  123.  
  124.                cxClient = SHORT1FROMMP (mp2) ;
  125.                cyClient = SHORT2FROMMP (mp2) ;
  126.  
  127.                VioSetOrg (0, 0, hvps) ;
  128.                WinSendMsg (hwnd, WM_ADJUST_ORG, NULL, NULL) ;
  129.                return 0 ;
  130.  
  131.           case WM_CHAR:
  132.                if (!(CHARMSG(&msg)->fs & KC_CHAR)        ||
  133.                     (CHARMSG(&msg)->fs & KC_KEYUP)       ||
  134.                     (CHARMSG(&msg)->fs & KC_INVALIDCHAR) ||
  135.                     (CHARMSG(&msg)->fs & KC_DEADKEY))
  136.                          return 0 ;
  137.  
  138.                for (sRep = 0 ; sRep < CHARMSG(&msg)->cRepeat ; sRep++)
  139.                     {
  140.                     VioWrtTTY ((PCHAR) & CHARMSG(&msg)->chr, 1, hvps) ;
  141.  
  142.                     switch (CHARMSG(&msg)->chr)
  143.                          {
  144.                          case '\b':                         // Backspace
  145.                               VioWrtTTY (" \b", 2, hvps) ;
  146.                               break ;
  147.  
  148.                          case '\r':                         // Return
  149.                               VioWrtTTY ("\n", 1, hvps) ;
  150.                               break ;
  151.                          }
  152.                     }
  153.                WinSendMsg (hwnd, WM_ADJUST_ORG, NULL, NULL) ;
  154.                return 1 ;
  155.  
  156.           case WM_ADJUST_ORG:
  157.                VioGetOrg    (&yOrigin, &xOrigin, hvps) ;
  158.                VioGetCurPos (&yCursor, &xCursor, hvps) ;
  159.  
  160.                if (xCursor < xOrigin)
  161.                     xOrigin = xCursor ;
  162.  
  163.                else if (xCursor >= xOrigin + cxClient / (SHORT) cxChar)
  164.                     xOrigin = xCursor - cxClient / (SHORT) cxChar + 1 ;
  165.  
  166.                if (yCursor < yOrigin)
  167.                     yOrigin = yCursor ;
  168.  
  169.                else if (yCursor >= yOrigin + cyClient / (SHORT) cyChar)
  170.                     yOrigin = yCursor - cyClient / (SHORT) cyChar + 1 ;
  171.  
  172.                VioSetOrg (yOrigin, xOrigin, hvps) ;
  173.                return 0 ;
  174.                               /*-----------------------------
  175.                                  Mouse and blockout handling
  176.                                 -----------------------------*/
  177.           case WM_BUTTON1DOWN:
  178.                x = MOUSEMSG(&msg)->x / (SHORT) cxChar ;
  179.                y = (cyClient - MOUSEMSG(&msg)->y) / (SHORT) cyChar ;
  180.  
  181.                WinSendMsg (hwnd, WM_CLEAR_BLOCKOUT, NULL, NULL) ;
  182.  
  183.                WinSetCapture (HWND_DESKTOP, hwnd) ;
  184.                fCapture = TRUE ;
  185.                fValidBlock = FALSE ;
  186.  
  187.                VioGetOrg (&yOrigin, &xOrigin, hvps) ;
  188.  
  189.                xBlockBeg = xOrigin + x ;
  190.                yBlockBeg = yOrigin + y ;
  191.  
  192.                WinSendMsg (hwnd, WM_SET_BLOCKOUT, mp1, mp2) ;
  193.                break ;
  194.  
  195.           case WM_MOUSEMOVE:
  196.                if (fCapture)
  197.                     WinSendMsg (hwnd, WM_SET_BLOCKOUT, mp1, mp2) ;
  198.                break ;
  199.  
  200.           case WM_BUTTON1UP:
  201.                if (fCapture)
  202.                     {
  203.                     WinSetCapture (HWND_DESKTOP, NULL) ;
  204.                     fCapture = FALSE ;
  205.                     fValidBlock = TRUE ;
  206.  
  207.                     WinSendMsg (hwnd, WM_SET_BLOCKOUT, mp1, mp2) ;
  208.                     }
  209.                return 1 ;
  210.  
  211.           case WM_SET_BLOCKOUT:
  212.                x = MOUSEMSG(&msg)->x / (SHORT) cxChar ;
  213.                y = (cyClient - MOUSEMSG(&msg)->y) / (SHORT) cyChar ;
  214.  
  215.                VioGetOrg (&yOrigin, &xOrigin, hvps) ;
  216.  
  217.                xBlockEnd = xOrigin + x ;
  218.                yBlockEnd = yOrigin + y ;
  219.  
  220.                if (cxVioSize * yBlockBeg + xBlockBeg <
  221.                    cxVioSize * yBlockEnd + xBlockEnd)
  222.                     {
  223.                     xBeg = xBlockBeg ;
  224.                     yBeg = yBlockBeg ;
  225.                     xEnd = xBlockEnd ;
  226.                     yEnd = yBlockEnd ;
  227.                     }
  228.                else
  229.                     {
  230.                     xBeg = xBlockEnd ;
  231.                     yBeg = yBlockEnd ;
  232.                     xEnd = xBlockBeg ;
  233.                     yEnd = yBlockBeg ;
  234.                     }
  235.  
  236.                VioWrtNAttr ("\x07", cxVioSize * yBeg + xBeg, 0, 0, hvps) ;
  237.  
  238.                VioWrtNAttr ("\x70",  cxVioSize * yEnd + xEnd -
  239.                                     (cxVioSize * yBeg + xBeg) + 1,
  240.                                     yBeg, xBeg, hvps) ;
  241.  
  242.                VioWrtNAttr ("\x07",  cxVioSize * cyVioSize -
  243.                                     (cxVioSize * yEnd + xEnd) - 1,
  244.                                     yEnd, xEnd + 1, hvps) ;
  245.                break ;
  246.  
  247.           case WM_CLEAR_BLOCKOUT:
  248.                VioWrtNAttr ("\x07", cxVioSize * cyVioSize, 0, 0, hvps) ;
  249.                fValidBlock = FALSE ;
  250.                break ;
  251.                               /*--------------------
  252.                                  Clipboard handling
  253.                                 --------------------*/
  254.           case WM_INITMENU:
  255.                switch (SHORT1FROMMP (mp1))
  256.                     {
  257.                     case IDM_EDIT:
  258.                          WinSendMsg (hwndMenu, MM_SETITEMATTR,
  259.                                      MPFROM2SHORT (IDM_CUT, TRUE),
  260.                                      MPFROM2SHORT (MIA_DISABLED,
  261.                                           fValidBlock ? 0 : MIA_DISABLED)) ;
  262.  
  263.                          WinSendMsg (hwndMenu, MM_SETITEMATTR,
  264.                                      MPFROM2SHORT (IDM_COPY, TRUE),
  265.                                      MPFROM2SHORT (MIA_DISABLED,
  266.                                           fValidBlock ? 0 : MIA_DISABLED)) ;
  267.  
  268.                          WinSendMsg (hwndMenu, MM_SETITEMATTR,
  269.                                      MPFROM2SHORT (IDM_CLEAR, TRUE),
  270.                                      MPFROM2SHORT (MIA_DISABLED,
  271.                                           fValidBlock ? 0 : MIA_DISABLED)) ;
  272.  
  273.                          WinSendMsg (hwndMenu, MM_SETITEMATTR,
  274.                                      MPFROM2SHORT (IDM_PASTE, TRUE),
  275.                                      MPFROM2SHORT (MIA_DISABLED,
  276.                               WinQueryClipbrdFmtInfo (hab, CF_TEXT, &usfInfo)
  277.                                              ? 0 : MIA_DISABLED)) ;
  278.                          return 0 ;
  279.                     }
  280.                break ;
  281.  
  282.           case WM_COMMAND:
  283.                switch (COMMANDMSG(&msg)->cmd)
  284.                     {
  285.                     case IDM_CUT:
  286.                     case IDM_COPY:
  287.                          if (!fValidBlock)
  288.                               return 0 ;
  289.                                                        // Copy text to
  290.                                                        // malloc'ed memory
  291.  
  292.                          sLen = (cxVioSize + 2) * (yEnd - yBeg + 1) + 1 ;
  293.                          pchText = malloc (sLen) ;
  294.  
  295.                          for (s = 0, y = yBeg ; y <= yEnd ; y++)
  296.                               {
  297.                               x    = (y == yBeg ? xBeg : 0) ;
  298.                               sLen = (y == yEnd ? xEnd + 1 : cxVioSize) - x ;
  299.  
  300.                               VioReadCharStr (pchText + s, &sLen,
  301.                                               y, x, hvps) ;
  302.  
  303.                               s += sLen ;
  304.                               while (--s >= 0 && pchText[s] == ' ') ;
  305.  
  306.                               s++ ;
  307.                               pchText[s++] = '\r' ;
  308.                               pchText[s++] = '\n' ;
  309.                               }
  310.                          pchText[s++] = '\0' ;         // s is string length
  311.  
  312.                                                        // Allocate memory block
  313.  
  314.                          DosAllocSeg (s, &selClipText, SEG_GIVEABLE) ;
  315.                          pchClipText = MAKEP (selClipText, 0) ;
  316.  
  317.                                                        // Copy to giveable seg
  318.  
  319.                          for (s = 0 ; pchClipText[s] = pchText[s] ; s++) ;
  320.                          free (pchText) ;
  321.                                                        // Set clipboard data
  322.                          WinOpenClipbrd (hab) ;
  323.                          WinEmptyClipbrd (hab) ;
  324.                          WinSetClipbrdData (hab, (ULONG) selClipText,
  325.                                                  CF_TEXT, CFI_SELECTOR) ;
  326.                          WinCloseClipbrd (hab) ;
  327.                                                        // Clear blockout
  328.  
  329.                          if (COMMANDMSG(&msg)->cmd == IDM_COPY)
  330.                               {
  331.                               WinSendMsg (hwnd, WM_CLEAR_BLOCKOUT, NULL, NULL);
  332.                               return 0 ;
  333.                               }
  334.                                              // fall through for IDM_CUT
  335.                     case IDM_CLEAR:
  336.                          if (!fValidBlock)
  337.                               return 0 ;
  338.                                                        // Clear selection
  339.  
  340.                          VioWrtNCell (" \x07",  cxVioSize * yEnd + xEnd -
  341.                                                (cxVioSize * yBeg + xBeg) + 1,
  342.                                                yBeg, xBeg, hvps) ;
  343.                          fValidBlock = FALSE ;
  344.                          return 0 ;
  345.  
  346.                     case IDM_PASTE:
  347.                                         // Get text selector from clipboard
  348.  
  349.                          WinOpenClipbrd (hab) ;
  350.                          selClipText = (SEL) WinQueryClipbrdData (hab,
  351.                                                                   CF_TEXT) ;
  352.                                         // Display to screen
  353.  
  354.                          if (selClipText != 0)
  355.                               {
  356.                               pchClipText = MAKEP (selClipText, 0) ;
  357.  
  358.                               for (sLen = 0 ; pchClipText[sLen] ; sLen++) ;
  359.  
  360.                               VioWrtTTY (pchClipText, sLen, hvps) ;
  361.                               }
  362.                          WinCloseClipbrd (hab) ;
  363.  
  364.                          WinSendMsg (hwnd, WM_ADJUST_ORG, NULL, NULL) ;
  365.                          return 0 ;
  366.                     }
  367.                break ;
  368.           }
  369.      return WinDefWindowProc (hwnd, msg, mp1, mp2) ;
  370.      }
  371.