📄 vidcap.c
字号:
/**************************************************************************
*
* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
* KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
* PURPOSE.
*
* Copyright (C) 1992 - 1996 Microsoft Corporation. All Rights Reserved.
*
**************************************************************************/
/****************************************************************************
*
* vidcap.c: WinMain and command processing
*
* Vidcap32 Source code
*
***************************************************************************/
#include <windows.h>
#include <windowsx.h>
#include <commdlg.h>
#include <mmsystem.h>
#include <mmreg.h>
#include <io.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <dos.h>
#include <shellapi.h>
#include <vfw.h>
#include "vidcap.h"
#include "vidframe.h"
#include "profile.h"
// generic window control classes
#include "toolbar.h"
#include "status.h"
#include "arrow.h"
#include "rlmeter.h"
#include "help.h"
// the standard toolbar class 'exports' this but doesn't put it in the
// header file
extern char szToolBarClass[];//HACK!
// height of the buttons on a toolbar - depends on the
// size of the bitmaps within IDBMP_TOOLBAR
#define BUTTONWIDTH 24
#define BUTTONHEIGHT 22
#define TOOLBAR_HEIGHT BUTTONHEIGHT + 6
// description and layout of toolbar buttons within IDBMP_TOOLBAR
#define APP_NUMTOOLS 8
#define BTN_SETFILE 0
#define BTN_EDITCAP 1
#define BTN_LIVE 2
#define BTN_CAPFRAME 3
#define BTN_CAPSEL 4
#define BTN_CAPAVI 5
#define BTN_CAPPAL 6
#define BTN_OVERLAY 7
static int aiButton[] = {BTN_SETFILE, BTN_EDITCAP,
BTN_LIVE, BTN_OVERLAY, BTN_CAPFRAME,
BTN_CAPSEL, BTN_CAPAVI, BTN_CAPPAL };
static int aiState[] = {BTNST_FOCUSUP, BTNST_UP,
BTNST_UP, BTNST_UP, BTNST_UP,
BTNST_UP, BTNST_UP, BTNST_UP};
static int aiType[] ={BTNTYPE_PUSH, BTNTYPE_PUSH,
BTNTYPE_CHECKBOX, BTNTYPE_CHECKBOX,
BTNTYPE_PUSH,
BTNTYPE_PUSH, BTNTYPE_PUSH, BTNTYPE_PUSH};
static int aiString[] = { IDC_toolbarSETFILE,
IDC_toolbarEDITCAP, IDC_toolbarLIVE,
IDC_toolbarOVERLAY,
IDC_toolbarCAPFRAME, IDC_toolbarCAPSEL,
IDC_toolbarCAPAVI, IDC_toolbarCAPPAL };
static int aPos[] = { 10, 35, 75, 100, 150, 175, 200, 225 };
//
// Global Variables
//
// preferences
BOOL gbCentre;
BOOL gbToolBar;
BOOL gbStatusBar;
BOOL gbAutoSizeFrame;
int gBackColour;
BOOL gbLive, gbOverlay;
BOOL gfIsRTL;
// saved window sizes
int gWinX, gWinY;
int gWinCX, gWinCY;
int gWinShow;
// command line options
int gCmdLineDeviceID = -1;
char gachAppName[] = "vidcapApp" ;
char gachIconName[] = "vidcapIcon" ;
char gachMenuName[] = "vidcapMenu" ;
char gachAppTitle[20]; //VidCap
char gachCaptureFile[_MAX_PATH];
char gachMCIDeviceName[21];
char gachString[128] ;
char gachBuffer[200] ;
char gachLastError[256];
HINSTANCE ghInstApp ;
HWND ghWndMain = NULL ;
HWND ghWndFrame; // child of ghWndMain - frames and scrolls
HWND ghWndCap ; // child of ghWndCap
HWND ghWndToolBar;
HWND ghWndStatus;
HANDLE ghAccel ;
WORD gwDeviceIndex ;
WORD gwPalFrames = DEF_PALNUMFRAMES ;
WORD gwPalColors = DEF_PALNUMCOLORS ;
WORD gwCapFileSize ;
CAPSTATUS gCapStatus ;
CAPDRIVERCAPS gCapDriverCaps ;
CAPTUREPARMS gCapParms ;
BOOL gbHaveHardware;
UINT gDriverCount;
BOOL gbIsScrncap; // For Scrncap.drv, we must yield
BOOL gbInLayout;
UINT gAVStreamMaster;
HANDLE ghwfex ;
LPWAVEFORMATEX glpwfex ;
FARPROC fpErrorCallback ;
FARPROC fpStatusCallback ;
FARPROC fpYieldCallback ;
// set to false when we capture a palette (or if we have warned him and
// he says its ok
BOOL bDefaultPalette = TRUE;
#ifdef DEBUG
int nTestCount;
#endif
// c-runtime cmd line
extern char ** __argv;
extern int __argc;
#define LimitRange(Val,Low,Hi) (max(Low,(min(Val,Hi))))
//
// Function prototypes
//
LONG FAR PASCAL MainWndProc(HWND, UINT, UINT, LONG) ;
LRESULT FAR PASCAL ErrorCallbackProc(HWND, int, LPSTR) ;
LRESULT FAR PASCAL StatusCallbackProc(HWND, int, LPSTR) ;
LRESULT FAR PASCAL YieldCallbackProc(HWND) ;
void vidcapSetLive(BOOL bLive);
void vidcapSetOverlay(BOOL bOverlay);
void vidcapSetCaptureFile(LPSTR pFileName);
BOOL vidcapRegisterClasses(HINSTANCE hInstance, HINSTANCE hPrevInstance);
BOOL vidcapCreateWindows(HINSTANCE hInstance, HINSTANCE hPrevInstance);
void vidcapLayout(HWND hwnd);
BOOL vidcapEnumerateDrivers(HWND hwnd);
BOOL vidcapInitHardware(HWND hwnd, HWND hwndCap, UINT uIndex);
void vidcapReadProfile(void);
void vidcapWriteProfile(void);
void vidcapReadSettingsProfile(void);
void vidcapWriteSettingsProfile(void);
/* --- initialisation -------------------------------------------------- */
//
// WinMain: Application Entry Point Function
//
int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow)
{
///////////////////////////////////////////////////////////////////////
// hInstance: handle for this instance
// hPrevInstance: handle for possible previous instances
// lpszCmdLine: long pointer to exec command line
// nCmdShow: Show code for main window display
///////////////////////////////////////////////////////////////////////
MSG msg ;
BOOL bValidCmdline;
BOOL fOK;
int i;
char ach[2];
ghInstApp = hInstance ;
LoadString(hInstance, IDS_CAP_RTL, ach, sizeof(ach));
gfIsRTL = ach[0] == '1';
gCmdLineDeviceID = -1;
// read the app title string - used in several message boxes
LoadString(hInstance, IDS_APP_TITLE, gachAppTitle, sizeof(gachAppTitle));
// read defaults out of the registry
vidcapReadProfile();
// look for cmd line options
bValidCmdline = TRUE;
for ( i = 1; (i < __argc) && bValidCmdline; i++) {
if ((__argv[i][0] == '/') || (__argv[i][0] == '-')) {
switch(__argv[i][1]) {
case 'D':
case 'd':
if (gCmdLineDeviceID < 0) {
// allow "-d0" and "-d 0"
PSTR p = &__argv[i][2];
if ((*p == 0) && ((i+1) < __argc)) {
p = __argv[++i];
}
gCmdLineDeviceID = atoi(p);
} else {
bValidCmdline = FALSE;
}
break;
default:
bValidCmdline = FALSE;
}
} else {
bValidCmdline = FALSE;
}
}
if (gCmdLineDeviceID == -1)
gCmdLineDeviceID = 0;
if (!bValidCmdline) {
MessageBoxID(IDS_ERR_CMDLINE, MB_OK|MB_ICONEXCLAMATION);
return(0);
}
if (!vidcapRegisterClasses(hInstance, hPrevInstance)) {
MessageBoxID(IDS_ERR_REGISTER_CLASS,
MB_ICONEXCLAMATION) ;
return 0 ;
}
if (!vidcapCreateWindows(hInstance, hPrevInstance)) {
MessageBoxID(IDS_ERR_CREATE_WINDOW,
MB_ICONEXCLAMATION | MB_OK) ;
return IDS_ERR_CREATE_WINDOW ;
}
// Get the default setup for video capture from the AVICap window
capCaptureGetSetup(ghWndCap, &gCapParms, sizeof(CAPTUREPARMS)) ;
// Overwrite the defaults with settings we have saved in the profile
vidcapReadSettingsProfile();
// Show the main window before connecting the hardware as this can be
// time consuming and the user should see something happening first...
ShowWindow(ghWndMain, nCmdShow) ;
UpdateWindow(ghWndMain) ;
ghAccel = LoadAccelerators(hInstance, "VIDCAP") ;
// Create a list of all capture drivers and append them to the Options menu
if (!(fOK = vidcapEnumerateDrivers(ghWndMain))) {
LoadString(ghInstApp, IDS_ERR_FIND_HARDWARE, gachLastError, sizeof(gachLastError));
}
// Try to connect to a capture driver
else if (fOK = vidcapInitHardware(ghWndMain, ghWndCap,
bValidCmdline ? gCmdLineDeviceID : 0)) {
// Hooray, we now have a capture driver connected!
vidcapSetCaptureFile(gachCaptureFile);
}
if (!fOK) {
if (!DoDialog(ghWndMain, IDD_NoCapHardware, NoHardwareDlgProc,
(LONG) (LPSTR) gachLastError)) {
// The user has asked to abort, since no driver was available
PostMessage(ghWndMain, WM_COMMAND,
GET_WM_COMMAND_MPS(IDM_F_EXIT, 0, 0));
}
}
// All set; get and process messages
while (GetMessage(&msg, NULL, 0, 0)) {
if (! TranslateAccelerator(ghWndMain, ghAccel, &msg)) {
TranslateMessage(&msg) ;
DispatchMessage(&msg) ;
}
}
return msg.wParam;
} // End of WinMain
BOOL
vidcapRegisterClasses(HINSTANCE hInstance, HINSTANCE hPrevInstance)
{
WNDCLASS wc;
if (! hPrevInstance) {
// If it's the first instance, register the window class
wc.lpszClassName = gachAppName ;
wc.hInstance = hInstance ;
wc.lpfnWndProc = MainWndProc ;
wc.hCursor = LoadCursor(NULL, IDC_ARROW) ;
wc.hIcon = LoadIcon(hInstance, gachIconName) ;
wc.lpszMenuName = gachMenuName ;
wc.hbrBackground = GetStockObject(WHITE_BRUSH) ;
wc.style = CS_HREDRAW | CS_VREDRAW ;
wc.cbClsExtra = 0 ;
wc.cbWndExtra = 0 ;
if (!RegisterClass(&wc)) {
return(FALSE);
}
if (!ArrowInit(hInstance)) {
return(FALSE);
}
if (!RLMeter_Register(hInstance)) {
return(FALSE);
}
}
if (!toolbarInit(hInstance, hPrevInstance)) {
return(FALSE);
}
if (!statusInit(hInstance, hPrevInstance)) {
return(FALSE);
}
return(TRUE);
}
BOOL
vidcapCreateWindows(HINSTANCE hInstance, HINSTANCE hPrevInstance)
{
POINT pt;
RECT rc;
TOOLBUTTON tb;
int i;
// Create Application's Main window
ghWndMain = CreateWindowEx(
gfIsRTL ? WS_EX_LEFTSCROLLBAR | WS_EX_RIGHT | WS_EX_RTLREADING : 0,
gachAppName,
gachAppTitle,
WS_CAPTION |
WS_SYSMENU |
WS_MINIMIZEBOX |
WS_MAXIMIZEBOX |
WS_THICKFRAME |
WS_CLIPCHILDREN |
WS_OVERLAPPED,
gWinX, gWinY,
gWinCX, gWinCY,
NULL,
NULL,
hInstance,
0) ;
if (ghWndMain == NULL) {
return(FALSE);
}
/*
* create a vidframe child window - this will create a child
* AVICAP window within itself.
*
* Don't worry about size and position - vidcapLayout will do this
* later (once we know the video format size).
*/
ghWndFrame = vidframeCreate(
ghWndMain,
hInstance,
hPrevInstance,
0, 0, 0, 0,
&ghWndCap);
if ((ghWndFrame == NULL) || (ghWndCap == NULL)) {
return(FALSE);
}
// Register the status and error callbacks before driver connects
// so we can get feedback about the connection process
fpErrorCallback = MakeProcInstance((FARPROC)ErrorCallbackProc, ghInstApp) ;
capSetCallbackOnError(ghWndCap, fpErrorCallback) ;
fpStatusCallback = MakeProcInstance((FARPROC)StatusCallbackProc, ghInstApp) ;
capSetCallbackOnStatus(ghWndCap, fpStatusCallback) ;
// We'll only install a yield callback later if using Scrncap.drv
fpYieldCallback = MakeProcInstance((FARPROC)YieldCallbackProc, ghInstApp) ;
/*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -