📄 vscapview.cpp
字号:
else if (MouseCaptureMode==1) {
NormalizeRect(&rcClip);
old_rcClip=rcClip;
if (bCapturing) bCapturing = FALSE;
}
ShowWindow(hWnd,SW_HIDE);
} //VK_ESCAPE
return DefWindowProc(hWnd, wMessage, wParam, lParam);
}
default:
return DefWindowProc(hWnd, wMessage, wParam, lParam);
}
return 0;
}
int CreateShiftWindow() {
// Code For Creating a Window for Specifying Region
// A borderless, invisible window used only for capturing mouse input for the whole screen
HINSTANCE hInstance = AfxGetInstanceHandle( );
WNDCLASS wndclass;
wndclass.style = 0;
wndclass.lpfnWndProc = (WNDPROC)MouseCaptureWndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance;
wndclass.hIcon = LoadIcon(hInstance, "WINCAP");
HICON hcur= LoadIcon(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDI_ICONCROSSHAIR));
//wndclass.hCursor = LoadCursor(NULL, IDC_CROSS);
wndclass.hCursor = hcur;
wndclass.hbrBackground = NULL;
//wndclass.lpszMenuName = (LPSTR)"MAINMENU";
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = (LPSTR) "ShiftRegionWindow";
if (!RegisterClass(&wndclass))
return 0;
HDC hScreenDC=::GetDC(NULL);
maxxScreen = GetDeviceCaps(hScreenDC,HORZRES);
maxyScreen = GetDeviceCaps(hScreenDC,VERTRES);
::ReleaseDC(NULL,hScreenDC);
hMouseCaptureWnd = CreateWindowEx(WS_EX_TOPMOST,"ShiftRegionWindow", "Title",WS_POPUP,0,0,maxxScreen,maxyScreen,NULL,NULL, hInstance, NULL);
return 0;
}
int InitSelectRegionWindow() {
return 0;
}
int InitDrawShiftWindow() {
HDC hScreenDC = ::GetDC(hMouseCaptureWnd);
FixRectSizePos(&rc, maxxScreen, maxyScreen);
rcClip.left=rc.left;
rcClip.top=rc.top;
rcClip.right=rc.right;
rcClip.bottom=rc.bottom;
DrawSelect(hScreenDC, TRUE, &rcClip);
old_rcClip = rcClip;
//Set Curosr at the centre of the clip rectangle
POINT ptOrigin;
ptOrigin.x=(rcClip.right+rcClip.left)/2;
ptOrigin.y=(rcClip.top+rcClip.bottom)/2;
rcOffset.left=rcClip.left-ptOrigin.x;
rcOffset.top=rcClip.top-ptOrigin.y;
rcOffset.right=rcClip.right-ptOrigin.x;
rcOffset.bottom=rcClip.bottom-ptOrigin.y;
::ReleaseDC(hMouseCaptureWnd,hScreenDC);
return 0;
}
int DestroyShiftWindow() {
if (hMouseCaptureWnd) ::DestroyWindow(hMouseCaptureWnd);
return 0;
}
///////////////////////// //////////////////
/////////////// Functions //////////////////
///////////////////////// //////////////////
static HANDLE Bitmap2Dib( HBITMAP hbitmap, UINT bits )
{
HANDLE hdib ;
HDC hdc ;
BITMAP bitmap ;
UINT wLineLen ;
DWORD dwSize ;
DWORD wColSize ;
LPBITMAPINFOHEADER lpbi ;
LPBYTE lpBits ;
GetObject(hbitmap,sizeof(BITMAP),&bitmap) ;
//
// DWORD align the width of the DIB
// Figure out the size of the colour table
// Calculate the size of the DIB
//
wLineLen = (bitmap.bmWidth*bits+31)/32 * 4;
wColSize = sizeof(RGBQUAD)*((bits <= 8) ? 1<<bits : 0);
dwSize = sizeof(BITMAPINFOHEADER) + wColSize +
(DWORD)(UINT)wLineLen*(DWORD)(UINT)bitmap.bmHeight;
//
// Allocate room for a DIB and set the LPBI fields
//
hdib = GlobalAlloc(GHND,dwSize);
if (!hdib)
return hdib ;
lpbi = (LPBITMAPINFOHEADER)GlobalLock(hdib) ;
lpbi->biSize = sizeof(BITMAPINFOHEADER) ;
lpbi->biWidth = bitmap.bmWidth ;
lpbi->biHeight = bitmap.bmHeight ;
lpbi->biPlanes = 1 ;
lpbi->biBitCount = (WORD) bits ;
lpbi->biCompression = BI_RGB ;
lpbi->biSizeImage = dwSize - sizeof(BITMAPINFOHEADER) - wColSize ;
lpbi->biXPelsPerMeter = 0 ;
lpbi->biYPelsPerMeter = 0 ;
lpbi->biClrUsed = (bits <= 8) ? 1<<bits : 0;
lpbi->biClrImportant = 0 ;
//
// Get the bits from the bitmap and stuff them after the LPBI
//
lpBits = (LPBYTE)(lpbi+1)+wColSize ;
hdc = CreateCompatibleDC(NULL) ;
GetDIBits(hdc,hbitmap,0,bitmap.bmHeight,lpBits,(LPBITMAPINFO)lpbi, DIB_RGB_COLORS);
lpbi->biClrUsed = (bits <= 8) ? 1<<bits : 0;
DeleteDC(hdc) ;
GlobalUnlock(hdib);
return hdib ;
}
UINT RecordAVIThread(LPVOID pParam) {
int top=rcUse.top;
int left=rcUse.left;
int width=rcUse.right-rcUse.left+1;
int height=rcUse.bottom - rcUse.top + 1;
int fps=frames_per_second;
CString fileName("\\~temp.avi");
tempfilepath = GetTempPath () + fileName;
//Test the validity of writing to the file
//Make sure the file to be created is currently not used by another application
int fileverified = 0;
while (!fileverified)
{
OFSTRUCT ofstruct;
HFILE fhandle = OpenFile( tempfilepath, &ofstruct, OF_SHARE_EXCLUSIVE | OF_WRITE | OF_CREATE );
if (fhandle != HFILE_ERROR) {
fileverified = 1;
CloseHandle( (HANDLE) fhandle );
DeleteFile(tempfilepath);
}
else {
srand( (unsigned)time( NULL ) );
int randnum = rand();
char numstr[50];
sprintf(numstr,"%d",randnum);
CString cnumstr(numstr);
CString fxstr("\\~temp");
CString exstr(".avi");
tempfilepath = GetTempPath () + fxstr + cnumstr + exstr;
}
}
RecordVideo(top,left,width,height,fps,tempfilepath);
return 0;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// RecordVideo
//
// The main function used in the recording of video
// Includes opening/closing avi file, initializing avi settings, capturing frames, applying cursor effects etc.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int RecordVideo(int top,int left,int width,int height,int fps,const char *szFileName) {
LPBITMAPINFOHEADER alpbi;
AVISTREAMINFO strhdr;
PAVIFILE pfile = NULL;
PAVISTREAM ps = NULL, psCompressed = NULL;
AVICOMPRESSOPTIONS opts;
AVICOMPRESSOPTIONS FAR * aopts[1] = {&opts};
HRESULT hr;
WORD wVer;
char szTitle[BUFSIZE];
actualwidth=width;
actualheight=height;
wVer = HIWORD(VideoForWindowsVersion());
if (wVer < 0x010a){
MessageBox(NULL, "Error! Video for Windows version too old!", "Error" , MB_OK|MB_ICONSTOP);
return FALSE;
}
alpbi = NULL;
////////////////////////////////////////////////
// CAPTURE FIRST FRAME
////////////////////////////////////////////////
alpbi=captureScreenFrame(left,top,width, height,1);
////////////////////////////////////////////////
// TEST VALIDITY OF COMPRESSOR
//////////////////////////////////////////////////
if (selected_compressor > 0) {
HIC hic = NULL;
hic = ICOpen(compressor_info[selected_compressor].fccType, compressor_info[selected_compressor].fccHandler, ICMODE_QUERY);
if (hic) {
int newleft,newtop,newwidth,newheight;
int align = 1;
while (ICERR_OK!=ICCompressQuery(hic, alpbi, NULL))
{
//Try adjusting width/height a little bit
align = align * 2 ;
if (align>8) break;
newleft=left;
newtop=top;
int wm = (width % align);
if (wm > 0) {
newwidth = width + (align - wm);
if (newwidth>maxxScreen)
newwidth = width - wm;
}
int hm = (height % align);
if (hm > 0) {
newheight = height + (align - hm);
if (newheight>maxyScreen)
newwidth = height - hm;
}
if (alpbi) FreeFrame(alpbi);
alpbi=captureScreenFrame(newleft,newtop,newwidth, newheight,1);
}
//if succeed with new width/height, use the new width and height
//else if still fails ==> default to MS Video 1 (MSVC)
if (align == 1) {
//Compressor has no problem with the current dimensions...so proceed
//do nothing here
}
else if (align <= 8) {
//Compressor can work if the dimensions is adjusted slightly
left=newleft;
top=newtop;
width=newwidth;
height=newheight;
actualwidth=newwidth;
actualheight=newheight;
}
else {
compfccHandler = mmioFOURCC('M', 'S', 'V', 'C');
strCodec = CString("Default Compressor");
}
ICClose(hic);
}
else {
compfccHandler = mmioFOURCC('M', 'S', 'V', 'C');
strCodec = CString("Default Compressor");
//MessageBox(NULL,"hic default","note",MB_OK);
}
}//selected_compressor
//Special Cases
if (compfccHandler==mmioFOURCC('D', 'I', 'V', 'X'))
{ //Still Can't Handle DIVX
compfccHandler = mmioFOURCC('M', 'S', 'V', 'C');
strCodec = CString("Default Compressor");
}
if (compfccHandler==mmioFOURCC('I', 'V', '5', '0'))
{ //Still Can't Handle Indeo 5.04
compfccHandler = mmioFOURCC('M', 'S', 'V', 'C');
strCodec = CString("Default Compressor");
}
////////////////////////////////////////////////
// Set Up Flashing Rect
////////////////////////////////////////////////
if (flashingRect) {
if (autopan)
pFrame->SetUpRegion(left,top,width,height,1);
else
pFrame->SetUpRegion(left,top,width,height,0);
pFrame->ShowWindow(SW_SHOW);
}
////////////////////////////////////////////////
// INIT AVI USING FIRST FRAME
////////////////////////////////////////////////
AVIFileInit();
//
// Open the movie file for writing....
//
strcpy(szTitle,"AVI Movie");
hr = AVIFileOpen(&pfile, szFileName, OF_WRITE | OF_CREATE, NULL);
if (hr != AVIERR_OK) goto error;
// Fill in the header for the video stream....
// The video stream will run in 15ths of a second....
_fmemset(&strhdr, 0, sizeof(strhdr));
strhdr.fccType = streamtypeVIDEO;// stream type
//strhdr.fccHandler = compfccHandler;
strhdr.fccHandler = 0;
strhdr.dwScale = 1;
strhdr.dwRate = fps;
strhdr.dwSuggestedBufferSize = alpbi->biSizeImage;
SetRect(&strhdr.rcFrame, 0, 0, // rectangle for stream
(int) alpbi->biWidth,
(int) alpbi->biHeight);
// And create the stream;
hr = AVIFileCreateStream(pfile, &ps, &strhdr);
if (hr != AVIERR_OK) goto error;
memset(&opts, 0, sizeof(opts));
aopts[0]->fccType = streamtypeVIDEO;
//aopts[0]->fccHandler = mmioFOURCC('M', 'S', 'V', 'C');
aopts[0]->fccHandler = compfccHandler;
aopts[0]->dwKeyFrameEvery = keyFramesEvery; // keyframe rate
aopts[0]->dwQuality = compquality; // compress quality 0-10,000
aopts[0]->dwBytesPerSecond = 0; // bytes per second
aopts[0]->dwFlags = AVICOMPRESSF_VALID | AVICOMPRESSF_KEYFRAMES; // flags
aopts[0]->lpFormat = 0x0; // save format
aopts[0]->cbFormat = 0;
aopts[0]->dwInterleaveEvery = 0; // for non-video streams only
//The 1 here indicates only 1 stream
//if (!AVISaveOptions(NULL, 0, 1, &ps, (LPAVICOMPRESSOPTIONS *) &aopts))
// goto error;
hr = AVIMakeCompressedStream(&psCompressed, ps, &opts, NULL);
if (hr != AVIERR_OK) goto error;
hr = AVIStreamSetFormat(psCompressed, 0,
alpbi, // stream format
alpbi->biSize + // format size
alpbi->biClrUsed * sizeof(RGBQUAD));
if (hr != AVIERR_OK) goto error;
FreeFrame(alpbi);
alpbi=NULL;
DWORD timeexpended, frametime, oldframetime;
initialtime = timeGetTime();
initcapture = 1;
oldframetime = 0;
nCurrFrame = 0;
nActualFrame = 0;
if (autopan) {
panrect_current.left = left;
panrect_current.top = top;
panrect_current.right = left + width - 1;
panrect_current.bottom = top + height - 1;
}
//////////////////////////////////////////////
// WRITING FRAMES
//////////////////////////////////////////////
long divx, oldsec;
divx=0;
oldsec=0;
while (recordstate) { //repeatedly loop
if (initcapture==0) {
timeexpended = timeGetTime() - initialtime;
}
else {
frametime = 0;
timeexpended = 0;
}
//Autopan
if ((autopan) && (width < maxxScreen) && (height < maxyScreen)) {
POINT xPoint;
GetCursorPos(&xPoint);
int extleft = ((panrect_current.right - panrect_current.left)*1)/4 + panrect_current.left;
int extright = ((panrect_current.right - panrect_current.left)*3)/4 + panrect_current.left;
int exttop = ((panrect_current.bottom - panrect_current.top)*1)/4 + panrect_current.top;
int extbottom = ((panrect_current.bottom - panrect_current.top)*3)/4 + panrect_current.top;
if (xPoint.x < extleft ) { //need to pan left
panrect_dest.left = xPoint.x - width/2;
panrect_dest.right = panrect_dest.left + width - 1;
if (panrect_dest.left < 0) {
panrect_dest.left = 0;
panrect_dest.right = panrect_dest.left + width - 1;
}
}
else if (xPoint.x > extright ) { //need to pan right
panrect_dest.left = xPoint.x - width/2;
panrect_dest.right = panrect_dest.left + width - 1;
if (panrect_dest.right >= maxxScreen) {
panrect_dest.right = maxxScreen - 1;
panrect_dest.left = panrect_dest.right - width + 1;
}
}
else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -