?? dialogs.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.
*
**************************************************************************/
/****************************************************************************
*
* dialogs.c: Dialog box 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 <vfw.h>
#include "arrow.h"
#include "rlmeter.h"
#include "vidcap.h"
#include "vidframe.h"
#include "help.h"
static long GetFreeDiskSpaceInKB(LPTSTR) ;
static int CountMCIDevices(WORD) ;
BOOL FAR PASCAL MCISetupProc(HWND, unsigned, UINT, LONG);
//--- utility functions ---------------------------------------------------
/*----------------------------------------------------------------------------*\
| SmartWindowPosition (HWND hWndDlg, HWND hWndShow)
| |
| Description: |
| This function attempts to position a dialog box so that it
| does not obscure the hWndShow window. This function is
| typically called during WM_INITDIALOG processing.
| |
| Arguments: |
| hWndDlg handle of the soon to be displayed dialog
| hWndShow handle of the window to keep visible
| |
| Returns: |
| 1 if the windows overlap and positions were adjusted
| 0 if the windows don't overlap
| |
\*----------------------------------------------------------------------------*/
int SmartWindowPosition (HWND hWndDlg, HWND hWndShow)
{
RECT rc, rcDlg, rcShow;
int iHeight, iWidth;
int iScreenHeight, iScreenWidth;
GetWindowRect(hWndDlg, &rcDlg);
GetWindowRect(hWndShow, &rcShow);
iScreenHeight = GetSystemMetrics(SM_CYSCREEN);
iScreenWidth = GetSystemMetrics(SM_CXSCREEN);
InflateRect (&rcShow, 5, 5); // allow a small border
if (IntersectRect(&rc, &rcDlg, &rcShow)){
/* the two do intersect, now figure out where to place */
/* this dialog window. Try to go below the Show window*/
/* first and then to the right, top and left. */
/* get the size of this dialog */
iHeight = rcDlg.bottom - rcDlg.top;
iWidth = rcDlg.right - rcDlg.left;
if ((WORD)(rcShow.bottom + iHeight + 1) < iScreenHeight){
/* will fit on bottom, go for it */
rc.top = rcShow.bottom + 1;
rc.left = (((rcShow.right - rcShow.left)/2) + rcShow.left)
- (iWidth/2);
} else if ((WORD)(rcShow.right + iWidth + 1) < iScreenWidth){
/* will fit to right, go for it */
rc.left = rcShow.right + 1;
rc.top = (((rcShow.bottom - rcShow.top)/2) + rcShow.top)
- (iHeight/2);
} else if ((WORD)(rcShow.top - iHeight - 1) > 0){
/* will fit on top, handle that */
rc.top = rcShow.top - iHeight - 1;
rc.left = (((rcShow.right - rcShow.left)/2) + rcShow.left)
- (iWidth/2);
} else if ((WORD)(rcShow.left - iWidth - 1) > 0){
/* will fit to left, do it */
rc.left = rcShow.left - iWidth - 1;
rc.top = (((rcShow.bottom - rcShow.top)/2) + rcShow.top)
- (iHeight/2);
} else {
/* we are hosed, they cannot be placed so that there is */
/* no overlap anywhere. To minimize the damage just put*/
/* the dialog in the lower left corner of the screen */
rc.top = (int)iScreenHeight - iHeight;
rc.left = (int)iScreenWidth - iWidth;
}
/* make any adjustments necessary to keep it on the screen */
if (rc.left < 0) rc.left = 0;
else if ((WORD)(rc.left + iWidth) > iScreenWidth)
rc.left = (int)(iScreenWidth - iWidth);
if (rc.top < 0) rc.top = 0;
else if ((WORD)(rc.top + iHeight) > iScreenHeight)
rc.top = (int)iScreenHeight - iHeight;
SetWindowPos(hWndDlg, NULL, rc.left, rc.top, 0, 0,
SWP_NOSIZE|SWP_NOZORDER|SWP_NOACTIVATE);
return 1;
} // if the windows overlap by default
return 0;
}
//
// GetFreeDiskSpace: Function to Measure Available Disk Space
//
static long GetFreeDiskSpaceInKB(LPTSTR pFile)
{
DWORD dwFreeClusters, dwBytesPerSector, dwSectorsPerCluster, dwClusters;
char RootName[MAX_PATH];
LPSTR ptmp; //required arg
// need to find path for root directory on drive containing
// this file.
GetFullPathName(pFile, sizeof(RootName)/sizeof(RootName[0]), RootName, &ptmp);
// truncate this to the name of the root directory (god how tedious)
if ((RootName[0] == TEXT('\\')) && (RootName[1] == TEXT('\\'))) {
// path begins with \\server\share\path so skip the first
// three backslashes
ptmp = &RootName[2];
while (*ptmp && (*ptmp != TEXT('\\'))) {
ptmp++;
}
if (*ptmp) {
// advance past the third backslash
ptmp++;
}
} else {
// path must be drv:\path
ptmp = RootName;
}
// find next backslash and put a null after it
while (*ptmp && (*ptmp != TEXT('\\'))) {
ptmp++;
}
// found a backslash ?
if (*ptmp) {
// skip it and insert null
ptmp++;
*ptmp = TEXT('\0');
}
if (!GetDiskFreeSpace(RootName,
&dwSectorsPerCluster,
&dwBytesPerSector,
&dwFreeClusters,
&dwClusters)) {
MessageBoxID(IDS_ERR_MEASUREFREEDISK, MB_OK | MB_ICONINFORMATION);
return (-1);
}
return(MulDiv (dwSectorsPerCluster * dwBytesPerSector,
dwFreeClusters,
1024));
}
//
// CountMCIDevices: Function to Find the Number of MCI Devices of a Type
//
static int CountMCIDevices(WORD wType)
{
int nTotal = 0 ;
DWORD dwCount ;
MCI_SYSINFO_PARMS mciSIP ;
mciSIP.dwCallback = 0 ;
mciSIP.lpstrReturn = (LPSTR)(LPVOID) &dwCount ;
mciSIP.dwRetSize = sizeof(DWORD) ;
mciSIP.wDeviceType = wType ;
// Use an MCI command to get the info
if (! mciSendCommand(0, MCI_SYSINFO, MCI_SYSINFO_QUANTITY,
(DWORD)(LPVOID) &mciSIP))
nTotal = (int) *((LPDWORD) mciSIP.lpstrReturn) ;
return nTotal ;
}
/* lMicroSec = StringRateToMicroSec(szRate)
*
* Convert <szRate> (e.g. "3.75" representing 3.75 frames per second)
* to microseconds (e.g. 266667L microseconds per frame).
*
* If the rate is close to zero or negative, then 0L is returned.
*/
DWORD StringRateToMicroSec(PSTR szRate)
{
double dRate;
dRate = atof(szRate);
if (dRate < 0.0001) {
return 0L;
} else {
return (DWORD) /*floor*/((1e6 / dRate) + 0.5);
}
}
/* ach = MicroSecToStringRate(achRate, lMicroSec)
*
* Convert <lMicroSec> (e.g. 266667L microseconds per frame) to a
* string rate (e.g. "3.75" representing 3.75 frames per second).
* Returns <achRate>.
*/
PSTR MicroSecToStringRate(PSTR achRate, DWORD dwMicroSec)
{
sprintf(achRate, "%.3f",
(dwMicroSec == 0L) ? 0.0 : (1e6 / (double) dwMicroSec));
return achRate;
}
/*
* update the text of an edit field based on a comarrow up or down change
* - write the text in N.NNN format (truncated to an integer)
*/
LONG FAR PASCAL
MilliSecVarArrowEditChange(
HWND hwndEdit,
UINT uCode,
LONG lMin,
LONG lMax,
UINT uInc
)
{
char achTemp[32];
LONG l;
GetWindowText(hwndEdit, achTemp, sizeof(achTemp));
l = atol(achTemp);
if(uCode == SB_LINEUP ) {
if(l + (long)uInc <= lMax ) {
l += uInc;
wsprintf(achTemp, "%ld.000", l );
SetWindowText(hwndEdit, achTemp );
} else {
MessageBeep( 0 );
}
} else if (uCode == SB_LINEDOWN ) {
if( l-(long)uInc >= lMin ) {
l -= uInc;
wsprintf( achTemp, "%ld.000", l );
SetWindowText( hwndEdit, achTemp );
} else {
MessageBeep( 0 );
}
}
return( l );
}
BOOL MCIGetDeviceNameAndIndex (HWND hwnd, LPINT lpnIndex, LPSTR lpName)
{
HWND hwndCB;
char buf[160];
char *cp;
hwndCB = GetDlgItem( hwnd, IDD_MCI_SOURCE );
*lpnIndex = (int)SendMessage( hwndCB, CB_GETCURSEL, 0, 0L);
SendMessage( hwndCB, CB_GETLBTEXT, *lpnIndex,
(LONG)(LPSTR) buf );
// Point cp to the system name
for (cp = buf + lstrlen(buf); cp > buf; cp--) {
if (*cp == ' ' && *(cp-1) == ',') {
cp++;
break;
}
}
lstrcpy (lpName, cp);
return TRUE;
}
/*--------------------------------------------------------------+
| TimeMSToHMSString() - change milliseconds into a time string |
+--------------------------------------------------------------*/
void FAR PASCAL TimeMSToHMSString (DWORD dwMS, LPSTR lpTime)
{
DWORD dwTotalSecs;
LONG lHundredths;
WORD wSecs;
WORD wMins;
WORD wHours;
/* convert to number of seconds */
dwTotalSecs = dwMS / 1000;
/* keep the remainder part */
lHundredths = (dwMS - (dwTotalSecs * 1000)) / 10;
/* break down into other components */
wHours = (WORD)(dwTotalSecs / 3600); // get # Hours
dwTotalSecs -= (wHours * 3600);
wMins = (WORD)(dwTotalSecs / 60); // get # Mins
dwTotalSecs -= (wMins * 60);
wSecs = (WORD)dwTotalSecs; // what's left is # seconds
/* build the string */
wsprintf((char far *)lpTime, "%02u:%02u:%02u.%02lu", wHours, wMins,
wSecs, lHundredths);
}
/*--------------------------------------------------------------+
| TimeHMSStringToMS() - change Time string to milliseconds |
| returns dwMilliseconds or -1 if error |
+--------------------------------------------------------------*/
LONG NEAR PASCAL TimeHMSStringToMS (LPSTR lpsz)
{
char achTime[12]; // buffer for time string (input)
DWORD dwMSecs; // total MSecs for this thing */
char *pDelim; // pointer to next delimeter
char *p; // general pointer
DWORD dwHours = 0; // # of hours
DWORD dwMins = 0; // # of minutes
DWORD dwSecs = 0; // # of seconds
WORD wHundredths = 0; // # hundredths
_fstrncpy(achTime, lpsz, sizeof (achTime));
if (achTime[0] == '\0')
return -1; // bad char so error out
/* rip through the whole string and look for illegal chars */
for (p = achTime; *p ; p++){
if (!isdigit(*p) && *p != '.' && *p != ':')
return -1; // bad char so error out
}
/* go find the hundredths portion if it exists */
pDelim = strchr(achTime, '.');
if (*pDelim){
p = strrchr(achTime, '.');
if (pDelim != p) {
return -1; // string has > 1 '.', return error
}
p++; // move up past delim
if (strlen(p) > 2) {
*(p+2) = '\0'; // knock off all but hundredths
}
wHundredths = atoi(p); // get the fractional part
*pDelim = '\0'; // null out this terminator
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -