diff options
author | René Schümann <white06tiger@gmail.com> | 2014-07-01 01:07:31 +0000 |
---|---|---|
committer | René Schümann <white06tiger@gmail.com> | 2014-07-01 01:07:31 +0000 |
commit | f7df9cb6c5824f5d4b2fa66becdd3ab845d2ce83 (patch) | |
tree | 90439b0f3fcbe8baeb69191c3a5f02541c9d236e /plugins/SendScreenshotPlus | |
parent | ce8093c2344cb19ba039b8a6d2243585ef61f638 (diff) |
SendSS v0.8.7.0
* improved highlighter/finder, now stops at top-level windows and not at last owner, SHIFT/ALT also finds every child (UMainForm)
+ added compatibility option for window capture (it captures indirectly) (UMainForm,Utils,resource)
* improved tab control creation (UMainForm)
! fixed handle leak (from r9609, still causes Miranda to freeze while "editor" is open. TBD) (UMainForm)
git-svn-id: http://svn.miranda-ng.org/main/trunk@9634 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'plugins/SendScreenshotPlus')
-rw-r--r-- | plugins/SendScreenshotPlus/res/resource.rc | 1 | ||||
-rw-r--r-- | plugins/SendScreenshotPlus/src/UMainForm.cpp | 91 | ||||
-rw-r--r-- | plugins/SendScreenshotPlus/src/UMainForm.h | 1 | ||||
-rw-r--r-- | plugins/SendScreenshotPlus/src/Utils.cpp | 71 | ||||
-rw-r--r-- | plugins/SendScreenshotPlus/src/Utils.h | 2 | ||||
-rw-r--r-- | plugins/SendScreenshotPlus/src/resource.h | 1 |
6 files changed, 103 insertions, 64 deletions
diff --git a/plugins/SendScreenshotPlus/res/resource.rc b/plugins/SendScreenshotPlus/res/resource.rc index d0264dcd6c..3e249e1a2f 100644 --- a/plugins/SendScreenshotPlus/res/resource.rc +++ b/plugins/SendScreenshotPlus/res/resource.rc @@ -110,6 +110,7 @@ BEGIN RTEXT "Size (HxW):",ID_edtSizeLabel,0,30,50,8 EDITTEXT ID_edtSize,52,28,43,13,ES_CENTER | ES_AUTOHSCROLL | ES_READONLY CONTROL "C&lient Area",ID_chkClientArea,"Button",BS_AUTOCHECKBOX | BS_LEFTTEXT | WS_TABSTOP,100,30,62,8,WS_EX_RIGHT + CONTROL "indirect capture",ID_chkIndirectCapture,"Button",BS_AUTOCHECKBOX | BS_LEFTTEXT | WS_TABSTOP,96,40,75,8,WS_EX_RIGHT CTEXT "Target Tool",ID_lblDropInfo,162,1,51,8 ICON IDI_TARGET,ID_imgTarget,174,12,29,29,SS_NOTIFY | SS_CENTERIMAGE | SS_SUNKEN | WS_GROUP END diff --git a/plugins/SendScreenshotPlus/src/UMainForm.cpp b/plugins/SendScreenshotPlus/src/UMainForm.cpp index 0a818fcc57..3d75ac336f 100644 --- a/plugins/SendScreenshotPlus/src/UMainForm.cpp +++ b/plugins/SendScreenshotPlus/src/UMainForm.cpp @@ -57,7 +57,7 @@ INT_PTR CALLBACK TfrmMain::DlgProc_CaptureTabPage(HWND hDlg, UINT uMsg, WPARAM w Static_SetIcon(GetDlgItem(hDlg, ID_imgTarget), Skin_GetIcon(ICO_COMMON_SSWINDOW1)); break; } - break; + return TRUE; case WM_CTLCOLORDLG: case WM_CTLCOLOREDIT: case WM_CTLCOLORSTATIC: @@ -203,45 +203,46 @@ void TfrmMain::wmInitdialog(WPARAM wParam, LPARAM lParam) { /// create the tab control. { - TAB_INFO itab={}; - RECT rcClient, rcTab; m_hwndTab = GetDlgItem(m_hWnd, IDC_CAPTURETAB); + TabCtrl_SetImageList(m_hwndTab, m_himlTab); TabCtrl_SetItemExtra(m_hwndTab, sizeof(TAB_INFO) - sizeof(TCITEMHEADER)); - + RECT rcTab; + TAB_INFO itab; itab.hwndMain = m_hWnd; itab.hwndTab = m_hwndTab; - - GetWindowRect(m_hwndTab, &rcTab); - GetWindowRect(m_hWnd, &rcClient); - - TabCtrl_SetImageList(m_hwndTab, m_himlTab); - - /// Add a tab for each of the three child dialog boxes. itab.tcih.mask = TCIF_PARAM|TCIF_TEXT|TCIF_IMAGE; + itab.tcih.iImage = 0; + /// Add a tab for each of the three child dialog boxes. itab.tcih.pszText = TranslateT("Window"); // itab.tcih.iImage = 0; - itab.hwndTabPage = CreateDialogParam(hInst,MAKEINTRESOURCE(IDD_UMain_CaptureWindow), m_hWnd,DlgProc_CaptureTabPage,IDD_UMain_CaptureWindow); - TabCtrl_InsertItem(m_hwndTab, 0, &itab); - MoveWindow(itab.hwndTabPage, (rcTab.left - rcClient.left)+2, (rcTab.top - rcClient.top), (rcTab.right - rcTab.left) - 2*5, (rcTab.bottom - rcTab.top) - 2*20, TRUE); + itab.hwndTabPage = CreateDialogParam(hInst,MAKEINTRESOURCE(IDD_UMain_CaptureWindow),m_hWnd,DlgProc_CaptureTabPage,IDD_UMain_CaptureWindow); + TabCtrl_InsertItem(m_hwndTab,0,&itab); + /// get tab boundaries (required after 1st tab) + GetClientRect(m_hwndTab,&rcTab); + MapWindowPoints(m_hwndTab,m_hWnd,(POINT*)&rcTab,2); + TabCtrl_AdjustRect(m_hwndTab,0,&rcTab); + rcTab.bottom-=rcTab.top; rcTab.right-=rcTab.left; + /// + SetWindowPos(itab.hwndTabPage,HWND_TOP,rcTab.left,rcTab.top,rcTab.right,rcTab.bottom,0); + CheckDlgButton(itab.hwndTabPage, ID_chkIndirectCapture, m_opt_chkIndirectCapture ? BST_CHECKED : BST_UNCHECKED); CheckDlgButton(itab.hwndTabPage, ID_chkClientArea, m_opt_chkClientArea ? BST_CHECKED : BST_UNCHECKED); itab.tcih.pszText = TranslateT("Desktop"); // itab.tcih.iImage = 1; - itab.hwndTabPage = CreateDialogParam(hInst,MAKEINTRESOURCE(IDD_UMain_CaptureDesktop), m_hWnd, DlgProc_CaptureTabPage,IDD_UMain_CaptureDesktop); - TabCtrl_InsertItem(m_hwndTab, 1, &itab); - MoveWindow(itab.hwndTabPage, (rcTab.left - rcClient.left)+2, (rcTab.top - rcClient.top), (rcTab.right - rcTab.left) - 2*5, (rcTab.bottom - rcTab.top) - 2*20, TRUE); + itab.hwndTabPage = CreateDialogParam(hInst,MAKEINTRESOURCE(IDD_UMain_CaptureDesktop),m_hWnd,DlgProc_CaptureTabPage,IDD_UMain_CaptureDesktop); + TabCtrl_InsertItem(m_hwndTab,1,&itab); + SetWindowPos(itab.hwndTabPage,HWND_TOP,rcTab.left,rcTab.top,rcTab.right,rcTab.bottom,0); hCtrl = GetDlgItem(itab.hwndTabPage, ID_edtCaption); ComboBox_ResetContent(hCtrl); ComboBox_SetItemData(hCtrl, ComboBox_AddString(hCtrl, TranslateT("<Entire Desktop>")) ,0); ComboBox_SetCurSel (hCtrl,0); if(m_MonitorCount >1) { - TCHAR tszTemp[120]; - for (size_t mon=0; mon<m_MonitorCount; ++mon) { /// @todo : fix format for non MSVC compilers + TCHAR tszTemp[120]; + for(size_t mon=0; mon<m_MonitorCount; ++mon) { /// @todo : fix format for non MSVC compilers mir_sntprintf(tszTemp, SIZEOF(tszTemp),_T("%Iu. %s%s"), - mon+1, - TranslateT("Monitor"), + mon+1, TranslateT("Monitor"), (m_Monitors[mon].dwFlags & MONITORINFOF_PRIMARY) ? TranslateT(" (primary)") : _T("") ); ComboBox_SetItemData(hCtrl, ComboBox_AddString(hCtrl, tszTemp) , mon+1); @@ -252,9 +253,9 @@ void TfrmMain::wmInitdialog(WPARAM wParam, LPARAM lParam) { itab.tcih.pszText = TranslateT("File"); // itab.tcih.iImage = 2; - itab.hwndTabPage = CreateDialogParam(hInst,MAKEINTRESOURCE(IDD_UMain_CaptureFile), m_hWnd, DlgProc_CaptureTabPage,IDD_UMain_CaptureFile); - TabCtrl_InsertItem(m_hwndTab, 2, &itab); - MoveWindow(itab.hwndTabPage, (rcTab.left - rcClient.left)+2, (rcTab.top - rcClient.top), (rcTab.right - rcTab.left) - 2*5, (rcTab.bottom - rcTab.top) - 2*20, TRUE); + itab.hwndTabPage = CreateDialogParam(hInst,MAKEINTRESOURCE(IDD_UMain_CaptureFile),m_hWnd,DlgProc_CaptureTabPage,IDD_UMain_CaptureFile); + TabCtrl_InsertItem(m_hwndTab,2,&itab); + SetWindowPos(itab.hwndTabPage,HWND_TOP,rcTab.left,rcTab.top,rcTab.right,rcTab.bottom,0); /// select tab and set m_hwndTabPage TabCtrl_SetCurSel(m_hwndTab, m_opt_tabCapture); @@ -385,6 +386,9 @@ void TfrmMain::wmCommand(WPARAM wParam, LPARAM lParam) { m_opt_chkTimed = (BYTE)Button_GetCheck((HWND)lParam); TfrmMain::chkTimedClick(); break; + case ID_chkIndirectCapture: + m_opt_chkIndirectCapture = (BYTE)Button_GetCheck((HWND)lParam); + break; case ID_chkClientArea: m_opt_chkClientArea = (BYTE)Button_GetCheck((HWND)lParam); if(m_hTargetWindow) @@ -392,7 +396,7 @@ void TfrmMain::wmCommand(WPARAM wParam, LPARAM lParam) { break; case ID_imgTarget: if(m_opt_tabCapture!=0) break; - m_hLastWin=0; + m_hLastWin=NULL; SetTimer(m_hWnd,ID_imgTarget,BUTTON_POLLDELAY,NULL); break; case ID_btnAbout: @@ -439,7 +443,7 @@ void TfrmMain::wmCommand(WPARAM wParam, LPARAM lParam) { break; case ID_edtCaption: //cboxDesktopChange m_opt_cboxDesktop = (BYTE)ComboBox_GetItemData((HWND)lParam, ComboBox_GetCurSel((HWND)lParam)); - m_hTargetWindow = 0; + m_hTargetWindow = NULL; if (m_opt_cboxDesktop > 0) { edtSizeUpdate(m_Monitors[m_opt_cboxDesktop-1].rcMonitor, GetParent((HWND)lParam), ID_edtSize); } @@ -513,24 +517,29 @@ void TfrmMain::wmTimer(WPARAM wParam, LPARAM lParam){ KillTimer(m_hWnd,ID_imgTarget); SystemParametersInfo(SPI_SETCURSORS,0,NULL,0); DestroyWindow(m_hTargetHighlighter),m_hTargetHighlighter=NULL; - SetTargetWindow(m_hTargetWindow); + SetTargetWindow(m_hLastWin); Show(); return; } POINT point; GetCursorPos(&point); - m_hTargetWindow=WindowFromPoint(point); + HWND hwnd=WindowFromPoint(point); if(!((GetAsyncKeyState(VK_SHIFT)|GetAsyncKeyState(VK_MENU))&0x8000)) - for(HWND hTMP; (hTMP=GetParent(m_hTargetWindow)); m_hTargetWindow=hTMP); - if(m_hTargetWindow!=m_hLastWin){ - m_hLastWin=m_hTargetWindow; + for(HWND hTMP; (hTMP=GetAncestor(hwnd,GA_PARENT)) && IsChild(hTMP,hwnd); hwnd=hTMP); + else{ + ScreenToClient(hwnd,&point); + HWND hTMP; if((hTMP=RealChildWindowFromPoint(hwnd,point))) + hwnd=hTMP; + } + if(hwnd!=m_hLastWin){ + m_hLastWin=hwnd; RECT rect; if(m_opt_chkClientArea){ - GetClientRect(m_hLastWin,&rect); - ClientToScreen(m_hLastWin,(POINT*)&rect); + GetClientRect(hwnd,&rect); + ClientToScreen(hwnd,(POINT*)&rect); rect.right=rect.left+rect.right; rect.bottom=rect.top+rect.bottom; }else - GetWindowRect(m_hLastWin,&rect); + GetWindowRect(hwnd,&rect); int width=rect.right-rect.left; int height=rect.bottom-rect.top; if(g_iTargetBorder){ @@ -559,7 +568,7 @@ void TfrmMain::wmTimer(WPARAM wParam, LPARAM lParam){ m_bCapture = true; switch (m_opt_tabCapture) { case 0: - m_Screenshot = CaptureWindow(m_hTargetWindow, m_opt_chkClientArea); + m_Screenshot = CaptureWindow(m_hTargetWindow, m_opt_chkClientArea, m_opt_chkIndirectCapture); break; case 1: m_Screenshot = CaptureMonitor((m_opt_cboxDesktop > 0) ? m_Monitors[m_opt_cboxDesktop-1].szDevice : NULL); @@ -648,7 +657,6 @@ void TfrmMain::UMevent(WPARAM wParam, LPARAM lParam) { FIP->FI_Unload(m_Screenshot); m_Screenshot = NULL; } - /* m_hTargetWindow = */m_hLastWin = NULL; Show(); }else{ // Saving Options and close @@ -712,6 +720,7 @@ void TfrmMain::LoadOptions(void) { m_opt_edtQuality = db_get_b(NULL, SZ_SENDSS, "JpegQuality", 75); m_opt_tabCapture = db_get_b(NULL, SZ_SENDSS, "Capture", 0); + m_opt_chkIndirectCapture = db_get_b(NULL, SZ_SENDSS, "IndirectCapture", 0); m_opt_chkClientArea = db_get_b(NULL, SZ_SENDSS, "ClientArea", 0); m_opt_cboxDesktop = db_get_b(NULL, SZ_SENDSS, "Desktop", 0); @@ -735,6 +744,7 @@ void TfrmMain::SaveOptions(void) { db_set_b(NULL, SZ_SENDSS, "JpegQuality", m_opt_edtQuality); db_set_b(NULL, SZ_SENDSS, "Capture", m_opt_tabCapture); + db_set_b(NULL, SZ_SENDSS, "IndirectCapture", m_opt_chkIndirectCapture); db_set_b(NULL, SZ_SENDSS, "ClientArea", m_opt_chkClientArea); db_set_b(NULL, SZ_SENDSS, "Desktop", m_opt_cboxDesktop); @@ -795,7 +805,7 @@ void TfrmMain::btnCaptureClick() { return; } if(m_opt_tabCapture!=2){ - m_Screenshot = CaptureWindow(m_hTargetWindow, m_opt_chkClientArea); + m_Screenshot = CaptureWindow(m_hTargetWindow, m_opt_chkClientArea, m_opt_chkIndirectCapture); } SendMessage(m_hWnd,UM_EVENT, 0, (LPARAM)EVT_CaptureDone); } @@ -1115,12 +1125,15 @@ void TfrmMain::FormClose() { bool send=true; if(m_opt_chkEditor){ SHELLEXECUTEINFO shex={sizeof(SHELLEXECUTEINFO)}; - shex.fMask=SEE_MASK_NOCLOSEPROCESS|SEE_MASK_NOASYNC; + shex.fMask=SEE_MASK_NOCLOSEPROCESS; shex.lpVerb=_T("edit"); shex.lpFile=m_pszFile; shex.nShow=SW_SHOWNORMAL; ShellExecuteEx(&shex); - WaitForSingleObject(shex.hProcess,INFINITE); + if(shex.hProcess){ + WaitForSingleObject(shex.hProcess,INFINITE); + CloseHandle(shex.hProcess); + } if(MessageBoxA(m_hWnd,"Send screenshot?","SendSS",MB_YESNO|MB_ICONQUESTION|MB_SYSTEMMODAL)!=IDYES) send=false; } diff --git a/plugins/SendScreenshotPlus/src/UMainForm.h b/plugins/SendScreenshotPlus/src/UMainForm.h index c9969234cb..8e3d0400e2 100644 --- a/plugins/SendScreenshotPlus/src/UMainForm.h +++ b/plugins/SendScreenshotPlus/src/UMainForm.h @@ -113,6 +113,7 @@ class TfrmMain{ RECT m_VirtualScreen; BYTE m_opt_chkOpenAgain; //TCheckBox *chkOpenAgain; + BYTE m_opt_chkIndirectCapture; //TCheckBox *chkIndirectCapture; BYTE m_opt_chkClientArea; //TCheckBox *chkClientArea; BYTE m_opt_edtQuality; //TLabeledEdit *edtQuality; bool m_opt_btnDeleteAfterSend; //TCheckBox *chkDeleteAfterSend; diff --git a/plugins/SendScreenshotPlus/src/Utils.cpp b/plugins/SendScreenshotPlus/src/Utils.cpp index fdfb29f24e..5c4cdc8162 100644 --- a/plugins/SendScreenshotPlus/src/Utils.cpp +++ b/plugins/SendScreenshotPlus/src/Utils.cpp @@ -73,43 +73,66 @@ BOOL CALLBACK MonitorInfoEnumProc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprc //--------------------------------------------------------------------------- // capture window as FIBITMAP - caller must FIP->FI_Unload(dib) -FIBITMAP* CaptureWindow (HWND hCapture, BOOL ClientArea) { +FIBITMAP* CaptureWindow (HWND hCapture, BOOL bClientArea, BOOL bIndirectCapture) { FIBITMAP *dib; HWND hForegroundWin; HDC hScrDC; // screen DC - RECT rect; // screen RECT + RECT rect; // screen RECT SIZE size; // DIB width and height = window resolution if (!hCapture || !IsWindow(hCapture)) return 0; hForegroundWin = GetForegroundWindow(); //Saving foreground window SetForegroundWindow(hCapture); // Make sure the target window is the foreground one BringWindowToTop(hCapture); // bring it to top as well - // redraw window to prevent runtime artifacts in picture + /// redraw window to prevent runtime artifacts in picture UpdateWindow(hCapture); - 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){//we could capture directly, but doing so breaks GetWindowRgn() and also includes artifacts... - RECT rectCA = {0}; - POINT pt = {0}; - GetClientRect (hCapture, &rectCA); - ClientToScreen(hCapture, &pt); - //crop the window to ClientArea - FIBITMAP* dibClient = FIP->FI_Copy(dib, - pt.x - rect.left, - pt.y - rect.top, - pt.x - rect.left + rectCA.right, - pt.y - rect.top + rectCA.bottom); + if(bIndirectCapture){ + intptr_t wastopmost=GetWindowLongPtr(hCapture,GWL_EXSTYLE)&WS_EX_TOPMOST; + if(!wastopmost) + SetWindowPos(hCapture,HWND_TOPMOST,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE); + hScrDC = GetDC(NULL); /*Get full virtualscreen*/ + size.cx = GetSystemMetrics(SM_CXVIRTUALSCREEN); + size.cy = GetSystemMetrics(SM_CYVIRTUALSCREEN); + dib = CaptureScreen(hScrDC,size); + ReleaseDC(hCapture,hScrDC); + if(bClientArea){ + GetClientRect(hCapture,&rect); + ClientToScreen(hCapture,(POINT*)&rect); + rect.right+=rect.left; rect.bottom+=rect.top; + }else + GetWindowRect(hCapture,&rect); + if(rect.left<0) rect.left=0; + if(rect.top<0) rect.top=0; + if(rect.right>(long)FIP->FI_GetWidth(dib)) rect.right=FIP->FI_GetWidth(dib); + if(rect.bottom>(long)FIP->FI_GetHeight(dib)) rect.bottom=FIP->FI_GetHeight(dib); + /// crop the window to ClientArea + FIBITMAP* dibClient = FIP->FI_Copy(dib,rect.left,rect.top,rect.right,rect.bottom); FIP->FI_Unload(dib); dib = dibClient; + if(!wastopmost) + SetWindowPos(hCapture,HWND_NOTOPMOST,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE); + }else{ + GetWindowRect(hCapture,&rect); + if(GetAncestor(hCapture,GA_PARENT)) + 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(bClientArea){//we could capture directly, but doing so breaks GetWindowRgn() and also includes artifacts... + RECT rectCA; GetClientRect(hCapture,&rectCA); + ClientToScreen(hCapture,(POINT*)&rectCA); + rectCA.left-=rect.left; rectCA.top-=rect.top; + rectCA.right+=rectCA.left; rectCA.bottom+=rectCA.top; + /// crop the window to ClientArea + FIBITMAP* dibClient = FIP->FI_Copy(dib,rectCA.left,rectCA.top,rectCA.right,rectCA.bottom); + FIP->FI_Unload(dib); + dib = dibClient; + } } if(hForegroundWin){//restore previous foreground window SetForegroundWindow(hForegroundWin); diff --git a/plugins/SendScreenshotPlus/src/Utils.h b/plugins/SendScreenshotPlus/src/Utils.h index 59e456bde3..9fed8a737d 100644 --- a/plugins/SendScreenshotPlus/src/Utils.h +++ b/plugins/SendScreenshotPlus/src/Utils.h @@ -49,7 +49,7 @@ int ComboBox_SelectItemData(HWND hwndCtl, int indexStart, LPARAM data); size_t MonitorInfoEnum(MONITORINFOEX* & myMonitors, RECT & virtualScreen); BOOL CALLBACK MonitorInfoEnumProc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData); -FIBITMAP* CaptureWindow(HWND hCapture, BOOL ClientArea); +FIBITMAP* CaptureWindow(HWND hCapture, BOOL bClientArea, BOOL bIndirectCapture); FIBITMAP* CaptureMonitor(TCHAR* szDevice); FIBITMAP* CaptureScreen(HDC hDC, SIZE size, HWND hCapture=0); //FIBITMAP* CaptureDesktop(); /*emulate print screen (not used)*/ diff --git a/plugins/SendScreenshotPlus/src/resource.h b/plugins/SendScreenshotPlus/src/resource.h index 9fb928481b..b2ba2ef4c5 100644 --- a/plugins/SendScreenshotPlus/src/resource.h +++ b/plugins/SendScreenshotPlus/src/resource.h @@ -86,6 +86,7 @@ #define ID_gboxOptions 1603 #define ID_chkEditor 1701 #define ID_chkClientArea 1704 +#define ID_chkIndirectCapture 1705 #define ID_chkTimed 1708 #define ID_chkOpenAgain 1710 #define IDC_HEADERBAR 1734 |