Subversion Repositories fastphp

Rev

Rev 19 | Rev 27 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
8 daniel-mar 1
unit BrowserMain;
2
 
25 daniel-mar 3
{$Include 'FastPHP.inc'}
4
 
8 daniel-mar 5
interface
6
 
7
uses
25 daniel-mar 8
  Windows, Messages, SysUtils, Variants, Classes, Graphics,
9
  Controls, Forms, Dialogs, OleCtrls, SHDocVw{$IFDEF USE_SHDOCVW_TLB}_TLB{$ENDIF}, ExtCtrls, StrUtils,
10
  StdCtrls, activex, UrlMon;
8 daniel-mar 11
 
12
type
13
  TForm2 = class(TForm)
14
    WebBrowser1: TWebBrowser;
15
    Timer1: TTimer;
16
    procedure Timer1Timer(Sender: TObject);
17
    procedure WebBrowser1BeforeNavigate2(ASender: TObject;
25 daniel-mar 18
      const pDisp: IDispatch; {$IFDEF USE_SHDOCVW_TLB}const{$ELSE}var{$ENDIF} URL, Flags, TargetFrameName, PostData,
8 daniel-mar 19
      Headers: OleVariant; var Cancel: WordBool);
12 daniel-mar 20
  strict private
21
    function EmbeddedWBQueryService(const rsid, iid: TGUID; out Obj{: IInterface}): HRESULT;
8 daniel-mar 22
  end;
23
 
24
var
25
  Form2: TForm2;
26
 
27
implementation
28
 
29
{$R *.dfm}
30
 
31
uses
9 daniel-mar 32
  WebBrowserUtils, FastPHPUtils, Functions, ShellAPI;
8 daniel-mar 33
 
34
// TODO: Add a lot of nice stuff to let the PHP script communicate with this host application
35
//       For example, allow window resizing etc.  (See Microsoft HTA for inspiration)
36
// TODO: Ajax gives Access Denied error... Create own security manager?
37
// TODO: History doesn't work?
38
// (All these ToDos: Also fix in the Editor)
9 daniel-mar 39
// TODO: kann man eventuell auch php dateien aus einer DLL rausziehen? das wäre TOLL!!!!
40
// TODO: headers... cookies...
11 daniel-mar 41
// TODO: WebBrowser1BeforeNavigate2 mit einem DLL-callback, sodass entwickler ihre eigenen fastphp:// links machen können, z.B. um DLL-Funktionen aufzurufen! (auch in JavaScript ansteuerbar?)
42
// TODO: let the website decide if the window is maximized etc, as well as it's caption, size and icon
19 daniel-mar 43
// TODO: Pass parameters (argv) to PHP
8 daniel-mar 44
 
12 daniel-mar 45
type
46
  TEmbeddedSecurityManager = class(TInterfacedObject, IInternetSecurityManager)
47
  public
48
    function GetSecuritySite(out ppSite: IInternetSecurityMgrSite): HResult; stdcall;
49
    function MapUrlToZone(pwszUrl: LPCWSTR; out dwZone: DWORD; dwFlags: DWORD): HResult; stdcall;
50
    function GetSecurityId(pwszUrl: LPCWSTR; pbSecurityId: Pointer; var cbSecurityId: DWORD; dwReserved: DWORD): HResult; stdcall;
51
    function ProcessUrlAction(pwszUrl: LPCWSTR; dwAction: DWORD; pPolicy: Pointer; cbPolicy: DWORD; pContext: Pointer; cbContext: DWORD; dwFlags, dwReserved: DWORD): HResult; stdcall;
52
    function QueryCustomPolicy(pwszUrl: LPCWSTR; const guidKey: TGUID; out pPolicy: Pointer; out cbPolicy: DWORD; pContext: Pointer; cbContext: DWORD; dwReserved: DWORD): HResult; stdcall;
53
    function SetZoneMapping(dwZone: DWORD; lpszPattern: PWideChar; dwFlags: DWORD): HResult; stdcall;
54
    function GetZoneMappings(dwZone: DWORD;out ppenumString: IEnumString; dwFlags: DWORD): HResult; stdcall;
55
    function SetSecuritySite(pSite: IInternetSecurityMgrSite): HResult; stdcall;
56
  end;
57
 
58
function TEmbeddedSecurityManager.SetSecuritySite(pSite: IInternetSecurityMgrSite): HResult; stdcall;
59
begin
60
  Result := INET_E_DEFAULT_ACTION;
61
end;
62
function TEmbeddedSecurityManager.GetSecuritySite(
63
  out ppSite: IInternetSecurityMgrSite): HResult; stdcall;
64
begin
65
  Result := INET_E_DEFAULT_ACTION;
