I want to use the MSHTML interfaces IHTMLDocument2, IHTMLElement2, IHTMLElementCollection, etc with TWebBrowser.
In Document := WebBrowser.Document as IHTMLDocument2; when TWebbrowser.SelectedEngine = IEOnly then everything is fine.
But, when I changed the property TWebBrowser.SelectedEngine = EdgeOnly or EdgeIfAvailable then WebBrowser.Document is nil.
How can I fix this?
Related
i used Delphi XE7 and DevExpress component, i need to create dxTileBarItem at runtime and add this to my dxTileBar but i cant.
var
//Tile4:TdxTileControlItem;
Tile4:TdxTileBarItem;
begin
Tile4 := TdxTileBarItem.Create(dxTileBar1);
Tile4.Name := 'Tile4';
Tile4.GroupIndex := 0;
Tile4.IndexInGroup := 3;
what is my mistake?
then i want to store a form object in manually created dxTileItem and call each from on OnTileClick such as ListBox, what do i should?
You can use the CreateItem method, for example:
var
MyTile: TdxTileBarItem;
begin
MyTile := dxTileBar1.CreateItem(tbisRegular);
MyTile.Name := 'My Tile';
...
end;
Or you can follow quite common pattern used by Delphi controls, add the item to the control's Items collection, for example:
var
MyTile: TdxTileBarItem;
begin
dxTileBar1.BeginUpdate;
try
MyTile := TdxTileBarItem(dxTileBar1.Items.Add);
MyTile.Name := 'My Tile';
...
finally
dxTileBar1.EndUpdate;
end;
MyTile.MakeVisible;
end;
I have a application which load plugins that are in the form of bpls. Each plugin contains a form to be embedded into another package called CoreInf (form name ManageF) which is just the base gui of the application that contains a TTabcontrol known as MTabcontrol1. Here basically what happens
A list of plugins are dynamically loaded at runtime in sequential order to layout the interface. It loads the plugins based on the interface IPluginFrame(Shared.bpl) . If it contains the interface it then tries to create a new tab in MTabcontrol1 and embedded the form. What im trying to do is make a dynamically created speedbutton onClick focus a TEdit box on a specific ebedded form but it keeps coming up as access violation errors.
Shared.bpl that contains the interface
unit PluginIntf;
interface
uses
FMX.Types, FMX.Controls;
type
IPluginFrame = interface
['{3B4943DB-951B-411B-8726-03BF1688542F}']
function GetBaseControl: TControl;
end;
implementation
end.
Form and Button that is to be ebedded into the interface
InventoryInf.pas has the form to be embeeded
var
InventoryF: TInventoryF;
implementation
{$R *.fmx}
function TInventoryF.GetBaseControl: TControl;
begin
Result := InvenLayout; //<---- This is a a TLayout which align
//to client this is the parent of every item on form
end;
//Below is the on click event for the TSpeedButton invBtn
//Which looks for the embedded form that is embedded
//in MTabcontrol1 as a TTabitem that has the name InventoryF
procedure TInventoryF.Look4Tabitem(Sender: TObject);
var
o : TTabitem;
s :TEdit;
begin
o := TTabitem(ManageF.MTabcontrol1.FindComponent('InventoryF'));
ManageF.MTabcontrol1.ActiveTab := o;
s := TEdit(ManageF.MTabcontrol1.FindComponent('VendorF').FindComponent('SearchEdit1')); <-- Dont think it actually found the TEdit
s.Setfocus; <------------------ Not focusing giving access violtaion error
with DataConModule1.InventoryQuery do
...
end;
TSpeedButton invBtn that is injected into Panel to the side
unit InjectedInvBtn;
interface
implementation
uses
FMX.Types, InventoryInf, FMX.Controls, FMX.Forms, InjectedControlsHelper, FMX.StdCtrls,
ManageInf;
var
SysBtn: TSpeedButton;
initialization
SysBtn := TInjectedControl<TSpeedButton>.Create;
SysBtn.Align := TAlignLayout.Top;
SysBtn.Name := 'invBtn';
SysBtn.Text := 'INVENTORY';
ManageF.MenuPanel.AddObject(SysBtn);
SysBtn.OnClick := InventoryF.Look4Tabitem;
end.
**ManageF Showing how it loads the forms into tabs MTabControl1 **
uses Shared;
function IsPluginFrameClass(AType: TRttiType; var AFormClass: TCustomFormClass): Boolean;
var
LClass: TClass;
begin
if not (AType is TRttiInstanceType) then Exit(False);
LClass := TRttiInstanceType(AType).MetaclassType;
Result := LClass.InheritsFrom(TCustomForm) and Supports(LClass, IPluginFrame);
if Result then
AFormClass := TCustomFormClass(LClass);
end;
function TSettingsF.LoadPluginTabs(const AFileName: string): HMODULE;
var
Context: TRttiContext;
Frame: TCustomForm;
FrameClass: TCustomFormClass;
LType: TRttiType;
Package: TRttiPackage;
Tab: TTabItem;
// Statusbar: TTabItem;
//Butz: TButton;
begin
Result := LoadPlugin(AFileName);
try
{ Cycle through the RTTI system's packages list to find the one we've just loaded. }
for Package in Context.GetPackages do
if Package.Handle = Result then
begin
{ Cycle through the package's types looking for implementors of the
IPluginFrameinterface defined in the shared package. }
for LType in Package.GetTypes do
if IsPluginFrameClass(LType, FrameClass) then
begin
{ For each frame, create a new tab to host its contents. In the case of
a VCL application, we could require an actual TFrame object, or failing
that, embed the form directly. FireMonkey has neither frames proper nor
supports embedded forms, so instead we ask the implementing form to
nominate a base control that will get embedded. }
Tab := TTabItem.Create(ManageF.MTabcontrol1);
Frame := FrameClass.Create(Tab);
Tab.Text := ' ' + Frame.Caption;
Tab.Name := Frame.Name;
MyTablist.Add(Tab);
(Frame as IPluginFrame).GetBaseControl.Parent := Tab;
{ Associate the tab with the plugin - since it owns the 'frame' form,
and that form owns its own components, freeing the tab will have the
effect of freeing all the actual plugin objects too. }
RegisterPluginComponent(Result, Tab);
ManageF.MTabcontrol1.AddObject(Tab);
Tab.Width := Tab.Canvas.TextWidth(Tab.Text + 'w');
end;
if IsStatusFrameClass(LType, FrameClass) then
begin
....
{ Associate the tab with the plugin - since it owns the 'frame' form,
and that form owns its own components, freeing the tab will have the
effect of freeing all the` actual plugin objects too. }
// RegisterPluginComponent(Result, Statusbar);
// ManageF.StatusMenuPanel1.AddObject(Statusbar);
//Statusbar.Width := Statusbar.Canvas.TextWidth(Statusbar.Name + 'w');
end;
Break;
end;
except
UnloadPlugin(Result);
raise;
end;
end;
Hope i illustrated the problem properly. Please Help =(
Found a work around by looping through the components of the Tcustomform that is embedded. Here is what i did.
instead of TEdit i used a tms edit box TTMSFMXSearchEdit
procedure TVendorF.focuscheck;
var
i: integer;
j: integer;
Fieldname: string;
o : TTabitem;
e : TTMSFMXSearchEdit;
begin
if ManageF.MTabcontrol1.FindComponent('VendorF').Name = 'VendorF' then
begin
o := TTabitem(ManageF.MTabcontrol1.FindComponent('VendorF'));
//ShowMessage(IntToStr(o.ComponentCount)) ;
// ShowMessage((o.Components[0].tostring));
for i := 0 to ManageF.MTabcontrol1.ActiveTab.ComponentCount - 1 do
if (ManageF.MTabcontrol1.ActiveTab.Components[i]) is TCustomForm then
begin
// ShowMessage('TCustomForm Recognized gonna look for child components now');
// ShowMessage(IntToStr(ManageF.MTabcontrol1.ActiveTab.Components[i].ComponentCount));
for j := 0 to ManageF.MTabcontrol1.ActiveTab.Components[i].ComponentCount - 1 do
if (ManageF.MTabcontrol1.ActiveTab.Components[i].Components[j]) is TTMSFMXSearchEdit then
begin
// ShowMessage('Edit box found =)')
if (ManageF.MTabcontrol1.ActiveTab.Components[i].Components[j].Name = 'VenSearchEdit1') then
begin
//ShowMessage('Edit1 box found =)');
//ShowMessage('See if we can focus it');
e := TTMSFMXSearchEdit(ManageF.MTabcontrol1.ActiveTab.Components[i].Components[j]) ;
e.SetFocus;
end;
end;
end;
end;
end;
Its a little sloppy but it works =). If anyone else got a better way let me know
I'm trying to implement custom headers and footers when printing from a TWebBrowser, as per the information in this Microsoft knowledge base question (KB267240). The knowledgebase article is quite helpful and even includes a lengthy code example, however, the code example is in C++ not Delphi, so I've had to attempt to convert the necessary data structure into Delphi code myself. I'm not terribly confident I've correctly converted the part of the code I need.
Here's probably the most important part of that article, where it explains what is supposed to go in my paramater vaIn in my code below:
When you use an OLECMDID enumeration of the OLECMDID_PRINT element
together with the ExecWB method, you can specify extended printing
information by passing in the SAFEARRAY structure through the VARIANT
argument pvaIn. This SAFEARRAY data type takes a maximum of five
items:
1) A string (BSTR) that contains a custom header.
2) A string (BSTR) that contains a custom footer.
3) ...
When I run the code I've written, it successfully removes the original header and footer, but does not replace it with my new header and footer strings, so I'm wondering if my code is incorrect in some way (or several ways), or if I simply shouldn't expect it to work since I'm using IE 9 and not a version in the 4-6 range that was current at the time the knowledgebase article was written.
var
vaIn, vaOut: OleVariant;
begin
vaIn := VarArrayCreate([0,1], varOleStr);
vaIn[0] := VarAsType('new header', VarOleStr); //header
vaIn[1] := VarAsType('new footer', VarOleStr); //footer
// Show print-preview dialog
WebBrowser1.ControlInterface.ExecWB(OLECMDID_PRINTPREVIEW,
OLECMDEXECOPT_DONTPROMPTUSER, vaIn, vaOut);
end;
This prints with custom header/footer. Custom headers don't for OLECMDID_PRINTPREVIEW, but they do work for OLECMDID_PRINT. The key is to use VT_ARRAY or VT_BYREF as the TVariantArg has to be passed by reference.
Code credit: TEmbeddedWB at https://github.com/7even11/Delphi-EmbeddedWB
procedure PrintWithHeaderFooter(ControlInterface: IWebBrowser2; Header, Footer: PWideChar; Options: OLECMDEXECOPT);
var
saBound: TSafeArrayBound;
psaHeadFoot: PSafeArray;
vaIn, vaOut: TVariantArg;
vHeadStr, vFootStr: TVariantArg;
rgIndex: LongInt;
begin
try
saBound.lLbound := 0;
saBound.cElements := 2;
psaHeadFoot := SafeArrayCreate(VT_VARIANT, 1, saBound);
vHeadStr.vt := VT_BSTR;
vHeadStr.bstrVal := SysAllocString(Header);
vFootStr.vt := VT_BSTR;
vFootStr.bstrVal := SysAllocString(Footer);
rgIndex := 0;
OleCheck(SafeArrayPutElement(psaHeadFoot, rgIndex, vHeadStr));
rgIndex := 1;
OleCheck(SafeArrayPutElement(psaHeadFoot, rgIndex, vFootStr));
vaIn.vt := VT_ARRAY or VT_BYREF;
vaIn.parray := psaHeadFoot;
ControlInterFace.ExecWB(OLECMDID_PRINT, Options,
OleVariant(vaIn), OleVariant(vaOut));
if vHeadStr.bstrVal <> nil then
SysFreeString(vHeadStr.bstrVal);
if vFootStr.bstrVal <> nil then
SysFreeString(vFootStr.bstrVal);
except
end;
end;
procedure Print(ControlInterface: IWebBrowser2; bHideSetup: Boolean = False; bCustomHeaderFooter: Boolean = False; Header: string = ''; Footer: string = '');
var
vaIn, vaOut: OleVariant;
begin
if DocumentLoaded(ControlInterface.Document) then
begin
if bCustomHeaderFooter then
begin
if bHideSetup then
PrintWithHeaderFooter(ControlInterface, TaskAllocWideString(Header), TaskAllocWideString(Footer), OLECMDEXECOPT_DONTPROMPTUSER)
else
PrintWithHeaderFooter(ControlInterface, TaskAllocWideString(Header), TaskAllocWideString(Footer), OLECMDEXECOPT_PROMPTUSER);
end
else
if bHideSetup then
ControlInterface.ExecWB(OLECMDID_PRINT, OLECMDEXECOPT_DONTPROMPTUSER, vaIn, vaOut)
else
ControlInterface.ExecWB(OLECMDID_PRINT, OLECMDEXECOPT_PROMPTUSER, vaIn, vaOut)
end;
end;
If I create n Tabsheets at runtime and create one Webbrowser inside each tabsheet using a method such as:
procedure createTab;
var crm: TWebbrowser;
var ts: TsTabSheet;
begin
//Instance of tabsheet
ts := TsTabSheet.Create(pageControl);
ts.PageControl := pageControl;
//Instance of webbrowser
crm := TWebbrowser.Create(ts);
crm.Parent := TWinControl(ts);
crm.Align := alClient;
end;
When one of tabsheet instance is active how could I know which webbrowser is inside it? Sample:
procedure navigateToActiveTabsheet(url: string);
begin
//TO DO - How navigate to webbrowser inside active tabsheet?
end;
The Controls property of a windowed control allows you to obtain every child control. Because these children can be any TControl descendent, you'll need to cast to TWebBrowser. Use the as operator to benefit from runtime validity checking of the cast:
procedure navigateToActiveTabsheet(url: string);
var
wb: TWebBrowser;
begin
wb := pageControl.ActivePage.Controls[0] as TWebBrowser;
wb.Navigate(url);
end;
var
WB: TWebBrowser;
WB := TWebBrowser(pageControl.ActivePage.Controls[0]);
How can i change adsense code TWebbrowser object after document complete
i try change div innerhtml but i cant my see adsense commercial how can do this
my code block
doc := ie.Document as IHTMLDocument3;
doc2 := ie.Document as IHTMLDocument2;
di := doc.getElementById('aliveli') as IHTMLElement;
s := tstringlist.Create;
s.Add('<script type="text/javascript"><!--');
s.Add('google_ad_client = "pub-8340139631405508";');
s.Add('/* 120x240, oluşturulma 28.10.2009 */');
s.Add('google_ad_slot = "8877320187";');
s.Add('google_ad_width = 468;');
s.Add('google_ad_height = 15;');
s.Add('//-->');
s.Add('</script>');
s.Add('<script type="text/javascript"');
s.Add('src="http://pagead2.googlesyndication.com/pagead/show_ads.js">');
s.Add('</script>');
s.Add('');
doc2.body.innerHTML := s.text;
Try using di.innerHTML instead of doc2.body.innerHTML.