Stop focus / activation looping from MDI child to MDI form.

  • Thread starter Thread starter HotIndigo
  • Start date Start date
H

HotIndigo

Guest
I am developing an application (in Visual Basic) that consists of a MDI form (frm_Main) hosting a number of forms, one of which contains panels that display an Excel worksheet. Each panel can only be displayed one at a time, with the others being hidden. This works well but I cannot focus on any worksheet cell to get mouse or keyboard input - cell entries can only be made programmatically(!). When I paused the debugger I found that, when single stepping, the program looped through the following sequence:

Private Sub mdl_Reports_GotFocus(ByVal sender As Object,
ByVal e As System.EventArgs) _
Handles Me.GotFocus
End Sub ' ** This code is in mdl_Reports **

Private Sub frm_Main_Activated(ByVal sender As Object,
ByVal e As System.EventArgs) _
Handles Me.Activated
End Sub ' ** This code is in mdl_Main **

Private Sub mdl_Reports_LostFocus(ByVal sender As Object,
ByVal e As System.EventArgs) _
Handles Me.LostFocus
End Sub ' ** This code is in mdl_Reports **

This is the essential code I am using (I have removed unrelated code):

Public Class frm_Main
Inherits Form
End Class

Public Class mdl_Reports
Inherits Form

Private Sub mdl_Reports_Load(ByVal sender As System.Object,
ByVal e As System.EventArgs) _
Handles MyBase.Load
Me.MdiParent = frm_Main
End Sub

Private Sub mnu_NewModel_Click(sender As Object,
e As EventArgs) _
Handles mnu_NewModel.Click
Dim Workbooks As Workbooks

oExcel = qExcel.Run_Excel()
ExHwnd = CType(oExcel.Hwnd, IntPtr)
With oExcel
SetParent(CInt(ExHwnd), CInt(pnl_Excel.Handle))
SendMessage(ExHwnd, WM_SYSCOMMAND, SC_MAXIMIZE, 0)
MoveWindow(ExHwnd, 0, -CtrlOffset, pnl_Excel.Width, pnl_Excel.Height + CtrlOffset, True)
End With
Workbooks = oExcel.Workbooks
Workbooks.Add()
oWB = oExcel.ActiveWorkbook
With oWB
.Activate()
.Title = "Template"
oSheet = CType(.Sheets.Add(), Worksheet)
End With
With oSheet
.Activate()
.Name = rName
.Visible = XlSheetVisibility.xlSheetVisible
If sheet Is Nothing Then
oSheet = DirectCast(oWB.Sheets.Add(After:=oWB.Sheets(oWB.Sheets.Count),
Count:=1,
Type:=XlSheetType.xlWorksheet),
Worksheet)
End If
.Range("A1").Value = "Model Name"
With oExcel
.SendKeys("{DOWN}", True)
.SendKeys("{DOWN}", True)
.SendKeys("^A", True)
End With
' Weirdness here - had to use above code because oExcel.Range("A3").Activate()
' or oExcel.Range("A3").Select() (or both together) did not work!
' Any comments or suggestions?
End With
With oExcel
.Visible = True
.EnableEvents = True
End With
SendMessage(ExHwnd, WM_ACTIVATE, WA_ACTIVE, 0)
End Sub

End Class

Friend Class qExcel
Shared WithEvents oExcel As doExcel = Nothing
Private Shared Running As Boolean = False

Friend Shared Function Run_Excel() As Office.Interop.Excel.Application
Dim rExcel = New Office.Interop.Excel.Application
oExcel = New doExcel(rExcel)
Running = True
ExcelRunning = True
Return rExcel
End Function

Friend Shared Sub QuitExcel(ByRef rExcel As Office.Interop.Excel.Application)
If Running Then
Try
rExcel.Quit()
rExcel = Nothing
oExcel.Dispose()
oExcel = Nothing
GC.Collect()
Running = False
ExcelRunning = False
Catch ex As Exception
End Try
End If
End Sub

Private Sub mnu_CloseTemplate_Click(sender As Object,
e As EventArgs) _
Handles mnu_CloseTemplate.Click
Call ReleaseWB()
Call qExcel.QuitExcel(oExcel)
End Sub

Private Sub ReleaseWB()

Dim ExcelWorkbooks As Workbooks = Nothing
Dim worksheets As Sheets = Nothing

Try
ExcelWorkbooks = oExcel.Workbooks
Catch ex As Exception
Exit Sub
End Try
For Each WB As Workbook In oExcel.Workbooks
worksheets = WB.Worksheets
For Each ws As Worksheet In worksheets
Try
Marshal.ReleaseComObject(ws)
Catch ex As Exception
End Try
Next
WB.Close(False) 'Don't save
Marshal.ReleaseComObject(WB)
Next
Try
Marshal.ReleaseComObject(worksheets)
worksheets = Nothing
Catch ex As Exception
End Try
Try
ExcelWorkbooks.Close()
Marshal.ReleaseComObject(ExcelWorkbooks)
ExcelWorkbooks = Nothing
Catch ex As Exception
End Try
End Sub

End Class

Friend Class doExcel
Implements IDisposable

Public Sub New(ByRef oExcel As Office.Interop.Excel.Application)
oExcel = New Office.Interop.Excel.Application
End Sub

Public Overloads Sub Dispose() Implements IDisposable.Dispose
End Sub

Protected Overrides Sub Finalize()
Dispose()
End Sub

End Class

frm_Main is the MDI container form. mdl_Reports is the child form.

It appears that focus is being constantly taken away from the Excel instance. Any clues as to why this looping is happening and is there a way to stop it so that I can achieve focus on the worksheet cells to enter values either by keyboard or mouse?

HotIndigo.

Continue reading...
 
Back
Top