home *** CD-ROM | disk | FTP | other *** search
- {$define RETAIL_VERSION}
- {!define Win32}
- {***************************************************************************
- Source File Name : WMFVIEW.PAS
- Autor : Mario M. Westphal
- Erstellt am : 20.02.1993
-
- Compiler : Borland Pascal for Windows
- Betriebssystem : DOS 5.0, Windows 3.x
- Compiler-Schalter : -
-
- Bemerkungen : -
-
- Beschreibung :
-
-
- Revisionen : 1.00 20.02.1993 created (MW)
- 07.04.1993 revisited (MW)
- ****************************************************************************}
- {$M 8192,8192}
- {$A+,B-,D+,F-,G+,I+,L+,N-,R+,S+,V+,W-,X+,Q+}
-
- {$ifdef RETAIL_VERSION}
- {$D-,L-,S-,R-,Q-,I-}
- {$endif}
-
- program MetafileViewer;
- {$R WMFVIEW.RES}
-
- uses
- WinTypes,
- WinProcs,
- Objects,
- OMemory,
- OWindows,
- ODialogs,
- OStdDlgs,
- WinDOS,
- Win31,
- CommDlg,
- Strings,
- ShellAPI,
- ToolHelp,
-
- SysTools,
- ExDlg,
- BPWmfImp;
-
- const
- AppName = 'Metafile Viewer';
-
- { Menu - IDs }
- idm_Load = 101;
- idm_About = 102;
- idm_Close = 103;
-
- idm_PalOptimize = 201;
- idm_Directmode = 202;
-
- idm_ZOriginal = 301;
- idm_ZClient = 302;
- idm_200 = 303;
- idm_400 = 304;
- idm_50 = 305;
- idm_25 = 306;
-
- type
- PMWindow = ^TMWindow;
- TMWindow = object(TWindow)
- MFName : array[0..255] of Char; { Dateiname Metafile }
- MFInfo : TFileSpec; { Struktur fⁿr Loadmetafile }
- MFNoRecs : LongInt; { Anzahl Records im Metafile }
- Pal : HPalette; { Metafile-Palette }
- OldPal : HPalette; { Original-Palette }
- PalOptimize : Boolean; { True => Palette optimieren }
- DirectMode : Boolean; { True => Keine Offscreen-Technik }
- Zoom : Real; { Aktueller Zoomfaktor }
- LastZoomID : Word; { Fⁿr Checkmenuitem }
- HomeDir : array[0..255] of Char; { Fⁿr die INI-Dateien }
- HasBitmapMem : Boolean; { True => Genug Speicher fⁿr OffScreen-Bitmap }
- hbmClient : HBitmap; { Offscreen-Bitmap }
- cxBitmap : Integer; { Gr÷▀e der Bitmap }
- cyBitmap : Integer;
- cxMeta : Integer; { Gr÷▀e des Metafiles (ohne Zoom) }
- cyMeta : Integer;
- XLogPixels : Integer; { Pixel/Zoll des Bildschirms }
- YLogPixels : Integer;
-
- constructor Init (AParent: PWindowsObject; ATitle: PChar);
-
- procedure SetupWindow; virtual;
-
- function CanClose : Boolean; virtual;
-
- destructor Done; virtual;
-
- function GetClassName: PChar; virtual;
-
- procedure GetWindowClass(var AWndClass: TWndClass); virtual;
-
- procedure Paint(PaintDC: HDC; var PaintInfo: TPaintStruct); virtual;
-
- procedure WMQueryNewPalette (var Msg: TMessage);
- virtual wm_First or wm_QueryNewPalette;
-
- procedure WMPaletteChanged (var Msg: TMessage);
- virtual wm_First or wm_PaletteChanged;
-
- procedure ShowMetaFile (PaintDC: HDC);
-
- procedure WMSize (var Msg: TMessage);
- virtual wm_First or wm_Size;
-
- procedure WMKeyDown (var Msg: TMessage);
- virtual wm_First or wm_KeyDown;
-
- procedure ProcessLoadFile (FileName: PChar);
-
- procedure CalcNewValues;
-
- procedure RedrawWindow;
-
- { Menⁿ Datei }
- procedure IDMLoad (var Msg: TMessage);
- virtual cm_First or idm_Load;
-
- procedure IDMAbout (var Msg: TMessage);
- virtual cm_First or idm_About;
-
- procedure IDMClose (var Msg: TMessage);
- virtual cm_First or idm_Close;
-
- { Menⁿ Optionen }
- procedure IDMPalOptimize (var Msg: TMessage);
- virtual cm_First or idm_PalOptimize;
-
- procedure IDMDirectMode (var Msg: TMessage);
- virtual cm_First or idm_DirectMode;
-
- { Menⁿ Zoom }
- procedure IDMZoomOriginal (var Msg: TMessage);
- virtual cm_First or idm_ZOriginal;
-
- procedure IDMZoomClient (var Msg: TMessage);
- virtual cm_First or idm_ZClient;
-
- procedure IDMZoom200 (var Msg: TMessage);
- virtual cm_First or idm_200;
-
- procedure IDMZoom400 (var Msg: TMessage);
- virtual cm_First or idm_400;
-
- procedure IDMZoom50 (var Msg: TMessage);
- virtual cm_First or idm_50;
-
- procedure IDMZoom25 (var Msg: TMessage);
- virtual cm_First or idm_25;
-
- { Drag 'n Drop }
- procedure WMDropFiles (var Msg: TMessage);
- virtual wm_First + wm_DropFiles;
-
- { INI-Datei }
-
- procedure ReadINIData;
- procedure WriteINIData;
- end;
-
- {-------------------------------------------------------------------------------
- Liefert die Gr÷▀e des freien linearen Adressraumes. Durch einen Aufruf der
- TOOLHELP.Routine MemManInfo wird die Anzahl der freien Seiten im Sytem
- ermittelt und mit der Gr÷▀e einer Seize multipliziert. Der resultierende
- Wert gibt die Gr÷▀e des Speichers an, den Windows ohne Swappen zur Verfⁿgung
- stellen kann.
- Die Funktion liefert allerdings nur im erweiterten Modus korrekte Werte. Im
- Standardmodus, oder wenn die DLL nicht gefunden wurde, liefert die Funktion
- als Default den gesamten verfⁿgbaren Speicher, inclusive Swapping-Option.
- }
- function GetFreeLinearSpace : LongInt;
- var
- pInfo : TMemManInfo;
- begin
- pInfo.dwSize := SizeOf(pInfo);
- if MemManInfo(@pInfo) then
- begin
- if GetWinFlags and WF_ENHANCED <> 0 then
- GetFreeLinearSpace := pInfo.dwMaxPagesLockable * pInfo.wPageSize
- else
- GetFreeLinearSpace := pInfo.dwLargestFreeBlock;
- end
- else
- GetFreeLinearSpace := GetFreeSpace(0);
- end;
-
-
- {*******************************************************************************}
- { TMWindow }
- {*******************************************************************************}
- constructor TMWindow.Init (AParent : PWindowsObject; ATitle: PChar);
- var IC : HDC;
- begin
- Inherited Init(AParent, ATitle);
- Attr.W := (GetSystemMetrics(sm_CXScreen))-100;
- Attr.H := (GetSystemMetrics(sm_CYScreen))-100;
- Attr.X := (GetSystemMetrics(sm_CXScreen) div 2) - Attr.W div 2;
- Attr.Y := (GetSystemMetrics(sm_CYScreen) div 2) - Attr.H div 2;
- Attr.Style := ws_OverlappedWindow or ws_ClipChildren or ws_HScroll or ws_VScroll;
- Attr.Menu := LoadMenu(HInstance,'MNU_MAIN');
-
- Scroller := New(PScroller,Init(@Self,1,1,0,0));
-
- FillChar(MFinfo,SizeOf(MFInfo),0);
- MFName[0] := #0;
-
- Pal := 0;
- CheckMenuItem(Attr.Menu,idm_PalOptimize,MF_CHECKED);
- Zoom := 0; { Default: Originalgr÷▀e }
- LastZoomID := idm_ZOriginal;
- CheckMenuItem(Attr.Menu,idm_ZOriginal,MF_CHECKED);
- hbmClient := 0;
- HasBitmapMem := true;
- DirectMode := false;
- OldPal := 0;
-
- { Ermittle Aufl÷sung Pixel/log. Zoll }
- IC := CreateIC('DISPLAY',nil,nil,nil);
- XLogPixels := GetDeviceCaps(IC,LOGPIXELSX);
- YLogPixels := GetDeviceCaps(IC,LOGPIXELSY);
-
- { Verfⁿgt der Treiber ⁿber eine Palette? }
- PalOptimize := (GetDeviceCaps(IC,RASTERCAPS) and RC_PALETTE <> 0);
- { Wenn nicht, ist auch keine Optimierung n÷tig }
- if not PalOptimize then
- EnableMenuItem(Attr.Menu,idm_PalOptimize,MF_BYCOMMAND or MF_GRAYED);
-
- DeleteDC(IC);
- end;
-
- {-------------------------------------------------------------------------------
- Drag 'n Drop API ankurbeln und Initialisierungsdaten lesen
- }
- procedure TMWindow.SetupWindow;
- begin
- Inherited SetupWindow;
- DragAcceptFiles(HWindow,true);
- ReadINIData;
- end;
-
- {-------------------------------------------------------------------------------
- Drag 'n Drop abschlie▀en, Initialisierungsdaten wegschreiben.
- }
- function TMWindow.CanClose : Boolean;
- begin
- DragAcceptFiles(HWindow,false);
- WriteINIData;
- CanClose := true;
- end;
-
- {-------------------------------------------------------------------------------
- Palette und Metafile freigeben
- }
- destructor TMWindow.Done;
- var
- DC : HDC;
- begin
- if OldPal <> 0 then
- begin
- { Palette aktivieren, die beim Programmstart aktiv war }
- DC := GetDC(HWindow);
- SelectPalette(DC,OldPal,true);
- RealizePalette(DC);
- ReleaseDC(HWindow,DC);
- end;
-
- if Pal <> 0 then
- begin
- DeleteObject(Pal);
- Pal := 0;
- end;
-
- if MFInfo.FInfo.hMF <> 0 then
- begin
- DeleteMetaFile(MFInfo.FInfo.hMF);
- MFInfo.FInfo.hMF := 0;
- end;
-
- if hbmClient <> 0 then
- begin
- DeleteObject(hbmClient);
- hbmClient := 0;
- end;
-
- Inherited Done;
- end;
-
- {-------------------------------------------------------------------------------
- }
- function TMWindow.GetClassName: PChar;
- begin
- GetClassName := 'METAFILE_VIEWER';
- end;
-
- {-------------------------------------------------------------------------------
- }
- procedure TMWindow.GetWindowClass(var AWndClass: TWndClass);
- begin
- Inherited GetWindowClass(AWndClass);
- AWndClass.hIcon := LoadIcon(HInstance,'ICON_APP');
- AWndClass.Style := AWndClass.Style and CS_BYTEALIGNWINDOW;
- end;
-
- {-------------------------------------------------------------------------------
- Anzeigen des Metafiles. Erzeugt eine OffScreen-Bitmap, wenn die Bitmap im
- physikalisch vorhandenen Speicher angelegt werden kann. Justiert die
- Scroller.
- }
- procedure TMWindow.ShowMetaFile (PaintDC: HDC);
- var
- OldDc : Integer;
- Pnt : TPoint;
- Size : TSize;
- MemDC : HDC;
- hbmOld : HBitmap;
- hpOld : HPalette;
- R : TRect;
- SizeOfBitmap : LongInt;
-
- { Fenstertitel anpassen }
- procedure ChangeCaption (IsOffScreen: Boolean);
- var
- Caption : array[0..255] of Char;
- begin
- StrCopy(Caption, AppName);
- StrCat(Caption, ': ');
- StrCat(Caption, AnsiLower(MFName));
- if IsOffScreen then StrCat(Caption,' (OffScreen)')
- else StrCat(Caption,' (Direct)');
- SetCaption(Caption);
- end;
-
- begin
- if MFInfo.FInfo.hMF <> 0 then
- begin
- { Erzeugen eines Bitmaps, da▀ das Metafile im aktuellen Zoomfaktor aufnehmen kann }
- if not DirectMode then
- begin
- { Berechne die Gr÷▀e der resultierenden Bitmap }
- SizeOfBitmap := (LongInt((cxBitmap+1))*(cyBitmap+1) *
- LongInt(GetDeviceCaps(PaintDC,BITSPIXEL))) div 8;
- { Wenn die Bitmap ohne das Auslagern von Seiten angelegt werden kann, wird sie }
- { erzeugt, im anderen Fall wird der "Direct"-Modus verwendet. }
- if GetFreeLinearSpace > SizeOfBitmap then
- hbmClient := CreateCompatibleBitmap(PaintDC,cxBitmap+1,cyBitmap+1)
- else
- hbmClient := 0;
- end
- else
- hbmClient := 0;
- HasBitmapMem := hbmClient <> 0;
-
- { Wenn genug Speicher fⁿr die Bitmap vorhanden war }
- if HasBitmapMem then
- begin
- Scroller^.TrackMode := true;
- Scroller^.AutoMode := true;
- ChangeCaption(true);
-
- MemDC := CreateCompatibleDC(PaintDC);
- SetMapMode(MemDC,MM_ANISOTROPIC);
- SetViewPortOrgEx(MemDC,0,0,@Pnt);
- hbmOld := SelectObject(MemDC,hbmClient);
- SetViewPortExtEx(MemDC,cxBitmap,cyBitmap,@Size);
- if Pal <> 0 then
- begin
- hpOld := SelectPalette(MemDC,Pal,false);
- if OldPal = 0 then OldPal := hpOld;
- RealizePalette(MemDC);
- end
- else
- hpOld := 0;
-
- GetClientRect(HWindow,R);
- FillRect(MemDC,R,GetStockObject(WHITE_BRUSH));
- PlayMetaFileExtended(@Self,MemDC,MFInfo.FInfo.hMF,MFNoRecs);
- if hpOld <> 0 then SelectPalette(MemDC,hpOld,false);
- SelectObject(MemDC,hbmOld);
- DeleteDC(MemDC);
- end
- else
- begin
- { Nicht genug Speicher fⁿr die Bitmap => Direct-Mode }
- Scroller^.TrackMode := false;
- Scroller^.AutoMode := false;
- ChangeCaption(false);
- end;
- end; { hMF <> 0 }
- end;
-
- {-------------------------------------------------------------------------------
- Realisiert die Palette und ruft ShowMetaFile auf, wenn eine OffScreen-Bitmap
- existiert. Im anderen Fall wird das Metafile direkt angezeigt.
- }
- procedure TMWindow.Paint(PaintDC: HDC; var PaintInfo: TPaintStruct);
- var
- hbmOld : HBitmap;
- hpOld : HPalette;
- MemDC : HDC;
- R : TRect;
- Pnt : TPoint;
- Size : TSize;
- x,y : LongInt;
-
- begin
- if MFInfo.FInfo.hMF <> 0 then
- begin
- if (HasBitmapMem) and (hbmClient = 0) then
- begin
- ShowMetaFile(PaintDC);
- end;
-
- if Scroller^.HasHScrollBar then x := Scroller^.XPos
- else x := 0;
- if Scroller^.HasVScrollBar then y := Scroller^.YPos
- else y := 0;
-
-
- { Die Palette immer als Hintergrundpalette realisieren. Wenn wir an dieser Stelle sind, und }
- { wir sind die aktive Anwendung, wurde die Palette schon in wm_QueryNewPalette als Vorder- }
- { grundpalette realisiert; im anderen Fall sind wir sowieso nicht die bestimmende Anwendung.}
- if Pal <> 0 then
- begin
- hpOld := SelectPalette(PaintDC,Pal,true);
- if OldPal = 0 then OldPal := hpOld;
- RealizePalette(PaintDC);
- end
- else
- hpOld := 0;
-
- GetClientRect(HWindow,R);
- if hbmClient <> 0 then
- begin
- MemDC := CreateCompatibleDC(PaintDC);
- hbmOld := SelectObject(MemDC,hbmClient);
- FillRect(PaintDC,R,GetStockObject(WHITE_BRUSH));
- BitBlt(PaintDC,x,y,Min(cxBitmap,R.Right)+1,Min(cyBitmap,R.Bottom)+1,
- MemDC,x,y,SRCCOPY);
- SelectObject(MemDC,hbmOld);
- DeleteDC(MemDC);
- end
- else begin
- ShowCursor(false);
- SetMapMode(PaintDC,MM_ANISOTROPIC);
- SetViewPortOrgEx(PaintDC,-x,-y,@Pnt);
- SetViewPortExtEx(PaintDC,cxBitmap,cyBitmap,@Size);
- FillRect(PaintDC,R,GetStockObject(WHITE_BRUSH));
- PlayMetaFile(PaintDC,MFInfo.FInfo.hMF);
- ShowCursor(true);
- end;
-
- if hpOld <> 0 then SelectPalette(PaintDC,hpOld,false);
-
- end;
- end;
-
- {-------------------------------------------------------------------------------
- Wird aufgerufen, wenn die Anwendung aktiv wird. Realisiert die Palette
- und baut das Fenster neu auf. Liefert einen Wert ungleich 0, wenn eine Palette
- realisiert wurde.
- }
- procedure TMWindow.WMQueryNewPalette (var Msg: TMessage);
- var
- DC : HDC;
- Changed : LongInt;
- hpOld : HPalette;
- begin
- { Haben wir ein Metafile geladen und eine Palette? }
- if (MFInfo.FInfo.hMF <> 0) and (Pal <> 0) then
- begin
- DC := GetDC(HWindow);
- hpOld := SelectPalette(DC,Pal,false);
- if OldPal = 0 then OldPal := hpOld;
- Changed := RealizePalette(DC);
- if hpOld <> 0 then SelectPalette(DC,hpOld,false);
- ReleaseDC(HWindow,DC);
- if Changed <> 0 then InvalidateRect(HWindow,nil,false);
- Msg.Result := Changed;
- end
- else
- DefWndProc(Msg);
- end;
-
- {-------------------------------------------------------------------------------
- Wird aufgerufen, wenn eine andere Anwendung eine neue Palette realisiert hat.
- Baut den Bilschirm neu auf, um die Ausgabe zu verbessern, auch wenn weniger
- Farben verfⁿgbar sind.
- }
- procedure TMWindow.WMPaletteChanged (var Msg: TMessage);
- var
- DC : HDC;
- Changed : LongInt;
- hpOld : HPalette;
- begin
- if Msg.wParam = HWindow then exit; { Nicht das eigene Fenster }
- if (MFInfo.FInfo.hMF <> 0) and (Pal <> 0) then
- begin
- DC := GetDC(HWindow);
- hpOld := SelectPalette(DC,Pal,true);
- if OldPal = 0 then OldPal := hpOld;
- Changed := RealizePalette(DC);
- if hpOld <> 0 then SelectPalette(DC,hpOld,false);
- ReleaseDC(HWindow,DC);
- if Changed <> 0 then InvalidateRect(HWindow,nil,false);
- Msg.Result := 0;
- end
- else
- DefWndProc(Msg);
- end;
-
- {-------------------------------------------------------------------------------
- Justiert die Scroller neu und baut die Anzeige neu auf.
- }
- procedure TMWindow.WMSize (var Msg: TMessage);
- var
- R : TRect;
- begin
- if Msg.wParam = SIZE_MINIMIZED then exit;
-
- if Zoom = 1 then
- RedrawWindow
- else
- begin
- if (cxBitmap > Msg.lParamLo) and (cyBitmap > Msg.lParamHi) then
- begin
- GetClientRect(HWindow,R);
- Scroller^.SetRange(Max(0,cxBitmap-R.Right),Max(0,cyBitmap-R.Bottom));
- Scroller^.SetPageSize;
- InvalidateRect(HWindow,nil,true);
- end
- else
- RedrawWindow;
- end;
- Msg.Result := 0;
- end;
-
- {-------------------------------------------------------------------------------
- Erm÷glicht das Scrollen ⁿber die Tastatur.
- }
- procedure TMWindow.WMKeyDown (var Msg: TMessage);
- begin
- case Msg.wParam of
- vk_Prior : SendMessage(HWindow,WM_VScroll,sb_PageUp,0);
- vk_Next : SendMessage(HWindow,WM_VScroll,sb_PageDown,0);
- vk_Up : SendMessage(HWindow,WM_VScroll,sb_LineUp,0);
- vk_Down : SendMessage(HWindow,WM_VScroll,sb_LineDown,0);
- vk_Left : begin
- if GetKeyState(vk_CONTROL) < 0 then
- SendMessage(HWindow,WM_HScroll,sb_PageUp,0)
- else
- SendMessage(HWindow,WM_HScroll,sb_LineUp,0)
- end;
- vk_Right : begin
- if GetKeyState(vk_CONTROL) < 0 then
- SendMessage(HWindow,WM_HScroll,sb_PageDown,0)
- else
- SendMessage(HWindow,WM_HScroll,sb_LineDown,0)
- end;
- end;
- end;
-
- {-------------------------------------------------------------------------------
- LΣdt das Metafile und aktualisiert die Ausgabe, Caption usw.
- }
- procedure TMWindow.ProcessLoadFile (FileName: PChar);
- const
- LIBNAME = 'WMFIMP.DLL';
-
- var
- i : Word;
- s : array[0..20] of Char;
- hOldCursor : HCursor;
- MsgWin : PMsgWindow;
- hFile : Integer;
-
- hGrImpLib : THandle;
- ModeSave : Word;
- pfnGetFilterVersion : TpfnGetFilterVersion;
- pfnLoadFile : TpfnLoadFile;
-
- begin
- StrCopy(MFName, FileName);
- if MFInfo.FInfo.hMF <> 0 then
- begin
- DeleteMetaFile(MFInfo.FInfo.hMF);
- MFInfo.FInfo.hMF := 0;
- end;
-
- { Library laden }
- ModeSave := SetErrorMode(SEM_NOOPENFILEERRORBOX);
- hGrImpLib := LoadLibrary(LIBNAME);
- if hGrImpLib < HINSTANCE_ERROR then
- begin
- MessageBox(0,'Kann die Bibliothek '+LIBNAME+' nicht finden!'#13#10+
- 'Bitte ⁿberprⁿfen Sie, ob Sie ⁿber eine Datei dieses Namens auf Ihrer Festplatte '+
- 'verfⁿgen und kopieren Sie diese in das Windows-Verzeichnis.',AppName,
- mb_IconStop or mb_Ok);
- SetErrorMode(ModeSave);
- exit;
- end;
-
- SetErrorMode(ModeSave);
-
- { Meldungsfenster anzeigen }
- MsgWin := PMsgWindow(Application^.MakeWindow(New(PMsgWindow,Init(@Self,'Information'))));
- MsgWin^.SetText('Laden und analysieren der Metadatei...');
-
- { Datei ÷ffnen }
- hOldCursor := SetCursor(LoadCursor(0,IDC_WAIT));
- hFile := _lopen(MFName,OF_READ);
- if hFile > 0 then
- begin
-
- { Alte Palette l÷schen }
- if Pal <> 0 then
- begin
- DeleteObject(Pal);
- Pal := 0;
- end;
-
- { Erzeuge die Info-Struktur fⁿr LoadMetaFile }
- FillChar(MFInfo,SizeOf(MFInfo),0);
- with MFInfo do
- begin
- Size := SizeOf(MFInfo);
- StrCopy(FullName,MFName);
- FHandle := hFile;
- FMode := OF_READ;
- FPos := 0;
- if PalOptimize then PalSpec := bpOptimize
- else PalSpec := bpNone;
- end;
-
- @pfnGetFilterVersion := GetProcAddress(hGrImpLib,'GETFILTERVERSION');
- @pfnLoadFile := GetProcAddress(hGrImpLib,'LOADFILE');
-
- { Datei laden }
- if pfnLoadFile(MFInfo) = 0 then
- begin
- if MFInfo.FInfo.OwnPal then Pal := 0 { Metafile hat eigene Palette }
- else Pal := MFInfo.FInfo.hPal; { Sonst erzeugte Palette benutzen }
- end
- else
- begin
- MessageBox(HWindow,'Dies ist kein gⁿltiges MetaFile!', AppName,mb_Ok or mb_IconExclamation);
- end;
- Dispose(MsgWin,Done);
- { Datei wieder schlie▀en }
- _lclose(hFile);
- end
- else
- begin
- MessageBox(HWindow,'Die Datei kann nicht ge÷ffnet werden!',AppName,
- mb_Ok or mb_IconExclamation);
- end;
- SetCursor(hOldCursor);
- FreeLibrary(hGrImpLib);
- Scroller^.ScrollTo(0,0);
- HasBitmapMem := true;
- RedrawWindow;
- end;
-
- {-------------------------------------------------------------------------------
- Berechnet die Gr÷▀e des Metafiles und die der Bitmap. Als "Normale Gr÷▀e"
- werden die Originalma▀e aus dem APM-Header angenommen. Auch die Zoomfaktoren
- beziehen sich auf diese Gr÷▀e.
- }
- procedure TMWindow.CalcNewValues;
- var
- wx, wy : Integer;
- R : TRect;
- f : Real;
- begin
- if MFInfo.FInfo.hMF = 0 then exit;
-
- { Breite/H÷he des Metafiles in logischen Einheiten }
- wx := (MFInfo.FInfo.rcBBox.Right-MFInfo.FInfo.rcBBox.Left)+1;
- wy := (MFInfo.FInfo.rcBBox.Bottom-MFInfo.FInfo.rcBBox.Top)+1;
-
- { Berechne die Gr÷▀e des Metafiles unter Berⁿcksichtigung des }
- { richtigen SeitenverhΣltnisses und des aktuellen Zoomfaktors }
- if Zoom = 1 then
- begin
- { Anpassung an die Gr÷▀e des Clientbereichs }
- GetClientRect(HWindow,R);
- InflateRect(R,-1,-1);
- end
- else
- begin
- { Originalgr÷▀e }
- R.Left := 0;
- R.Top := 0;
- R.Right := LongInt(wx) * XLogPixels div MFInfo.FInfo.wInch;
- R.Bottom := LongInt(wy) * YLogPixels div MFInfo.FInfo.wInch;
- end;
-
- if R.Right > R.Bottom then
- begin
- f := Abs(wx / wy);
- cyMeta := R.Bottom;
- cxMeta := Round(cyMeta * f);
- if cxMeta > R.Right then
- begin
- cxMeta := R.Right;
- cyMeta := Round(cxMeta / f);
- end;
- end
- else
- begin
- f := Abs(wy / wx);
- cxMeta := R.Right;
- cyMeta := Round(cxMeta * f);
- if cyMeta > R.Bottom then
- begin
- cyMeta := R.Bottom;
- cxMeta := Round(cyMeta / f);
- end;
- end;
-
- if Zoom <> 0 then
- begin
- cxBitmap := Round(cxMeta*Zoom);
- cyBitmap := Round(cyMeta*Zoom);
- end
- else
- begin
- cxBitmap := cxMeta;
- cyBitmap := cyMeta;
- end;
-
- GetClientRect(HWindow,R);
- InflateRect(R,-1,-1);
- Scroller^.SetRange(Max(0,cxBitmap-R.Right),Max(0,cyBitmap-R.Bottom));
- Scroller^.SetPageSize;
- end;
-
- {-------------------------------------------------------------------------------
- Gibt die OffScreen-Bitmap frei und macht das Fenster ungⁿltig. Wird
- aufgerufen, wenn ein neuer Zoomfaktor eingestellt wird, wenn ein neues
- Metafile geladen wird oder wenn zwischen "Palette optimieren" und "Normal"
- umgeschaltet wird.
- }
- procedure TMWindow.RedrawWindow;
- begin
- if hbmClient <> 0 then
- begin
- DeleteObject(hbmClient);
- hbmClient := 0;
- end;
- CalcNewValues;
- InvalidateRect(HWindow,nil,true);
- end;
-
- {-------------------------------------------------------------------------------
- Behandelt den User-Dialog zum Laden einer Datei.
- }
- procedure TMWindow.IDMLoad (var Msg: TMessage);
- const
- DefExt = 'wmf';
-
- var
- OpenFN : TOpenFileName;
- Filter : array [0..100] of Char;
- FullFileName: array [0..255] of Char;
-
- begin
- { Filter fⁿr die Dateinamen aufbauen. Dieser mu▀ mit einer 00 beendet werden. }
- StrCopy(FullFileName, '');
- SetCurDir(HomeDir);
-
- FillChar(Filter, SizeOf(Filter), #0); { 00 am Ende! }
- StrCopy(Filter, 'Metadateien');
- StrCopy(@Filter[StrLen(Filter)+1], '*.wmf');
-
- FillChar(OpenFN, SizeOf(TOpenFileName), #0);
- with OpenFN do
- begin
- hInstance := HInstance;
- hwndOwner := HWindow;
- lpstrDefExt := DefExt;
- lpstrFile := FullFileName;
- lpstrFilter := Filter;
- lpstrFileTitle := nil;
- flags := ofn_FileMustExist or ofn_HideReadOnly;
- lStructSize := sizeof(TOpenFileName);
- nFilterIndex := 1; {Index in den String-Filter }
- nMaxFile := SizeOf(FullFileName);
- end;
-
- MFNoRecs := 0; { Anzahl der EintrΣge im Metafile ist noch unbekannt }
-
- if GetOpenFileName(OpenFN) then
- begin
- FileSplit(FullFileName,HomeDir,Filter,Filter);
- if HomeDir[StrLen(HomeDir)-1] = '\' then HomeDir[StrLen(HomeDir)-1] := #0;
- ProcessLoadFile(FullFileName);
- end;
- end;
-
-
- {-------------------------------------------------------------------------------
- "Hallo"-Dialog
- }
- procedure TMWindow.IDMAbout (var Msg: TMessage);
- begin
- Application^.ExecDialog(New(PCtrDialog,Init(@Self,'DLG_ABOUT',CTRDLG_PARENT)));
- end;
-
- {-------------------------------------------------------------------------------
- Menⁿoption schlie▀en
- }
- procedure TMWindow.IDMClose (var Msg: TMessage);
- begin
- PostMessage(HWindow,WM_CLOSE,0,0);
- end;
-
- {-------------------------------------------------------------------------------
- Schaltet die Palettenoptimierung ein oder aus.
- }
- procedure TMWindow.IDMPalOptimize (var Msg: TMessage);
- begin
- if PalOptimize then
- begin
- PalOptimize := not PalOptimize;
- CheckMenuItem(Attr.Menu,idm_PalOptimize,MF_UNCHECKED);
- if MFInfo.FInfo.hMF <> 0 then ProcessLoadFile(MFName);
- end
- else
- begin
- PalOptimize := not PalOptimize;
- CheckMenuItem(Attr.Menu,idm_PalOptimize,MF_CHECKED);
- if MFInfo.FInfo.hMF <> 0 then ProcessLoadFile(MFName);
- end;
- end;
-
-
- {-------------------------------------------------------------------------------
- Schaltet den Direkt-Modus ein oder aus.
- }
- procedure TMWindow.IDMDirectMode (var Msg: TMessage);
- begin
- if DirectMode then
- begin
- DirectMode := not DirectMode;
- CheckMenuItem(Attr.Menu,idm_DirectMode,MF_UNCHECKED);
- if MFInfo.FInfo.hMF <> 0 then ProcessLoadFile(MFName);
- end
- else
- begin
- DirectMode := not DirectMode;
- CheckMenuItem(Attr.Menu,idm_DirectMode,MF_CHECKED);
- if MFInfo.FInfo.hMF <> 0 then ProcessLoadFile(MFName);
- end;
- end;
-
- {-------------------------------------------------------------------------------
- }
- procedure TMWindow.IDMZoomOriginal (var Msg: TMessage);
- begin
- Zoom := 0;
- CheckMenuItem(Attr.Menu,LastZoomID,MF_UNCHECKED);
- CheckMenuItem(Attr.Menu,301,MF_CHECKED);
- HasBitmapMem := true;
- RedrawWindow;
- LastZoomID := 301;
- end;
-
- {-------------------------------------------------------------------------------
- }
- procedure TMWindow.IDMZoomClient (var Msg: TMessage);
- begin
- Zoom := 1;
- CheckMenuItem(Attr.Menu,LastZoomID,MF_UNCHECKED);
- CheckMenuItem(Attr.Menu,302,MF_CHECKED);
- HasBitmapMem := true;
- RedrawWindow;
- LastZoomID := 302;
- end;
-
- {-------------------------------------------------------------------------------
- }
- procedure TMWindow.IDMZoom200 (var Msg: TMessage);
- begin
- Zoom := 2;
- CheckMenuItem(Attr.Menu,LastZoomID,MF_UNCHECKED);
- CheckMenuItem(Attr.Menu,303,MF_CHECKED);
- HasBitmapMem := true;
- RedrawWindow;
- LastZoomID := 303;
- end;
-
- {-------------------------------------------------------------------------------
- }
- procedure TMWindow.IDMZoom400 (var Msg: TMessage);
- begin
- Zoom := 4;
- CheckMenuItem(Attr.Menu,LastZoomID,MF_UNCHECKED);
- CheckMenuItem(Attr.Menu,304,MF_CHECKED);
- HasBitmapMem := true;
- RedrawWindow;
- LastZoomID := 304;
- end;
-
- {-------------------------------------------------------------------------------
- }
- procedure TMWindow.IDMZoom50 (var Msg: TMessage);
- begin
- Zoom := 0.5;
- CheckMenuItem(Attr.Menu,LastZoomID,MF_UNCHECKED);
- CheckMenuItem(Attr.Menu,305,MF_CHECKED);
- HasBitmapMem := true;
- RedrawWindow;
- LastZoomID := 305;
- end;
-
- {-------------------------------------------------------------------------------
- }
- procedure TMWindow.IDMZoom25 (var Msg: TMessage);
- begin
- Zoom := 0.25;
- CheckMenuItem(Attr.Menu,LastZoomID,MF_UNCHECKED);
- CheckMenuItem(Attr.Menu,306,MF_CHECKED);
- HasBitmapMem := true;
- RedrawWindow;
- LastZoomID := 306;
- end;
-
- {-------------------------------------------------------------------------------
- Drag 'n Drop
- Behandelt das Ablegen von Dateien aus dem Dateimanager.
- }
- procedure TMWindow.WMDropFiles (var Msg: TMessage);
- var
- Name : array[0..255] of Char;
- wFiles: Word;
- begin
- Msg.Result := 0; { "Botschaft verarbeitet" }
-
- wFiles := DragQueryFile(Msg.wParam, $FFFF, nil, 0);
-
- if wFiles > 1 then
- begin
- MessageBox(HWindow,'Diese Anwendung kann nur einzelne Dateien anzeigen',AppName,
- mb_Ok or mb_IconExclamation);
- end
- else
- begin
- if IsIconic(HWindow) then Show(sw_ShowNormal);
- { Die erste Datei holen }
- DragQueryFile(Msg.wParam, 0, Name, SizeOf(Name));
- MFNoRecs := 0; { Anzahl der EintrΣge ist noch unbekannt }
- ProcessLoadFile(Name);
- end;
-
- { Freigabe des durch wm_DropFiles belegten Speichers }
- DragFinish(Msg.wParam);
- end;
-
- {-------------------------------------------------------------------------------
- Lie▀t die EintrΣge aus der INI-Datei
- }
- procedure TMWindow.ReadINIData;
- begin
- GetPrivateProfileString(AppName,'lastdir','',HomeDir,SizeOf(HomeDir),'WMFVIEW.INI');
- end;
-
- {-------------------------------------------------------------------------------
- }
- procedure TMWindow.WriteINIData;
- begin
- WritePrivateProfileString(AppName,'lastdir',HomeDir,'WMFVIEW.INI');
- end;
-
- {*******************************************************************************}
- { TAnApplication }
- {*******************************************************************************}
- type
- TAnApplication = object(TApplication)
- procedure InitMainWindow; virtual;
- end;
-
- procedure TAnApplication.InitMainWindow;
- begin
- MainWindow := New(PMWindow, Init(nil, AppName));
- end;
-
-
- {*******************************************************************************}
- { M A I N }
- {*******************************************************************************}
- var
- MyApp : TAnApplication;
-
- begin
- MyApp.Init(AppName);
- MyApp.Run;
- MyApp.Done;
- end.
-
-