Theme:
v
NetAccess™ Tutorial

Description

In this NetAccess™ Tutorial we will create a C# DLL containing a C# Web Browser User Control. We will then use this DLL from APL+Win embedding the Web Browser control in an APL+Win form.

Tutorial

Proceed as follows:

  1. Load APL+Win and load the NetAccess.w3 workspace
  2. Open the Edit / Preferences menu and check the NetAccess generates a Visual Studio project when you click the Generate button check box
  3. in the Default directory where NetAccess generates your C# projects edit control, type the complete path of your Visual Studio Projects directory, in my case: J:\Documents\Visual Studio 2008\Projects
  4. Click OK to close the NetAccess 3.1 Preferences dialog
  5. Type: NetAccess.UserControls in the NameSpace field
  6. Type: Browser in the Class field
  7. Check the User Control check box as we want to generate a DLL containing a C# User Control
    The DLL C# Code is automatically generated and a complete Visual Studio 2008 Solution is automatically created:
  8. Click OK to close the Message Box
  9. Open Visual Studio and select File / Open / Project/Solutions...
  10. Select the NetAccess.UserControls solution, then select the NetAccess.UserControls.sln file and click Open
  11. In the Solution Explorer pane on the right, double click WebBrowser.cs You should obtain something like this:
  12. Drag and drop a WebBrowser control from the Visual Studio Toolbox to the User Control You should obtain something like this, the WebBrowser control being docked into the User Control container:
  13. Press Ctrl+S to save the changes made to the User Control
  14. Right click on Browser.cs in Solution Explorer and select View Code The same code as generated by NetAccess™ gets displayed.
  15. Locate the Constructor on line 36 and type: this.webBrowser1. after InitializeComponent()
    This displays an Intellisense popup showing all the C# WebBrowser object properties, methods and events.



    You can scroll through this list to inspect all the available properties, methods and events.
    We will select some of them and implement them as properties, methods and events of our User Control.
  16. We are interested in implementing the Navigate method; so we can type: this.webBrowser1.Navigate( and as soon as we type the open parenthesis, Intellisense shows us which kind of parameters the Navigate method expects:



    We see that the Navigate method expects a string argument. So, to implement this method, let's return to NetAccess™
  17. Alt+Tab to NetAccess™
  18. Click the Methods button
  19. Type Navigate for the method name, void for the result, url for the Argument1 name and string for the Argument1 Type, as follows:
  20. Click on the C# Code button
    We see that the Navigate method has been added to our DLL:
    namespace NetAccess.UserControls
    {
        [Guid("F1709450-61AD-46EF-BDDE-1C1807F21944")]
        [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
        public interface IBrowser
        {
            int ParentHandle { get; set; }
            int[] where { get; set; }
            void Navigate(string url);
        }
    
        [Guid("09837D8A-372D-4518-9FC4-C760E7A58C1B")]
        [ClassInterface(ClassInterfaceType.None)]
        [ProgId("NetAccess.UserControls.Browser")]
        public partial class Browser : UserControl, IBrowser
        {
            [DllImport("user32")]
            private static extern int SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
            private System.IntPtr parent;
    
            public Browser()
            {
                InitializeComponent();
            }
    
            public int ParentHandle
            {
                get { return (int)parent; }
                set 
                { 
                    parent = (System.IntPtr)value;
                    SetParent(this.Handle, parent);
                }
            }
    
            public int[] where
            {
                get
                {
                    int top = this.Top;
                    int left = this.Left;
                    int height = this.Height;
                    int width = this.Width;
                    return new int[] { top, left, height, width };
                }
                set
                {
                    //this.SetBounds(value[1], value[0], value[3], value[2]);
                    //this.maskedTextBox1.SetBounds(0, 0, value[3], value[2]);
                    this.Top = value[0];
                    this.Left = value[1];
                    this.Height = value[2];
                    this.Width = value[3];
                    this.Controls[0].Top = 0;
                    this.Controls[0].Left = 0;
                    this.Controls[0].Height = value[2];
                    this.Controls[0].Width = value[3];
                }
            }
    
            public void Navigate(string url)
            {
            }
        }
    
    It's time to come back to Visual Studio to implement the Navigate code, but before doing that we must save our NetAccess project.
  21. Press: Ctrl+S to save the NetAccess project and accept the name of NetAccess.UserControls.ccg; click Save
  22. Press: Alt+Tab to return to Visual Studio
    Visual Studio displays the following dialog:



    Click Yes
  23. Locate the public void Navigate(string url) { this.webBrowser1.Navigate(url); } This instructs the Browser User Control to call the Navigate method on the webBrowser1 WebBrowser instance that it contains.
    We could have chosen a different name for our User Control method, but it is clearer to use the same name as the WebBrowser method we want to invoke.
    It's time to test our Browser C# User Control in APL. But first we need to compile our DLL!
  24. In Solution Explorer right click the Solution at the top and select Build Solution If everything goes well, you should see: Build succeeded being displayed in the Visual Studio status bar
  25. Start APL+Win
    Type the following code:
          'ff'⎕wi'Create' 'Form'('scale'5)('caption' 'Testing the C# Browser User Control')
          'ff'⎕wi'.web.Create' 'NetAccess.UserControls.Browser'('ParentHandle'('ff'⎕wi'hwnd'))
          'ff'⎕wi'.web.where'(0 0,'ff'⎕wi'size')
          'ff'⎕wi'.web.Navigate' 'http://www.microsoft.com'
    
    The 1st line create an APL+Win form and sets its coordinates to pixels ('scale'5).
    The 2nd line creates an instance of our C# DLL (called: ff.web) and forces its parent to be the ff APL Form.
    The 3rd line forces the C# WebBrowser object to use the whole ff Form client area.
    The 4th line calls the Navigate method to navigate to the Microsoft Web Site
    Here is what you should see:



  26. Alt+Tab to the NetAccess window
    We will now define an event handler.
  27. Click the Events button
  28. Define the DocumentCompleted event as follows:



    This creates the correct event declaration code in the DLL.
    Be sure to press Ctrl+S to save the DLL code.
  29. Now Alt+Tab to Visual Studio and click Yes to reload the latest version of the DLL (as saved by NetAccess)
  30. Change the DLL code around line 50 as follows:
    public Browser()
    {
        InitializeComponent();
        this.webBrowser1.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(webBrowser1_DocumentCompleted);
    }
    
    void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
    {
        DocumentCompleted();
    }
    
    i.e. define a DocumentCompleted event handler on the webBrowser1 object associating it with a webBrowser1_DocumentCompleted event handler method. In the webBrowser1_DocumentCompleted simply fire the DocumentCompleted event defined on the Browser object.
  31. Exit APL because you cannot recompile the DLL in Visual Studio if it is still in use by APL
  32. In Visual Studio, in Solution Explorer right click the Solution at the top and select Build Solution to recompile the DLL
  33. Start APL once more
  34. Enter the following instructions:
          'ff'⎕wi'Create' 'Form'('scale'5)('caption' 'Testing the C# Browser User Control')
          'ff'⎕wi'.web.Create' 'NetAccess.UserControls.Browser'('ParentHandle'('ff'⎕wi'hwnd'))
          'ff'⎕wi'.web.where'(0 0,'ff'⎕wi'size')
          'ff'⎕wi'.web.onXDocumentCompleted' '⎕←"The Web Page has just completed loading!"'
          'ff'⎕wi'.web.Navigate' 'http://www.microsoft.com'
    The Web Page has just completed loading!
    The Web Page has just completed loading!
    The Web Page has just completed loading!
          'ff'⎕wi'.web.Navigate' 'http://www.lescasse.com'
    The Web Page has just completed loading!
    
    You can clearly see that the onXDocumentCompleted event does fire when the page has been entirely loaded. Note that in the case of the Microsoft Web Site, this event fires 3 times seeming to indicate that 3 different pages are loaded in a row. For my own site the onXDocumentCompleted fires only once as it generally is the case.
    So now, all what's left left to do is to create a couple of properties in our DLL.
  35. Exit APL so that we can recompile the DLL when we need to
  36. Now Alt+Tab to the NetAccess Window and click the Properties button
  37. Define a Visible property with a Type of bool and leave Get & Set set to get & set
  38. Define a IsBusy property with a Type of bool and change Get & Set set to just get as the C# WebBrowser object IsBusy property is a read-only property
  39. Define a DocumentText property with a Type of string and leave Get & Set set to get & set
    At this stage the NetAccess™ window should look like this:


    This creates the correct properties declaration code in the DLL.
    Be sure to press Ctrl+S to save the DLL code.
  40. Press: Alt+Tab to return to Visual Studio
    Visual Studio displays the following dialog:



    Click Yes
  41. Locate the Visible property around line 66 in the DLL code and change it to read:
    public new bool Visible
    {
        get { return webBrowser1.Visible;}
        set { webBrowser1.Visible = value;}
    }
    
  42. Locate the DocumentText property around line 50 in the DLL code and change it to read:
    public string DocumentText
    {
        get { return webBrowser1.DocumentText;}
        set { webBrowser1.DocumentText = value;}
    }
    
  43. Locate the IsBusy property around line 58 in the DLL code and change it to read:
    public bool IsBusy
    {
        get { return webBrowser1.IsBusy;}
        //set { _IsBusy = value;}
    }
    
  44. In Visual Studio, in Solution Explorer right click the Solution at the top and select Build Solution to recompile the DLL
  45. Start APL once again
  46. Enter the following instructions:
          'ff'⎕wi'Create' 'Form'('scale'5)('size'200 500)('caption' 'Testing the C# Browser User Control')
          'ff'⎕wi'.web.Create' 'NetAccess.UserControls.Browser'('ParentHandle'('ff'⎕wi'hwnd'))
          'ff'⎕wi'.web.where'(0 0,'ff'⎕wi'size')
          'ff'⎕wi'.web.Visible'0
          'ff'⎕wi'.web.Visible'1
          'ff'⎕wi'.web.xDocumentText' '<html><head/><body><h1>Populating the Browser Object</h1><p>This document has been directly sent to the Browser from APL</p></body></html>'
    
    You should see the following APL Form:

Conclusion

As you can see, it is pretty easy to use a C# control in an APL+Win form. Visual Studio and C# offer a very rich set of wonderful controls and all of them can be embedded and used in APL+Win form. NetAccess helps generate all the DLL complex code. You just need to complete the various methods, properties and events code for them to do something useful.