Changes On Branch updatecheck
Not logged in

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Changes In Branch updatecheck Excluding Merge-Ins

This is equivalent to a diff from 81540a5449 to f09c69e9b9

2018-03-21
18:08
Delphi 10.2.2 Tokyo check-in: 58587b2302 user: tinus tags: trunk
2017-05-14
14:31
Added Win64 platform support. Fixed the most egregious errors wrt bitness. Leaf check-in: f09c69e9b9 user: tinus tags: updatecheck
2017-02-19
20:38
Implemented updating and replacing of plugin. check-in: 6d33ea7784 user: tinus tags: updatecheck
17:30
Merged in trunk, and incorporated some fixes for Win64. check-in: 23338c7949 user: tinus tags: updatecheck
2017-02-08
16:04
Added versionable ignore-glob. Updated and normalized Delphi project (10.1 Berlin Update 2). check-in: 81540a5449 user: tinus tags: trunk
2017-02-07
20:56
Merge with v1.2 fix. check-in: 388a0bb939 user: tinus tags: trunk

Added .fossil-settings/encoding-glob.


1
+
*

Changes to .fossil-settings/ignore-glob.

1

2
3
4
5
6
7
8

9
10
11
12
13
14
15
1
2
3


4
5
6
7
8
9
10
11
12
13
14


+

-
-




+






