home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1998 January / Pcwk0198.iso / System / WING / DOGGIE.C_ / DOGGIE.C
C/C++ Source or Header  |  1995-06-20  |  22KB  |  578 lines

  1. /**************************************************************************
  2.  
  3.     DOGGIE.C - a sprite demo for WinG
  4.  
  5.  **************************************************************************/
  6. /**************************************************************************
  7.  
  8.     (C) Copyright 1994 Microsoft Corp.  All rights reserved.
  9.  
  10.     You have a royalty-free right to use, modify, reproduce and 
  11.     distribute the Sample Files (and/or any modified version) in 
  12.     any way you find useful, provided that you agree that 
  13.     Microsoft has no warranty obligations or liability for any 
  14.     Sample Application Files which are modified. 
  15.  
  16.  **************************************************************************/
  17.  
  18. #include <windows.h>
  19. #include "doggie.h"
  20. #include "mmsystem.h"
  21. #include "..\utils\utils.h"
  22. #include <wing.h>
  23.  
  24. /*----------------------------------------------------------------------------*\
  25. |                                                                              |
  26. |   g l o b a l   v a r i a b l e s                                            |
  27. |                                                                              |
  28. \*----------------------------------------------------------------------------*/
  29. static  char  szAppName[]="Doggie: WinG Sprite Demo";
  30.  
  31. static  HINSTANCE hInstApp;
  32. static  HWND      hwndApp;
  33. static  HPALETTE  hpalApp;
  34. static  BOOL      fAppActive;
  35.  
  36. typedef struct header
  37. {
  38.   BITMAPINFOHEADER  Header;
  39.   RGBQUAD           aColors[256];
  40. } header;
  41.  
  42. header    BufferHeader;
  43. long      Orientation = 1;     // assume bottom-up DIBs
  44. void far *pBuffer = 0;
  45. HDC       Buffer = 0;
  46.  
  47. char unsigned TransparentColor = 0xf3;
  48.  
  49. typedef struct pal
  50. {
  51.   WORD Version;
  52.   WORD NumberOfEntries;
  53.   PALETTEENTRY aEntries[256];
  54. } pal;
  55.  
  56. pal LogicalPalette =
  57. {
  58.   0x300,
  59.   256
  60. };
  61.  
  62. HBITMAP  gbmOldMonoBitmap = 0;
  63. PDIB     pBitmap;
  64. int      BitmapX, BitmapY;
  65. int      DogX, DogY;
  66. int      dx,dy;
  67.  
  68.  
  69. /*----------------------------------------------------------------------------*\
  70. |                                                                              |
  71. |   f u n c t i o n   d e f i n i t i o n s                                    |
  72. |                                                                              |
  73. \*----------------------------------------------------------------------------*/
  74.  
  75. LONG FAR PASCAL _export  AppWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam);
  76. LONG  AppCommand (HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam);
  77.  
  78. void  AppExit(void);
  79. BOOL  AppIdle(void);
  80.  
  81. /*----------------------------------------------------------------------------*\
  82. |   AppAbout( hDlg, uiMessage, wParam, lParam )                                |
  83. |                                                                              |
  84. |   Description:                                                               |
  85. |       This function handles messages belonging to the "About" dialog box.    |
  86. |       The only message that it looks for is WM_COMMAND, indicating the user  |
  87. |       has pressed the "OK" button.  When this happens, it takes down         |
  88. |       the dialog box.                                                        |
  89. |                                                                              |
  90. |   Arguments:                                                                 |
  91. |       hDlg            window handle of about dialog window                   |
  92. |       uiMessage       message number                                         |
  93. |       wParam          message-dependent                                      |
  94. |       lParam          message-dependent                                      |
  95. |                                                                              |
  96. |   Returns:                                                                   |
  97. |       TRUE if message has been processed, else FALSE                         |
  98. |                                                                              |
  99. \*----------------------------------------------------------------------------*/
  100. BOOL FAR PASCAL _export AppAbout(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
  101. {
  102.     switch (msg)
  103.     {
  104.         case WM_COMMAND:
  105.       if (LOWORD(wParam) == IDOK)
  106.             {
  107.                 EndDialog(hwnd,TRUE);
  108.             }
  109.             break;
  110.  
  111.         case WM_INITDIALOG:
  112.             return TRUE;
  113.     }
  114.     return FALSE;
  115. }
  116.  
  117. /*----------------------------------------------------------------------------*\
  118. |   AppInit( hInst, hPrev)                                                     |
  119. |                                                                              |
  120. |   Description:                                                               |
  121. |       This is called when the application is first loaded into               |
  122. |       memory.  It performs all initialization that doesn't need to be done   |
  123. |       once per instance.                                                     |
  124. |                                                                              |
  125. |   Arguments:                                                                 |
  126. |       hInstance       instance handle of current instance                    |
  127. |       hPrev           instance handle of previous instance                   |
  128. |                                                                              |
  129. |   Returns:                                                                   |
  130. |       TRUE if successful, FALSE if not                                       |
  131. |                                                                              |
  132. \*----------------------------------------------------------------------------*/
  133. BOOL AppInit(HINSTANCE hInst,HINSTANCE hPrev,int sw,LPSTR szCmdLine)
  134. {
  135.     WNDCLASS cls;
  136.  
  137.     /* Save instance handle for DialogBoxes */
  138.     hInstApp = hInst;
  139.  
  140. // Clear the System Palette so that WinG blting runs at full speed.
  141.     ClearSystemPalette();
  142.  
  143.     if (!hPrev)
  144.     {
  145.         /*
  146.          *  Register a class for the main application window
  147.          */
  148.         cls.hCursor        = LoadCursor(NULL,IDC_ARROW);
  149.         cls.hIcon          = LoadIcon(hInst,"AppIcon");
  150.         cls.lpszMenuName   = "AppMenu";
  151.         cls.lpszClassName  = szAppName;
  152.         cls.hbrBackground  = (HBRUSH) NULL;
  153.         cls.hInstance      = hInst;
  154.         cls.style          = CS_BYTEALIGNCLIENT | CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS;
  155.         cls.lpfnWndProc    = (WNDPROC)AppWndProc;
  156.         cls.cbWndExtra     = 0;
  157.         cls.cbClsExtra     = 0;
  158.  
  159.         if (!RegisterClass(&cls))
  160.             return FALSE;
  161.     }
  162.  
  163.     dx = 400;
  164.     dy = 400;
  165.  
  166.     pBitmap = DibOpenFile("Doggie");      
  167.     
  168.     if (!pBitmap)
  169.       pBitmap = DibOpenFile("doggie2.bmp");
  170.  
  171.     BitmapX = DibWidth(pBitmap);
  172.     BitmapY = DibHeight(pBitmap);
  173.  
  174.     hwndApp = CreateWindow (szAppName,              // Class name
  175.                             szAppName,              // Caption
  176.                             WS_OVERLAPPEDWINDOW,    // Style bits
  177.                             CW_USEDEFAULT, 0,       // Position
  178.                             dx,dy,                  // Size
  179.                             (HWND)NULL,             // Parent window (no parent)
  180.                             (HMENU)NULL,            // use class menu
  181.                             hInst,                  // handle to window instance
  182.                             (LPSTR)NULL             // no params to pass on
  183.                            );
  184.     ShowWindow(hwndApp,sw);
  185.  
  186.     return TRUE;
  187. }
  188.  
  189.  
  190. /*----------------------------------------------------------------------------*\
  191. |   AppExit()                                                                  |
  192. |                                                                              |
  193. |   Description:                                                               |
  194. |     App is just about to exit, cleanup.                                      |
  195. |                                                                              |
  196. \*----------------------------------------------------------------------------*/
  197. void AppExit()
  198. {
  199.   if (Buffer)
  200.   {
  201.     HBITMAP hbm;
  202.  
  203.     //  Retrieve the current WinGBitmap, replace with the original
  204.     hbm = (HBITMAP)SelectObject(Buffer, gbmOldMonoBitmap);
  205.  
  206.     //  And delete the WinGBitmap and WinGDC
  207.     DeleteObject(hbm);
  208.     DeleteDC(Buffer);
  209.   }
  210.  
  211.   if(hpalApp)
  212.   {
  213.     DeleteObject(hpalApp);
  214.   }
  215. }
  216.  
  217. /*----------------------------------------------------------------------------*\
  218. |   WinMain( hInst, hPrev, lpszCmdLine, cmdShow )                              |
  219. |                                                                              |
  220. |   Description:                                                               |
  221. |       The main procedure for the App.  After initializing, it just goes      |
  222. |       into a message-processing loop until it gets a WM_QUIT message         |
  223. |       (meaning the app was closed).                                          |
  224. |                                                                              |
  225. |   Arguments:                                                                 |
  226. |       hInst           instance handle of this instance of the app            |
  227. |       hPrev           instance handle of previous instance, NULL if first    |
  228. |       szCmdLine       ->null-terminated command line                         |
  229. |       cmdShow         specifies how the window is initially displayed        |
  230. |                                                                              |
  231. |   Returns:                                                                   |
  232. |       The exit code as specified in the WM_QUIT message.                     |
  233. |                                                                              |
  234. \*----------------------------------------------------------------------------*/
  235. int PASCAL WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw)
  236. {
  237.     MSG     msg;
  238.  
  239.     /* Call initialization procedure */
  240.     if (!AppInit(hInst,hPrev,sw,szCmdLine))
  241.   return FALSE;
  242.  
  243.     /*
  244.      * Polling messages from event queue
  245.      */
  246.     for (;;)
  247.     {
  248.         if (PeekMessage(&msg, NULL, 0, 0,PM_REMOVE))
  249.         {
  250.             if (msg.message == WM_QUIT)
  251.                 break;
  252.  
  253.             TranslateMessage(&msg);
  254.             DispatchMessage(&msg);
  255.         }
  256.         else
  257.         {
  258.             if (AppIdle())
  259.                 WaitMessage();
  260.         }
  261.     }
  262.  
  263.     AppExit();
  264.     return msg.wParam;
  265. }
  266.  
  267. /*----------------------------------------------------------------------------*\
  268. |   AppIdle()                                                                  |
  269. |                                                                              |
  270. |   Description:                                                               |
  271. |     Place to do idle time stuff.                                             |
  272. |                                                                              |
  273. \*----------------------------------------------------------------------------*/
  274. BOOL AppIdle()
  275. {
  276.     if (fAppActive)
  277.     {
  278.   //
  279.   // we are the foreground app.
  280.   //
  281.   return TRUE;      // nothing to do.
  282.     }
  283.     else
  284.     {
  285.   //
  286.   // we are a background app.
  287.   //
  288.   return TRUE;      // nothing to do.
  289.     }
  290. }
  291.  
  292. /*----------------------------------------------------------------------------*\
  293. |   AppPaint(hwnd, hdc)                                                        |
  294. |                                                                              |
  295. |   Description:                                                               |
  296. |       The paint function.                                                    |
  297. |                                                                              |
  298. |   Arguments:                                                                 |
  299. |       hwnd             window painting into                                  |
  300. |       hdc              display context to paint to                           |
  301. |                                                                              |
  302. \*----------------------------------------------------------------------------*/
  303. AppPaint (HWND hwnd, HDC hdc)
  304. {
  305.   WinGBitBlt(hdc,0,0,dx,dy,Buffer,0,0);
  306.  
  307.   return TRUE;
  308. }
  309.  
  310.  
  311. /*----------------------------------------------------------------------------
  312.  
  313. PaintDoggie
  314.  
  315. */
  316.  
  317.  
  318. void PaintDoggie( HDC Screen, int X, int Y )
  319. {
  320.   int DestinationX = X - BitmapX/2;
  321.   int DestinationY = Y - BitmapY/2;
  322.   int Width = BitmapX;
  323.   int Height = BitmapY;
  324.  
  325.   TransparentDIBits((BITMAPINFO far *)&BufferHeader,pBuffer,X-BitmapX/2,
  326.     Y-BitmapY/2,DibPtr(pBitmap),DibInfo(pBitmap),0,0,DIB_RGB_COLORS,
  327.     TransparentColor);
  328.  
  329.   WinGBitBlt(Screen,DestinationX,DestinationY,Width,Height,
  330.       Buffer,X-BitmapX/2,Y-BitmapY/2);
  331.  
  332. }
  333.  
  334.  
  335. /*----------------------------------------------------------------------------*\
  336. |   AppWndProc( hwnd, uiMessage, wParam, lParam )                              |
  337. |                                                                              |
  338. |   Description:                                                               |
  339. |       The window proc for the app's main (tiled) window.  This processes all |
  340. |       of the parent window's messages.                                       |
  341. |                                                                              |
  342. \*----------------------------------------------------------------------------*/
  343. LONG FAR PASCAL _export AppWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
  344. {
  345.     PAINTSTRUCT ps;
  346.     HDC hdc;
  347.     static int XOffset, YOffset;
  348.     BOOL f;
  349.     DWORD Offset;
  350.     int X;
  351.     int Y;
  352.  
  353.     switch (msg)
  354.     {
  355.         case WM_CREATE:
  356.       break;
  357.  
  358.         case WM_ACTIVATEAPP:
  359.       fAppActive = (BOOL)wParam;
  360.       break;
  361.  
  362.       case WM_SIZE:
  363.         dx = LOWORD(lParam);
  364.         dy = HIWORD(lParam);
  365.  
  366.       if(Buffer)
  367.       {
  368.         HBITMAP hbm;
  369.  
  370.         //  Create a new 8-bit WinGBitmap with the new size
  371.         BufferHeader.Header.biWidth = LOWORD(lParam);
  372.         BufferHeader.Header.biHeight = HIWORD(lParam) * Orientation;
  373.         hbm = WinGCreateBitmap(Buffer,
  374.           (BITMAPINFO far *)&BufferHeader, &pBuffer);
  375.  
  376.         //  Select it in and delete the old one
  377.         hbm = (HBITMAP)SelectObject(Buffer, hbm);
  378.         DeleteObject(hbm);
  379.       }
  380.       else
  381.       {
  382.         //  Create a new WinGDC and 8-bit WinGBitmap
  383.  
  384.         HBITMAP hbm;
  385.           int Counter;
  386.           HDC Screen;
  387.           RGBQUAD far *pColorTable;
  388.  
  389.         //  Get WinG to recommend the fastest DIB format
  390.  
  391.         if(WinGRecommendDIBFormat((BITMAPINFO far *)&BufferHeader))
  392.         {
  393.           //  make sure it's 8bpp and remember the orientation
  394.  
  395.           BufferHeader.Header.biBitCount = 8;
  396.           BufferHeader.Header.biCompression = BI_RGB;
  397.           Orientation = BufferHeader.Header.biHeight;
  398.         }
  399.         else
  400.         {
  401.           //  set it up ourselves
  402.   
  403.           BufferHeader.Header.biSize = sizeof(BITMAPINFOHEADER);
  404.           BufferHeader.Header.biPlanes = 1;
  405.           BufferHeader.Header.biBitCount = 8;
  406.           BufferHeader.Header.biCompression = BI_RGB;
  407.           BufferHeader.Header.biSizeImage = 0;
  408.           BufferHeader.Header.biClrUsed = 0;
  409.           BufferHeader.Header.biClrImportant = 0;
  410.         }
  411.  
  412.         BufferHeader.Header.biWidth = LOWORD(lParam);
  413.         BufferHeader.Header.biHeight = HIWORD(lParam) * Orientation;
  414.  
  415.         //  create an identity palette from the DIB's color table
  416.  
  417.         //  get the 20 system colors as PALETTEENTRIES
  418.     
  419.           Screen = GetDC(0);
  420.  
  421.           GetSystemPaletteEntries(Screen,0,10,LogicalPalette.aEntries);
  422.           GetSystemPaletteEntries(Screen,246,10,
  423.                 LogicalPalette.aEntries + 246);
  424.  
  425.         ReleaseDC(0,Screen);
  426.  
  427.         // initialize the logical palette and DIB color table
  428.  
  429.           for(Counter = 0;Counter < 10;Counter++)
  430.           {
  431.             // copy the system colors into the DIB header
  432.             // WinG will do this in WinGRecommendDIBFormat,
  433.             // but it may have failed above so do it here anyway
  434.             
  435.             BufferHeader.aColors[Counter].rgbRed =
  436.                     LogicalPalette.aEntries[Counter].peRed;
  437.             BufferHeader.aColors[Counter].rgbGreen =
  438.                     LogicalPalette.aEntries[Counter].peGreen;
  439.             BufferHeader.aColors[Counter].rgbBlue =
  440.                     LogicalPalette.aEntries[Counter].peBlue;
  441.             BufferHeader.aColors[Counter].rgbReserved = 0;
  442.  
  443.             LogicalPalette.aEntries[Counter].peFlags = 0;
  444.  
  445.             BufferHeader.aColors[Counter + 246].rgbRed =
  446.                   LogicalPalette.aEntries[Counter + 246].peRed;
  447.             BufferHeader.aColors[Counter + 246].rgbGreen =
  448.                   LogicalPalette.aEntries[Counter + 246].peGreen;
  449.             BufferHeader.aColors[Counter + 246].rgbBlue =
  450.                   LogicalPalette.aEntries[Counter + 246].peBlue;
  451.             BufferHeader.aColors[Counter + 246].rgbReserved = 0;
  452.  
  453.             LogicalPalette.aEntries[Counter + 246].peFlags = 0;
  454.           }
  455.  
  456.  
  457.           pColorTable = (RGBQUAD far *)
  458.             ((char far *)pBitmap + pBitmap->biSize);
  459.  
  460.           for(Counter = 10;Counter < 246;Counter++)
  461.           {
  462.             // copy from the original color table to the WinGBitmap's
  463.             // color table and the logical palette
  464.  
  465.             BufferHeader.aColors[Counter].rgbRed =
  466.               LogicalPalette.aEntries[Counter].peRed =
  467.                 pColorTable[Counter].rgbRed;
  468.             BufferHeader.aColors[Counter].rgbGreen =
  469.               LogicalPalette.aEntries[Counter].peGreen =
  470.                 pColorTable[Counter].rgbGreen;
  471.             BufferHeader.aColors[Counter].rgbBlue =
  472.               LogicalPalette.aEntries[Counter].peBlue =
  473.                 pColorTable[Counter].rgbBlue;
  474.             BufferHeader.aColors[Counter].rgbReserved = 0;
  475.             LogicalPalette.aEntries[Counter].peFlags = PC_NOCOLLAPSE;
  476.           }
  477.  
  478.           hpalApp = CreatePalette((LOGPALETTE far *)&LogicalPalette);
  479.           
  480.         //  Create a WinGDC and Bitmap, then select away
  481.         Buffer = WinGCreateDC();
  482.         hbm = WinGCreateBitmap(Buffer,
  483.           (BITMAPINFO far *)&BufferHeader, &pBuffer);
  484.  
  485.         //  Store the old hbitmap to select back in before deleting
  486.         gbmOldMonoBitmap = (HBITMAP)SelectObject(Buffer, hbm);
  487.       }
  488.  
  489.       PatBlt(Buffer, 0,0,dx,dy, BLACKNESS);
  490.  
  491.       //  Stick the doggie into the center of the buffer
  492.       TransparentDIBits((BITMAPINFO far *)&BufferHeader,pBuffer,
  493.         dx/2-BitmapX/2,dy/2-BitmapY/2,DibPtr(pBitmap),DibInfo(pBitmap),
  494.         DIB_RGB_COLORS,0,0,TransparentColor);
  495.             break;
  496.         case WM_MOUSEMOVE:
  497.           if(GetKeyState(VK_LBUTTON) < 0)
  498.           {
  499.             hdc = GetDC(hwnd);
  500.             Offset = GetViewportOrg(hdc);
  501.             XOffset = LOWORD(Offset);
  502.             YOffset = HIWORD(Offset);
  503.           
  504.                 X = LOWORD(lParam);
  505.                 Y = HIWORD(lParam);
  506.  
  507.         SelectPalette(hdc,hpalApp,FALSE);
  508.         RealizePalette(hdc);
  509.             PaintDoggie(hdc,X - XOffset,Y - YOffset);
  510.             ReleaseDC(hwnd,hdc);
  511.           }
  512.  
  513.           break;
  514.  
  515.         case WM_COMMAND:
  516.             return AppCommand(hwnd,msg,wParam,lParam);
  517.  
  518.     case WM_DESTROY:
  519.             PostQuitMessage(0);
  520.             break;
  521.  
  522.         case WM_CLOSE:
  523.       break;
  524.  
  525.         case WM_PALETTECHANGED:
  526.       if ((HWND)wParam == hwnd)
  527.     break;
  528.  
  529.       // fall through to WM_QUERYNEWPALETTE
  530.  
  531.   case WM_QUERYNEWPALETTE:
  532.       hdc = GetDC(hwnd);
  533.  
  534.       if (hpalApp)
  535.     SelectPalette(hdc, hpalApp, FALSE);
  536.  
  537.       f = RealizePalette(hdc);
  538.       ReleaseDC(hwnd,hdc);
  539.  
  540.       if (f)
  541.     InvalidateRect(hwnd,NULL,TRUE);
  542.  
  543.       return f;
  544.  
  545.         case WM_PAINT:
  546.       hdc = BeginPaint(hwnd,&ps);
  547.      SelectPalette(hdc, hpalApp, FALSE);
  548.      RealizePalette(hdc);
  549.       AppPaint (hwnd,hdc);
  550.             EndPaint(hwnd,&ps);
  551.             return 0L;
  552.     }
  553.     return DefWindowProc(hwnd,msg,wParam,lParam);
  554. }
  555.  
  556. /*----------------------------------------------------------------------------*\
  557. |   AppCommand(hwnd, msg, wParam, lParam )                                     |
  558. |                                                                              |
  559. |   Description:                                                               |
  560. |     Handles WM_COMMAND messages for the main window (hwndApp)                |
  561. |   of the parent window's messages.                                           |
  562. |                                                                              |
  563. \*----------------------------------------------------------------------------*/
  564. LONG AppCommand (HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
  565. {
  566.     switch(wParam)
  567.     {
  568.         case MENU_ABOUT:
  569.             DialogBox(hInstApp,"AppAbout",hwnd,(DLGPROC)AppAbout);
  570.             break;
  571.  
  572.         case MENU_EXIT:
  573.             PostMessage(hwnd,WM_CLOSE,0,0L);
  574.             break;
  575.     }
  576.     return 0L;
  577. }
  578.