📄 scemfinspectdlg.cpp
字号:
/*
* This file is part of the EMFexplorer projet.
* Copyright (C) 2004 Smith Charles.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*
* Extension: for commercial use, apply the Equity Public License, which
* adds to the normal terms of the GLPL a condition of donation to the author.
* If you are interested in support for this source code,
* contact Smith Charles <smith.charles@free.fr> for more information.
*/
#include "stdafx.h"
#include "SCEMFInspectDlg.h"
#include "SCGenInclude.h"
#include SC_INC_WINLIB(SCWinGUI.h)
#include SC_INC_EMFLIB(SCEMF.h)
#include SC_INC_EMFLIB(SCEMFDoc.h)
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define SC_SPACE_X 10
#define SC_SPACE_Y 10
#define SC_NO_HSCROLL 1
#define SC_XMARGIN 72 // twips
#define SC_FIRSTLINE_INDENT SC_XMARGIN // twips
#define SC_PARA_TAB0 3*1440 // twips
#define SC_PARA_TAB1 (SC_PARA_TAB0 + 1440/4)
#define SC_PARA_INDENT SC_PARA_TAB1
#define SC_RIGHT_INDENT 72 // twips
/////////////////////////////////////////////////////////////////////////////
// CSCEMFInspectDlg dialog
CSCEMFInspectDlg::CSCEMFInspectDlg(CWnd* pParent /*=NULL*/)
: CDialog(CSCEMFInspectDlg::IDD, pParent),
m_bDestroyed(FALSE),
m_hEmf(NULL)
{
//{{AFX_DATA_INIT(CSCEMFInspectDlg)
m_EdBrkCount = _T("");
m_strDPI = _T("");
m_strSize = _T("");
//}}AFX_DATA_INIT
m_bStopBrk = FALSE;
m_nMaxBrkPos = 0;
m_bCracking = FALSE;
}
// auto-reset event to signal that the control has returned from breakmetafile;
// starts out not signaled
HANDLE g_hCrackerDead = CreateEvent(NULL, FALSE, FALSE, NULL);
// auto-reset event to signal that breakmetafile is requested to stop;
// starts out not signaled
HANDLE g_hEmergencyQuit = CreateEvent(NULL, FALSE, FALSE, NULL);
CSCEMFInspectDlg::~CSCEMFInspectDlg()
{
if (m_bCracking)
{
m_bStopBrk = TRUE;
m_bDestroyed = TRUE;
SetEvent(g_hEmergencyQuit);
while (WaitForSingleObject(g_hCrackerDead, 0) == WAIT_TIMEOUT)
{
SCYieldForAWhile();
}
}
}
void CSCEMFInspectDlg::OnDestroy()
{
CDialog::OnDestroy();
}
void CSCEMFInspectDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CSCEMFInspectDlg)
DDX_Control(pDX, IDC_PROGRESS_BRK, m_Progress);
DDX_Text(pDX, IDC_EDIT_BRKCOUNT, m_EdBrkCount);
DDX_Text(pDX, IDC_EDIT_DPI, m_strDPI);
DDX_Text(pDX, IDC_EDIT_SIZE, m_strSize);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CSCEMFInspectDlg, CDialog)
//{{AFX_MSG_MAP(CSCEMFInspectDlg)
ON_WM_SIZE()
ON_WM_CLOSE()
ON_WM_TIMER()
ON_BN_CLICKED(IDC_BTN_STOPBRK, OnBtnStopbrk)
ON_WM_DESTROY()
ON_BN_CLICKED(IDC_BTN_SAVERTF, OnBtnSaveRTF)
ON_BN_CLICKED(IDC_BTN_COPYALL, OnBtnCopyAll)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
SC_IMPLEMENT_ENABLE_CONTROL(CSCEMFInspectDlg)
/////////////////////////////////////////////////////////////////////////////
// CSCEMFInspectDlg support methods
void CSCEMFInspectDlg::OnSize(UINT nType, int cx, int cy)
{
CDialog::OnSize(nType, cx, cy);
// Add your message handler code here
SCRelocateControls();
}
void CSCEMFInspectDlg::SCRelocateControls()
{
if (!IsWindow(m_EdEMFContent.m_hWnd))
return;
CRect rect;
GetClientRect(rect);
// EMF edit
CRect rect1;
CWnd *pWnd;
//stop button
pWnd=GetDlgItem(IDC_BTN_STOPBRK);
if (pWnd)
{
pWnd->GetWindowRect(&rect1);
ScreenToClient(rect1);
rect1.left = rect.left;
pWnd->MoveWindow(rect1);
}
//progress
m_Progress.GetWindowRect(&rect1);
ScreenToClient(rect1);
rect1.right = rect.right;
m_Progress.MoveWindow(rect1);
//EMF edit
rect.top = rect1.bottom + SC_SPACE_Y;
m_EdEMFContent.MoveWindow(rect);
PARAFORMAT2 pf;
memset(&pf, 0, sizeof(pf));
pf.cbSize = sizeof(pf);
pf.dxStartIndent = SC_FIRSTLINE_INDENT;
pf.dxOffset = SC_PARA_INDENT;
pf.dxRightIndent = SC_RIGHT_INDENT;
pf.dwMask = PFM_OFFSETINDENT | PFM_OFFSET | PFM_RIGHTINDENT;
pf.dwMask |= PFM_TABSTOPS;
pf.cTabCount = 2;
pf.rgxTabs[0] = SC_PARA_TAB0;
pf.rgxTabs[1] = SC_PARA_TAB1;
m_EdEMFContent.SetParaFormat(pf);
#if SC_NO_HSCROLL
HDC hTargetDC = ::CreateCompatibleDC(NULL);
HBITMAP hbm = ::CreateCompatibleBitmap(hTargetDC, rect.Width(), rect.Height());
HBITMAP hOldBm = (HBITMAP)SelectObject(hTargetDC, hbm);
int iDpiX = GetDeviceCaps(hTargetDC, LOGPIXELSX);
int iLineWidth = MulDiv(rect.Width() - GetSystemMetrics(SM_CXVSCROLL), 1440, iDpiX);
iLineWidth -= 2*SC_XMARGIN;
m_EdEMFContent.SetTargetDevice(hTargetDC, iLineWidth); // ok, it owns hTargetDC
// but what happens to the bitmap (hbm)?
#endif
}
void CSCEMFInspectDlg::SCCheckTextContent()
{
#if 0
// for testing
SCMarkText(_T("EMR_SAVEDC"), 0x000000FF);
SCMarkText(_T("EMR_RESTOREDC"), 0x00FF0000);
#endif
}
void CSCEMFInspectDlg::SCMarkText(CString sText, COLORREF color)
{
//insert text at end
CString sEdText;
m_EdEMFContent.GetWindowText(sEdText);
long tLen = sEdText.GetLength();
if (tLen==0)
return;
CHARRANGE cr;
// find the text
long n = 0;
while(n < tLen)
{
n = sEdText.Find(LPCTSTR(sText), n);
if (n == -1)
break;
// go to start of line
while ((n>0)&&(sEdText.Mid(n,1) != _T('\n')))
n--;
if (n>0)
n++;
cr.cpMin = n;
// go to end of line
n += sText.GetLength();
while ((n<tLen)&&(sEdText.Mid(n,1) != _T('\n')))
n++;
//change color
cr.cpMax = n;
m_EdEMFContent.SetSel(cr);
CHARFORMAT cf;
m_EdEMFContent.GetSelectionCharFormat(cf);
cf.cbSize = sizeof(cf);
cf.dwEffects = NULL;
cf.dwMask = CFM_COLOR;
cf.crTextColor = color;
m_EdEMFContent.SetSelectionCharFormat(cf);
// next occurrence
}
//clear selection
cr.cpMin = cr.cpMax = tLen;
m_EdEMFContent.SetSel(cr);
//no undo allowed
m_EdEMFContent.EmptyUndoBuffer();
}
/////////////////////////////////////////////////////////////////////////////
// CSCEMFInspectDlg message handlers
BOOL CSCEMFInspectDlg::OnInitDialog()
{
CDialog::OnInitDialog();
return SCInitDialog();
}
BOOL CSCEMFInspectDlg::SCInitDialog()
{
// create controls
// edit text
{
CRect rect(0,0,200,100);
DWORD dwStyle = WS_CHILD|WS_VISIBLE|ES_MULTILINE|ES_AUTOVSCROLL|ES_AUTOHSCROLL|ES_WANTRETURN
|WS_VSCROLL | ((SC_NO_HSCROLL)?0:WS_HSCROLL);
if (!m_EdEMFContent.Create( dwStyle, rect, this, 1))
{
TRACE0("Could not create edit content\n");
return FALSE;
}
m_EdEMFContent.SetOptions(ECOOP_OR, ECO_AUTOVSCROLL |
ECO_AUTOHSCROLL | ECO_AUTOWORDSELECTION | ECO_READONLY );
//default font settings
LOGFONT lf;
memset(&lf, 0, sizeof(LOGFONT)); // zero out structure
lf.lfHeight = 12; // request a 12-pixel-height font
_tcscpy(lf.lfFaceName, _T("Arial")); // request a face name "Arial"
//get some parent font info
CFont *pFont = GetFont();
if (pFont)
{
pFont->GetLogFont(&lf);
}
VERIFY(m_Edfont.CreateFontIndirect(&lf)); // create the font
m_EdEMFContent.SetFont(&m_Edfont, FALSE);
m_EdEMFContent.SetBackgroundColor(FALSE, RGB(255, 255, 250));
}
//
SCRelocateControls();
// other controls
SCUpdateAllControls();
if (m_hEmf)
{
ModifyStyle(WS_CHILD, WS_DLGFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU,
SWP_DRAWFRAME|SWP_SHOWWINDOW);
SCShowControl(IDCANCEL, SW_SHOW);
SCBeginCracking();
}
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
long CSCEMFInspectDlg::OnSCBrkPos(long lCurPos)
{
m_Progress.SetPos(lCurPos);
CString strPos;
m_EdBrkCount.Format(_T("%d/%d"), lCurPos, m_nMaxBrkPos);
UpdateData(FALSE);
SCYieldForAWhile(); // see comments before SCEMFcrkGuardian
return (m_bStopBrk ? 0 : 1);
}
long CSCEMFInspectDlg::OnSCBrkMaxPos(long lMaxPos)
{
m_Progress.SetRange32(0,lMaxPos);
m_nMaxBrkPos = lMaxPos;
m_EdBrkCount.Format(_T("%d recs"), m_nMaxBrkPos);
UpdateData(FALSE);
SCYieldForAWhile(); // see comments before SCEMFcrkGuardian
return (m_bStopBrk ? 0 : 1);
}
long CSCEMFInspectDlg::OnSCBrkRecStr(long lCurPos, TCHAR *szRecStr)
{
m_Progress.SetPos(lCurPos);
long lLen0 = m_EdEMFContent.GetTextLength();
m_EdEMFContent.SCAddText(szRecStr);
m_EdBrkCount.Format(_T("%d/%d"), lCurPos, m_nMaxBrkPos);
// Sometimes I want to deactivate it
#if 1
long lLen1 = m_EdEMFContent.GetTextLength();
CHARRANGE cr;
// find the text
FINDTEXTEX ft;
//ft.chrg.cpMin = lLen0;
ft.chrg.cpMax = lLen1;
long lNext = lLen0;
while (lNext<lLen1)
{
ft.chrg.cpMin = lNext;
#if (_RICHEDIT_VER >= 0x0200)
ft.lpstrText = _T("EMR_");
#else
ft.lpstrText = "EMR_";
#endif
if (m_EdEMFContent.FindText(0, &ft)==-1)
break;
//change color
cr.cpMin = ft.chrgText.cpMin;
lNext = ft.chrgText.cpMax;
ft.chrg.cpMin = lNext;
#if (_RICHEDIT_VER >= 0x0200)
ft.lpstrText = _T("\t");
#else
ft.lpstrText = "\t";
#endif
if (m_EdEMFContent.FindText(0, &ft)!=-1)
{
cr.cpMax = ft.chrgText.cpMin;
lNext = ft.chrgText.cpMax;
m_EdEMFContent.SetSel(cr);
CHARFORMAT cf;
m_EdEMFContent.GetSelectionCharFormat(cf);
cf.cbSize = sizeof(cf);
cf.crTextColor = RGB(0, 0, 255);
cf.dwEffects = CFE_BOLD;
cf.dwMask = CFM_BOLD|CFM_COLOR;
m_EdEMFContent.SetSelectionCharFormat(cf);
}
}
//clear selection
cr.cpMin = cr.cpMax = lLen1;
m_EdEMFContent.SetSel(cr);
//no undo allowed
m_EdEMFContent.EmptyUndoBuffer();
#endif
UpdateData(FALSE);
SCYieldForAWhile(); // see comments before SCEMFcrkGuardian
return (m_bStopBrk ? 0 : 1);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -