📄 bitmap.cpp
字号:
//------------------------------------------------------------------------------
// File: Bitmap.cpp
//
// Desc: DirectShow sample code - Bitmap manipulation routines for
// VMR alpha-blended bitmap
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
#include <dshow.h>
#include <commctrl.h>
#include <commdlg.h>
#include <stdio.h>
#include <tchar.h>
#include <atlbase.h>
#include "ticker.h"
#include "bitmap.h"
//
// Constants
//
const float EDGE_BUFFER=0.04f; // Pixel buffer between bitmap and window edge
// (represented in composition space [0 - 1.0f])
const float SLIDE_VALUE = 0.05f; // Amount to slide image in composition space
const int SLIDE_TIMER = 2001;
const int SLIDE_TIMEOUT = 125; // 125 ms between ticker movements
//
// Global data
//
IVMRMixerBitmap9 *pBMP = NULL;
DWORD g_dwTickerFlags=0;
int gnSlideTimer=0;
TCHAR g_szAppText[DYNAMIC_TEXT_SIZE]={0};
float g_fBitmapCompWidth=0; // Width of bitmap in composition space units
int g_nImageWidth=0; // Width of text bitmap
// Text font information
HFONT g_hFont=0;
LONG g_lFontPointSize = DEFAULT_FONT_SIZE;
TCHAR g_szFontName[100] = {DEFAULT_FONT_NAME};
TCHAR g_szFontStyle[32] = {DEFAULT_FONT_STYLE};
COLORREF g_rgbColors = DEFAULT_FONT_COLOR;
// Destination rectangle used for alpha-blended text
VMR9NormalizedRect g_rDest={0};
HRESULT BlendApplicationImage(HWND hwndApp)
{
LONG cx, cy;
HRESULT hr;
// Read the default video size
hr = pWC->GetNativeVideoSize(&cx, &cy, NULL, NULL);
if (FAILED(hr))
{
Msg(TEXT("GetNativeVideoSize FAILED! hr=0x%x\r\n"), hr);
return hr;
}
// Load the bitmap to alpha blend from the resource file
HBITMAP hbm = LoadBitmap(ghInst, MAKEINTRESOURCE(IDR_TICKER));
// Create a device context compatible with the current window
HDC hdc = GetDC(hwndApp);
HDC hdcBmp = CreateCompatibleDC(hdc);
ReleaseDC(hwndApp, hdc);
// Select our bitmap into the device context and save the old one
BITMAP bm;
HBITMAP hbmOld;
GetObject(hbm, sizeof(bm), &bm);
hbmOld = (HBITMAP)SelectObject(hdcBmp, hbm);
// Configure the VMR's bitmap structure
VMR9AlphaBitmap bmpInfo;
ZeroMemory(&bmpInfo, sizeof(bmpInfo) );
bmpInfo.dwFlags = VMRBITMAP_HDC;
bmpInfo.hdc = hdcBmp;
// Remember the width of this new bitmap
g_nImageWidth = bm.bmWidth;
// Save the ratio of the bitmap's width to the width of the video file.
// This value is used to reposition the bitmap in composition space.
g_fBitmapCompWidth = (float)g_nImageWidth / (float)cx;
// Display the bitmap in the bottom right corner.
// rSrc specifies the source rectangle in the GDI device context
// rDest specifies the destination rectangle in composition space (0.0f to 1.0f)
SetRect(&bmpInfo.rSrc, 0, 0, g_nImageWidth, bm.bmHeight);
bmpInfo.rDest.left = 1.0f;
bmpInfo.rDest.right = 1.0f + g_fBitmapCompWidth;
bmpInfo.rDest.top = (float)(cy - bm.bmHeight) / (float)cy - EDGE_BUFFER;
bmpInfo.rDest.bottom = 1.0f - EDGE_BUFFER;
// Copy initial settings to global memory for later modification
g_rDest = bmpInfo.rDest;
// Transparency value 1.0 is opaque, 0.0 is transparent.
bmpInfo.fAlpha = TRANSPARENCY_VALUE;
// Set the COLORREF so that the bitmap outline will be transparent
SetColorRef(bmpInfo);
// Give the bitmap to the VMR for display
hr = pBMP->SetAlphaBitmap(&bmpInfo);
if (FAILED(hr))
{
Msg(TEXT("SetAlphaBitmap FAILED! hr=0x%x\r\n\r\n%s\0"),
hr, STR_VMR_DISPLAY_WARNING);
}
// Select the initial object back into our device context
DeleteObject(SelectObject(hdcBmp, hbmOld));
// Clean up resources
DeleteObject(hbm);
DeleteDC(hdcBmp);
return hr;
}
void ClearTickerState(void)
{
if (gnSlideTimer)
{
KillTimer(NULL, gnSlideTimer);
gnSlideTimer = 0;
}
// Clear current ticker flags
g_dwTickerFlags = 0;
// Enable all Ticker menu items, which may have been
// disabled if the ticker was currently disabled
EnableMenuItem(ghMenu, ID_SLIDE, MF_ENABLED);
EnableMenuItem(ghMenu, ID_TICKER_STATIC_IMAGE, MF_ENABLED);
EnableMenuItem(ghMenu, ID_TICKER_DYNAMIC_TEXT, MF_ENABLED);
EnableMenuItem(ghMenu, ID_SET_FONT, MF_ENABLED);
EnableMenuItem(ghMenu, ID_SET_TEXT, MF_ENABLED);
// Clear menu check marks
CheckMenuItem(ghMenu, ID_SLIDE, MF_UNCHECKED);
}
HRESULT DisableTicker(DWORD dwFlags)
{
HRESULT hr;
VMR9AlphaBitmap bmpInfo={0};
// Read the current bitmap settings
hr = pBMP->GetAlphaBitmapParameters(&bmpInfo);
if (FAILED(hr))
Msg(TEXT("GetAlphaBitmapParameters FAILED! hr=0x%x\r\n"), hr);
// If the request is to disable the bitmap, then disable it
// and ignore the other flags for now
if (dwFlags & MARK_DISABLE)
{
// Temporarily disable bitmap display
bmpInfo.dwFlags = VMRBITMAP_DISABLE;
// Disable other ticker menu items
EnableMenuItem(ghMenu, ID_SLIDE, MF_GRAYED);
EnableMenuItem(ghMenu, ID_TICKER_STATIC_IMAGE, MF_GRAYED);
EnableMenuItem(ghMenu, ID_TICKER_DYNAMIC_TEXT, MF_GRAYED);
EnableMenuItem(ghMenu, ID_SET_FONT, MF_GRAYED);
EnableMenuItem(ghMenu, ID_SET_TEXT, MF_GRAYED);
// Update the bitmap settings
hr = pBMP->UpdateAlphaBitmapParameters(&bmpInfo);
if (FAILED(hr))
Msg(TEXT("UpdateAlphaBitmapParameters FAILED to disable ticker! hr=0x%x\r\n"), hr);
}
else
{
// Reset the bitmap with default values
if (g_dwTickerFlags & MARK_STATIC_IMAGE)
hr = BlendApplicationImage(ghApp);
else
hr = BlendApplicationText(ghApp, g_szAppText);
// Reenable other ticker menu items
EnableMenuItem(ghMenu, ID_SLIDE, MF_ENABLED);
EnableMenuItem(ghMenu, ID_TICKER_STATIC_IMAGE, MF_ENABLED);
EnableMenuItem(ghMenu, ID_TICKER_DYNAMIC_TEXT, MF_ENABLED);
EnableMenuItem(ghMenu, ID_SET_FONT, MF_ENABLED);
EnableMenuItem(ghMenu, ID_SET_TEXT, MF_ENABLED);
}
return hr;
}
void FlipFlag(DWORD dwFlag)
{
// If the flag is set, clear it
if (g_dwTickerFlags & dwFlag)
g_dwTickerFlags &= ~dwFlag;
// Otherwise, set the flag
else
g_dwTickerFlags |= dwFlag;
}
void SlideTicker(DWORD dwFlags)
{
if (dwFlags & MARK_SLIDE)
{
gnSlideTimer = (int) SetTimer(NULL, SLIDE_TIMER, SLIDE_TIMEOUT, TimerProc);
CheckMenuItem(ghMenu, ID_SLIDE, MF_CHECKED);
}
else
{
if (gnSlideTimer)
{
KillTimer(NULL, gnSlideTimer);
gnSlideTimer=0;
}
CheckMenuItem(ghMenu, ID_SLIDE, MF_UNCHECKED);
ResetBitmapPosition();
}
}
VOID CALLBACK TimerProc(
HWND hwnd, // handle to window
UINT uMsg, // WM_TIMER message
UINT_PTR idEvent, // timer identifier
DWORD dwTime // current system time
)
{
HandleSlide();
}
void HandleSlide(void)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -