home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / shapw102.zip / shpwn102.zip / treyes.c < prev    next >
C/C++ Source or Header  |  1998-09-22  |  18KB  |  730 lines

  1. /*
  2.  * treyes.c - eyes watches mouse pointer with shape window
  3.  */
  4.  
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #include <math.h>
  9.  
  10. #define INCL_PM
  11. #include <os2.h>
  12.  
  13. #include "shapewin.h"
  14.  
  15. #include "treyes.h"
  16. #include "treyeres.h"
  17.  
  18. /*
  19.  * Uses two window for control transparent bitmap
  20.  */
  21.  
  22. HWND    hwndFrame = NULLHANDLE ;    /* Invisible Frame Window       */
  23. HWND    hwndShape = NULLHANDLE ;    /* Shape Window for Eye Image   */
  24.  
  25. /*
  26.  * Uses Memory DC/PS and Bitmap to manage eye image
  27.  */
  28.  
  29. HDC     hdcMem = NULLHANDLE ;
  30. HPS     hpsMem = NULLHANDLE ;
  31. HBITMAP hbmMem = NULLHANDLE ;
  32.  
  33. /*
  34.  * myname - adjust and save program names
  35.  */
  36.  
  37. UCHAR   ProgramPath[256] ;
  38. UCHAR   ProgramName[256] ;
  39.  
  40. static  void    myname(PSZ me)
  41. {
  42.     PUCHAR  p, last ;
  43.  
  44.     /*
  45.      * full pathname of program
  46.      */
  47.  
  48.     for (p = me, last = NULL ; *p ; p++) {
  49.         if (*p == '/' || *p == '\\') {
  50.             last = p ;
  51.         }
  52.     }
  53.     if (last != NULL) {
  54.         strcpy(ProgramPath, me) ;
  55.     } else if (DosSearchPath(7, "PATH", me, ProgramPath, 256) != 0) {
  56.         strcpy(ProgramPath, me) ;
  57.     }
  58.  
  59.     /*
  60.      * basename of program
  61.      */
  62.  
  63.     for (p = ProgramPath, last = NULL ; *p ; p++) {
  64.         if (*p == '/' || *p == '\\') {
  65.             last = p ;
  66.         }
  67.     }
  68.     if (last == NULL) {
  69.         strcpy(ProgramName, ProgramPath) ;
  70.     } else {
  71.         strcpy(ProgramName, &last[1]) ;
  72.     }
  73.     if ((p = strrchr(ProgramName, '.')) != NULL) {
  74.         *p = '\0' ;
  75.     }
  76. }
  77.  
  78. /*
  79.  * Error Notify
  80.  */
  81.  
  82. void    trMessage(PSZ msg)
  83. {
  84.     WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, msg, ProgramName, 0, MB_OK) ;
  85. }
  86.  
  87. /*
  88.  * initPosSize - initial Size & Positions from argument (or default)
  89.  */
  90.  
  91. static  void    initPosSize(int ac, char *av[], PSWP swp)
  92. {
  93.     SWP     swpScr ;
  94.     POINTL  ptCur  ;
  95.     int     i      ;
  96.  
  97.     TRACE("InitPosSize\n") ;
  98.     
  99.     /*
  100.      * set default size, position to pointer and 10th of screen size
  101.      */
  102.  
  103.     WinQueryPointerPos(HWND_DESKTOP, &ptCur) ;
  104.     WinQueryWindowPos(HWND_DESKTOP, &swpScr) ;
  105.     
  106.     swp->x = ptCur.x ;
  107.     swp->y = ptCur.y ;
  108.     swp->cx = swpScr.cx / 8 ;
  109.     swp->cy = swpScr.cy / 8 ;
  110.  
  111.     /*
  112.      * change them if option specified
  113.      */
  114.  
  115.     for (i = 1 ; i < ac ; i++) {
  116.         if (av[i][0] != '-') {
  117.         continue ;
  118.     }
  119.     switch (av[i][1]) {
  120.     case 'w' :
  121.     case 'W' :
  122.         if (av[i][2] != '\0') {
  123.             swp->cx = atoi(&av[i][2]) ;
  124.         } else if ((i + 1) < ac) {
  125.             swp->cx = atoi(av[i+=1]) ;
  126.         }
  127.         break ;
  128.     case 'h' :
  129.     case 'H' :
  130.         if (av[i][2] != '\0') {
  131.             swp->cy = atoi(&av[i][2]) ;
  132.         } else if ((i + 1) < ac) {
  133.             swp->cy = atoi(av[i+=1]) ;
  134.         }
  135.         break ;
  136.     case 'x' :
  137.     case 'X' :
  138.         if (av[i][2] != '\0') {
  139.             swp->x = atoi(&av[i][2]) ;
  140.         } else if ((i + 1) < ac) {
  141.             swp->x = atoi(av[i+=1]) ;
  142.         }
  143.         break ;
  144.     case 'y' :
  145.     case 'Y' :
  146.         if (av[i][2] != '\0') {
  147.             swp->y = atoi(&av[i][2]) ;
  148.         } else if ((i + 1) < ac) {
  149.             swp->y = atoi(av[i+=1]) ;
  150.         }
  151.         break ;
  152.     }
  153.     }
  154.     
  155.     /*
  156.      * adjust position to fit screen
  157.      */
  158.     
  159.     if (swp->cx > swpScr.cx) {
  160.         swp->cx = swpScr.cx ;
  161.     }
  162.     if (swp->cy > swpScr.cy) {
  163.         swp->cy = swpScr.cy ;
  164.     }
  165.     if ((swp->x + swp->cx) > swpScr.cx) {
  166.         swp->x = swpScr.cx - swp->cx ;
  167.     }
  168.     if ((swp->y + swp->cy) > swpScr.cy) {
  169.         swp->y = swpScr.cy - swp->cy ;
  170.     }
  171.     
  172.     TRACE("initPosSize pos %d %d, size %d, %d\n", swp->x, swp->y, swp->cx, swp->cy) ;
  173. }
  174.  
  175. /*
  176.  * Uses Memory DC/PS to manage eye image bitmap
  177.  */
  178.  
  179. static  void    createMemorySpace(HAB hab)
  180. {
  181.     SIZEL   siz ;
  182.     
  183.     TRACE("createMemorySpace\n") ;
  184.     
  185.     hdcMem = DevOpenDC(hab, OD_MEMORY, "*", 0, NULL, NULLHANDLE) ;
  186.     siz.cx = siz.cy = 0 ;
  187.     hpsMem = GpiCreatePS(hab, hdcMem, &siz,
  188.             PU_PELS | GPIF_DEFAULT | GPIT_MICRO | GPIA_ASSOC) ;
  189.  
  190.     if (hdcMem == NULLHANDLE || hpsMem == NULLHANDLE) {
  191.         if (hdcMem != NULLHANDLE) DevCloseDC(hdcMem)   ;
  192.     if (hpsMem != NULLHANDLE) GpiDestroyPS(hpsMem) ;
  193.     hdcMem = NULLHANDLE ;
  194.     hpsMem = NULLHANDLE ;
  195.     TRACE("createMemorySpace - failed\n") ;
  196.     }
  197. }
  198.  
  199. static  void    disposeMemorySpace(void)
  200. {
  201.     TRACE("disposeMemorySpace\n") ;
  202.     
  203.     if (hpsMem != NULLHANDLE) {
  204.         if (hbmMem != NULLHANDLE) {
  205.         GpiSetBitmap(hpsMem, NULLHANDLE) ;
  206.         GpiDeleteBitmap(hbmMem) ;
  207.     }
  208.         GpiDestroyPS(hpsMem) ;
  209.     }
  210.     if (hdcMem != NULLHANDLE) {
  211.         DevCloseDC(hdcMem) ;
  212.     }
  213.     hpsMem = NULLHANDLE ;
  214.     hdcMem = NULLHANDLE ;
  215. }
  216.  
  217. /*
  218.  * draw eye image on memory PS
  219.  */
  220.  
  221. #define SIZE_DIV        16
  222. #define SIZE_OUT        15
  223. #define SIZE_INN        13
  224. #define SIZE_EYE        4
  225.  
  226. #define COLOR_BLACK     CLR_BLACK
  227. #define COLOR_WHITE     CLR_WHITE
  228. #define COLOR_BACK      CLR_BLUE        /* not BLACK nor WHITE  */
  229.  
  230. static  SIZEL   drawSize ;
  231.  
  232. static  void    drawBack(int cx, int cy)
  233. {
  234.     POINTL  pt1, pt2 ;
  235.     ARCPARAMS   arcParam ;
  236.     
  237.     TRACE("drawBack %d x %d\n", cx, cy) ;
  238.  
  239.     drawSize.cx = cx ;
  240.     drawSize.cy = cy ;
  241.     
  242.     if (hpsMem == NULLHANDLE) {
  243.         TRACE("drawBack - no Memory PS\n") ;
  244.         return ;
  245.     }
  246.     
  247.     /*
  248.      * Fill Background
  249.      */
  250.      
  251.     GpiSetColor(hpsMem, COLOR_BACK) ;
  252.     pt1.x = 0 ;
  253.     pt1.y = 0 ;
  254.     GpiMove(hpsMem, &pt1) ;
  255.     pt2.x = drawSize.cx ;
  256.     pt2.y = drawSize.cy ;
  257.     GpiBox(hpsMem, DRO_FILL, &pt2, 0, 0) ;
  258.  
  259.     /*
  260.      * Calc Centers
  261.      */
  262.     
  263.     pt1.y = pt2.y = drawSize.cy / 2 ;
  264.     pt1.x = (drawSize.cx * 1) / 4 ;
  265.     pt2.x = (drawSize.cx * 3) / 4 ;
  266.     
  267.     /*
  268.      * Draw Outer (BLACK) circle
  269.      */
  270.     
  271.     arcParam.lP = (drawSize.cx / 4) * SIZE_OUT / SIZE_DIV ;
  272.     arcParam.lQ = (drawSize.cy / 2) * SIZE_OUT / SIZE_DIV ;
  273.     arcParam.lR = 0 ;
  274.     arcParam.lS = 0 ;
  275.     GpiSetArcParams(hpsMem, &arcParam) ;
  276.     
  277.     GpiSetColor(hpsMem, COLOR_BLACK) ;
  278.     GpiMove(hpsMem, &pt1) ;
  279.     GpiFullArc(hpsMem, DRO_FILL, (FIXED) 0x10000) ;
  280.     GpiMove(hpsMem, &pt2) ;
  281.     GpiFullArc(hpsMem, DRO_FILL, (FIXED) 0x10000) ;
  282. }
  283.  
  284. static  void    drawBallCalcPos(PPOINTL base, PPOINTL ptr, PPOINTL eye)
  285. {
  286.     int     ix, iy, rad ;
  287.     double  r ;
  288.     
  289.     ix = (drawSize.cx / 4) * (SIZE_INN - SIZE_EYE) / SIZE_DIV ;
  290.     iy = (drawSize.cy / 2) * (SIZE_INN - SIZE_EYE) / SIZE_DIV ;
  291.     rad = (ix < iy) ? ix : iy ;
  292.     TRACE("CalcPos rad %d\n", rad) ;
  293.  
  294.     ix = ptr->x - base->x ;
  295.     iy = ptr->y - base->y ;
  296.     
  297.     if (((ix *  ix) + (iy * iy)) <= (rad * rad)) {
  298.         eye->x = ptr->x ;
  299.     eye->y = ptr->y ;
  300.     } else {
  301.         r = atan2((double) ix, (double) iy) ;
  302.     eye->x = base->x + (LONG) (sin(r) * (double) rad) ;
  303.     eye->y = base->y + (LONG) (cos(r) * (double) rad) ;
  304.     }
  305.     TRACE("CalcPos pos %d %d\n", eye->x, eye->y) ;
  306. }
  307.  
  308. static  POINTL  ptLastC = { -1, -1 } ;
  309. static  POINTL  ptLastR = { 0, 0 } ;
  310. static  POINTL  ptLastL = { 0, 0 } ;
  311.  
  312. static  void    drawBall(BOOL restrict)
  313. {
  314.     ARCPARAMS   arcParam ;
  315.     POINTL      pt, ptCR, ptCL, ptER, ptEL ;
  316.     RECTL       rect ;
  317.     
  318.     TRACE("drawBall\n") ;
  319.     
  320.     if (hpsMem == NULLHANDLE) {
  321.         TRACE("drawBall - no Memory PS\n") ;
  322.         return ;
  323.     }
  324.     
  325.     WinQueryPointerPos(HWND_DESKTOP, &pt) ;
  326.     WinMapWindowPoints(HWND_DESKTOP, hwndFrame, &pt, 1) ;
  327.  
  328.     if (pt.x == ptLastC.x && pt.y == ptLastC.y) {
  329.         TRACE("drawBall - not changed\n") ;
  330.         return ;
  331.     }
  332.     
  333.     ptCL.y = ptCR.y = drawSize.cy / 2 ;
  334.     ptCL.x = (drawSize.cx * 1) / 4 ;
  335.     ptCR.x = (drawSize.cx * 3) / 4 ;
  336.  
  337.     /*
  338.      * Draw Inner Circle to clear last eye ball
  339.      */
  340.      
  341.     arcParam.lP = (drawSize.cx / 4) * SIZE_INN / SIZE_DIV ;
  342.     arcParam.lQ = (drawSize.cy / 2) * SIZE_INN / SIZE_DIV ;
  343.     arcParam.lR = 0 ;
  344.     arcParam.lS = 0 ;
  345.     GpiSetArcParams(hpsMem, &arcParam) ;
  346.  
  347.     GpiSetColor(hpsMem, COLOR_WHITE) ;
  348.     GpiMove(hpsMem, &ptCL) ;
  349.     GpiFullArc(hpsMem, DRO_FILL, (FIXED) 0x10000) ;
  350.     GpiMove(hpsMem, &ptCR) ;
  351.     GpiFullArc(hpsMem, DRO_FILL, (FIXED) 0x10000) ;
  352.  
  353.     if (restrict) { 
  354.         rect.xLeft   = ptCL.x - (drawSize.cx / 4) * SIZE_INN / SIZE_DIV ;
  355.         rect.xRight  = ptCR.x + (drawSize.cx / 4) * SIZE_INN / SIZE_DIV ;
  356.         rect.yTop    = ptCL.y + (drawSize.cy / 2) * SIZE_INN / SIZE_DIV ;
  357.         rect.yBottom = ptCL.y - (drawSize.cy / 2) * SIZE_INN / SIZE_DIV ;
  358.     }
  359.     
  360.     /*
  361.      * draw eye ball
  362.      */
  363.      
  364.     arcParam.lP = (drawSize.cx / 4) * SIZE_EYE / SIZE_DIV ;
  365.     arcParam.lQ = (drawSize.cy / 2) * SIZE_EYE / SIZE_DIV ;
  366.     arcParam.lR = 0 ;
  367.     arcParam.lS = 0 ;
  368.     GpiSetArcParams(hpsMem, &arcParam) ;
  369.     
  370.     drawBallCalcPos(&ptCL, &pt, &ptEL) ;
  371.     drawBallCalcPos(&ptCR, &pt, &ptER) ;
  372.     
  373.     GpiSetColor(hpsMem, COLOR_BLACK) ;
  374.     GpiMove(hpsMem, &ptEL) ;
  375.     GpiFullArc(hpsMem, DRO_FILL, (FIXED) 0x10000) ;
  376.     GpiMove(hpsMem, &ptER) ;
  377.     GpiFullArc(hpsMem, DRO_FILL, (FIXED) 0x10000) ;
  378.  
  379.     ptLastC = pt   ;
  380.     ptLastL = ptEL ;
  381.     ptLastR = ptER ;
  382.     
  383.     if (hwndShape != NULLHANDLE) {
  384.         if (restrict) {
  385.             WinSendMsg(hwndShape, SHAPEWIN_MSG_UPDATE, MPFROMP(&rect), NULL) ;
  386.         } else {
  387.             WinSendMsg(hwndShape, SHAPEWIN_MSG_UPDATE, NULL, NULL) ;
  388.         }
  389.     }
  390. }
  391.  
  392. /*
  393.  * bitmap & window to display eye image
  394.  */
  395.  
  396. static  void    adjustImage(PSWP swp)
  397. {
  398.     BITMAPINFOHEADER2   bmi ;
  399.     HBITMAP     hbm  ;
  400.     HWND        hwnd ;
  401.     SHAPEWIN    shpctrl ;
  402.     
  403.     TRACE("adjustImage\n") ;
  404.     
  405.     if (hdcMem == NULLHANDLE || hpsMem == NULLHANDLE) {
  406.         TRACE("adjustImage - no Memory PS\n") ;
  407.         return ;
  408.     }
  409.     if (hwndFrame == NULLHANDLE) {
  410.         TRACE("adjustImage - no Frame Window\n") ;
  411.         return ;
  412.     }
  413.  
  414.     /*
  415.      * if bitmap already exist and having same size, use it
  416.      */
  417.  
  418.     if (hbmMem != NULLHANDLE) {
  419.         bmi.cbFix = sizeof(bmi) ;
  420.     GpiQueryBitmapInfoHeader(hbmMem, &bmi) ;
  421.  
  422.     if (bmi.cx == swp->cx && bmi.cy == swp->cy) {
  423.         return ;
  424.     }
  425.     GpiSetBitmap(hpsMem, NULLHANDLE) ;  /* unlink from Memory PS */
  426.     }
  427.     
  428.     /*
  429.      * create new bitmap of given size
  430.      */
  431.     
  432.     memset(&bmi, 0, sizeof(bmi)) ;
  433.     bmi.cbFix = sizeof(bmi) ;
  434.     bmi.cx = swp->cx ;
  435.     bmi.cy = swp->cy ;
  436.     bmi.cPlanes       = 1  ;
  437.     bmi.cBitCount     = 24 ;
  438.     bmi.ulCompression = 0  ;
  439.     bmi.cclrUsed      = 0  ;
  440.     bmi.cclrImportant = 0  ;
  441.  
  442.     hbm = GpiCreateBitmap(hpsMem, &bmi, 0, NULL, NULL) ;
  443.     GpiSetBitmap(hpsMem, hbm) ;
  444.     
  445.     /*
  446.      * credate new window with new bitmap
  447.      */
  448.  
  449.     if (hbm == NULLHANDLE) {
  450.         TRACE("adjustImage - failed to create Bitmap\n") ;
  451.         return ;
  452.     }
  453.  
  454.     drawBack(swp->cx, swp->cy) ;
  455.     drawBall(FALSE) ;
  456.  
  457.     shpctrl.cx = swp->cx ;
  458.     shpctrl.cy = swp->cy ;
  459.     shpctrl.hpsDraw = hpsMem ;
  460.     shpctrl.hpsMask = hpsMem ;
  461.     
  462.     hwnd = WinCreateWindow(
  463.             HWND_DESKTOP,           /* Parent Window    */
  464.             "ShapeWin",             /* Window Class     */
  465.         NULL,                   /* Window Text      */
  466.         0,                      /* Window Style     */
  467.         swp->x,  swp->y,
  468.         swp->cx, swp->cy,
  469.         hwndFrame,              /* Owner Window     */
  470.         HWND_TOP,               /* Z-Order          */
  471.         0,                      /* Window ID        */
  472.         &shpctrl,               /* Control Data     */
  473.         NULL) ;                 /* Pres. Param.     */
  474.  
  475.     if (hwnd == NULLHANDLE) {
  476.         TRACE("adjustImage - failed to create window\n") ;
  477.         return ;
  478.     }
  479.     
  480.     WinShowWindow(hwnd, TRUE) ;
  481.  
  482.     if (hwndShape != NULLHANDLE) {
  483.         WinShowWindow(hwndShape, FALSE) ;
  484.         WinDestroyWindow(hwndShape) ;
  485.     }
  486.     hwndShape = hwnd ;
  487.  
  488.     if (hbmMem != NULLHANDLE) {
  489.         GpiDeleteBitmap(hbmMem) ;
  490.     }
  491.     hbmMem = hbm ;
  492. }
  493.  
  494. /*
  495.  * create/disposeWindow - create/dispose Window and related resources
  496.  */
  497.  
  498. static  PFNWP   pfnFrame ;
  499. static MRESULT EXPENTRY procFrame(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2) ;
  500.  
  501. static  void    createWindow(HAB hab, PSWP swp)
  502. {
  503.     FRAMECDATA  fcd ;
  504.  
  505.     TRACE("createWindow\n") ;
  506.     
  507.     if (hab == NULLHANDLE || swp == NULL) {
  508.         TRACE("createWindow - bad parameters\n") ;
  509.         return ;
  510.     }
  511.     
  512.     memset(&fcd, 0, sizeof(fcd)) ;
  513.     fcd.cb = sizeof(fcd) ;
  514.     fcd.flCreateFlags = (FCF_TASKLIST | FCF_ICON) ;
  515.     fcd.hmodResources = NULLHANDLE ;
  516.     fcd.idResources   = ID_TREYES  ;   
  517.  
  518.     hwndFrame = WinCreateWindow(
  519.             HWND_DESKTOP,           /* Parent window handle     */
  520.             WC_FRAME,               /* Frame Window Class       */
  521.             ProgramName,            /* as Title                 */
  522.             0,                      /* Window Style             */
  523.             swp->x, swp->y,
  524.         swp->cx, swp->cy,
  525.             NULLHANDLE,             /* Owner Window             */
  526.             HWND_TOP,               /* Z-Order                  */
  527.             0,                      /* Window ID                */
  528.             &fcd,                   /* Control Data             */
  529.             NULL) ;                 /* Presentation Parameter   */
  530.  
  531.     if (hwndFrame == NULLHANDLE) {
  532.         TRACE("createWindow - failed to create frmae window\n") ;
  533.         return ;
  534.     }
  535.  
  536.     pfnFrame = WinSubclassWindow(hwndFrame, procFrame) ;
  537.  
  538.     WinSendMsg(hwndFrame, WM_SETICON, 
  539.         MPFROMP(WinLoadPointer(HWND_DESKTOP, NULLHANDLE, ID_TREYES)), NULL) ;
  540.  
  541.     WinRegisterClass(hab, "ShapeWin", ShapeWinProc, 0L, sizeof(PVOID)) ;
  542.  
  543.     /*
  544.      * adjust Bitmap/Window size to frame size
  545.      */
  546.      
  547.     adjustImage(swp) ;
  548. }
  549.  
  550. static  void    disposeWindow(void)
  551. {
  552.     TRACE("disposeWindow\n") ;
  553.     
  554.     if (hwndShape != NULLHANDLE) {
  555.         WinDestroyWindow(hwndShape) ;
  556.     }
  557.     if (hwndFrame != NULLHANDLE) {
  558.         WinDestroyWindow(hwndFrame) ;
  559.     }
  560.     hwndShape = NULLHANDLE ;
  561.     hwndFrame = NULLHANDLE ;
  562. }
  563.  
  564. /*
  565.  * context menu
  566.  */
  567.  
  568. static  HWND    hwndPopup = NULLHANDLE ;    /* context menu */
  569.  
  570. static  void    contextMenu(void)
  571. {
  572.     POINTL  pt   ;
  573.     ULONG   opts ;
  574.     
  575.     if (hwndPopup == NULLHANDLE) {
  576.         hwndPopup = WinLoadMenu(hwndFrame, NULLHANDLE, IDM_POPUP) ;
  577.     }
  578.     if (hwndPopup == NULLHANDLE) {
  579.         TRACE("failed to load opup menu\n") ;
  580.         return ;
  581.     }
  582.     
  583.     WinQueryPointerPos(HWND_DESKTOP, &pt) ;
  584.  
  585.     opts = PU_POSITIONONITEM | PU_HCONSTRAIN | PU_VCONSTRAIN |
  586.                  PU_KEYBOARD | PU_MOUSEBUTTON1 | PU_MOUSEBUTTON2 ;
  587.  
  588.     WinPopupMenu(HWND_DESKTOP, hwndFrame, hwndPopup, 
  589.                                 pt.x, pt.y, IDM_MOVE, opts) ;
  590. }
  591.  
  592. /*
  593.  * procFrame - sub-classed frame window procedure for eye
  594.  *
  595.  *      bitmap window send messages ti its owner (frame).  process those
  596.  *      messages to perform transparent background
  597.  */
  598.  
  599. static  BOOL    fsResize = FALSE ;
  600. static  POINTL  ptResize ;
  601.  
  602. static MRESULT EXPENTRY procFrame(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  603. {
  604.     SWP     swp  ;
  605.     PSWP    pswp ;
  606.     SHORT   x, y ;
  607.     USHORT  fs   ;
  608.     POINTL  pt   ;
  609.     
  610.     TRACE("frame %08x %08x %08x\n", msg, mp1, mp2) ;
  611.     
  612.     switch (msg) {
  613.         
  614.     case WM_ADJUSTWINDOWPOS :
  615.         pswp = (PSWP) PVOIDFROMMP(mp1) ;
  616.         if (pswp->fl & SWP_SIZE) {
  617.             adjustImage(pswp) ;
  618.         }
  619.     WinSetWindowPos(hwndShape, pswp->hwndInsertBehind,
  620.                 pswp->x, pswp->y, pswp->cx, pswp->cy, pswp->fl) ;
  621.     pswp->fl &= ~SWP_SHOW ;
  622.     pswp->fl |=  SWP_HIDE ;
  623.     return (*pfnFrame) (hwnd, msg, mp1, mp2) ;
  624.     
  625.     case WM_BEGINDRAG :
  626.         fs = TF_MOVE | TF_SETPOINTERPOS ;
  627.         WinSendMsg(hwndFrame, WM_TRACKFRAME, MPFROMSHORT(fs), NULL) ;
  628.         return (MRESULT) 0 ;
  629.  
  630.     case WM_CONTEXTMENU :
  631.         TRACE("WM_CONEXTMENU\n") ;
  632.     contextMenu() ;
  633.         return (MRESULT) 0 ;
  634.     
  635.     case WM_COMMAND :
  636.         switch (SHORT1FROMMP(mp1)) {
  637.         case IDM_MOVE :
  638.         fs = TF_MOVE | TF_SETPOINTERPOS ;
  639.             WinSendMsg(hwndFrame, WM_TRACKFRAME, MPFROMSHORT(fs), NULL) ;
  640.         return (MRESULT) 0 ;
  641.         case IDM_SIZE :
  642.         fsResize = TRUE ;
  643.         WinSetCapture(HWND_DESKTOP, hwnd) ;
  644.         WinQueryPointerPos(HWND_DESKTOP, &ptResize) ;
  645.         return (MRESULT) 0 ;
  646.     case IDM_HIDE :
  647.         WinShowWindow(hwnd, FALSE) ;
  648.         return (MRESULT) 0 ;
  649.     case IDM_EXIT :
  650.         WinShowWindow(hwnd, FALSE) ;
  651.         WinPostMsg(hwnd, WM_CLOSE, NULL, NULL) ;
  652.         return (MRESULT) 0 ;
  653.         }
  654.         return (MRESULT) 0 ;
  655.  
  656.     case WM_MOUSEMOVE  :
  657.         if (fsResize) {
  658.         WinQueryPointerPos(HWND_DESKTOP, &pt)   ;
  659.         if (pt.x != ptResize.x || pt.y != ptResize.y) {
  660.                 WinSetCapture(HWND_DESKTOP, NULLHANDLE) ;
  661.             fsResize = FALSE ;
  662.             fs = TF_SETPOINTERPOS ;
  663.                 if (pt.x < ptResize.x) {
  664.             fs |= TF_LEFT ;
  665.         } else if (pt.x > ptResize.x) {
  666.             fs |= TF_RIGHT ;
  667.         }
  668.         if (pt.y < ptResize.y) {
  669.             fs |= TF_BOTTOM ;
  670.         } else if (pt.y > ptResize.y) {
  671.             fs |= TF_TOP ;
  672.         }
  673.                 WinSendMsg(hwndFrame, WM_TRACKFRAME, MPFROMSHORT(fs), NULL) ;
  674.         return (MRESULT) 0 ;
  675.         }
  676.         }
  677.     break ;
  678.     
  679.     case WM_TIMER :
  680.         drawBall(TRUE) ;
  681.         return (MRESULT) 0 ;
  682.     }
  683.     return (*pfnFrame) (hwnd, msg, mp1, mp2) ;
  684. }
  685.  
  686. /*
  687.  * main - program start here
  688.  */
  689.  
  690. int     main(int ac, char *av[])
  691. {
  692.     HAB     hab  ;
  693.     HMQ     hmq  ;
  694.     QMSG    qmsg ;
  695.     SWP     swp  ;
  696.  
  697.     myname(av[0]) ;
  698.  
  699.     hab = WinInitialize(0) ;
  700.     hmq = WinCreateMsgQueue(hab, 0) ;
  701.  
  702.     initPosSize(ac, av, &swp) ;
  703.     
  704.     createMemorySpace(hab)  ;
  705.     createWindow(hab, &swp) ;
  706.  
  707.     if (hwndFrame == NULLHANDLE) {
  708.         trMessage("failed to create bitmap/windows") ;
  709.         disposeMemorySpace()    ; 
  710.         WinDestroyMsgQueue(hmq) ;
  711.         WinTerminate(hab) ;
  712.     return 1 ;
  713.     }
  714.     
  715.     WinStartTimer(hab, hwndFrame, 1, 200) ;
  716.     WinShowWindow(hwndFrame, TRUE) ;
  717.  
  718.     while (WinGetMsg(hab, &qmsg, 0, 0, 0)) {
  719.         WinDispatchMsg(hab, &qmsg) ;
  720.     }
  721.  
  722.     disposeWindow()      ;
  723.     disposeMemorySpace() ;
  724.     
  725.     WinDestroyMsgQueue(hmq) ;
  726.     WinTerminate(hab) ;
  727.     
  728.     return 0 ; 
  729. }
  730.