JD2022-TU1/main/extern/Camcam/LIBS/Input/BACK.cpp

354 lines
8.5 KiB
C++

#include "SCENE.h"
#include "MEDIA.h"
#define UPDATE_ONFOCUS 50
#define UPDATE_NOFOCUS 100
class BACK_Grabber:public INPUT_IO
{
public:
RECT WR;
u32 IsFocused;
u32 LastUpDate;
WORLD *pWorld;
HDC hdcScreen;
HDC hdcCompatible;
HBITMAP hbmScreen;
int INIT (class WORLD*){return 0;};
int FRAME (void);
int END (void)
{
if (hbmScreen) DeleteObject(hbmScreen);
if (hdcCompatible) DeleteDC(hdcCompatible);
if (hdcScreen) DeleteDC(hdcScreen);
return 0;
};
IOTYPE GetType() {return IOtype_BACK;};
};
typedef BOOL (WINAPI *lpfnSetLayeredWindowAttributes)(HWND hWnd,
COLORREF crKey, BYTE bAlpha, DWORD dwFlags);
extern lpfnSetLayeredWindowAttributes m_pSetLayeredWindowAttributes;
//#pragma optimize( "", off )
void BACK_GetrWNSDRect( HWND hWnd,RECT *pR)
{
RECT CltRect;
POINT CArea;
GetWindowRect(hWnd,pR);
GetClientRect(hWnd, &CltRect);
CArea.x = 0;
CArea.y = 0;
ClientToScreen(hWnd,(POINT *)&CArea);
pR->top = CArea.y;
pR->left= CArea.x;
pR->bottom = pR->top + CltRect.bottom - CltRect.top;
pR->right = pR->left + CltRect.right - CltRect.left;
}
typedef BOOL (_stdcall *tPrintWindow)( HWND, HDC,UINT);
static tPrintWindow pPrintWindow =0;
typedef struct HWNDStack_
{
HWND hwndMe;
u32 ulNumberOfWindows;
HWND HWNDStack[1024];
} HWNDStack;
static u32 Depth = 0;
BOOL CALLBACK EnumChildProc3(HWND hwnd, LPARAM lParam)
{
if (Depth < 3)
{
Depth++;
EnumChildWindows(hwnd,EnumChildProc3,lParam);
Depth--;
}
if (lParam == 0)
{
//InvalidateRect( hwnd, NULL, TRUE) ;
//UpdateWindow( hwnd) ;
} else
{
/* InvalidateRect( hwnd, NULL, TRUE) ;
UpdateWindow( hwnd) ;//*/
SendMessage(hwnd, WM_PRINT, (WPARAM)lParam ,
PRF_CHILDREN +
PRF_CLIENT +
PRF_NONCLIENT+
PRF_ERASEBKGND +
//PRF_OWNED +
//PRF_CHECKVISIBLE +
0);//*/
}
return true;
}
BOOL CALLBACK EnumWndProc(HWND hwnd, LPARAM lParam)
{
HWNDStack *pHWS;
pHWS = (HWNDStack *)lParam;
if (pHWS->ulNumberOfWindows > 1000) return false;
if ((IsWindowVisible(hwnd)) && (pHWS->hwndMe != hwnd))
{
/* Overlap */
RECT ReC,pDst;
RECT MotherReC;
GetWindowRect(pHWS->hwndMe,&MotherReC);
GetWindowRect(hwnd,&ReC);
if(IntersectRect(&pDst,&ReC,&MotherReC))
{
pHWS->HWNDStack[pHWS->ulNumberOfWindows++] = hwnd;
// if (Gloak==0 && pPrintWindow)
{
// res = pPrintWindow(hwnd, (HDC)lParam, 0);
// InvalidateRect(hwnd,NULL,false);//*/
} /*else
if (!res)
SendMessage(hwnd, WM_PRINT, (WPARAM)lParam ,
PRF_CHILDREN +
PRF_CLIENT +
PRF_NONCLIENT+
//PRF_ERASEBKGND +
//PRF_OWNED +
//PRF_CHECKVISIBLE +
0);//*/
}
}
return true;
}
int Update(BACK_Grabber *Ret,WORLD *pScene)
{
RECT WR2;
u32 Update = 0;
DWORD time = timeGetTime();
BACK_GetrWNSDRect(pScene->OwnerHwnd,&WR2);
WR2.right = WR2.right - WR2.left;
WR2.bottom = WR2.bottom - WR2.top;
if (pScene->OwnerHwnd == GetFocus())
Ret->IsFocused = 1;
else
Ret->IsFocused = 0;
if (Ret->IsFocused && (time - Ret->LastUpDate) > UPDATE_ONFOCUS)
Update = 1;
if (!Ret->IsFocused && (time - Ret->LastUpDate) > UPDATE_NOFOCUS)
Update = 1;
if (memcmp(&WR2,&Ret->WR,sizeof(RECT)) || Update)
{
Ret->LastUpDate = time;
Ret->WR = WR2;
if (Ret->Image.SetSize(Ret->WR.right, Ret->WR.bottom))
{
if (Ret->ulAssociatedTextureIndex != -1) pScene->DI->DestroyTexture(Ret->ulAssociatedTextureIndex);
Ret->ulAssociatedTextureIndex = -1;
Ret->ulAssociatedTextureIndex = pScene->DI->CreateTexture(&Ret->Image,Ret->ulColorMode);
}
HDC hDC = GetDC(GetDesktopWindow());
HDC hDCMem = CreateCompatibleDC(hDC);
HBITMAP hBmp = CreateCompatibleBitmap(hDC, GetDeviceCaps(hDC, HORZRES), GetDeviceCaps(hDC, VERTRES));
ReleaseDC(GetDesktopWindow(), hDC);
HGDIOBJ hOld = SelectObject(hDCMem, hBmp);
if (pPrintWindow == 0)
{
HINSTANCE handle = ::GetModuleHandle("user32.dll");
if ( handle == 0 )
handle = ::LoadLibrary("User32.dll");
if (handle)
pPrintWindow = (tPrintWindow)::GetProcAddress(handle,"PrintWindow");
}
HWNDStack HWS;
bool res = false;
HWS.hwndMe = pScene->OwnerHwnd;
HWS.ulNumberOfWindows = 0;
SET(&Ret->Image,0);
EnumWindows(EnumWndProc,(WPARAM)&HWS);
OSVERSIONINFO osver;
osver.dwOSVersionInfoSize = sizeof(osver);
GetVersionEx(&osver);
if ((osver.dwMajorVersion <= 5) && (HWS.ulNumberOfWindows)) HWS.ulNumberOfWindows--;
while (HWS.ulNumberOfWindows--)
{
res = false;
res = pPrintWindow(HWS.HWNDStack[HWS.ulNumberOfWindows], hDCMem, 0);
if (!res)
{
EnumChildWindows(HWS.HWNDStack[HWS.ulNumberOfWindows],EnumChildProc3,(WPARAM)hDCMem);
SendMessage(HWS.HWNDStack[HWS.ulNumberOfWindows], WM_PRINT, (WPARAM)hDCMem,
PRF_CHILDREN +
PRF_CLIENT +
//PRF_NONCLIENT+
//PRF_ERASEBKGND +
//PRF_OWNED +
//PRF_CHECKVISIBLE +
0);//*/
}
RECT ReC,pDst,Desk;
RECT MotherReC;
GetWindowRect(pScene->OwnerHwnd,&MotherReC);
GetWindowRect(HWS.HWNDStack[HWS.ulNumberOfWindows],&ReC);
GetWindowRect(GetDesktopWindow(),&Desk);
IntersectRect(&pDst,&ReC,&MotherReC);
BITMAPINFOHEADER bi;
memset(&bi, 0,sizeof(BITMAPINFOHEADER));
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = ReC.right - ReC.left;
bi.biHeight = ReC.bottom - ReC.top;
bi.biPlanes = 1;
bi.biBitCount = 32;
bi.biCompression = BI_RGB;
s32 XBase,YBase,XLen,YLen,YLenT,XBasSource,YBasSource;
XBase = pDst.left - MotherReC.left;
YBase = pDst.top - MotherReC.top;
XLen = pDst.right - pDst.left;
YLenT = YLen = pDst.bottom - pDst.top;
XBasSource = pDst.left - ReC.left;
YBasSource = (ReC.bottom - ReC.top) - (pDst.top - ReC.top) - 1;
YBase = Ret->Image.SY - YBase - 1;
s32 *pBASE = Ret->Image.GetBase();
while (YLen--)
{
u32 Line[2048];
GetDIBits ( hDCMem, hBmp, YBasSource,1, Line,(BITMAPINFO*)&bi, DIB_RGB_COLORS);
if (YBase < Ret->Image.SY)
memcpy(pBASE + XBase + (YBase)*Ret->Image.PITCH,Line + XBasSource,XLen*4);
YBasSource--;
YBase--;
}
//if (HWS.ulNumberOfWindows < 10 ) HWS.ulNumberOfWindows = 0;
}
SelectObject(hDCMem, hOld );
if (hDCMem) DeleteObject(hDCMem);
if (hBmp) DeleteObject(hBmp);
/*
// Create a normal DC and a memory DC for the entire screen. The
// normal DC provides a "snapshot" of the screen contents. The
// memory DC keeps a copy of this "snapshot" in the associated
// bitmap.
if (!Ret->hdcScreen)
{
Ret->hdcScreen = CreateDC("DISPLAY", NULL, NULL, NULL);
Ret->hdcCompatible = CreateCompatibleDC(Ret->hdcScreen);
// Create a compatible bitmap for hdcScreen.
Ret->hbmScreen = CreateCompatibleBitmap(Ret->hdcScreen,
GetDeviceCaps(Ret->hdcScreen, HORZRES),
GetDeviceCaps(Ret->hdcScreen, VERTRES));
}
// Select the bitmaps into the compatible DC.
if (Ret->hbmScreen && SelectObject(Ret->hdcCompatible, Ret->hbmScreen))
{
BitBlt(Ret->hdcCompatible,
0,0,
Ret->Image.SX, Ret->Image.SY,
Ret->hdcScreen,
Ret->WR.left,Ret->WR.top,
SRCCOPY);
BITMAPINFOHEADER bi;
memset(&bi, 0,sizeof(BITMAPINFOHEADER));
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = Ret->Image.SX;
bi.biHeight = Ret->Image.SY;
bi.biPlanes = 1;
bi.biBitCount = 32;
bi.biCompression = BI_RGB;
GetDIBits ( Ret->hdcCompatible, Ret->hbmScreen, 0,
Ret->Image.SY, Ret->Image.BASE,
(BITMAPINFO*)&bi, DIB_RGB_COLORS);
};*/
return 1;
}
return 0;
}
int BACK_Grabber::FRAME (void)
{
return Update(this,pWorld);
}
INPUT_IO *BACK_CREATE(WORLD *pScene,char *Filename)
{
u32 SX,SY;
INPUT_IO *Ret;
Ret = (INPUT_IO *)new(BACK_Grabber);
((BACK_Grabber*)Ret)->pWorld = pScene;
((BACK_Grabber*)Ret)->hdcScreen = NULL;
((BACK_Grabber*)Ret)->hdcCompatible = NULL;
((BACK_Grabber*)Ret)->hbmScreen = NULL;
Ret->dTotalTime = 0;
Ret->dAvgFramePerSecond = 30.0;
Ret->ulAssociatedTextureIndex = -1;
Update((BACK_Grabber*)Ret,pScene);
return (INPUT_IO *)Ret;
};
void UpdateAllBack(WORLD *pScene)
{
static int Locker = 0;
if (pScene == NULL) return;
if (Locker ) return;
Locker ++;
for (int Counter = 0 ; Counter < MAX_INPMED ; Counter++)
{
if (pScene->ID_MEDIA[Counter] && (pScene->ID_MEDIA[Counter]->GetType() == IOtype_BACK)
&& (pScene->ID_MEDIA[Counter]->VirtuallyDestroyed == 0))
{
if (pScene->ID_MEDIA[Counter]->FRAME())
{
if ((pScene->ID_MEDIA[Counter]->ulAssociatedTextureIndex != -1) )
{
pScene->DI->UpdateTexture_BM_2_HW(pScene->ID_MEDIA[Counter]->ulAssociatedTextureIndex);
}
}
}
}
Locker --;
}