Source file: /~heha/hs/wmfview.zip/src/WmfView.h

#pragma once

/**** allgemein ****/
#define WIN32_LEAN_AND_MEAN
#define WINVER 0x600
#define _WIN32_WINNT 0x0600
#include <windows.h>
#include <windowsx.h>
#include <commdlg.h>
#include <shellapi.h>
#include <commctrl.h>
#include <commdlg.h>
#include <shlwapi.h>

#include <stdio.h>
#ifdef UNICODE
# define _UNICODE
#endif
#include <tchar.h>

#define elemof(x) (sizeof(x)/sizeof((x)[0]))
#define T(x) TEXT(x)
#define nobreak
#ifndef __cplusplus
typedef enum {false,true} bool;
#endif
#ifndef IS_INTRESOURCE
# define IS_INTRESOURCE(x) ((DWORD)(x)>>16==0)
#endif
//#ifndef _W64
//# define ULONG_PTR ULONG
//#endif

#define VADDBUF buf+=_vsntprintf(buf,(int)(end-buf),
#define  ADDBUF buf+= _sntprintf(buf,(int)(end-buf),

#ifdef UNICODE
# define SA T("%S")	// Formatbezeichner, um Ansi-String auszugeben
#else
# define SA T("%s")
#endif

int round(float f);

/**** WMFVIEW.C ****/
#if !defined(_M_AXP64) && !defined(_M_IA64)
//Win32-typische Strukturen mit DWORD-Ausrichtung initialisieren
UINT _fastcall InitStr(UINT len, LPVOID buf);
#define InitStruct(d,l)  InitStr(l,d)
#endif

#ifdef _DEBUG
#define debug(x) DebugOut x
EXTERN_C void _cdecl DebugOut(const char*,...);
#else
#define debug(x)
#endif

EXTERN_C HINSTANCE hInst;	// wo die Ressourcen sind
EXTERN_C HWND hContent;		// Baumdiagramm für Metadatei-Inhalt
EXTERN_C HWND hObjects;		// Baumdiagramm für Metadatei-Objekte
EXTERN_C HWND hShow;		// Skalierbare Metadatei-Anzeige
EXTERN_C HWND hStatus;		// Statuszeile
EXTERN_C HWND hToolbar;		// Werkzeugleiste
EXTERN_C bool EmfMode;
EXTERN_C bool ClipboardMode;
EXTERN_C LPBYTE pLoadedMeta;	// Zeiger geladene Metadaten (immer im Speicher)
EXTERN_C DWORD lLoadedMeta;	// Länge geladene Metadaten
// Geplant: Windows-Spooler-Datei-Anzeige (Arme-Leute-PDF)

typedef struct{
 short left,top,right,bottom;
#ifdef __cplusplus
 inline short Width()  {return right-left;};
 inline short Height() {return bottom-top;};
 inline operator=(const RECT&r) {left=(short)r.left;top=(short)r.top;right=(short)r.right;bottom=(short)r.bottom;};
#endif
}RECTS;
typedef struct{
 short cx,cy;
}SIZES;

typedef struct{
 BYTE versioncode;	// um geänderte Versionen dieser Struktur zu erfassen
 BYTE showcmd;		// Fenstererscheinungsbild
 RECTS winpos;		// Fensterposition und -größe
 short xdiviv,ydivih;	// Position der zwei Teiler
 BYTE fopt;		// Options-Flags
 BYTE fshow;		// Anzeige-Flags
// BYTE fzoom;		// Zoom-Flags (gibts überhaupt welche?)
// bool ShowRecordHead;
// bool ShowRaw;		// Nicht durch Windows-Enum-Funktionen schicken!
}CONFIG;
// Schalter:
// Bit 0: Jeden Record-Kopf (im Baumdiagramm) anzeigen (nicht sonderlich aussagekräftig)
// Bit 1: Metadatei-Parsen per eigenem Kode, nicht mittels Windows-Funktion (evtl. hilfreich bei beschädigten Dateien)
enum {optRecordHead=1, optRaw=2};
// Schalter:
// Bit 0: Zeichenfläche (als weißes Rechteck) anzeigen (bei Standard-WMF nicht verfügbar)
// Bit 1: Ausgabe auf Zeichenfläche beschneiden (bei Standard-WMF nicht verfügbar)
// Bit 2: Anisotrope Ausgabe erlauben (nur bei Zoomstufen "Ganze Metadatei", "Ganze Zeichenfläche" wirksam)
//        Bei der Zoomstufe "1int:1pix" ist die Ausgabe durchaus stets anisotrop
enum {showArea=1,showClip=2,showAnis=4};

EXTERN_C CONFIG Config;

