Solved

vb.net - instantiating flash activex programmatically

Posted on 2006-06-18
8
2,105 Views
Last Modified: 2013-11-25
There is a bug in the flash ocx that makes it impossible to use a single control to load multiple movies in sequence if they both use a key listener to map keypresses to functions. Since i have several templates that do the same job with different interfaces but require that i map keystrokes the same way in each, what happens is that if the user switches from one template to the other the key listener is loaded again each time and duplicates the key processing for each instance - meaning instead of {down} you get {down}{down} or {down}{down}{down} depending on how many times you switch.

My question is - I need a workaround for this issue. I can load 2 controls but then if I add more templates it requires updating the code and adding more controls.

As a workaround I thought I would try to destroy and re-create the flash control in code. Since its designed to be used as a forms control I'm finding it a bit dificult to implement - the single line im getting stuck on (so far) is:

Me.AxFlashMovie.OcxState = CType(resources.GetObject("AxFlashMovie.OcxState"), System.Windows.Forms.AxHost.State)

Which causes an error when i use it in a function: 'GetObject' is not a member of 'Resources'.
Even though I'm copying it directly from the managed code section. I can't find any description of how to get around this.

I hoping for a way to get around the getobject issue so i can create and destroy the instance or any other reasonable and dynamic way to get around the key.listener bug.

thanks,

John
0
Comment
Question by:jobrienct
  • 4
  • 4
8 Comments
 
LVL 11

Expert Comment

by:pratap_r
ID: 16932379
you'll have to load the corresponding DLL first into the App domain before you can instantiate it.

Psuedo code:
Assembly asm = Assembly.LoadFromFile(dll file)
Type t = asm.GetType("AxFlashMovie.OcxState");
yourobject = t.InvokeMember(t.Name, BindingFlags.CreateInstance, null, null, null);

What it does is,
1. loads the dll
2. gets a reference to the type (your control in this case)
3. Initialize the class by calling its constructor

Have Fun!
Pratap
0
 
LVL 10

Author Comment

by:jobrienct
ID: 16933522
I cant get vb.net to make heads nor tails of that...

Type Assembly isnt defined.

Does it help if I have a drag and drop version of the control already on the form ? can i instantiate a new one inherting from that?

JOhn
0
 
LVL 11

Expert Comment

by:pratap_r
ID: 16934458
Assembly is defined in System.Reflections

check out MSDN, I'll post some sample code when I get some free time
0
 
LVL 10

Author Comment

by:jobrienct
ID: 16935599
nm. I've worked it out, no need to load the dll since its already referenced - I just dropped the managed code tidbits and set a coupla Friend-ly variables to the shockwave object and then switched between them in this routine which i call when a theme is selected - right now im using 2 variables because it lets me get it out the door and fix a nasty bug, later ill make it more dynamic so that themes described in the xml are supported without modifying the code.

One issue i had that stumped me for a bit was that i was trying to destroy the axControl by setting its variable = nothing. Apparently it's required that I first .dispose() it - it seemed to be ignoring me and leaving the old movie loaded.

