MDI Child. Метод Show () вызывает исключение NullReferenceException в платформе - PullRequest
1 голос
/ 24 января 2009

Ниже приведена проблема, я провел большое количество исследований, но до сих пор не смог ее решить. Я счастлив найти решение или обходной путь. Несмотря на то, что фреймворк старый (1.0), на данном этапе я не могу выполнить обновление до 1.1 или более поздней версии (в настоящее время клиент не желает платить за конверсию), и я даже не уверен, что это решит проблему. ... Любая помощь очень ценится:

Платформа : .NET 1.0 VB.NET Приложение Windows Forms MDI, работающее в Windows XP

Проблема : дочернее окно MDI (child1) вызывает метод .Show() другого дочернего окна MDI (child2), и выдается NullReferenceException.

Это происходит только из одной конкретной формы (child1) и только тогда, когда эта дочерняя форма находится в развернутом состоянии, а родительское окно MDI также находится в развернутом состоянии.

Исключение выдается для любой другой дочерней формы, которая открывается из кода в child1 (т. Е. Ошибка не изолирована при открытии формы одного типа).

Исключение выдается только при запуске из отладчика с включенным «Break Into the Debugger Когда выброшено исключение» (хотя эта ошибка позже проявляется, что является реальной проблемой). Такое поведение, по-видимому, объясняется в рамках, поскольку исключение перехватывается, но с ним ничего не делается (см. Приведенный ниже код).

Исключение, похоже, выдается из самой структуры (1.0). Смотрите трассировку стека ниже:

system.windows.forms.dll!System.Windows.Forms.NativeWindow::WindowClassCallback(__int32 hWnd = 461572, __int32 msg = 36, __int32 wparam = 0, __int32 lparam = 1239164) + 0x48 bytes 
    system.windows.forms.dll!System.Windows.Forms.UnsafeNativeMethods::CreateWindowEx(__int32 dwExStyle = 327744, String* lpszClassName = "WindowsForms10.Window.8.app13", String* lpszWindowName = "Diary Entry: ROSIE MILES", __int32 style = 1204748288, __int32 x = -2147483648, __int32 y = -2147483648, __int32 width = 480, __int32 height = 380, __int32 hWndParent = 920114, __int32 hMenu = 0, __int32 hInst = 285212672, System.Object pvParam = null) + 0x3c bytes  
    system.windows.forms.dll!System.Windows.Forms.NativeWindow::CreateHandle(System.Windows.Forms.CreateParams cp = {System.Windows.Forms.CreateParams}) + 0x1d6 bytes  
    system.windows.forms.dll!System.Windows.Forms.Control::CreateHandle() + 0x19a bytes 
    system.windows.forms.dll!System.Windows.Forms.Form::CreateHandle() + 0x12f bytes    
    system.windows.forms.dll!System.Windows.Forms.Control::get_Handle() + 0x2f bytes    
    system.windows.forms.dll!System.Windows.Forms.Form::SetVisibleCore(bool value = true) + 0x1e9 bytes 
    system.windows.forms.dll!System.Windows.Forms.Control::set_Visible(bool value = true) + 0x1e bytes  
    system.windows.forms.dll!System.Windows.Forms.Control::Show() + 0x14 bytes  
>   SpecMed.exe!SpecMed.ScheduleForm.viewScheduleMenuItem_Click(Object sender = {System.Windows.Forms.MenuItem}, System.EventArgs e = {System.EventArgs}) Line 1508 + 0xb bytes Basic
    system.windows.forms.dll!System.Windows.Forms.MenuItem::OnClick(System.EventArgs e = {System.EventArgs}) + 0x8d bytes   
    system.windows.forms.dll!MenuItemData::Execute() + 0x1e bytes   
    system.windows.forms.dll!System.Windows.Forms.Command::Invoke() + 0x4c bytes    
    system.windows.forms.dll!System.Windows.Forms.Command::DispatchID(__int32 id = 299) + 0x2c bytes    
    system.windows.forms.dll!System.Windows.Forms.Control::WmCommand(System.Windows.Forms.Message m = {System.Windows.Forms.Message}) + 0x4a bytes  
    system.windows.forms.dll!System.Windows.Forms.Control::WndProc(System.Windows.Forms.Message m = {System.Windows.Forms.Message}) + 0x1f3 bytes   
    system.windows.forms.dll!ControlNativeWindow::OnMessage(System.Windows.Forms.Message m = {System.Windows.Forms.Message}) + 0x19 bytes   
    system.windows.forms.dll!ControlNativeWindow::WndProc(System.Windows.Forms.Message m = {System.Windows.Forms.Message}) + 0xda bytes 
    system.windows.forms.dll!System.Windows.Forms.NativeWindow::Callback(__int32 hWnd = 6621754, __int32 msg = 273, __int32 wparam = 299, __int32 lparam = 0) + 0x4a bytes  
    system.windows.forms.dll!System.Windows.Forms.Application::ComponentManagerSystem.Windows.Forms.UnsafeNativeMethods+IMsoComponentManager.FPushMessageLoop(__int32 dwComponentID = 1, __int32 reason = -1, __int32 pvLoopData = 0) + 0x2c1 bytes 
    system.windows.forms.dll!ThreadContext::RunMessageLoop(__int32 reason = -1, System.Windows.Forms.ApplicationContext context = {System.Windows.Forms.ApplicationContext}) + 0x1c5 bytes  
    system.windows.forms.dll!System.Windows.Forms.Application::Run(System.Windows.Forms.Form mainForm = {SpecMed.MainForm}) + 0x34 bytes    
    SpecMed.exe!SpecMed.Program.Main() Line 15 + 0x1d bytes Basic