#pragma pack(push,2)
typedef struct{
 DWORD id;
 WORD  handle;
 RECTS rcArea;		// Vorgesehene Ausgabefläche in WMF-Einheiten
 short inch;
 DWORD reserved;
 WORD  checksum;
}PLACEABLE_HEADER;
#pragma pack(pop)

#ifdef __cplusplus
struct cRECT:RECT{
 inline int Width() const	{return right-left;};
 inline void Width(int w)	{right=left+w;};
 inline int Height() const	{return bottom-top;};
 inline void Height(int h)	{bottom=top+h;};
 inline int MidX() const	{return (left+right)>>1;};
 inline int MidY() const	{return (top+bottom)>>1;};
 inline void operator=(const RECTS&r){left=r.left;top=r.top;right=r.right;bottom=r.bottom;};
 inline void operator=(const RECTL&r){CopyRect(this,(RECT*)&r);};
 void Scale(float sx, float sy) {left=round(left*sx); top=round(top*sy); right=round(right*sx); bottom=round(bottom*sy);};
 void Scale(float s)		{left=round(left*s); top=round(top*s); right=round(right*s); bottom=round(bottom*s);};
};

struct POINTF:POINTFLOAT{
};

struct RECTF{
 float left,top,right,bottom;
 inline float Width() const	{return right-left;};
 inline void Width(float w)	{right=left+w;};
 inline float Height() const	{return bottom-top;};
 inline void Height(float h)	{bottom=top+h;};
 inline operator=(const RECT&r) {left=(float)r.left;top=(float)r.top;right=(float)r.right;bottom=(float)r.bottom;};
 inline operator=(const RECTL&r){left=(float)r.left;top=(float)r.top;right=(float)r.right;bottom=(float)r.bottom;};
 inline operator=(const RECTS&r){left=r.left;top=r.top;right=r.right;bottom=r.bottom;};
 void Scale(float sx, float sy) {left*=sx; top*=sy; right*=sx; bottom*=sy;};
 void Scale(float s)		{left*=s; top*=s; right*=s; bottom*=s;};
};

#endif

#define PLACEABLE_HEADER_ID  0x9AC6CDD7UL	// placeable metafile


/**** EMF.C ****/
typedef union {
 LOGPEN pen;
 LOGBRUSH brush;
 LOGFONT font;
}OBJINFO;

typedef struct {
 BYTE objidx[8];	// Indizes in die Handle-Tabelle mit OBJ_xxx-1-Indizes
 BYTE BkMode;
 BYTE PolyFillMode;
 BYTE ROP2;
 BYTE MapMode;
 BYTE StretchBltMode;
 BYTE TextAlign;
 BYTE ArcDir;	// nur 32bit
 BYTE rsv1;
 WORD TextCharExtra;
 WORD TextJustify_BreakCount;
 WORD TextJustify_BreakExtra;
 WORD rsv2;
 COLORREF BkColor;
 COLORREF TextColor;
 POINT Position;	// MoveTo, LineTo, ArcTo...
 POINT WindowOrg;
 SIZE  WindowExt;
 POINT ViewportOrg;
 SIZE  ViewportExt;
 UINT Flags;
}GDIINFO;

//GDIINFO.Flags:
enum {	GI_BKCOLOR_VALID=1,
	GI_TEXTCOLOR_VALID=2,
	GI_POSITION_VALID=4,
	GI_TEXTALIGN_VALID=8,
	GI_WINDOWORG_VALID=16,
	GI_WINDOWEXT_VALID=32,
	GI_VIEWPORTORG_VALID=64,
	GI_VIEWPORTEXT_VALID=128,
};
//Abhängigkeits-Bits
enum {	DEP_PEN		=1 << (OBJ_PEN-1),	// mäkeliges MSVC9
	DEP_BRUSH	=1 << (OBJ_BRUSH-1),
	DEP_PAL		=1 << (OBJ_PAL-1),
	DEP_FONT	=1 << (OBJ_FONT-1),
	DEP_REGION	=1 << (OBJ_REGION-1),
	DEP_BKMODE	=1 << 8,	// Nur wenn PEN oder BRUSH löchrig!
	DEP_POLYFILL	=1 << 9,	// Nur bei Polygon mit >=5 Ecken
	DEP_ROP2	=1 << 10,	// eigentlich immer
	DEP_MM		=1 << 11,	// MapMode, Window, Viewport
	DEP_SBM		=1 << 12,	// StretchBltMode
	DEP_TEXT	=1 << 13,	// TextAlign usw.
	DEP_ARCDIR	=1 << 14,
	DEP_BCOLOR	=1 << 16,
	DEP_TCOLOR	=1 << 17,
	DEP_POSITION	=1 << 18,
};

