354 lines
8.5 KiB
C++
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 --;
|
|
}
|
|
|
|
|
|
|