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

📄 bmpmix9.cpp

📁 最近在学习directshow, Directshow实务精选的源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
                              0,0, // size
                              LR_DEFAULTCOLOR | LR_DEFAULTSIZE );
    if( hBitmap )
    {
        BITMAP bmpInfo;
        if( ::GetObject( hBitmap, sizeof(bmpInfo), &bmpInfo ) )
        {
            lHeight = bmpInfo.bmHeight;
            lWidth  = bmpInfo.bmWidth;
            ret = true;
        }    
    }

    DeleteObject( hBitmap );
    return ret;
}

HRESULT SetInitialAlphaBitmap()
{
    HRESULT hr = E_FAIL;
    VMR9AlphaBitmap alphaBitmap;

    // Initialize the alpha bitmap
    FAIL_RET( SetUpAlphaBitmap( alphaBitmap, 0 ) );
    
    // Apply the bitmap to the VMR
    FAIL_RET( g_pMixerBitmap->SetAlphaBitmap( &alphaBitmap ) );

    return hr;
}

HRESULT UpdateAlphaBitmap(int nIndex)
{
    HRESULT hr = E_FAIL;
    VMR9AlphaBitmap alphaBitmap;

    // Update the bitmap by index
    FAIL_RET( SetUpAlphaBitmap( alphaBitmap, nIndex ) );

    // Apply the bitmap to the VMR
    FAIL_RET( g_pMixerBitmap->SetAlphaBitmap( &alphaBitmap ) );

    return hr;
}

HRESULT SetUpAlphaBitmap( VMR9AlphaBitmap& alphaBitmap, int nIndex )
{
    if( g_pMixerBitmap == NULL || g_pSurfaces[nIndex] == NULL )
    {
        return E_FAIL;
    }

    ZeroMemory( &alphaBitmap, sizeof VMR9AlphaBitmap);

    // Initialize VMR9AlphaBitmap structure
    alphaBitmap.dwFlags   = VMR9AlphaBitmap_EntireDDS | VMR9AlphaBitmap_SrcColorKey;
    alphaBitmap.hdc       = NULL;
    alphaBitmap.pDDS      = g_pSurfaces[nIndex];
    alphaBitmap.clrSrcKey = RGB(255,255,255);  // white background

    // Position the bitmap within the VMR's composition space (0.0 - 1.0).
    // Because the bitmap can move on mouse clicks, keep track of the
    // current X and Y positions.  The width/height of the alpha-bitmap are
    // predetermined by constant sizes.
    alphaBitmap.rDest.top    = g_fCurrentY - BMP_SIZE_Y / 2;
    alphaBitmap.rDest.left   = g_fCurrentX - BMP_SIZE_X / 2;
    alphaBitmap.rDest.bottom = g_fCurrentY + BMP_SIZE_Y / 2;
    alphaBitmap.rDest.right  = g_fCurrentX + BMP_SIZE_X / 2;
    alphaBitmap.fAlpha       = ALPHA_VALUE;

    return S_OK;
}

HRESULT MoveAlphaBitmap(float fX, float fY)
{
    HRESULT hr=S_OK;
    VMR9AlphaBitmap alphaBitmap;

    if( g_pMixerBitmap == NULL || g_pSurfaces[g_nCurrentImage] == NULL )
    {
        return E_FAIL;
    }

    ZeroMemory( &alphaBitmap, sizeof VMR9AlphaBitmap);

    // Initialize VMR9AlphaBitmap structure
    alphaBitmap.dwFlags   = VMR9AlphaBitmap_EntireDDS | VMR9AlphaBitmap_SrcColorKey;
    alphaBitmap.hdc       = NULL;
    alphaBitmap.pDDS      = g_pSurfaces[g_nCurrentImage];
    alphaBitmap.clrSrcKey = RGB(255,255,255);

    // Position the bitmap within the VMR's composition space (0.0 - 1.0)
    // centered around the mouse point
    alphaBitmap.rDest.top    = fY - BMP_SIZE_Y / 2;
    alphaBitmap.rDest.left   = fX - BMP_SIZE_X / 2;
    alphaBitmap.rDest.bottom = fY + BMP_SIZE_Y / 2;
    alphaBitmap.rDest.right  = fX + BMP_SIZE_X / 2;
    alphaBitmap.fAlpha       = ALPHA_VALUE;

    // Apply the bitmap to the VMR
    FAIL_RET( g_pMixerBitmap->SetAlphaBitmap( &alphaBitmap ) );

    // We successfully set the value, so remember the current coordinates
    g_fCurrentX = fX;
    g_fCurrentY = fY;

    return S_OK;
}

