I have found all kind of examples about how to make TWebBrowser use a proxy (like 202.8.128.5:8080). However all those examples are changing the proxy globally for all running instances of TWebBrowser. I have two instances. How do I set a different proxy for each browser?
问题:
回答1:
This can be achieved using the following code (public code, not mine):
{$DEFINE DELPHI2009_UP}
function SetProxy(Server: String): Boolean;
// Server z.B. '127.0.0.1:8080' oder ''
type
INTERNET_PER_CONN_OPTION = record
dwOption: DWORD;
Value: record case Integer of 1: (dwValue: DWORD);
2: (pszValue: {$IFDEF DELPHI2009_UP}PWideChar{$ELSE}PAnsiChar{$ENDIF});
3: (ftValue: TFileTime);
end;
end;
LPINTERNET_PER_CONN_OPTION = ^INTERNET_PER_CONN_OPTION;
INTERNET_PER_CONN_OPTION_LIST = record dwSize: DWORD;
pszConnection:
LPTSTR;
dwOptionCount:
DWORD;
dwOptionError:
DWORD;
pOptions:
LPINTERNET_PER_CONN_OPTION;
end;
LPINTERNET_PER_CONN_OPTION_LIST = ^INTERNET_PER_CONN_OPTION_LIST;
const
INTERNET_PER_CONN_FLAGS = 1;
INTERNET_PER_CONN_PROXY_SERVER = 2;
INTERNET_PER_CONN_PROXY_BYPASS = 3;
INTERNET_PER_CONN_AUTOCONFIG_URL = 4;
INTERNET_PER_CONN_AUTODISCOVERY_FLAGS = 5;
PROXY_TYPE_DIRECT = $00000001;
PROXY_TYPE_PROXY = $00000002;
PROXY_TYPE_AUTO_PROXY_URL = $00000004;
PROXY_TYPE_AUTO_DETECT = $00000008;
INTERNET_OPTION_REFRESH = 37;
INTERNET_OPTION_PER_CONNECTION_OPTION = 75;
INTERNET_OPTION_SETTINGS_CHANGED = 39;
var
OptionsList: INTERNET_PER_CONN_OPTION_LIST;
BufSize: DWORD;
HInternet: Pointer;
Agent: String;
begin
Result := False;
BufSize := SizeOf(OptionsList);
OptionsList.dwSize := BufSize;
OptionsList.pszConnection := nil; // nil -> LAN, sonst Verbindungsname
OptionsList.dwOptionCount := 3; // 3 Optionen werden gesetzt
OptionsList.pOptions := AllocMem(3 * SizeOf(INTERNET_PER_CONN_OPTION));
try
if not Assigned(OptionsList.pOptions) then
EXIT;
OptionsList.pOptions^.dwOption := INTERNET_PER_CONN_FLAGS;
OptionsList.pOptions^.Value.dwValue := PROXY_TYPE_DIRECT or
PROXY_TYPE_PROXY;
inc(OptionsList.pOptions);
OptionsList.pOptions^.dwOption := INTERNET_PER_CONN_PROXY_SERVER;
OptionsList.pOptions^.Value.pszValue := PChar(Server);
inc(OptionsList.pOptions);
OptionsList.pOptions^.dwOption := INTERNET_PER_CONN_PROXY_BYPASS;
OptionsList.pOptions^.Value.pszValue := 'local';
dec(OptionsList.pOptions, 2);
Agent := ExtractFileName(Application.ExeName);
HInternet := InternetOpen
({$IFDEF DELPHI2009_UP}PWideChar{$ELSE}PAnsiChar{$ENDIF}
(Agent), INTERNET_OPEN_TYPE_DIRECT, nil, nil, 0);
try // Optionen setzen
Result := InternetSetOption(HInternet,
INTERNET_OPTION_PER_CONNECTION_OPTION, @OptionsList, BufSize);
InternetSetOption(HInternet, INTERNET_OPTION_REFRESH, nil, 0);
finally
InternetCloseHandle(HInternet);
end;
finally
FreeMem(OptionsList.pOptions); // Speicher freigeben
end;
end;
- Drop two
TWebBrowser
components on your form and twoTButton
TWebBrowser
components will have the default names WebBrowser1 and WebBrowser2- The two
TButton
will have the default names Button1 and Button2 - Add
WinInet
to youruses
clause
Call the above function in Button1
Code for Button1
OnClick
event:
procedure TForm1.Button1Click(Sender: TObject);
begin
SetProxy('ip:port');
WebBrowser1.Navigate('www.whatismyipaddress.com');
end;
Code for Button2
OnClick
event:
procedure TForm1.Button2Click(Sender: TObject);
begin
SetProxy('ip:port');
WebBrowser2.Navigate('www.whatismyipaddress.com');
end;
And here is how it looks:
On the left is WebBrowser1 with a proxy and on the right is WebBrowser2 with a different proxy - both browsers are in the same application and apparently they worked. I've also visited the address from my regular browser (Chrome) while the application was running and it indeed showed up as using my original connection.
So, it works. The WebBrowser components are using their assigned proxy's while the browser on my pc remains unaffected (isn't using either of the proxy's)
Tested this using Rad Studio 10.2 Tokyo just now. Good luck :)
UPDATE
As highlighted in the comments, a way to set the proxy that will be used to navigate, without setting it at design time or in the button you use to Navigate
is by using a TStringList
and loading it from a file (.txt, for example). This can be used in the TWebBrowser
OnBeforeNavigate2
event.
procedure TForm1.WebBrowser1BeforeNavigate2(ASender: TObject; const pDisp: IDispatch; var URL, Flags, TargetFrameName, PostData, Headers: OleVariant; var Cancel: WordBool);
var
proxylist: TStringList;
begin
proxylist:= TStringList.Create;
proxylist.LoadFromFile('proxylist.txt');
SetProxy(proxylist.Strings[0]); //adds the proxy from the 1st line in the txt
proxylist.Free;
end;
Create a .txt file named proxylist in your application folder and write the proxy there.
Now you'll have a proxy set for your TWebBrowser
before you begin to navigate. Either way, I'm sure there a lot of ways to expand this so use your imagination.