unsigned int ambient::getHeight() { FB::PluginWindow *plgwin = this->GetWindow(); HWND parent; RECT winrect; WINDOWINFO inf; inf.cbSize = sizeof(WINDOWINFO); if(this->isWindowless()) { FB::PluginWindowlessWin *plgwindows = (FB::PluginWindowlessWin *) plgwin; parent = plgwindows->getHWND(); // again down one step parent = GetParent(parent); GetWindowInfo(parent,&inf); GetWindowRect(parent,&winrect); parentWidth = winrect.right; parentHeight = winrect.bottom; }else{ FB::PluginWindowWin *plgwindows = (FB::PluginWindowWin *)plgwin; parent = plgwindows->getBrowserHWND(); GetWindowInfo(parent,&inf); GetWindowRect(parent,&winrect); parentWidth = winrect.right; parentHeight = winrect.bottom; } return parentHeight; }
unsigned int ambient::grabFrame(unsigned int webBrowser, unsigned int scwidth, unsigned int scheight, unsigned int width, unsigned int height) { FB::PluginWindow *plgwin = this->GetWindow(); FB::PluginWindowWin *plgwindows = (FB::PluginWindowWin *)plgwin; HWND parent=NULL,child=NULL; WINDOWINFO inf; inf.cbSize = sizeof(WINDOWINFO); flashPlugin = NULL; if(webBrowser != AUTO_FETCH) { if(webBrowser == MOZILLA_FIREFOX) { parent = plgwindows->getBrowserHWND(); // <-- GeckoPluginWindow parent = ::GetParent(parent); // <--- MozillaWindowClass (intermediate window) parent = ::GetParent(parent); // <--- MozillaWindowClass (main window) child = ::GetWindow(parent,GW_CHILD); // <--- The first MozillaWindowClass GetWindowInfo(child, &inf); while(child != NULL) { if((inf.rcClient.right - inf.rcClient.left) == width && (inf.rcClient.bottom - inf.rcClient.top)==height) break; child = ::GetNextWindow(child,GW_HWNDNEXT); GetWindowInfo(child,&inf); }; if(child == NULL) return 3; // no such window child = ::GetWindow(child,GW_CHILD); flashPlugin = child; }else if(webBrowser == OPERA) { parent = plgwindows->getBrowserHWND(); //<--- OperaWindowClass //parent = GetParent(parent); child = ::GetWindow(parent,GW_CHILD); // <--- The first aPluginWindowClass GetWindowInfo(child, &inf); while(child != NULL) { if((inf.rcClient.right - inf.rcClient.left) == width && (inf.rcClient.bottom - inf.rcClient.top)==height) break; child = ::GetNextWindow(child,GW_HWNDNEXT); ::GetWindowInfo(child,&inf); }; if(child == NULL) return 3; // no such window flashPlugin = child; }else if(webBrowser == MICROSOFT_IE) { parent = ::GetParent(plgwindows->getHWND()); child = ::GetWindow(parent,GW_CHILD); ::GetWindowInfo(child,&inf); while(child != NULL) { if((inf.rcClient.right - inf.rcClient.left) == width && (inf.rcClient.bottom - inf.rcClient.top)==height) break; child = ::GetNextWindow(child,GW_HWNDNEXT); ::GetWindowInfo(child,&inf); }; if(child == NULL) return 3; // no such window flashPlugin = child; }else if(webBrowser == GOOGLE_CHROME) { parent = plgwindows->getBrowserHWND(); // <-- NativeWindowClass parent = ::GetParent(parent); // <-- WrapperNativeWindowClass parent = ::GetParent(parent); // <-- Chrome_RenderWidgetHost child = ::GetWindow(parent,GW_CHILD); // <-- The first NativeWindowClass(Plugin) of this page GetWindowInfo(child,&inf); // try to find the window with the given resolution while(child != NULL) { if((inf.rcClient.right - inf.rcClient.left) == width && (inf.rcClient.bottom - inf.rcClient.top)==height) break; child = ::GetNextWindow(child,GW_HWNDNEXT); GetWindowInfo(child,&inf); }; if(child == NULL) return 3; // no such window //child = GetWindow(child,GW_CHILD); flashPlugin = child; // we have our HWND }else if(webBrowser == SAFARI) { unsigned int winOrder; parent = plgwindows->getBrowserHWND(); // because of the content script the plugin is always the last window so just step backwards and grep the flash plugin // TODO: if we are not the last one if(::GetNextWindow(parent,GW_HWNDPREV) == NULL) winOrder = GW_HWNDNEXT; else { // step back while (::GetNextWindow(parent,GW_HWNDPREV) != NULL) parent = ::GetNextWindow(parent,GW_HWNDPREV); winOrder = GW_HWNDNEXT; } while(parent != NULL) { // we have to get the child of every window child = ::GetWindow(parent,GW_CHILD); if(child != NULL) { GetWindowInfo(child,&inf); if((inf.rcClient.right - inf.rcClient.left) == width && (inf.rcClient.bottom - inf.rcClient.top)==height) break; } parent = ::GetNextWindow(parent,winOrder); } if(parent == NULL || child == NULL) return 3; flashPlugin = child; }else{ return 2; //not supported } }else{ // try to fetch the window automatically ... test each browser strategy // if the browser hwnd is NULL, then we are in the internet explorer ... if(plgwindows->getBrowserHWND() == NULL) { parent = GetParent(plgwindows->getHWND()); child = ::GetWindow(parent,GW_CHILD); GetWindowInfo(child,&inf); while(child != NULL) { if((inf.rcClient.right - inf.rcClient.left) == width && (inf.rcClient.bottom - inf.rcClient.top)==height) break; child = ::GetNextWindow(child,GW_HWNDNEXT); GetWindowInfo(child,&inf); }; if(child != NULL) flashPlugin = child; } if(child == NULL) { // mozilla parent = plgwindows->getBrowserHWND(); // <-- GeckoPluginWindow parent = GetParent(parent); // <--- MozillaWindowClass (intermediate window) parent = GetParent(parent); // <--- MozillaWindowClass (main window) child = ::GetWindow(parent,GW_CHILD); // <--- The first MozillaWindowClass GetWindowInfo(child, &inf); while(child != NULL) { if((inf.rcClient.right - inf.rcClient.left) == width && (inf.rcClient.bottom - inf.rcClient.top)==height) break; child = ::GetNextWindow(child,GW_HWNDNEXT); ::GetWindowInfo(child,&inf); }; if(child != NULL) { child = ::GetWindow(child,GW_CHILD); flashPlugin = child; } } if(child == NULL) // no such window, next strategy { parent = plgwindows->getBrowserHWND(); //<--- OperaWindowClass //parent = GetParent(parent); child = ::GetWindow(parent,GW_CHILD); // <--- The first aPluginWindowClass GetWindowInfo(child, &inf); while(child != NULL) { if((inf.rcClient.right - inf.rcClient.left) == width && (inf.rcClient.bottom - inf.rcClient.top)==height) break; child = ::GetNextWindow(child,GW_HWNDNEXT); GetWindowInfo(child,&inf); }; if(child != NULL) flashPlugin = child; } if(child == NULL) // and again { parent = plgwindows->getBrowserHWND(); // <-- NativeWindowClass parent = GetParent(parent); // <-- WrapperNativeWindowClass parent = GetParent(parent); // <-- Chrome_RenderWidgetHost child = ::GetWindow(parent,GW_CHILD); // <-- The first NativeWindowClass(Plugin) of this page GetWindowInfo(child,&inf); // try to find the window with the given resolution while(child != NULL) { if((inf.rcClient.right - inf.rcClient.left) == width && (inf.rcClient.bottom - inf.rcClient.top)==height) break; child = ::GetNextWindow(child,GW_HWNDNEXT); GetWindowInfo(child,&inf); }; if(child != NULL) flashPlugin = child; // no such window //child = GetWindow(child,GW_CHILD); // we have our HWND } if(child == NULL) { unsigned int winOrder; parent = plgwindows->getBrowserHWND(); // because of the content script the plugin is always the last window so just step backwards and grep the flash plugin // TODO: if we are not the last one if(::GetNextWindow(parent,GW_HWNDPREV) == NULL) winOrder = GW_HWNDNEXT; else { // setp back while (::GetNextWindow(parent,GW_HWNDPREV) != NULL) parent = ::GetNextWindow(parent,GW_HWNDPREV); winOrder = GW_HWNDNEXT; } while(parent != NULL) { // we have to get the child of every window child = ::GetWindow(parent,GW_CHILD); if(child != NULL) { GetWindowInfo(child,&inf); if((inf.rcClient.right - inf.rcClient.left) == width && (inf.rcClient.bottom - inf.rcClient.top)==height) break; } parent = ::GetNextWindow(parent,winOrder); } if(parent != NULL && child != NULL) flashPlugin = child; } if(flashPlugin == NULL) return 3; //hmm... } GetWindowRect(flashPlugin,&winrect); // we may have the window handle but, since we are calling this on a timer it may happen that we enter this section twice // prevent this behavior with a mutex if(WaitForSingleObject(this->calcMutex,1) == WAIT_TIMEOUT) return 4; // grab a frame from the flash plugin embedded in the active page HDC flashHDC = GetWindowDC(flashPlugin); HDC Memory = CreateCompatibleDC(flashHDC); HBITMAP bmMemory = CreateCompatibleBitmap(flashHDC,winrect.right-winrect.left,winrect.bottom-winrect.top); HBITMAP Old = (HBITMAP) SelectObject(Memory, bmMemory); //BitBlt(Memory,0,30,winrect.right-winrect.left,winrect.bottom-winrect.top,flashHDC,0,0,SRCCOPY); // mirror the image vertical and scale it StretchBlt(Memory,0,0,scwidth,scheight,flashHDC,0,0,winrect.right-winrect.left,winrect.bottom-winrect.top,SRCCOPY); BITMAPINFO Info; ZeroMemory(&Info, sizeof(BITMAPINFO)); Info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); Info.bmiHeader.biWidth = scwidth; Info.bmiHeader.biHeight = -scheight; Info.bmiHeader.biBitCount = 32; Info.bmiHeader.biCompression = BI_RGB; Info.bmiHeader.biPlanes = 1; GetDIBits(Memory,bmMemory,0,scheight,NULL,&Info,DIB_RGB_COLORS); // now copy the image to our buffer // NOTE: it's a BGR frame ... if(Info.bmiHeader.biSizeImage == 0) { SelectObject(Memory, Old); ReleaseDC(flashPlugin,Memory); ReleaseDC(flashPlugin,flashHDC); DeleteObject(bmMemory); DeleteDC(Memory); ReleaseMutex(this->calcMutex); return 4; } unsigned char *data = (unsigned char *)malloc(Info.bmiHeader.biSizeImage); ZeroMemory(data,Info.bmiHeader.biSizeImage); GetDIBits(Memory,bmMemory,0,scheight,data,&Info,DIB_RGB_COLORS); SelectObject(Memory, Old); ReleaseDC(flashPlugin,Memory); ReleaseDC(flashPlugin,flashHDC); DeleteDC(Memory); DeleteObject(bmMemory); ambientLib->lightFromPicture(data,IMAGE_FORMAT_BGRA); free(data); ReleaseMutex(this->calcMutex); return 0; }