Я отразил этот метод на случайности получить некоторое представление о проблеме. Код для метода WindowClass.Callback ():

public IntPtr Callback(IntPtr hWnd, int msg, IntPtr wparam, IntPtr lparam)
{
    try
    {
        UnsafeNativeMethods.SetWindowLong(hWnd, -4, this.defWindowProc);
        this.targetWindow.AssignHandle(hWnd);
        return this.targetWindow.Callback(hWnd, msg, wparam, lparam);
    }
    catch (Exception)
    {
    }
    return IntPtr.Zero;
}

Как видите, исключение поймано, но с этим ничего не поделано.

Проявление пользовательского интерфейса:

Причина этого исключения, похоже, проявляется позже, с ужасным поведением вызывающей (child1) и вызываемой (child2) дочерних форм.

В пользовательском интерфейсе даже то, что он исключение игнорируется, родительский элемент MDI отображает два дочерних блока управления MDI (то есть два набора блоков минимизации, восстановления и закрытия) и два дочерних значка (см. Снимки экрана). Один блок управления отключен.

альтернативный текст http://www.freeimagehosting.net/uploads/a65a085cd3.jpg альтернативный текст http://www.freeimagehosting.net/uploads/fcbee0eccf.jpg

После закрытия формы child2 child1 перестает отвечать на запросы и перерисовывается.

Исследование:

Выполняя поиск в Интернете, я обнаружил следующие статьи, в которых описываются похожие или почти идентичные проблемы (но на разных платформах), но ни одно из этих решений не помогло.

http://social.msdn.microsoft.com/Forums/en-US/winforms/thread/66cee5a3-c743-4be6-ae63-7416b81a9688/ (Звучит так же, как и те же самые проблемы, но, похоже, решение пока не опубликовано).

http://support.microsoft.com/kb/871045 (Схожие, но не те же проблемы, решение, похоже, не помогает).

http://www.devnewsgroups.net/group/microsoft.public.dotnet.framework.windowsforms/topic39112.aspx: (звучит как одна и та же проблема, но для разных рамок).

В вызывающей дочерней форме (child1) есть сторонние элементы управления (Janus WinForms Suite), которые, как я подозреваю, как-то вызывают проблему. Эти элементы управления являются элементами управления .NET, а не Activex.

Попытки решения

Я пытался вызвать событие child1, которое обрабатывает родительский MDI, а затем родительский MDI открывает child2. Все та же проблема.

Я попытался установить MDI-родитель child2 после того, как child1 вызовет child2.Show (). Все еще без улучшений.

Я пытался установить MDI Parent для child2 до вызова child2.InitialiseComponents (). Без улучшений.

После ввода всего этого я начинаю думать, что проблема не в вызове child2 как таковом, а в том, как обрабатывается child1, когда child2 открывается, максимизируется и, следовательно, отправляет child1 за ним?

Если кто-нибудь может мне помочь или указать мне правильное направление, я, несомненно, буду признателен.

Спасибо

Ответы [ 2 ]

1 голос
/ 24 января 2009

Обходной путь:

Я нашел обходной путь, который не особенно элегантен, но в настоящее время, кажется, работает:

Проверяя, максимизирована ли форма вызова, и сохраняя ее, можно минимизировать (или восстановить) форму вызова до вызова .Show () (предотвращая проблему), а затем установить максимизировать вызываемые формы WindowState. , Установка максимального состояния вызываемых форм имитирует поведение того, что обычно должно происходить (кроме небольшого мерцания с изменением размера форм).

Код:

'-- workaround to prevent UI problem with maximised child form calling another maxmised child form --'
Dim isMaximised As Boolean = (WindowState = FormWindowState.Maximized)

'-- minimise the current form so the problem wont occur when we call the new child Form --'
If isMaximised Then WindowState = FormWindowState.Minimized

Dim form As DiaryEntryForm = DiaryEntryForm.GetForm(scheduleId, Me)
'-- if the calling child was originally maximised, then maximsed the called form to similute what should normally happen --'
If isMaximised Then form.WindowState = FormWindowState.Maximized
form.Show()

Однако я продолжу пытаться найти решение. Любая помощь приветствуется. Спасибо.

0 голосов
/ 29 января 2009

Вы пытаетесь объединить меню как часть показа детей MDI? Если это так, вы можете столкнуться с этой проблемой

http://support.microsoft.com/kb/895579

Исправление будет работать вокруг проблемы, если это то, что вы видите.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...