//
//  FUNCTION: MyRegisterClass()
//
//  PURPOSE: Registers the window class.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
    WNDCLASSEX wcex;
    ZeroMemory(&wcex, sizeof(wcex));

    // Set the members of the window class structure.
    // Don't provide a background brush, because we process the WM_PAINT
    // messages in OnPaint().  If a movie is active, we tell the VMR to
    // repaint the window; otherwise, we repaint with COLOR_WINDOW+1.
    // If a background brush is provided, you will see a white flicker
    // whenever you resize the main application window, because Windows
    // will repaint the window before the application also repaints.
    wcex.cbSize = sizeof(WNDCLASSEX);
    wcex.lpfnWndProc    = (WNDPROC)WndProc;
    wcex.hInstance      = hInstance;
    wcex.hIcon          = LoadIcon(hInstance, (LPCTSTR)IDI_BMPMIX9);
    wcex.hIconSm        = LoadIcon(hInstance, (LPCTSTR)IDI_BMPMIX9);
    wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
    wcex.lpszMenuName   = (LPCTSTR)IDC_BMPMIX9;
    wcex.lpszClassName  = szWindowClass;
    
    return RegisterClassEx(&wcex);
}

//
//   FUNCTION: InitInstance(HANDLE, int)
//
//   PURPOSE: Saves instance handle and creates main window
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow, HWND& hWnd)
{
   hInst = hInstance; // Store instance handle in our global variable

   hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
                       CW_USEDEFAULT, CW_USEDEFAULT, 400, 400, 
                       NULL, NULL, hInstance, NULL);
   if (!hWnd)
   {
      return FALSE;
   }

   ShowWindow(hWnd, nCmdShow);
   UpdateWindow(hWnd);

   return TRUE;
}

// Message handler for about box
LRESULT CALLBACK AboutDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
        case WM_INITDIALOG:
                return TRUE;

        case WM_COMMAND:
            if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) 
            {
                EndDialog(hDlg, LOWORD(wParam));
                return TRUE;
            }
            break;
    }
    return FALSE;
}


