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

  1. /*
  2.  * trbitmap.c - display bitmap 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 "trbitmap.h"
  16. #include "trbitres.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 Bitmap  */
  24.  
  25. /*
  26.  * Bitmap to Display
  27.  */
  28.  
  29. PUCHAR  pszBitmap = NULL       ;    /* Bitmap File Name     */
  30.  
  31. HDC     hdcBitmap = NULLHANDLE ;    /* Memory DC for Bitmap */
  32. HPS     hpsBitmap = NULLHANDLE ;    /* Memory PS for Bitmap */
  33. HBITMAP hbmBitmap = NULLHANDLE ;    /* Bitmap Handle        */
  34.  
  35. /*
  36.  * myname - adjust and save program names
  37.  */
  38.  
  39. UCHAR   ProgramPath[256] ;
  40. UCHAR   ProgramName[256] ;
  41.  
  42. static  void    myname(PSZ me)
  43. {
  44.     PUCHAR  p, last ;
  45.  
  46.     /*
  47.      * full pathname of program
  48.      */
  49.  
  50.     for (p = me, last = NULL ; *p ; p++) {
  51.         if (*p == '/' || *p == '\\') {
  52.             last = p ;
  53.         }
  54.     }
  55.     if (last != NULL) {
  56.         strcpy(ProgramPath, me) ;
  57.     } else if (DosSearchPath(7, "PATH", me, ProgramPath, 256) != 0) {
  58.         strcpy(ProgramPath, me) ;
  59.     }
  60.  
  61.     /*
  62.      * basename of program
  63.      */
  64.  
  65.     for (p = ProgramPath, last = NULL ; *p ; p++) {
  66.         if (*p == '/' || *p == '\\') {
  67.             last = p ;
  68.         }
  69.     }
  70.     if (last == NULL) {
  71.         strcpy(ProgramName, ProgramPath) ;
  72.     } else {
  73.         strcpy(ProgramName, &last[1]) ;
  74.     }
  75.     if ((p = strrchr(ProgramName, '.')) != NULL) {
  76.         *p = '\0' ;
  77.     }
  78. }
  79.  
  80. /*
  81.  * Error Notify
  82.  */
  83.  
  84. void    trMessage(PSZ msg)
  85. {
  86.     WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, msg, ProgramName, 0, MB_OK) ;
  87. }
  88.  
  89. /*
  90.  * load/free Bitmap
  91.  */
  92.  
  93. static  void    loadBitmap(HAB hab)
  94. {
  95.     SIZEL   siz ;
  96.     
  97.     hdcBitmap = DevOpenDC(hab, OD_MEMORY, "*", 0, NULL, NULLHANDLE) ;
  98.     siz.cx = siz.cy = 0 ;
  99.     hpsBitmap = GpiCreatePS(hab, hdcBitmap, &siz,
  100.             PU_PELS | GPIF_DEFAULT | GPIT_MICRO | GPIA_ASSOC) ;
  101.  
  102.     if (hdcBitmap == NULLHANDLE || hpsBitmap == NULLHANDLE) {
  103.         return ;
  104.     }
  105.     hbmBitmap = bitmapLoadFile(hab, hpsBitmap, pszBitmap) ;
  106. }
  107.  
  108. static  void    freeBitmap(void)
  109. {
  110.     if (hbmBitmap != NULLHANDLE) {
  111.         GpiDeleteBitmap(hbmBitmap) ;
  112.     }
  113.     if (hpsBitmap != NULLHANDLE) {
  114.         GpiDestroyPS(hpsBitmap) ;
  115.     }
  116.     if (hdcBitmap != NULLHANDLE) {
  117.         DevCloseDC(hdcBitmap) ;
  118.     }
  119. }
  120.  
  121. /*
  122.  * createFrame - create frame window
  123.  */
  124.  
  125. static  PFNWP   pfnFrame ;
  126. static MRESULT EXPENTRY procFrame(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2) ;
  127.  
  128. static  void    createFrame(HAB hab)
  129. {
  130.     FRAMECDATA  fcd    ;
  131.     UCHAR       title[256] ;
  132.  
  133.     memset(&fcd, 0, sizeof(fcd)) ;
  134.     fcd.cb = sizeof(fcd) ;
  135.     fcd.flCreateFlags = (FCF_TASKLIST | FCF_ICON) ;
  136.     fcd.hmodResources = NULLHANDLE  ;
  137.     fcd.idResources   = ID_TRBITMAP ;   
  138.  
  139.     sprintf(title, "%s [%s]", ProgramName, pszBitmap) ;
  140.     
  141.     hwndFrame = WinCreateWindow(
  142.             HWND_DESKTOP,           /* Parent window handle     */
  143.             WC_FRAME,               /* Frame Window Class       */
  144.             title,                  /* as Title                 */
  145.             0,                      /* Window Style             */
  146.             0, 0, 0, 0,             /* Position & size          */
  147.             NULLHANDLE,             /* Owner Window             */
  148.             HWND_TOP,               /* Z-Order                  */
  149.             0,                      /* Window ID                */
  150.             &fcd,                   /* Control Data             */
  151.             NULL) ;                 /* Presentation Parameter   */
  152.  
  153.     if (hwndFrame == NULLHANDLE) {
  154.         return ;
  155.     }
  156.  
  157.     pfnFrame = WinSubclassWindow(hwndFrame, procFrame) ;
  158.  
  159.     WinSendMsg(hwndFrame, WM_SETICON, 
  160.         MPFROMP(WinLoadPointer(HWND_DESKTOP, NULLHANDLE, ID_TRBITMAP)), NULL) ;
  161. }
  162.  
  163. /*
  164.  * createShape - create shape window
  165.  */
  166.  
  167. static  void    createShape(HAB hab)
  168. {
  169.     BITMAPINFOHEADER2   bmi ;
  170.     SHAPEWIN    shpctrl ;
  171.     
  172.     if (hwndFrame == NULLHANDLE) {
  173.         return ;
  174.     }
  175.     if (hpsBitmap == NULLHANDLE || hbmBitmap == NULLHANDLE) {
  176.         return ;
  177.     }
  178.     bmi.cbFix = sizeof(bmi) ;
  179.     GpiQueryBitmapInfoHeader(hbmBitmap, &bmi) ;
  180.     
  181.     /*
  182.      * Register Window Class
  183.      */
  184.      
  185.     WinRegisterClass(hab, ShapeWinName, ShapeWinProc, 0L, sizeof(PVOID)) ;
  186.  
  187.     /*
  188.      * Create Image Window
  189.      */
  190.  
  191.     shpctrl.cx = bmi.cx ;
  192.     shpctrl.cy = bmi.cy ;
  193.     shpctrl.hpsDraw = hpsBitmap ;
  194.     shpctrl.hpsMask = hpsBitmap ;
  195.     
  196.     hwndShape = WinCreateWindow(
  197.             HWND_DESKTOP,           /* Parent Window    */
  198.             ShapeWinName,           /* Window Class     */
  199.         NULL,                   /* Window Text      */
  200.         0,                      /* Window Style     */
  201.         0, 0, 0, 0,             /* Pos & Size       */
  202.         hwndFrame,              /* Owner Window     */
  203.         HWND_TOP,               /* Z-Order          */
  204.         0,                      /* Window ID        */
  205.         &shpctrl,               /* Control Data     */
  206.         NULL) ;                 /* Pres. Param.     */
  207.     
  208.     if (hwndShape == NULLHANDLE) {
  209.         return ;
  210.     }
  211. }
  212.  
  213. /*
  214.  * placeStartup - set startup position
  215.  */
  216.  
  217. static  void    placeStartup(void)
  218. {
  219.     POINTL  pt ;
  220.     SWP     swpScreen ;
  221.     BITMAPINFOHEADER2   bmi ;
  222.     SHORT   x, y ;
  223.     
  224.     if (hbmBitmap == NULLHANDLE || hwndFrame == NULLHANDLE || hwndShape == NULLHANDLE) {
  225.         return ;
  226.     }
  227.     
  228.     bmi.cbFix = sizeof(bmi) ;
  229.     GpiQueryBitmapInfoHeader(hbmBitmap, &bmi) ;
  230.  
  231.     WinQueryPointerPos(HWND_DESKTOP, &pt) ;
  232.     WinQueryWindowPos(HWND_DESKTOP, &swpScreen) ;
  233.  
  234.     x = pt.x ;
  235.     y = pt.y ;
  236.     
  237.     if ((x + bmi.cx) > swpScreen.cx) {
  238.         x = swpScreen.cx - bmi.cx ;
  239.     }
  240.     if ((y + bmi.cy) > swpScreen.cy) {
  241.         y = swpScreen.cy - bmi.cy ;
  242.     }
  243.     
  244.     WinSetWindowPos(hwndFrame, NULLHANDLE, 
  245.             x, y, bmi.cx, bmi.cy, (SWP_MOVE | SWP_SIZE | SWP_HIDE)) ;
  246.     WinSetWindowPos(hwndShape, NULLHANDLE, 
  247.             x, y, bmi.cx, bmi.cy, (SWP_MOVE | SWP_SIZE | SWP_SHOW)) ;
  248. }
  249.  
  250. /*
  251.  * context menu
  252.  */
  253.  
  254. static  HWND    hwndPopup = NULLHANDLE ;    /* context menu */
  255.  
  256. static  void    contextMenu(void)
  257. {
  258.     POINTL  pt   ;
  259.     ULONG   opts ;
  260.     
  261.     if (hwndPopup == NULLHANDLE) {
  262.         hwndPopup = WinLoadMenu(hwndFrame, NULLHANDLE, IDM_POPUP) ;
  263.     }
  264.     if (hwndPopup == NULLHANDLE) {
  265.         printf("failed to load opup menu\n") ;
  266.         return ;
  267.     }
  268.     
  269.     WinQueryPointerPos(HWND_DESKTOP, &pt) ;
  270.  
  271.     opts = PU_HCONSTRAIN | PU_VCONSTRAIN |
  272.          PU_KEYBOARD | PU_MOUSEBUTTON1 | PU_MOUSEBUTTON2 ;
  273.  
  274.     WinPopupMenu(HWND_DESKTOP, hwndFrame, hwndPopup, 
  275.                                 pt.x, pt.y, IDM_HIDE, opts) ;
  276. }
  277.  
  278. /*
  279.  * procFrame - sub-classed frame window procedure for transparent bitmap
  280.  *
  281.  *      bitmap window send messages ti its owner (frame).  process those
  282.  *      messages to perform bitmap display
  283.  */
  284.  
  285. static MRESULT EXPENTRY procFrame(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  286. {
  287.     PSWP    pswp ;
  288.     SHORT   x, y ;
  289.     
  290.     TRACE("frame %08x %08x %08x\n", msg, mp1, mp2) ;
  291.     
  292.     switch (msg) {
  293.         
  294.     case WM_ADJUSTWINDOWPOS :
  295.         pswp = (PSWP) PVOIDFROMMP(mp1) ;
  296.     WinSetWindowPos(hwndShape, pswp->hwndInsertBehind,
  297.                 pswp->x, pswp->y, pswp->cx, pswp->cy, pswp->fl) ;
  298.     pswp->fl &= ~SWP_SHOW ;
  299.     pswp->fl |=  SWP_HIDE ;
  300.     return (*pfnFrame) (hwnd, msg, mp1, mp2) ;
  301.  
  302.     case WM_SINGLESELECT :
  303.         WinSetWindowPos(hwndShape, HWND_TOP, 0, 0, 0, 0, SWP_ZORDER) ;
  304.     return (MRESULT) 0 ;
  305.                 
  306.     case WM_BEGINDRAG :
  307.         WinSendMsg(hwndFrame, WM_TRACKFRAME, 
  308.             MPFROMSHORT(TF_MOVE | TF_SETPOINTERPOS), NULL) ;
  309.         return (MRESULT) 0 ;
  310.  
  311.     case WM_CONTEXTMENU :
  312.         TRACE("WM_CONEXTMENU\n") ;
  313.     contextMenu() ;
  314.         return (MRESULT) 0 ;
  315.     
  316.     case WM_COMMAND :
  317.         switch (SHORT1FROMMP(mp1)) {
  318.     case IDM_HIDE :
  319.         WinShowWindow(hwnd, FALSE) ;
  320.         return (MRESULT) 0 ;
  321.     case IDM_EXIT :
  322.         WinPostMsg(hwnd, WM_CLOSE, NULL, NULL) ;
  323.         return (MRESULT) 0 ;
  324.         }
  325.     }
  326.     return (*pfnFrame) (hwnd, msg, mp1, mp2) ;
  327. }
  328.  
  329. /*
  330.  * main - program start here
  331.  */
  332.  
  333. int     main(int ac, char *av[])
  334. {
  335.     HAB     hab  ;
  336.     HMQ     hmq  ;
  337.     QMSG    qmsg ;
  338.     int     i    ;
  339.     UCHAR   msg[256] ;
  340.  
  341.     myname(av[0]) ;
  342.     _wildcard(&ac, &av) ;
  343.  
  344.     hab = WinInitialize(0) ;
  345.     hmq = WinCreateMsgQueue(hab, 0) ;
  346.     
  347.     /*
  348.      * load given bitmap
  349.      */
  350.      
  351.     for (i = 1, pszBitmap = NULL ; i < ac ; i++) {
  352.         if (pszBitmap == NULL) {
  353.         pszBitmap = av[i] ;
  354.         break ;
  355.     }
  356.     }
  357.     if (pszBitmap == NULL) {
  358.         sprintf(msg, "usage : %s bitmap-file", av[0]) ;
  359.         trMessage(msg) ;
  360.         freeBitmap() ;
  361.         WinDestroyMsgQueue(hmq) ;
  362.         WinTerminate(hab) ;
  363.     return 1 ;
  364.     }
  365.     
  366.     loadBitmap(hab) ;
  367.     
  368.     if (hbmBitmap == NULLHANDLE) {
  369.         trMessage("failed to load bitmap") ;
  370.         freeBitmap() ;
  371.         WinDestroyMsgQueue(hmq) ;
  372.         WinTerminate(hab) ;
  373.     return 1 ;
  374.     }
  375.     
  376.     /*
  377.      * Start Window Processing
  378.      */
  379.  
  380.     createFrame(hab) ;
  381.     createShape(hab) ;
  382.  
  383.     if (hwndFrame == NULLHANDLE || hwndShape == NULLHANDLE) {    
  384.         trMessage("failed to create windows") ;
  385.     if (hwndFrame != NULLHANDLE) WinDestroyWindow(hwndFrame) ;
  386.     if (hwndShape != NULLHANDLE) WinDestroyWindow(hwndShape) ;
  387.         freeBitmap() ;
  388.         WinDestroyMsgQueue(hmq) ;
  389.         WinTerminate(hab) ;
  390.     return 1 ;
  391.     }
  392.     
  393.     placeStartup() ;
  394.     
  395.     while (WinGetMsg(hab, &qmsg, 0, 0, 0)) {
  396.         WinDispatchMsg(hab, &qmsg) ;
  397.     }
  398.  
  399.     /*
  400.      * dispose resources
  401.      */
  402.     
  403.     WinDestroyWindow(hwndFrame)  ;
  404.     WinDestroyWindow(hwndShape) ;
  405.  
  406.     freeBitmap() ;
  407.     
  408.     WinDestroyMsgQueue(hmq) ;
  409.     WinTerminate(hab) ;
  410.     
  411.     return 0 ; 
  412. }
  413.