typedef struct {
 union{
  POINTL*pl;			// Zeiger auf Punktliste (für Hervorhebung)
  POINTS*ps;
 }PointList;
 int nPoints;
 BYTE Flags;
 BYTE Type;
 BYTE unused[2];
 GDIINFO gi;
 DWORD dlen;			// Länge der variablen Daten in Byte (bes. für Garbage)
 union{
  METARECORD wmr;
  METAHEADER wmh;
  PLACEABLE_HEADER pmh;
  ENHMETARECORD emr;		// alles variable Länge
 };
}DECODEINFO;

typedef union{
 VOID	*v;
 BYTE	*b,*uc;
 WORD	*w,*us;
 DWORD	*dw,*ul;
 CHAR	*c;
 SHORT	*s;
 LONG	*l;
 FLOAT	*f;
 POINTL	*pl;
 POINTS	*ps;
 SIZEL	*sl;
 SIZES	*ss;
 RECTL	*rl;
 RECTS	*rs;
 COLORREF *color;
}MULTIPOINTER;

//DECODEINFO.Flags:
enum {	DI_POINTS=1,	// 16-bit-Punktkoordinaten
	DI_BRECT=2,	// Hüllrechteck (als erster Parameter) vorhanden
	DI_NODRAW=4,	// Kein Zeichen-Objekt
	DI_SELECTED=8};
//DECODEINFO.Type:
enum {WMF_RECORD, WMF_METAHEADER, WMF_PLACEABLE_HEADER, WMF_METAFILEPICT, EMF_RECORD, WMF_GARBAGE};

#define DECIMAL_DELIMITER '.'


enum {ES_ZEROTERMINATED = 1,
      ES_WIDECHAR = 2};
EXTERN_C LPTSTR EscapeStr(LPTSTR buf,LPCTSTR end, LPCSTR s, int slen, UINT Flags);

EXTERN_C LPTSTR DecodeE(LPCSTR EnumNummer, unsigned input, LPTSTR buf, LPCTSTR end);

EXTERN_C int _stdcall EmfEnumProc(HDC,HANDLETABLE*,const ENHMETARECORD*,int,LPARAM);
EXTERN_C void _stdcall EmfDecodeFunc(DECODEINFO*,TVINSERTSTRUCT*,LPTSTR,LPCTSTR);

/**** WMF.C ****/
EXTERN_C bool MfEnumInternal(BYTE Type, LPCVOID data, DWORD dlen);
EXTERN_C int _stdcall WmfEnumProc(HDC,HANDLETABLE*,METARECORD*,int,LPARAM);
EXTERN_C void _stdcall WmfDecodeFunc(DECODEINFO*,TVINSERTSTRUCT*,LPTSTR,LPCTSTR);


/**** show.cpp ***/
#ifdef __cplusplus
extern cRECT rcFrame;	// Vorgesehene Rahmengröße, in Metadatei-Einheiten
extern cRECT rcBBox;	// Vorgefundene Metadatei-Ausdehnung (nach Enumeration aller Elemente)
extern POINT dpi;	// Vorgefundene Skalierung [Pixel pro Zoll], ggf. unterschiedlich in x- und y-Richtung
enum{			// Sonder-Zoomwerte (bleiben bei Größenveränderung des Fensters bestehen)
 ZOOM_MOUSEUD=-512,	// dazu addiert die Anzahl der Zoom-Sprünge, um die Mausposition (GetMessagePos())
 ZOOM_UD=-256,		// dazu addiert die Anzahl der Zoom-Sprünge, um die Bildmitte
 ZOOM_NEXT=-8,		// vorwärts in History-Liste
 ZOOM_PREV=-7,		// zurück in History-Liste (nur Kommando, nie CurZoom)
 ZOOM_BBOX_W=-6,	// auf Bounding-Box, genau 1 Scrollbalken, isotrop
 ZOOM_BBOX_A=-5,	// auf Bounding-Box, anisotrop
 ZOOM_BBOX=-4,		// auf Bounding-Box, isotrop
 ZOOM_FRAME_W=-3,	// FRAME-Breite oder -Höhe, je nachdem, was größer ist (1 Rollbalken), isotrop
 ZOOM_FRAME_A=-2,	// so wie früher
 ZOOM_FRAME=-1,		// auf Zeichenfläche, isotrop
 ZOOM_TEXT=0};		// 1 Pixel = 1 WMF/EMF-Rasterschritt, ggf. anisotrop
extern int CurZoom;
bool SetZoom(HWND Wnd, int newzoom);
bool CanZoom(HWND Wnd, int newzoom);	// zum Test von ZOOM_PREV und ZOOM_NEXT, aber auch ZOOM_UD±1
					// Was tun bei numerischen Zoomstufen bei Standard-WMFs?
#endif
EXTERN_C LRESULT CALLBACK ShowProc(HWND,UINT,WPARAM,LPARAM);
Detected encoding: ANSI (CP1252)4
Wrong umlauts? - Assume file is ANSI (CP1252) encoded