• WinCE Overlay


    在代码中增加了很多对代码的注释。

    同时,对在不同平台(Telechips,MStar)的测试效果也做了说明。

    虽然代码是 Overlay 示例,但还是增加了一些东东,如注释或者说明,对 Overlay 有兴趣的童鞋可以看看。  

      1 // mosquito.cpp : Defines the entry point for the application.  
      2 //  
      3   
      4 #include "stdafx.h"  
      5 #include <windows.h>  
      6 #include <commctrl.h>  
      7 #include "Resource.h"  
      8 //-----------------------------------------------------------------------------  
      9 // Include files  
     10 //-----------------------------------------------------------------------------  
     11 #include <ddraw.h>  
     12   
     13 //-----------------------------------------------------------------------------  
     14 // Local definitions  
     15 //-----------------------------------------------------------------------------  
     16 #define NAME                TEXT("MosquitoWndClass")  
     17 #define TITLE               TEXT("Mosquito")  
     18   
     19 #define BUG_WIDTH           320  
     20 #define BUG_HEIGHT          200  
     21   
     22 #ifdef UNDER_CE  
     23 #define RAND_INT(x) (Random() % x)  
     24 #else  
     25 #define RAND_INT(x) (rand()*x/RAND_MAX)  
     26 #endif  
     27 #define RANDOM_VELOCITY() (int)(((RAND_INT(5)+3)*2))  
     28   
     29 //-----------------------------------------------------------------------------  
     30 // Default settings  
     31 //-----------------------------------------------------------------------------  
     32 #define TIMER_ID            1  
     33 #define TIMER_RATE          200  
     34   
     35 //-----------------------------------------------------------------------------  
     36 // Global data  
     37 //-----------------------------------------------------------------------------  
     38 LPDIRECTDRAW                g_pDD = NULL;        // DirectDraw object  
     39 LPDIRECTDRAWSURFACE         g_pDDSPrimary = NULL; // Primary Surface.  
     40 LPDIRECTDRAWSURFACE         g_pDDSOverlay = NULL; // The overlay primary.  
     41 BOOL                        g_bActive = FALSE;   // Is application active?  
     42 int                         g_RotationAngles = 0; // Supported rotation angles.  
     43 int                         g_CurrentAngle = 0;   // Current rotation angle.  
     44   
     45 // Overlay position and velocity data.  
     46   
     47 int g_nOverlayXPos, g_nOverlayYPos;  
     48 int g_nOverlayXVel, g_nOverlayYVel;  
     49 int g_nOverlayWidth, g_nOverlayHeight;  
     50 DWORD g_dwOverlayXPositionAlignment;  
     51   
     52 // Our instance handle.  
     53   
     54 HINSTANCE g_hInstance;  
     55   
     56 //-----------------------------------------------------------------------------  
     57 // Local data  
     58 //-----------------------------------------------------------------------------  
     59 static TCHAR                szImg1[] = TEXT("IDB_BUGIMAGE1");//TEXT("IDB_BUGIMAGE1");  
     60 static TCHAR                szImg2[] = TEXT("IDB_BUGIMAGE2");  
     61 static TCHAR                szImg3[] = TEXT("IDB_BUGIMAGE3");  
     62   
     63 // These are the pixel formats this app supports.  Most display adapters  
     64 // with overlay support will recognize one or more of these formats.  
     65 // We start with YUV format, then work down to RGB. (All 16 bpp.)  
     66   
     67 /* 
     68  * Telechips 8902 支持 2 层 overlay 
     69  * 只能创建一层 YUV 的 overlay (可以再创建一层 RGB overlay) 
     70  * RGB 模式可以创建多个,模式与顺序没有不影响创建 
     71 */  
     72 static DDPIXELFORMAT ddpfOverlayFormats[] = {  
     73     //{sizeof(DDPIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('Y','U','Y','V'),0,0,0,0,0},  // YUYV - Leo.Zheng Telechips 8902 可以支持  
     74     //{sizeof(DDPIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('U','Y','V','Y'),0,0,0,0,0},  // UYVY - Leo.Zheng Telechips 8902:Create No.1 surface return: 0x88760218  
     75     // {sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 16,  0x7C00, 0x03e0, 0x001F, 0},        // 16-bit RGB 5:5:5  
     76     {sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 16,  0xF800, 0x07e0, 0x001F, 0},        // 16-bit RGB 5:6:5  
     77 };  
     78   
     79 #define PF_TABLE_SIZE (sizeof(ddpfOverlayFormats) / sizeof(ddpfOverlayFormats[0]))  
     80   
     81 static RECT rs;  
     82 static RECT rd;  
     83   
     84 //-----------------------------------------------------------------------------  
     85 // Prototypes  
     86 //-----------------------------------------------------------------------------  
     87 void ReleaseAllObjects(void);  
     88 HRESULT InitFail(HWND, HRESULT, LPCTSTR, ...);  
     89 HRESULT RestoreAllSurfaces();  
     90 void MoveOverlay();  
     91 long FAR PASCAL WindowProc(HWND, UINT, WPARAM, LPARAM);  
     92 BOOL CopyBitmapToYUVSurface(LPDIRECTDRAWSURFACE, HBITMAP);  
     93 BOOL LoadImageOntoSurface(LPDIRECTDRAWSURFACE, UINT);  
     94 HRESULT WINAPI EnumSurfacesCallback(LPDIRECTDRAWSURFACE, LPDDSURFACEDESC, LPVOID);  
     95 HRESULT LoadBugImages();  
     96 HRESULT InitApp(HINSTANCE hInstance, int nCmdShow);  
     97   
     98 //-----------------------------------------------------------------------------  
     99 // Name: ReleaseAllObjects()  
    100 // Desc: Finished with all objects we use; release them  
    101 //-----------------------------------------------------------------------------  
    102 static void ReleaseAllObjects(void)  
    103 {  
    104     if(g_pDDSOverlay != NULL)  
    105     {  
    106                 // 如果不再需要一个覆盖表面或只想不让覆盖可见, 就可以设定适当的标志调用 UpdateOverlay 方法来隐藏该覆盖表面  
    107         // Use UpdateOverlay() with the DDOVER_HIDE flag to remove an overlay from the display.  
    108             // g_pDDSOverlay->UpdateOverlay(NULL, g_pDDSPrimary, NULL, DDOVER_HIDE, NULL);  
    109         g_pDDSOverlay->Release();  
    110         g_pDDSOverlay = NULL;  
    111     }  
    112   
    113     if(g_pDDSPrimary != NULL)  
    114     {  
    115         g_pDDSPrimary->Release();  
    116         g_pDDSPrimary = NULL;  
    117     }  
    118   
    119     if(g_pDD != NULL)  
    120     {  
    121         g_pDD->Release();  
    122         g_pDD = NULL;  
    123     }  
    124 }  
    125   
    126 //-----------------------------------------------------------------------------  
    127 // Name: InitFail()  
    128 // Desc: This function is called if an initialization function fails  
    129 //-----------------------------------------------------------------------------  
    130 #define PREFIX      TEXT("MOSQUITO: ")  
    131 #define PREFIX_LEN  10  
    132   
    133 static HRESULT InitFail(HWND hWnd, HRESULT hRet, LPCTSTR szError,...)  
    134 {  
    135     TCHAR szBuff[128] = PREFIX;  
    136     va_list vl;  
    137   
    138     va_start(vl, szError);  
    139     StringCchVPrintf(szBuff + PREFIX_LEN, (128-PREFIX_LEN), szError, vl);      
    140     size_t len = wcslen(szBuff);  
    141     StringCchPrintf(szBuff + len, 128 - len, TEXT("
    "));  
    142     ReleaseAllObjects();  
    143     OutputDebugString(szBuff);  
    144     DestroyWindow(hWnd);  
    145     va_end(vl);  
    146     return hRet;  
    147 }  
    148   
    149 #undef PREFIX_LEN  
    150 #undef PREFIX  
    151   
    152 //-----------------------------------------------------------------------------  
    153 // Name: RestoreAllSurfaces  
    154 // Desc: Called in case we lose our surface's vram.  
    155 //-----------------------------------------------------------------------------  
    156 static HRESULT RestoreAllSurfaces()  
    157 {  
    158     HRESULT hRet = 0;  
    159   
    160     // Try Restoring the primary surface.  
    161     hRet = g_pDDSPrimary->Restore();  
    162     if(hRet != DD_OK)  
    163             return hRet;  
    164   
    165     // Try Restoring the overlay surface.  
    166     hRet = g_pDDSOverlay->Restore();  
    167     if(hRet != DD_OK)  
    168             return hRet;  
    169   
    170     // Reload the images.  
    171     hRet = LoadBugImages();  
    172     if(hRet != DD_OK)  
    173         return hRet;  
    174   
    175     // Show the overlay.  
    176     hRet = g_pDDSOverlay->UpdateOverlay(&rs, g_pDDSPrimary, &rd, DDOVER_SHOW, NULL);  
    177   
    178     return hRet;  
    179 }  
    180   
    181 //-----------------------------------------------------------------------------  
    182 // Name: MoveOverlay()  
    183 // Desc: Called on the timer, this function moves the overlay around the  
    184 //       screen, periodically calling flip to animate the mosquito.  
    185 //-----------------------------------------------------------------------------  
    186 static void MoveOverlay()  
    187 {  
    188     HRESULT hRet = 0;  
    189     DWORD dwXAligned = 0;  
    190   
    191     // Add the current velocity vectors to the position.  
    192     g_nOverlayXPos += g_nOverlayXVel;  
    193     g_nOverlayYPos += g_nOverlayYVel;  
    194   
    195     // Check to see if this new position puts the overlay off the edge of the screen.  
    196     // SetOverlayPosition() won't like that.  
    197     // Have we gone off the left edge?  
    198     if(g_nOverlayXPos < 0)  
    199         {  
    200            g_nOverlayXPos = 0;  
    201            g_nOverlayXVel = RANDOM_VELOCITY();  
    202     }  
    203   
    204     // Have we gone off the right edge?  
    205   
    206     if((g_nOverlayXPos + g_nOverlayWidth) > GetSystemMetrics(SM_CXSCREEN))  
    207         {  
    208            g_nOverlayXPos = GetSystemMetrics(SM_CXSCREEN) - g_nOverlayWidth;  
    209            g_nOverlayXVel = -RANDOM_VELOCITY();  
    210     }  
    211   
    212     // Have we gone off the top edge?  
    213     if(g_nOverlayYPos < 0)  
    214         {  
    215            g_nOverlayYPos = 0;  
    216            g_nOverlayYVel = RANDOM_VELOCITY();  
    217     }  
    218   
    219     // Have we gone off the bottom edge?  
    220     if((g_nOverlayYPos + g_nOverlayHeight) > GetSystemMetrics(SM_CYSCREEN))  
    221         {  
    222            g_nOverlayYPos = GetSystemMetrics(SM_CYSCREEN) - g_nOverlayHeight;  
    223            g_nOverlayYVel = -RANDOM_VELOCITY();  
    224     }  
    225   
    226     // We need to check for any alignment restrictions on the X position.  
    227     if(g_dwOverlayXPositionAlignment)  
    228            dwXAligned = g_nOverlayXPos - g_nOverlayXPos % g_dwOverlayXPositionAlignment;  
    229     else  
    230            dwXAligned = g_nOverlayXPos;  
    231   
    232     // Set the overlay to it's new position. 重新放置覆盖  
    233     hRet = g_pDDSOverlay->SetOverlayPosition(dwXAligned, g_nOverlayYPos);  
    234     if(hRet == DDERR_SURFACELOST)  
    235     {  
    236             if(FAILED(RestoreAllSurfaces()))   
    237                 return;  
    238     }  
    239   
    240         // 注意, 不要使用太靠近目标表面的右/下边界的坐标. 因为 SetOverlayPosition 方法并不执行剪切功能,  
    241         // 所以使用那些可能导致覆盖超出目标表面边界的坐标会引起调用的失败, 并返回 DDERR_INVALIDPOSITION.  
    242   
    243     // Flip.  
    244     while(TRUE)  
    245     {  
    246         hRet = g_pDDSOverlay->Flip(NULL, 0);  
    247         if(hRet == DD_OK)  
    248             break;  
    249         if(hRet == DDERR_SURFACELOST)           // 正常情况下,不执行此 if 语句  
    250         {  
    251             hRet = RestoreAllSurfaces();  
    252             if(hRet != DD_OK)  
    253                 break;  
    254         }  
    255         if(hRet != DDERR_WASSTILLDRAWING)  
    256             break;  
    257     }  
    258 }  
    259   
    260   
    261 //-----------------------------------------------------------------------------  
    262 // Name: WindowProc()  
    263 // Desc: The Main Window Procedure  
    264 //-----------------------------------------------------------------------------  
    265 long FAR PASCAL WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)  
    266 {  
    267     int                         NewAngle;  
    268     DEVMODE                     DevMode;  
    269   
    270     switch (message)  
    271     {  
    272 #ifdef UNDER_CE  
    273         case WM_ACTIVATE:  
    274 #else  
    275         case WM_ACTIVATEAPP:  
    276 #endif  
    277             // Pause if minimized or not the top window  
    278             g_bActive = (wParam == WA_ACTIVE) || (wParam == WA_CLICKACTIVE);  
    279             return 0L;  
    280   
    281         case WM_KILLFOCUS:  
    282             // We do not allow anyone else to have the keyboard focus until  
    283             // we are done.  
    284             SetFocus(hWnd);  
    285             return 0L;  
    286   
    287         case WM_DESTROY:  
    288             // Clean up and close the app  
    289                         RETAILMSG(1,(L"[mosquito]overlay test - release overlay objects.
    "));  
    290             ReleaseAllObjects();  
    291             PostQuitMessage(0);  
    292                         return 0L;  
    293   
    294                 case WM_LBUTTONDOWN:            // Leo.Zheng 没有窗体,无法响应 MOUSE 消息  
    295                         PostMessage(hWnd, WM_CLOSE, 0, 0);  
    296                         break;  
    297   
    298         case WM_KEYDOWN:  
    299             // Handle any non-accelerated key commands  
    300             switch (wParam)  
    301             {  
    302                 case VK_ESCAPE:  
    303                 case VK_F12:  
    304                     PostMessage(hWnd, WM_CLOSE, 0, 0);  
    305                     return 0L;  
    306   
    307                 case VK_SPACE:  
    308                     // Rotate to the "next" angle.  
    309                     if (g_CurrentAngle >= 0 && g_RotationAngles >= 0)  
    310                                         {  
    311                         NewAngle = g_CurrentAngle;  
    312                         do  
    313                         {  
    314                             NewAngle <<= 1;  
    315                             if (NewAngle == DMDO_0)  
    316                             {  
    317                                 NewAngle = DMDO_90;  
    318                             }  
    319                             if (NewAngle > DMDO_270)  
    320                             {  
    321                                 NewAngle = DMDO_0;  
    322                             }  
    323                         }while (!(NewAngle & g_RotationAngles) && (NewAngle != DMDO_0));  
    324   
    325                         memset(&DevMode, 0, sizeof (DevMode));  
    326                         DevMode.dmSize = sizeof (DevMode);  
    327                         DevMode.dmFields = DM_DISPLAYORIENTATION;  
    328                         DevMode.dmDisplayOrientation = NewAngle;  
    329   
    330                         if (DISP_CHANGE_SUCCESSFUL == ChangeDisplaySettingsEx(NULL, &DevMode, NULL, CDS_RESET, NULL))  
    331                                                 {  
    332                             g_CurrentAngle = NewAngle;  
    333                                                         RestoreAllSurfaces();  
    334                         }  
    335                     }  
    336                     return 0L;  
    337             }  
    338             break;  
    339   
    340         case WM_TIMER:  
    341             // Update and flip surfaces  
    342             if (g_bActive && TIMER_ID == wParam)  
    343             {  
    344                 MoveOverlay();  
    345                                 Sleep(100);  
    346                                 LoadBugImages();  
    347             }  
    348             break;  
    349     }  
    350     return DefWindowProc(hWnd, message, wParam, lParam);  
    351 }  
    352   
    353 //-----------------------------------------------------------------------------  
    354 //  Function: CopyBitmapToYUVSurface  
    355 //  Description:   
    356 //      Copies an RGB GDI bitmap to a YUV surface. Both bitmap and surface  
    357 //      must be a multiple of 2 pixels in width for the supported YUV formats.    
    358 //      The following formats are supported:  
    359 //              YUYV  
    360 //              UYVY  
    361 //        
    362 //      The "YUYV" YUV pixel format looks like this:  
    363 //          As a series of BYTES:    [Y0][U][Y1][V] (reverse it for a DWORD)  
    364 //   
    365 //      The "UYVY" YUV pixel format looks like this:  
    366 //          As a series of BYTES:    [U][Y0][V][Y1] (reverse it for a DWORD)  
    367 //   
    368 //      As you can see, both formats pack two pixels into a single DWORD. The   
    369 //      pixels share U and V components and have separate Y components.  
    370 //        
    371 //  Returns: TRUE if successful, otherwise FALSE.  
    372 //-----------------------------------------------------------------------------  
    373 static BOOL CopyBitmapToYUVSurface(LPDIRECTDRAWSURFACE lpDDSurf, HBITMAP hbm)  
    374 {  
    375     HDC                 hdcImage;  
    376     HRESULT             ddrval;  
    377     DDSURFACEDESC       ddsd;  
    378     DWORD               x, y, dwWidth, dwHeight;  
    379     DWORD               dwPitch;  
    380     LPBYTE              pSurf;  
    381     DWORD               dwBytesInRow;  
    382     COLORREF            color;  
    383     BYTE                R,G,B, Y0,Y1,U,V;  
    384     BOOL                bRet = FALSE;  
    385   
    386     if (hbm == NULL || lpDDSurf == NULL)  
    387         return FALSE;  
    388   
    389     //  
    390     //  select bitmap into a memoryDC so we can use it.  
    391     //  
    392     hdcImage = CreateCompatibleDC(NULL);  
    393     SelectObject(hdcImage, hbm);  
    394   
    395     memset(&ddsd, 0, sizeof(ddsd));  
    396     ddsd.dwSize = sizeof(ddsd);  
    397     // Lock down the surface so we can modify it's contents.  
    398     ddrval=lpDDSurf->Lock( NULL, &ddsd, DDLOCK_WAITNOTBUSY, NULL);  
    399     if (FAILED(ddrval))  
    400             goto CleanUp;  
    401   
    402     dwWidth=ddsd.dwWidth;  
    403     dwHeight=ddsd.dwHeight;  
    404     dwPitch=ddsd.lPitch;  
    405     pSurf=(LPBYTE)ddsd.lpSurface;  
    406         dwBytesInRow=ddsd.dwWidth*2;  
    407   
    408     // Go through the image 2 pixels at a time and convert to YUV  
    409     for(y=0; y<dwHeight; y++)  
    410     {  
    411                 for(x=0; x<dwWidth; x+=2)  
    412                 {  
    413                         // The equations for color conversion used here, probably aren't   
    414                         // exact, but they seem to do an OK job.  
    415                         color=GetPixel(hdcImage, x,y);  
    416                         R=GetRValue(color);  
    417                         G=GetGValue(color);  
    418                         B=GetBValue(color);  
    419                     Y0= (BYTE)(0.29*R + 0.59*G + 0.14*B);  
    420                         U= (BYTE)(128.0 - 0.14*R - 0.29*G + 0.43*B);  
    421   
    422                         color=GetPixel(hdcImage, x+1,y);  
    423                         R=GetRValue(color);  
    424                         G=GetGValue(color);  
    425                         B=GetBValue(color);  
    426                         Y1= (BYTE)(0.29*R + 0.57*G + 0.14*B);  
    427                         V= (BYTE)(128.0 + 0.36*R - 0.29*G - 0.07*B);  
    428   
    429                         switch (ddsd.ddpfPixelFormat.dwFourCC)  
    430                         {  
    431                                 case MAKEFOURCC('Y','U','Y','V'):   
    432                                         *(pSurf++) = Y0;  
    433                                         *(pSurf++) = U;  
    434                                         *(pSurf++) = Y1;  
    435                                         *(pSurf++) = V;  
    436                                         break;  
    437                                 case MAKEFOURCC('U','Y','V','Y'):   
    438                                         *(pSurf++) = U;  
    439                                         *(pSurf++) = Y0;  
    440                                         *(pSurf++) = V;  
    441                                         *(pSurf++) = Y1;  
    442                                         break;  
    443                         }                         
    444                 }  
    445                 pSurf+=(dwPitch-dwBytesInRow);  
    446     }  
    447   
    448     lpDDSurf->Unlock(NULL);       
    449   
    450 CleanUp:  
    451     if(hdcImage)  
    452         DeleteDC(hdcImage);  
    453   
    454         return TRUE;  
    455 }  
    456   
    457 //-----------------------------------------------------------------------------  
    458 //  Function: LoadImageOnToSurface  
    459 //  Description:  
    460 //      Loads a resource based bitmap image onto a DirectDraw surface.  Can  
    461 //      covert the bitmap to all RGB formats, plus a couple YUV formats.  
    462 //-----------------------------------------------------------------------------  
    463 static BOOL LoadImageOntoSurface(LPDIRECTDRAWSURFACE lpdds, UINT lpstrResID)  
    464 {  
    465     HBITMAP hbm = NULL;  
    466     HDC     hdcImage = NULL;  
    467     HDC     hdcSurf = NULL;  
    468     BOOL bRetVal = FALSE;  
    469     HRESULT ddrval;  
    470     DDSURFACEDESC ddsd;  
    471   
    472     if(!lpdds)  
    473                 return FALSE;  
    474   
    475     // get surface size and format.  
    476     memset(&ddsd, 0, sizeof(ddsd));  
    477     ddsd.dwSize = sizeof(ddsd);  
    478     ddsd.dwFlags = DDSD_HEIGHT | DDSD_WIDTH;  
    479     ddrval = lpdds->GetSurfaceDesc(&ddsd);  
    480     if(FAILED(ddrval))  
    481             goto Exit;  
    482   
    483         // Load the bitmap resource.  We'll use LoadImage() since it'll scale the   
    484     // image to fit our surface, and maintain the color information in the bitmap.  
    485     hbm = (HBITMAP)LoadImage(g_hInstance, MAKEINTRESOURCE(lpstrResID), IMAGE_BITMAP, 0, 0, 0);  
    486         if(hbm == NULL)  
    487             goto Exit;  
    488   
    489     // If our surface is a FOURCC YUV format, we need to do a little work to convert  
    490     // our RGB resource bitmap into the appropriate YUV format.  
    491     if(ddsd.ddpfPixelFormat.dwFlags == DDPF_FOURCC)  
    492     {  
    493                 if(!CopyBitmapToYUVSurface(lpdds, hbm))  
    494                         goto Exit;  
    495     }  
    496     else  //Looks like we're just using a standard RGB surface format, let GDI do the work.  
    497     {  
    498             // Create a DC and associate the bitmap with it.  
    499             hdcImage = CreateCompatibleDC(NULL);  
    500             SelectObject(hdcImage, hbm);  
    501      
    502             ddrval = lpdds->GetDC(&hdcSurf);  
    503             if(FAILED(ddrval))  
    504                 goto Exit;  
    505       
    506             if(BitBlt(hdcSurf, 0, 0, ddsd.dwWidth, ddsd.dwHeight, hdcImage, 0, 0, SRCCOPY) == FALSE)  
    507                 goto Exit;  
    508   
    509                 ::SetBkMode(hdcSurf,TRANSPARENT);  
    510                 ::SetTextColor(hdcSurf,RGB(255,0,0));  
    511                 RECT Rect={0,0,100,50};  
    512                 ::DrawText(hdcSurf,_T("ABCD"),4,&Rect,DT_SINGLELINE|DT_LEFT);  
    513     }  
    514   
    515     bRetVal = TRUE;  
    516       
    517 Exit:  
    518     if(hdcSurf)  
    519             lpdds->ReleaseDC(hdcSurf);  
    520     if(hdcImage)  
    521             DeleteDC(hdcImage);  
    522     if(hbm)  
    523             DeleteObject(hbm);  
    524   
    525     return bRetVal;  
    526 }  
    527   
    528 //-----------------------------------------------------------------------------  
    529 // Name: EnumSurfacesCallback()  
    530 // Desc: Used by LoadBugImages to aid it loading all three bug images.  
    531 //-----------------------------------------------------------------------------  
    532 static HRESULT WINAPI EnumSurfacesCallback(LPDIRECTDRAWSURFACE lpDDSurface,    
    533                      LPDDSURFACEDESC lpDDSurfaceDesc,    
    534                      LPVOID lpContext)  
    535 {  
    536     int *CallCount = (int *)lpContext;  
    537     HRESULT hr = (HRESULT)DDENUMRET_OK;  
    538     UINT ResName;  
    539   
    540     // Load the Bug Image appropriate...  
    541     if(*CallCount == 0)  
    542         {  
    543         ResName = IDB_BUGIMAGE2;  
    544     }  
    545     else if(*CallCount == 1)  
    546         {  
    547         ResName = IDB_BUGIMAGE3;  
    548     }  
    549     else  
    550         {  
    551         hr = (HRESULT)DDENUMRET_CANCEL;  
    552         goto exit;  
    553     }  
    554   
    555     if(!LoadImageOntoSurface(lpDDSurface, ResName))  
    556         {  
    557         hr = (HRESULT)DDENUMRET_CANCEL;  
    558         goto exit;  
    559     }  
    560   
    561     // Bump the count.  
    562     (*CallCount)++;  
    563         if(*CallCount >= 2)  
    564         {  
    565                 *CallCount = 0;  
    566         }  
    567   
    568 exit:  
    569     lpDDSurface->Release();  
    570     return hr;  
    571 }  
    572   
    573 //-----------------------------------------------------------------------------  
    574 // Name: LoadBugImages()  
    575 // Desc: Load the bug resource images into our various flipping surfaces.  
    576 //-----------------------------------------------------------------------------  
    577 static HRESULT LoadBugImages()  
    578 {  
    579     HRESULT hRet;  
    580     static int CallCount = 0;  
    581   
    582     // Put the first bug image onto the first buffer of our complex surface.  
    583         if(0 == CallCount)  
    584         {  
    585                 if(!LoadImageOntoSurface(g_pDDSOverlay, IDB_BUGIMAGE1))  
    586                         return (E_FAIL);  
    587         }  
    588   
    589     // Use the enumeration attachment function to load the other images.  
    590     hRet = g_pDDSOverlay->EnumAttachedSurfaces((LPVOID)&CallCount,EnumSurfacesCallback);  
    591   
    592     return (hRet);  
    593 }  
    594   
    595 //-----------------------------------------------------------------------------  
    596 // Name: InitApp()  
    597 // Desc: Do work required for every instance of the application:  
    598 //          Create the window, initialize data  
    599 //-----------------------------------------------------------------------------  
    600 static HRESULT InitApp(HINSTANCE hInstance, int nCmdShow)  
    601 {  
    602     HWND          hWnd;  
    603     WNDCLASS      wc;  
    604     DDSURFACEDESC ddsd;  
    605     DDCAPS        ddcaps;  
    606     HRESULT       hRet;  
    607     DWORD         dwUpdateFlags = 0;  
    608     DDOVERLAYFX   ovfx;  
    609     DEVMODE       DevMode;  
    610   
    611     // Check for rotation support by getting the rotation angles supported.  
    612     memset(&DevMode, 0, sizeof(DevMode));  
    613     DevMode.dmSize = sizeof(DevMode);  
    614     DevMode.dmFields = DM_DISPLAYQUERYORIENTATION;  
    615     if(DISP_CHANGE_SUCCESSFUL == ChangeDisplaySettingsEx(NULL, &DevMode, NULL, CDS_TEST, NULL))  
    616         {  
    617         g_RotationAngles = DevMode.dmDisplayOrientation;  
    618     }  
    619     else  
    620         {  
    621         OutputDebugString(L"MOSQUITO: Device does not support any rotation modes. Rotation disabled.");  
    622         g_RotationAngles = -1;  
    623     }  
    624   
    625     // Get the current rotation angle.  
    626     memset(&DevMode, 0, sizeof (DevMode));  
    627     DevMode.dmSize = sizeof (DevMode);  
    628     DevMode.dmFields = DM_DISPLAYORIENTATION;  
    629     if(DISP_CHANGE_SUCCESSFUL == ChangeDisplaySettingsEx(NULL, &DevMode, NULL, CDS_TEST, NULL))  
    630         {  
    631         g_CurrentAngle = DevMode.dmDisplayOrientation;  
    632     }  
    633     else  
    634         {  
    635         OutputDebugString(L"MOSQUITO: Unable to read current rotation. Rotation disabled.");  
    636         g_CurrentAngle = -1;  
    637     }  
    638   
    639     // Set up and register window class.  
    640     wc.style = CS_HREDRAW | CS_VREDRAW;  
    641     wc.lpfnWndProc = WindowProc;  
    642     wc.cbClsExtra = 0;  
    643     wc.cbWndExtra = 0;  
    644     wc.hInstance = hInstance;  
    645     wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_MOSQUITO));  
    646     wc.hCursor = LoadCursor(NULL, IDC_ARROW);  
    647     wc.hbrBackground = (HBRUSH )GetStockObject(BLACK_BRUSH);  
    648     wc.lpszMenuName = NULL;  
    649     wc.lpszClassName = NAME;  
    650     RegisterClass(&wc);  
    651   
    652     // Create a window.  
    653     hWnd = CreateWindowEx(WS_EX_TOPMOST,  
    654       NAME,  
    655       TITLE,  
    656       WS_POPUP,  
    657       0,  
    658       0,  
    659       GetSystemMetrics(SM_CXSCREEN),  
    660       GetSystemMetrics(SM_CYSCREEN),  
    661       NULL,  
    662       NULL,  
    663       hInstance,  
    664       NULL);  
    665     if(!hWnd)  
    666         return FALSE;  
    667     // We never show the window, only set focus to it.  
    668     SetFocus(hWnd);  
    669   
    670     // Create the main DirectDraw object  
    671     hRet = DirectDrawCreate(NULL, &g_pDD, NULL);  
    672     if(hRet != DD_OK)  
    673         return InitFail(hWnd, hRet, TEXT("DirectDrawCreate FAILED"));  
    674   
    675     // Get normal mode.  
    676     hRet = g_pDD->SetCooperativeLevel(hWnd, DDSCL_NORMAL);  
    677     if(hRet != DD_OK)  
    678         return InitFail(hWnd, hRet, TEXT("SetCooperativeLevel FAILED"));  
    679   
    680     // Get a primary surface interface pointer (only needed for init.)  
    681         // 要使用覆盖表面, 必须先要初始化一个主表面, 覆盖表面将显示在该主表面上  
    682     memset(&ddsd, 0, sizeof(ddsd));  
    683     ddsd.dwSize = sizeof(ddsd);  
    684     ddsd.dwFlags = DDSD_CAPS;  
    685     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;  
    686     hRet = g_pDD->CreateSurface(&ddsd, &g_pDDSPrimary, NULL);  
    687     if(hRet != DD_OK)  
    688         return InitFail(hWnd, hRet, TEXT("CreateSurface FAILED"));  
    689   
    690     // See if we can support overlays.  
    691         // 初始化 DirectDraw 后, 需要检测设备是否支持覆盖表面  
    692         // 因为 DirectDraw 不能仿真覆盖, 所以如果硬件不支持覆盖, 就不能继续下面的工作  
    693     memset(&ddcaps, 0, sizeof(ddcaps));  
    694     ddcaps.dwSize = sizeof(ddcaps);  
    695     hRet = g_pDD->GetCaps(&ddcaps, NULL);  
    696     if(hRet != DD_OK)  
    697         return InitFail(hWnd, hRet, TEXT("GetCaps FAILED"));  
    698   
    699     if(ddcaps.dwOverlayCaps == 0)  
    700         return InitFail(hWnd, hRet, TEXT("Overlays are not supported in hardware!"));  
    701         /* // Leo.Zheng Add 
    702         if(!(capsDrv.dwCaps & DDCAPS_OVERLAY)) 
    703                 return FALSE; 
    704         */  
    705   
    706     // Get alignment info to compute our overlay surface size.  
    707     rs.left = 0;  
    708     rs.top = 0;  
    709     rs.right = BUG_WIDTH;  
    710     rs.bottom = BUG_HEIGHT;  
    711     if(ddcaps.dwAlignSizeSrc != 0)  
    712             rs.right += rs.right % ddcaps.dwAlignSizeSrc;  
    713       
    714     // Create the overlay flipping surface. We will attempt the pixel formats  
    715         // in our table one at a time until we find one that jives.  
    716         // 如果知道显示设备支持覆盖表面, 就可以创建一个. 因为没有指明设备怎样支持覆盖表面的标准, 所以不能够期望创建任意大小的像素格式的表面.  
    717         // 另外, 也不要期望第一次创建覆盖表面就会成功. 因此, 必须作好准备进行多次创建的尝试, 直到有一个能够工作为止.  
    718         int i = 0;  
    719     memset(&ddsd, 0, sizeof(ddsd));  
    720     ddsd.dwSize = sizeof(ddsd);  
    721     ddsd.ddsCaps.dwCaps = DDSCAPS_OVERLAY | DDSCAPS_FLIP;  
    722     ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_BACKBUFFERCOUNT | DDSD_PIXELFORMAT;  
    723         ddsd.dwWidth = rs.right;  
    724         ddsd.dwHeight = rs.bottom;  
    725     ddsd.dwBackBufferCount = 1;  
    726     do  
    727         {       // Leo.Zheng MStar 2521 只创建 16-bit RGB 5:6:5 成功; 创建 16-bit RGB 5:5:5 失败.  
    728             ddsd.ddpfPixelFormat = ddpfOverlayFormats[i];  
    729             hRet = g_pDD->CreateSurface(&ddsd, &g_pDDSOverlay, NULL);                   // Leo.Zheng 此处调用后引起使用 IOCtrl 显示在 LCD 上的消失  
    730                 RETAILMSG(1,(L"[mosquito]Create No.%d surface return: 0x%X
    ",i + 1,hRet));  
    731     }while(hRet != DD_OK && (++i < PF_TABLE_SIZE));  
    732     if(hRet != DD_OK)  
    733         return InitFail(hWnd, hRet, TEXT("Unable to create overlay surface!"));  
    734   
    735     // Load the images.  
    736     if(LoadBugImages() != DD_OK)  
    737         return InitFail(hWnd, hRet, TEXT("Unable to load images to overlay surface!"));  
    738   
    739     // Finish setting up the overlay.  
    740     int StretchFactor1000 = ddcaps.dwMinOverlayStretch > 1000 ? ddcaps.dwMinOverlayStretch : 1000;  
    741   
    742     rd.left=0;   
    743     rd.top=0;  
    744     // Adding 999 takes care of integer truncation problems.  
    745     rd.right  = (rs.right * StretchFactor1000 + 999) / 1000;  
    746     rd.bottom = rs.bottom * StretchFactor1000 / 1000;  
    747     if (ddcaps.dwAlignSizeDest != 0)  
    748             rd.right = (int)((rd.right + ddcaps.dwAlignSizeDest - 1)/ ddcaps.dwAlignSizeDest) * ddcaps.dwAlignSizeDest;  
    749   
    750         // 显示覆盖表面: 在设置了源矩形和目的矩形后, 就可以显示覆盖了.  
    751         // 程序开始在临时变量 dwUpdateFlags 中设定了 DDOVER_SHOW 和 DDOVER_DDFX 标志, 指明该覆盖是第一次显示,   
    752         // 硬件应该使用包含在 DDOVERLAYFX 结构中的效果信息完成这一工作.  
    753         // UpdateOverlay 用于重新定位一个覆盖页面, 或修改其视觉属性.  
    754     // Set the flags we'll send to UpdateOverlay  
    755     dwUpdateFlags = DDOVER_SHOW;  
    756         // dwUpdateFlags = DDOVER_SHOW | DDOVER_DDFX;                   // Leo.Zheng DDOVER_DDFX WinCE 不支持  
    757   
    758         // 检查 DDCAPS 结构确定覆盖是否支持源 Color Key  
    759     // Does the overlay hardware support source color keying?  
    760     // If so, we can hide the black background around the image.  
    761     // This probably won't work with YUV formats  
    762     memset(&ovfx, 0, sizeof(ovfx));  
    763     ovfx.dwSize = sizeof(ovfx);  
    764     if(ddcaps.dwOverlayCaps & DDOVERLAYCAPS_CKEYSRC)                    // MStar2521 不支持 color key  
    765     {  
    766         dwUpdateFlags |= DDOVER_KEYSRCOVERRIDE;  
    767   
    768         // Create an overlay FX structure so we can specify a source color key.  
    769         // This information is ignored if the DDOVER_SRCKEYOVERRIDE flag   
    770         // isn't set.  
    771         ovfx.dckSrcColorkey.dwColorSpaceLowValue=0; // black as the color key  
    772         ovfx.dckSrcColorkey.dwColorSpaceHighValue=0;  
    773     }  
    774         else  
    775         {  
    776                 RETAILMSG(1,(L"[mosquito]cannot support color key: 0x%X(0x%x)
    ",ddcaps.dwOverlayCaps,DDOVERLAYCAPS_CKEYSRC));  
    777         }  
    778   
    779     // Update the overlay parameters.  
    780         // 调用 IDirectDrawSurface::UpdateOverlay 方法来显示覆盖  
    781     hRet = g_pDDSOverlay->UpdateOverlay(&rs, g_pDDSPrimary, &rd, dwUpdateFlags, &ovfx);  
    782     if(hRet != DD_OK)  
    783         {  
    784                 // 在 MStar 2521 设备上运行第二个此程序实例时出错。  
    785                 // 在 TeleChips 8902 设备上运行第三个此程序实例时出错。  
    786                 return InitFail(hWnd, hRet, TEXT("Unable to show overlay surface: 0x%x!"),hRet);  
    787         }  
    788   
    789     // Set a bunch of position and velocity module vars.  
    790     g_nOverlayXPos = 0;  
    791     g_nOverlayYPos = 0;  
    792     g_nOverlayXVel = RANDOM_VELOCITY();  
    793     g_nOverlayYVel = RANDOM_VELOCITY();  
    794     g_nOverlayWidth = rd.right - rd.left;  
    795     g_nOverlayHeight = rd.bottom - rd.top;  
    796       
    797     // Set the "destination position alignment" global so we won't have to  
    798     // keep calling GetCaps() everytime we move the overlay surface.  
    799     g_dwOverlayXPositionAlignment = ddcaps.dwAlignBoundaryDest;  
    800   
    801     // Create a timer to flip the pages.  
    802     if(TIMER_ID != SetTimer(hWnd, TIMER_ID, TIMER_RATE, NULL))  
    803         return InitFail(hWnd, hRet, TEXT("SetTimer FAILED"));  
    804   
    805     return DD_OK;  
    806 }  
    807   
    808 //-----------------------------------------------------------------------------  
    809 // Name: WinMain()  
    810 // Desc: Initialization, message loop  
    811 //-----------------------------------------------------------------------------  
    812 int PASCAL WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,  
    813 #ifdef UNDER_CE  
    814         LPWSTR lpCmdLine,  
    815 #else  
    816         LPSTR lpCmdLine,  
    817 #endif  
    818         int nCmdShow)  
    819 {  
    820     MSG msg;  
    821   
    822     g_hInstance = hInstance;  
    823     if(InitApp(hInstance, nCmdShow) != DD_OK)  
    824         return FALSE;  
    825   
    826     while(GetMessage(&msg, NULL, 0, 0))  
    827     {  
    828         TranslateMessage(&msg);  
    829         DispatchMessage(&msg);  
    830     }  
    831   
    832     return msg.wParam;  
    833 }  
  • 相关阅读:
    Scala(四)流程控制
    Scala(九)异常
    Idea中安装翻译插件
    hiveserver2启动卡住问题解决方案
    Scala(十)隐式转换
    Scala(七)集合
    Scala(六)面向对象
    Scala(八)模式匹配
    SharePoint 2010 文档库添加文件icon
    Windows Server 2008 r2 在Hyperv里搭建SharePoint 2010开发环境
  • 原文地址:https://www.cnblogs.com/91program/p/5201453.html
Copyright © 2020-2023  润新知