📄 canvas.cpp
字号:
//-----------------------------------------------------------------------------------//
// Windows Graphics Programming: Win32 GDI and DirectDraw //
// ISBN 0-13-086985-6 //
// //
// Written by Yuan, Feng www.fengyuan.com //
// Copyright (c) 2000 by Hewlett-Packard Company www.hp.com //
// Published by Prentice Hall PTR, Prentice-Hall, Inc. www.phptr.com //
// //
// FileName : canvas.cpp //
// Description: Canvas window for EMFScope //
// Version : 1.00.001, July 10, 2000 //
//-----------------------------------------------------------------------------------//
#define STRICT
#include <windows.h>
#include <assert.h>
#include "Winpp.h"
#include "Progress.h"
#include "Stream.h"
#include "emfscope.h"
#include "canvas.h"
#include "spehon32\\spehon32.h"
#include "resource.h"
#include "toolbar.h"
#include "Spoolfil.h"
#include "Examemf.h"
#define maxx MetaHeader.szlDevice.cx
#define maxy MetaHeader.szlDevice.cy
KCanvasWindow::KCanvasWindow(HINSTANCE hInst, HWND hWnd, int x, int y, int w, int h)
{
scale = 1;
hMetaFile = NULL;
hNTMetaFile = NULL;
page_margin = 10;
canvas_backcolor = RGB(0xFF, 0xFF, 0x80);
hInstance = hInst;
Createwindow("CanvasClass",
IDI_COLIVE,
0,
"Canvas",
WS_VISIBLE | WS_CHILD | WS_BORDER,
mapx(x), mapy(y), mapx(w), mapy(h),
hWnd,
hInst,
NULL, 0, (HBRUSH) GetStockObject(WHITE_BRUSH) );
}
void KCanvasWindow::GetDisplayRect(RECT *r)
{
int xScroll = GetScrollPos (m_hWnd, SB_HORZ);
int yScroll = GetScrollPos (m_hWnd, SB_VERT);
r->left = - xScroll + page_margin;
r->right = maxx/scale - xScroll + page_margin;
r->top = - yScroll + page_margin;
r->bottom = maxy/scale - yScroll + page_margin;
}
int CALLBACK SlowPaintEMF(HDC hDC, HANDLETABLE *lpHTable,
ENHMETARECORD *lpEMFR, int nObj, LPVOID lpData)
{
if (lpData)
{
KProgress *Progress = (KProgress *) lpData;
if (Progress->Active())
if (Progress->AbortDraw())
Progress->Destroy();
else
{
Progress->Delay();
if (lpEMFR->iType==EMR_HEADER)
Progress->SetRange(0, ((ENHMETAHEADER *)lpEMFR)->nRecords);
else
Progress->Move();
}
}
return PlayEnhMetaFileRecord(hDC, lpHTable, lpEMFR, nObj);
}
LRESULT KCanvasWindow::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_CREATE:
m_hWnd = hWnd;
break;
case WM_PAINT:
if (hMetaFile || hNTMetaFile)
{
PAINTSTRUCT ps;
RECT rect;
HBRUSH bbrush;
BeginPaint(hWnd, &ps);
GetDisplayRect(&rect);
bbrush = CreateSolidBrush(canvas_backcolor);
FillRect(ps.hdc, &rect, bbrush);
DeleteObject(bbrush);
if (hMetaFile)
if (canvas_delay==0)
PlayEnhMetaFile(ps.hdc, hMetaFile, &rect);
else
{
KProgress Progress;
Progress.Create(EmfScope.hinst_EmfScope, EmfScope.m_hWnd, IDD_PROGRESS, IDC_PROGRESS, IDC_NUMBER, canvas_delay);
EnumEnhMetaFile(ps.hdc, hMetaFile,
(ENHMFENUMPROC) SlowPaintEMF,
& Progress,
&rect);
Progress.Destroy();
SetFocus(EmfScope.m_hWnd);
}
else if (hNTMetaFile)
PlayNTEnhMetaFile(ps.hdc, hNTMetaFile, &rect);
EndPaint(hWnd, &ps);
}
else
return DefWindowProc(hWnd, uMsg, wParam, lParam);
break;
case WM_DESTROY:
if (hMetaFile)
{
DeleteEnhMetaFile(hMetaFile);
hMetaFile = NULL;
}
if (hNTMetaFile)
{
delete hNTMetaFile;
hNTMetaFile = NULL;
}
break;
case WM_HSCROLL:
case WM_VSCROLL:
Scroll (uMsg, HIWORD (wParam), LOWORD(wParam));
break;
case WM_SIZE:
SetScaleColor(0, 0);
break;
default:
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
return 0;
}
void KCanvasWindow::SetDelay(int delay)
{
if (canvas_delay != delay)
{
canvas_delay = delay;
InvalidateRect(m_hWnd, NULL, TRUE);
}
}
void KCanvasWindow::SetScaleColor(int newscale, COLORREF backcolor)
{
RECT rect;
if ((newscale==scale) && (canvas_backcolor==backcolor))
return;
if (backcolor) // no black
canvas_backcolor = backcolor;
// newscale==0 will force repaint
if (newscale)
scale = newscale;
GetClientRect(m_hWnd, &rect);
if ((maxx/scale+page_margin*2) < rect.right)
ShowScrollBar(m_hWnd, SB_HORZ, FALSE); // no scroll bar needed
else
{
ShowScrollBar(m_hWnd, SB_HORZ, TRUE);
EnableScrollBar(m_hWnd, SB_HORZ, ESB_ENABLE_BOTH);
SetScrollRange(m_hWnd, SB_HORZ, 0, (maxx/scale+page_margin*2) - rect.right, FALSE);
}
// always reset scrool bar position,
// we need that inf WS_PAINT processing, even if we don't have show scroll bar
SetScrollPos(m_hWnd, SB_HORZ, 0, FALSE);
if ((maxy/scale+page_margin*2) < rect.bottom)
ShowScrollBar(m_hWnd, SB_VERT, FALSE);
else
{
ShowScrollBar(m_hWnd, SB_VERT, TRUE);
SetScrollRange(m_hWnd, SB_VERT, 0, (maxy/scale+page_margin*2) - rect.bottom, FALSE);
}
// always reset scrool bar position,
// we need that inf WS_PAINT processing, even if we don't have show scroll bar
SetScrollPos(m_hWnd, SB_VERT, 0, FALSE);
InvalidateRect(m_hWnd, NULL, TRUE);
}
BOOL KCanvasWindow::UnloadEmfFile(const char *filename)
{
if ( strcmp(filename, CurEmfFileName) == 0 )
{
if (hMetaFile)
DeleteEnhMetaFile(hMetaFile);
hMetaFile = NULL;
if (hNTMetaFile)
{
delete hNTMetaFile;
hNTMetaFile = NULL;
}
CurEmfFileName[0] = 0;
InvalidateRect(m_hWnd, NULL, TRUE); // clear the window
return TRUE;
}
else
return FALSE;
}
BOOL KCanvasWindow::LoadEmfFile(const char *filename)
{
HENHMETAFILE hNew;
int len;
hNew = GetEnhMetaFile(filename);
if (hNew!=NULL) // standard EMF file
{
len = GetEnhMetaFileHeader(hNew, sizeof(MetaHeader), &MetaHeader);
assert(len != 0);
}
else
{
KInputFile * ntemf = new KInputFile;
if (ntemf==NULL)
return FALSE;
if (!ntemf->Open(filename))
return FALSE;
if (!CheckNTSpoolEmfFile(ntemf, & MetaHeader))
{
ntemf->Close();
return FALSE;
}
if (hNTMetaFile)
delete hNTMetaFile;
hNTMetaFile = ntemf;
}
if (hMetaFile)
DeleteEnhMetaFile(hMetaFile);
hMetaFile = hNew;
strcpy(CurEmfFileName, filename);
// make sure canvas window in visible and big enough, by resizing it's parent
EmfScope.WakeUp();
SetScaleColor(0, 0); // force redraw with current scale
return TRUE;
}
const char szEmfFilter[] = "Enhanced Metafiles (*.emf)\0*.emf\0"
"Windows Metafiles (*.wmf)\0*.wmf\0"
"WinNT Enhanced Metafiles (*.spl)\0*.spl\0"
"All Files (*.*)\0*.*\0";
const char *KCanvasWindow::OpenFile(void)
{
OPENFILENAME ofn;
static char szFile[256]; // full filename with path, reply filename to caller
char szFileTitle[256]; // filename without path
strcpy(szFile, "");
memset(&ofn, 0, sizeof(ofn));
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hwndOwner = m_hWnd;
ofn.lpstrFilter = szEmfFilter;
ofn.lpstrCustomFilter = (LPSTR) NULL;
ofn.nMaxCustFilter = 0L;
ofn.nFilterIndex = 1;
ofn.lpstrFile = szFile;
ofn.nMaxFile = sizeof(szFile);
ofn.lpstrFileTitle = szFileTitle;
ofn.nMaxFileTitle = sizeof(szFileTitle);
ofn.lpstrInitialDir = NULL;
ofn.lpstrTitle = "Load Metafile";
ofn.Flags = 0L;
ofn.nFileOffset = 0;
ofn.nFileExtension = 0;
ofn.lpstrDefExt = "EMF";
if (!GetOpenFileName(&ofn))
return NULL;
if (LoadEmfFile(szFile))
return szFile;
return NULL;
}
BOOL KCanvasWindow::Exam(void)
{
HDC dc;
RECT rect;
dc = GetDC(m_hWnd);
rect.left = 0;
rect.right = maxx-1;
rect.top = 0;
rect.bottom = maxy-1;
// EnumEnhMetaFile(dc, hMetaFile, (ENHMFENUMPROC) MyEnhMetaFileProc, this, &rect);
ReleaseDC(m_hWnd, dc);
return FALSE;
}
BOOL KCanvasWindow::Print(void)
{
HDC hDCPrinter;
int iEntries;
if (hMetaFile == NULL)
return FALSE;
{
PRINTDLG pd;
memset(&pd, 0, sizeof(pd));
pd.lStructSize = sizeof(PRINTDLG);
pd.hwndOwner = m_hWnd;
pd.Flags = PD_RETURNDC;
pd.hInstance = hInstance;
if (!PrintDlg(&pd) || (pd.hDC==NULL))
return FALSE;
hDCPrinter = pd.hDC;
}
{
DOCINFO DocInfo;
char title[128];
// put a special tag before the title so spehon32 can ignore it
strcpy(title, ItsMe);
GetEnhMetaFileDescription(hMetaFile, sizeof(title)-strlen(title), title+strlen(title));
memset(&DocInfo, 0, sizeof(DocInfo));
DocInfo.cbSize = sizeof(DOCINFO);
DocInfo.lpszDocName = title;
DocInfo.lpszOutput = NULL;
StartDoc(hDCPrinter, &DocInfo);
}
StartPage(hDCPrinter);
iEntries = GetEnhMetaFilePaletteEntries(hMetaFile, 0, NULL);
if (iEntries)
{
PLOGPALETTE plogPal;
PBYTE pjTmp;
HPALETTE hPal;
if ((plogPal = (PLOGPALETTE)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT,
sizeof(DWORD) + sizeof(PALETTEENTRY)*iEntries )) == NULL)
{
MessageBox(m_hWnd, "Failed in Creating Palette!", "Error", MB_OK);
}
plogPal->palVersion = 0x300;
plogPal->palNumEntries = (WORD) iEntries;
pjTmp = (PBYTE) plogPal;
pjTmp += 8;
GetEnhMetaFilePaletteEntries(hMetaFile, iEntries, (PPALETTEENTRY)pjTmp);
hPal = CreatePalette(plogPal);
GlobalFree(plogPal);
SelectPalette(hDCPrinter, hPal, FALSE);
RealizePalette(hDCPrinter);
}
{
RECT rc;
ENHMETAHEADER EnhMetaHdr;
GetEnhMetaFileHeader(hMetaFile, sizeof(ENHMETAHEADER), &EnhMetaHdr);
rc.top = 0;
rc.left = 0;
rc.right = EnhMetaHdr.szlDevice.cx;
rc.bottom = EnhMetaHdr.szlDevice.cy;
if (!PlayEnhMetaFile(hDCPrinter, hMetaFile, &rc))
{
char text[128];
wsprintf(text, "Fail in PlayEnhMetaFile! Error %ld\n", GetLastError());
MessageBox(0, text, "Play", MB_OK);
}
}
EndPage(hDCPrinter);
EndDoc(hDCPrinter);
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -