Copying a Frame to the Clipboard

The following code fragment copies a frame to the Clipboard. It uses the MCI_STATUS and MCI_WHERE commands to get the movie palette and playback-area extents. With this information, it can make a copy of the movie palette and create a bitmap sized to match the stage window. It then uses the MCI_UPDATE command to draw the current movie frame into the bitmap.

This example is similar to one presented in Chapter 7, “Using the Movie Player Functions.” The CopyPalette function, which makes a copy of the logical palette for the movie, is defined in the MMPLAY sample application included on your MDK disc.

void CopyFrame(HWND hWnd)         // hWnd is a handle to the stage window
{
    HPALETTE hPalette, hClipPalette;
    HDC hDC, hMemoryDC;
    HBITMAP hBitmap;

    MCI_STATUS_PARMS      mciStatus;
    MCI_ANIM_RECT_PARMS   mciRect;
    MCI_ANIM_UPDATE_PARMS mciUpdate;

    /* Get handle to movie palette, and make a copy of the palette.
     */
    mciStatus.dwItem = MCI_ANIM_STATUS_HPAL;
    dwError = mciSendCommand(wDeviceID, MCI_STATUS, MCI_STATUS_ITEM,
                              (DWORD)(LPVOID)&mciStatus);

    if(dwError)
    {
        showError(dwError);
        return;
    }
    hPalette = mciStatus.dwReturn;

    if((hClipPalette = CopyPalette(hPalette)) == NULL)
    {
        MessageBox(hWndMain, "Could not copy palette.", szAppName, MB_OK);
        return;
    }

    /* Get playback area extents.
     */
    dwError = mciSendCommand(wDeviceID, MCI_WHERE,
                    MCI_ANIM_WHERE_DESTINATION | MCI_ANIM_RECT,
                    (DWORD)(LPVOID)&mciRect);

    if(dwError)
    {
        showError(dwError);
        return;
    }

    /* Create bitmap, sized to match the playback area.
     */
    hDC = GetDC(hWnd);
    hMemoryDC = CreateCompatibleDC(hDC);
    hBitmap = CreateCompatibleBitmap(hDC, mciRect.rc.right,
                                                                                mciRect.rc.bottom);

    /* Select the bitmap into the memory DC and draw the
     * movie frame into the bitmap.
     */
    SelectObject(hMemoryDC, hBitmap);

    mciUpdate.hDC = hMemoryDC;
    dwError = mciSendCommand(wDeviceID, MCI_UPDATE, MCI_ANIM_UPDATE_HDC,
                              (DWORD)(LPVOID)&mciUpdate);

    if(dwError)
        showError(dwError)
    else
    {
        /* Place the bitmap and logical palette on the Clipboard.
         */
        if(OpenClipboard(hWnd))
        {
            EmptyClipboard();
            SetClipboardData(CF_BITMAP, hBitmap);
            SetClipboardData(CF_PALETTE, hClipPalette);
            CloseClipboard();
        }
        else
            MessageBox(hWndMain, "Could not open Clipboard.",
                        szAppName, MB_OK | MB_ICONEXCLAMATION);
    }
    DeleteDC(hMemoryDC);
    ReleaseDC(hWnd, hDC);
}