📄 复件 testvip.cpp
字号:
// TestVip.cpp : Application that utilizes the DirectDraw to test the VIP driver.
// Note: Window mode not complete yet, so the dialog of the screen settings is not available.
#include "stdafx.h"
#include "resource.h"
#define WS_EX_APPWINDOW 0x00040000L
#define MAX_LOADSTRING 100
#ifdef DEFINE_GUID
#undef DEFINE_GUID
#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
EXTERN_C const GUID name \
= { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } }
#endif
DEFINE_GUID(IID_IDirectDraw4, 0x9c59509a,0x39bd,0x11d1,0x8c,0x4a,0x00,0xc0,0x4f,0xd9,0x30,0xc5 );
DEFINE_GUID(IID_IDDVideoPortContainer, 0x6C142760,0xA733,0x11CE,0xA5,0x21,0x00,0x20,0xAF,0x0B,0xE5,0x60 );
// Global Variables:
HINSTANCE g_hInst; // current instance
HMENU g_hMenu;
HWND g_hWnd;
HWND g_hWndCB;
TCHAR g_szTitle[MAX_LOADSTRING]; // The title bar text
TCHAR g_szWindowClass[MAX_LOADSTRING]; // The title bar text
UINT g_uiVideoChkItemId;
UINT g_uiColourChkItemId;
UINT g_uiFieldChkItemId;
LPDDVIDEOPORTCONTAINER g_pVPContainer = NULL;// Video port container object
LPDIRECTDRAWVIDEOPORT g_pVideoPort = NULL; // Video port object
DDPIXELFORMAT g_vpInputFormats[4]; // Input format of the video port
DDVIDEOPORTINFO g_vpInfo; // Video port information
DDCOLORCONTROL g_vpColorControl; // Current color data of the video port
LPDIRECTDRAW4 g_pDD = NULL; // DirectDraw object
LPDIRECTDRAWSURFACE4 g_pDDSPrimary = NULL; // DirectDraw primary surface
LPDIRECTDRAWSURFACE4 g_pDDSOverlay = NULL; // DirectDraw back surface
LPDIRECTDRAWSURFACE4 g_pDDSCurrVPSurf; // Current surface that is written by video port
HANDLE g_hAppMutex = NULL;
BOOL g_fFullScreen;
RECT g_rectLockArea;
// Forward declarations of functions included in this code module:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
BOOL CALLBACK SettingDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
BOOL InitPlay(VOID);
BOOL InitFail(LPCTSTR szError,...);
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
// TODO: Place code here.
MSG msg;
HACCEL hAccelTable;
HANDLE hMutex;
hMutex = CreateMutex(NULL, FALSE, TEXT("TestVipInstance"));
if( hMutex && (GetLastError()==ERROR_ALREADY_EXISTS) )
{
RETAILMSG(1, (TEXT("Previous instance already exist.")));
CloseHandle(hMutex);
return FALSE;
}
g_hAppMutex = hMutex;
// Initialize global strings
LoadString(hInstance, IDS_APP_TITLE, g_szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_TESTVIP, g_szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
// Perform application initialization:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
if( !InitPlay() )
return FALSE;
hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_TESTVIP);
// Main message loop:
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return msg.wParam;
}
VOID ReleaseObjects(VOID)
{
if( g_pDDSOverlay != NULL )
{
g_pDDSOverlay->Release();
g_pDDSOverlay = NULL;
}
if( g_pDDSPrimary != NULL )
{
g_pDDSPrimary->Release();
g_pDDSPrimary = NULL;
}
if( g_pDD != NULL )
{
g_pDD->Release();
g_pDD = NULL;
}
if( g_pVideoPort != NULL )
{
g_pVideoPort->Release();
g_pVideoPort = NULL;
}
if( g_pVPContainer != NULL )
{
g_pVPContainer->Release();
g_pVPContainer = NULL;
}
if( g_hAppMutex != NULL )
{
CloseHandle(g_hAppMutex);
g_hAppMutex = NULL;
}
}
BOOL InitFail(LPCTSTR szError,...)
{
va_list vl;
va_start(vl, szError);
RETAILMSG(1, (szError, vl));
ReleaseObjects();
DestroyWindow(g_hWnd);
va_end(vl);
return FALSE;
}
//
// FUNCTION: MyRegisterClass()
//
// PURPOSE: Registers the window class.
//
// COMMENTS:
//
// This function and its usage is only necessary if you want this code
// to be compatible with Win32 systems prior to the 'RegisterClassEx'
// function that was added to Windows 95. It is important to call this function
// so that the application will get 'well formed' small icons associated
// with it.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASS wc;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = (WNDPROC) WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = 0;
wc.hCursor = 0;
wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = 0;
wc.lpszClassName = g_szWindowClass;
return RegisterClass(&wc);
}
HRESULT WINAPI EnumVideoCallback(LPDDVIDEOPORTCAPS lpDDVideoPortCaps, LPVOID lpContext)
{
RETAILMSG(1, (TEXT("Got video port %d: max width %d; max height %d; CAPS 0x%x; FX 0x%x"),
lpDDVideoPortCaps->dwVideoPortID, lpDDVideoPortCaps->dwMaxWidth,
lpDDVideoPortCaps->dwMaxHeight, lpDDVideoPortCaps->dwCaps,
lpDDVideoPortCaps->dwFX));
memcpy(lpContext, lpDDVideoPortCaps, sizeof(DDVIDEOPORTCAPS));
return DDENUMRET_OK;
}
BOOL InitPlay(VOID)
{
DWORD dwFlags;
DDSURFACEDESC2 ddsd;
HRESULT hRet;
LPDIRECTDRAW pDD;
hRet = DirectDrawCreate(NULL, &pDD, NULL);
if (hRet != DD_OK)
return InitFail(TEXT("DirectDrawCreate FAILED"));
// Fetch DirectDraw4 interface
hRet = pDD->QueryInterface(IID_IDirectDraw4, (LPVOID *)&g_pDD);
if (hRet != DD_OK)
return InitFail(TEXT("QueryInterface for IID_IDirectDraw4 FAILED"));
// Fetch VideoPortContainer interface
hRet = pDD->QueryInterface(IID_IDDVideoPortContainer, (LPVOID *)&g_pVPContainer);
if (hRet != DD_OK)
return InitFail(TEXT("QueryInterface for IID_IDDVideoPortContainer FAILED"));
pDD->Release();
pDD = NULL;
// Get exclusive mode
g_fFullScreen = TRUE;
dwFlags = DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN;
hRet = g_pDD->SetCooperativeLevel(g_hWnd, dwFlags);
if (hRet != DD_OK)
return InitFail(TEXT("SetCooperativeLevel FAILED, g_fFullScreen is %d"), g_fFullScreen);
// Create the primary surface
memset(&ddsd, 0, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_VIDEOPORT;
hRet = g_pDD->CreateSurface(&ddsd, &g_pDDSPrimary, NULL);
if (hRet != DD_OK)
return InitFail(TEXT("Create primary surface FAILED"));
// Create the overlay surface
/* memset(&ddsd, 0, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS;
ddsd.ddsCaps.dwCaps = DDSCAPS_OVERLAY | DDSCAPS_VIDEOPORT;
hRet = g_pDD->CreateSurface(&ddsd, &g_pDDSOverlay, NULL);
if (hRet != DD_OK)
return InitFail(TEXT("Create overlay surface FAILED"));
*/
// Enum video ports
DDVIDEOPORTCAPS vpCaps;
DDVIDEOPORTCONNECT vpConnectInfo[4];
DWORD dwInfoArrayLen = 4;
hRet = g_pVPContainer->EnumVideoPorts(0, NULL, &vpCaps, EnumVideoCallback);
if (hRet != DD_OK)
return InitFail(TEXT("Enumerate video ports FAILED"));
// Get connect information
hRet = g_pVPContainer->GetVideoPortConnectInfo(vpCaps.dwVideoPortID, &dwInfoArrayLen, vpConnectInfo);
if ((hRet!=DD_OK) && (hRet!=DDERR_MOREDATA))
return InitFail(TEXT("Get connect information of video port FAILED"));
// Create video port
DDVIDEOPORTDESC vpDesc;
vpDesc.dwSize = sizeof(DDVIDEOPORTDESC);
vpDesc.dwFieldWidth = 720;
vpDesc.dwVBIWidth = 0;
vpDesc.dwFieldHeight = 260; // include VBI height(20 lines)
vpDesc.dwMicrosecondsPerField = 16000; // 16ms/field = 60fields/s ; maybe??
vpDesc.dwMaxPixelsPerSecond = 240 * 240 * 60;
vpDesc.dwVideoPortID = vpCaps.dwVideoPortID;
vpDesc.dwReserved1 = 0;
memcpy(&vpDesc.VideoPortType, &vpConnectInfo[0], sizeof(DDVIDEOPORTCONNECT));
vpDesc.dwReserved2 = 0;
vpDesc.dwReserved3 = 0;
hRet = g_pVPContainer->CreateVideoPort(DDVPCREATE_VIDEOONLY, &vpDesc, &g_pVideoPort, NULL);
if (hRet != DD_OK)
return InitFail(TEXT("Create video port FAILED"));
// Set target surface
hRet = g_pVideoPort->SetTargetSurface((LPDIRECTDRAWSURFACE)g_pDDSPrimary, DDVPTARGET_VIDEO);
if (hRet != DD_OK)
return InitFail(TEXT("Set target surface FAILED"));
g_pDDSCurrVPSurf = g_pDDSPrimary;
// Get input formats
DWORD dwNumFormats = 4;
hRet = g_pVideoPort->GetInputFormats(&dwNumFormats, g_vpInputFormats, DDVPFORMAT_VIDEO);
if (hRet != DD_OK)
return InitFail(TEXT("Get input formats FAILED"));
// Get color control
g_vpColorControl.dwSize = sizeof(DDCOLORCONTROL);
hRet = g_pVideoPort->GetColorControls(&g_vpColorControl);
if (hRet != DD_OK)
return InitFail(TEXT("Get color controls FAILED"));
// Start video
g_vpInfo.dwSize = sizeof(DDVIDEOPORTINFO);
g_vpInfo.dwOriginX = 0;
g_vpInfo.dwOriginY = 0;
g_vpInfo.dwVPFlags = DDVP_CROP | DDVP_PRESCALE;
g_vpInfo.rCrop.left = 0;
g_vpInfo.rCrop.top = 0; // Exclude VBI
g_vpInfo.rCrop.right = 720;
g_vpInfo.rCrop.bottom = 251+4;
g_vpInfo.dwPrescaleWidth = 320;
g_vpInfo.dwPrescaleHeight = 240;
g_vpInfo.lpddpfInputFormat = &g_vpInputFormats[0];
g_vpInfo.lpddpfVBIInputFormat = NULL;
g_vpInfo.lpddpfVBIOutputFormat = NULL;
g_vpInfo.dwVBIHeight = 17;
g_vpInfo.dwReserved1 = 0;
g_vpInfo.dwReserved2 = 0;
hRet = g_pVideoPort->StartVideo(&g_vpInfo);
if (hRet != DD_OK)
return InitFail(TEXT("Start video FAILED"));
g_uiVideoChkItemId = ID_MENUVIDEOPLAY;
return TRUE;
}
//
// FUNCTION: InitInstance(HANDLE, int)
//
// PURPOSE: Saves instance handle and creates main window
//
// COMMENTS:
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -