summaryrefslogtreecommitdiff
path: root/plugins/SendScreenshotPlus/src/Utils.cpp
diff options
context:
space:
mode:
authorRené Schümann <white06tiger@gmail.com>2013-11-05 16:29:17 +0000
committerRené Schümann <white06tiger@gmail.com>2013-11-05 16:29:17 +0000
commitaa7f145a48708f577f6386f7aba86470f36cab26 (patch)
tree74c898e39e1c878154641dfa6fc6205571a7e193 /plugins/SendScreenshotPlus/src/Utils.cpp
parentebe0ab019e3c45fac0ff6067ff8808b060aff987 (diff)
// 4 out of 5
! fixed transparency issues when capturing windows + added support to capture child windows (next commit) * changed order of "set foreground" and "make top window" to hopefully fix usability problems related to it, also "restore" top window after capture git-svn-id: http://svn.miranda-ng.org/main/trunk@6789 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'plugins/SendScreenshotPlus/src/Utils.cpp')
-rw-r--r--plugins/SendScreenshotPlus/src/Utils.cpp135
1 files changed, 59 insertions, 76 deletions
diff --git a/plugins/SendScreenshotPlus/src/Utils.cpp b/plugins/SendScreenshotPlus/src/Utils.cpp
index ad2c00d4cf..f6daf450d5 100644
--- a/plugins/SendScreenshotPlus/src/Utils.cpp
+++ b/plugins/SendScreenshotPlus/src/Utils.cpp
@@ -80,21 +80,22 @@ FIBITMAP* CaptureWindow (HWND hCapture, BOOL ClientArea) {
if (!hCapture || !IsWindow(hCapture)) return 0;
hForegroundWin = GetForegroundWindow(); //Saving foreground window
- BringWindowToTop(hCapture); // This window bring the target window to the top of all others
SetForegroundWindow(hCapture); // Make sure the target window is the foreground one
- // redraw window to prevent runtime artefact in picture
+ BringWindowToTop(hCapture); // bring it to top as well
+ // redraw window to prevent runtime artifacts in picture
UpdateWindow(hCapture);
- hScrDC = GetWindowDC(hCapture);
-
- // get window resolution
- GetWindowRect(hCapture, &rect);
+ GetWindowRect(hCapture,&rect);
+ if(GetParent(hCapture))
+ hScrDC=GetDC(hCapture);//hCapture is part of a window, capture that
+ else
+ hScrDC=GetWindowDC(hCapture);//entire window w/ title bar
size.cx=ABS(rect.right-rect.left);
size.cy=ABS(rect.bottom-rect.top);
//capture window and get FIBITMAP
dib = CaptureScreen(hScrDC,size,hCapture);
ReleaseDC(hCapture,hScrDC);
- if(ClientArea) {
+ if(ClientArea){//we could capture directly, but doing so breaks GetWindowRgn() and also includes artifacts...
RECT rectCA = {0};
POINT pt = {0};
GetClientRect (hCapture, &rectCA);
@@ -108,9 +109,9 @@ FIBITMAP* CaptureWindow (HWND hCapture, BOOL ClientArea) {
FIP->FI_Unload(dib);
dib = dibClient;
}
- // Restoring foreground window
- if(hForegroundWin){
+ if(hForegroundWin){//restore previous foreground window
SetForegroundWindow(hForegroundWin);
+ BringWindowToTop(hForegroundWin);
}
return dib;
}
@@ -152,85 +153,67 @@ FIBITMAP* CaptureScreen (HDC hDC,SIZE size,HWND hCapture){
// select new bitmap into memory DC
SelectObject(hMemDC, hBitmap);
- if(hCapture) {
+ if(hCapture && hDC){
PrintWindow(hCapture,hMemDC,0);
}else{// bitblt screen DC to memory DC
BitBlt(hMemDC,0,0,size.cx,size.cy,hScrDC,0,0,CAPTUREBLT|SRCCOPY);
}
dib = FIP->FI_CreateDIBFromHBITMAP(hBitmap);
-
- //alpha channel from window is always wrong,
- //coz GDI do not draw all in alpha mode.
- //we have to create our own new alpha channel.
- bool bFixAlpha = true;
- bool bInvert = false;
-
- // Create monochrome (1 bit) B+W mask bitmap.
- HBITMAP hMask = CreateBitmap(size.cx,size.cy, 1, 1, NULL);
- HDC hMaskDC = CreateCompatibleDC(0);
- SelectBitmap(hMaskDC, hMask);
-
- //Create a SolidBrush object for non transparent area
- HBRUSH hBr = CreateSolidBrush(RGB(255,255,255));
-
- HRGN hrgn = NULL;
- int regionType;
- if(hCapture) {
- hrgn = CreateRectRgn(0,0,0,0);
- regionType = GetWindowRgn(hCapture, hrgn);
- if (regionType != ERROR) {
- // not layerd - fill the window region
- FillRgn(hMaskDC, hrgn, hBr);
- }
- else { //layerd window (WS_EX_LAYERED)
- BYTE bAlpha= 0;
- COLORREF crKey=0; //0x00bbggrr
- DWORD dwFlags=0;
- if(GetLayeredWindowAttributes(hCapture,&crKey,&bAlpha,&dwFlags)) {
- //per window transparency (like fading in a whole window).
- if((dwFlags & LWA_ALPHA) == LWA_ALPHA) {
- //Use bAlpha to determine the opacity of the layered window.
- bFixAlpha = false;
- }
- if((dwFlags & LWA_COLORKEY) == LWA_COLORKEY) {
- //Use crKey as the transparency color.
- SetBkColor(hMemDC, crKey);
- BitBlt(hMaskDC, 0, 0, size.cx, size.cy, hMemDC, 0, 0, SRCCOPY);
- bInvert = true;
- bFixAlpha = true;
+
+ if(hCapture){
+ //alpha channel from window is always wrong,
+ //coz GDI do not draw all in alpha mode.
+ //we have to create our own new alpha channel.
+ bool bFixAlpha=true;
+ bool bInvert=false;
+ HBRUSH hBr=CreateSolidBrush(RGB(255,255,255));//Create a SolidBrush object for non transparent area
+ HBITMAP hMask=CreateBitmap(size.cx,size.cy,1,1,NULL);// Create monochrome (1 bit) B+W mask bitmap.
+ HDC hMaskDC=CreateCompatibleDC(0);
+ SelectBitmap(hMaskDC,hMask);
+ HRGN hRgn=CreateRectRgn(0,0,0,0);
+ if(GetWindowRgn(hCapture,hRgn)==ERROR){
+ if((GetWindowLong(hCapture,GWL_EXSTYLE)&WS_EX_LAYERED)){
+ BYTE bAlpha=0;
+ COLORREF crKey=0;//0x00bbggrr
+ DWORD dwFlags=0;
+ if(GetLayeredWindowAttributes(hCapture,&crKey,&bAlpha,&dwFlags)) {
+ //per window transparency (like fading in a whole window).
+ if((dwFlags&LWA_COLORKEY)){
+ SetBkColor(hMemDC,crKey);
+ BitBlt(hMaskDC,0,0,size.cx,size.cy,hMemDC,0,0,SRCCOPY);
+ bInvert=true;
+ }else if((dwFlags&LWA_ALPHA)){
+ bFixAlpha=false;
+ }
+ }else{//per-pixel transparency (won't use the WM_PAINT)
+ bFixAlpha=false;
}
+ }else{//not layered - fill the window region
+ SetRectRgn(hRgn,0,0,size.cx,size.cy);
+ FillRgn(hMaskDC,hRgn,hBr);
}
- else {
- //per-pixel transparency (won't use the WM_PAINT )
- bFixAlpha = false;
- }
+ }else{
+// if(!hDC) SetRectRgn(hRgn,0,0,size.cx,size.cy);//client area only, no transparency
+ FillRgn(hMaskDC,hRgn,hBr);
}
+ DeleteObject(hRgn);
+ if(bFixAlpha){
+ FIBITMAP* dibMask = FIP->FI_CreateDIBFromHBITMAP(hMask);
+ if(bInvert) FIP->FI_Invert(dibMask);
+ FIBITMAP* dib8 = FIP->FI_ConvertTo8Bits(dibMask);
+ //copy the dib8 alpha mask to dib32 main bitmap
+ FIP->FI_SetChannel(dib,dib8,FICC_ALPHA);
+ FIP->FI_Unload(dibMask);
+ FIP->FI_Unload(dib8);
+ }
+ DeleteDC(hMaskDC);
+ DeleteObject(hMask);
+ DeleteObject(hBr);
}
- else { //fill the desktop region
- hrgn = CreateRectRgn(0,0,size.cx,size.cy);
- FillRgn(hMaskDC, hrgn, hBr);
- }
-
- if(bFixAlpha) {
- FIBITMAP* dibMask = FIP->FI_CreateDIBFromHBITMAP(hMask);
- if(bInvert) FIP->FI_Invert(dibMask);
- FIBITMAP* dib8 = FIP->FI_ConvertTo8Bits(dibMask);
-
- //copy the dib8 alpha mask to dib32 main bitmap
- FIP->FI_SetChannel(dib,dib8,FICC_ALPHA);
- FIP->FI_Unload(dibMask);
- FIP->FI_Unload(dib8);
- }
-
//clean up
- DeleteObject(hBr);
- if(hrgn) DeleteObject(hrgn);
- DeleteDC(hMaskDC);
- DeleteObject(hMask);
- SelectObject(hMemDC, hOld);
DeleteDC(hMemDC);
- if(!hDC) ReleaseDC(NULL, hScrDC);
DeleteObject(hBitmap);
+ if(!hDC) ReleaseDC(NULL, hScrDC);
#ifdef _DEBUG
switch (FIP->FI_GetImageType(dib)){