⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mosquito.cpp

📁 Windows Mobile6 DDraw案例应用
💻 CPP
📖 第 1 页 / 共 2 页
字号:

    // Go through the image 2 pixels at a time and convert to YUV
    for(y=0; y<dwHeight; y++)
    {
    for(x=0; x<dwWidth; x+=2)
        {
        // The equations for color conversion used here, probably aren't 
        // exact, but they seem to do an OK job.
            color=GetPixel(hdcImage, x,y);
            R=GetRValue(color);
            G=GetGValue(color);
            B=GetBValue(color);
            Y0= (BYTE)(0.29*R + 0.59*G + 0.14*B);
            U= (BYTE)(128.0 - 0.14*R - 0.29*G + 0.43*B);

            color=GetPixel(hdcImage, x+1,y);
            R=GetRValue(color);
            G=GetGValue(color);
            B=GetBValue(color);
            Y1= (BYTE)(0.29*R + 0.57*G + 0.14*B);
            V= (BYTE)(128.0 + 0.36*R - 0.29*G - 0.07*B);

            switch (ddsd.ddpfPixelFormat.dwFourCC)
            {
                case MAKEFOURCC('Y','U','Y','V'): 
                    *(pSurf++) = Y0;
                    *(pSurf++) = U;
                    *(pSurf++) = Y1;
                    *(pSurf++) = V;
                    break;
                case MAKEFOURCC('U','Y','V','Y'): 
                    *(pSurf++) = U;
                    *(pSurf++) = Y0;
                    *(pSurf++) = V;
                    *(pSurf++) = Y1;
                    break;
            }                       
        }
        pSurf+=(lPitch-dwBytesInRow);
    }

    lpDDSurf->Unlock(NULL);     

CleanUp:
    if(hdcImage)
    DeleteDC(hdcImage);

    return TRUE;
}



//-----------------------------------------------------------------------------
//  Function: LoadImageOnToSurface
//  Description:
//      Loads a resource based bitmap image onto a DirectDraw surface.  Can
//      covert the bitmap to all RGB formats, plus a couple YUV formats.
//-----------------------------------------------------------------------------
static BOOL 
LoadImageOntoSurface(LPDIRECTDRAWSURFACE lpdds, LPCTSTR lpstrResID)
{
    HBITMAP hbm = NULL;
    HDC     hdcImage = NULL;
    HDC     hdcSurf = NULL;
    BOOL bRetVal = FALSE;
    HRESULT ddrval;
    DDSURFACEDESC ddsd;

    if (!lpdds) return FALSE;

    //
    // get surface size and format.
    //
    memset(&ddsd, 0, sizeof(ddsd));
    ddsd.dwSize = sizeof(ddsd);
    ddsd.dwFlags = DDSD_HEIGHT | DDSD_WIDTH;
    ddrval = lpdds->GetSurfaceDesc(&ddsd);
    if (FAILED(ddrval))
        goto Exit;

    // Load the bitmap resource.  We'll use LoadImage() since it'll scale the 
    // image to fit our surface, and maintain the color information in the
    // bitmap.
    hbm = (HBITMAP)LoadImage(g_hInstance, lpstrResID, IMAGE_BITMAP, 0, 0, 0);
    if (hbm == NULL)
        goto Exit;


    // If our surface is a FOURCC YUV format, we need to do a little work to convert
    // our RGB resource bitmap into the appropriate YUV format.
    if (ddsd.ddpfPixelFormat.dwFlags == DDPF_FOURCC)
    {
    if (!CopyBitmapToYUVSurface(lpdds, hbm))
        goto Exit;        
    }
    else  //Looks like we're just using a standard RGB surface format, let GDI do the work.
    {
        // Create a DC and associate the bitmap with it.
        hdcImage = CreateCompatibleDC(NULL);
        SelectObject(hdcImage, hbm);
   
        ddrval = lpdds->GetDC(&hdcSurf);
        if (FAILED(ddrval))
            goto Exit;
    
        if (BitBlt(hdcSurf, 0, 0, ddsd.dwWidth, ddsd.dwHeight, hdcImage, 0, 0, SRCCOPY) == FALSE)
            goto Exit;
    }

    bRetVal = TRUE;
    
Exit:
    if (hdcSurf)
        lpdds->ReleaseDC(hdcSurf);
    if (hdcImage)
        DeleteDC(hdcImage);
    if (hbm)
        DeleteObject(hbm);

    return bRetVal;
}



//-----------------------------------------------------------------------------
// Name: EnumSurfacesCallback()
// Desc: Used by LoadBugImages to aid it loading all three bug images.
//-----------------------------------------------------------------------------
static HRESULT WINAPI 
EnumSurfacesCallback(LPDIRECTDRAWSURFACE lpDDSurface,  
                     LPDDSURFACEDESC lpDDSurfaceDesc,  
                     LPVOID lpContext)
{
    int * CallCount = (int *)lpContext;
    HRESULT hr = (HRESULT)DDENUMRET_OK;
    LPTSTR ResName;

    // Load the Bug Image appropriate...

    if (*CallCount == 0) {
        ResName = szImg2;
    }
    else if (*CallCount == 1) {
        ResName = szImg3;
    }
    else {
        // Eh?
        hr = (HRESULT)DDENUMRET_CANCEL;
        goto exit;
    }

    if (!LoadImageOntoSurface(lpDDSurface, ResName)) {
        hr = (HRESULT)DDENUMRET_CANCEL;
        goto exit;
    }

    // Bump the count.

    (*CallCount)++;

exit:
    lpDDSurface->Release();
    return hr;
}