66
end;
67
function TEmbeddedSecurityManager.GetSecurityId(pwszUrl: LPCWSTR; pbSecurityId: Pointer;
68
  var cbSecurityId: DWORD; dwReserved: DWORD): HResult; stdcall;
69
begin
70
  Result := INET_E_DEFAULT_ACTION;
71
end;
72
function TEmbeddedSecurityManager.ProcessUrlAction(pwszUrl: LPCWSTR; dwAction: DWORD;
73
  pPolicy: Pointer; cbPolicy: DWORD; pContext: Pointer; cbContext: DWORD;
74
  dwFlags, dwReserved: DWORD): HResult; stdcall;
75
begin
76
  // Result := INET_E_DEFAULT_ACTION;
77
 
78
  // TODO: Doesn't work... Cross-Domain is still not allowed.
79
  PDWORD(pPolicy)^ := URLPOLICY_ALLOW;
80
  Result := S_OK;
81
end;
82
function TEmbeddedSecurityManager.QueryCustomPolicy(pwszUrl: LPCWSTR; const guidKey: TGUID;
83
  out pPolicy: Pointer; out cbPolicy: DWORD; pContext: Pointer; cbContext: DWORD;
84
  dwReserved: DWORD): HResult; stdcall;
85
begin
86
  // Result := INET_E_DEFAULT_ACTION;
87
 
88
  // TODO: Doesn't work... Cross-Domain is still not allowed.
89
  PDWORD(pPolicy)^ := URLPOLICY_ALLOW;
90
  Result := S_OK;
91
end;
92
function TEmbeddedSecurityManager.SetZoneMapping(dwZone: DWORD; lpszPattern: PWideChar;
93
  dwFlags: DWORD): HResult; stdcall;
94
begin
95
  Result := INET_E_DEFAULT_ACTION;
96
end;
97
function TEmbeddedSecurityManager.GetZoneMappings(dwZone: DWORD;out ppenumString: IEnumString;
98
  dwFlags: DWORD): HResult; stdcall;
99
begin
100
  Result := INET_E_DEFAULT_ACTION;
101
end;
102
function TEmbeddedSecurityManager.MapUrlToZone(pwszUrl: LPCWSTR; out dwZone: DWORD; dwFlags: DWORD): HResult;
103
begin
16 daniel-mar 104
  dwZone := URLZONE_TRUSTED;
105
  Result := S_OK;
106
end;
12 daniel-mar 107
 
108
function TForm2.EmbeddedWBQueryService(const rsid, iid: TGUID; out Obj{: IInterface}): HRESULT;
109
var
110
    sam: IInternetSecurityManager;
111
begin
112
    Result := E_NOINTERFACE;
113
 
114
    //rsid ==> Service Identifier
115
    //iid ==> Interface identifier
116
    if IsEqualGUID(rsid, IInternetSecurityManager) and IsEqualGUID(iid, IInternetSecurityManager) then
117
    begin
118
        sam := TEmbeddedSecurityManager.Create;
119
        IInterface(Obj) := sam;
120
        Result := S_OK;
121
    end;
122
end;
123
 
8 daniel-mar 124
procedure TForm2.Timer1Timer(Sender: TObject);
125
var
126
  phpScript: string;
127
begin
128
  Timer1.Enabled := false;
129
  phpScript := ParamStr(1);
130
 
12 daniel-mar 131
  // Remove Security
132
  WebBrowser1.ServiceQuery := EmbeddedWBQueryService;
133
 
8 daniel-mar 134
  WebBrowser1.LoadHTML('<h1>FastPHP</h1>Running script... please wait...');
135
 
136
  // TODO: nice HTML error/intro pages (as resource?)
137
  if phpScript = '' then
138
  begin
139
    WebBrowser1.LoadHTML('<h1>FastPHP</h1>Please enter a PHP file to execute.');
140
    Abort;
141
  end;
142
 
143
  if not FileExists(phpScript) then
144
  begin
145
    WebBrowser1.LoadHTML(Format('<h1>FastPHP</h1>File %s does not exist.', [phpScript]));
146
    Abort;
147
  end;
148
 
149
  WebBrowser1.LoadHTML(RunPHPScript(phpScript), phpScript);
150
end;
151
 
152
procedure TForm2.WebBrowser1BeforeNavigate2(ASender: TObject;
25 daniel-mar 153
  const pDisp: IDispatch; {$IFDEF USE_SHDOCVW_TLB}const{$ELSE}var{$ENDIF} URL, Flags, TargetFrameName, PostData,
8 daniel-mar 154
  Headers: OleVariant; var Cancel: WordBool);