-
*/__history/*
*/__recovery/*
out/
*.dcu
*.exe
*.local
*.identcache
*.dsk
*.stat
*.tvsconfig
~*.*
*.~*
*.bak
*.rej
*.org
*.res
*/__recover/*

Added src/Debug.pas.












































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
unit Debug;

interface

procedure ODS(const DebugOutput: string); overload;
procedure ODS(const DebugOutput: string; const Args: array of const); overload;

implementation
uses
  Classes, SysUtils,
  Windows,
  L_SpecialFolders;

var
  OutputLog: TStreamWriter;

{ ------------------------------------------------------------------------------------------------ }
procedure ODS(const DebugOutput: string); overload;
begin
  OutputDebugString(PChar('PreviewHTML['+IntToHex(GetCurrentThreadId, 4)+']: ' + DebugOutput));
  {$IFDEF DEBUG}
  if OutputLog = nil then begin
    OutputLog := TStreamWriter.Create(TFileStream.Create(ChangeFileExt(TSpecialFolders.DLLFullName, '.log'), fmCreate or fmShareDenyWrite), TEncoding.UTF8);
    OutputLog.OwnStream;
    OutputLog.BaseStream.Seek(0, soFromEnd);
  end;
  OutputLog.Write(FormatDateTime('yyyy-MM-dd hh:nn:ss.zzz: ', Now));
  OutputLog.WriteLine(DebugOutput.Replace(#10, #10 + StringOfChar(' ', 25)));
  {$ENDIF}
end {ODS};
{ ------------------------------------------------------------------------------------------------ }
procedure ODS(const DebugOutput: string; const Args: array of const); overload;
begin
  ODS(Format(DebugOutput, Args));
end{ODS};


initialization

finalization
  OutputLog.Free;

end.

Changes to src/F_PreviewHTML.pas.

66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
66
67
68
69
70
71
72



73
74
75
76
77

78
79
80
81
82
83





















84
85
86
87
88
89
90







-
-
-





-
+
+
+



-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







    procedure ForgetBuffer(const BufferID: TBufferID);
    procedure DisplayPreview(HTML: string; const BufferID: TBufferID);
  end;

var
  frmHTMLPreview: TfrmHTMLPreview;

procedure ODS(const DebugOutput: string); overload;
procedure ODS(const DebugOutput: string; const Args: array of const); overload;

////////////////////////////////////////////////////////////////////////////////////////////////////
implementation
uses
  ShellAPI, ComObj, StrUtils, IOUtils, Masks, MSHTML,
  RegExpr, L_SpecialFolders,
  WebBrowser, SciSupport, U_Npp_PreviewHTML;
  WebBrowser, SciSupport,
  Debug,
  U_Npp_PreviewHTML;

{$R *.dfm}

var
  OutputLog: TStreamWriter;

{ ------------------------------------------------------------------------------------------------ }
procedure ODS(const DebugOutput: string); overload;
begin
  OutputDebugString(PChar('PreviewHTML['+IntToHex(GetCurrentThreadId, 4)+']: ' + DebugOutput));
  if OutputLog = nil then begin
    OutputLog := TStreamWriter.Create(TFileStream.Create(ChangeFileExt(TSpecialFolders.DLLFullName, '.log'), fmCreate or fmShareDenyWrite), TEncoding.UTF8);
    OutputLog.OwnStream;
    OutputLog.BaseStream.Seek(0, soFromEnd);
  end;
  OutputLog.Write(FormatDateTime('yyyy-MM-dd hh:nn:ss.zzz: ', Now));
  OutputLog.WriteLine(DebugOutput);
end {ODS};
{ ------------------------------------------------------------------------------------------------ }
procedure ODS(const DebugOutput: string; const Args: array of const); overload;
begin
  ODS(Format(DebugOutput, Args));
end{ODS};


{ ================================================================================================ }

{ ------------------------------------------------------------------------------------------------ }
procedure TfrmHTMLPreview.FormCreate(Sender: TObject);
begin
  FScrollPositions := TDictionary<TBufferID,TPoint>.Create;
717
718
719
720
721
722
723
724
725
726
727
728
729
695
696
697
698
699
700
701





702







-
-
-
-
-

procedure TfrmHTMLPreview.wbIETitleChange(ASender: TObject; const Text: WideString);
begin
  inherited;
  self.UpdateDisplayInfo(StringReplace(Text, 'about:blank', '', [rfReplaceAll]));
end;


initialization

finalization
  OutputLog.Free;

end.

Added src/U_AutoUpdate.pas.































































































































































































































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
unit U_AutoUpdate;

interface

uses
  SysUtils;

type
  TPluginUpdate = class
  private
    FURL: string;
//    FOnProgress: TProgressEvent; // TODO: see L_HttpClient
    FLatestVersion: string;

    function GetCurrentVersion: string;
    function GetLatestVersion: string;
  public
    constructor Create{(const AURL: string)};

    function IsUpdateAvailable(out NewVersion, Changes: string): Boolean;
    function DownloadUpdate: string;
    function ReplacePlugin(const PathDownloaded: string): Boolean;

    property URL: string            read FURL;

    property CurrentVersion: string read GetCurrentVersion;
    property LatestVersion: string  read GetLatestVersion;
  public
    class function CompareVersions(const VersionA, VersionB: string): Integer;
  end;

  EUpdateError = class(Exception);

implementation
uses
  Classes, RegularExpressions, Windows, NetEncoding, Zip,
  L_HttpClient, L_VersionInfoW, L_SpecialFolders,
  Debug;

{ ------------------------------------------------------------------------------------------------ }
{ TPluginUpdate }

{ ------------------------------------------------------------------------------------------------ }
constructor TPluginUpdate.Create;
begin
  //FURL := AURL;
end {TPluginUpdate.Create};

{ ------------------------------------------------------------------------------------------------ }
function TPluginUpdate.GetCurrentVersion: string;
begin
  with TFileVersionInfo.Create(TSpecialFolders.DLLFullName) do begin
    Result := FileVersion;
    Free;
  end;
end {TPluginUpdate.GetCurrentVersion};

{ ------------------------------------------------------------------------------------------------ }
function TPluginUpdate.GetLatestVersion: string;
begin
  // TODO
end {TPluginUpdate.GetLatestVersion};

{ ------------------------------------------------------------------------------------------------ }
function TPluginUpdate.IsUpdateAvailable(out NewVersion, Changes: string): Boolean;
var
  Http: THttpClient;
  Notes: string;
  Matches: TMatchCollection;
  Match: TMatch;
  s: string;
  FirstPos, LastPos: Integer;
begin
  // Download the current release notes
  ODS('Create HttpClient');
  Http := THttpClient.Create('http://fossil.2of4.net/npp_preview/doc/publish/ReleaseNotes.txt');
  try
    ODS('Http.Get');
    if Http.Get() = 200 then begin
      ODS('%d %s', [Http.StatusCode, Http.StatusText]);
      for s in Http.ResponseHeaders do
        ODS(s);
      // get the response stream, and look for the latest version in there
      Notes := Http.ResponseString;
      ODS('Response: "%s"', [Copy(StringReplace(StringReplace(Notes, #10, '·', [rfReplaceAll]), #13, '·', [rfReplaceAll]), 1, 250)]);

      NewVersion := '';
      FirstPos := -1;
      LastPos := -1;

      Matches := TRegEx.Matches(Notes, 'v[0-9]+(\.[0-9]+){3}');
      ODS('Matches: %d', [Matches.Count]);
      for Match in Matches do begin
        ODS('Match: Success=%s; Value="%s"; Index=%d', [BoolToStr(Match.Success, True), Match.Value, Match.Index]);
        if NewVersion = '' then
          NewVersion := Match.Value;
        if FirstPos = -1 then
          FirstPos := Match.Index;
        if CompareVersions(CurrentVersion, Match.Value) <= 0 then begin
          // This version is equal or older than the current version
          LastPos := Match.Index;
          Break;
        end;
      end {for};

      if FirstPos = -1 then
        FirstPos := Notes.IndexOf('<pre>') + 5;
      if (LastPos = -1) or (LastPos = FirstPos) then
        LastPos := Notes.IndexOf('</pre>');

      Changes := Notes.Substring(FirstPos - 1, LastPos - FirstPos);
      ODS('NewVersion: "%s"; Changes: "%s"', [NewVersion, Changes]);

      Changes := TNetEncoding.HTML.Decode(Changes.Trim);
    end else begin
      // TODO: show message, open project's main page?
      raise EUpdateError.CreateFmt('%d %s', [Http.StatusCode, Http.StatusText]);
    end;
  finally
    Http.Free;
  end;

  Result := CompareVersions(CurrentVersion, NewVersion) > 0;

  FLatestVersion := NewVersion;
end {TPluginUpdate.IsUpdateAvailable};

{ ------------------------------------------------------------------------------------------------ }
function TPluginUpdate.DownloadUpdate: string;
var
  Http: THttpClient;
  FS: TFileStream;
begin
  // TODO: Download http://fossil.2of4.net/npp_preview/zip/Preview_Plugin.zip?uuid=publish&name=plugins to a temp dir,
  //  extract it to a custom temp folder, and return that folder's path
  Http := THttpClient.Create('http://fossil.2of4.net/npp_preview/zip/Preview_Plugin.zip?uuid=publish&name=plugins');
  try
    if Http.Get() = 200 then begin
      Result := TSpecialFolders.TempDll + 'Preview_Plugin.zip';
      FS := TFileStream.Create(Result, fmCreate or fmShareDenyWrite);
      try
        FS.CopyFrom(Http.ResponseStream, 0);
      finally
        FS.Free;
      end;
    end else begin
      // TODO: show message, open project's main page?
      raise EUpdateError.CreateFmt('%d %s', [Http.StatusCode, Http.StatusText]);
    end;
  finally
    Http.Free;
  end;
end {TPluginUpdate.DownloadUpdate};

{ ------------------------------------------------------------------------------------------------ }
function TPluginUpdate.ReplacePlugin(const PathDownloaded: string): Boolean;
var
  NppDir: string;
  Zip: TZipFile;
  i: Integer;
  Info: TZipHeader;
  Name: string;
  Backup: string;
begin
  NppDir := TSpecialFolders.DLL + '..\';

  Zip := TZipFile.Create;
  try
    ODS(PathDownloaded);
    Zip.Open(PathDownloaded, zmRead);
    for i := 0 to Zip.FileCount - 1 do begin
      Info := Zip.FileInfo[i];
      Name := Zip.FileName[i].Replace('/', '\');
      ODS(Name);

      if Name.EndsWith('\') then Continue; // Skip directories

      if SameFileName(ExtractFileName(Name), 'ReleaseNotes.txt') then begin
        Name := Name.Replace('ReleaseNotes.txt', 'Doc\PreviewHTML\ReleaseNotes.txt', [rfIgnoreCase]);
        ODS('=> ' + Name);
      end;

      if FileExists(NppDir + Name) then begin
        Backup := NppDir + ChangeFileExt(Name, '-' + CurrentVersion + ExtractFileExt(Name));
        if SameFileName(ExtractFileExt(Name), '.dll') then begin
          Backup := ChangeFileExt(Backup, '.~' + ExtractFileExt(Backup).Substring(1));
          ODS('Backup: ' + Backup);
          Win32Check(RenameFile(NppDir + Name, Backup));
        end else begin
          ODS('Backup: ' + Backup);
          Win32Check(CopyFile(PChar(NppDir + Name), PChar(Backup), False));
        end;
      end;

      ODS('Extracting file to: ' + NppDir + Name);
      ForceDirectories(ExtractFileDir(NppDir + Name));
      Zip.Extract(i, ExtractFileDir(NppDir + Name), False);
    end {for};
  finally
    Zip.Free;
  end;

  // TODO: Rename the current DLL to ChangeFileExt(DllName, '-' + OwnVersion + '.~dll')
  // HardlinkOrCopy all files in extract location to path relative to plugins folder. ./Config should
  //  be translated to PluginsConfigFolder. ReleaseNotes.txt gets special treatment: it's in the
  //  root folder, but should be moved to ./Doc/PreviewHTML.
  Result := True;
end {TPluginUpdate.ReplacePlugin};

{ ------------------------------------------------------------------------------------------------ }
class function TPluginUpdate.CompareVersions(const VersionA, VersionB: string): Integer;
var
  va, vb: string;
  na, nb: Integer;
  Code: Integer;
begin
  Result := 0;
  if (VersionA = '') or (VersionB = '') then
    Exit;

  if VersionA[1] = 'v' then va := Copy(VersionA, 2) else va := VersionA;
  if VersionB[1] = 'v' then vb := Copy(VersionB, 2) else vb := VersionB;

  repeat
    na := 0;
    if va <> '' then begin
//ODS('va: "%s"; na: %d', [va, na]);
      Val(va, na, Code);
//ODS('va: "%s"; na: %d; Code: %d', [va, na, Code]);
      if Code in [0, 1] then
        va := ''
      else
        va := Copy(va, Code + 1);
    end;

    nb := 0;
    if vb <> '' then begin
//ODS('vb: "%s"; nb: %d', [vb, nb]);
      Val(vb, nb, Code);
//ODS('vb: "%s"; nb: %d; Code: %d', [vb, nb, Code]);
      if Code in [0, 1] then
        vb := ''
      else
        vb := Copy(vb, Code + 1);
    end;

    Result := nb - na;
//ODS('Result = %d := %d - %d', [Result, nb, na]);
    if Result <> 0 then
      Exit;
  until (va = '') and (vb = '');
end {TPluginUpdate.CompareVersions};

end.

Changes to src/U_CustomFilter.pas.

34
35
36
37
38
39
40

41
42
43
44
45
46
47
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48







+








////////////////////////////////////////////////////////////////////////////////////////////////////
implementation

uses
  IOUtils,
  process, Pipes,
  Debug,
  F_PreviewHTML;

{ TCustomFilterThread }

{ ------------------------------------------------------------------------------------------------ }
constructor TCustomFilterThread.Create(const Data: TFilterData);
begin

Changes to src/U_Npp_PreviewHTML.pas.

8
9
10
11
12
13
14

15
16
17
18
19
20
21
22
23
24


25
26
27
28


29
30
31
32
33
34

35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55


56
57
58

59
60

61
62
63
64
65
66
67
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23


24
25
26
27


28
29
30
31
32
33
34

35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55

56
57
58
59

60
61

62
63
64
65
66
67
68
69







+








-
-
+
+


-
-
+
+





-
+




















-
+
+


-
+

-
+







  NppPlugin, SciSupport,
  F_About, F_PreviewHTML;

type
  TNppPluginPreviewHTML = class(TNppPlugin)
  private
    FSettings: TIniFile;
    FUpdated: Boolean;
  public
    constructor Create;

    procedure SetInfo(NppData: TNppData); override;

    procedure CommandShowPreview;
    procedure CommandSetIEVersion(const BrowserEmulation: Integer);
    procedure CommandOpenFile(const Filename: nppString);
    procedure CommandShowAbout;
    procedure CommandReplaceHelloWorld;
    procedure CommandCheckUpdates;
    procedure CommandShowAbout;

    procedure DoNppnToolbarModification; override;
    procedure DoNppnFileClosed(const BufferID: Cardinal); override;
    procedure DoNppnBufferActivated(const BufferID: Cardinal); override;
    procedure DoNppnFileClosed(const BufferID: THandle); override;
    procedure DoNppnBufferActivated(const BufferID: THandle); override;
    procedure DoModified(const hwnd: HWND; const modificationType: Integer); override;

    function  GetSettings(const Name: string = 'Settings.ini'): TIniFile;
  end {TNppPluginPreviewHTML};

procedure _FuncReplaceHelloWorld; cdecl;
procedure _FuncCheckUpdate; cdecl;
procedure _FuncShowPreview; cdecl;
procedure _FuncOpenSettings; cdecl;
procedure _FuncOpenFilters; cdecl;
procedure _FuncShowAbout; cdecl;

procedure _FuncSetIE7; cdecl;
procedure _FuncSetIE8; cdecl;
procedure _FuncSetIE9; cdecl;
procedure _FuncSetIE10; cdecl;
procedure _FuncSetIE11; cdecl;
procedure _FuncSetIE12; cdecl;
procedure _FuncSetIE13; cdecl;


var
  Npp: TNppPluginPreviewHTML;

////////////////////////////////////////////////////////////////////////////////////////////////////
implementation
uses
  WebBrowser, Registry;
  WebBrowser, Registry,
  U_AutoUpdate;

{ ------------------------------------------------------------------------------------------------ }
procedure _FuncReplaceHelloWorld; cdecl;
procedure _FuncCheckUpdate; cdecl;
begin
  Npp.CommandReplaceHelloWorld;
  Npp.CommandCheckUpdates;
end;
{ ------------------------------------------------------------------------------------------------ }
procedure _FuncOpenSettings; cdecl;
begin
  Npp.CommandOpenFile('Settings.ini');
end;
{ ------------------------------------------------------------------------------------------------ }
170
171
172
173
174
175
176
177




178
179


















































180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252









253
254
255
256
257
258
259








+
+
+
+


+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

















-
-
-
-
-
-
-
-
-








  self.AddFuncSeparator;

  self.AddFuncItem('Edit &settings', _FuncOpenSettings);
  self.AddFuncItem('Edit &filter definitions', _FuncOpenFilters);

  self.AddFuncSeparator;

  self.AddFuncItem('Check for &updates', _FuncCheckUpdate);

  self.AddFuncSeparator;

  self.AddFuncItem('&About', _FuncShowAbout);
end {TNppPluginPreviewHTML.SetInfo};

{ ------------------------------------------------------------------------------------------------ }
procedure TNppPluginPreviewHTML.CommandCheckUpdates;
const
  scYesNo: array[Boolean] of string = ('No', 'Yes');
var
  Current, Latest, Notes: string;
  Update: TPluginUpdate;
  ZipPath: string;
begin
  try
    if FUpdated then begin
      MessageBox(Npp.NppData.NppHandle, 'Please restart Notepad++ first!', PChar(Caption), MB_ICONWARNING);
      Exit;
    end;

    Update := TPluginUpdate.Create;
    try
      Current := Update.CurrentVersion;
      if not Update.IsUpdateAvailable(Latest, Notes) then begin
        MessageBox(Npp.NppData.NppHandle,
                   PChar(Format('Nothing to update!'#10#10'Your current version of this plugin, v%s, is the most recent one.',
                                [Current])), PChar(Caption),
                   MB_ICONINFORMATION);
        Exit;
      end;

      if ID_YES = MessageBox(Npp.NppData.NppHandle,
                             PChar(Format('Update available!'#10#10
                                        + 'Your current version of this plugin, v%0:s, is out of date.'
                                        + ' We recommend you update to version %1:s.'#10#10
                                        + 'These are the changes since the current version:'#10#10
                                        + '%2:s'#10#10
                                        + 'Do you want to download and install %1:s?',
                                          [Current, Latest, Notes])),
                             PChar(Caption), MB_YESNO or MB_DEFBUTTON1 or MB_ICONQUESTION) then begin
        ZipPath := Update.DownloadUpdate;
        FUpdated := Update.ReplacePlugin(ZipPath);
        if FUpdated then
          MessageBox(Npp.NppData.NppHandle,
                     'Update completed. Please restart Notepad++ to use the updated plugin.',
                     PChar(Caption), MB_ICONINFORMATION);
      end;
    finally
      Update.Free;
    end;
  except
    ShowException(ExceptObject, ExceptAddr);
  end;
end {TNppPluginPreviewHTML.CommandCheckUpdate};

{ ------------------------------------------------------------------------------------------------ }
procedure TNppPluginPreviewHTML.CommandOpenFile(const Filename: nppString);
var
  FullPath: nppString;
begin
  try
    FullPath := Npp.ConfigDir + '\PreviewHTML\' + Filename;
    if not FileExists(FullPath) and FileExists(ChangeFileExt(FullPath, '.sample' + ExtractFileExt(FullPath))) then
      FullPath := ChangeFileExt(FullPath, '.sample' + ExtractFileExt(FullPath));
    if not DoOpen(FullPath) then
      MessageBox(Npp.NppData.NppHandle, PChar(Format('Unable to open "%s".', [FullPath])), PChar(Caption), MB_ICONWARNING);
  except
    ShowException(ExceptObject, ExceptAddr);
  end;
end {TNppPluginPreviewHTML.CommandOpenFilters};

{ ------------------------------------------------------------------------------------------------ }
procedure TNppPluginPreviewHTML.CommandReplaceHelloWorld;
var
  s: UTF8String;
begin
  s := 'Hello World';
  SendMessage(self.NppData.ScintillaMainHandle, SCI_REPLACESEL, 0, LPARAM(PAnsiChar(s)));
end {TNppPluginPreviewHTML.CommandReplaceHelloWorld};

{ ------------------------------------------------------------------------------------------------ }
procedure TNppPluginPreviewHTML.CommandSetIEVersion(const BrowserEmulation: Integer);
begin
  if GetBrowserEmulation <> BrowserEmulation then begin
    SetBrowserEmulation(BrowserEmulation);
    MessageBox(Npp.NppData.NppHandle,
                PChar(Format('The preview browser mode has been set to correspond to Internet Explorer version %d.'#13#10#13#10 +
268
269
270
271
272
273
274
275

276
277
278
279
280
281
282
283
284

285
286
287
288
289
290
291
315
316
317
318
319
320
321

322
323
324
325
326
327
328
329
330

331
332
333
334
335
336
337
338







-
+








-
+







  SendMessage(self.NppData.NppHandle, NPPM_ADDTOOLBARICON, WPARAM(self.CmdIdFromDlgId(0)), LPARAM(@tb));

//  SendMessage(self.NppData.ScintillaMainHandle, SCI_SETMODEVENTMASK, SC_MOD_INSERTTEXT or SC_MOD_DELETETEXT, 0);
//  SendMessage(self.NppData.ScintillaSecondHandle, SCI_SETMODEVENTMASK, SC_MOD_INSERTTEXT or SC_MOD_DELETETEXT, 0);
end {TNppPluginPreviewHTML.DoNppnToolbarModification};

{ ------------------------------------------------------------------------------------------------ }
procedure TNppPluginPreviewHTML.DoNppnBufferActivated(const BufferID: Cardinal);
procedure TNppPluginPreviewHTML.DoNppnBufferActivated(const BufferID: THandle);
begin
  inherited;
  if Assigned(frmHTMLPreview) and frmHTMLPreview.Visible then begin
    frmHTMLPreview.btnRefresh.Click;
  end;
end {TNppPluginPreviewHTML.DoNppnBufferActivated};

{ ------------------------------------------------------------------------------------------------ }
procedure TNppPluginPreviewHTML.DoNppnFileClosed(const BufferID: Cardinal);
procedure TNppPluginPreviewHTML.DoNppnFileClosed(const BufferID: THandle);
begin
  if Assigned(frmHTMLPreview) then begin
    frmHTMLPreview.ForgetBuffer(BufferID);
  end;
  inherited;
end {TNppPluginPreviewHTML.DoNppnFileClosed};

Added src/common/L_HttpClient.pas.











































































































































































































































































































































































































































































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
unit L_HttpClient;

interface
uses
  SysUtils, Classes, WinInet;

type
  THttpConnectEnum = (
    hcDirect          = INTERNET_OPEN_TYPE_DIRECT,
    hcPreconfig       = INTERNET_OPEN_TYPE_PRECONFIG,
    hcPreconfigNoAuto = INTERNET_OPEN_TYPE_PRECONFIG_WITH_NO_AUTOPROXY,
    hcProxy           = INTERNET_OPEN_TYPE_PROXY
  );

  THttpClient = class;
  TProgressNotify = procedure(Sender: THttpClient; Msg: string; BytesRead, TotalBytes: Cardinal; out Cancel: Boolean) of object;

  THttpClient = class
    private
      FhReq: HINTERNET;
      FOnProgress: TProgressNotify;
      FURL: string;

      function  SendRequestAndGetResponse(const Verb, Resource: string;
                                          const Data: Pointer; const DataSize: Cardinal;
                                          Flags: Cardinal = 0): integer;
      procedure ReadResponseHeaders;
    protected
      FPath: string;
      FRequestHeaders: TStringList;
      FResponseStatus: cardinal;
      FResponseStatusText: string;
      FResponseHeaders: TStringList;
      FResponseStream: TMemoryStream;

      function QueryInfoString(const InfoFlag: cardinal): string; overload; inline;
      function QueryInfoString(const InfoFlag: cardinal; out Value: string): boolean; overload;
      function QueryInfoInteger(const InfoFlag: cardinal): cardinal; overload; inline;
      function QueryInfoInteger(const InfoFlag: cardinal; out Value: cardinal): Boolean; overload; inline;

      function GetResponseString: string; // RawString
    public
      UserAgent: string;
      Hostname: string;
      Port: integer;
      UseProxy: THttpConnectEnum;
      Proxy, ProxyByPass: string;
      UserName: string;
      Password: string;
      ConnectTimeout, SendTimeout, ReceiveTimeout: Cardinal;

      constructor Create(const URL: string); overload;
      constructor Create(const Hostname, Path: string; const Port: integer = INTERNET_DEFAULT_HTTP_PORT); overload;
      destructor  Destroy; override;

      function Head(Path: string = ''; const BypassCache: Boolean = False): integer;
      function Get(Path: string = ''; const BypassCache: Boolean = False): integer;
      function Post(Data: string): integer; overload;
      function Post(Data: TStream): integer; overload;
      function Post(Path: string; Data: string): integer; overload;
      function Post(Path: string; Data: TStream): integer; overload;

      property Path: string                   read FPath;
      property RequestHeaders: TStringList    read FRequestHeaders;
      property StatusCode: cardinal           read FResponseStatus;
      property StatusText: string             read FResponseStatusText;
      property ResponseHeaders: TStringList   read FResponseHeaders;
      property ResponseStream: TMemoryStream  read FResponseStream;
      property ResponseString: string         read GetResponseString; // RawString
      property URL: string                    read FURL;

      property OnProgress: TProgressNotify    read FOnProgress  write FOnProgress;
  end;

type
  EHttpError = class(Exception);


implementation
uses
  Windows, Math;

const
  READBUFFERSIZE = 4096;
  ERROR_INSUFFICIENT_BUFFER = 122;   { dderror }

resourcestring
  scConnecting =  'Connecting';
  scUploading  =  'Sending';
  scDownloading = 'Receiving';
  scFinished    = 'Done';

{ ================================================================================================ }
{ THttpClient }

{ ------------------------------------------------------------------------------------------------ }
constructor THttpClient.Create(const URL: string);
var
  UC: URL_COMPONENTS;
begin
  UC.dwStructSize := sizeof(UC);
  UC.lpszScheme := nil;
  UC.dwSchemeLength := 0;
  UC.nScheme := INTERNET_SCHEME_UNKNOWN;
  UC.lpszHostName := PChar(StringOfChar(#0, Length(URL) + 1));
  UC.dwHostNameLength := Length(URL) + 1;
  UC.nPort := INTERNET_INVALID_PORT_NUMBER;
  UC.lpszUserName := PChar(StringOfChar(#0, Length(URL) + 1));
  UC.dwUserNameLength := Length(URL) + 1;
  UC.lpszPassword := PChar(StringOfChar(#0, Length(URL) + 1));
  UC.dwPasswordLength := Length(URL) + 1;
  UC.lpszUrlPath := PChar(StringOfChar(#0, Length(URL) + 1));
  UC.dwUrlPathLength := Length(URL) + 1;
  UC.lpszExtraInfo := nil;
  UC.dwExtraInfoLength := 0;

  Win32Check(InternetCrackUrl(PChar(URL), 0, 0, UC));
  if not UC.nScheme in [INTERNET_SCHEME_HTTP, INTERNET_SCHEME_HTTPS, INTERNET_SCHEME_FILE] then begin
    raise EHttpError.CreateFmt('Unsupported scheme used in URL "%s". Only http:// and https:// are supported', [URL]);
  end;
  Create(UC.lpszHostName, UC.lpszUrlPath, UC.nPort);
  Self.UserName := UC.lpszUserName;
  Self.Password := UC.lpszPassword;
end {THttpClient.Create};
{ ------------------------------------------------------------------------------------------------ }
constructor THttpClient.Create(const Hostname, Path: string; const Port: integer);
var
  UC: URL_COMPONENTS;
  Buffer: string;
  Size: Cardinal;
begin
  FPath := Path;
  Self.UserAgent := ChangeFileExt(ExtractFileName(ParamStr(0)), '');
  Self.Hostname := Hostname;
  Self.Port := Port;
  Self.UseProxy := hcPreconfig;
  FRequestHeaders := TStringList.Create;
  FRequestHeaders.NameValueSeparator := ':';
  ConnectTimeout := 0;
  SendTimeout := 0;
  ReceiveTimeout := 0;

  Size := INTERNET_MAX_URL_LENGTH;
  SetLength(Buffer, Size);
  if InternetCreateUrl(UC, ICU_ESCAPE, PChar(Buffer), Size) then begin
    FURL := Copy(Buffer, 1, Size);
  end else if GetLastError = ERROR_INSUFFICIENT_BUFFER then begin
    SetLength(Buffer, Size);
    if InternetCreateUrl(UC, ICU_ESCAPE, PChar(Buffer), Size) then begin
      FURL := Copy(Buffer, 1, Size);
    end;
  end;
end {THttpClient.Create};
{ ------------------------------------------------------------------------------------------------ }
destructor THttpClient.Destroy;
begin
  if Assigned(FResponseStream) then FreeAndNil(FResponseStream);
  if Assigned(FResponseHeaders) then FreeAndNil(FResponseHeaders);
  FRequestHeaders.Free;
  inherited;
end {THttpClient.Destroy};

{ ------------------------------------------------------------------------------------------------ }
function THttpClient.Head(Path: string = ''; const BypassCache: Boolean = False): integer;
begin
  if Path = '' then begin
    Path := FPath;
  end;
  if BypassCache then begin
    Result := SendRequestAndGetResponse('HEAD', Path, nil, 0, INTERNET_FLAG_RELOAD);
  end else begin
    Result := SendRequestAndGetResponse('HEAD', Path, nil, 0);
  end;
end {THttpClient.Head};

{ ------------------------------------------------------------------------------------------------ }
function THttpClient.Get(Path: string = ''; const BypassCache: Boolean = False): integer;
begin
  if Path = '' then begin
    Path := FPath;
  end;
  if BypassCache then begin
    Result := SendRequestAndGetResponse('GET', Path, nil, 0, INTERNET_FLAG_RELOAD);
  end else begin
    Result := SendRequestAndGetResponse('GET', Path, nil, 0);
  end;
end {THttpClient.Get};

{ ------------------------------------------------------------------------------------------------ }
function THttpClient.Post(Data: TStream): integer;
begin
  Result := Self.Post(FPath, Data);
end {THttpClient.Post};
{ ------------------------------------------------------------------------------------------------ }
function THttpClient.Post(Path: string; Data: TStream): integer;
var
  MemData: TMemoryStream;
  CleanUp: boolean;
begin
  if Data is TMemoryStream then begin
    MemData := TMemoryStream(Data);
    CleanUp := False;
  end else begin
    Data.Position := 0;
    MemData := TMemoryStream.Create;
    MemData.CopyFrom(Data, Data.Size);
    CleanUp := True;
  end;
  try
    Result := SendRequestAndGetResponse('POST', Path, MemData.Memory, MemData.Size);
  finally
    if CleanUp then begin
      MemData.Free;
    end;
  end;
end {THttpClient.Post};
{ ------------------------------------------------------------------------------------------------ }
function THttpClient.Post(Data: string): integer;
begin
  Result := Self.Post(FPath, Data);
end {THttpClient.Post};
{ ------------------------------------------------------------------------------------------------ }
function THttpClient.Post(Path: string; Data: string): integer;
begin
  Result := SendRequestAndGetResponse('POST', Path, PChar(Data), ByteLength(Data));
end {THttpClient.Post};

{ ------------------------------------------------------------------------------------------------ }
function THttpClient.SendRequestAndGetResponse(const Verb, Resource: string;
                                               const Data: Pointer;
                                               const DataSize: Cardinal;
                                               Flags: Cardinal = 0): integer;
var
  hInt, hConn: HINTERNET;
  PProxy, PProxyBypass, PUserName, PPassword: PChar;
  BytesRead, TotalBytesToRead, TotalBytesRead: Cardinal;
  Buffer: TMemoryStream;
  Size: Cardinal;
  Cancel: Boolean;
begin
  Result := 0; // means the request has been canceled

  FPath := Resource;

  { Initialize the response data }
  FResponseStatus := 0;
  FResponseStatusText := '';
  if Assigned(FResponseHeaders) then FreeAndNil(FResponseHeaders);
  if Assigned(FResponseStream) then FreeAndNil(FResponseStream);

  { Set the proxy parameters }
  if UseProxy = hcProxy then begin
    if Length(Self.Proxy) = 0 then begin
      PProxy := nil;
    end else begin
      PProxy := PChar(Self.Proxy);
    end;
    if Length(Self.ProxyByPass) = 0 then begin
      PProxyByPass := nil;
    end else begin
      PProxyByPass := PChar(Self.ProxyByPass);
    end;
  end else begin
    PProxy := nil;
    PProxyBypass := nil;
  end;

  Cancel := False;
  if Assigned(FOnProgress) then begin
    FOnProgress(Self, scConnecting, 0, 0, Cancel);
    if Cancel then
      Exit;
  end;

  { Open an internet handle and set the request parameters }
  hInt := InternetOpen(PChar(UserAgent), Ord(UseProxy), PProxy, PProxyBypass, 0);
  Win32Check(Assigned(hInt));
  try
    if ConnectTimeout > 0 then InternetSetOption(hInt, INTERNET_OPTION_CONNECT_TIMEOUT, @ConnectTimeout, sizeof(ConnectTimeout));
    if SendTimeout > 0    then InternetSetOption(hInt, INTERNET_OPTION_SEND_TIMEOUT,    @SendTimeout,    sizeof(SendTimeout));
    if ReceiveTimeout > 0 then InternetSetOption(hInt, INTERNET_OPTION_RECEIVE_TIMEOUT, @ReceiveTimeout, sizeof(ReceiveTimeout));

    if Length(Self.UserName) = 0 then begin
      PUserName := nil;
    end else begin
      PUserName := PChar(Self.UserName);
    end;
    if Length(Self.Password) = 0 then begin
      PPassword := nil;
    end else begin
      PPassword := PChar(Self.Password);
    end;

    { Try to connect, then send the request }
    hConn := InternetConnect(hInt, PChar(Hostname), Self.Port, PUserName, PPassword, INTERNET_SERVICE_HTTP, 0, 1);
    Win32Check(Assigned(hConn));
    try
      if Self.Port = INTERNET_DEFAULT_HTTPS_PORT then begin
        Flags := Flags or INTERNET_FLAG_SECURE or INTERNET_FLAG_IGNORE_CERT_CN_INVALID or INTERNET_FLAG_IGNORE_CERT_DATE_INVALID;
      end;
      FhReq := HttpOpenRequest(hConn, PChar(Verb), PChar(Resource), nil, nil, nil, Flags, 1);
      Win32Check(Assigned(FhReq));
      try
        InternetQueryOption(FhReq, INTERNET_OPTION_URL, nil, Size);
        FURL := StringOfChar(#0, Size);
        Win32Check(InternetQueryOption(FhReq, INTERNET_OPTION_URL, PChar(FURL), Size));
        SetLength(FURL, Size);

        if Assigned(FOnProgress) then begin
          FOnProgress(Self, scUploading, 0, 0, Cancel);
          if Cancel then
            Exit;
        end;

        Win32Check(HttpSendRequest(FhReq,
                                   PChar(FRequestHeaders.Text), Length(FRequestHeaders.Text),
                                   Data, DataSize));

        { Try to get the content-length }
        if not QueryInfoInteger(HTTP_QUERY_CONTENT_LENGTH, TotalBytesToRead) then
          TotalBytesToRead := 0;

        FResponseStream := TMemoryStream.Create;
        Buffer := TMemoryStream.Create;
        try
          TotalBytesRead := 0;
          Buffer.SetSize(READBUFFERSIZE);
          repeat
            Sleep(0);
            if not InternetReadFile(FhReq, Buffer.Memory, READBUFFERSIZE, BytesRead) then begin
              Break;
            end;
            if BytesRead > 0 then begin
              Buffer.Position := 0;
              FResponseStream.CopyFrom(Buffer, Min(BytesRead, READBUFFERSIZE));
              Inc(TotalBytesRead, BytesRead);
              if Assigned(FOnProgress) then begin
                FOnProgress(Self, scDownloading, TotalBytesRead, TotalBytesToRead, Cancel);
                if Cancel then Exit;
              end;
            end;
          until (BytesRead = 0);
        finally
          Buffer.Free;
          FResponseStream.Position := 0;
        end;

        { Read the response status and headers }
        FResponseStatus := QueryInfoInteger(HTTP_QUERY_STATUS_CODE);
        FResponseStatusText := QueryInfoString(HTTP_QUERY_STATUS_TEXT);
        ReadResponseHeaders;

      finally
        InternetCloseHandle(FhReq);
      end;
    finally
      InternetCloseHandle(hConn);
    end;
  finally
    InternetCloseHandle(hInt);
  end;

  if Assigned(FOnProgress) then
    FOnProgress(Self, scFinished, TotalBytesRead, TotalBytesToRead, Cancel);

  Result := FResponseStatus;
end {THttpClient.SendRequestAndGetResponse};


{ ------------------------------------------------------------------------------------------------ }
function THttpClient.QueryInfoInteger(const InfoFlag: cardinal): cardinal;
begin
  Win32Check(QueryInfoInteger(InfoFlag, Result));
end {THttpClient.QueryInfoInteger};
{ ------------------------------------------------------------------------------------------------ }
function THttpClient.QueryInfoInteger(const InfoFlag: cardinal; out Value: cardinal): boolean;
var
  Index, BufSize: Cardinal;
begin
  Index := 0;
  bufsize := sizeOf(Value);
  Result := HttpQueryInfo(FhReq, InfoFlag or HTTP_QUERY_FLAG_NUMBER, @Value, BufSize, Index);
end {THttpClient.QueryInfoInteger};

{ ------------------------------------------------------------------------------------------------ }
function THttpClient.QueryInfoString(const InfoFlag: cardinal): string;
begin
  Win32Check(QueryInfoString(InfoFlag, Result));
end {THttpClient.QueryInfoString};
{ ------------------------------------------------------------------------------------------------ }
function THttpClient.QueryInfoString(const InfoFlag: cardinal; out Value: string): Boolean;
var
  BufSize, Index: cardinal;
  i: byte;
begin
  Result := True;
  Index := 0;
  bufsize := READBUFFERSIZE;
  for i := 0 to 1 do begin
    SetLength(Value, bufsize div SizeOf(Char));
    if not HttpQueryInfo(FhReq, InfoFlag, PChar(Value), bufsize, Index) then begin
      case GetLastError of
        ERROR_INSUFFICIENT_BUFFER: begin
          // bufsize now contains the required size; just go to the next iteration.
        end;
        ERROR_HTTP_HEADER_NOT_FOUND: begin
          // no more headers; just return the current result
          SetLength(Value, bufsize div SizeOf(Char));
          Break;
        end;
        else begin
          Result := False;
          Break;
        end;
      end;
    end else begin
      // HttpQueryInfo was successful
      SetLength(Value, bufsize div SizeOf(Char));
      Break;
    end;
  end {for};
end {THttpClient.QueryInfoString};

{ ------------------------------------------------------------------------------------------------ }
procedure THttpClient.ReadResponseHeaders;
var
  Headers, Header: string;
  i, Offset: integer;
begin
  Headers := QueryInfoString(HTTP_QUERY_RAW_HEADERS);
  Header := StringOfChar(#0, Length(Headers));
  FResponseHeaders := TStringList.Create;
  FResponseHeaders.NameValueSeparator := ':';
  FResponseHeaders.CaseSensitive := False;

  Offset := 0;
  for i := 1 to Length(Headers) - 1 do begin
    if Headers[i] = #0 then begin
      SetLength(Header, i - Offset - 1);
      if Length(Header) = 0 then begin
        Break;
      end;
      FResponseHeaders.Add(Header);
      Header := StringOfChar(#0, Length(Headers) - i);
      Offset := i;
    end else begin
      Header[i - Offset] := Headers[i];
    end;
  end;
  if (Length(Header) > 0) and (Header[1] <> #0) then begin
    Offset := Pos(#0, Header);
    if Offset > 0 then begin
      FResponseHeaders.Add(Copy(Header, 1, Offset - 1));
    end else begin
      FResponseHeaders.Add(Header);
    end;
  end;
end {THttpClient.ReadResponseHeaders};

{ ------------------------------------------------------------------------------------------------ }
function THttpClient.GetResponseString: string; // RawString
var
  ContentType: string;
  CharPos: Integer;
  Encoding: TEncoding;
  SS: TStringStream;
begin
  if Assigned(FResponseStream) and (FResponseStream.Size > 0) then begin
//    SetLength(Result, FResponseStream.Size div StringElementSize(Result));
//    CopyMemory(@Result[1], FResponseStream.Memory, FResponseStream.Size);
    ContentType := ResponseHeaders.Values['Content-Type'];
    CharPos := Pos('charset=', ContentType);
    if CharPos > 0 then begin
      Encoding := TEncoding.GetEncoding(Copy(ContentType, CharPos + 8));
    end else begin
      Encoding := TEncoding.Default;
    end;
    SS := TStringStream.Create('', Encoding, True);
    try
      SS.CopyFrom(FResponseStream, 0);
      Result := SS.DataString;
    finally
      SS.Free;
    end;
  end else begin
    Result := '';
  end;
end {THttpClient.GetResponseString};

end.

Changes to src/common/L_VersionInfoW.pas.

1
2
3
4
5
6
7
8
9
10
11
12

13
14
15
16
17
18
19
20
21
22
23
24










25
26
27

28


29
30


31
32
33
34
35

36
37
38

39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54






















55
56
57
58
59
60
61
62
63
64
65
66

67
68
69
70
71
72
73
74
75
76
77

78
79
80


81
82
83


84
85
86



87
88

89
90
91
92





93




94
95
96
97

98
99

100
101
102

103
104
105

106
107
108
109
110
111
112
113
114
115
116
117
118

119
120
121
122
123










124
125

126
127
128

129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144





145
146
147
148
1
2
3
4
5
6
7
8
9
10
11

12
13
14










15
16
17
18
19
20
21
22
23
24
25
26

27
28
29
30
31

32
33
34
35
36
37

38
39
40

41
42
43














44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76

77
78
79
80
81
82
83
84
85
86
87

88
89


90
91
92


93
94



95
96
97
98

99
100



101
102
103
104
105
106
107
108
109
110
111
112
113

114
115

116
117
118

119
120
121

122
123
124
125
126
127
128
129
130
131
132
133
134

135





136
137
138
139
140
141
142
143
144
145
146

147
148


149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174











-
+


-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+


-
+

+
+

-
+
+




-
+


-
+


-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+











-
+










-
+

-
-
+
+

-
-
+
+
-
-
-
+
+
+

-
+

-
-
-
+
+
+
+
+

+
+
+
+



-
+

-
+


-
+


-
+












-
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+

-
+

-
-
+
















+
+
+
+
+




unit L_VersionInfoW;

interface

uses
  Windows, SysUtils;

type
  TFileVersionInfo = class
  private
    { Private declarations }
    FFilename         : WideString;
    FFilename         : string;
    FHasVersionInfo   : boolean;

    FCompanyName      : WideString;
    FFileDescription  : WideString;
    FFileVersion      : WideString;
    FInternalname     : WideString;
    FLegalCopyright   : WideString;
    FLegalTradeMarks  : WideString;
    FOriginalFilename : WideString;
    FProductName      : WideString;
    FProductVersion   : WideString;
    FComments         : WideString;
    FCompanyName      : string;
    FFileDescription  : string;
    FFileVersion      : string;
    FInternalname     : string;
    FLegalCopyright   : string;
    FLegalTradeMarks  : string;
    FOriginalFilename : string;
    FProductName      : string;
    FProductVersion   : string;
    FComments         : string;
    FMajorVersion     : Word;
    FMinorVersion     : Word;
    FRevision          : Word;
    FRevision         : Word;
    FBuild            : Word;
    FFlags            : Word;
    FFileDateTime     : TDateTime;

    procedure SetFileName(AFileName: WideString);
    procedure SetFileName(const AFileName: string);
    function  HasFlag(const Index: integer): boolean;
  protected
    { Protected declarations }
  public
    { Public declarations }
    constructor Create(AFileName: WideString);
    constructor Create(const AFileName: string);
    destructor  Destroy; override;

    property FileName         : WideString read FFileName           write SetFileName;
    property FileName         : string    read FFileName           write SetFileName;
  public
    { Published declarations }
    property CompanyName      : WideString  read FCompanyName;
    property FileDescription  : WideString  read FFileDescription;
    property FileVersion      : WideString  read FFileVersion;
    property Internalname     : WideString  read FInternalname;
    property LegalCopyright   : WideString  read FLegalCopyright;
    property LegalTradeMarks  : WideString  read FLegalTradeMarks;
    property OriginalFilename : WideString  read FOriginalFilename;
    property ProductName      : WideString  read FProductName;
    property ProductVersion   : WideString  read FProductVersion;
    property Comments         : WideString  read FComments;
    property MajorVersion     : Word        read FMajorVersion;
    property MinorVersion     : Word        read FMinorVersion;
    property Revision         : Word        read FRevision;
    property Build            : Word        read FBuild;
    property CompanyName      : string    read FCompanyName;
    property FileDescription  : string    read FFileDescription;
    property FileVersion      : string    read FFileVersion;
    property Internalname     : string    read FInternalname;
    property LegalCopyright   : string    read FLegalCopyright;
    property LegalTradeMarks  : string    read FLegalTradeMarks;
    property OriginalFilename : string    read FOriginalFilename;
    property ProductName      : string    read FProductName;
    property ProductVersion   : string    read FProductVersion;
    property Comments         : string    read FComments;
    property MajorVersion     : Word      read FMajorVersion;
    property MinorVersion     : Word      read FMinorVersion;
    property Revision         : Word      read FRevision;
    property Build            : Word      read FBuild;
    property Flags            : Word      read FFlags;
    property IsDebug          : boolean   index VS_FF_DEBUG         read HasFlag;
    property IsPreRelease     : boolean   index VS_FF_PRERELEASE    read HasFlag;
    property IsPatched        : boolean   index VS_FF_PATCHED       read HasFlag;
    property IsPrivateBuild   : boolean   index VS_FF_PRIVATEBUILD  read HasFlag;
    property IsInfoInferred   : boolean   index VS_FF_INFOINFERRED  read HasFlag;
    property IsSpecialBuild   : boolean   index VS_FF_SPECIALBUILD  read HasFlag;
    property FileDateTime     : TDateTime read FFileDateTime;
  end;

implementation

type
  TLangAndCP = record
    wLanguage : word;
    wCodePage : word;
  end;
  PLangAndCP = ^TLangAndCP;

constructor TFileVersionInfo.Create(AFileName: WideString);
constructor TFileVersionInfo.Create(const AFileName: string);
begin
  inherited Create;
  SetFileName(AFileName);
end;

destructor TFileVersionInfo.Destroy;
begin
  inherited Destroy;
end;

procedure TFileVersionInfo.SetFileName(AFileName: WideString);
procedure TFileVersionInfo.SetFileName(const AFileName: string);
var
  Dummy     : cardinal;
  BufferSize: integer;
  Dummy     : UINT;
  BufferSize: DWORD;
  Buffer    : Pointer;
  Lang      : PLangAndCP;
  SubBlock  : WideString;
  PLang     : PLangAndCP;
  SubBlock  : string;
  InfoBlock : VS_FIXEDFILEINFO;
  InfoPtr   : Pointer;
  function QueryValue(AName: WideString): WideString;
  SysTime: TSystemTime;
  { - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - }
  function QueryValue(const AName: string): string;
  var
    Value   : PWChar;
    Value   : PChar;
  begin
    SubBlock := WideFormat('\\StringFileInfo\\%.4x%.4x\\%s', [Lang.wLanguage, Lang.wCodePage, AName]);
    VerQueryValueW(Buffer, PWChar(SubBlock), Pointer(Value), Dummy);
    Result := WideString(Value);
    SubBlock := WideFormat('\\StringFileInfo\\%.4x%.4x\\%s', [PLang.wLanguage, PLang.wCodePage, AName]);
    if VerQueryValue(Buffer, PChar(SubBlock), Pointer(Value), Dummy) then
      Result := string(Value)
    else
      Result := '';
  end;
  { - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - }
var
  PInfoBlock : PVSFixedFileInfo;
  FileTime   : TFileTime;
begin
  FFilename := AFileName;

  BufferSize := GetFileVersionInfoSizeW(PWChar(AFileName), Dummy);
  BufferSize := GetFileVersionInfoSize(PChar(AFileName), Dummy);
  FHasVersionInfo := (Buffersize > 0);
  if BufferSize > 0 then begin
  if FHasVersionInfo then begin
    Buffer := AllocMem(BufferSize);
    try
      GetFileVersionInfoW(PWChar(AFileName),0,BufferSize,Buffer);
      GetFileVersionInfo(PChar(AFileName), Dummy, BufferSize, Buffer);

      SubBlock := '\\VarFileInfo\\Translation';
      VerQueryValueW(Buffer, PWChar(SubBlock), Pointer(Lang), Dummy);
      VerQueryValue(Buffer, PChar(SubBlock), Pointer(PLang), Dummy);

      FCompanyName      := QueryValue('CompanyName');
      FFileDescription  := QueryValue('FileDescription');
      FFileVersion      := QueryValue('FileVersion');
      FInternalName     := QueryValue('InternalName');
      FLegalCopyright   := QueryValue('LegalCopyright');
      FLegalTradeMarks  := QueryValue('LegalTradeMarks');
      FOriginalFilename := QueryValue('OriginalFilename');
      FProductName      := QueryValue('ProductName');
      FProductVersion   := QueryValue('ProductVersion');
      FComments         := QueryValue('Comments');

      VerQueryValue(Buffer, '\', InfoPtr, Dummy);
      VerQueryValue(Buffer, '\', Pointer(PInfoBlock), Dummy);
      Move(InfoPtr^, InfoBlock, SizeOf(VS_FIXEDFILEINFO));
      FMajorVersion := InfoBlock.dwFileVersionMS shr 16;
      FMinorVersion := InfoBlock.dwFileVersionMS and 65535;
      FRevision     := InfoBlock.dwFileVersionLS shr 16;
      FBuild        := InfoBlock.dwFileVersionLS and 65535;
      FMajorVersion := PInfoBlock.dwFileVersionMS shr 16;
      FMinorVersion := PInfoBlock.dwFileVersionMS and 65535;
      FRevision     := PInfoBlock.dwFileVersionLS shr 16;
      FBuild        := PInfoBlock.dwFileVersionLS and 65535;
      FFlags        := PInfoBlock.dwFileFlags and PInfoBlock.dwFileFlagsMask;

      FileTime.dwLowDateTime  := PInfoBlock.dwFileDateLS;
      FileTime.dwHighDateTime := PInfoBlock.dwFileDateMS;
      if FileTimeToLocalFileTime(FileTime, FileTime) and FileTimeToSystemTime(FileTime, SysTime) and (SysTime.wYear > 1601) then
        FFileDateTime := SystemTimeToDateTime(SysTime);
    finally
      FreeMem(Buffer,BufferSize);
      FreeMem(Buffer, BufferSize);
    end;
  end
  else begin
  end else begin
    FCompanyname      := '';
    FFileDescription  := '';
    FFileVersion      := '';
    FInternalname     := '';
    FLegalCopyright   := '';
    FLegalTradeMarks  := '';
    FOriginalFilename := '';
    FProductName      := '';
    FProductVersion   := '';
    FComments         := '';
    FMajorVersion     := 0;
    FMinorVersion     := 0;
    FRevision         := 0;
    FBuild            := 0;
  end;
end;

function TFileVersionInfo.HasFlag(const Index: integer): boolean;
begin
  Result := (FFlags and Index) <> 0;
end;


end.

Changes to src/lib/NppDockingForms.pas.

147
148
149
150
151
152
153
154

155
156
157
158
159
160
161

162
163
164
165
166
167
168
147
148
149
150
151
152
153

154
155
156
157
158
159
160

161
162
163
164
165
166
167
168







-
+






-
+







  GetMem(self.ToolbarData.AdditionalInfo, 1000*sizeof(nppPChar));

{$IFDEF NPPUNICODE}
  StringToWideChar(self.Caption, self.ToolbarData.Title, 500);
  GetModuleFileNameW(HInstance, self.ToolbarData.ModuleName, 1000);
  StringToWideChar(ExtractFileName(self.ToolbarData.ModuleName), self.ToolbarData.ModuleName, 1000);
  StringToWideChar('', self.ToolbarData.AdditionalInfo, 1);
  {r:=}SendMessageW(self.Npp.NppData.NppHandle, NPPM_DMMREGASDCKDLG, 0, Integer(@self.ToolbarData));
  {r:=}SendMessageW(self.Npp.NppData.NppHandle, NPPM_DMMREGASDCKDLG, 0, NativeInt(@self.ToolbarData));
{$ELSE}
  StrCopy(self.ToolbarData.Title, PChar(self.Caption));
  GetModuleFileNameA(HInstance, self.ToolbarData.ModuleName, 1000);
  StrLCopy(self.ToolbarData.ModuleName, PChar(ExtractFileName(self.ToolbarData.ModuleName)), 1000);
  StrCopy(self.ToolbarData.AdditionalInfo, PChar(''));
  {r:=}
  SendMessageA(self.Npp.NppData.NppHandle, NPPM_DMMREGASDCKDLG, 0, Integer(@self.ToolbarData));
  SendMessageA(self.Npp.NppData.NppHandle, NPPM_DMMREGASDCKDLG, 0, NativeInt(@self.ToolbarData));
{$ENDIF}

  self.Visible := true;
end;

procedure TNppDockingForm.Show;
begin
181
182
183
184
185
186
187
188

189
190
191
192
193
194
195
181
182
183
184
185
186
187

188
189
190
191
192
193
194
195







-
+







// This hack prevents the Win Dialog default procedure from an endless loop while
// looking for the prevoius component, while in a floating state.
// I still don't know why the pointer climbs up to the docking dialog that holds this one
// but this works for now.
procedure TNppDockingForm.RemoveControlParent(control: TControl);
var
  wincontrol: TWinControl;
  i, r: integer;
  i, r: NativeInt;
begin
  if (control is TWinControl) then
  begin
    wincontrol := control as TWinControl;
    wincontrol.HandleNeeded;
    r := Windows.GetWindowLong(wincontrol.Handle, GWL_EXSTYLE);
    if (r and WS_EX_CONTROLPARENT = WS_EX_CONTROLPARENT) then

Changes to src/lib/SciSupport.pas.

1
2
3
4
5
6
7
8
9
10
11
12
13

14
15
16
17
18
19



20
21
22
23
24
25
26
1
2
3
4
5
6
7
8
9
10
11
12

13
14
15
16



17
18
19
20
21
22
23
24
25
26












-
+



-
-
-
+
+
+







unit scisupport;

// Support unit for scintilla use in pascal. The constants are all created from scintilla.iface by
// a python script.

interface

{$DEFINE MACRO_SUPPORT}

uses Windows;

type
  TScintillaMessageFnc = function(ptr : Pointer; Msg, wParam, lParam : LongInt) : LongInt; cdecl;
  TScintillaMessageFnc = function(ptr : Pointer; Msg: UINT; wParam: WPARAM; lParam : LPARAM) : LRESULT; cdecl;
  uptr_t = Longword;
  sptr_t = Longint;
  TNotifyHeader = record
	  hwndFrom : Pointer;
	  idFrom : Cardinal;
	  code : Cardinal;
	  hwndFrom : HWND;
	  idFrom : uptr_t;
	  code : NativeUInt;
  end;
  PSCNotification = ^TSCNotification;
  TSCNotification = record
    nmhdr 		          : TNotifyHeader;
    position    	      : Integer;		// SCN_STYLENEEDED, SCN_MODIFIED
    ch 			            : Integer;		// SCN_CHARADDED, SCN_KEY
    modifiers		        : Integer;		// SCN_KEY

Changes to src/lib/nppplugin.pas.

395
396
397
398
399
400
401
402

403
404
405
406
407
408
409
395
396
397
398
399
400
401

402
403
404
405
406
407
408
409







-
+







  DMN_CLOSE = (DMN_FIRST + 1); //nmhdr.code = DWORD(DMN_CLOSE, 0)); //nmhdr.hwndFrom = hwndNpp; //nmhdr.idFrom = ctrlIdNpp;
  DMN_DOCK = (DMN_FIRST + 2);
  DMN_FLOAT = (DMN_FIRST + 3); //nmhdr.code = DWORD(DMN_XXX, int newContainer);	//nmhdr.hwndFrom = hwndNpp; //nmhdr.idFrom = ctrlIdNpp;


type
{$IFDEF NPPUNICODE}
  nppString = WideString;
  nppString = UnicodeString;
  nppChar = WChar;
  nppPChar = PWChar;
{$ELSE}
  nppString = AnsiString;
  nppChar = AnsiChar;
  nppPChar = PAnsiChar;
{$ENDIF}
425
426
427
428
429
430
431
432

433
434
435
436
437
438
439
425
426
427
428
429
430
431

432
433
434
435
436
437
438
439







-
+








  TToolbarIcons = record
    ToolbarBmp: HBITMAP;
    ToolbarIcon: HICON;
  end;

  TCommunicationInfo = record
    internalMsg: Cardinal;
    internalMsg: NativeUInt;
    srcModuleName: nppPChar;
    info: Pointer;
  end;

  TNppData = record
    NppHandle: HWND;
    ScintillaMainHandle: HWND;
469
470
471
472
473
474
475
476

477
478
479
480
481
482
483
469
470
471
472
473
474
475

476
477
478
479
480
481
482
483







-
+







    PrevContainer: Cardinal; // internal
    ModuleName:nppPChar; // name of module GetModuleFileName(0...)
  end;

  TNppPlugin = class(TObject)
  private
    FuncArray: array of _TFuncItem;
    FClosingBufferID: Integer;
    FClosingBufferID: THandle;
    FConfigDir: string;
  protected
    PluginName: nppString;
    function GetPluginsConfigDir: string;
    function AddFuncSeparator: Integer;
    function AddFuncItem(Name: nppString; Func: PFUNCPLUGINCMD): Integer; overload;
    function AddFuncItem(Name: nppString; Func: PFUNCPLUGINCMD; ShortcutKey: TShortcutKey): Integer; overload;
499
500
501
502
503
504
505
506
507


508
509
510
511
512
513
514
499
500
501
502
503
504
505


506
507
508
509
510
511
512
513
514







-
-
+
+







    function GetFuncsArray(var FuncsCount: Integer): Pointer;
    procedure BeNotified(sn: PSCNotification);
    procedure MessageProc(var Msg: TMessage); virtual;

    // hooks
    procedure DoNppnToolbarModification; virtual;
    procedure DoNppnShutdown; virtual;
    procedure DoNppnBufferActivated(const BufferID: Cardinal); virtual;
    procedure DoNppnFileClosed(const BufferID: Cardinal); virtual;
    procedure DoNppnBufferActivated(const BufferID: THandle); virtual;
    procedure DoNppnFileClosed(const BufferID: THandle); virtual;
    procedure DoUpdateUI(const hwnd: HWND; const updated: Integer); virtual;
    procedure DoModified(const hwnd: HWND; const modificationType: Integer); virtual;

    // df
    function DoOpen(filename: String): boolean; overload;
    function DoOpen(filename: String; Line: Integer): boolean; overload;
    procedure GetFileLine(var filename: String; var Line: Integer);
748
749
750
751
752
753
754
755

756
757
758
759
760

761
762
763
764
765
766
767
748
749
750
751
752
753
754

755
756
757
758
759

760
761
762
763
764
765
766
767







-
+




-
+







end;

procedure TNppPlugin.DoNppnToolbarModification;
begin
  // override these
end;

procedure TNppPlugin.DoNppnBufferActivated(const BufferID: Cardinal);
procedure TNppPlugin.DoNppnBufferActivated(const BufferID: THandle);
begin
  // override these
end;

procedure TNppPlugin.DoNppnFileClosed(const BufferID: Cardinal);
procedure TNppPlugin.DoNppnFileClosed(const BufferID: THandle);
begin
  // override these
end;

procedure TNppPlugin.DoModified(const hwnd: HWND; const modificationType: Integer);
begin
  // override these

Changes to src/prj/PreviewHTML.dpr.

25
26
27
28
29
30
31
32



33
34
35
36
37
38
39
25
26
27
28
29
30
31

32
33
34
35
36
37
38
39
40
41







-
+
+
+







  U_Npp_PreviewHTML in '..\U_Npp_PreviewHTML.pas',
  F_About in '..\F_About.pas' {AboutForm},
  F_PreviewHTML in '..\F_PreviewHTML.pas' {frmHTMLPreview},
  WebBrowser in '..\lib\WebBrowser.pas',
  L_VersionInfoW in '..\common\L_VersionInfoW.pas',
  L_SpecialFolders in '..\common\L_SpecialFolders.pas',
  RegExpr in '..\common\RegExpr.pas',
  U_CustomFilter in '..\U_CustomFilter.pas';
  U_CustomFilter in '..\U_CustomFilter.pas',
  U_AutoUpdate in '..\U_AutoUpdate.pas',
  Debug in '..\Debug.pas';

{$R *.res}

{$Include '..\lib\NppPluginInclude.pas'}

begin
  { First, assign the procedure to the DLLProc variable }

Changes to src/prj/PreviewHTML.dproj.

1
2
3
4
5
6
7

8
9
10
11

12
13
14
15
16
17
18
19





20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36






37


38
39
40
41
42
43
44
1
2
3
4
5
6

7
8
9
10

11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57






-
+



-
+








+
+
+
+
+

















+
+
+
+
+
+

+
+







<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <PropertyGroup>
        <ProjectGuid>{A2533A0E-8621-4A31-A675-059AFF5AA9FB}</ProjectGuid>
        <MainSource>PreviewHTML.dpr</MainSource>
        <Base>True</Base>
        <Config Condition="'$(Config)'==''">Debug</Config>
        <TargetedPlatforms>1</TargetedPlatforms>
        <TargetedPlatforms>3</TargetedPlatforms>
        <AppType>Library</AppType>
        <FrameworkType>VCL</FrameworkType>
        <ProjectVersion>18.2</ProjectVersion>
        <Platform Condition="'$(Platform)'==''">Win32</Platform>
        <Platform Condition="'$(Platform)'==''">Win64</Platform>
    </PropertyGroup>
    <PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''">
        <Base>true</Base>
    </PropertyGroup>
    <PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Base)'=='true') or '$(Base_Win32)'!=''">
        <Base_Win32>true</Base_Win32>
        <CfgParent>Base</CfgParent>
        <Base>true</Base>
    </PropertyGroup>
    <PropertyGroup Condition="('$(Platform)'=='Win64' and '$(Base)'=='true') or '$(Base_Win64)'!=''">
        <Base_Win64>true</Base_Win64>
        <CfgParent>Base</CfgParent>
        <Base>true</Base>
    </PropertyGroup>
    <PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_1)'!=''">
        <Cfg_1>true</Cfg_1>
        <CfgParent>Base</CfgParent>
        <Base>true</Base>
    </PropertyGroup>
    <PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_2)'!=''">
        <Cfg_2>true</Cfg_2>
        <CfgParent>Base</CfgParent>
        <Base>true</Base>
    </PropertyGroup>
    <PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Cfg_2)'=='true') or '$(Cfg_2_Win32)'!=''">
        <Cfg_2_Win32>true</Cfg_2_Win32>
        <CfgParent>Cfg_2</CfgParent>
        <Cfg_2>true</Cfg_2>
        <Base>true</Base>
    </PropertyGroup>
    <PropertyGroup Condition="('$(Platform)'=='Win64' and '$(Cfg_2)'=='true') or '$(Cfg_2_Win64)'!=''">
        <Cfg_2_Win64>true</Cfg_2_Win64>
        <CfgParent>Cfg_2</CfgParent>
        <Cfg_2>true</Cfg_2>
        <Base>true</Base>
    </PropertyGroup>
    <PropertyGroup Condition="'$(Base)'!=''">
        <DCC_UNIT_PLATFORM>false</DCC_UNIT_PLATFORM>
        <DCC_SYMBOL_PLATFORM>false</DCC_SYMBOL_PLATFORM>
        <SanitizedProjectName>PreviewHTML</SanitizedProjectName>
        <VerInfo_MinorVer>4</VerInfo_MinorVer>
        <PostBuildEventCancelOnError>false</PostBuildEventCancelOnError>
        <PostBuildEvent>
            <![CDATA["C:\MC\Run\Util\Compression\UPX\upx.exe" --best -q "$(OUTPUTPATH)"
$(PostBuildEvent)]]>
        </PostBuildEvent>
62
63
64
65
66
67
68




69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86

87
88





89
90
91
92
93
94
95
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118







+
+
+
+


















+


+
+
+
+
+







        <DCC_E>false</DCC_E>
        <DCC_DcuOutput>..\..\out\dcu\$(PLATFORM)\$(CONFIG)</DCC_DcuOutput>
    </PropertyGroup>
    <PropertyGroup Condition="'$(Base_Win32)'!=''">
        <DCC_Namespace>System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)</DCC_Namespace>
        <AppEnableRuntimeThemes>true</AppEnableRuntimeThemes>
    </PropertyGroup>
    <PropertyGroup Condition="'$(Base_Win64)'!=''">
        <DCC_Namespace>System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace)</DCC_Namespace>
        <VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
    </PropertyGroup>
    <PropertyGroup Condition="'$(Cfg_1)'!=''">
        <DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>
        <DCC_DebugInformation>0</DCC_DebugInformation>
        <DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
        <DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>
    </PropertyGroup>
    <PropertyGroup Condition="'$(Cfg_2)'!=''">
        <VerInfo_Debug>true</VerInfo_Debug>
        <VerInfo_PreRelease>true</VerInfo_PreRelease>
        <PostBuildEvent>
            <![CDATA[]]>
        </PostBuildEvent>
        <DCC_SymbolReferenceInfo>2</DCC_SymbolReferenceInfo>
        <DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>
        <DCC_Optimize>false</DCC_Optimize>
        <DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>
    </PropertyGroup>
    <PropertyGroup Condition="'$(Cfg_2_Win32)'!=''">
        <Debugger_HostApplication>C:\MC\Run\Office\Np++\unicode\notepad++</Debugger_HostApplication>
        <AppEnableRuntimeThemes>true</AppEnableRuntimeThemes>
    </PropertyGroup>
    <PropertyGroup Condition="'$(Cfg_2_Win64)'!=''">
        <VerInfo_MinorVer>0</VerInfo_MinorVer>
        <Debugger_HostApplication>C:\MC\Run\Office\Np++\x64\notepad++.exe</Debugger_HostApplication>
        <VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
    </PropertyGroup>
    <ItemGroup>
        <DelphiCompile Include="$(MainSource)">
            <MainSource>MainSource</MainSource>
        </DelphiCompile>
        <RcCompile Include="PreviewHTML_TB.rc">
            <Form>PreviewHTML_TB.res</Form>
        </RcCompile>
109
110
111
112
113
114
115


116
117
118
119
120
121
122
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147







+
+







            <Form>frmHTMLPreview</Form>
        </DCCReference>
        <DCCReference Include="..\lib\WebBrowser.pas"/>
        <DCCReference Include="..\common\L_VersionInfoW.pas"/>
        <DCCReference Include="..\common\L_SpecialFolders.pas"/>
        <DCCReference Include="..\common\RegExpr.pas"/>
        <DCCReference Include="..\U_CustomFilter.pas"/>
        <DCCReference Include="..\U_AutoUpdate.pas"/>
        <DCCReference Include="..\Debug.pas"/>
        <BuildConfiguration Include="Debug">
            <Key>Cfg_2</Key>
            <CfgParent>Base</CfgParent>
        </BuildConfiguration>
        <BuildConfiguration Include="Base">
            <Key>Base</Key>
        </BuildConfiguration>
163
164
165
166
167
168
169
170
171
172

173

















































































































































































































































































































































174
175
176
177
178
179

180
181
182
183
184
185
186
187
188
189
190
191
192
193
188
189
190
191
192
193
194

195

196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539

540







541
542
543
544
545
546
547







-

-
+

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+





-
+
-
-
-
-
-
-
-







                    <VersionInfoKeys Name="OriginalFilename"/>
                    <VersionInfoKeys Name="ProductName"/>
                    <VersionInfoKeys Name="ProductVersion">6.0.0.0</VersionInfoKeys>
                    <VersionInfoKeys Name="Comments"/>
                </VersionInfoKeys>
            </Delphi.Personality>
            <Platforms>
                <Platform value="OSX32">False</Platform>
                <Platform value="Win32">True</Platform>
                <Platform value="Win64">False</Platform>
                <Platform value="Win64">True</Platform>
            </Platforms>
            <Deployment Version="3">
                <DeployFile LocalName="..\..\out\Win32\Debug\PreviewHTML.dll" Configuration="Debug" Class="ProjectOutput">
                    <Platform Name="Win32">
                        <RemoteName>PreviewHTML.dll</RemoteName>
                        <Overwrite>true</Overwrite>
                    </Platform>
                </DeployFile>
                <DeployClass Name="AdditionalDebugSymbols">
                    <Platform Name="Win32">
                        <RemoteDir>Contents\MacOS</RemoteDir>
                        <Operation>0</Operation>
                    </Platform>
                    <Platform Name="OSX32">
                        <Operation>1</Operation>
                    </Platform>
                </DeployClass>
                <DeployClass Name="AndroidClassesDexFile">
                    <Platform Name="Android">
                        <RemoteDir>classes</RemoteDir>
                        <Operation>1</Operation>
                    </Platform>
                </DeployClass>
                <DeployClass Name="AndroidGDBServer">
                    <Platform Name="Android">
                        <RemoteDir>library\lib\armeabi-v7a</RemoteDir>
                        <Operation>1</Operation>
                    </Platform>
                </DeployClass>
                <DeployClass Name="AndroidLibnativeArmeabiFile">
                    <Platform Name="Android">
                        <RemoteDir>library\lib\armeabi</RemoteDir>
                        <Operation>1</Operation>
                    </Platform>
                </DeployClass>
                <DeployClass Name="AndroidLibnativeMipsFile">
                    <Platform Name="Android">
                        <RemoteDir>library\lib\mips</RemoteDir>
                        <Operation>1</Operation>
                    </Platform>
                </DeployClass>
                <DeployClass Name="AndroidServiceOutput">
                    <Platform Name="Android">
                        <RemoteDir>library\lib\armeabi-v7a</RemoteDir>
                        <Operation>1</Operation>
                    </Platform>
                </DeployClass>
                <DeployClass Name="AndroidSplashImageDef">
                    <Platform Name="Android">
                        <RemoteDir>res\drawable</RemoteDir>
                        <Operation>1</Operation>
                    </Platform>
                </DeployClass>
                <DeployClass Name="AndroidSplashStyles">
                    <Platform Name="Android">
                        <RemoteDir>res\values</RemoteDir>
                        <Operation>1</Operation>
                    </Platform>
                </DeployClass>
                <DeployClass Name="Android_DefaultAppIcon">
                    <Platform Name="Android">
                        <RemoteDir>res\drawable</RemoteDir>
                        <Operation>1</Operation>
                    </Platform>
                </DeployClass>
                <DeployClass Name="Android_LauncherIcon144">
                    <Platform Name="Android">
                        <RemoteDir>res\drawable-xxhdpi</RemoteDir>
                        <Operation>1</Operation>
                    </Platform>
                </DeployClass>
                <DeployClass Name="Android_LauncherIcon36">
                    <Platform Name="Android">
                        <RemoteDir>res\drawable-ldpi</RemoteDir>
                        <Operation>1</Operation>
                    </Platform>
                </DeployClass>
                <DeployClass Name="Android_LauncherIcon48">
                    <Platform Name="Android">
                        <RemoteDir>res\drawable-mdpi</RemoteDir>
                        <Operation>1</Operation>
                    </Platform>
                </DeployClass>
                <DeployClass Name="Android_LauncherIcon72">
                    <Platform Name="Android">
                        <RemoteDir>res\drawable-hdpi</RemoteDir>
                        <Operation>1</Operation>
                    </Platform>
                </DeployClass>
                <DeployClass Name="Android_LauncherIcon96">
                    <Platform Name="Android">
                        <RemoteDir>res\drawable-xhdpi</RemoteDir>
                        <Operation>1</Operation>
                    </Platform>
                </DeployClass>
                <DeployClass Name="Android_SplashImage426">
                    <Platform Name="Android">
                        <RemoteDir>res\drawable-small</RemoteDir>
                        <Operation>1</Operation>
                    </Platform>
                </DeployClass>
                <DeployClass Name="Android_SplashImage470">
                    <Platform Name="Android">
                        <RemoteDir>res\drawable-normal</RemoteDir>
                        <Operation>1</Operation>
                    </Platform>
                </DeployClass>
                <DeployClass Name="Android_SplashImage640">
                    <Platform Name="Android">
                        <RemoteDir>res\drawable-large</RemoteDir>
                        <Operation>1</Operation>
                    </Platform>
                </DeployClass>
                <DeployClass Name="Android_SplashImage960">
                    <Platform Name="Android">
                        <RemoteDir>res\drawable-xlarge</RemoteDir>
                        <Operation>1</Operation>
                    </Platform>
                </DeployClass>
                <DeployClass Name="DebugSymbols">
                    <Platform Name="Win32">
                        <Operation>0</Operation>
                    </Platform>
                    <Platform Name="iOSSimulator">
                        <Operation>1</Operation>
                    </Platform>
                    <Platform Name="OSX32">
                        <Operation>1</Operation>
                    </Platform>
                </DeployClass>
                <DeployClass Name="DependencyFramework">
                    <Platform Name="Win32">
                        <Operation>0</Operation>
                    </Platform>
                    <Platform Name="OSX32">
                        <Operation>1</Operation>
                        <Extensions>.framework</Extensions>
                    </Platform>
                </DeployClass>
                <DeployClass Name="DependencyModule">
                    <Platform Name="Win32">
                        <Operation>0</Operation>
                        <Extensions>.dll;.bpl</Extensions>
                    </Platform>
                    <Platform Name="OSX32">
                        <Operation>1</Operation>
                        <Extensions>.dylib</Extensions>
                    </Platform>
                </DeployClass>
                <DeployClass Required="true" Name="DependencyPackage">
                    <Platform Name="Win32">
                        <Operation>0</Operation>
                        <Extensions>.bpl</Extensions>
                    </Platform>
                    <Platform Name="iOSDevice64">
                        <Operation>1</Operation>
                        <Extensions>.dylib</Extensions>
                    </Platform>
                    <Platform Name="OSX32">
                        <Operation>1</Operation>
                        <Extensions>.dylib</Extensions>
                    </Platform>
                    <Platform Name="iOSDevice32">
                        <Operation>1</Operation>
                        <Extensions>.dylib</Extensions>
                    </Platform>
                    <Platform Name="iOSSimulator">
                        <Operation>1</Operation>
                        <Extensions>.dylib</Extensions>
                    </Platform>
                </DeployClass>
                <DeployClass Name="File">
                    <Platform Name="Win32">
                        <Operation>0</Operation>
                    </Platform>
                    <Platform Name="iOSDevice64">
                        <Operation>0</Operation>
                    </Platform>
                    <Platform Name="OSX32">
                        <Operation>0</Operation>
                    </Platform>
                    <Platform Name="iOSDevice32">
                        <Operation>0</Operation>
                    </Platform>
                    <Platform Name="Android">
                        <Operation>0</Operation>
                    </Platform>
                    <Platform Name="iOSSimulator">
                        <Operation>0</Operation>
                    </Platform>
                </DeployClass>
                <DeployClass Name="ProjectAndroidManifest">
                    <Platform Name="Android">
                        <Operation>1</Operation>
                    </Platform>
                </DeployClass>
                <DeployClass Name="ProjectOSXEntitlements"/>
                <DeployClass Name="ProjectOSXInfoPList"/>
                <DeployClass Name="ProjectOSXResource">
                    <Platform Name="OSX32">
                        <RemoteDir>Contents\Resources</RemoteDir>
                        <Operation>1</Operation>
                    </Platform>
                </DeployClass>
                <DeployClass Required="true" Name="ProjectOutput">
                    <Platform Name="iOSDevice64">
                        <Operation>1</Operation>
                    </Platform>
                    <Platform Name="iOSDevice32">
                        <Operation>1</Operation>
                    </Platform>
                    <Platform Name="Win32">
                        <Operation>0</Operation>
                    </Platform>
                    <Platform Name="Linux64">
                        <Operation>1</Operation>
                    </Platform>
                    <Platform Name="OSX32">
                        <Operation>1</Operation>
                    </Platform>
                    <Platform Name="Android">
                        <RemoteDir>library\lib\armeabi-v7a</RemoteDir>
                        <Operation>1</Operation>
                    </Platform>
                    <Platform Name="iOSSimulator">
                        <Operation>1</Operation>
                    </Platform>
                </DeployClass>
                <DeployClass Name="ProjectiOSDeviceDebug">
                    <Platform Name="iOSDevice64">
                        <RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir>
                        <Operation>1</Operation>
                    </Platform>
                    <Platform Name="iOSDevice32">
                        <RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir>
                        <Operation>1</Operation>
                    </Platform>
                </DeployClass>
                <DeployClass Name="ProjectiOSDeviceResourceRules"/>
                <DeployClass Name="ProjectiOSEntitlements"/>
                <DeployClass Name="ProjectiOSInfoPList"/>
                <DeployClass Name="ProjectiOSResource">
                    <Platform Name="iOSSimulator">
                        <Operation>1</Operation>
                    </Platform>
                    <Platform Name="iOSDevice64">
                        <Operation>1</Operation>
                    </Platform>
                    <Platform Name="iOSDevice32">
                        <Operation>1</Operation>
                    </Platform>
                </DeployClass>
                <DeployClass Name="iPad_Launch1024">
                    <Platform Name="iOSSimulator">
                        <Operation>1</Operation>
                    </Platform>
                    <Platform Name="iOSDevice64">
                        <Operation>1</Operation>
                    </Platform>
                    <Platform Name="iOSDevice32">
                        <Operation>1</Operation>
                    </Platform>
                </DeployClass>
                <DeployClass Name="iPad_Launch1536">
                    <Platform Name="iOSSimulator">
                        <Operation>1</Operation>
                    </Platform>
                    <Platform Name="iOSDevice64">
                        <Operation>1</Operation>
                    </Platform>
                    <Platform Name="iOSDevice32">
                        <Operation>1</Operation>
                    </Platform>
                </DeployClass>
                <DeployClass Name="iPad_Launch2048">
                    <Platform Name="iOSSimulator">
                        <Operation>1</Operation>
                    </Platform>
                    <Platform Name="iOSDevice64">
                        <Operation>1</Operation>
                    </Platform>
                    <Platform Name="iOSDevice32">
                        <Operation>1</Operation>
                    </Platform>
                </DeployClass>
                <DeployClass Name="iPad_Launch768">
                    <Platform Name="iOSSimulator">
                        <Operation>1</Operation>
                    </Platform>
                    <Platform Name="iOSDevice64">
                        <Operation>1</Operation>
                    </Platform>
                    <Platform Name="iOSDevice32">
                        <Operation>1</Operation>
                    </Platform>
                </DeployClass>
                <DeployClass Name="iPhone_Launch320">
                    <Platform Name="iOSSimulator">
                        <Operation>1</Operation>
                    </Platform>
                    <Platform Name="iOSDevice64">
                        <Operation>1</Operation>
                    </Platform>
                    <Platform Name="iOSDevice32">
                        <Operation>1</Operation>
                    </Platform>
                </DeployClass>
                <DeployClass Name="iPhone_Launch640">
                    <Platform Name="iOSSimulator">
                        <Operation>1</Operation>
                    </Platform>
                    <Platform Name="iOSDevice64">
                        <Operation>1</Operation>
                    </Platform>
                    <Platform Name="iOSDevice32">
                        <Operation>1</Operation>
                    </Platform>
                </DeployClass>
                <DeployClass Name="iPhone_Launch640x1136">
                    <Platform Name="iOSSimulator">
                        <Operation>1</Operation>
                    </Platform>
                    <Platform Name="iOSDevice64">
                        <Operation>1</Operation>
                    </Platform>
                    <Platform Name="iOSDevice32">
                        <Operation>1</Operation>
                    </Platform>
                </DeployClass>
                <ProjectRoot Platform="Android" Name="$(PROJECTNAME)"/>
                <ProjectRoot Platform="Linux64" Name="$(PROJECTNAME)"/>
                <ProjectRoot Platform="OSX32" Name="$(PROJECTNAME)"/>
                <ProjectRoot Platform="Win32" Name="$(PROJECTNAME)"/>
                <ProjectRoot Platform="Win64" Name="$(PROJECTNAME)"/>
                <ProjectRoot Platform="iOSDevice32" Name="$(PROJECTNAME).app"/>
                <ProjectRoot Platform="iOSDevice64" Name="$(PROJECTNAME).app"/>
                <ProjectRoot Platform="iOSSimulator" Name="$(PROJECTNAME).app"/>
            </Deployment>
        </BorlandProject>
        <ProjectFileVersion>12</ProjectFileVersion>
    </ProjectExtensions>
    <Import Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')" Project="$(BDS)\Bin\CodeGear.Delphi.Targets"/>
    <Import Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')" Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj"/>
    <PropertyGroup Condition="'$(Config)'=='Release' And '$(Platform)'=='OSX32'">
    <Import Project="$(MSBuildProjectName).deployproj" Condition="Exists('$(MSBuildProjectName).deployproj')"/>
        <PreBuildEvent/>
        <PreBuildEventIgnoreExitCode>False</PreBuildEventIgnoreExitCode>
        <PreLinkEvent/>
        <PreLinkEventIgnoreExitCode>False</PreLinkEventIgnoreExitCode>
        <PostBuildEvent>&quot;C:\MC\Run\Util\Compression\UPX\upx.exe&quot; --best -q &quot;$(OUTPUTPATH)&quot; </PostBuildEvent>
        <PostBuildEventIgnoreExitCode>True</PostBuildEventIgnoreExitCode>
    </PropertyGroup>
    <PropertyGroup Condition="'$(Config)'=='Release' And '$(Platform)'=='Win32'">
        <PreBuildEvent/>
        <PreBuildEventIgnoreExitCode>False</PreBuildEventIgnoreExitCode>
        <PreLinkEvent/>
        <PreLinkEventIgnoreExitCode>False</PreLinkEventIgnoreExitCode>
        <PostBuildEvent>&quot;C:\MC\Run\Util\Compression\UPX\upx.exe&quot; --best -q &quot;$(OUTPUTPATH)&quot; </PostBuildEvent>
        <PostBuildEventIgnoreExitCode>True</PostBuildEventIgnoreExitCode>