Also I'll move the If Not IsNothing() bit down so that i destroy the old one after the new one is visible - to get rid of the flash of white between the 2.


    Sub SwitchMovie(ByVal sTheme As String, ByVal sFilename As String, ByVal sFullscreen As String)
        'MsgBox(sTheme & ":" & sFilename & ":" & sFullscreen)
        My.Settings.LastTheme = sTheme
        My.Settings.LastThemeFilename = sFilename
        My.Settings.LastThemeFullscreen = sFullscreen

        Try
            Select Case sTheme
                Case "Theater"

                    If Not IsNothing(AxFlash2) Then
                        AxFlash2.Hide()
                        AxFlash2.Visible = False
                        AxFlash2.Dispose()
                        AxFlash2 = Nothing
                    End If

                    AxFlash1 = New AxShockwaveFlashObjects.AxShockwaveFlash
                    Me.scMain.Panel2.Controls.Add(Me.AxFlash1)
                    Me.AxFlash1.Dock = System.Windows.Forms.DockStyle.Fill
                    Me.AxFlash1.Enabled = True
                    Me.AxFlash1.Location = New System.Drawing.Point(0, 0)
                    Me.AxFlash1.Name = "AxFlash1"

                    Me.AxFlash1.Size = New System.Drawing.Size(277, 503)
                    Me.AxFlash1.TabIndex = 0

                    Me.AxFlash1.Visible = True
                    Me.AxFlash1.Show()
                    Me.AxFlash1.Movie = sIPGPath & sFilename
                    Me.AxFlash1.Play()

                    Select Case sFullscreen
                        Case "1"
                            Me.tsbtnToggleMenu.Checked = False
                            Me.tsBtnPublish.Checked = False
                            ToggleMenu()
                        Case "0"
                            Me.tsBtnPublish.Checked = False
                            Me.tsbtnToggleMenu.Checked = True
                            ToggleMenu()
                    End Select

                Case "Frame"
                    If Not IsNothing(AxFlash1) Then
                        AxFlash1.Hide()
                        AxFlash1.Visible = False
                        AxFlash1.Dispose()
                        AxFlash1 = Nothing
                    End If

                    AxFlash2 = New AxShockwaveFlashObjects.AxShockwaveFlash
                    Me.scMain.Panel2.Controls.Add(Me.AxFlash2)
                    Me.AxFlash2.Dock = System.Windows.Forms.DockStyle.Fill
                    Me.AxFlash2.Enabled = True
                    Me.AxFlash2.Location = New System.Drawing.Point(0, 0)
                    Me.AxFlash2.Name = "axFlash2"
                    Me.AxFlash2.Size = New System.Drawing.Size(277, 503)
                    Me.AxFlash2.TabIndex = 0

                    Me.AxFlash2.Visible = True
                    Me.AxFlash2.Show()
                    Me.AxFlash2.Movie = sIPGPath & sFilename
                    Me.AxFlash2.Play()

                    Select Case sFullscreen
                        Case "1"
                            Me.tsbtnToggleMenu.Checked = False
                            Me.tsBtnPublish.Checked = False
                            ToggleMenu()

                        Case "0"
                            Me.tsBtnPublish.Checked = False
                            Me.tsbtnToggleMenu.Checked = True
                            ToggleMenu()
                    End Select
            End Select

        Catch ex As Exception
            MsgBox(ex.ToString & ": " & ex.StackTrace)

            'HandleError("SwitchMovie: " & ex.ToString)

        End Try
    End Sub
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 11

Expert Comment

by:pratap_r
ID: 16935721
its better to load your dll dynamically instead of referencing it. Even if you reference it, the way COM works you'll need to release your classes explicitly with calls to ReleaseComObject

here is an example, its not easy, you'll have to release each and every reference explicitly for the object to be fully disposed(in your case for the movie to unload)
http://www.codeproject.com/vb/net/ReleaseExcelObject.asp

The above is for excel, but works the same for any COM object
0
 
LVL 10

Author Comment

by:jobrienct
ID: 16935973
thanks,

I think the excel object is probably much better documented then the flash control - and im not sure where to find a reference to the types of objects i might have to dispose in this way - movies? code snippets? components? sprites? in fact if i could simply dispose of the Key listener directly instead of allowing it to aggregate each time the flash movie is reloaded then I would be out of this pickle wihtout worrying about directly instantiating the com object.

also - if i directly load the flash ocx do i have to worry about interop? do i have to distribute the ocx with my app as well? it might be another version but still compatible that is installed on the client machine. Im expecting the flash control to pre-exist right now (limited audience - and if they have an internet browser they almost certainly have a flash control.)

I'll look around for a reference and ill double check my code for a leak that would indicate im leaving dirty memory behind.

0
 
LVL 11

Accepted Solution

by:
pratap_r earned 500 total points
ID: 16936148
you dont have to deal with teh movies, action scripts etc (those are data as far as you are concerned).

you will however need to release any references to the data objects if you have any. I just see the constructor in the code you have posted, so there isn't much you need to release.

For directly loading the ocx, you cant directly load it, you need to use tblimp first to create the wrappers for it. (This happens behind the scenes when you add a reference to it). And yes, the correct version of flash ocx needs to be present, if its not then its bound to fail. So its better to distribute a latest ocx with your code.
0
 
LVL 10

Author Comment

by:jobrienct
ID: 16936540
I'll take all this under advisement for a future update, thanks.

For my purposes right now (fixing this bug and getting a usable copy back out) an examination of memory usage indicates its a clean dispose() - I switched movies more times then a user would ever consider doing and the usage levels always settled. The good news is that the exercise exposed a bug in my code that i was able to deal with. That and the edumacation was certainly worth the trip - thanks a ton.

John
0

Featured Post

What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

Join & Write a Comment

Suggested Solutions

Since upgrading to Office 2013 or higher installing the Smart Indenter addin will fail. This article will explain how to install it so it will work regardless of the Office version installed.
When we want to run, execute or repeat a statement multiple times, a loop is necessary. This article covers the two types of loops in Python: the while loop and the for loop.
This video teaches viewers about errors in exception handling.
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.

747 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now