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

  1. /*
  2.  * tranime.c - animate bitmaps with transparent background
  3.  */
  4.  
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <string.h>
  8.  
  9. #define INCL_PM
  10. #include <os2.h>
  11.  
  12. #include "shapewin.h"
  13. #include "bmpload.h"
  14.  
  15. #include "tranime.h"
  16. #include "tranires.h"
  17.  
  18. /*
  19.  * myname - adjust and save program names
  20.  */
  21.  
  22. UCHAR   ProgramPath[256] ;
  23. UCHAR   ProgramName[256] ;
  24.  
  25. static  void    myname(PSZ me)
  26. {
  27.     PUCHAR  p, last ;
  28.  
  29.     /*
  30.      * full pathname of program
  31.      */
  32.  
  33.     for (p = me, last = NULL ; *p ; p++) {
  34.         if (*p == '/' || *p == '\\') {
  35.             last = p ;
  36.         }
  37.     }
  38.     if (last != NULL) {
  39.         strcpy(ProgramPath, me) ;
  40.     } else if (DosSearchPath(7, "PATH", me, ProgramPath, 256) != 0) {
  41.         strcpy(ProgramPath, me) ;
  42.     }
  43.  
  44.     /*
  45.      * basename of program
  46.      */
  47.  
  48.     for (p = ProgramPath, last = NULL ; *p ; p++) {
  49.         if (*p == '/' || *p == '\\') {
  50.             last = p ;
  51.         }
  52.     }
  53.     if (last == NULL) {
  54.         strcpy(ProgramName, ProgramPath) ;
  55.     } else {
  56.         strcpy(ProgramName, &last[1]) ;
  57.     }
  58.     if ((p = strrchr(ProgramName, '.')) != NULL) {
  59.         *p = '\0' ;
  60.     }
  61. }
  62.  
  63. /*
  64.  * Error Notify
  65.  */
  66.  
  67. void    taMessage(PSZ msg)
  68. {
  69.     WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, msg, ProgramName, 0, MB_OK) ;
  70. }
  71.  
  72. /*
  73.  * Control Dialog Position
  74.  */
  75.  
  76. void    dialogAtCenter(HWND hwndDialog)
  77. {
  78.     SWP     posScr ;
  79.     SWP     posDlg ;
  80.  
  81.     WinQueryWindowPos(HWND_DESKTOP, &posScr) ;
  82.     WinQueryWindowPos(hwndDialog,   &posDlg) ;
  83.  
  84.     posDlg.x = (posScr.cx - posDlg.cx) / 2 ;
  85.     posDlg.y = (posScr.cy - posDlg.cy) / 2 ;
  86.  
  87. #if 0
  88.     printf("Disktop size %d x %d\n", posScr.cx, posScr.cy) ;
  89.     printf("Dialog  size %d x %d\n", posDlg.cx, posDlg.cy) ;
  90.     printf("Place dialog at ( %d, %d)\n", posDlg.x, posDlg.y) ;
  91.     fflush(stdout) ;
  92. #endif    
  93.  
  94.     WinSetWindowPos(hwndDialog, NULLHANDLE,
  95.                     posDlg.x, posDlg.y, 0, 0, SWP_MOVE) ;
  96. }
  97.  
  98. void    dialogAtMouse(HWND hwndDialog)
  99. {
  100.     POINTL  pt ;
  101.     SWP     posDlg ;
  102.     SWP     posScr ;
  103.  
  104.     WinQueryPointerPos(HWND_DESKTOP, &pt)    ;
  105.     WinQueryWindowPos(HWND_DESKTOP, &posScr) ;
  106.     WinQueryWindowPos(hwndDialog,   &posDlg) ;
  107.  
  108.     posDlg.x = pt.x - (posDlg.cx / 10)    ;
  109.     posDlg.y = pt.y - (posDlg.cy * 4 / 5) ;
  110.  
  111.     if (posDlg.x < 0) {
  112.         posDlg.x = 0 ;
  113.     }
  114.     if (posDlg.y < 0) {
  115.         posDlg.y = 0 ;
  116.     }
  117.     if ((posDlg.x + posDlg.cx) > posScr.cx) {
  118.         posDlg.x = posScr.cx - posDlg.cx ;
  119.     }
  120.     if ((posDlg.y + posDlg.cy) > posScr.cy) {
  121.         posDlg.y = posScr.cy - posDlg.cy ;
  122.     }
  123.     WinSetWindowPos(hwndDialog, NULLHANDLE,
  124.                     posDlg.x, posDlg.y, 0, 0, SWP_MOVE) ;
  125. }
  126.  
  127. /*
  128.  * bitmaps to use
  129.  */
  130.  
  131. typedef struct _ANIM {
  132.     HDC     hdc  ;
  133.     HPS     hps  ;
  134.     HBITMAP hbm  ;
  135.     SHORT   cx   ;
  136.     SHORT   cy   ;
  137.     HWND    hwnd ;
  138. } ANIREC, *ANIPTR ;
  139.  
  140. ANIREC  tabAnim[32] = { 0 } ;
  141. int     numAnim = 0 ;
  142. int     stepAnim  = 20  ;
  143. int     delayAnim = 500 ;
  144.  
  145. #define YLOC    100
  146.  
  147. static  BOOL    loadOne(HAB hab, PUCHAR name, ANIPTR p)
  148. {
  149.     SIZEL   siz ;
  150.     BITMAPINFOHEADER2   bmi ;
  151.     
  152.     p->hdc = DevOpenDC(hab, OD_MEMORY, "*", 0, NULL, NULLHANDLE) ;
  153.     siz.cx = siz.cy = 0 ;
  154.     p->hps = GpiCreatePS(hab, p->hdc, &siz,
  155.             PU_PELS | GPIF_DEFAULT | GPIT_MICRO | GPIA_ASSOC) ;
  156.     p->hbm = bitmapLoadFile(hab, p->hps, name) ;
  157.     
  158.     if (p->hdc == NULLHANDLE || p->hps == NULLHANDLE ||p->hbm == NULLHANDLE) {
  159.         if (p->hbm != NULLHANDLE) GpiDeleteBitmap(p->hbm) ;
  160.     if (p->hps != NULLHANDLE) GpiDestroyPS(p->hps) ;
  161.     if (p->hdc != NULLHANDLE) DevCloseDC(p->hdc) ;
  162.     return FALSE ;
  163.     }
  164.  
  165.     bmi.cbFix = sizeof(bmi) ;
  166.     GpiQueryBitmapInfoHeader(p->hbm, &bmi) ;
  167.  
  168.     p->cx = bmi.cx ;
  169.     p->cy = bmi.cy ;
  170.     
  171.     return TRUE ;
  172. }
  173.  
  174. void    loadBitmaps(HAB hab, int ac, char *av[])
  175. {
  176.     int     i ;
  177.     
  178.     for (i = 1 ; i < ac && numAnim < 32 ; i++) {
  179.         if (av[i][0] != '-') {
  180.             if (loadOne(hab, av[i], &tabAnim[numAnim]) == TRUE) {
  181.                 numAnim += 1 ;
  182.         }
  183.         } else {
  184.         if (av[i][1] == 'd' || av[i][1] == 'D') {
  185.             if (av[i][2] != '\0') {
  186.             delayAnim = atoi(&av[i][2]) ;
  187.         } else if ((i + 1) < ac) {
  188.             delayAnim = atoi(av[i+=1]) ;
  189.         }
  190.         }
  191.         if (av[i][1] == 's' || av[i][1] == 'S') {
  192.             if (av[i][2] != '\0') {
  193.             stepAnim = atoi(&av[i][2]) ;
  194.         } else if ((i + 1) < ac) {
  195.             stepAnim = atoi(av[i+=1]) ;
  196.         }
  197.         }
  198.         }
  199.     }
  200. }
  201.  
  202. void    freeBitmaps(void)
  203. {
  204.     int     i ;
  205.     
  206.     for (i = 0 ; i < numAnim ; i++) {
  207.         if (tabAnim[i].hwnd != NULLHANDLE) {
  208.         WinDestroyWindow(tabAnim[i].hwnd) ;
  209.     }
  210.         GpiDeleteBitmap(tabAnim[i].hbm) ;
  211.     GpiDestroyPS(tabAnim[i].hps) ;
  212.     DevCloseDC(tabAnim[i].hdc) ;
  213.     }
  214. }
  215.  
  216. /*
  217.  * dialog procedure for animation control
  218.  */
  219.  
  220. static  SWP     swpScreen ;
  221. static  int     curBitmap = 0 ;
  222. static  int     nxtBitmap = 0 ;
  223. static  int     curLocate = 0 ;
  224. static  int     nxtLocate = 0 ;
  225.  
  226. MRESULT EXPENTRY    procControl(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  227. {
  228.     int         i       ;
  229.     ANIPTR      pAnim   ;
  230.     SHAPEWIN    shpctrl ;
  231.     PSWP        pswp    ;
  232.     UCHAR   buff[128] ;    
  233.  
  234.     switch(msg) {
  235.     
  236.     case WM_INITDLG :
  237.         dialogAtCenter(hwnd) ;
  238.     WinSendMsg(hwnd, WM_SETICON, 
  239.         MPFROMP(WinLoadPointer(HWND_DESKTOP, NULLHANDLE, ID_TRANIME)), NULL) ;
  240.         WinQueryWindowPos(HWND_DESKTOP, &swpScreen) ;
  241.     
  242.     sprintf(buff, "%d", stepAnim) ;
  243.         WinSetWindowText(WinWindowFromID(hwnd, IDC_STEP), buff) ;
  244.     sprintf(buff, "%d", delayAnim) ;
  245.         WinSetWindowText(WinWindowFromID(hwnd, IDC_DELAY), buff) ;
  246.     
  247.         for (i = 0, pAnim = tabAnim ; i < numAnim ; i++, pAnim++) {
  248.  
  249.         shpctrl.cx = pAnim->cx ;
  250.         shpctrl.cy = pAnim->cy ;
  251.         shpctrl.hpsDraw = pAnim->hps ;
  252.         shpctrl.hpsMask = pAnim->hps ;
  253.         
  254.         pAnim->hwnd = WinCreateWindow(
  255.                 HWND_DESKTOP,           /* Parent Window    */
  256.                 ShapeWinName,           /* Window Class     */
  257.                 NULL,                   /* Window Text      */
  258.             0,                      /* Window Style     */
  259.             0, 0, 0, 0,             /* Pos & Size       */
  260.             hwnd,                   /* Owner Window     */
  261.             HWND_TOP,               /* Z-Order          */
  262.             0,                      /* Window ID        */
  263.             &shpctrl,               /* Control Data     */
  264.             NULL) ;                 /* Pres. Param.     */
  265.     }
  266.         return (MRESULT) 0 ;
  267.  
  268.     case WM_CLOSE :
  269.         WinDismissDlg(hwnd, TRUE) ;
  270.     return (MRESULT) 0 ;
  271.  
  272.     case WM_DESTROY :
  273.         return (MRESULT) 0 ;
  274.         
  275.     case WM_WINDOWPOSCHANGED :
  276.         pswp = (PSWP) PVOIDFROMMP(mp1) ;
  277.     if (pswp->fl & SWP_ZORDER) {
  278.             for (i = 0, pAnim = tabAnim ; i < numAnim ; i++, pAnim++) {
  279.             WinSetWindowPos(pAnim->hwnd, 
  280.             pswp->hwndInsertBehind, 0, 0, 0, 0, SWP_ZORDER) ;
  281.             }
  282.     }
  283.         return WinDefDlgProc(hwnd, msg, mp1, mp2) ;
  284.     
  285.     case WM_COMMAND :
  286.         switch (SHORT1FROMMP(mp1)) {
  287.     case IDC_EXIT :
  288.         WinPostMsg(hwnd, WM_CLOSE, NULL, NULL) ;
  289.         return (MRESULT) 0 ;
  290.  
  291.     case IDC_RUN :
  292.             WinQueryWindowText(WinWindowFromID(hwnd, IDC_STEP), 64, buff) ;
  293.         stepAnim  = atoi(buff) ;
  294.             WinQueryWindowText(WinWindowFromID(hwnd, IDC_DELAY), 64, buff) ;
  295.         delayAnim = atoi(buff) ;
  296.  
  297.             if (delayAnim == 0) {
  298.             taMessage("no delay specified") ;
  299.         return (MRESULT) 0 ;
  300.         }
  301.  
  302.         pAnim = &tabAnim[curBitmap] ;
  303.         WinSetWindowPos(pAnim->hwnd, NULLHANDLE, 
  304.                 curLocate, YLOC, 0, 0, (SWP_MOVE | SWP_SHOW)) ;
  305.             WinStartTimer(WinQueryAnchorBlock(hwnd), hwnd, 1, delayAnim) ;
  306.         return (MRESULT) 0 ;
  307.  
  308.         case IDC_STOP :
  309.         WinStopTimer(WinQueryAnchorBlock(hwnd), hwnd, 1) ;
  310.         pAnim = &tabAnim[curBitmap] ;
  311.             WinShowWindow(pAnim->hwnd, FALSE) ;
  312.         return (MRESULT) 0 ;
  313.     }
  314.     return (MRESULT) 0 ;
  315.  
  316.     case WM_TIMER :
  317.         if ((curBitmap + 1) < numAnim) {
  318.         nxtBitmap = curBitmap + 1 ;
  319.     } else {
  320.         nxtBitmap = 0 ;
  321.     }
  322.     if ((curLocate + stepAnim) >= swpScreen.cx) {
  323.         nxtLocate = 0 ;
  324.     } else if ((curLocate + stepAnim) < 0) {
  325.         nxtLocate = swpScreen.cx ;
  326.     } else {
  327.         nxtLocate = curLocate + stepAnim ;
  328.     }
  329.         pAnim = &tabAnim[curBitmap] ;
  330.     WinShowWindow(pAnim->hwnd, FALSE) ;
  331.         pAnim = &tabAnim[nxtBitmap] ;
  332.     WinSetWindowPos(pAnim->hwnd, NULLHANDLE,
  333.                 nxtLocate, YLOC, 0, 0, (SWP_MOVE | SWP_SHOW)) ;
  334.     curLocate = nxtLocate ;
  335.     curBitmap = nxtBitmap ;
  336.         return (MRESULT) 0 ;
  337.     }
  338.     return WinDefDlgProc(hwnd, msg, mp1, mp2) ;
  339. }
  340.  
  341. /*
  342.  * main - program start here
  343.  */
  344.  
  345. int     main(int ac, char *av[])
  346. {
  347.     HAB     hab ;
  348.     HMQ     hmq ;
  349.     SIZEL   siz ;
  350.  
  351.     myname(av[0]) ;
  352.     _wildcard(&ac, &av) ;
  353.     
  354.     hab = WinInitialize(0) ;
  355.     hmq = WinCreateMsgQueue(hab, 0) ;
  356.  
  357.     WinRegisterClass(hab, ShapeWinName, ShapeWinProc, 0L, sizeof(PVOID)) ;
  358.  
  359.     loadBitmaps(hab, ac, av) ;
  360.     
  361.     if (numAnim == 0) {
  362.         taMessage("no animating bitmaps") ;
  363.         WinDestroyMsgQueue(hmq) ;
  364.         WinTerminate(hab) ;
  365.     return 1 ;
  366.     }
  367.  
  368.     WinDlgBox(HWND_DESKTOP, HWND_DESKTOP, 
  369.                 procControl, NULLHANDLE, ID_CONTROL, NULL) ;
  370.         
  371.     freeBitmaps() ;
  372.     
  373.     WinDestroyMsgQueue(hmq) ;
  374.     WinTerminate(hab) ;
  375.     return 0 ;
  376. }
  377.