640 lines
18 KiB
C
640 lines
18 KiB
C
|
/****************************************************************************
|
||
|
*
|
||
|
* capinit.c
|
||
|
*
|
||
|
* Initialization code.
|
||
|
*
|
||
|
* Microsoft Video for Windows Sample Capture Class
|
||
|
*
|
||
|
* Copyright (c) 1992 - 1995 Microsoft Corporation. All Rights Reserved.
|
||
|
*
|
||
|
* You have a royalty-free right to use, modify, reproduce and
|
||
|
* distribute the Sample Files (and/or any modified version) in
|
||
|
* any way you find useful, provided that you agree that
|
||
|
* Microsoft has no warranty obligations or liability for any
|
||
|
* Sample Application Files which are modified.
|
||
|
*
|
||
|
***************************************************************************/
|
||
|
|
||
|
#define INC_OLE2
|
||
|
#pragma warning(disable:4103)
|
||
|
#include <windows.h>
|
||
|
#include <windowsx.h>
|
||
|
#include <win32.h>
|
||
|
|
||
|
#define MODULE_DEBUG_PREFIX "AVICAP32\\"
|
||
|
#define _INC_MMDEBUG_CODE_ TRUE
|
||
|
#include "MMDEBUG.H"
|
||
|
|
||
|
#if !defined CHICAGO
|
||
|
#include <ntverp.h>
|
||
|
#endif
|
||
|
|
||
|
#include <mmsystem.h>
|
||
|
|
||
|
#include <vfw.h>
|
||
|
#include "ivideo32.h"
|
||
|
#include "avicapi.h"
|
||
|
|
||
|
HINSTANCE ghInstDll;
|
||
|
TCHAR szCaptureWindowClass[] = TEXT("ClsCapWin");
|
||
|
|
||
|
|
||
|
// If the following structure changes, update AVICAP and AVICAP.32 also!!!
|
||
|
typedef struct tCapDriverInfo {
|
||
|
TCHAR szKeyEnumName[MAX_PATH];
|
||
|
TCHAR szDriverName[MAX_PATH];
|
||
|
TCHAR szDriverDescription[MAX_PATH];
|
||
|
TCHAR szDriverVersion[80];
|
||
|
TCHAR szSoftwareKey[MAX_PATH];
|
||
|
DWORD dnDevNode; // Set if this is a PnP device
|
||
|
BOOL fOnlySystemIni; // If the [path]drivername is only in system.ini
|
||
|
BOOL fDisabled; // User has disabled driver in the control panel
|
||
|
BOOL fActive; // Reserved
|
||
|
} CAPDRIVERINFO, FAR *LPCAPDRIVERINFO;
|
||
|
|
||
|
DWORD videoCreateDriverList (void);
|
||
|
DWORD videoFreeDriverList (void);
|
||
|
|
||
|
extern UINT wTotalVideoDevs; // total video devices
|
||
|
extern LPCAPDRIVERINFO aCapDriverList[]; // Array of all capture drivers
|
||
|
|
||
|
#if !defined CHICAGO
|
||
|
typedef struct tagVS_VERSION
|
||
|
{
|
||
|
WORD wTotLen;
|
||
|
WORD wValLen;
|
||
|
WORD wType;
|
||
|
TCHAR szSig[16];
|
||
|
WORD Padding1[1];
|
||
|
VS_FIXEDFILEINFO vffInfo;
|
||
|
} VS_VERSION;
|
||
|
|
||
|
typedef struct tagLANGANDCP
|
||
|
{
|
||
|
WORD wLanguage;
|
||
|
WORD wCodePage;
|
||
|
} LANGANDCP;
|
||
|
|
||
|
|
||
|
/*
|
||
|
typedef struct _VS_FIXEDFILEINFO { // vsffi
|
||
|
DWORD dwSignature;
|
||
|
DWORD dwStrucVersion;
|
||
|
DWORD dwFileVersionMS;
|
||
|
DWORD dwFileVersionLS;
|
||
|
DWORD dwProductVersionMS;
|
||
|
DWORD dwProductVersionLS;
|
||
|
DWORD dwFileFlagsMask;
|
||
|
DWORD dwFileFlags;
|
||
|
DWORD dwFileOS;
|
||
|
DWORD dwFileType;
|
||
|
DWORD dwFileSubtype;
|
||
|
DWORD dwFileDateMS;
|
||
|
DWORD dwFileDateLS;
|
||
|
} VS_FIXEDFILEINFO;
|
||
|
|
||
|
VS_VERSION_INFO {
|
||
|
WORD wLength;
|
||
|
WORD wValueLength;
|
||
|
WORD wType;
|
||
|
WCHAR szKey[16];
|
||
|
WORD Padding1[];
|
||
|
VS_FIXEDFILEINFO Value;
|
||
|
WORD Padding2[];
|
||
|
WORD Children[];
|
||
|
};
|
||
|
|
||
|
|
||
|
*/
|
||
|
|
||
|
#endif
|
||
|
|
||
|
BOOL gfIsRTL;
|
||
|
|
||
|
|
||
|
|
||
|
BOOL FAR PASCAL RegisterCaptureClass (HINSTANCE hInst)
|
||
|
{
|
||
|
WNDCLASS cls;
|
||
|
|
||
|
// If we're already registered, we're OK
|
||
|
if (GetClassInfo(hInst, szCaptureWindowClass, &cls))
|
||
|
return TRUE;
|
||
|
|
||
|
cls.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||
|
cls.hIcon = NULL;
|
||
|
cls.lpszMenuName = NULL;
|
||
|
cls.lpszClassName = szCaptureWindowClass;
|
||
|
cls.hbrBackground = (HBRUSH)(COLOR_APPWORKSPACE + 1);
|
||
|
cls.hInstance = hInst;
|
||
|
cls.style = CS_HREDRAW|CS_VREDRAW | CS_BYTEALIGNCLIENT |
|
||
|
CS_GLOBALCLASS | CS_DBLCLKS;
|
||
|
cls.lpfnWndProc = (WNDPROC) CapWndProc;
|
||
|
cls.cbClsExtra = 0;
|
||
|
// Kludge, VB Status and Error GlobalAlloc'd ptrs + room to grow...
|
||
|
cls.cbWndExtra = sizeof (LPCAPSTREAM) + sizeof (DWORD) * 4;
|
||
|
|
||
|
RegisterClass(&cls);
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Internal version
|
||
|
// Get the name and version of the video device
|
||
|
//
|
||
|
BOOL capInternalGetDriverDesc (UINT wDriverIndex,
|
||
|
LPTSTR lpszName, int cbName,
|
||
|
LPTSTR lpszVer, int cbVer)
|
||
|
{
|
||
|
#ifdef CHICAGO
|
||
|
// This calls into 16-bit AVICAP via a thunk
|
||
|
return (BOOL) capxGetDriverDescription ((WORD) wDriverIndex,
|
||
|
lpszName, (WORD) cbName,
|
||
|
lpszVer, (WORD) cbVer);
|
||
|
#else
|
||
|
LPTSTR lpVersion;
|
||
|
UINT wVersionLen;
|
||
|
BOOL bRetCode;
|
||
|
TCHAR szGetName[MAX_PATH];
|
||
|
DWORD dwVerInfoSize;
|
||
|
DWORD dwVerHnd;
|
||
|
TCHAR szBuf[MAX_PATH];
|
||
|
BOOL fGetName;
|
||
|
BOOL fGetVersion;
|
||
|
|
||
|
|
||
|
|
||
|
fGetName = lpszName != NULL && cbName != 0;
|
||
|
fGetVersion = lpszVer != NULL && cbVer != 0;
|
||
|
|
||
|
if(fGetName)
|
||
|
lpszName[0] = TEXT('\0');
|
||
|
if(fGetVersion)
|
||
|
lpszVer [0] = TEXT('\0');
|
||
|
|
||
|
|
||
|
if(DV_ERR_OK != videoCreateDriverList ())
|
||
|
return FALSE;
|
||
|
|
||
|
if(wDriverIndex >= wTotalVideoDevs) {
|
||
|
videoFreeDriverList ();
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
|
||
|
// Use description and version from registry,
|
||
|
// but can be overwritten by the file's description and product version.
|
||
|
if(fGetName) {
|
||
|
if(lstrlen(aCapDriverList[wDriverIndex]->szDriverDescription))
|
||
|
lstrcpyn(lpszName, aCapDriverList[wDriverIndex]->szDriverDescription, cbName);
|
||
|
else // If no description, we have at least the driver name.
|
||
|
lstrcpyn(lpszName, aCapDriverList[wDriverIndex]->szDriverName, cbName);
|
||
|
}
|
||
|
|
||
|
if(fGetVersion)
|
||
|
lstrcpyn(lpszVer, aCapDriverList[wDriverIndex]->szDriverVersion, cbVer);
|
||
|
|
||
|
lstrcpyn(szBuf, aCapDriverList[wDriverIndex]->szDriverName, MAX_PATH);
|
||
|
|
||
|
videoFreeDriverList ();
|
||
|
|
||
|
// You must find the size first before getting any file info
|
||
|
dwVerInfoSize = GetFileVersionInfoSize(szBuf, &dwVerHnd);
|
||
|
|
||
|
if (dwVerInfoSize) {
|
||
|
LPTSTR lpstrVffInfo; // Pointer to block to hold info
|
||
|
HANDLE hMem; // handle to mem alloc'ed
|
||
|
|
||
|
// Get a block big enough to hold version info
|
||
|
hMem = GlobalAlloc(GMEM_MOVEABLE, dwVerInfoSize);
|
||
|
lpstrVffInfo = GlobalLock(hMem);
|
||
|
|
||
|
// Get the File Version first
|
||
|
if (GetFileVersionInfo(szBuf, 0L, dwVerInfoSize, lpstrVffInfo)) {
|
||
|
VS_VERSION FAR *pVerInfo = (VS_VERSION FAR *) lpstrVffInfo;
|
||
|
|
||
|
// fill in the file version
|
||
|
wsprintf(szBuf,
|
||
|
TEXT("Version: %d.%d.%d.%d"),
|
||
|
HIWORD(pVerInfo->vffInfo.dwFileVersionMS),
|
||
|
LOWORD(pVerInfo->vffInfo.dwFileVersionMS),
|
||
|
HIWORD(pVerInfo->vffInfo.dwFileVersionLS),
|
||
|
LOWORD(pVerInfo->vffInfo.dwFileVersionLS));
|
||
|
if (fGetVersion)
|
||
|
lstrcpyn (lpszVer, szBuf, cbVer);
|
||
|
}
|
||
|
|
||
|
// Now try to get the FileDescription
|
||
|
// First try this for the "Translation" entry, and then
|
||
|
// try the American english translation.
|
||
|
// Keep track of the string length for easy updating.
|
||
|
// 040904E4 represents the language ID and the four
|
||
|
// least significant digits represent the codepage for
|
||
|
// which the data is formatted. The language ID is
|
||
|
// composed of two parts: the low ten bits represent
|
||
|
// the major language and the high six bits represent
|
||
|
// the sub language.
|
||
|
|
||
|
lstrcpy(szGetName, TEXT("\\StringFileInfo\\040904E4\\FileDescription"));
|
||
|
|
||
|
wVersionLen = 0;
|
||
|
lpVersion = NULL;
|
||
|
|
||
|
// Look for the corresponding string.
|
||
|
bRetCode = VerQueryValue((LPVOID)lpstrVffInfo,
|
||
|
(LPTSTR)szGetName,
|
||
|
(void FAR* FAR*)&lpVersion,
|
||
|
(UINT FAR *) &wVersionLen);
|
||
|
|
||
|
if (fGetName && bRetCode && wVersionLen && lpVersion)
|
||
|
lstrcpyn (lpszName, lpVersion, cbName);
|
||
|
|
||
|
// Let go of the memory
|
||
|
GlobalUnlock(hMem);
|
||
|
GlobalFree(hMem);
|
||
|
}
|
||
|
return TRUE;
|
||
|
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
#ifdef UNICODE
|
||
|
// ansi thunk for above (called from ansi thunk functions
|
||
|
// for capGetDriverDescriptionA, and WM_GET_DRIVER_NAMEA etc)
|
||
|
BOOL capInternalGetDriverDescA(UINT wDriverIndex,
|
||
|
LPSTR lpszName, int cbName,
|
||
|
LPSTR lpszVer, int cbVer)
|
||
|
{
|
||
|
LPWSTR pName = NULL, pVer = NULL;
|
||
|
BOOL bRet;
|
||
|
|
||
|
if (lpszName) {
|
||
|
pName = LocalAlloc(LPTR, cbName * sizeof(WCHAR));
|
||
|
}
|
||
|
|
||
|
if (lpszVer) {
|
||
|
pVer = LocalAlloc(LPTR, cbVer * sizeof(WCHAR));
|
||
|
}
|
||
|
|
||
|
bRet = capInternalGetDriverDesc(
|
||
|
wDriverIndex,
|
||
|
pName, cbName,
|
||
|
pVer, cbVer);
|
||
|
|
||
|
if (lpszName) {
|
||
|
WideToAnsi(lpszName, pName, cbName);
|
||
|
}
|
||
|
|
||
|
if (lpszVer) {
|
||
|
WideToAnsi(lpszVer, pVer, cbVer);
|
||
|
}
|
||
|
|
||
|
if (pVer) {
|
||
|
LocalFree(pVer);
|
||
|
}
|
||
|
|
||
|
if (pName) {
|
||
|
LocalFree(pName);
|
||
|
}
|
||
|
|
||
|
return bRet;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
|
||
|
//
|
||
|
// Exported version
|
||
|
// Get the name and version of the video device
|
||
|
//
|
||
|
// unicode and win-16 version - see ansi thunk below
|
||
|
BOOL VFWAPI capGetDriverDescription (UINT wDriverIndex,
|
||
|
LPTSTR lpszName, int cbName,
|
||
|
LPTSTR lpszVer, int cbVer)
|
||
|
{
|
||
|
return (capInternalGetDriverDesc (wDriverIndex,
|
||
|
lpszName, cbName,
|
||
|
lpszVer, cbVer));
|
||
|
}
|
||
|
|
||
|
#ifdef UNICODE
|
||
|
// ansi thunk for above
|
||
|
BOOL VFWAPI capGetDriverDescriptionA(UINT wDriverIndex,
|
||
|
LPSTR lpszName, int cbName,
|
||
|
LPSTR lpszVer, int cbVer)
|
||
|
{
|
||
|
return capInternalGetDriverDescA(wDriverIndex,
|
||
|
lpszName, cbName, lpszVer, cbVer);
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
|
||
|
//
|
||
|
// Disconnect from hardware resources
|
||
|
//
|
||
|
BOOL CapWinDisconnectHardware(LPCAPSTREAM lpcs)
|
||
|
{
|
||
|
if( lpcs->hVideoCapture ) {
|
||
|
videoStreamFini (lpcs->hVideoCapture);
|
||
|
videoClose( lpcs->hVideoCapture );
|
||
|
}
|
||
|
if( lpcs->hVideoDisplay ) {
|
||
|
videoStreamFini (lpcs->hVideoDisplay);
|
||
|
videoClose( lpcs->hVideoDisplay );
|
||
|
}
|
||
|
if( lpcs->hVideoIn ) {
|
||
|
videoClose( lpcs->hVideoIn );
|
||
|
}
|
||
|
|
||
|
lpcs->fHardwareConnected = FALSE;
|
||
|
|
||
|
lpcs->hVideoCapture = NULL;
|
||
|
lpcs->hVideoDisplay = NULL;
|
||
|
lpcs->hVideoIn = NULL;
|
||
|
|
||
|
lpcs->sCapDrvCaps.fHasDlgVideoSource = FALSE;
|
||
|
lpcs->sCapDrvCaps.fHasDlgVideoFormat = FALSE;
|
||
|
lpcs->sCapDrvCaps.fHasDlgVideoDisplay = FALSE;
|
||
|
lpcs->sCapDrvCaps.fHasDlgVideoDisplay = FALSE;
|
||
|
lpcs->sCapDrvCaps.fHasOverlay = FALSE;
|
||
|
lpcs->sCapDrvCaps.fDriverSuppliesPalettes = FALSE;
|
||
|
|
||
|
lpcs->sCapDrvCaps.hVideoIn = NULL;
|
||
|
lpcs->sCapDrvCaps.hVideoOut = NULL;
|
||
|
lpcs->sCapDrvCaps.hVideoExtIn = NULL;
|
||
|
lpcs->sCapDrvCaps.hVideoExtOut = NULL;
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Connect to hardware resources
|
||
|
// Return: TRUE if hardware connected to the stream
|
||
|
//
|
||
|
BOOL CapWinConnectHardware (LPCAPSTREAM lpcs, UINT wDeviceIndex)
|
||
|
{
|
||
|
DWORD dwError;
|
||
|
CHANNEL_CAPS VideoCapsExternalOut;
|
||
|
TCHAR ach1[MAX_PATH];
|
||
|
TCHAR ach2[MAX_PATH * 3];
|
||
|
CAPINFOCHUNK cic;
|
||
|
HINSTANCE hInstT;
|
||
|
|
||
|
lpcs->hVideoCapture = NULL;
|
||
|
lpcs->hVideoDisplay = NULL;
|
||
|
lpcs->hVideoIn = NULL;
|
||
|
lpcs->fHardwareConnected = FALSE;
|
||
|
lpcs->fUsingDefaultPalette = TRUE;
|
||
|
lpcs->sCapDrvCaps.fHasDlgVideoSource = FALSE;
|
||
|
lpcs->sCapDrvCaps.fHasDlgVideoFormat = FALSE;
|
||
|
lpcs->sCapDrvCaps.fHasDlgVideoDisplay = FALSE;
|
||
|
lpcs->sCapDrvCaps.wDeviceIndex = wDeviceIndex;
|
||
|
|
||
|
// Clear any existing capture device name chunk
|
||
|
cic.fccInfoID = mmioFOURCC ('I','S','F','T');
|
||
|
cic.lpData = NULL;
|
||
|
cic.cbData = 0;
|
||
|
SetInfoChunk (lpcs, &cic);
|
||
|
|
||
|
// try and open the video hardware!!!
|
||
|
if( !(dwError = videoOpen( &lpcs->hVideoIn, wDeviceIndex, VIDEO_IN ) ) ) {
|
||
|
if( !(dwError = videoOpen( &lpcs->hVideoCapture, wDeviceIndex, VIDEO_EXTERNALIN ) ) ) {
|
||
|
// We don't require the EXTERNALOUT channel,
|
||
|
// but do require EXTERNALIN and IN
|
||
|
videoOpen( &lpcs->hVideoDisplay, wDeviceIndex, VIDEO_EXTERNALOUT );
|
||
|
if( (!dwError) && lpcs->hVideoCapture && lpcs->hVideoIn ) {
|
||
|
|
||
|
lpcs->fHardwareConnected = TRUE;
|
||
|
capInternalGetDriverDesc (wDeviceIndex,
|
||
|
ach1, sizeof (ach1) / sizeof(TCHAR),
|
||
|
ach2, sizeof (ach2) / sizeof(TCHAR));
|
||
|
lstrcat (ach1, TEXT(", "));
|
||
|
lstrcat (ach1, ach2);
|
||
|
|
||
|
statusUpdateStatus (lpcs, IDS_CAP_INFO, (LPTSTR) ach1);
|
||
|
|
||
|
// Make a string of the current task and capture driver
|
||
|
ach2[0] = '\0';
|
||
|
if (hInstT = GetWindowInstance (GetParent(lpcs->hwnd)))
|
||
|
GetModuleFileName (hInstT, ach2, sizeof (ach2)/sizeof(TCHAR));
|
||
|
lstrcat (ach2, TEXT(" -AVICAP32- "));
|
||
|
lstrcat (ach2, ach1);
|
||
|
|
||
|
// Set software chunk with name of capture device
|
||
|
if (*ach2) {
|
||
|
|
||
|
#ifdef UNICODE
|
||
|
// INFO chunks must be ASCII data
|
||
|
CHAR achA[MAX_PATH*3];
|
||
|
cic.cbData = lstrlen(ach2) + 1; // set the number of characters
|
||
|
WideToAnsi(achA, ach2, cic.cbData);
|
||
|
cic.lpData = achA;
|
||
|
#else
|
||
|
cic.lpData = ach2;
|
||
|
cic.cbData = lstrlen(ach2) + 1;
|
||
|
#endif
|
||
|
SetInfoChunk (lpcs, &cic);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if (dwError)
|
||
|
errorDriverID (lpcs, dwError);
|
||
|
|
||
|
if(!lpcs->fHardwareConnected) {
|
||
|
CapWinDisconnectHardware(lpcs);
|
||
|
}
|
||
|
else {
|
||
|
if (lpcs->hVideoDisplay && videoGetChannelCaps (lpcs->hVideoDisplay,
|
||
|
&VideoCapsExternalOut,
|
||
|
sizeof (CHANNEL_CAPS)) == DV_ERR_OK) {
|
||
|
lpcs->sCapDrvCaps.fHasOverlay = (BOOL)(VideoCapsExternalOut.dwFlags &
|
||
|
(DWORD)VCAPS_OVERLAY);
|
||
|
}
|
||
|
else
|
||
|
lpcs->sCapDrvCaps.fHasOverlay = FALSE;
|
||
|
// if the hardware doesn't support it, make sure we don't enable
|
||
|
if (!lpcs->sCapDrvCaps.fHasOverlay)
|
||
|
lpcs->fOverlayWindow = FALSE;
|
||
|
|
||
|
// Start the external in channel streaming continuously
|
||
|
videoStreamInit (lpcs->hVideoCapture, 0L, 0L, 0L, 0L);
|
||
|
} // end if hardware is available
|
||
|
|
||
|
#if 0
|
||
|
// if we don't have a powerful machine, disable capture
|
||
|
if (GetWinFlags() & (DWORD) WF_CPU286)
|
||
|
CapWinDisconnectHardware(lpcs);
|
||
|
#endif
|
||
|
|
||
|
if (!lpcs->fHardwareConnected){
|
||
|
lpcs->fLiveWindow = FALSE;
|
||
|
lpcs->fOverlayWindow = FALSE;
|
||
|
}
|
||
|
|
||
|
if (lpcs->hVideoIn)
|
||
|
lpcs->sCapDrvCaps.fHasDlgVideoFormat = !videoDialog (lpcs->hVideoIn,
|
||
|
lpcs->hwnd, VIDEO_DLG_QUERY);
|
||
|
|
||
|
if (lpcs->hVideoCapture)
|
||
|
lpcs->sCapDrvCaps.fHasDlgVideoSource = !videoDialog (lpcs->hVideoCapture,
|
||
|
lpcs->hwnd, VIDEO_DLG_QUERY);
|
||
|
|
||
|
if (lpcs->hVideoDisplay)
|
||
|
lpcs->sCapDrvCaps.fHasDlgVideoDisplay = !videoDialog (lpcs->hVideoDisplay,
|
||
|
lpcs->hwnd, VIDEO_DLG_QUERY);
|
||
|
|
||
|
// these handles are not supported on WIN32 for the good reason that
|
||
|
// the videoXXX api set is not published for 32-bit
|
||
|
// we might want to make use of the handles ourselves...???
|
||
|
lpcs->sCapDrvCaps.hVideoIn = NULL;
|
||
|
lpcs->sCapDrvCaps.hVideoOut = NULL;
|
||
|
lpcs->sCapDrvCaps.hVideoExtIn = NULL;
|
||
|
lpcs->sCapDrvCaps.hVideoExtOut = NULL;
|
||
|
|
||
|
return lpcs->fHardwareConnected;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
//
|
||
|
// Creates a child window of the capture class
|
||
|
// Normally:
|
||
|
// Set lpszWindowName to NULL
|
||
|
// Set dwStyle to WS_CHILD | WS_VISIBLE
|
||
|
// Set hmenu to a unique child id
|
||
|
|
||
|
// Unicode and Win-16 version. See ansi thunk below
|
||
|
HWND VFWAPI capCreateCaptureWindow (
|
||
|
LPCTSTR lpszWindowName,
|
||
|
DWORD dwStyle,
|
||
|
int x, int y, int nWidth, int nHeight,
|
||
|
HWND hwndParent, int nID)
|
||
|
{
|
||
|
DWORD dwExStyle;
|
||
|
|
||
|
dwExStyle = gfIsRTL ? WS_EX_LEFTSCROLLBAR | WS_EX_RIGHT | WS_EX_RTLREADING : 0;
|
||
|
RegisterCaptureClass(ghInstDll);
|
||
|
|
||
|
#ifdef USE_AVIFILE
|
||
|
AVIFileInit();
|
||
|
#endif
|
||
|
|
||
|
return CreateWindowEx(dwExStyle,
|
||
|
szCaptureWindowClass,
|
||
|
lpszWindowName,
|
||
|
dwStyle,
|
||
|
x, y, nWidth, nHeight,
|
||
|
hwndParent, (HMENU) nID,
|
||
|
ghInstDll,
|
||
|
NULL);
|
||
|
}
|
||
|
|
||
|
#ifdef UNICODE
|
||
|
// ansi thunk
|
||
|
HWND VFWAPI capCreateCaptureWindowA (
|
||
|
LPCSTR lpszWindowName,
|
||
|
DWORD dwStyle,
|
||
|
int x, int y, int nWidth, int nHeight,
|
||
|
HWND hwndParent, int nID)
|
||
|
{
|
||
|
LPWSTR pw;
|
||
|
int chsize;
|
||
|
HWND hwnd;
|
||
|
|
||
|
if (lpszWindowName == NULL) {
|
||
|
pw = NULL;
|
||
|
} else {
|
||
|
// remember the null
|
||
|
chsize = lstrlenA(lpszWindowName) + 1;
|
||
|
pw = LocalLock(LocalAlloc(LPTR, chsize * sizeof(WCHAR)));
|
||
|
|
||
|
AnsiToWide(pw, lpszWindowName, chsize);
|
||
|
}
|
||
|
|
||
|
hwnd = capCreateCaptureWindowW(pw, dwStyle, x, y, nWidth, nHeight,
|
||
|
hwndParent, nID);
|
||
|
|
||
|
if (pw != NULL) {
|
||
|
LocalFree(LocalHandle(pw));
|
||
|
}
|
||
|
return(hwnd);
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
|
||
|
#ifdef CHICAGO
|
||
|
|
||
|
static char pszDll16[] = "AVICAP.DLL";
|
||
|
static char pszDll32[] = "AVICAP32.DLL";
|
||
|
|
||
|
BOOL PASCAL avicapf_ThunkConnect32(LPCSTR pszDll16, LPCSTR pszDll32, HINSTANCE hinst, DWORD dwReason);
|
||
|
|
||
|
BOOL WINAPI DllMain(
|
||
|
HANDLE hInstance,
|
||
|
DWORD dwReason,
|
||
|
LPVOID reserved)
|
||
|
{
|
||
|
#if defined DEBUG || defined DEBUG_RETAIL
|
||
|
DebugSetOutputLevel (GetProfileInt ("Debug", "Avicap32", 0));
|
||
|
AuxDebugEx (1, DEBUGLINE "DllEntryPoint, %08x,%08x,%08x\r\n", hInstance, dwReason, reserved);
|
||
|
#endif
|
||
|
|
||
|
if (dwReason == DLL_PROCESS_ATTACH)
|
||
|
{
|
||
|
char ach[2];
|
||
|
ghInstDll = hInstance;
|
||
|
|
||
|
LoadString(ghInstDll, IDS_CAP_RTL, ach, sizeof(ach));
|
||
|
gfIsRTL = ach[0] == TEXT('1');
|
||
|
|
||
|
// INLINE_BREAK;
|
||
|
if (!avicapf_ThunkConnect32(pszDll16, pszDll32, hInstance, dwReason))
|
||
|
return FALSE;
|
||
|
|
||
|
#if defined _WIN32 && defined CHICAGO
|
||
|
// we do this so that we can Get LinPageLock & PageAllocate services
|
||
|
//
|
||
|
;
|
||
|
// OpenMMDEVLDR();
|
||
|
#endif
|
||
|
|
||
|
}
|
||
|
else if (dwReason == DLL_PROCESS_DETACH)
|
||
|
{
|
||
|
|
||
|
#if defined _WIN32 && defined CHICAGO
|
||
|
;
|
||
|
// CloseMMDEVLDR();
|
||
|
#endif
|
||
|
|
||
|
return avicapf_ThunkConnect32(pszDll16, pszDll32, hInstance, dwReason);
|
||
|
}
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
#else // this is the NT dll entry point
|
||
|
|
||
|
BOOL DllInstanceInit(HANDLE hInstance, DWORD dwReason, LPVOID reserved)
|
||
|
{
|
||
|
if (dwReason == DLL_PROCESS_ATTACH) {
|
||
|
TCHAR ach[2];
|
||
|
|
||
|
ghInstDll = hInstance;
|
||
|
DisableThreadLibraryCalls(hInstance);
|
||
|
LoadString(ghInstDll, IDS_CAP_RTL, ach, NUMELMS(ach));
|
||
|
gfIsRTL = ach[0] == TEXT('1');
|
||
|
DebugSetOutputLevel (GetProfileIntA("Debug", "Avicap32", 0));
|
||
|
videoInitHandleList();
|
||
|
} else if (dwReason == DLL_PROCESS_DETACH) {
|
||
|
videoDeleteHandleList();
|
||
|
}
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
#endif // CHICAGO / NT dll entry point
|
||
|
|
||
|
|