PRB: Deactivate Event of Non-Modal ActiveX Form Fails to Fire

Last reviewed: November 26, 1997
Article ID: Q170370
The information in this article applies to:
  • Microsoft Visual Basic Professional and Enterprise Editions for Windows, version 5.0

SYMPTOMS

Visual Basic 5.0 allows developers to create in-process ActiveX servers with non-modal forms. However, when a user switches between a non-modal form that is part of the main application and a non-modal form that is part of an in-process ActiveX server, the Deactivate Event of the forms will not fire.

RESOLUTION

You can work around this limitation using any message hooking control or AddressOf. See the REFERENCES section below for more information.

The message you need to hook is WM_ACTIVATE. When you receive WM_ACTIVATE you should check the lower word of the wParam to see if it is equal to WA_INACTIVE. If it is then your form is being deactivated and you can call your deactivation code. The following code snippet shows how your message handler would work:

   Private Const WM_ACTIVATE As Long = &H6
   Private Const WA_INACTIVE As Integer = 0
   Private Const WA_ACTIVE As Integer = 1
   Private Const WA_CLICKACTIVE As Integer = 2

   Function WindowProc(ByVal hw As Long, ByVal uMsg As _
      Long, ByVal wParam As Long, ByVal lParam As Long) As Long
      Select Case Msg
         Case WM_ACTIVATE
            Dim fActive As Integer
            fActive = &HFFFF& And wparam
            Select Case fActive
               Case WA_INACTIVE
                  ' Call deactivation code here
               Case WA_ACTIVE
                  ' Call activation code here
               Case WA_CLICKACTIVE
                  ' Call activation code here
               Case Else
            End Select
         Case Else
      End Select
   End Function

NOTE: If you have third-party controls on your for, they may be subclassing the form as well. If you try to remove your subclass in this scenari, you could crash. In these circumstances, you can just leave your subclass in place.

STATUS

This behavior is by design.

MORE INFORMATION

The Visual Basic 5.0 help topic for the Deactivate event explains the following:

"If an .exe file built by Visual Basic displays a dialog box created by a .dll file also built in Visual Basic, the .exe file's form will get the Deactivate and LostFocus events. This may be unexpected, because you should not get the Deactivate event:

  • If the object is an out-of-process component.
  • If the object isn't written in Visual Basic.
  • In the development environment when calling a DLL built in Visual Basic."

This documentation is a little misleading and should state the following instead:

"You should not get a Deactivate event if the focus is changed to another form that is not part of the VB Project containing the form that currently has the focus."

Steps to Reproduce Behavior

  1. Create a new ActiveX DLL project in Visual Basic 5.0. From the Project Menu, select Add Form.

  2. Add a Label to the new form and set the Caption to the following:

          Non-modal ActiveX form
    

  3. Add the following code to the Form_Deactivate:

          Beep
    

  4. Change the Name of the Form to "frmActiveX" without the quotes.

  5. Change the name of Class1 to "FormClass" without the quotes.

  6. Change the name of the Project to "FormPrb" without the quotes.

  7. Add the following code the class module:

          Public Sub ShowForm()
    
            frmActiveX.Show 0 'show it modeless
          End Sub
    
    

  8. Save the Project, and then choose Make FormPrb.DLL from the File menu.

  9. From the File Menu, select New Project, and then select Standard EXE.

  10. Add a CommandButton to the Form.

  11. Add the following code to the Form:

          Dim oFormPrb As Object
    

          Private Sub Command1_Click()
    
             oFormPrb.showform
          End Sub
    
          Private Sub Form_Deactivate()
             Beep
          End Sub
    
          Private Sub Form_Load()
             Set oFormPrb = CreateObject("FormPrb.formclass")
          End Sub
    
    

  12. Run the Form and then click the CommandButton.

  13. Try moving between the two forms. You will notice that the Beep in the Form_Deactivate does not fire. However, the title bar of forms changes to show which form has the focus.

REFERENCES

For more information, please see the following articles in the Microsoft Knowledge Base:

   ARTICLE-ID: Q170570
   TITLE     : HOWTO: Build a Windows Message Handler with AddressOf in VB5

   ARTICLE-ID: Q168795
   TITLE     : HOWTO: Hook Into a Window's Messages Using AddressOf
Keywords          : vb5all VBKBAutomation VBKBAX VBKBComp VBKBDLL
Version           : 5.0
Platform          : WINDOWS
Issue type        : kbprb


================================================================================


THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY.

Last reviewed: November 26, 1997
© 1998 Microsoft Corporation. All rights reserved. Terms of Use.