home *** CD-ROM | disk | FTP | other *** search
/ Multimedia Jumpstart / Multimedia Microsoft Jumpstart Version 1.1a (Microsoft).BIN / develpmt / source / blt / qa.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-02-08  |  35.7 KB  |  1,190 lines

  1. /*----------------------------------------------------------------------------*\
  2. |   qa.c - A template for a Windows application                                |
  3. |                                                                              |
  4. |   History:                                                                   |
  5. |       01/01/88 toddla     Created                                            |
  6. |                                                                              |
  7. \*----------------------------------------------------------------------------*/
  8.  
  9. #include <windows.h>
  10. #include <windowsx.h>
  11. #include <commdlg.h>
  12. #include <mmsystem.h>   // for timeGetTime()
  13. #include <stdlib.h>     // for rand()
  14. #include "qa.h"
  15. #include "dib.h"
  16.  
  17. #ifdef WIN32
  18.     // unless you have Win32s 1.1 timeGetTime() does not work
  19. //  #define timeGetTime()   GetTickCount()
  20. #endif
  21.  
  22. /*----------------------------------------------------------------------------*\
  23. |                                                                              |
  24. |   g l o b a l   v a r i a b l e s                                            |
  25. |                                                                              |
  26. \*----------------------------------------------------------------------------*/
  27. static  char    szAppName[]="Blt App";
  28. static  char    szAppFilter[]="Bitmaps\0*.bmp;*.dib\0All Files\0*.*\0";
  29.  
  30. static  HINSTANCE hInstApp;
  31. static  HWND      hwndApp;
  32. static  HACCEL    hAccelApp;
  33. static    HPALETTE  hpalApp;
  34. static  HPALETTE  hpalBack;
  35. static    BOOL      fAppActive;
  36. static  BOOL      gfBackPal;
  37. static  BOOL      gfClipping;
  38. static  BOOL      gfStretch;
  39. static  BOOL      gfMirror;
  40.  
  41. #ifdef WIN32
  42.     #define _export
  43. #else
  44.     #define SetPixelV   SetPixel
  45. #endif
  46.  
  47. struct {
  48.     BITMAPINFOHEADER bi;
  49.     RGBQUAD          argb[256];
  50. }   biApp;
  51.  
  52. static LPBITMAPINFOHEADER lpbiApp;
  53. static HBITMAP hbmApp;
  54. static HBITMAP hbmDS;        // from CreateDIBSection
  55. static HDC     hdcApp;
  56. static HDC     hdcDS;
  57.  
  58. static BITMAP  bm;
  59. static DWORD   SizeImage;
  60. static DWORD   OffsetScan0;
  61. static LPBYTE  lpBitmapBits;
  62. static LPVOID  lpDibBits;
  63. static LPBYTE  BitmapTranslate;
  64.  
  65. typedef void (*PDraw)(HDC hdc, int x, int y, int dx, int dy);
  66.  
  67. void DrawRGB(HDC hdc, int x, int y, int dx, int dy);
  68. void DrawPAL(HDC hdc, int x, int y, int dx, int dy);
  69. void DrawIDX(HDC hdc, int x, int y, int dx, int dy);
  70.  
  71. void DrawDRGB(HDC hdc, int x, int y, int dx, int dy);
  72. void DrawDPAL(HDC hdc, int x, int y, int dx, int dy);
  73. void DrawDIDX(HDC hdc, int x, int y, int dx, int dy);
  74.  
  75. void DrawBLTDS(HDC hdc, int x, int y, int dx, int dy);
  76. void DrawBLT(HDC hdc, int x, int y, int dx, int dy);
  77. void DrawSBDS(HDC hdc, int x, int y, int dx, int dy);
  78. void DrawSB(HDC hdc, int x, int y, int dx, int dy);
  79. void DrawDEV(HDC hdc, int x, int y, int dx, int dy);
  80. void DrawSETBLT(HDC hdc, int x, int y, int dx, int dy);
  81. void DrawSETDIB(HDC hdc, int x, int y, int dx, int dy);
  82. void DrawXLATBLT(HDC hdc, int x, int y, int dx, int dy);
  83. void DrawCOPYBLT(HDC hdc, int x, int y, int dx, int dy);
  84.  
  85. BOOL IsWin32s()
  86. {
  87.     return LOBYTE(GetVersion()) == 3 && (GetVersion() & 0x80000000l);
  88. }
  89.  
  90. //
  91. // are we able to use DIB_PAL_INDICES
  92. //
  93. BOOL InitIDX()  {return !IsWin32s();}
  94.  
  95. //
  96. // stuff to test CreateDIBSection
  97. //
  98. static HBITMAP (WINAPI *XCreateDIBSection)(HDC, LPBITMAPINFO, UINT, LPVOID FAR *, HANDLE, DWORD);
  99. #define CreateDIBSection XCreateDIBSection
  100.  
  101. #ifdef WIN32
  102.     #define GDIMOD    "GDI32"
  103. #else
  104.     #define GDIMOD     "GDI"
  105. #endif
  106.  
  107. static BOOL InitDS()
  108. {
  109.     (FARPROC&)XCreateDIBSection = GetProcAddress(GetModuleHandle(GDIMOD), "CreateDIBSection");
  110.     return XCreateDIBSection != NULL;
  111. }
  112.  
  113. static UINT     RandomSeed;
  114.  
  115. struct {
  116.     PDraw Draw;
  117.     BOOL (*Init)(void);
  118.     char *      szName;
  119.     DWORD       time;
  120.     int         count;
  121. }   aDraw[] = {
  122.     //
  123.     // BitBlt and StretchBlt for comparing.
  124.     //
  125.         DrawBLT,NULL,    "BitBlt                     ",0,0,
  126.         DrawSB, NULL,    "StretchBlt                 ",0,0,
  127.  
  128.     //
  129.     // CreateDIBSection.
  130.     //
  131.         DrawBLTDS, InitDS,  "BitBlt (DIBSection)        ",0,0,
  132.         DrawSBDS,  InitDS,  "StretchBlt (DIBSection)    ",0,0,
  133.  
  134.     //
  135.     //    SetDIBitsToDevice
  136.     //
  137.         DrawRGB,NULL,    "DibToDevice (RGB)    ",0,0,
  138.         DrawPAL,NULL,    "DibToDevice (PAL)    ",0,0,
  139. #ifdef WIN32
  140.         DrawIDX,InitIDX, "DibToDevice (IDX)    ",0,0,
  141. #endif
  142.     //
  143.     //    StretchDIBits, should be the same 
  144.     //
  145.         DrawDRGB,NULL,   "StretchDIBits (RGB)        ",0,0,
  146.         DrawDPAL,NULL,   "StretchDIBits (PAL)        ",0,0,
  147. #ifdef WIN32
  148.         DrawDIDX,InitIDX,"StretchDIBits (IDX)        ",0,0,
  149. #endif
  150.  
  151.     //
  152.     // versions of set+BitBlt
  153.     //
  154. #ifndef WIN32
  155.         //  uses .ASM code
  156.         DrawXLATBLT,NULL,"XlatBits + BitBlt",0,0,
  157.         DrawCOPYBLT,NULL,"CopyBits + BitBlt",0,0,
  158. #endif
  159.         DrawSETBLT,NULL, "SetBitmapBits + BitBlt     ",0,0,
  160.         DrawSETDIB,NULL, "SetDIBits + BitBlt         ",0,0,
  161. };
  162.  
  163. #define NUM_DRAW    (sizeof(aDraw) / sizeof(aDraw[0]))
  164.  
  165. /*----------------------------------------------------------------------------*\
  166. \*----------------------------------------------------------------------------*/
  167.  
  168. static int iDraw;
  169. static PDraw Draw;
  170.  
  171. void SetDraw(int i)
  172. {
  173.     char ach[128];
  174.  
  175.     if (aDraw[i].Draw == NULL)
  176.         return;
  177.  
  178.     iDraw = i;
  179.     Draw = aDraw[i].Draw;
  180.     wsprintf(ach, "%s - %s", (LPSTR)szAppName, (LPSTR)aDraw[i].szName);
  181.     SetWindowText(hwndApp, ach);
  182. }
  183.  
  184. /*----------------------------------------------------------------------------*\
  185. |                                                                              |
  186. |   f u n c t i o n   d e f i n i t i o n s                                    |
  187. |                                                                              |
  188. \*----------------------------------------------------------------------------*/
  189.  
  190. LONG FAR PASCAL _export AppWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam);
  191. int  ErrMsg (LPSTR sz,...);
  192. LONG AppCommand (HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam);
  193.  
  194. void AppExit(void);
  195. BOOL AppIdle(void);
  196. void AppOpenFile(HWND hwnd, LPSTR szFileName);
  197.  
  198. HPALETTE Create666Palette(void);
  199.  
  200. /*----------------------------------------------------------------------------*\
  201. |   AppAbout( hDlg, uiMessage, wParam, lParam )                                |
  202. |                                                                              |
  203. |   Description:                                                               |
  204. |       This function handles messages belonging to the "About" dialog box.    |
  205. |       The only message that it looks for is WM_COMMAND, indicating the use   |
  206. |       has pressed the "OK" button.  When this happens, it takes down         |
  207. |       the dialog box.                                                        |
  208. |                                                                              |
  209. |   Arguments:                                                                 |
  210. |       hDlg            window handle of about dialog window                   |
  211. |       uiMessage       message number                                         |
  212. |       wParam          message-dependent                                      |
  213. |       lParam          message-dependent                                      |
  214. |                                                                              |
  215. |   Returns:                                                                   |
  216. |       TRUE if message has been processed, else FALSE                         |
  217. |                                                                              |
  218. \*----------------------------------------------------------------------------*/
  219. BOOL FAR PASCAL _export AppAbout(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
  220. {
  221.     switch (msg)
  222.     {
  223.         case WM_COMMAND:
  224.         if (LOWORD(wParam) == IDOK)
  225.             {
  226.                 EndDialog(hwnd,TRUE);
  227.             }
  228.             break;
  229.  
  230.         case WM_INITDIALOG:
  231.             return TRUE;
  232.     }
  233.     return FALSE;
  234. }
  235.  
  236. /*----------------------------------------------------------------------------*\
  237. |   AppInit( hInst, hPrev)                                                     |
  238. |                                                                              |
  239. |   Description:                                                               |
  240. |       This is called when the application is first loaded into               |
  241. |       memory.  It performs all initialization that doesn't need to be done   |
  242. |       once per instance.                                                     |
  243. |                                                                              |
  244. |   Arguments:                                                                 |
  245. |       hInstance       instance handle of current instance                    |
  246. |       hPrev           instance handle of previous instance                   |
  247. |                                                                              |
  248. |   Returns:                                                                   |
  249. |       TRUE if successful, FALSE if not                                       |
  250. |                                                                              |
  251. \*----------------------------------------------------------------------------*/
  252. BOOL AppInit(HINSTANCE hInst,HINSTANCE hPrev,int sw,LPSTR szCmdLine)
  253. {
  254.     WNDCLASS cls;
  255.     int      dx,dy;
  256.     int      i;
  257.  
  258.     /* Save instance handle for DialogBoxs */
  259.     hInstApp = hInst;
  260.  
  261.     hAccelApp = LoadAccelerators(hInst, "AppAccel");
  262.  
  263.     if (!hPrev)
  264.     {
  265.         /*
  266.          *  Register a class for the main application window
  267.          */
  268.         cls.hCursor        = LoadCursor(NULL,IDC_ARROW);
  269.         cls.hIcon          = LoadIcon(hInst,"AppIcon");
  270.         cls.lpszMenuName   = "AppMenu";
  271.         cls.lpszClassName  = szAppName;
  272.         cls.hbrBackground  = (HBRUSH)(COLOR_WINDOW + 1);
  273.         cls.hInstance      = hInst;
  274.         cls.style          = CS_BYTEALIGNCLIENT | CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS;
  275.         cls.lpfnWndProc    = (WNDPROC)AppWndProc;
  276.         cls.cbWndExtra     = 0;
  277.         cls.cbClsExtra     = 0;
  278.  
  279.         if (!RegisterClass(&cls))
  280.             return FALSE;
  281.     }
  282.  
  283.     dx = GetSystemMetrics (SM_CXSCREEN) / 2;
  284.     dy = GetSystemMetrics (SM_CYSCREEN) / 2;
  285.  
  286.     hwndApp = CreateWindow (szAppName,    // Class name
  287.                             szAppName,              // Caption
  288.                             WS_OVERLAPPEDWINDOW,    // Style bits
  289.                             CW_USEDEFAULT, 0,       // Position
  290.                 dx,dy,            // Size
  291.                             (HWND)NULL,             // Parent window (no parent)
  292.                             (HMENU)NULL,            // use class menu
  293.                             hInst,                  // handle to window instance
  294.                             (LPSTR)NULL             // no params to pass on
  295.                            );
  296.     ShowWindow(hwndApp,sw);
  297.  
  298.     //
  299.     // init every thing.
  300.     //                   
  301.     for (i=0; i<NUM_DRAW; i++)
  302.     {
  303.         if (aDraw[i].Init && !aDraw[i].Init())
  304.             aDraw[i].Draw = NULL;
  305.     }
  306.                
  307.     if (*szCmdLine)
  308.         AppOpenFile(hwndApp, szCmdLine);
  309.     else
  310.         AppOpenFile(hwndApp, "Herman");
  311.  
  312.     RandomSeed = (UINT)timeGetTime();
  313.     srand(RandomSeed);
  314.  
  315.     hpalBack = Create666Palette();
  316.  
  317.     //
  318.     // build the draw menu.
  319.     //
  320.     HMENU hmenu = GetSubMenu(GetMenu(hwndApp), 1);
  321.     DeleteMenu(hmenu, MENU_DRAW, MF_BYCOMMAND);
  322.  
  323.     for (i=0; i<NUM_DRAW; i++)
  324.     {
  325.         AppendMenu(hmenu, 0, MENU_DRAW+i, aDraw[i].szName);
  326.     }
  327.  
  328.     AppendMenu(hmenu, MF_SEPARATOR, -1, NULL);
  329.     AppendMenu(hmenu, 0, MENU_BACKPAL, "Background Pal");
  330.     AppendMenu(hmenu, 0, MENU_CLIP, "Clipping");
  331.     AppendMenu(hmenu, 0, MENU_STRETCH, "Stretch");
  332.     AppendMenu(hmenu, 0, MENU_MIRROR, "Mirror");
  333.  
  334.     // pick a default.
  335.     SetDraw(0);
  336.  
  337.     return TRUE;
  338. }
  339.  
  340.  
  341. /*----------------------------------------------------------------------------*\
  342. |   AppExit()                                       |
  343. |                                                                              |
  344. |   Description:                                                               |
  345. |    app is just about to exit, cleanup                       |
  346. |                                                                              |
  347. \*----------------------------------------------------------------------------*/
  348. void AppExit()
  349. {
  350.     DeleteObject(hpalBack);
  351.     AppOpenFile(hwndApp, NULL);
  352. }
  353.  
  354. /*----------------------------------------------------------------------------*\
  355. \*----------------------------------------------------------------------------*/
  356.  
  357. #define RandRGB() RGB(rand() % 256, rand() % 256, rand() % 256)
  358. #define RandPT(pt, rc) ((pt).x = rc.left + (rand() % (rc.right-rc.left))), ((pt).y = rc.top + (rand() % (rc.bottom-rc.top)))
  359.  
  360. RECT    rcRand;
  361. RECT    rcApp;
  362. RECT    rcApp2;
  363.  
  364. void InitDC(HDC hdc)
  365. {
  366.     if (gfBackPal)
  367.     {
  368.         SelectPalette(hdc, hpalBack, FALSE);
  369.         RealizePalette(hdc);
  370.  
  371.         SelectPalette(hdc, hpalApp, TRUE);
  372.         RealizePalette(hdc);
  373.     }
  374.     else
  375.     {
  376.         SelectPalette(hdc, hpalApp, FALSE);
  377.         RealizePalette(hdc);
  378.     }
  379.  
  380.     SetStretchBltMode(hdc, COLORONCOLOR);
  381. }
  382.  
  383. void DrawRandom(HDC hdc)
  384. {
  385.     BOOL f;
  386.     POINT pt;
  387.     POINT ptW;
  388.     int dx,dy;
  389.  
  390.     if (f = (hdc == NULL))
  391.     {
  392.         hdc = GetDC(hwndApp);
  393.         InitDC(hdc);
  394.     }
  395.  
  396.     if (gfStretch)
  397.     {
  398.         RandPT(pt, rcApp);
  399.  
  400.         if (gfClipping)
  401.             RandPT(ptW, rcApp2);
  402.         else
  403.             RandPT(ptW, rcApp);
  404.  
  405.         dx = ptW.x - pt.x;
  406.         dy = ptW.y - pt.y;
  407.  
  408.         if (!gfMirror)
  409.         {
  410.             if (dx < 0)
  411.                 pt.x = ptW.x, dx = -dx;
  412.  
  413.             if (dy < 0)
  414.                 pt.y = ptW.y, dy = -dy;
  415.         }
  416.     }
  417.     else
  418.     {
  419.         RandPT(pt, rcRand);
  420.  
  421.         dx = bm.bmWidth;
  422.         dy = bm.bmHeight;
  423.     }
  424.  
  425.     Draw(hdc, pt.x, pt.y, dx, dy);
  426.  
  427.     if (f)
  428.         ReleaseDC(hwndApp, hdc);
  429. }
  430.  
  431. void CopyText(LPSTR pch)
  432. {
  433.     HANDLE h = GlobalAlloc(GHND, lstrlen(pch+1));
  434.     lstrcpy((LPSTR)GlobalLock(h), pch);
  435.     OpenClipboard(hwndApp);
  436.     EmptyClipboard();
  437.     SetClipboardData(CF_TEXT, h);
  438.     CloseClipboard();
  439. }
  440.  
  441. /*----------------------------------------------------------------------------*\
  442. |   TimeIt()                                                                 |
  443. \*----------------------------------------------------------------------------*/
  444.  
  445. #define N 100
  446.  
  447. #define FPS(time,n) \
  448.             time ? (1000l * n / time) : 0, \
  449.             time ? (1000000l * n / time) % 1000: 0
  450.  
  451. char achMsg[2048];
  452.  
  453. void TimeIt()
  454. {
  455.     HDC hdc;
  456.     LONG time;
  457.     int i,n;
  458.     char *pch;
  459.     HCURSOR hcur;
  460.     int iDrawSave;
  461.  
  462.     InvalidateRect(hwndApp, NULL, TRUE);
  463.     UpdateWindow(hwndApp);
  464.  
  465.     hdc = GetDC(hwndApp);
  466.     InitDC(hdc);
  467.  
  468.     hcur = SetCursor(NULL);
  469.  
  470.     iDrawSave = iDraw;
  471.  
  472.     for (n=0; n<NUM_DRAW; n++)
  473.     {
  474.         if (aDraw[n].Draw == NULL)
  475.             continue;
  476.  
  477.         SetDraw(n);
  478.  
  479.         srand(RandomSeed);
  480.  
  481.         time = timeGetTime();
  482.  
  483.         for (i=0; i<N; i++)
  484.         {
  485.             DrawRandom(hdc);
  486.         }
  487.  
  488.         time = timeGetTime() - time;
  489.  
  490.         aDraw[n].time = time;
  491.         aDraw[n].count = N;
  492.     }
  493.  
  494.     SetDraw(iDrawSave);
  495.     SetCursor(hcur);
  496.     ReleaseDC(hwndApp, hdc);
  497.  
  498.     pch = achMsg;
  499.  
  500.     for (n=0; n<NUM_DRAW; n++)
  501.     {
  502.         if (aDraw[n].Draw == NULL)
  503.             continue;
  504.  
  505.         pch += wsprintf(pch, "%-40s\t%3ld.%03ld fps\r\n", (LPSTR)aDraw[n].szName, FPS(aDraw[n].time,N));
  506.     }
  507.  
  508.     CopyText(achMsg);
  509.  
  510.     ErrMsg(achMsg);
  511. }
  512.  
  513. /*----------------------------------------------------------------------------*\
  514. |   WinMain( hInst, hPrev, lpszCmdLine, cmdShow )                              |
  515. |                                                                              |
  516. |   Description:                                                               |
  517. |       The main procedure for the App.  After initializing, it just goes      |
  518. |       into a message-processing loop until it gets a WM_QUIT message         |
  519. |       (meaning the app was closed).                                          |
  520. |                                                                              |
  521. |   Arguments:                                                                 |
  522. |       hInst           instance handle of this instance of the app            |
  523. |       hPrev           instance handle of previous instance, NULL if first    |
  524. |       szCmdLine       ->null-terminated command line                         |
  525. |       cmdShow         specifies how the window is initially displayed        |
  526. |                                                                              |
  527. |   Returns:                                                                   |
  528. |       The exit code as specified in the WM_QUIT message.                     |
  529. |                                                                              |
  530. \*----------------------------------------------------------------------------*/
  531. int PASCAL WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw)
  532. {
  533.     MSG     msg;
  534.  
  535.     /* Call initialization procedure */
  536.     if (!AppInit(hInst,hPrev,sw,szCmdLine))
  537.     return FALSE;
  538.  
  539.     /*
  540.      * Polling messages from event queue
  541.      */
  542.     for (;;)
  543.     {
  544.         if (PeekMessage(&msg, NULL, 0, 0,PM_REMOVE))
  545.         {
  546.             if (msg.message == WM_QUIT)
  547.                 break;
  548.  
  549.         if (hAccelApp && TranslateAccelerator(hwndApp, hAccelApp, &msg))
  550.         continue;
  551.  
  552.             TranslateMessage(&msg);
  553.             DispatchMessage(&msg);
  554.         }
  555.         else
  556.     {
  557.         if (AppIdle())
  558.                 WaitMessage();
  559.         }
  560.     }
  561.  
  562.     AppExit();
  563.     return msg.wParam;
  564. }
  565.  
  566. /*----------------------------------------------------------------------------*\
  567. |   AppIdle()                                       |
  568. |                                                                              |
  569. |   Description:                                                               |
  570. |    place to do idle time stuff.                           |
  571. |                                                                              |
  572. |   Returns:                                       |
  573. |    RETURN TRUE IF YOU HAVE NOTHING TO DO OTHERWISE YOUR APP WILL BE A     |
  574. |    CPU PIG!                                   |
  575. \*----------------------------------------------------------------------------*/
  576. BOOL AppIdle()
  577. {
  578.     if (fAppActive)
  579.     {
  580.     //
  581.     // we are the foreground app.
  582.         //
  583.         if (lpbiApp)
  584.         {
  585.             DrawRandom(NULL);
  586.             return FALSE;
  587.         }
  588.  
  589.     return TRUE;        // nothing to do.
  590.     }
  591.     else
  592.     {
  593.     //
  594.     // we are a background app.
  595.     //
  596.     return TRUE;        // nothing to do.
  597.     }
  598. }
  599.  
  600. /*----------------------------------------------------------------------------*\
  601. |   AppOpenFile()                                   |
  602. |                                                                              |
  603. |   Description:                                                               |
  604. |    open a file stupid                               |
  605. |                                                                              |
  606. \*----------------------------------------------------------------------------*/
  607. void AppOpenFile(HWND hwnd, LPSTR szFileName)
  608. {
  609.     HDC hdc;
  610.     LPVOID lpBits;
  611.  
  612.     if (hpalApp) DeleteObject(hpalApp);
  613.     if (hdcApp)  DeleteObject(hdcApp);
  614.     if (hbmApp)  DeleteObject(hbmApp);
  615.     if (hdcDS)   DeleteObject(hdcDS);
  616.     if (hbmDS)   DeleteObject(hbmDS);
  617.     if (lpbiApp) DibFree(lpbiApp);
  618.  
  619.     hpalApp  = NULL;
  620.     lpbiApp  = NULL;
  621.     hbmApp   = NULL;
  622.     hdcApp   = NULL;
  623.  
  624.     if (szFileName == NULL)
  625.         return;
  626.  
  627.     lpbiApp = DibOpenFile(szFileName);
  628.  
  629.     if (lpbiApp == NULL)
  630.     {
  631.         ErrMsg("Cant open %s", szFileName);
  632.         return;
  633.     }
  634.  
  635.     //
  636.     // get the palette
  637.     //
  638.     hpalApp = DibCreatePalette(lpbiApp);
  639.  
  640.     //
  641.     //  make this a identity palette for fast drawing.
  642.     //
  643.     MakeIdentityPalette(hpalApp);
  644.     DibMapToPalette(lpbiApp, hpalApp);
  645.  
  646.     //
  647.     // convert to a bitmap
  648.     //
  649.     hbmApp = BitmapFromDib(lpbiApp, hpalApp, DIB_RGB_COLORS);
  650.  
  651.     //
  652.     // bitmap stuff.
  653.     //
  654.     GetObject(hbmApp, sizeof(bm), (LPVOID)&bm);
  655.     SizeImage = (DWORD)(UINT)bm.bmHeight * (DWORD)(UINT)bm.bmWidthBytes;
  656.     lpBitmapBits = (LPBYTE)GlobalAllocPtr(GHND, SizeImage);
  657.     BitmapTranslate = (LPBYTE)GlobalAllocPtr(GHND, 256);
  658.  
  659.     OffsetScan0 = SizeImage - bm.bmWidthBytes;
  660.     GetBitmapBits(hbmApp, SizeImage, lpBitmapBits);
  661.  
  662.     lpDibBits = DibPtr(lpbiApp);
  663.  
  664.     //
  665.     // we will use DIB_PAL_COLORS to draw DIBs
  666.     //
  667.     hmemcpy(&biApp, lpbiApp, sizeof(biApp));        //save RGB colors
  668.     DibSetUsage(lpbiApp, hpalApp, DIB_PAL_COLORS);
  669.  
  670.     //
  671.     // make memory DCs for easy access.
  672.     //
  673.     hdc = GetDC(NULL);
  674.  
  675.     //
  676.     // make a DIBSECTION
  677.     //
  678.     if (XCreateDIBSection != NULL)
  679.     {
  680.         hbmDS = CreateDIBSection(hdc, (LPBITMAPINFO)&biApp,  DIB_RGB_COLORS, &lpBits, NULL, 0);
  681. ////    hbmDS = CreateDIBSection(hdc, (LPBITMAPINFO)&biApp,  DIB_PAL_INDICIES, &lpBits, NULL, 0);
  682. ////    hbmDS = CreateDIBSection(hdc, (LPBITMAPINFO)lpbiApp, DIB_PAL_COLORS, &lpBits, NULL, 0);
  683.         GetObject(hbmDS, sizeof(bm), (LPVOID)&bm);
  684.  
  685.         hdcDS = CreateCompatibleDC(hdc);
  686.  
  687.         //
  688.         // copy the bits.
  689.         //
  690.         SetDIBits(hdcDS, hbmDS, 0, bm.bmHeight,
  691.             DibPtr(lpbiApp), (LPBITMAPINFO)&biApp, DIB_RGB_COLORS);
  692.  
  693.         SelectObject(hdcDS, hbmDS);
  694.     }
  695.     
  696.     for (int i=0; i<256; i++)
  697.         BitmapTranslate[i] = i;
  698.  
  699.     hdcApp = CreateCompatibleDC(hdc);
  700.     ReleaseDC(NULL, hdc);
  701.  
  702.     SelectObject(hdcApp, hbmApp);
  703.     SelectPalette(hdcApp, hpalApp, FALSE);
  704.     RealizePalette(hdcApp);
  705.  
  706.     SendMessage(hwndApp, WM_SIZE, 0, 0);
  707. }
  708.  
  709. /*----------------------------------------------------------------------------*\
  710. |   AppPaint(hwnd, hdc)                                                        |
  711. |                                                                              |
  712. |   Description:                                                               |
  713. |       The paint function.  Right now this does nothing.                      |
  714. |                                                                              |
  715. |   Arguments:                                                                 |
  716. |       hwnd             window painting into                                  |
  717. |       hdc              display context to paint to                           |
  718. |                                                                              |
  719. |   Returns:                                                                   |
  720. |       nothing                                                                |
  721. |                                                                              |
  722. \*----------------------------------------------------------------------------*/
  723. AppPaint (HWND hwnd, HDC hdc)
  724. {
  725.     return TRUE;
  726. }
  727.  
  728. /*----------------------------------------------------------------------------*\
  729. |   AppWndProc( hwnd, uiMessage, wParam, lParam )                              |
  730. |                                                                              |
  731. |   Description:                                                               |
  732. |       The window proc for the app's main (tiled) window.  This processes all |
  733. |       of the parent window's messages.                                       |
  734. |                                                                              |
  735. \*----------------------------------------------------------------------------*/
  736. LONG FAR PASCAL _export AppWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
  737. {
  738.     PAINTSTRUCT ps;
  739.     HDC hdc;
  740.     BOOL f;
  741.     int i;
  742.  
  743.     switch (msg)
  744.     {
  745.         case WM_CREATE:
  746.         break;
  747.  
  748.         case WM_ACTIVATEAPP:
  749.         fAppActive = (BOOL)wParam;
  750.         break;
  751.  
  752.         case WM_TIMER:
  753.             break;
  754.  
  755.         case WM_ERASEBKGND:
  756.             break;
  757.  
  758.         case WM_INITMENU:
  759.             for (i=0; i<NUM_DRAW; i++)
  760.             {
  761.                 EnableMenuItem((HMENU)wParam, MENU_DRAW + i, aDraw[i].Draw ? MF_ENABLED : MF_GRAYED);
  762.                 CheckMenuItem((HMENU)wParam, MENU_DRAW + i, iDraw == i ? MF_CHECKED : MF_UNCHECKED);
  763.             }
  764.  
  765.             CheckMenuItem((HMENU)wParam, MENU_BACKPAL, gfBackPal ? MF_CHECKED : MF_UNCHECKED);
  766.             CheckMenuItem((HMENU)wParam, MENU_CLIP, gfClipping ? MF_CHECKED : MF_UNCHECKED);
  767.             CheckMenuItem((HMENU)wParam, MENU_MIRROR, gfMirror ? MF_CHECKED : MF_UNCHECKED);
  768.             CheckMenuItem((HMENU)wParam, MENU_STRETCH, gfStretch ? MF_CHECKED : MF_UNCHECKED);
  769.         break;
  770.  
  771.         case WM_COMMAND:
  772.             return AppCommand(hwnd,msg,wParam,lParam);
  773.  
  774.     case WM_DESTROY:
  775.         hAccelApp = NULL;
  776.             PostQuitMessage(0);
  777.             break;
  778.  
  779.         case WM_SIZE:
  780.             InvalidateRect(hwnd, NULL, TRUE);
  781.  
  782.             GetClientRect(hwnd, &rcApp);
  783.             GetClientRect(hwnd, &rcApp2);
  784.             GetClientRect(hwnd, &rcRand);
  785.  
  786.             if (lpbiApp == NULL)
  787.                 return 0L;
  788.  
  789.             if (!gfClipping)
  790.             {
  791.                 if ((int)DibWidth(lpbiApp) < rcRand.right)
  792.                     rcRand.right  -= DibWidth(lpbiApp);
  793.  
  794.                 if ((int)DibHeight(lpbiApp) < rcRand.bottom)
  795.                     rcRand.bottom -= DibHeight(lpbiApp);
  796.             }
  797.             else
  798.             {
  799.                 rcRand.left   -= DibWidth(lpbiApp);
  800.                 rcRand.right  += DibWidth(lpbiApp);
  801.                 rcRand.top    -= DibHeight(lpbiApp);
  802.                 rcRand.bottom += DibHeight(lpbiApp);
  803.  
  804.                 rcApp2 = rcRand;
  805.             }
  806.             break;
  807.  
  808.         case WM_CLOSE:
  809.         break;
  810.  
  811.         case WM_PALETTECHANGED:
  812.         if ((HWND)wParam == hwnd)
  813.         break;
  814.  
  815.         // fall through to WM_QUERYNEWPALETTE
  816.  
  817.     case WM_QUERYNEWPALETTE:
  818.         hdc = GetDC(hwnd);
  819.  
  820.         if (hpalApp)
  821.         SelectPalette(hdc, hpalApp, FALSE);
  822.  
  823.         f = RealizePalette(hdc);
  824.         ReleaseDC(hwnd,hdc);
  825.  
  826.         if (f)
  827.         InvalidateRect(hwnd,NULL,TRUE);
  828.  
  829.         return f;
  830.  
  831.         case WM_PAINT:
  832.         hdc = BeginPaint(hwnd,&ps);
  833.         AppPaint (hwnd,hdc);
  834.             EndPaint(hwnd,&ps);
  835.             return 0L;
  836.     }
  837.     return DefWindowProc(hwnd,msg,wParam,lParam);
  838. }
  839.  
  840. /*----------------------------------------------------------------------------*\
  841. |   AppCommand(hwnd, msg, wParam, lParam )                       |
  842. |                                                                              |
  843. |   Description:                                                               |
  844. |    handles WM_COMMAND messages for the main window (hwndApp)           |
  845. |       of the parent window's messages.                                       |
  846. |                                                                              |
  847. \*----------------------------------------------------------------------------*/
  848. LONG AppCommand (HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
  849. {
  850.     char achFileName[128];
  851.     OPENFILENAME ofn;
  852.     int i;
  853.  
  854.     switch(LOWORD(wParam))
  855.     {
  856.         case MENU_ABOUT:
  857.         DialogBox(hInstApp,"AppAbout",hwnd,AppAbout);
  858.             break;
  859.  
  860.     case MENU_OPEN:
  861.             achFileName[0] = 0;
  862.  
  863.             /* prompt user for file to open */
  864.             ofn.lStructSize = sizeof(OPENFILENAME);
  865.             ofn.hwndOwner = hwnd;
  866.             ofn.hInstance = NULL;
  867.         ofn.lpstrFilter = szAppFilter;
  868.             ofn.lpstrCustomFilter = NULL;
  869.             ofn.nMaxCustFilter = 0;
  870.             ofn.nFilterIndex = 0;
  871.             ofn.lpstrFile = achFileName;
  872.         ofn.nMaxFile = sizeof(achFileName);
  873.             ofn.lpstrFileTitle = NULL;
  874.             ofn.nMaxFileTitle = 0;
  875.             ofn.lpstrInitialDir = NULL;
  876.         ofn.lpstrTitle = NULL;
  877.         ofn.Flags = OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY;
  878.             ofn.nFileOffset = 0;
  879.             ofn.nFileExtension = 0;
  880.             ofn.lpstrDefExt = NULL;
  881.             ofn.lCustData = 0;
  882.             ofn.lpfnHook = NULL;
  883.             ofn.lpTemplateName = NULL;
  884.  
  885.             if (GetOpenFileName(&ofn))
  886.             {
  887.         AppOpenFile(hwnd,achFileName);
  888.             }
  889.  
  890.             break;
  891.  
  892.         case MENU_EXIT:
  893.             PostMessage(hwnd,WM_CLOSE,0,0L);
  894.             break;
  895.  
  896.         case MENU_TIME:
  897.             TimeIt();
  898.             break;
  899.  
  900.         case MENU_BACKPAL:
  901.             gfBackPal = !gfBackPal;
  902.             PostMessage(hwnd, WM_SIZE, 0, 0);
  903.             break;
  904.  
  905.         case MENU_CLIP:
  906.             gfClipping = !gfClipping;
  907.             PostMessage(hwnd, WM_SIZE, 0, 0);
  908.             break;
  909.  
  910.         case MENU_MIRROR:
  911.             gfMirror = !gfMirror;
  912.             PostMessage(hwnd, WM_SIZE, 0, 0);
  913.             break;
  914.  
  915.         case MENU_STRETCH:
  916.             gfStretch = !gfStretch;
  917.             PostMessage(hwnd, WM_SIZE, 0, 0);
  918.             break;
  919.  
  920.     default:
  921.         i = (int)LOWORD(wParam) - MENU_DRAW;
  922.         
  923.             if (i >= 0 && i < NUM_DRAW && aDraw[i].Draw)
  924.                 SetDraw(i);
  925.             
  926.             InvalidateRect(hwnd, NULL, TRUE);
  927.             break;
  928.     }
  929.     return 0L;
  930. }
  931.  
  932. /*----------------------------------------------------------------------------*\
  933. |   ErrMsg - Opens a Message box with a error message in it.  The user can     |
  934. |            select the OK button to continue                                  |
  935. \*----------------------------------------------------------------------------*/
  936. int ErrMsg (LPSTR sz,...)
  937. {
  938.     static char ach[4096];
  939.  
  940.     wvsprintf (ach,sz,(LPSTR)(&sz+1));   /* Format the string */
  941.     MessageBox(hwndApp,ach,szAppName,MB_OK|MB_ICONEXCLAMATION|MB_TASKMODAL);
  942.     return FALSE;
  943. }
  944.  
  945. typedef void (FAR PASCAL CONVERTPROC)(
  946.         LPVOID pd,              // --> dst.
  947.         LONG   dd,              // offset to start at
  948.         LONG   nd,              // dst_next_scan.
  949.         LPVOID ps,              // --> source.
  950.         LONG   ds,              // offset to start at
  951.         LONG   ns,              // src_next_scan.
  952.         LONG   dx,              // pixel count.
  953.         LONG   dy,              // scan count.
  954.         LPVOID pc);             // pixel convert table.
  955.  
  956. extern "C" CONVERTPROC copy_8_8, convert_8_8;
  957.  
  958. void DrawDRGB(HDC hdc, int x, int y, int dx, int dy)
  959. {
  960.     StretchDIBits(
  961.         hdc,
  962.         x,y,dx,dy,
  963.         0,0,
  964.         DibWidth(lpbiApp),
  965.         DibHeight(lpbiApp),
  966.         DibPtr(lpbiApp), (LPBITMAPINFO)&biApp,
  967.         DIB_RGB_COLORS,SRCCOPY);
  968. }
  969.  
  970. void DrawDPAL(HDC hdc, int x, int y, int dx, int dy)
  971. {
  972.     StretchDIBits(
  973.         hdc,
  974.         x,y,dx,dy,
  975.         0,0,
  976.         DibWidth(lpbiApp),
  977.         DibHeight(lpbiApp),
  978.         DibPtr(lpbiApp), (LPBITMAPINFO)lpbiApp,
  979.         DIB_PAL_COLORS,SRCCOPY);
  980. }
  981.  
  982. #ifdef WIN32
  983. void DrawDIDX(HDC hdc, int x, int y, int dx, int dy)
  984. {
  985.     StretchDIBits(
  986.         hdc,
  987.         x,y,dx,dy,
  988.         0,0,
  989.         DibWidth(lpbiApp),
  990.         DibHeight(lpbiApp),
  991.         DibPtr(lpbiApp), (LPBITMAPINFO)&biApp,
  992.         DIB_PAL_INDICES,SRCCOPY);
  993. }
  994. #endif
  995.  
  996. void DrawRGB(HDC hdc, int x, int y, int dx, int dy)
  997. {
  998.     SetDIBitsToDevice(hdc, x, y, dx, dy,
  999.         0, 0, 0, DibHeight(lpbiApp), DibPtr(lpbiApp),
  1000.         (LPBITMAPINFO)&biApp, DIB_RGB_COLORS);
  1001. }
  1002.  
  1003. void DrawPAL(HDC hdc, int x, int y, int dx, int dy)
  1004. {
  1005.     SetDIBitsToDevice(hdc, x, y, dx, dy,
  1006.         0, 0, 0, DibHeight(lpbiApp), DibPtr(lpbiApp),
  1007.         (LPBITMAPINFO)lpbiApp, DIB_PAL_COLORS);
  1008. }
  1009.  
  1010. #ifdef WIN32
  1011. void DrawIDX(HDC hdc, int x, int y, int dx, int dy)
  1012. {
  1013.     SetDIBitsToDevice(hdc, x, y, dx, dy,
  1014.         0, 0, 0, DibHeight(lpbiApp), DibPtr(lpbiApp),
  1015.         (LPBITMAPINFO)&biApp, DIB_PAL_INDICES);
  1016. }
  1017. #endif
  1018.  
  1019. void DrawBLT(HDC hdc, int x, int y, int dx, int dy)
  1020. {
  1021.     //  Flush cached bitmaps
  1022.     SetPixelV(hdcApp, 0, 0, 0L);
  1023.     BitBlt(hdc, x, y, dx, dy, hdcApp, 0, 0, SRCCOPY);
  1024. }
  1025.  
  1026. void DrawSB(HDC hdc, int x, int y, int dx, int dy)
  1027. {
  1028.     //  Flush cached bitmaps
  1029.     SetPixelV(hdcApp, 0, 0, 0L);
  1030.     StretchBlt(hdc, x, y, dx, dy,
  1031.             hdcApp, 0, 0,
  1032.             bm.bmWidth, bm.bmHeight,
  1033.             SRCCOPY);
  1034. }
  1035.  
  1036.  
  1037. void DrawBLTDS(HDC hdc, int x, int y, int dx, int dy)
  1038. {
  1039.     BitBlt(hdc, x, y, dx, dy,hdcDS, 0, 0, SRCCOPY);
  1040. }
  1041.  
  1042. void DrawSBDS(HDC hdc, int x, int y, int dx, int dy)
  1043. {
  1044.     StretchBlt(hdc, x, y, dx, dy,
  1045.             hdcDS, 0, 0,bm.bmWidth, bm.bmHeight,SRCCOPY);
  1046. }
  1047.  
  1048. void DrawSETBLT(HDC hdc, int x, int y, int dx, int dy)
  1049. {
  1050.     SetBitmapBits(hbmApp, SizeImage, lpBitmapBits);
  1051.  
  1052.     StretchBlt(hdc, x, y, dx, dy,
  1053.         hdcApp, 0, 0,
  1054.         bm.bmWidth, bm.bmHeight,
  1055.         SRCCOPY);
  1056. }
  1057.  
  1058. void DrawSETDIB(HDC hdc, int x, int y, int dx, int dy)
  1059. {
  1060.     SetDIBits(hdc, hbmApp, 0, DibHeight(lpbiApp),
  1061.             DibPtr(lpbiApp), (LPBITMAPINFO)lpbiApp, DIB_PAL_COLORS);
  1062.  
  1063.     StretchBlt(hdc, x, y, dx, dy,
  1064.         hdcApp, 0, 0,
  1065.         bm.bmWidth, bm.bmHeight,
  1066.         SRCCOPY);
  1067. }
  1068.  
  1069. #ifndef WIN32
  1070. void DrawCOPYBLT(HDC hdc, int x, int y, int dx, int dy)
  1071. {
  1072.     copy_8_8(lpBitmapBits, 0, bm.bmWidthBytes,
  1073.              lpBitmapBits, OffsetScan0, -(int)bm.bmWidthBytes,
  1074.              bm.bmWidth, bm.bmHeight, BitmapTranslate);
  1075.  
  1076.     SetBitmapBits(hbmApp, SizeImage, lpBitmapBits);
  1077.  
  1078.     StretchBlt(hdc, x, y, dx, dy,
  1079.         hdcApp, 0, 0,
  1080.         bm.bmWidth, bm.bmHeight,
  1081.         SRCCOPY);
  1082. }
  1083.  
  1084. void DrawXLATBLT(HDC hdc, int x, int y, int dx, int dy)
  1085. {
  1086.     convert_8_8(lpBitmapBits, 0, bm.bmWidthBytes,
  1087.                 lpBitmapBits, OffsetScan0, -(int)bm.bmWidthBytes,
  1088.                 bm.bmWidth, bm.bmHeight, BitmapTranslate);
  1089.  
  1090.     SetBitmapBits(hbmApp, SizeImage, lpBitmapBits);
  1091.  
  1092.     StretchBlt(hdc, x, y, dx, dy,
  1093.         hdcApp, 0, 0,
  1094.         bm.bmWidth, bm.bmHeight,
  1095.         SRCCOPY);
  1096. }
  1097. #endif
  1098.  
  1099. //
  1100. // create a 6*6*6 rainbow palette
  1101. //
  1102. HPALETTE Create666Palette()
  1103. {
  1104.     LOGPALETTE          *pPal;
  1105.     PALETTEENTRY        *ppe;
  1106.     HPALETTE            hpal = NULL;
  1107.     WORD                nNumColors;
  1108.     BYTE                r,g,b;
  1109.  
  1110.     nNumColors = 6*6*6;
  1111.     pPal = (LOGPALETTE*)LocalAlloc(LPTR,sizeof(LOGPALETTE) + nNumColors * sizeof(PALETTEENTRY));
  1112.  
  1113.     if (!pPal)
  1114.     goto exit;
  1115.  
  1116.     pPal->palNumEntries = nNumColors;
  1117.     pPal->palVersion    = 0x300;
  1118.  
  1119.     ppe = pPal->palPalEntry;
  1120.  
  1121.     for (r=0; r<6; r++)
  1122.         for (g=0; g<6; g++)
  1123.             for (b=0; b<6; b++)
  1124.             {
  1125.                 ppe->peRed   = (BYTE)((UINT)r * 255 / 6);
  1126.                 ppe->peGreen = (BYTE)((UINT)g * 255 / 6);
  1127.                 ppe->peBlue  = (BYTE)((UINT)b * 255 / 6);
  1128.                 ppe->peFlags = (BYTE)0;
  1129.                 ppe++;
  1130.             }
  1131.  
  1132.     hpal = CreatePalette(pPal);
  1133.     LocalFree((HANDLE)pPal);
  1134.  
  1135. exit:
  1136.     return hpal;
  1137. }
  1138.  
  1139. /*****************************************************************************
  1140.  *
  1141.  * dprintf() is called by the DPF macro if DEBUG is defined at compile time.
  1142.  *
  1143.  * The messages will be send to COM1: like any debug message. To
  1144.  * enable debug output, add the following to WIN.INI :
  1145.  *
  1146.  * [debug]
  1147.  * QA=1
  1148.  *
  1149.  ****************************************************************************/
  1150.  
  1151. #ifdef DEBUG
  1152.  
  1153. #define MODNAME "QA"
  1154.  
  1155. #ifndef WIN32
  1156.     #define lstrcatA lstrcat
  1157.     #define lstrcpyA lstrcpy
  1158.     #define lstrlenA lstrlen
  1159.     #define wvsprintfA      wvsprintf
  1160.     #define GetProfileIntA  GetProfileInt
  1161.     #define OutputDebugStringA OutputDebugString
  1162. #endif
  1163.  
  1164. #define _WINDLL
  1165. #include <stdarg.h>
  1166.  
  1167. void FAR CDECL dprintf(LPSTR szFormat, ...)
  1168. {
  1169.     char ach[128];
  1170.     va_list va;
  1171.  
  1172.     static BOOL fDebug = -1;
  1173.  
  1174.     if (fDebug == -1)
  1175.     fDebug = GetProfileIntA("Debug", MODNAME, TRUE);
  1176.  
  1177.     if (!fDebug)
  1178.         return;
  1179.  
  1180.     lstrcpyA(ach, MODNAME ": ");
  1181.     va_start(va, szFormat);
  1182.     wvsprintfA(ach+lstrlenA(ach),szFormat,(LPSTR)va);
  1183.     va_end(va);
  1184.     lstrcatA(ach, "\r\n");
  1185.  
  1186.     OutputDebugStringA(ach);
  1187. }
  1188.  
  1189. #endif
  1190.