155
var
16 daniel-mar 156
  myURL, myUrl2, getData: string;
8 daniel-mar 157
  p: integer;
9 daniel-mar 158
  background: boolean;
159
  ArgGet, ArgPost, ArgHeader: string;
8 daniel-mar 160
begin
9 daniel-mar 161
  background := Pos('background|', URL) >= 1;
162
 
8 daniel-mar 163
  {$REGION 'Line number references (PHP errors and warnings)'}
164
  if Copy(URL, 1, length(FASTPHP_GOTO_URI_PREFIX)) = FASTPHP_GOTO_URI_PREFIX then
165
  begin
9 daniel-mar 166
    // TODO: maybe we could even open that file in the editor!
8 daniel-mar 167
    ShowMessage('This action only works in FastPHP editor.');
168
    Cancel := true;
169
    Exit;
170
  end;
171
  {$ENDREGION}
172
 
173
  {$REGION 'Intelligent browser (executes PHP scripts)'}
174
  if URL <> 'about:blank' then
175
  begin
176
    myUrl := URL;
177
 
9 daniel-mar 178
    myurl := StringReplace(myurl, 'background|', '', []);
179
 
8 daniel-mar 180
    p := Pos('?', myUrl);
9 daniel-mar 181
    if p >= 1 then
182
    begin
183
      getData := copy(myURL, p+1, Length(myURL)-p);
184
      myURL := copy(myURL, 1, p-1);
185
    end
186
    else
187
    begin
188
      getData := '';
189
    end;
8 daniel-mar 190
 
16 daniel-mar 191
    myURL := StringReplace(myURL, 'http://wa.viathinksoft.de', '', []);
192
 
9 daniel-mar 193
    myURL := StringReplace(myURL, 'file:///', '', []);
194
    myURL := StringReplace(myURL, '/', '\', [rfReplaceAll]);
8 daniel-mar 195
 
9 daniel-mar 196
    // TODO: real myURL urldecode
197
    myURL := StringReplace(myURL, '+', ' ', []);
198
    myURL := StringReplace(myURL, '%20', ' ', []);
199
    myURL := StringReplace(myURL, '%%', '%', []);
200
 
201
    ArgHeader := '';
202
    ArgHeader := MyVarToStr(Headers);
203
    ArgHeader := StringReplace(ArgHeader, #13, '|CR|', [rfReplaceAll]);
204
    ArgHeader := StringReplace(ArgHeader, #10, '|LF|', [rfReplaceAll]);
205
 
11 daniel-mar 206
    // *.xphp is ViaThinkSoft's extension associated to FastPHPBrowser
207
    // This allows the "executable PHP scripts" to be executed via double click.--
208
    if FileExists(myURL) and (EndsText('.xphp', myURL) or EndsText('.php', myURL) or EndsText('.php3', myURL) or EndsText('.php4', myURL) or EndsText('.php5', myURL) or EndsText('.phps', myURL)) then
8 daniel-mar 209
    begin
9 daniel-mar 210
      if background then
211
      begin
212
        // TODO: how to detach the process?
213
        ShellExecute(0, 'open', PChar(GetPHPExe), PChar('"'+myURL+'" "'+ArgGet+'" "'+ArgPost+'" "'+ArgHeader+'"'), PChar(ExtractFileDir(Application.ExeName)), SW_HIDE);
214
      end
215
      else
216
      begin
217
        // TODO: somehow prepend fastphp_server.inc.php (populates the $_GET and $_POST arrays)
218
        // TODO: is there a maximal length for the command line?
219
        ArgGet := MyVarToStr(getData);
220
        ArgPost := MyVarToStr(PostData);
16 daniel-mar 221
 
222
        myUrl2 := myUrl;
223
        myUrl2 := StringReplace(myUrl2, '\', '/', [rfReplaceAll]);
224
        // TODO: real myURL urlencode
225
        myUrl2 := StringReplace(myUrl2, '%', '%%', []);
226
        //myUrl2 := StringReplace(myUrl2, ' ', '%20', []);
227
        myUrl2 := StringReplace(myUrl2, ' ', '+', []);
228
        myUrl2 := 'http://wa.viathinksoft.de/' + myUrl2;
229
 
230
        showmessage(myUrl2);
231
        WebBrowser1.LoadHTML(GetDosOutput('"'+GetPHPExe+'" "'+myURL+'" "'+ArgGet+'" "'+ArgPost+'" "'+ArgHeader+'"', ExtractFileDir(Application.ExeName)), myUrl2);
9 daniel-mar 232
      end;
8 daniel-mar 233
      Cancel := true;
234
    end;
235
  end;
236
  {$ENDREGION}
237
end;
238
 
239
end.