VSTools 2010: Adding Company Name to Dynamics GP Home Page

Patrick Roth - Click for blog homepageA few years ago, the question came up (partner, customer, Convergence - I don't recall) about being able to identify the current company on the Dynamics Home Page of the Navigation pane.

Currently at the top of the Home Page, the page will default to:

%user%'s Home

which after substituting the user id we would get:

sa's Home

The thought would be that the title should also display the company name currently logged into such as:

sa's Home in Fabrikam, Inc.

With a script.log and some research, I found the procedure that creates the file.  After that it was a simple matter of creating the trigger in Dexterity to change the output file - Homepage.xml - to add the company name.  The only tricky part was doing the actual substitution in the file since it was a 4k file and thus would be a "big text" field in Dexterity.

Now that VSTools 2010 exposes the ability for procedure & function triggers, I thought that I would revisit this project to see if it was possible to do with the new feature.

The first step is to do a script.log to see where this might be possible to intercept the call that Dynamics is making to do this.  To test, I turned on the script logging and pressed the Refresh button and then turned logging off.

Script.log

'ScBar_NotifyOnHomeSelect of form syScBarObj'
    'RefreshHomePage of form syHomePageXML'
        'XML_CreateStream of form syHomePageXML', "C:\Users\patrick\AppData\Local\Temp\HomePage.xml"
           <lots of stuff removed>
            'Get() of form syHomePageLayout', 0, 2-, 13
                'Get() of form TableObj', 0, 2-, table 'syHomePageLayout', 13
            'Destroy of form syUser', 1-
            'Destroy of form syHomePageLayout', 2-
        'LoadXML of form syHomePageXML', "C:\Users\patrick\AppData\Local\Temp\HomePage.xml"
    'Command_ShowAndEnable', Start Control Number, 0
        'UserHasAccess() of form syCmdSecurityObj', 0, 0, 1568, 298, ""

 

I snipped a large chunk of the "XML Creation" code that we don't care about for our purposes in the script.log above.  When I do that, it is fairly obvious the script that "kicks off" the whole process is RefreshHomePage of form syHomePageXML.

That procedure appears to contain 2 calls that do the work.

XML_CreateStream of form syHomeageXML
LoadXML of form syHomePageXML

If you didn't have source code, you could guess fairly easily that XML_CreateStream is what creates the data and LoadXML is what makes the home page display in the navigation pane.

The next step would be to see what the parameters are using the Dynamics SDK.  We potentially would have to worry that VSTools wouldn't support the parameter types the script uses, however in this case it is obvious that both of these scripts take a single parameter that is the path (in native format) to the xml file to be used.  As it is a simple string, we know that VSTools 2010 will have it available.

Then the question would be - which procedure do we trigger on?

In this case, I don't see that it should make a difference.  We could trigger after the creation of the XML or trigger before it is displayed in the LoadXML procedure - both should work.  I chose the first approach.

After I created my new Visual Studio 2010 project, I chose the Dynamics GP 2010 C# template and coded the event subscription:

Initialize Procedure

 public void Initialize()
{
     Microsoft.Dexterity.Applications.Dynamics.Forms.SyHomePageXml.Procedures.XmlCreateStream.InvokeAfterOriginal += 
           new Microsoft.Dexterity.Applications.DynamicsDictionary.SyHomePageXmlForm.XmlCreateStreamProcedure.InvokeEventHandler(XmlCreateStream_InvokeAfterOriginal);
}

Visual Studio suggests creating the new method XmlCreateStream_InvokeAfterOriginal and I let it do so.  In it, I need to read the XML file and make the substitution.

As this was an XML file, I thought perhaps I could be fancy and look through the Nodes, the attributes to the nodes, the different elements to find my target and somehow rename it.  Well I gave it 15 minutes of honest effort before I decided I could just do a Replace() on what I needed and call it good.  I'll leave it up to the readership to post the "correct" code in the comments but in my book sometimes "it works" is good enough.

EventHandler Code with Comments

 void XmlCreateStream_InvokeAfterOriginal(object sender, Microsoft.Dexterity.Applications.DynamicsDictionary.SyHomePageXmlForm.XmlCreateStreamProcedure.InvokeEventArgs e)
{
     XmlDocument xml = new XmlDocument();
     //inParam1 is the pathname to the HomePage.xml file generated by this procedure
     xml.Load(@e.inParam1);
     //replace the stock "sa's Home" with "sa's Home in Fabrikam" to identify the current company
     xml.InnerXml = xml.InnerXml.Replace(Dynamics.Globals.UserId.Value + "'s Home", Dynamics.Globals.UserId.Value + "'s Home in " + Dynamics.Globals.CompanyName.Value);
     //and overwrite the file with our change
     xml.Save(@e.inParam1);
}

After compiling my assembly, I placed it in my \Addins folder and relaunched Dynamics GP 2010.  Below is a screenshot of the results with the modified title marked.

 

While I realize this isn't a complex project, it was interesting to research and do.  And I find it groundbreaking in the fact that you previously HAD to use Dexterity to make this work.  VS Tools 2010 now gives me a choice in the toolset I wish to use - for this project anyway.

Best Regards,
Patrick Roth

// Copyright © Microsoft Corporation. All Rights Reserved.
// This code released under the terms of the
// Microsoft Public License (MS-PL, https://opensource.org/licenses/ms-pl.html.)