//-----------------------------------------------------------------------------
// Name: LoadBugImages()
// Desc: Load the bug resource images into our various flipping surfaces.
//-----------------------------------------------------------------------------
static HRESULT
LoadBugImages()
{
    HRESULT hRet;
    int CallCount = 0;

    // Put the first bug image onto the first buffer of our complex surface.
    if (!LoadImageOntoSurface(g_pDDSOverlay, szImg1))
        return (E_FAIL);

    // Use the enumeration attachment function to load the other images.
    hRet = g_pDDSOverlay->EnumAttachedSurfaces((LPVOID)&CallCount,EnumSurfacesCallback);
    return (hRet);
}

//-----------------------------------------------------------------------------
// Name: InitApp()
// Desc: Do work required for every instance of the application:
//          Create the window, initialize data
//-----------------------------------------------------------------------------
static HRESULT
InitApp(HINSTANCE hInstance, int nCmdShow)
{
    HWND                        hWnd;
    WNDCLASS                    wc;
    DDSURFACEDESC               ddsd;
    DDCAPS                      ddcaps;
    HRESULT                     hRet;
    DWORD                       dwUpdateFlags = 0;
    DDOVERLAYFX                 ovfx;
    DEVMODE                     DevMode;

    // Check for rotation support by getting the rotation angles supported.
 
    memset(&DevMode, 0, sizeof(DevMode));
    DevMode.dmSize = sizeof(DevMode);
    DevMode.dmFields = DM_DISPLAYQUERYORIENTATION;

    if (DISP_CHANGE_SUCCESSFUL == ChangeDisplaySettingsEx(NULL, &DevMode, NULL, CDS_TEST, NULL)) {

        g_RotationAngles = DevMode.dmDisplayOrientation;
    }
    else {

        OutputDebugString(L"MOSQUITO: Device does not support any rotation modes. Rotation disabled.");
        g_RotationAngles = -1;
    }

    // Get the current rotation angle.

    memset(&DevMode, 0, sizeof (DevMode));
    DevMode.dmSize = sizeof (DevMode);
    DevMode.dmFields = DM_DISPLAYORIENTATION;

    if (DISP_CHANGE_SUCCESSFUL == ChangeDisplaySettingsEx(NULL, &DevMode, NULL, CDS_TEST, NULL)) {

        g_CurrentAngle = DevMode.dmDisplayOrientation;
    }
    else {

        OutputDebugString(L"MOSQUITO: Unable to read current rotation. Rotation disabled.");
        g_CurrentAngle = -1;
    }

    // Set up and register window class.

    wc.style = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc = WindowProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInstance;
    wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_MAIN_ICON));
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH )GetStockObject(BLACK_BRUSH);
    wc.lpszMenuName = NULL;
    wc.lpszClassName = NAME;
    RegisterClass(&wc);

    // Create a window.

    hWnd = CreateWindowEx(WS_EX_TOPMOST,
                          NAME,
                          TITLE,
                          WS_POPUP,
                          0,
                          0,
                          GetSystemMetrics(SM_CXSCREEN),
                          GetSystemMetrics(SM_CYSCREEN),
                          NULL,
                          NULL,
                          hInstance,
                          NULL);
    if (!hWnd)
        return FALSE;
    // We never show the window, only set focus to it.
    SetFocus(hWnd);

    // Create the main DirectDraw object

    hRet = DirectDrawCreate(NULL, &g_pDD, NULL);
    if (hRet != DD_OK)
        return InitFail(hWnd, hRet, szDDrawFailedMsg);

    // Get normal mode.

    hRet = g_pDD->SetCooperativeLevel(hWnd, DDSCL_NORMAL);
    if (hRet != DD_OK)
        return InitFail(hWnd, hRet, szSetCooperativeFailMsg);

    // Get a primary surface interface pointer (only needed for init.)

    memset(&ddsd, 0, sizeof(ddsd));
    ddsd.dwSize = sizeof(ddsd);
    ddsd.dwFlags = DDSD_CAPS;
    ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
    hRet = g_pDD->CreateSurface(&ddsd, &g_pDDSPrimary, NULL);
    if (hRet != DD_OK)
        return InitFail(hWnd, hRet, szCreateSurfaceFailMsg);

    // See if we can support overlays.

    memset(&ddcaps, 0, sizeof(ddcaps));
    ddcaps.dwSize = sizeof(ddcaps);
    hRet = g_pDD->GetCaps(&ddcaps, NULL);
    if (hRet != DD_OK)
        return InitFail(hWnd, hRet, szGetCapsFailMsg);

    if (ddcaps.dwOverlayCaps == 0)
        return InitFail(hWnd, hRet, szNoOverlaysMsg);

    // Get alignment info to compute our overlay surface size.

    rs.left = 0;
    rs.top = 0;
    rs.right = BUG_WIDTH;
    rs.bottom = BUG_HEIGHT;
    if (ddcaps.dwAlignSizeSrc != 0)
        rs.right += rs.right % ddcaps.dwAlignSizeSrc;
    
    // Create the overlay flipping surface. We will attempt the pixel formats
    // in our table one at a time until we find one that jives.

    memset(&ddsd, 0, sizeof(ddsd));
    ddsd.dwSize = sizeof(ddsd);
    ddsd.ddsCaps.dwCaps = DDSCAPS_OVERLAY | DDSCAPS_FLIP;
    ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_BACKBUFFERCOUNT | 
                   DDSD_PIXELFORMAT;
    ddsd.dwWidth = rs.right;
    ddsd.dwHeight = rs.bottom;
    ddsd.dwBackBufferCount = 2;

    int i = 0;
    do {
        ddsd.ddpfPixelFormat = ddpfOverlayFormats[i];
        hRet = g_pDD->CreateSurface(&ddsd, &g_pDDSOverlay, NULL);
    } while (hRet != DD_OK && (++i < PF_TABLE_SIZE));

    if (hRet != DD_OK)
        return InitFail(hWnd, hRet, szCreateOverlayFailMsg);

    // Load the images.

    if (LoadBugImages() != DD_OK)
        return InitFail(hWnd, hRet, szLoadOverlayFailMsg);

    // Finish setting up the overlay.

    int StretchFactor1000 = ddcaps.dwMinOverlayStretch > 1000 ? ddcaps.dwMinOverlayStretch : 1000;

    rd.left=0; 
    rd.top=0;
    // Adding 999 takes care of integer truncation problems.
    rd.right  = (rs.right * StretchFactor1000 + 999) / 1000;
    rd.bottom = rs.bottom * StretchFactor1000 / 1000;
    if (ddcaps.dwAlignSizeDest != 0)
        rd.right = (int)((rd.right + ddcaps.dwAlignSizeDest - 1)/ ddcaps.dwAlignSizeDest) *
                    ddcaps.dwAlignSizeDest;

    // Set the flags we'll send to UpdateOverlay
    dwUpdateFlags = DDOVER_SHOW;

    // Does the overlay hardware support source color keying?
    // If so, we can hide the black background around the image.
    // This probably won't work with YUV formats
    memset(&ovfx, 0, sizeof(ovfx));
    ovfx.dwSize = sizeof(ovfx);
    if (ddcaps.dwOverlayCaps & DDOVERLAYCAPS_CKEYSRC)
    {
        dwUpdateFlags |= DDOVER_KEYSRCOVERRIDE;

        // Create an overlay FX structure so we can specify a source color key.
        // This information is ignored if the DDOVER_SRCKEYOVERRIDE flag 
        // isn't set.
        ovfx.dckSrcColorkey.dwColorSpaceLowValue=0; // black as the color key
        ovfx.dckSrcColorkey.dwColorSpaceHighValue=0;
    }

    // Update the overlay parameters.

    hRet = g_pDDSOverlay->UpdateOverlay(&rs, g_pDDSPrimary, &rd, dwUpdateFlags, &ovfx);
    if (hRet != DD_OK)
        return InitFail(hWnd, hRet, szShowOverlayFailMsg);

    // Set a bunch of position and velocity module vars.

    g_nOverlayXPos = 0;
    g_nOverlayYPos = 0;
    g_nOverlayXVel = RANDOM_VELOCITY();
    g_nOverlayYVel = RANDOM_VELOCITY();
    g_nOverlayWidth = rd.right - rd.left;
    g_nOverlayHeight = rd.bottom - rd.top;
    
    // Set the "destination position alignment" global so we won't have to
    // keep calling GetCaps() everytime we move the overlay surface.

    g_dwOverlayXPositionAlignment = ddcaps.dwAlignBoundaryDest;

    // Create a timer to flip the pages.

    if (TIMER_ID != SetTimer(hWnd, TIMER_ID, TIMER_RATE, NULL))
        return InitFail(hWnd, hRet, szSetTimerFailMsg);

    return DD_OK;
}

//-----------------------------------------------------------------------------
// Name: WinMain()
// Desc: Initialization, message loop
//-----------------------------------------------------------------------------
int PASCAL
WinMain(HINSTANCE hInstance,
        HINSTANCE hPrevInstance,
#ifdef UNDER_CE
        LPWSTR lpCmdLine,
#else
        LPSTR lpCmdLine,
#endif
        int nCmdShow)
{
    MSG                         msg;

    g_hInstance = hInstance;

    InitApp(hInstance, nCmdShow);

    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    if (g_szErrorMessage != NULL){
        MessageBox(NULL, g_szErrorMessage, szDDrawError, MB_OK | MB_ICONEXCLAMATION);
        return FALSE;
    }

    return msg.wParam;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -