Mark Williams
Members-
Content Count
288 -
Joined
-
Last visited
Community Reputation
14 GoodTechnical Information
-
Delphi-Version
Delphi 10.4 Sydney
Recent Profile Visitors
The recent visitors block is disabled and is not being shown to other users.
-
Manipulating IIS with the Application Host Administration Interface - OLE issues
Mark Williams replied to Mark Williams's topic in Windows API
The code I am using was an example I got off the web. Can't even remember where now! Can't fund the MS documentation for it although I can find the documentation for the Application Host Administration Interface. If I change the call as follows: Site := ServerManager.GetAdminSection('sites', 'system.applicationHost/'); I then get an error advising that the first parameter is not a valid section path in the config file. So I think the return value of an OLEVariant is okay. I think the problem lies with the parameters passed to the function. I think the first param is correct 'system.applicationHost/sites'. I think it is the second param that is causing the problem:'MACHINE/WEBROOT/APPHOST'. The second param is already declared in the call to: ServerManager.CommitPath := 'MACHINE/WEBROOT/APPHOST'; That is that is the path to the config file. The MS documentation for the Application Host Administration Interface states it relates to IIS7 and IIS8 and I am using IIS10, but can't find later documentation and I have tested it a little with IIS10 and seems to work. The documentation declares the GetAdminSection function as HRESULT GetAdminSection( [in, string] BSTR bstrSectionName, [in, string] BSTR bstrPath, [out, retval] IAppHostElement** ppAdminSection ); Calling the function as: GetAdminSection('system.applicationHost/', 'MACHINE/WEBROOT/APPHOST', SitesSection); Results in a run time error that there are too many parameters. This works using thee imported type library, but not as an OLE call. That would suggest that the second parameter in the OLE call is also correct. As you can probably see I am floundering! I guess I will have to work with the rather yuk interface! Thanks for your help. -
Manipulating IIS with the Application Host Administration Interface - OLE issues
Mark Williams replied to Mark Williams's topic in Windows API
I had started to go down this route. I'm using the 64 bit type library, which is even more of a pain to use. It does seem to work however. Thanks for the reference to the dotnet wrapper. -
Manipulating IIS with the Application Host Administration Interface - OLE issues
Mark Williams replied to Mark Williams's topic in Windows API
Same result. It reports true for Server Manager, but then fails with the variant does not reference... error on the call to ServerManager.GetAdminSection. -
Manipulating IIS with the Application Host Administration Interface - OLE issues
Mark Williams posted a topic in Windows API
I cannot understand why the following code does not work: function IsOleObjectActive(OleObject: OleVariant): Boolean; begin Result := not VarIsClear(OleObject) and not VarIsEmpty(OleObject) and not VarIsNull(OleObject); end; procedure TForm1.Button1Click(Sender: TObject); var ServerManager: OleVariant; Site: OleVariant; AppPool: OleVariant; Security: OleVariant; begin // Initialize COM library CoInitialize(nil); try // Create an instance of the ServerManager object ServerManager := CreateOleObject ('Microsoft.ApplicationHost.WritableAdminManager'); ServerManager.CommitPath := 'MACHINE/WEBROOT/APPHOST'; // Add a new site Site := ServerManager.GetAdminSection('system.applicationHost/sites', 'MACHINE/WEBROOT/APPHOST'); - if IsOleObjectActive(Site) then Showmessage('Active') else exit; Site := Site.Collection.AddElement('site'); //FAILS HERE Site.Properties.Item('name').Value := trim(eSiteName.text); // Site.Properties.Item('id').Value := 2; Site.Properties.Item('physicalPath').Value := 'C:\inetpub\wwwroot\' + trim(ePhysicalPath.text); // Configure bindings Site.Bindings.Collection.AddElement('binding'); Site.Bindings.Collection.Item(0).Properties.Item('protocol').Value := 'http'; Site.Bindings.Collection.Item(0).Properties.Item('bindingInformation').Value := '*:80'; Site.Bindings.Collection.AddElement('binding'); Site.Bindings.Collection.Item(1).Properties.Item('protocol').Value := 'https'; Site.Bindings.Collection.Item(1).Properties.Item('bindingInformation').Value := '*:443'; // Add an application pool AppPool := ServerManager.GetAdminSection ('system.applicationHost/applicationPools', 'MACHINE/WEBROOT/APPHOST'); AppPool := AppPool.Collection.AddElement('add'); AppPool.Properties.Item('name').Value := trim(eSiteName.text); AppPool.Properties.Item('managedRuntimeVersion').Value := trim(eNetFramework.text); // Assign the application pool to the site Site.Applications.Collection.Item(0).Properties.Item('applicationPool') .Value := trim(eSiteName.text); // Commit the changes ServerManager.CommitChanges; finally // Uninitialize COM library CoUninitialize; end; When I try to add the new site I get "Variant does not reference an automation object." I've tried adding the application pool first, but same problem. As far as I can see the section names are correct as per the applicationHost.config file and all functions, properties are correct as per the nativerd.dll. I've also tried running the app in elevated mode. Makes no difference. -
1. But that will give me the textextent of the caption as it appears on a tpanel, not as it appears on the title bar. I assume these can be different depending on the theme. 2. Can't see how TMessageForm helps. Don't see that it addresses the theming issue.
-
I create a themed form on the fly. The form caption varies each time. I am trying to set the form width to a sufficient size so that the caption is displayed in full. I can't see any easy way of doing this. I'm guessing I have to analyse all the elements on the title bar and go from there. Starting with the text extent of the desired caption: var Canvas: TCanvas; s: string; r: TRect; t: TTextFormat; begin s := caption; Canvas := TCanvas.Create; try Canvas.Handle := GetDC(0); TStyleManager.ActiveStyle.GetTextExtent(Canvas.Handle, teTextLabel, s, t, r); finally ReleaseDC(0, Canvas.Handle); end; First, I cannot work out which themed element represents the title bar caption. It has to be within the range [teCategoryButtons..teTextLabel]] ie: teCategoryButtons, teCategoryPanelGroup, teCheckListBox, teControlBar, teDataNavButtons, teGrid, teHint, tePanel, teTabSet, teTextLabel, I've opted for teTextLabel, but have no idea if this is right. Secondly, the code does not compile. "No overloaded version of GetTextExtent...". I don't understand why. GetTextExtent is declared as: function GetTextExtent(DC: HDC; Details: TThemedElementDetails; const Text: string; Flags: TTextFormat; out ExtentRect: TRect): Boolean; overload; Assuming I can get this to work and correctly calculate the required text width for the title bar, I guess I then have to work out the width required for all other elements on the title bar and set form width accordingly. It will probably take me the rest of my limited remaining years to work out how to query all the other elements on the title bar. Can anyone suggest a simpler way of achieving this?
-
I've moved to a new laptop running Windows 11. I installed from the downloaded ISO. I'm missing the help files. When I go into Manage Platform (to try and switch off dark mode), I am told that setup cannot continue due to a corrupted installation file. How can I get the help files please and is there a way of fixing the corrupted file?
-
That was ir. Must have inadvertently deleted it. Thanks
-
Just revisited a project after a few days away. Now, for one of the units in the project, when I toggle F12 to show its form, nothing happens. The menu item "Toggle Form/Unit is also disabled. It is only this one form and not any others that has this issue. I am not aware of any changes I may have made last time that could be causing this issue. When I view the project source, I can see that the unit is listed but it doesn't have its form listed after it like all the other project units that have associated forms. I assume that somehow the form's connection to the unit has been lost. Restore in 'Restore.pas' {frmRestore}, Reconciler in 'Reconciler.pas' {frmReconciler}, Settings in 'Settings.pas'; I have tried removing the unit and re-adding it to the project, but that does nothing. Anyone have any idea what might be causing this and how I can fix it? Thanks
-
I have a licence for Delphi 10 through to 11.0. I haven't renewed my subscription since then. I'm trying to move my Delphi to a new laptop. When try and download any version within the above range from Embarcadero I am simply advised that I haven't renewed my subscription and the download is declined. I'm guessing there must be some way of doing this. Can anyone help please?
-
FireDac in memory dataset filter before iterate?
Mark Williams replied to Mark Williams's topic in Databases
Ran some tests on an in memory dataset of 25K records. Without filter 31ms to iterate the whole dataset (whilst also querying each record to see if it matched the required "document_category_id)." . Filtering first took twice as long to filter and iterate even though the resulting dataset was only 30 records. That sort of answers my question. But would this still hold true with say a million plus records? -
I need to work with a potentially large dataset in memory. It has an integer field called "document_category_id". On first loading the table it is sometimes necessary to update records in the table from one document_category_id to another. This might need to be done for several, but not all of the various document_category_ids. Trying to work out what is the most efficient way of iterating. Would it be more efficient to filter on the requored document_category_ids first and then iterate or to iterate on an unfiltered table?
-
Managed to work out a solution in the end. Sure there will be some issues I haven't considered, but seems to work ok. If anyone is interested here's the code: procedure TForm3.TabControl2DrawTab(Control: TCustomTabControl; TabIndex: Integer; const Rect: TRect; Active: Boolean); var TabName:String; Pt : TPoint; R: TRect; TabUnderMouse:Integer; begin Pt := TabControl2.ScreenToClient(Mouse.CursorPos); TabUnderMouse := TabControl1.IndexOfTabAt(Pt.X, Pt.Y); with (Control as TTabControl).canvas do begin R := Rect; if TabIndex=1 then Font.Style := [fsStrikeout]; if (TabUnderMouse = TabIndex)and Active then Font.Color := TStyleManager.ActiveStyle.GetStyleFontColor(sfTabTextActiveHot) else if Active then Font.Color := TStyleManager.ActiveStyle.GetStyleFontColor(sfTabTextActiveNormal) else if (TabUnderMouse = TabIndex) then Font.Color := TStyleManager.ActiveStyle.GetStyleFontColor(sfTabTextInActiveHot) else Font.Color := TStyleManager.ActiveStyle.GetStyleFontColor(sfTabTextInActiveNormal); tabName := TTabControl(Control).Tabs[TabIndex]; Brush.Style := bsClear; DrawText(Handle, PChar(TabName), Length(TabName), R, DT_SINGLELINE or DT_VCENTER or DT_CENTER) end; end;
-
I want to show a TabControl with tabs with different font styles. Basically, I want the font in some of the tabs to be shown in strikeout. The app uses a couple of different themes. I thought I'd use the StyleManager to achieve this with the following code: with (Control as TTabControl) do begin tabName := TTabControl(Control).Tabs[TabIndex]; if TabIndex=1 then Canvas.Font.Style:=[fsStrikeout]; Pt := TabControl2.ScreenToClient(Mouse.CursorPos); TabUnderMouse := TabControl1.IndexOfTabAt(Pt.X, Pt.Y); if Active then Details := TStyleManager.ActiveStyle.GetElementDetails(ttTabItemSelected) else if (TabUnderMouse=TabIndex) then Details := TStyleManager.ActiveStyle.GetElementDetails(ttTabItemHot) else Details := TStyleManager.ActiveStyle.GetElementDetails(ttTabItemNormal); TStyleManager.ActiveStyle.DrawElement(Canvas.Handle, Details, Rect); TStyleManager.ActiveStyle.DrawText(Canvas.Handle, Details, TabName, Rect, DT_VCENTER or DT_CENTER, Canvas.Font.Color); end; This sets the colour of the tab background perfectly depending on its state, but has no impact on the font which is always black. However, the font is always black whatever the state of the tab. The color parameter in the DrawText function does not appear to do anything. I've tried setting the canvas font color before calling Drawtext to the stylefontcolor of the tab element in its various states. It has no effect, not does entering any color whatsoever in the color parameter.
-
Thinfinity VirtualUI - cloud-based conversion
Mark Williams replied to Mark Williams's topic in General Help
Seems to be spam.