//
//  FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
//
//  PURPOSE:  Processes messages for the main window.
//
//  WM_COMMAND  - process the application menu
//  WM_PAINT    - paint the main window
//  WM_DESTROY  - post a quit message and return
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    HRESULT hr;

    switch (message) 
    {
        case WM_COMMAND:
        {
            int nId, nEvent;
            nId    = LOWORD(wParam); 
            nEvent = HIWORD(wParam); 

            // Parse the menu selections:
            switch (nId)
            {
                case IDM_PLAY_FILE:
                    hr = StartGraph(g_hWnd);
                    if( FAILED(hr) )
                    {
                        MessageBox(NULL, TEXT("Failed to create the VMR9 graph!"), 
                                   TEXT("BitmapMix9 failure!"), MB_OK);
                    }
                    g_nCurrentImage = 0;
                    break;

                case IDM_FILE_CLOSE:
                    OnFileClose( hWnd );
                    break;

                case IDM_ABOUT:
                   DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)AboutDlgProc);
                   break;

                case IDM_EXIT:
                   DestroyWindow(hWnd);
                   break;
            }
            break;
        }

        case WM_PAINT:
            OnPaint(hWnd);
            break;

        case WM_MOUSEMOVE:
            // If the left mouse button is down, treat this as a drag operation
            if (wParam & MK_LBUTTON)
                HandleMouseClick(lParam);
            break;

        case WM_LBUTTONDOWN:
            HandleMouseClick(lParam);
            break;

        case WM_DISPLAYCHANGE:
            if( g_pWC )
                g_pWC->DisplayModeChanged();
            break;

        case WM_SIZE:
            if( g_pWC )
            {
                RECT clientRect;
                if( ::GetClientRect( g_hWnd, &clientRect ) )
                {
                    g_pWC->SetVideoPosition(NULL, &clientRect );            
                }
            }
            break;

        case WM_TIMER:
            if( (UINT_PTR) wParam == g_nTimerID )
            {
                // Rotate through our list of bitmaps
                g_nCurrentImage++;
                g_nCurrentImage %= NUMBITMAPS;

                hr = UpdateAlphaBitmap(g_nCurrentImage);
                if( FAILED( hr ) )
                    return 0;
            }
            break;

        case WM_DESTROY:
            KillTimer(g_hWnd, g_nTimerID);
            PostQuitMessage(0);
            break;
   }

   return DefWindowProc(hWnd, message, wParam, lParam);
}

void OnFileClose( HWND hWnd )
{
    if( g_pMC != NULL ) 
    {
        OAFilterState state;
        do {
            g_pMC->Stop();
            g_pMC->GetState(0, & state );
        } while( state != State_Stopped ) ;
    }

    ClearD3D();
    ClearDirectShow();
    ::InvalidateRect( hWnd, NULL, TRUE );
}

void OnPaint(HWND hwnd) 
{
    HRESULT hr;
    PAINTSTRUCT ps; 
    HDC         hdc; 
    RECT        rcClient; 

    GetClientRect(hwnd, &rcClient); 
    hdc = BeginPaint(hwnd, &ps); 

    if(g_pWC) 
    { 
        // When using VMR Windowless mode, you must explicitly tell the
        // renderer when to repaint the video in response to WM_PAINT
        // messages.  This is most important when the video is stopped
        // or paused, since the VMR won't be automatically updating the
        // window as the video plays.
        if (g_pWC)
            hr = g_pWC->RepaintVideo(hwnd, hdc);  
    } 
    else  // No video image. Just paint the whole client area. 
    { 
        FillRect(hdc, &rcClient, (HBRUSH)(COLOR_WINDOW + 1)); 
    } 

    EndPaint(hwnd, &ps); 
} 


void HandleMouseClick(LPARAM lParam)
{
    // Make sure that we're already playing the movie
    if (!g_bRunning)
        return;

    // Get the window coordinates of the mouse pointer
    int xPos = GET_X_LPARAM(lParam);
    int yPos = GET_Y_LPARAM(lParam);

    // Get the window client area rectangle
    RECT rcClient; 
    GetClientRect(g_hWnd, &rcClient); 

    // Convert the click position into composition space coordinates,
    // which range from 0.0 to 1.0
    float fX, fY;
    fX = (float) ((float)xPos / (float)rcClient.right );
    fY = (float) ((float)yPos / (float)rcClient.bottom );

    // Bound coordinates to allowed space
    if (fX > 1.0) fX = 1.0;    if (fX < 0.0) fX = 0.0;
    if (fY > 1.0) fY = 1.0;    if (fY < 0.0) fY = 0.0;

    // Because mouse movement messages can be very frequent,
    // only update the bitmap if it has moved a sufficient distance.
    if ((fabs(fX - g_fCurrentX) >= MOVE_TOLERANCE) ||
        (fabs(fY - g_fCurrentY) >= MOVE_TOLERANCE))
    {
        MoveAlphaBitmap(fX, fY);
    }
}

⌨️ 快捷键说明

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