{"id":162,"date":"2019-09-30T22:19:27","date_gmt":"2019-09-30T19:19:27","guid":{"rendered":"http:\/\/www.potansif.com\/?p=162"},"modified":"2019-10-01T15:17:26","modified_gmt":"2019-10-01T12:17:26","slug":"dokuman-onizleme-bileseni-previewhandler","status":"publish","type":"post","link":"http:\/\/www.potansif.com\/?p=162","title":{"rendered":"D\u00f6k\u00fcman \u00d6nizleme Bile\u015feni &#8211; PreviewHandler"},"content":{"rendered":"<p>Merhaba,<\/p>\n<p>Bazen geli\u015ftirdi\u011fimiz uygulamalarda word, excel, pdf gibi d\u00f6k\u00fcmanlar\u0131 kullan\u0131c\u0131ya bir tercih sunabilmek i\u00e7in belgeyi\u00a0a\u00e7madan \u00f6nce \u00f6nizleme uygulamam\u0131zda bir\u00a0\u00f6nizlemesini yapt\u0131rmak isteyebiliriz. Windows Vista \/ Windows Server 2008 ile birlikte iki API yay\u0131nland\u0131, bu API&#8217;ler arac\u0131l\u0131y\u011f\u0131yla kendi uygulamalar\u0131m\u0131zda bu t\u00fcr bir y\u00f6ntemi kolayl\u0131kla kullanabilir hale geldik. Tam kaynak kodunu verece\u011fim unit&#8217;i bir bile\u015fen olacak \u015fekilde kurgulad\u0131m. Payla\u015ft\u0131\u011f\u0131m bu kodlar\u0131n son s\u00fcr\u00fcm\u00fcn\u00fc\u00a0<a href=\"https:\/\/github.com\/uparlayan\/PreviewHandler-VCL-\">https:\/\/github.com\/uparlayan\/PreviewHandler-VCL-<\/a>\u00a0linkinden takip edebilirsiniz.<br \/>\n<!--more--><br \/>\nGerekli a\u00e7\u0131klamalar kod i\u00e7inde yer alaca\u011f\u0131ndan fazla detaya girmiyorum, i\u015fte kodlar;<\/p>\n<pre><code>\/\/\/ &lt;summary&gt;\r\n\/\/\/ \u00a0Windows i\u015fletim sisteminin IPreviewHandler apisini kullanarak d\u00f6k\u00fcman \u00f6nizleme yap\u0131labilmesini sa\u011flayan\r\n\/\/\/ \u00a0bile\u015fendir.\r\n\/\/\/ &lt;\/summary&gt;\r\n\/\/\/ \u00a0&lt;example&gt;\r\n\/\/\/ \u00a0 \u00a0\u00d6rnek kullan\u0131m i\u00e7in a\u015fa\u011f\u0131daki kodu inceleyebilirsiniz\r\n\/\/\/ \u00a0&lt;code lang=\"Delphi\"&gt;\r\n\/\/\/ \u00a0unit Unit1;\r\n\/\/\/\r\n\/\/\/ \u00a0interface\r\n\/\/\/\r\n\/\/\/ \u00a0uses\r\n\/\/\/ \u00a0 \u00a0Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,\r\n\/\/\/ \u00a0 \u00a0Dialogs, ComCtrls, ShellCtrls, ExtCtrls, StdCtrls, dxPreviewHandler, Vcl.FileCtrl, cxGraphics, cxControls,\r\n\/\/\/ \u00a0 \u00a0cxLookAndFeels, cxLookAndFeelPainters, cxContainer, cxEdit, dxSkinsCore, dxSkinVS2010, cxGroupBox;\r\n\/\/\/\r\n\/\/\/ \u00a0type\r\n\/\/\/ \u00a0 \u00a0TForm1 = class(TForm)\r\n\/\/\/ \u00a0 \u00a0 \u00a0Panel1 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0: TPanel;\r\n\/\/\/ \u00a0 \u00a0 \u00a0Panel2 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0: TPanel;\r\n\/\/\/ \u00a0 \u00a0 \u00a0DirectoryListBox1 : TDirectoryListBox;\r\n\/\/\/ \u00a0 \u00a0 \u00a0FileListBox1 \u00a0 \u00a0 \u00a0: TFileListBox;\r\n\/\/\/ \u00a0 \u00a0 \u00a0DriveComboBox1 \u00a0 \u00a0: TDriveComboBox;\r\n\/\/\/ \u00a0 \u00a0 \u00a0Splitter1 \u00a0 \u00a0 \u00a0 \u00a0 : TSplitter;\r\n\/\/\/ \u00a0 \u00a0 \u00a0Splitter2 \u00a0 \u00a0 \u00a0 \u00a0 : TSplitter;\r\n\/\/\/ \u00a0 \u00a0 \u00a0dxPreviewHandler1 : TdxPreviewHandler;\r\n\/\/\/ \u00a0 \u00a0 \u00a0procedure FormCreate(Sender: TObject);\r\n\/\/\/ \u00a0 \u00a0 \u00a0procedure FileListBox1Click(Sender: TObject);\r\n\/\/\/ \u00a0 \u00a0 \u00a0procedure Panel1Resize(Sender: TObject);\r\n\/\/\/ \u00a0 \u00a0private\r\n\/\/\/ \u00a0 \u00a0public\r\n\/\/\/ \u00a0 \u00a0end;\r\n\/\/\/\r\n\/\/\/ \u00a0var\r\n\/\/\/ \u00a0 \u00a0Form1: TForm1;\r\n\/\/\/\r\n\/\/\/ \u00a0implementation\r\n\/\/\/\r\n\/\/\/ \u00a0{$R *.dfm}\r\n\/\/\/\r\n\/\/\/ \u00a0procedure TForm1.FormCreate(Sender: TObject);\r\n\/\/\/ \u00a0begin\r\n\/\/\/ \u00a0 \u00a0DriveComboBox1.DirList := DirectoryListBox1;\r\n\/\/\/ \u00a0 \u00a0DirectoryListBox1.FileList := FileListBox1;\r\n\/\/\/ \u00a0 \u00a0dxPreviewHandler1.Control := Panel1;\r\n\/\/\/ \u00a0end;\r\n\/\/\/\r\n\/\/\/ \u00a0procedure TForm1.FileListBox1Click(Sender: TObject);\r\n\/\/\/ \u00a0begin\r\n\/\/\/ \u00a0 \u00a0if (FileExists(FileListBox1.FileName, True) = TRUE) then begin\r\n\/\/\/ \u00a0 \u00a0 \u00a0 \u00a0dxPreviewHandler1.FileName := FileListBox1.FileName;\r\n\/\/\/ \u00a0 \u00a0 \u00a0 \u00a0dxPreviewHandler1.Preview;\r\n\/\/\/ \u00a0 \u00a0end;\r\n\/\/\/ \u00a0end;\r\n\/\/\/\r\n\/\/\/ \u00a0procedure TForm1.Panel1Resize(Sender: TObject);\r\n\/\/\/ \u00a0begin\r\n\/\/\/ \u00a0 \u00a0dxPreviewHandler1.Resize;\r\n\/\/\/ \u00a0end;\r\n\/\/\/\r\n\/\/\/ \u00a0end.\r\n\/\/\/ \u00a0&lt;\/code&gt;\r\n\/\/\/ \u00a0&lt;\/example&gt;\r\n\/\/\/ &lt;remarks&gt;\r\n\/\/\/ \u00a0Copyright \u00a9 U\u011fur PARLAYAN (01.05.2013) L\u00fctfen kaynak belirterek kullan\u0131n\u0131z.\r\n\/\/\/ &lt;\/remarks&gt;\r\nunit dxPreviewHandler;\r\n\u00a0\r\ninterface\r\n\u00a0\r\nuses\r\n\u00a0StdCtrls,\r\n\u00a0Registry, ComObj, ActiveX, AxCtrls, ShlObj,\r\n\u00a0Windows, Classes, Controls, SysUtils, Dialogs;\r\n\u00a0\r\ntype\r\n\u00a0\/\/\/ &lt;summary&gt;\r\n\u00a0\/\/\/ \u00a0Detaylar\u0131na \u015fu linkten ula\u015fabilirsiniz;\r\n\u00a0\/\/\/ \u00a0&lt;see href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/windows\/desktop\/bb761818(v=vs.85).aspx\" \/&gt;\r\n\u00a0\/\/\/ &lt;\/summary&gt;\r\n\u00a0IInitializeWithFile \u00a0 = interface(IUnknown) ['{b7d14566-0509-4cce-a71f-0a554233bd9b}']\r\n\u00a0 \u00a0function Initialize(pszFilePath: LPWSTR; grfMode: DWORD):HRESULT; stdcall;\r\n\u00a0end;\r\n\u00a0\r\n\u00a0\/\/\/ &lt;summary&gt;\r\n\u00a0\/\/\/ \u00a0Detaylar\u0131na \u015fu linkten ula\u015fabilirsiniz;\r\n\u00a0\/\/\/ \u00a0&lt;see href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/windows\/desktop\/bb761810(v=vs.85).aspx\" \/&gt;\r\n\u00a0\/\/\/ &lt;\/summary&gt;\r\n\u00a0IInitializeWithStream = interface(IUnknown) ['{b824b49d-22ac-4161-ac8a-9916e8fa3f7f}']\r\n\u00a0 \u00a0function Initialize(pstream: IStream; grfMode: DWORD): HRESULT; stdcall;\r\n\u00a0end;\r\n\u00a0\r\n\u00a0\/\/\/ &lt;summary&gt;\r\n\u00a0\/\/\/ \u00a0Detaylar\u0131na \u015fu linkten ula\u015fabilirsiniz;\r\n\u00a0\/\/\/ \u00a0&lt;see href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/windows\/desktop\/cc144143(v=vs.85).aspx\" \/&gt;\r\n\u00a0\/\/\/ &lt;\/summary&gt;\r\n\u00a0IPreviewHandler \u00a0 \u00a0 \u00a0 = interface(IUnknown) ['{8895b1c6-b41f-4c1c-a562-0d564250836f}']\r\n\u00a0 \u00a0function SetWindow(hwnd: HWND; var RectangleRef: TRect): HRESULT; stdcall;\r\n\u00a0 \u00a0function SetRect(var RectangleRef: TRect): HRESULT; stdcall;\r\n\u00a0 \u00a0function DoPreview(): HRESULT; stdcall;\r\n\u00a0 \u00a0function Unload(): HRESULT; stdcall;\r\n\u00a0 \u00a0function SetFocus(): HRESULT; stdcall;\r\n\u00a0 \u00a0function QueryFocus(phwnd: HWND): HRESULT; stdcall;\r\n\u00a0 \u00a0function TranslateAccelerator(PointerToWindowMessage: MSG): HRESULT; stdcall;\r\n\u00a0end;\r\n\r\n\u00a0TdxPreviewHandler = class(TComponent)\r\n\u00a0private\r\n\u00a0 \u00a0FFileName : string; \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \/\/ G\u00f6sterilecek dosyan\u0131n yolu ve ad\u0131 bu de\u011fi\u015fkende saklanacakt\u0131r.\r\n\u00a0 \u00a0FHandler \u00a0: IPreviewHandler; \u00a0\/\/ Bu arabirim arac\u0131l\u0131\u011f\u0131yla api \u00e7a\u011f\u0131r\u0131lacakt\u0131r.\r\n\u00a0 \u00a0FControl \u00a0: TWinControl; \u00a0 \u00a0 \u00a0\/\/ Bu nesne \u00fczerinde \u00f6nizleme yap\u0131lacakt\u0131r.\r\n\u00a0 \u00a0FClassID \u00a0: String; \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \/\/ Bir TGUID de\u011feri bar\u0131nd\u0131rmaktad\u0131r.\r\n\u00a0 \u00a0FKip \u00a0 \u00a0 \u00a0: String; \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \/\/ PreviewFile prosed\u00fcr\u00fcnde kullan\u0131lan en son kipi tutar.\r\n\r\n\u00a0 \u00a0\/\/\/ &lt;summary&gt;\r\n\u00a0 \u00a0\/\/\/ \u00a0PreviewFile prosed\u00fcr\u00fcn\u00fc tetikleyecek \u015fekilde g\u00f6r\u00fcnt\u00fclenmek istenen dosyan\u0131n tam yolunu ve ad\u0131n\u0131 vermemizi sa\u011flar.\r\n\u00a0 \u00a0\/\/\/ &lt;\/summary&gt;\r\n\u00a0 \u00a0procedure SetFileName(const Value: string);\r\n\u00a0\r\n\u00a0 \u00a0\/\/\/ &lt;summary&gt;\r\n\u00a0 \u00a0\/\/\/ \u00a0FControl \u00fczerine binecek \u015fekilde belgeyi g\u00f6r\u00fcnt\u00fcler.\r\n\u00a0 \u00a0\/\/\/ &lt;\/summary&gt;\r\n\u00a0 \u00a0procedure PreviewFile;\r\n\u00a0\r\n\u00a0 \u00a0\/\/\/ &lt;summary&gt;\r\n\u00a0 \u00a0\/\/\/ \u00a0Dosyan\u0131n uzant\u0131s\u0131n\u0131 okur.\r\n\u00a0 \u00a0\/\/\/ &lt;\/summary&gt;\r\n\u00a0 \u00a0function GetFileExt: String;\r\n\u00a0\r\n\u00a0 \u00a0\/\/\/ &lt;summary&gt;\r\n\u00a0 \u00a0\/\/\/ \u00a0Dosya uzant\u0131s\u0131n\u0131n Registry'deki Preview Handler'inin s\u0131n\u0131f kimli\u011fini okur.\r\n\u00a0 \u00a0\/\/\/ &lt;\/summary&gt;\r\n\u00a0 \u00a0function GetClassID: String;\r\n\u00a0protected\r\n\u00a0public\r\n\u00a0 \u00a0\/\/\/ &lt;summary&gt;\r\n\u00a0 \u00a0\/\/\/ \u00a0Klasik Create yordam\u0131ndan farkl\u0131 olarak nesnenin runtime an\u0131nda bir preview alan\u0131na do\u011frudan ba\u011flanarak\r\n\u00a0 \u00a0\/\/\/ \u00a0\u00fcretilmesini sa\u011flar.\r\n\u00a0 \u00a0\/\/\/ &lt;\/summary&gt;\r\n\u00a0 \u00a0\/\/\/ &lt;param name=\"aOwner\"&gt;\r\n\u00a0 \u00a0\/\/\/ \u00a0TComponent t\u00fcr\u00fcnden Parent nesne kastedilmektedir.\r\n\u00a0 \u00a0\/\/\/ &lt;\/param&gt;\r\n\u00a0 \u00a0\/\/\/ &lt;param name=\"aControl\"&gt;\r\n\u00a0 \u00a0\/\/\/ \u00a0TWinControl t\u00fcr\u00fcnden bir nesne, mesela TPanel veya (DevEx'in) TcxGroupBox gibi nesneleri kastedilmektedir.\r\n\u00a0 \u00a0\/\/\/ &lt;\/param&gt;\r\n\u00a0 \u00a0constructor Create(aOwner: TComponent; aControl: TWinControl); overload;\r\n\u00a0\r\n\u00a0 \u00a0\/\/\/ &lt;summary&gt;\r\n\u00a0 \u00a0\/\/\/ \u00a0Nesne yok edilirken kulland\u0131\u011f\u0131 IPreviewHandler ba\u011flant\u0131s\u0131n\u0131 da yok etmelidir. IPreviewHandler.Unload\r\n\u00a0 \u00a0\/\/\/ \u00a0metoduyla birlikte nesne yok edilir.\r\n\u00a0 \u00a0\/\/\/ &lt;\/summary&gt;\r\n\u00a0 \u00a0destructor Destroy; override;\r\n\u00a0\r\n\u00a0 \u00a0\/\/\/ &lt;summary&gt;\r\n\u00a0 \u00a0\/\/\/ \u00a0IPreviewHandler.Unload medorunu \u00e7a\u011f\u0131r\u0131r.\r\n\u00a0 \u00a0\/\/\/ &lt;\/summary&gt;\r\n\u00a0 \u00a0procedure Bosalt;\r\n\u00a0\r\n\u00a0 \u00a0\/\/\/ &lt;summary&gt;\r\n\u00a0 \u00a0\/\/\/ \u00a0FControl nesnesinin \u00fczerine binecek \u015fekilde belgeyi ekranda g\u00f6r\u00fcnt\u00fclemek i\u00e7in PreviewFile prosed\u00fcr\u00fcn\u00fc \u00e7a\u011f\u0131r\u0131r.\r\n\u00a0 \u00a0\/\/\/ &lt;\/summary&gt;\r\n\u00a0 \u00a0procedure Preview;\r\n\u00a0\r\n\u00a0 \u00a0\/\/\/ &lt;summary&gt;\r\n\u00a0 \u00a0\/\/\/ \u00a0Bile\u015fen d\u0131\u015f\u0131ndan da referans azalt\u0131m\u0131n\u0131 kullanabilmek i\u00e7in IPreviewHandler._Release metodunu \u00e7a\u011f\u0131r\u0131r.\r\n\u00a0 \u00a0\/\/\/ &lt;\/summary&gt;\r\n\u00a0 \u00a0procedure _DelRef; deprecated; { \u00d6nerilmez... }\r\n\u00a0\r\n\u00a0 \u00a0\/\/\/ &lt;summary&gt;\r\n\u00a0 \u00a0\/\/\/ \u00a0D\u00f6k\u00fcman\u0131n g\u00f6sterilece\u011fi b\u00f6lgenin yeniden hesaplanmas\u0131nda kullan\u0131l\u0131r.\r\n\u00a0 \u00a0\/\/\/ &lt;\/summary&gt;\r\n\u00a0 \u00a0\/\/\/ &lt;remarks&gt;\r\n\u00a0 \u00a0\/\/\/ \u00a0FControl nesnesinin resize olay\u0131 tetiklenirken bu prosed\u00fcr \u00e7a\u011f\u0131r\u0131lmal\u0131d\u0131r.\r\n\u00a0 \u00a0\/\/\/ &lt;\/remarks&gt;\r\n\u00a0 \u00a0procedure Resize;\r\n\u00a0\r\n\u00a0published\r\n\u00a0 \u00a0\/\/\/ &lt;summary&gt;\r\n\u00a0 \u00a0\/\/\/ \u00a0Dosyan\u0131n uzant\u0131s\u0131n\u0131 verir.\r\n\u00a0 \u00a0\/\/\/ &lt;\/summary&gt;\r\n\u00a0 \u00a0property FileExt \u00a0: String \u00a0 \u00a0 \u00a0read GetFileExt;\r\n\u00a0\r\n\u00a0 \u00a0\/\/\/ &lt;summary&gt;\r\n\u00a0 \u00a0\/\/\/ \u00a0Dosyan\u0131n path'iyle birlikte tam ad\u0131n\u0131 verir. \u00d6rn: \"C:\\depo\\test.pdf\" gibi...\r\n\u00a0 \u00a0\/\/\/ &lt;\/summary&gt;\r\n\u00a0 \u00a0property FileName : String \u00a0 \u00a0 \u00a0read FFileName \u00a0 \u00a0 \u00a0write SetFileName;\r\n\u00a0\r\n\u00a0 \u00a0\/\/\/ &lt;summary&gt;\r\n\u00a0 \u00a0\/\/\/ \u00a0Registry'de dosya uzant\u0131s\u0131n\u0131 a\u00e7acak olan Preview Handler nesnesinin s\u0131n\u0131f kimli\u011fini verir.\r\n\u00a0 \u00a0\/\/\/ &lt;\/summary&gt;\r\n\u00a0 \u00a0property ClassID \u00a0: String \u00a0 \u00a0 \u00a0read FClassID; \/\/ Registry'den okuma i\u015flemini GetClassID fonksiyonu ger\u00e7ekle\u015ftirir. Burada de\u011fi\u015fken kullan\u0131lmas\u0131n\u0131n sebebi Registry trafi\u011fini azaltmak i\u00e7indir.\r\n\u00a0\r\n\u00a0 \u00a0\/\/\/ &lt;summary&gt;\r\n\u00a0 \u00a0\/\/\/ \u00a0Belge bu nesnenin \u00fczerinde g\u00f6r\u00fcnt\u00fclenir.\r\n\u00a0 \u00a0\/\/\/ &lt;\/summary&gt;\r\n\u00a0 \u00a0property Control \u00a0: TWinControl read FControl \u00a0 \u00a0 \u00a0 write FControl;\r\n\u00a0end;\r\n\r\nconst\r\n\u00a0 \u00a0 E_PREVIEWHANDLER_DRM_FAIL \u00a0 = $86420001;\r\n\u00a0 \u00a0 E_PREVIEWHANDLER_NOAUTH \u00a0 \u00a0 = $86420002;\r\n\u00a0 \u00a0 E_PREVIEWHANDLER_NOTFOUND \u00a0 = $86420003;\r\n\u00a0 \u00a0 E_PREVIEWHANDLER_CORRUPT \u00a0 \u00a0= $86420004;\r\n\u00a0\r\nprocedure Register;\r\n\r\nimplementation\r\n\r\nprocedure Register;\r\nbegin\r\n\u00a0RegisterComponents('UpDevEx', [TdxPreviewHandler]);\r\nend;\r\n\r\n{ TdxPreviewHandler }\r\n\u00a0\r\nconstructor TdxPreviewHandler.Create(aOwner: TComponent; aControl: TWinControl);\r\nbegin\r\n\u00a0inherited Create(aOwner);\r\n\u00a0Control := aControl;\r\nend;\r\n\u00a0\r\ndestructor TdxPreviewHandler.Destroy;\r\nbegin\r\n\u00a0{ FHandler interface taraf\u0131ndan hal\u00e2 kullan\u0131ld\u0131\u011f\u0131 i\u00e7in yok etme i\u015flemi interface taraf\u0131ndan ger\u00e7ekle\u015ftiriliyor... Ayr\u0131ca bir destroy, free ve nil sekans\u0131na girilmesine gerek yok... }\r\n\u00a0inherited Destroy;\r\nend;\r\n\u00a0\r\nprocedure TdxPreviewHandler.Bosalt;\r\nbegin\r\n\u00a0if (Assigned(FHandler) = TRUE) then begin\r\n\u00a0 \u00a0 \u00a0FHandler.Unload;\r\n\u00a0end;\r\nend;\r\n\u00a0\r\nprocedure TdxPreviewHandler._DelRef;\r\nbegin\r\n\u00a0if (Assigned(FHandler) = TRUE) then begin\r\n\u00a0 \u00a0 \u00a0FHandler._Release;\r\n\u00a0end;\r\nend;\r\n\u00a0\r\nfunction TdxPreviewHandler.GetClassID: String;\r\nvar\r\n\u00a0aRegistry \u00a0: \u00a0TRegistry;\r\n\u00a0aExtens \u00a0 \u00a0,\r\n\u00a0aRegPath \u00a0 : \u00a0String;\r\nbegin\r\n\u00a0Result     := '';\r\n\u00a0aRegistry \u00a0:= TRegistry.Create();\r\n\u00a0try\r\n\u00a0 \u00a0aRegistry.RootKey := HKEY_CLASSES_ROOT;\r\n\u00a0 \u00a0aExtens \u00a0:= GetFileExt; { mesela '.pdf' veya '.docx' gibi... }\r\n\u00a0 \u00a0aRegPath := aExtens + '\\shellex\\{8895b1c6-b41f-4c1c-a562-0d564250836f}';\r\n\u00a0 \u00a0if (aRegistry.KeyExists(aRegPath) = TRUE) then begin\r\n\u00a0 \u00a0 \u00a0 \u00a0aRegistry.Access := KEY_READ; { 32 ve 64 bit windows i\u015fletim sistemlerinde registry'e eri\u015fim farkl\u0131 kaynaklardan ger\u00e7ekle\u015fiyor... }\r\n\u00a0 \u00a0 \u00a0 \u00a0aRegistry.OpenKey(aRegPath, FALSE);\r\n\u00a0 \u00a0 \u00a0 \u00a0Result := aRegistry.ReadString(''); { Varsay\u0131lan de\u011feri okur. Bu bile\u015fen i\u00e7in bu kadar\u0131 yeterlidir... }\r\n\u00a0 \u00a0 \u00a0 \u00a0aRegistry.CloseKey;\r\n\u00a0 \u00a0end;\r\n\u00a0finally\r\n\u00a0 \u00a0FreeAndNil(aRegistry);\r\n\u00a0end;\r\n\u00a0FClassID := Result;\r\nend;\r\n\u00a0\r\nfunction TdxPreviewHandler.GetFileExt: String;\r\nbegin\r\n\u00a0Result := ExtractFileExt(FFileName);\r\nend;\r\n\u00a0\r\nprocedure TdxPreviewHandler.PreviewFile;\r\nvar\r\n\u00a0aGUID \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 : TGUID;\r\n\u00a0aRect \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 : TRect;\r\n\u00a0FileInit \u00a0 \u00a0 \u00a0 \u00a0 \u00a0: IInitializeWithFile;\r\n\u00a0StreamInit \u00a0 \u00a0 \u00a0 \u00a0: IInitializeWithStream;\r\n\u00a0FS \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0: TFileStream;\r\n\u00a0SA \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0: IStream;\r\n\u00a0TamponBellek \u00a0 \u00a0 \u00a0: TMemoryStream;\r\n\u00a0Mesaj \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 : String;\r\n\u00a0X: Integer;\r\nbegin\r\n\u00a0FKip := ''; \/\/ Ba\u015flang\u0131\u00e7 de\u011feridir.\r\n\u00a0\r\n\u00a0{ \u00d6n izlemenin yap\u0131laca\u011f\u0131 konteyner bir nesne yoksa do\u011frudan \u00e7\u0131k\u0131l\u0131r... }\r\n\u00a0if (Assigned(FControl) = False) then Exit;\r\n\u00a0\r\n\u00a0FClassID := GetClassID;\r\n\u00a0\r\n\u00a0{ Dosya uzant\u0131s\u0131n\u0131 a\u00e7acak bir preview handler ID'si yok demektir... }\r\n\u00a0if (FClassID = '') then Exit;\r\n\u00a0\r\n\u00a0{\r\n\u00a0 \u00a0FHandler olu\u015fturulmu\u015fsa \u015fu an bellekte bir dosya preview olarak g\u00f6steriliyor demektir. Bu durumda API 2 yoldan birini kendisi se\u00e7ecektir;\r\n\u00a0 \u00a01) Ya yeni bir FHandler arabirimi \u00fcretip yeni belgeyi ona y\u00fckleyecek,\r\n\u00a0 \u00a02) Ya da mevcut FHandler arabirimindeki belgeyi bellekten kald\u0131r\u0131p yenisini y\u00fckleyecek...\r\n\u00a0 \u00a0IPreviewHandler.Unload metodu bize 2. se\u00e7ene\u011fi uygulama \u015fans\u0131 veriyor. B\u00f6ylece arka taraftaki Referans say\u0131mlar\u0131nda\r\n\u00a0 \u00a0mevcut referans\u0131 azaltmakla, yani IPreviewHandler._Release ile u\u015fra\u015fmak zorunda kalm\u0131yoruz. Zira _Release'nin\r\n\u00a0 \u00a0RefCount de\u011feri 0'a ula\u015ft\u0131\u011f\u0131nda arabirim kendisini destroy ediyor dolay\u0131s\u0131yla arabirimi yeniden \u00fcretmek\r\n\u00a0 \u00a0gerekebiliyor, \u00e7ok kar\u0131\u015f\u0131k o nedenle buraya hi\u00e7 girmemek en iyi \u00e7\u00f6z\u00fcm bence...\r\n\u00a0 \u00a0Yani \u00f6zetle unload metodu bellekteki IPreview arabirimini yok etmeden sadece dosya ba\u011flant\u0131s\u0131n\u0131 kesip ilgili\r\n\u00a0 \u00a0dosyan\u0131n bellekteki yerini s\u0131f\u0131rl\u0131yor ve yeni bir dosya y\u00fckleyebilmemize olanak tan\u0131yor.\r\n\u00a0 \u00a0Bunun i\u00e7in BOSALT adl\u0131 bir prosed\u00fcr ekledim.\r\n\u00a0}\r\n\u00a0if Assigned(FHandler) then FHandler.Unload;\r\n\u00a0\r\n\u00a0aGUID \u00a0 \u00a0:= StringToGUID(FClassID);\r\n\u00a0FHandler := CreateComObject(aGUID) as IPreviewHandler;\r\n\u00a0\r\n\u00a0{ \u0130\u015fletim sisteminde Dosya uzant\u0131s\u0131n\u0131 a\u00e7abilecek tan\u0131ml\u0131 bir Preview Handler \"nesnesi\" yok demektir... Dolay\u0131s\u0131yla \u00e7\u0131k\u0131yoruz...\r\n\u00a0 \u00a0Bu durum daha \u00e7ok kurulup kald\u0131r\u0131ld\u0131ktan sonra registry'deki \u00e7\u00f6plerini temizlemeyen programlar nedeniyle ortaya \u00e7\u0131kar... }\r\n\u00a0if (FHandler = nil) then Exit;\r\n\u00a0\r\n\u00a0{ Bunu daha \u00e7ok word ve excel kullan\u0131yor... }\r\n\u00a0if (FHandler.QueryInterface(IInitializeWithFile, FileInit) = 0) then begin\r\n\u00a0 \u00a0 \u00a0FileInit.Initialize(StringToOleStr(FFileName), STGM_READ or STGM_SHARE_DENY_NONE);\r\n\u00a0 \u00a0 \u00a0FKip := 'fileinit';\r\n\u00a0end;\r\n\u00a0{ Bu noktada ELSE kullan\u0131lmamas\u0131n\u0131n sebebi arabirimin her iki metodu da ayn\u0131 anda destekleyebilecek \u015fekilde tasarlanmas\u0131ndan kaynaklan\u0131yor olabilir. Test edilmeli... UP }\r\n\u00a0\r\n\u00a0{ Bunu da daha \u00e7ok Acrobat Reader kullan\u0131yor... }\r\n\u00a0if (FHandler.QueryInterface(IInitializeWithStream, StreamInit) = 0) then begin\r\n\u00a0 \u00a0 \u00a0{ Hem dosya, hem de bellek ak\u0131\u015f\u0131 kullanmam\u0131z\u0131n tek bir nedeni var. Dosya ak\u0131\u015f\u0131 kulland\u0131\u011f\u0131m\u0131zda i\u015fletim sistemi\r\n\u00a0 \u00a0 \u00a0 \u00a0dosyay\u0131 (biz her ne kadar ShareDenyNone desek bile) bir sebepten dolay\u0131 i\u015flem g\u00f6ren bir dosya olarak alg\u0131l\u0131yor,\r\n\u00a0 \u00a0 \u00a0 \u00a0Bu sorunu a\u015fman\u0131n en basit yolu dosyay\u0131 belle\u011fe kopyalay\u0131p bellek kopyas\u0131 \u00fczerinde i\u015flem yapmak. O nedenle dosyay\u0131\r\n\u00a0 \u00a0 \u00a0 \u00a0diskten okuduktan sonra do\u011fruadn belle\u011fe al\u0131yoruz ve dosyay\u0131 kapat\u0131yoruz. Bu sayede \"Dosya ba\u015fka bir i\u015flem\r\n\u00a0 \u00a0 \u00a0 \u00a0taraf\u0131ndan kullan\u0131l\u0131yor...\" gibi bir hata ile muhatap olmuyoruz... Aksi durumda dosyay\u0131 kendimiz a\u00e7t\u0131\u011f\u0131m\u0131z\r\n\u00a0 \u00a0 \u00a0 \u00a0halde silememe gibi sorunlarla kar\u015f\u0131la\u015f\u0131rd\u0131k...\r\n\u00a0 \u00a0 \u00a0}\r\n\u00a0 \u00a0 \u00a0try\r\n\u00a0 \u00a0 \u00a0 \u00a0try\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0FS := TFileStream.Create(FFileName, fmOpenRead or fmShareDenyNone); \/\/ Dosyay\u0131 oku, payla\u015f\u0131m i\u00e7in herhangi bir kilit koyma, di\u011fer programlar da o dosyaya eri\u015febilsin...\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0if (Assigned(FS) = TRUE) then begin\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0TamponBellek:= TMemoryStream.Create;\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0TamponBellek.Clear;\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0TamponBellek.Size := FS.Size;\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0TamponBellek.CopyFrom(FS, FS.Size);\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0end;\r\n\u00a0 \u00a0 \u00a0 \u00a0finally\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0FS.Free; { Nihayetinde dosyay\u0131 kapat... Dosya diskte dursun, zaten yerini biliyoruz... }\r\n\u00a0 \u00a0 \u00a0 \u00a0end;\r\n\u00a0 \u00a0 \u00a0finally\r\n\u00a0 \u00a0 \u00a0 \u00a0SA := TStreamAdapter.Create(TamponBellek, soOwned) as IStream;\r\n\u00a0 \u00a0 \u00a0 \u00a0StreamInit.Initialize(SA, STGM_READ or STGM_SHARE_DENY_NONE);\r\n\u00a0\r\n\u00a0 \u00a0 \u00a0 \u00a0if \u00a0(FKip &lt;&gt; '')\r\n\u00a0 \u00a0 \u00a0 \u00a0then FKip := format('%s + %s', [FKip, 'streaminit'])\r\n\u00a0 \u00a0 \u00a0 \u00a0else FKip := 'streaminit';\r\n\u00a0 \u00a0 \u00a0end;\r\n\u00a0end;\r\n\u00a0\r\n\u00a0{\r\n\u00a0 \u00a0Acrobat ve MS Office aras\u0131nda IPreviewHandler arabiriminin kullan\u0131m\u0131yla ilgili temel bir farkl\u0131l\u0131k var.\r\n\u00a0 \u00a0Ofis, yeni bir dosya eklenece\u011fi zaman kendisini kapat\u0131p yeni dosyayla birlikte belle\u011fe yeniden y\u00fckleniyor.\r\n\u00a0 \u00a0Acrobat ise ayn\u0131 durumda kendisini kapatm\u0131yor, sadece eski dosyay\u0131 kapat\u0131p yeni dosyay\u0131 y\u00fckl\u00fcyor.\r\n\u00a0 \u00a0O nedenle birisi fileinit'i di\u011feri ise FileStream'i kullan\u0131yor. Yani normalde olmas\u0131 gereken ofisin y\u00f6ntemi\r\n\u00a0 \u00a0fakat StreamInit if blo\u011fundaki i\u015flemi baz\u0131 programlar kendi i\u00e7inde de\u011fil, bizim yapmam\u0131z\u0131 ye\u011fliyor. Temel fark asl\u0131nda bu...\r\n\u00a0}\r\n\u00a0\r\n\u00a0ARect := Rect( 0, 0, FControl.Width, FControl.Height);\r\n\u00a0try\r\n\u00a0 \u00a0FHandler.SetWindow(FControl.Handle, aRect);\r\n\u00a0 \u00a0FHandler.SetRect(aRect);\r\n\u00a0\r\n\u00a0 \u00a0case FHandler.DoPreview of\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0S_OK \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 : Mesaj := ''; \/\/ 'The operation completed successfully.';\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0E_PREVIEWHANDLER_DRM_FAIL \u00a0 \u00a0: Mesaj := 'Telif haklar\u0131 gere\u011fi bu dosya dijital haklar y\u00f6netimi taraf\u0131ndan engellendi.'; \/\/'Blocked by digital rights management.';\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0E_PREVIEWHANDLER_NOAUTH \u00a0 \u00a0 \u00a0: Mesaj := 'Dosya izinleri engellendi.'; \/\/ 'Blocked by file permissions.';\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0E_PREVIEWHANDLER_NOTFOUND \u00a0 \u00a0: Mesaj := 'Nesne bulunamad\u0131.'; \/\/ 'Item was not found.';\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0E_PREVIEWHANDLER_CORRUPT \u00a0 \u00a0 : Mesaj := '\u00d6nizleme yapan program d\u00fczg\u00fcn y\u00fcklenmemi\u015f veya ilgili fonksiyonu bozuk.'#13#10\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0+ 'Bu noktada a\u011f y\u00f6neticinizden yard\u0131m talep edebilirsiniz; A\u011f y\u00f6neticiniz \u015funlar\u0131 yapmal\u0131d\u0131r;'#13#10#13#10\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0+ ' 1) \u0130lgili program\u0131 bilgisayar\u0131n\u0131zdan kald\u0131r\u0131n (uninstall)'#13#10\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0+ ' 2) Kald\u0131rma i\u015flemi bittikten sonra Registry kay\u0131tlar\u0131n\u0131 temizleyen programlardan biriyle (CCleaner gibi) temizlik yap\u0131n'#13#10\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0+ ' 3) Kald\u0131rd\u0131\u011f\u0131n\u0131z program\u0131n eskiden kurulu oldu\u011fu Klas\u00f6rleri silin (Genelde Program Files klas\u00f6r\u00fcn\u00fcn alt\u0131nda olurlar)'#13#10\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0+ ' 4) 2. ad\u0131m\u0131 tekrar yap\u0131n'#13#10\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0+ ' 5) Bilgisayar\u0131n\u0131z\u0131 yeniden ba\u015flat\u0131n'#13#10\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0+ ' 6) Kald\u0131rd\u0131\u011f\u0131n\u0131z program\u0131 sa\u011fl\u0131kl\u0131 bir \u015fekilde yeniden kurun'#13#10\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0; \/\/ 'Item was corrupt.';\r\n\u00a0 \u00a0end;\r\n\u00a0\r\n\u00a0 \u00a0if (Mesaj &lt;&gt; '') then begin\r\n\u00a0 \u00a0 \u00a0 \u00a0ShowMessage('DoPreview : ' + Mesaj);\r\n\u00a0 \u00a0end;\r\n\u00a0 \u00a0FHandler._AddRef; { Referans say\u0131m\u0131n\u0131 tetiklemek ve yeni bir dosyan\u0131n y\u00fcklendi\u011fini IPreviewHandler arabirimine bildirmek i\u00e7in bu \u015fart... }\r\n\u00a0except\r\n\u00a0 \u00a0FHandler.Unload;\r\n\u00a0end;\r\nend;\r\n\u00a0\r\nprocedure TdxPreviewHandler.Resize;\r\nvar\r\n\u00a0aRect: TRect;\r\nbegin\r\n\u00a0if (Assigned(FControl) = True) then begin\r\n\u00a0 \u00a0 \u00a0if (FControl.Visible = TRUE) then begin\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0if (Assigned(FHandler) = True) then begin\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0try\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0aRect := Rect( 0, 0, FControl.Width, FControl.Height);\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0FHandler.SetWindow(FControl.Handle, aRect);\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0FHandler.SetRect(aRect);\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0\/\/ FHandler.DoPreview; \u00a0 \u00a0 \u00a0\/\/ gereksiz...\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0\/\/ FHandler.SetFocus; \u00a0 \u00a0 \u00a0 \/\/ gereksiz...\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0if pos('streaminit', FKip) &gt; 0 then FHandler._AddRef; \/\/ \u015eart ! .... Referans say\u0131m\u0131n\u0131 tetiklemek ve yeni bir dosyan\u0131n y\u00fcklendi\u011fini IPreviewHandler arabirimine bildirmek i\u00e7in bu \u015fart...\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0except\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0on E: Exception do ShowMessage('Hata: ' + E.Message);\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0end;\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0end;\r\n\u00a0 \u00a0 \u00a0end;\r\n\u00a0end;\r\nend;\r\n\u00a0\r\nprocedure TdxPreviewHandler.Preview;\r\nbegin\r\n\u00a0 PreviewFile;\r\nend;\r\n\u00a0\r\nprocedure TdxPreviewHandler.SetFileName(const Value: string);\r\nbegin\r\n\u00a0 if not FileExists(Value, True) then exit; \/\/ dosya yoksa do\u011frudan \u00e7\u0131k...\r\n\u00a0 if Trim(FFileName) = Trim(Value) then Exit; \/\/ Ayn\u0131 \u015feyi arka arkaya y\u00fcklememek i\u00e7indir...\r\n\u00a0 FFileName := Value;\r\n\u00a0 if \u00a0(GetClassID &lt;&gt; '')\r\n\u00a0 then PreviewFile \u00a0\/\/ Destekleniyorsa belgeyi ekranda g\u00f6sterir.\r\n\u00a0 else Bosalt; \u00a0 \u00a0 \u00a0\/\/ Desteklenmiyorsa ekran\u0131 ve belle\u011fi temizler.\r\nend;\r\n\u00a0\r\nend.<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>azen geli\u015ftirdi\u011fimiz uygulamalarda word, excel, pdf gibi d\u00f6k\u00fcmanlar\u0131 kullan\u0131c\u0131ya bir tercih sunabilmek i\u00e7in belgeyi\u00a0a\u00e7madan \u00f6nce \u00f6nizleme uygulamam\u0131zda bir\u00a0\u00f6nizlemesini yapt\u0131rmak isteyebiliriz. Windows Vista \/ Windows Server 2008 ile birlikte iki API yay\u0131nland\u0131, bu API&#8217;ler arac\u0131l\u0131y\u011f\u0131yla kendi uygulamalar\u0131m\u0131zda bu t\u00fcr bir y\u00f6ntemi kolayl\u0131kla kullanabilir hale geldik. Tam kaynak kodunu verece\u011fim unit&#8217;i bir bile\u015fen olacak \u015fekilde kurgulad\u0131m.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3],"tags":[4,21],"class_list":["post-162","post","type-post","status-publish","format-standard","hentry","category-blog","tag-delphi","tag-previewhandler"],"_links":{"self":[{"href":"http:\/\/www.potansif.com\/index.php?rest_route=\/wp\/v2\/posts\/162","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/www.potansif.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.potansif.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.potansif.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.potansif.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=162"}],"version-history":[{"count":7,"href":"http:\/\/www.potansif.com\/index.php?rest_route=\/wp\/v2\/posts\/162\/revisions"}],"predecessor-version":[{"id":257,"href":"http:\/\/www.potansif.com\/index.php?rest_route=\/wp\/v2\/posts\/162\/revisions\/257"}],"wp:attachment":[{"href":"http:\/\/www.potansif.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=162"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.potansif.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=162"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.potansif.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=162"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}