mirror of
https://github.com/duilib/duilib.git
synced 2026-10-18 23:00:38 +08:00
02d1ed8832
2、修正了若干bug
301 lines
9.4 KiB
C++
301 lines
9.4 KiB
C++
#include "StdAfx.h"
|
|
#include "ScrCaptureWnd.h"
|
|
#include "Canvas.h"
|
|
#include "CanvasContainer.h"
|
|
#include "Util.h"
|
|
|
|
CScrCaptureWnd* CScrCaptureWnd::m_pInstance = NULL;
|
|
|
|
class CDialogBuilderCallbackEx : public IDialogBuilderCallback
|
|
{
|
|
public:
|
|
CControlUI* CreateControl(LPCTSTR pstrClass)
|
|
{
|
|
if( _tcscmp(pstrClass, DUI_CTR_CANVAS) == 0 ) return new CCanvasUI;
|
|
else if( _tcscmp(pstrClass, DUI_CTR_CANVASCONTAINER) == 0 ) return new CCanvasContainerUI;
|
|
return NULL;
|
|
}
|
|
};
|
|
|
|
CScrCaptureWnd::CScrCaptureWnd() : m_hEditMenu(NULL), m_bClipChoiced(false)
|
|
{
|
|
m_ptClipBasePoint.x = m_ptClipBasePoint.y = 0;
|
|
::ZeroMemory(&m_rcWindow, sizeof(m_rcWindow));
|
|
::ZeroMemory(&m_rcClipPadding, sizeof(m_rcClipPadding));
|
|
::ZeroMemory(m_sClipDrawStringBuf, sizeof(m_sClipDrawStringBuf));
|
|
};
|
|
|
|
CScrCaptureWnd::~CScrCaptureWnd()
|
|
{
|
|
::DestroyMenu(m_hEditMenu);
|
|
}
|
|
|
|
CScrCaptureWnd* CScrCaptureWnd::Instance()
|
|
{
|
|
if (m_pInstance == NULL) m_pInstance = new CScrCaptureWnd;
|
|
return m_pInstance;
|
|
}
|
|
|
|
LPCTSTR CScrCaptureWnd::GetWindowClassName() const
|
|
{
|
|
return _T("UIScrCaptureFrame");
|
|
}
|
|
|
|
UINT CScrCaptureWnd::GetClassStyle() const
|
|
{
|
|
return UI_CLASSSTYLE_DIALOG | CS_DBLCLKS;
|
|
}
|
|
|
|
void CScrCaptureWnd::OnFinalMessage(HWND /*hWnd*/)
|
|
{
|
|
delete this;
|
|
};
|
|
|
|
void CScrCaptureWnd::Init()
|
|
{
|
|
m_hEditMenu = ::CreatePopupMenu();
|
|
::AppendMenu(m_hEditMenu, MF_STRING, MENUCMD_ADDRECTANGE, _T("添加矩形"));
|
|
::AppendMenu(m_hEditMenu, MF_STRING, MENUCMD_ADDELLIPSE, _T("添加椭圆"));
|
|
::AppendMenu(m_hEditMenu, MF_STRING, MENUCMD_ADDARROW, _T("添加箭头"));
|
|
::AppendMenu(m_hEditMenu, MF_STRING, MENUCMD_ADDBRUSH, _T("添加画刷工具"));
|
|
::AppendMenu(m_hEditMenu, MF_STRING, MENUCMD_ADDTEXT, _T("添加文字"));
|
|
::AppendMenu(m_hEditMenu, MF_STRING, MENUCMD_UNDO, _T("撤销编辑"));
|
|
::AppendMenu(m_hEditMenu, MF_SEPARATOR, 0, NULL);
|
|
::AppendMenu(m_hEditMenu, MF_STRING, MENUCMD_RECHOICE, _T("重新选择截图区域"));
|
|
::AppendMenu(m_hEditMenu, MF_STRING, MENUCMD_SAVEANDQUIT, _T("复制并退出截图"));
|
|
::AppendMenu(m_hEditMenu, MF_STRING, MENUCMD_SAVE, _T("保存"));
|
|
::AppendMenu(m_hEditMenu, MF_SEPARATOR, 0, NULL);
|
|
::AppendMenu(m_hEditMenu, MF_STRING, MENUCMD_HIDETOOLBAR, _T("隐藏编辑工具栏"));
|
|
::AppendMenu(m_hEditMenu, MF_STRING, MENUCMD_QUIT, _T("退出截屏"));
|
|
|
|
m_pDesktopImage = m_pm.FindControl(_T("desktopimage"));
|
|
m_pDesktopMask = m_pm.FindControl(_T("desktopmask"));
|
|
m_pDesktopMaskBorder = m_pm.FindControl(_T("desktopmaskborder"));
|
|
m_pDesktopCanvasContainer = static_cast<CContainerUI*>(m_pm.FindControl(_T("desktopcanvascontainer")));
|
|
if (m_pDesktopImage == NULL || m_pDesktopMask == NULL ||
|
|
m_pDesktopMaskBorder == NULL || m_pDesktopCanvasContainer == NULL) ::PostQuitMessage(0L);
|
|
|
|
::GetWindowRect(::GetDesktopWindow(), &m_rcWindow);
|
|
::SetWindowPos(GetHWND(), NULL, m_rcWindow.left, m_rcWindow.top, m_rcWindow.right-m_rcWindow.left, m_rcWindow.bottom-m_rcWindow.top, SWP_NOZORDER);
|
|
|
|
HBITMAP hDesktopBmp = CreateDesktopBitmap(GetHWND());
|
|
m_pm.AddImage(_T("desktopimage"), hDesktopBmp, m_rcWindow.right-m_rcWindow.left, m_rcWindow.bottom-m_rcWindow.top, false);
|
|
HBITMAP hDesktopBmpMask = CreateDesktopMaskBitmap(GetHWND());
|
|
m_pm.AddImage(_T("desktopimagemask"), hDesktopBmpMask, m_rcWindow.right-m_rcWindow.left, m_rcWindow.bottom-m_rcWindow.top, true);
|
|
|
|
m_pDesktopImage->SetBkImage(_T("desktopimage"));
|
|
m_pDesktopMask->SetBkImage(_T("desktopimagemask"));
|
|
}
|
|
|
|
void CScrCaptureWnd::OnPrepare()
|
|
{
|
|
}
|
|
|
|
void CScrCaptureWnd::Notify(TNotifyUI& msg)
|
|
{
|
|
if( msg.sType == _T("windowinit") ) {
|
|
OnPrepare();
|
|
}
|
|
else if( msg.sType == _T("click") ) {
|
|
}
|
|
}
|
|
|
|
RECT CScrCaptureWnd::GetWindowRect() const
|
|
{
|
|
return m_rcWindow;
|
|
}
|
|
|
|
RECT CScrCaptureWnd::GetClipPadding() const
|
|
{
|
|
return m_rcClipPadding;
|
|
}
|
|
|
|
void CScrCaptureWnd::SetClipPadding(RECT rc) {
|
|
m_rcClipPadding = rc;
|
|
_stprintf_s(m_sClipDrawStringBuf, MAX_PATH - 1, _T("file='desktopimagemask' scale9='%d,%d,%d,%d' hole='true'"),
|
|
m_rcClipPadding.left, m_rcClipPadding.top, m_rcClipPadding.right, m_rcClipPadding.bottom);
|
|
m_pDesktopMask->SetBkImage(m_sClipDrawStringBuf);
|
|
m_pDesktopMaskBorder->SetPos(GetClipRect());
|
|
m_pDesktopCanvasContainer->SetPos(GetCanvasContainerRect());
|
|
}
|
|
|
|
RECT CScrCaptureWnd::GetClipRect() const
|
|
{
|
|
RECT rc = m_rcClipPadding;
|
|
rc.left = rc.left+m_rcWindow.left;
|
|
rc.top = rc.top+m_rcWindow.top;
|
|
rc.right = m_rcWindow.right-rc.right;
|
|
rc.bottom = m_rcWindow.bottom-rc.bottom;
|
|
return rc;
|
|
}
|
|
|
|
RECT CScrCaptureWnd::GetCanvasContainerRect() const
|
|
{
|
|
RECT rcInset = m_pDesktopCanvasContainer->GetInset();
|
|
RECT rc = m_rcClipPadding;
|
|
rc.left = rc.left+m_rcWindow.left-rcInset.left;
|
|
rc.top = rc.top+m_rcWindow.top-rcInset.left;
|
|
rc.right = m_rcWindow.right-rc.right+rcInset.left;
|
|
rc.bottom = m_rcWindow.bottom-rc.bottom+rcInset.left;
|
|
return rc;
|
|
}
|
|
|
|
LRESULT CScrCaptureWnd::MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, bool& bHandled)
|
|
{
|
|
if( uMsg == WM_KEYDOWN ) {
|
|
if( wParam == VK_ESCAPE ) {
|
|
PostQuitMessage(0);
|
|
return true;
|
|
}
|
|
|
|
}
|
|
return false;
|
|
}
|
|
|
|
LRESULT CScrCaptureWnd::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
if( uMsg == WM_CREATE ) {
|
|
m_pm.Init(m_hWnd);
|
|
m_pm.AddPreMessageFilter(this);
|
|
CDialogBuilder builder;
|
|
CDialogBuilderCallbackEx cb;
|
|
CControlUI* pRoot = builder.Create(_T("ScrCapture.xml"), (UINT)0, &cb, &m_pm);
|
|
ASSERT(pRoot && "Failed to parse XML");
|
|
m_pm.AttachDialog(pRoot);
|
|
m_pm.AddNotifier(this);
|
|
Init();
|
|
return 0;
|
|
}
|
|
else if( uMsg == WM_DESTROY ) {
|
|
::PostQuitMessage(0L);
|
|
}
|
|
else if(uMsg == WM_LBUTTONDOWN) {
|
|
if (!m_bClipChoiced) {
|
|
m_pDesktopCanvasContainer->SetEnabled(false);
|
|
m_ptClipBasePoint.x = GET_X_LPARAM(lParam);
|
|
m_ptClipBasePoint.y = GET_Y_LPARAM(lParam);
|
|
return 0;
|
|
}
|
|
}
|
|
else if(uMsg == WM_LBUTTONUP) {
|
|
if (!m_bClipChoiced) {
|
|
m_bClipChoiced = true;
|
|
m_pDesktopMaskBorder->SetVisible(false);
|
|
m_pDesktopCanvasContainer->SetVisible(true);
|
|
m_pDesktopCanvasContainer->SetEnabled(true);
|
|
SetClipPadding(m_rcClipPadding);
|
|
return 0;
|
|
}
|
|
else {
|
|
|
|
}
|
|
}
|
|
else if(uMsg == WM_LBUTTONDBLCLK) {
|
|
// todo:完成截图,保存到剪贴板
|
|
m_bClipChoiced = true;
|
|
::PostQuitMessage(0L);
|
|
return 0;
|
|
}
|
|
else if(uMsg == WM_RBUTTONUP) {
|
|
if (m_bClipChoiced) {
|
|
POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
|
|
RECT rcClipRect = GetClipRect();
|
|
if (::PtInRect(&rcClipRect, pt)) {
|
|
::ClientToScreen(m_hWnd, &pt);
|
|
::TrackPopupMenu(m_hEditMenu, TPM_TOPALIGN, pt.x, pt.y, 0, m_hWnd, NULL);
|
|
::PostMessage(m_hWnd, WM_NULL, 0, 0);
|
|
}
|
|
else {
|
|
m_bClipChoiced = false;
|
|
m_pDesktopCanvasContainer->SetEnabled(false);
|
|
::SendMessage(m_hWnd, WM_MOUSEMOVE, 0, MAKELPARAM(pt.x, pt.y));
|
|
}
|
|
}
|
|
else {
|
|
// 退出截图
|
|
::PostQuitMessage(0L);
|
|
}
|
|
return 0;
|
|
}
|
|
else if(uMsg == WM_MOUSEMOVE) {
|
|
if (!m_bClipChoiced) {
|
|
if( ::GetKeyState(VK_LBUTTON) < 0 ) { // 左键按下状态
|
|
if (m_ptClipBasePoint.x != GET_X_LPARAM(lParam) || m_ptClipBasePoint.y != GET_Y_LPARAM(lParam)) {
|
|
m_rcClipPadding.left = min(GET_X_LPARAM(lParam), m_ptClipBasePoint.x)-m_rcWindow.left; if (m_rcClipPadding.left < 0) m_rcClipPadding.left = 0;
|
|
m_rcClipPadding.top = min(GET_Y_LPARAM(lParam), m_ptClipBasePoint.y)-m_rcWindow.top; if (m_rcClipPadding.top < 0) m_rcClipPadding.top = 0;
|
|
m_rcClipPadding.right = m_rcWindow.right-max(GET_X_LPARAM(lParam), m_ptClipBasePoint.x); if (m_rcClipPadding.right < 0) m_rcClipPadding.right = 0;
|
|
m_rcClipPadding.bottom = m_rcWindow.bottom-max(GET_Y_LPARAM(lParam), m_ptClipBasePoint.y); if (m_rcClipPadding.bottom < 0) m_rcClipPadding.bottom = 0;
|
|
m_pDesktopMaskBorder->SetVisible(false);
|
|
m_pDesktopCanvasContainer->SetVisible(true);
|
|
SetClipPadding(m_rcClipPadding);
|
|
}
|
|
}
|
|
else {
|
|
RECT rc;
|
|
HWND hWnd;
|
|
::EnableWindow(m_hWnd, FALSE);
|
|
hWnd = SmallestWindowFromCursor(rc);
|
|
::EnableWindow(m_hWnd, TRUE);
|
|
::SetFocus(m_hWnd);
|
|
rc.left = rc.left-m_rcWindow.left; if (rc.left < 0) rc.left = 0;
|
|
rc.top = rc.top-m_rcWindow.top; if (rc.top < 0) rc.top = 0;
|
|
rc.right = m_rcWindow.right-rc.right; if (rc.right < 0) rc.right = 0;
|
|
rc.bottom = m_rcWindow.bottom-rc.bottom; if (rc.bottom < 0) rc.bottom = 0;
|
|
if (rc.left != m_rcClipPadding.left || rc.right != m_rcClipPadding.right || rc.top != m_rcClipPadding.top || rc.bottom != m_rcClipPadding.bottom) {
|
|
SetClipPadding(rc);
|
|
m_pDesktopMaskBorder->SetVisible(true);
|
|
m_pDesktopCanvasContainer->SetVisible(false);
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
|
|
}
|
|
}
|
|
else if(uMsg == WM_COMMAND) {
|
|
switch (LOWORD(wParam))
|
|
{
|
|
case MENUCMD_ADDRECTANGE:
|
|
return 0;
|
|
case MENUCMD_ADDELLIPSE:
|
|
return 0;
|
|
case MENUCMD_ADDARROW:
|
|
return 0;
|
|
case MENUCMD_ADDBRUSH:
|
|
return 0;
|
|
case MENUCMD_ADDTEXT:
|
|
return 0;
|
|
case MENUCMD_UNDO:
|
|
return 0;
|
|
case MENUCMD_RECHOICE:
|
|
{
|
|
m_bClipChoiced = false;
|
|
m_pDesktopCanvasContainer->SetEnabled(false);
|
|
POINT pt;
|
|
::GetCursorPos(&pt);
|
|
::SendMessage(m_hWnd, WM_MOUSEMOVE, 0, MAKELPARAM(pt.x, pt.y));
|
|
}
|
|
return 0;
|
|
case MENUCMD_SAVEANDQUIT:
|
|
{
|
|
// todo:
|
|
PostQuitMessage(0L);
|
|
}
|
|
return 0;
|
|
case MENUCMD_SAVE:
|
|
{
|
|
// todo:弹出保存对话框
|
|
}
|
|
return 0;
|
|
case MENUCMD_HIDETOOLBAR:
|
|
return 0;
|
|
case MENUCMD_QUIT:
|
|
PostQuitMessage(0L);
|
|
return 0;
|
|
}
|
|
}
|
|
LRESULT lRes = 0;
|
|
if( m_pm.MessageHandler(uMsg, wParam, lParam, lRes) ) return lRes;
|
|
return CWindowWnd::HandleMessage(uMsg, wParam, lParam);
|
|
}
|