📄 vidcap.c
字号:
* CREATE THE TOOL BAR WINDOW
*/
/* NOTE: let vidcapLayout() position it */
ghWndToolBar = CreateWindowEx(
gfIsRTL ? WS_EX_LEFTSCROLLBAR | WS_EX_RIGHT | WS_EX_RTLREADING : 0,
szToolBarClass,
NULL,
WS_CHILD|WS_BORDER|WS_VISIBLE|WS_TABSTOP|
WS_CLIPSIBLINGS,
0, 0,
0, 0,
ghWndMain,
NULL,
hInstance,
NULL);
if (ghWndToolBar == NULL) {
return(FALSE);
}
/* set the bitmap and button size to be used for this toolbar */
pt.x = BUTTONWIDTH;
pt.y = BUTTONHEIGHT;
toolbarSetBitmap(ghWndToolBar, hInstance, IDBMP_TOOLBAR, pt);
for (i = 0; i < APP_NUMTOOLS; i++) {
rc.left = aPos[i];
rc.top = 2;
rc.right = rc.left + pt.x;
rc.bottom = rc.top + pt.y;
tb.rc = rc;
tb.iButton = aiButton[i];
tb.iState = aiState[i];
tb.iType = aiType[i];
tb.iString = aiString[i];
toolbarAddTool(ghWndToolBar, tb);
}
// create the status bar - let vidcapLayout do the positioning
ghWndStatus = CreateWindowEx(
gfIsRTL ? WS_EX_LEFTSCROLLBAR | WS_EX_RIGHT | WS_EX_RTLREADING : 0,
szStatusClass,
NULL,
WS_CHILD|WS_BORDER|WS_VISIBLE|WS_CLIPSIBLINGS,
0, 0,
0, 0,
ghWndMain,
NULL,
hInstance,
NULL);
if (ghWndStatus == NULL) {
return(FALSE);
}
return(TRUE);
}
/*
* Enumerate the potential capture drivers and add the list to the Options
* menu. This function is only called once at startup.
* Returns FALSE if no drivers are available.
*/
BOOL
vidcapEnumerateDrivers(HWND hwnd)
{
char achDeviceVersion[80] ;
char achDeviceAndVersion[160] ;
UINT uIndex ;
HMENU hMenuSub;
gDriverCount = 0 ;
hMenuSub = GetSubMenu (GetMenu (hwnd), 2); // Options menu
for (uIndex = 0 ; uIndex < MAXVIDDRIVERS ; uIndex++) {
if (capGetDriverDescription(uIndex,
(LPSTR)achDeviceAndVersion, sizeof(achDeviceAndVersion),
(LPSTR)achDeviceVersion, sizeof(achDeviceVersion))) {
// Concatenate the device name and version strings
lstrcat (achDeviceAndVersion, ", ");
lstrcat (achDeviceAndVersion, achDeviceVersion);
AppendMenu (hMenuSub,
MF_STRING,
IDM_O_DRIVER0 + uIndex,
achDeviceAndVersion);
gDriverCount++;
}
else
break;
}
// Now refresh menu, position capture window, start driver etc
DrawMenuBar(ghWndMain) ;
return (gDriverCount);
}
/*
* Connect the capture window to a capture driver.
* uIndex specifies the index of the driver to use.
* Returns TRUE on success, or FALSE if the driver connection failed.
*/
BOOL
vidcapInitHardware(HWND hwnd, HWND hwndCap, UINT uIndex)
{
UINT uError ;
UINT uI;
HMENU hMenu;
char szName[MAX_PATH];
char szVersion[MAX_PATH];
// Since the driver may not provide a reliable error string
// provide a default
LoadString(ghInstApp, IDS_ERR_FIND_HARDWARE, gachLastError, sizeof(gachLastError));
// Try connecting to the capture driver
if (uError = capDriverConnect(hwndCap, uIndex)) {
gbHaveHardware = TRUE;
gwDeviceIndex = uIndex;
}
else {
gbHaveHardware = FALSE;
gbLive = FALSE;
gbOverlay = FALSE;
}
// Get the capabilities of the capture driver
capDriverGetCaps(hwndCap, &gCapDriverCaps, sizeof(CAPDRIVERCAPS)) ;
// Get the settings for the capture window
capGetStatus(hwndCap, &gCapStatus , sizeof(gCapStatus));
// Modify the toolbar buttons
toolbarModifyState(ghWndToolBar, BTN_CAPFRAME,
gbHaveHardware ? BTNST_UP : BTNST_GRAYED);
toolbarModifyState(ghWndToolBar, BTN_CAPSEL,
gbHaveHardware ? BTNST_UP : BTNST_GRAYED);
toolbarModifyState(ghWndToolBar, BTN_CAPAVI,
gbHaveHardware ? BTNST_UP : BTNST_GRAYED);
toolbarModifyState(ghWndToolBar, BTN_LIVE,
gbHaveHardware ? BTNST_UP : BTNST_GRAYED);
// Is overlay supported?
toolbarModifyState(ghWndToolBar, BTN_OVERLAY,
(gbHaveHardware && gCapDriverCaps.fHasOverlay) ?
BTNST_UP : BTNST_GRAYED);
// Can the device create palettes?
toolbarModifyState(ghWndToolBar, BTN_CAPPAL,
(gbHaveHardware && gCapDriverCaps.fDriverSuppliesPalettes) ?
BTNST_UP : BTNST_GRAYED);
// Check the appropriate driver in the Options menu
hMenu = GetMenu (hwnd);
for (uI = 0; uI < gDriverCount; uI++) {
CheckMenuItem (hMenu, IDM_O_DRIVER0 + uI,
MF_BYCOMMAND | ((uIndex == uI) ? MF_CHECKED : MF_UNCHECKED));
}
// Unlike all other capture drivers, Scrncap.drv needs to use
// a Yield callback, and we don't want to abort on mouse clicks,
// so determine if the current driver is Scrncap.drv
capGetDriverDescription (uIndex,
szName, sizeof (szName),
szVersion, sizeof (szVersion));
// Set a flag if we're using Scrncap.drv
gbIsScrncap = (BOOL) _fstrstr (szName, "Screen Capture");
// Get video format and adjust capture window
vidcapLayout(ghWndMain);
InvalidateRect(ghWndMain, NULL, TRUE);
// set the preview rate (units are millisecs)
capPreviewRate(hwndCap, gbHaveHardware ? 33 : 0);
// set live/overlay to default
vidcapSetLive(gbLive);
vidcapSetOverlay(gbOverlay);
strcat (szName, ", ");
strcat (szName, szVersion);
statusUpdateStatus(ghWndStatus,
gbHaveHardware ? szName : gachLastError);
return gbHaveHardware;
}
/*
* layout the main window. Put the toolbar at the top and the status
* line at the bottom, and then give all the rest to vidframe,
* - it will centre or scroll the AVICAP window appropriately.
*/
void
vidcapLayout(HWND hwnd)
{
RECT rc;
RECT rw;
int cy;
int cyBorder, cxBorder;
int cyTotal;
int cxToolbar;
int cyMenuAndToolbarAndCaption;
gbInLayout = TRUE; // So that we process WM_GETMINMAXINFO normally
/* for both the toolbar and status bar window,
* we want just one of the four borders. We do this
* by setting the WS_BORDER style, and sizing and positioning
* the window so that the 3 unwanted borders are outside the parent.
*/
cyBorder = GetSystemMetrics(SM_CYBORDER);
cxBorder = GetSystemMetrics(SM_CXBORDER);
// Figure out the height of the menu, toolbar, and caption
GetWindowRect (hwnd, &rw);
GetClientRect (hwnd, &rc);
ClientToScreen (hwnd, (LPPOINT) &rc);
cyMenuAndToolbarAndCaption = (rc.top - rw.top) + TOOLBAR_HEIGHT;
cxToolbar = aPos[APP_NUMTOOLS - 1] + BUTTONWIDTH * 3;
if (gbAutoSizeFrame && gbHaveHardware && gCapStatus.uiImageWidth) {
cyTotal = gCapStatus.uiImageHeight +
cyMenuAndToolbarAndCaption +
(gbStatusBar ? statusGetHeight() : 0) +
cyBorder * 2 +
12; // vidFrame height
// Never make the frame smaller than the toolbar
if (gCapStatus.uiImageWidth >= (UINT) cxToolbar) {
SetWindowPos(
hwnd,
0, // placement-order handle
0, // horizontal position
0, // vertical position
gCapStatus.uiImageWidth + cxBorder * 24, // width
cyTotal, // height
SWP_NOZORDER | SWP_NOMOVE // window-positioning flags
);
} else {
SetWindowPos(
hwnd,
0, // placement-order handle
0, // horizontal position
0, // vertical position
cxToolbar, // width
cyTotal, // height
SWP_NOZORDER | SWP_NOMOVE // window-positioning flags
);
}
}
GetClientRect(hwnd, &rc);
if (gbToolBar) {
// put the toolbar at the top - in fact, just off the top so as to
// hide it's border
MoveWindow(
ghWndToolBar,
-cxBorder, -cyBorder,
RECTWIDTH(rc)+ (cxBorder * 2),
TOOLBAR_HEIGHT,
TRUE);
rc.top += (TOOLBAR_HEIGHT - cyBorder);
} else {
MoveWindow(ghWndToolBar, 0, 0, 0, 0, TRUE);
}
// status bar at the bottom
if (gbStatusBar) {
cy = statusGetHeight() + cyBorder;
MoveWindow(
ghWndStatus,
-cxBorder, rc.bottom - cy,
RECTWIDTH(rc) + (2 * cxBorder), cy + cyBorder,
TRUE);
rc.bottom -= cy;
} else {
MoveWindow(ghWndStatus, 0, 0, 0, 0, TRUE);
}
// rest of window goes to vidframe window
MoveWindow(
ghWndFrame,
rc.left, rc.top,
RECTWIDTH(rc), RECTHEIGHT(rc),
TRUE);
// Always layout the frame window, since it is aligned on a
// DWORD boundary for maximum codec drawing efficiency
vidframeLayout(ghWndFrame, ghWndCap);
gbInLayout = FALSE;
}
/*
* initialise settings from the profile used before window creation time
*/
void
vidcapReadProfile(void)
{
// read defaults out of the registry
gbCentre = mmGetProfileFlag(gachAppTitle, "CenterImage", TRUE);
gbToolBar = mmGetProfileFlag(gachAppTitle, "ToolBar", TRUE);
gbStatusBar = mmGetProfileFlag(gachAppTitle, "StatusBar", TRUE);
gbAutoSizeFrame = mmGetProfileFlag(gachAppTitle, "AutoSizeFrame", TRUE);
gBackColour = mmGetProfileInt(gachAppTitle, "BackgroundColor", IDD_PrefsLtGrey);
gWinX = mmGetProfileInt(gachAppTitle, "WindowXPos", (UINT) CW_USEDEFAULT);
if (gWinX != (UINT) CW_USEDEFAULT)
gWinX = LimitRange(gWinX, 0, GetSystemMetrics (SM_CXSCREEN) - 40);
gWinY = mmGetProfileInt(gachAppTitle, "WindowYPos", 0);
gWinY = LimitRange(gWinY, 0, GetSystemMetrics (SM_CYSCREEN) - 40);
gWinCX = mmGetProfileInt(gachAppTitle, "WindowWidth", 320);
gWinCX = LimitRange(gWinCX, 20, GetSystemMetrics (SM_CXSCREEN));
gWinCY = mmGetProfileInt(gachAppTitle, "WindowHeight", 240);
gWinCY = LimitRange(gWinCY, 20, GetSystemMetrics (SM_CYSCREEN));
gWinShow = mmGetProfileInt(gachAppTitle, "WindowShow", SW_SHOWDEFAULT);
gWinShow = LimitRange(gWinShow, SW_SHOWNORMAL, SW_SHOWDEFAULT);
gbOverlay = mmGetProfileInt(gachAppTitle, "OverlayWindow", FALSE);
gbLive = mmGetProfileInt(gachAppTitle, "LiveWindow", TRUE);
}
void
vidcapWriteProfile(void)
{
mmWriteProfileFlag(gachAppTitle, "CenterImage", gbCentre, TRUE);
mmWriteProfileFlag(gachAppTitle, "ToolBar", gbToolBar, TRUE);
mmWriteProfileFlag(gachAppTitle, "StatusBar", gbStatusBar, TRUE);
mmWriteProfileFlag(gachAppTitle, "AutoSizeFrame", gbAutoSizeFrame, TRUE);
mmWriteProfileInt(gachAppTitle, "BackgroundColor", gBackColour, IDD_PrefsLtGrey);
mmWriteProfileInt(gachAppTitle, "WindowXPos", gWinX, (UINT) CW_USEDEFAULT);
mmWriteProfileInt(gachAppTitle, "WindowYPos", gWinY, 0);
mmWriteProfileInt(gachAppTitle, "WindowWidth", gWinCX, 320);
mmWriteProfileInt(gachAppTitle, "WindowHeight", gWinCY, 240);
mmWriteProfileInt(gachAppTitle, "WindowShow", gWinShow, SW_SHOWDEFAULT);
mmWriteProfileInt(gachAppTitle, "OverlayWindow", gbOverlay, FALSE);
mmWriteProfileInt(gachAppTitle, "LiveWindow", gbLive, TRUE);
}
/*
* initialise settings from the profile used AFTER window creation time
*/
void
vidcapReadSettingsProfile(void)
{
DWORD dwSize;
mmGetProfileString(gachAppTitle, "CaptureFile", "",
gachCaptureFile, sizeof(gachCaptureFile));
mmGetProfileString(gachAppTitle, "MCIDevice", "VideoDisc",
gachMCIDeviceName, sizeof(gachMCIDeviceName));
gCapParms.dwRequestMicroSecPerFrame =
mmGetProfileInt(gachAppTitle, "MicroSecPerFrame",
DEF_CAPTURE_RATE);
gCapParms.dwRequestMicroSecPerFrame =
mmGetProfileInt(gachAppTitle, "MicroSecPerFrame",
DEF_CAPTURE_RATE);
gCapParms.fCaptureAudio = mmGetProfileFlag(gachAppTitle, "CaptureAudio",
gCapStatus.fAudioHardware);
gCapParms.fLimitEnabled = mmGetProfileFlag(gachAppTitle, "LimitEnabled",
FALSE);
gCapParms.wTimeLimit =
mmGetProfileInt(gachAppTitle, "TimeLimit", 30);
gCapParms.fMCIControl= mmGetProfileFlag(gachAppTitle, "MCIControl", FALSE);
gCapParms.fStepMCIDevice= mmGetProfileFlag(gachAppTitle, "StepMCIDevice", FALSE);
gCapParms.dwMCIStartTime =
mmGetProfileInt(gachAppTitle, "MCIStartTime", 10000);
gCapParms.dwMCIStopTime =
mmGetProfileInt(gachAppTitle, "MCIStopTime", 20000);
gCapParms.fStepCaptureAt2x = mmGetProfileFlag(gachAppTitle, "StepCapture2x",
FALSE);
gCapParms.wStepCaptureAverageFrames =
mmGetProfileInt(gachAppTitle, "StepCaptureAverageFrames", 3);
gCapParms.AVStreamMaster = mmGetProfileInt (gachAppTitle, "AVStreamMaster",
AVSTREAMMASTER_AUDIO);
gCapParms.fUsingDOSMemory = mmGetProfileFlag (gachAppTitle, "CaptureToDisk",
TRUE);
gCapParms.dwIndexSize =
mmGetProfileInt(gachAppTitle, "IndexSize",
CAP_SMALL_INDEX);
// Retrieve the saved audio format
// Ask the ACM what the largest known wave format is
acmMetrics(NULL,
ACM_METRIC_MAX_SIZE_FORMAT,
&dwSize);
// If a wave format was saved in the registry, use that size
dwSize = max (dwSize, mmGetProfileBinary(gachAppTitle, "WaveFormatBinary",
NULL,
NULL,
0));
if (glpwfex = (LPWAVEFORMATEX) GlobalAllocPtr(GHND, dwSize)) {
capGetAudioFormat(ghWndCap, glpwfex, (WORD)dwSize) ;
mmGetProfileBinary(gachAppTitle, "WaveFormatBinary",
glpwfex,
glpwfex,
dwSize);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -