STRETCH.CPP
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:10k
源码类别:

Windows编程

开发平台:

Visual C++

  1. /*==========================================================================
  2.  *
  3.  *  Copyright (C) 1995-1997 Microsoft Corporation. All Rights Reserved.
  4.  *
  5.  *  File:       stretch.cpp
  6.  *
  7.  *  stretch with multimonitor support
  8.  *
  9.  ***************************************************************************/
  10. #define NAME "Stretch"
  11. #define TITLE "Stretch"
  12. #define WIN32_LEAN_AND_MEAN
  13. #include <windows.h>
  14. #include <windowsx.h>
  15. #include <ddraw.h>
  16. #include "resource.h"
  17. #include "ddutil.h"
  18. #include "ddmm.h"
  19. #define SIZEX 64
  20. #define SIZEY 64
  21. char *szBitmap = "DONUT";
  22. HWND hwnd;
  23. DWORD           UpdateDelay = 100;
  24. LPDIRECTDRAW lpDD; // DirectDraw object
  25. LPDIRECTDRAWSURFACE lpDDSPrimary; // DirectDraw primary surface
  26. LPDIRECTDRAWSURFACE lpDDSOne; // Offscreen surface 1
  27. LPDIRECTDRAWCLIPPER     lpClipper;      // clipper for primary
  28. LPDIRECTDRAWPALETTE lpDDPal; // DirectDraw palette
  29. BOOL                    bActive;        // is application active?
  30. /* multimon stuff
  31. */
  32. int     MyDevice;
  33. char    MyDeviceName[128];
  34. RECT    MyDeviceRect;
  35. BOOL ddInit(HWND);
  36. /*
  37.  * restoreAll
  38.  *
  39.  * restore all lost objects
  40.  */
  41. BOOL restoreAll( void )
  42. {
  43.     return lpDDSPrimary->Restore() == DD_OK &&
  44.            lpDDSOne->Restore()     == DD_OK &&
  45.            DDReLoadBitmap(lpDDSOne, szBitmap) == DD_OK;
  46. } /* restoreAll */
  47. /*
  48.  * updateFrame
  49.  * 
  50.  * Decide what needs to be blitted next, wait for flip to complete,
  51.  * then flip the buffers.
  52.  */
  53. void updateFrame( void )
  54. {
  55.     static DWORD lastTickCount = 0;
  56.     static int currentFrame = 0;
  57.     static BOOL         haveBackground = FALSE;
  58.     DWORD thisTickCount;
  59.     RECT rcRect;
  60.     RECT destRect;
  61.     HRESULT ddrval;
  62.     POINT               pt;
  63.     thisTickCount = GetTickCount();
  64.     if((thisTickCount - lastTickCount) <= UpdateDelay)
  65.     {
  66. return;
  67.     }
  68.     // Move to next frame;
  69.     lastTickCount = thisTickCount;
  70.     currentFrame++;
  71.     if(currentFrame > 59)
  72.     {
  73.         currentFrame = 0;
  74.     }
  75.     // Blit the stuff for the next frame
  76.     rcRect.left   = currentFrame%10*64;
  77.     rcRect.top    = currentFrame/10*64;
  78.     rcRect.right  = currentFrame%10*64 + 64;
  79.     rcRect.bottom = currentFrame/10*64 + 64;
  80.     GetClientRect( hwnd, &destRect );
  81.     if (destRect.right  < 64) destRect.right = 64;
  82.     if (destRect.bottom < 64)  destRect.bottom = 64;
  83.     pt.x = pt.y = 0;
  84.     ClientToScreen( hwnd, &pt );
  85.     pt.x -= MyDeviceRect.left;
  86.     pt.y -= MyDeviceRect.top;
  87.     OffsetRect(&destRect, pt.x, pt.y);
  88.     while( 1 )
  89.     {
  90.         ddrval = lpDDSPrimary->Blt( &destRect, lpDDSOne, &rcRect, 0, NULL );
  91. if( ddrval == DD_OK )
  92. {
  93.     break;
  94. }
  95. if( ddrval == DDERR_SURFACELOST )
  96. {
  97.             if(!restoreAll())
  98.     {
  99. return;
  100.     }
  101. }
  102. if( ddrval != DDERR_WASSTILLDRAWING )
  103. {
  104.     return;
  105. }
  106.     }
  107.     if(ddrval != DD_OK)
  108.     {
  109. return;
  110.     }
  111. } /* updateFrame */
  112. /*
  113.  * finiObjects
  114.  *
  115.  * finished with all objects we use; release them
  116.  */
  117. static void finiObjects( BOOL fKillDD )
  118. {
  119.     if( lpDDSPrimary != NULL )
  120.     {
  121.         lpDDSPrimary->Release();
  122.         lpDDSPrimary = NULL;
  123.     }
  124.     if( lpDDSOne != NULL )
  125.     {
  126.         lpDDSOne->Release();
  127.         lpDDSOne = NULL;
  128.     }
  129.     if( lpDDPal != NULL )
  130.     {
  131.         lpDDPal->Release();
  132.         lpDDPal = NULL;
  133.     }
  134.     if( fKillDD && lpDD != NULL )
  135.     {
  136.         lpDD->Release();
  137.         lpDD = NULL;
  138.     }
  139. } /* finiObjects */
  140. long FAR PASCAL WindowProc( HWND hWnd, UINT message, 
  141.     WPARAM wParam, LPARAM lParam )
  142. {
  143.     RECT  rc;
  144.     switch( message )
  145.     {
  146.     case WM_ACTIVATEAPP:
  147.      bActive = wParam;
  148. break;
  149.     case WM_DISPLAYCHANGE:
  150.         ddInit(hwnd);
  151.         break;
  152.     case WM_SIZE:
  153.     case WM_MOVE:
  154.         if (MyDevice != DirectDrawDeviceFromWindow(hwnd,NULL,NULL))
  155.         {
  156.             ddInit(hwnd);
  157.         }
  158.         break;
  159.     case WM_PALETTECHANGED:
  160.         if ((HWND)wParam == hWnd)
  161.             break;
  162.         // fall through to WM_QUERYNEWPALETTE
  163.     case WM_QUERYNEWPALETTE:
  164.         // install our palette here
  165.         if (lpDDPal)
  166.         {
  167.             lpDDSPrimary->SetPalette(lpDDPal);
  168.         }
  169.         // reload the bitmap into the surface because the palette
  170.         // has changed..
  171.         DDReLoadBitmap(lpDDSOne, szBitmap);
  172.         break;
  173.     case WM_CREATE:
  174.         break;
  175.     case WM_GETMINMAXINFO:
  176.         ((MINMAXINFO*)lParam)->ptMinTrackSize.x = SIZEX;
  177.         ((MINMAXINFO*)lParam)->ptMinTrackSize.y = SIZEY;
  178.         return 0;
  179.     case WM_KEYDOWN:
  180. switch( wParam )
  181. {
  182. case VK_ESCAPE:
  183.         case VK_F12:
  184.             PostMessage(hWnd, WM_CLOSE, 0, 0);
  185.     break;
  186. }
  187. break;
  188.     case WM_DESTROY:
  189.         finiObjects(TRUE);
  190. PostQuitMessage( 0 );
  191.         break;
  192.     case WM_KEYUP:
  193.         if (wParam >= '1' && wParam <= '9')
  194.         {
  195.             SetRect(&rc, 0, 0, SIZEX*(wParam-'0'), SIZEY*(wParam-'0'));
  196.             goto size_me;
  197.         }
  198.         break;
  199.     case WM_COMMAND: 
  200.      switch(LOWORD(wParam))
  201. {
  202.     case ID_ROTATION_STOP:     
  203. UpdateDelay = 0x7fffffff;
  204. break;
  205.     case ID_ROTATION_SLOW:     
  206. UpdateDelay = 200;
  207. break;
  208.     case ID_ROTATION_FAST:     
  209.                 UpdateDelay = 100;
  210. break;
  211.     case ID_FILE_EXIT:     
  212.                 PostMessage( hWnd, WM_CLOSE, 0, 0L );
  213.         break;
  214.     
  215.             case ID_SIZE_1X1: SetRect(&rc, 0, 0, SIZEX*1, SIZEY*1); goto size_me;
  216.             case ID_SIZE_2X1: SetRect(&rc, 0, 0, SIZEX*2, SIZEY*1); goto size_me;
  217.             case ID_SIZE_3X1: SetRect(&rc, 0, 0, SIZEX*3, SIZEY*1); goto size_me;
  218.             case ID_SIZE_1X2: SetRect(&rc, 0, 0, SIZEX*1, SIZEY*2); goto size_me;
  219.             case ID_SIZE_2X2: SetRect(&rc, 0, 0, SIZEX*2, SIZEY*2); goto size_me;
  220.             case ID_SIZE_3X2: SetRect(&rc, 0, 0, SIZEX*3, SIZEY*2); goto size_me;
  221.             case ID_SIZE_1X3: SetRect(&rc, 0, 0, SIZEX*1, SIZEY*3); goto size_me;
  222.             case ID_SIZE_2X3: SetRect(&rc, 0, 0, SIZEX*2, SIZEY*3); goto size_me;
  223.     case ID_SIZE_3X3: SetRect(&rc, 0, 0, SIZEX*3, SIZEY*3); goto size_me;
  224. size_me:
  225.                 AdjustWindowRectEx(&rc, GetWindowLong(hWnd, GWL_STYLE),
  226.     GetMenu(hWnd) != NULL, GetWindowLong(hWnd, GWL_EXSTYLE));
  227. SetWindowPos(hWnd, NULL, 0, 0, rc.right-rc.left, rc.bottom-rc.top,
  228.                     SWP_NOZORDER|SWP_NOMOVE|SWP_NOACTIVATE);
  229. break;
  230.     } 
  231.     break;
  232.     }
  233.     return DefWindowProc(hWnd, message, wParam, lParam);
  234. } /* WindowProc */
  235. /*
  236.  * This function is called if the initialization function fails
  237.  */
  238. BOOL initFail( HWND hwnd )
  239. {
  240.     finiObjects(TRUE);
  241.     MessageBox( hwnd, "DirectDraw Init FAILED", TITLE, MB_OK );
  242.     DestroyWindow( hwnd );
  243.     return FALSE;
  244. } /* initFail */
  245. /*
  246.  * ddInit
  247.  */
  248. BOOL ddInit( HWND hwnd )
  249. {
  250.     DDSURFACEDESC ddsd;
  251.     HRESULT             ddrval;
  252.     char                ach[128];
  253.     /*
  254.      * clean up our mess
  255.      */
  256.     finiObjects(TRUE);
  257.     MyDevice = DirectDrawDeviceFromWindow(hwnd,MyDeviceName,&MyDeviceRect);
  258.     if (MyDeviceName[0] == 0) lstrcpy(MyDeviceName, "(none)");
  259.     wsprintf(ach, "%s - %s", TITLE, MyDeviceName);
  260.     SetWindowText(hwnd, ach);
  261.     /*
  262.      * create the main DirectDraw object
  263.      */
  264.     lpDD = DirectDrawCreateFromWindow(hwnd);
  265.     if( lpDD == NULL )
  266.     {
  267. return initFail(hwnd);
  268.     }
  269.     ddrval = lpDD->SetCooperativeLevel( hwnd, DDSCL_NORMAL );
  270.     // Create the primary surface
  271.     ddsd.dwSize = sizeof( ddsd );
  272.     ddsd.dwFlags = DDSD_CAPS;
  273.     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
  274.     ddrval = lpDD->CreateSurface( &ddsd, &lpDDSPrimary, NULL );
  275.     if( ddrval != DD_OK )
  276.     {
  277. return initFail(hwnd);
  278.     }
  279.     // create a clipper for the primary surface
  280.     ddrval = lpDD->CreateClipper( 0, &lpClipper, NULL );
  281.     if( ddrval != DD_OK )
  282.     {
  283.         return initFail(hwnd);
  284.     }
  285.     ddrval = lpClipper->SetHWnd( 0, hwnd );
  286.     if( ddrval != DD_OK )
  287.     {
  288.         return initFail(hwnd);
  289.     }
  290.     ddrval = lpDDSPrimary->SetClipper( lpClipper );
  291.     if( ddrval != DD_OK )
  292.     {
  293.         return initFail(hwnd);
  294.     }
  295.     // load our palette
  296.     lpDDPal = DDLoadPalette(lpDD, szBitmap);
  297.     // make sure to set the palette before loading bitmaps.
  298.     if (lpDDPal)
  299. lpDDSPrimary->SetPalette(lpDDPal);
  300.     // load our bitmap
  301.     lpDDSOne = DDLoadBitmap(lpDD, szBitmap, 0, 0);
  302.     if( lpDDSOne == NULL )
  303.     {
  304. return initFail(hwnd);
  305.     }
  306.     return TRUE;
  307. } /* doInit */
  308. /*
  309.  * doInit - do work required for every instance of the application:
  310.  *   create the window, initialize data
  311.  */
  312. static BOOL doInit( HINSTANCE hInstance, int nCmdShow )
  313. {
  314.     WNDCLASS wc;
  315.     /*
  316.      * set up and register window class
  317.      */
  318.     wc.style = CS_HREDRAW | CS_VREDRAW;
  319.     wc.lpfnWndProc = WindowProc;
  320.     wc.cbClsExtra = 0;
  321.     wc.cbWndExtra = 0;
  322.     wc.hInstance = hInstance;
  323.     wc.hIcon = LoadIcon( hInstance, IDI_APPLICATION );
  324.     wc.hCursor = LoadCursor( NULL, IDC_ARROW );
  325.     wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
  326.     wc.lpszMenuName = NULL; // MAKEINTRESOURCE(IDR_MENU);
  327.     wc.lpszClassName = NAME;
  328.     RegisterClass( &wc );
  329.     
  330.     /*
  331.      * create a window
  332.      */
  333.     hwnd = CreateWindowEx(
  334. 0,
  335. NAME,
  336. TITLE,
  337.         WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME,
  338. CW_USEDEFAULT,
  339. CW_USEDEFAULT,
  340. 128,
  341. 128,
  342. NULL,
  343. NULL,
  344. hInstance,
  345. NULL );
  346.     if( !hwnd )
  347.     {
  348. return FALSE;
  349.     }
  350.     PostMessage(hwnd, WM_COMMAND, ID_SIZE_3X3, 0);
  351.     ShowWindow( hwnd, nCmdShow );
  352.     UpdateWindow( hwnd );
  353.     /*
  354.      * create the direct draw objects
  355.      */
  356.     ddInit(hwnd);
  357.     return TRUE;
  358. } /* doInit */
  359. /*
  360.  * WinMain - initialization, message loop
  361.  */
  362. int PASCAL WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
  363. LPSTR lpCmdLine, int nCmdShow)
  364. {
  365.     MSG         msg;
  366.     if( !doInit( hInstance, nCmdShow ) )
  367.     {
  368. return FALSE;
  369.     }
  370.     while( 1 )
  371.     {
  372. if( PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE ) )
  373. {
  374.     if( !GetMessage( &msg, NULL, 0, 0 ) )
  375. return msg.wParam;
  376.     TranslateMessage(&msg); 
  377.     DispatchMessage(&msg);
  378. }
  379.         else
  380. {
  381.     updateFrame();
  382. }
  383.     }
  384. } /* WinMain */