2009-01-24 4 views
1

Le problème ci-dessous est important, j'ai fait beaucoup de recherches, mais je n'ai pas réussi à le résoudre jusqu'ici. Je suis heureux de trouver une solution ou une solution de contournement. Bien que le framework soit ancien (1.0), je ne suis pas en mesure de passer à 1.1 ou plus tard (le client n'est pas prêt à payer pour la conversion actuellement), et je ne suis même pas sûr que cela résoudrait le problème ... Toute aide est très appréciée:La méthode .Show() de MDI Child soulève NullReferenceException dans le Framework

Plate-forme: .NET 1.0 VB.NET Windows Forms application MDI fonctionnant sous Windows XP

problème: Une fenêtre enfant MDI (child1) appelle la méthode .Show() d'une fenêtre enfant MDI différente (child2) et un NullReferenceException est levé. Cela se produit uniquement à partir d'un formulaire particulier (enfant1) et uniquement lorsque la forme enfant est dans un état agrandi et que la fenêtre parent MDI est également dans un état agrandi.

L'exception est levée pour tout autre formulaire enfant ouvert à partir du code dans child1 (c'est-à-dire que l'erreur n'est pas isolée pour l'ouverture d'un type de formulaire). L'exception n'est levée que lors de l'exécution à partir du débogueur avec «Break In the Debugger lorsqu'une exception est lancée» (bien que cette erreur se manifeste plus tard, sur le vrai problème). Ce comportement semble être expliqué dans le cadre dans la mesure où une exception est interceptée mais rien n'est fait avec (voir le code reflété ci-dessous).

L'exception semble provenir du cadre (1.0) lui-même. Voir la trace de la pile ci-dessous:

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 

J'ai réfléchi cette méthode sur le hors-chance d'obtenir un aperçu du problème. Le code pour la méthode WindowClass.Callback() est:

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; 
} 

Comme vous pouvez le voir, l'exception est pris, mais rien ne se fait avec elle.

UI manifestation:

La cause de cette exception semble alors se manifester plus tard, avec un comportement terrible de l'appel (child1) et appelé (CHILD2) formulaires enfants. Dans l'interface utilisateur, même si l'exception est ignorée, le parent MDI affiche deux boîtes de contrôle MDI enfant (à savoir deux ensembles de cases de réduction, de restauration et de fermeture) et deux icônes enfants (voir captures d'écran). Une boîte de contrôle est désactivée.

alt text http://www.freeimagehosting.net/uploads/a65a085cd3.jpg alt text http://www.freeimagehosting.net/uploads/fcbee0eccf.jpg

Après la fermeture de la forme child2, child1 devient non réactif et ne parvient pas à repeindre.

recherche:

Recherche sur le Web, j'ai trouvé les articles suivants, qui semblent décrire des problèmes similaires ou presque identiques (mais différents cadres), mais aucune de ces solutions ont aidé.(Cela ressemble exactement aux mêmes problèmes, mais aucune solution ne semble avoir été publiée).

http://support.microsoft.com/kb/871045 (Similaire mais pas les mêmes problèmes, la solution ne semble pas aider).

http://www.devnewsgroups.net/group/microsoft.public.dotnet.framework.windowsforms/topic39112.aspx: (Ressemble au même problème, mais pour un cadre différent).

Le formulaire enfant appelant (child1), a des contrôles tiers (Janus WinForms Suite), qui je pense sont en quelque sorte à l'origine du problème. Ces contrôles sont des contrôles .NET et non Activex.

Tentatives Solutions

J'ai essayé élever un événement sur child1, que les poignées de parent MDI, et le parent MDI ouvre child2. Toujours le même problème.

J'ai essayé de définir le parent MDI de child2, après que child1 ait appelé child2.Show(). Toujours pas d'amélioration.

J'ai essayé de définir le parent MDI de child2 avant l'appel child2.InitialiseComponents(). Pas d'amélioration. Après avoir tapé tout cela, je commence à penser que le problème n'est pas d'appeler child2 en tant que tel, mais plutôt comment child1 est géré quand child2 est ouvert, maximisé et envoie donc child1 derrière lui?

Si quelqu'un peut m'aider, ou pointer en moi la bonne direction, je l'apprécierais.

Merci

Répondre

0

Essayez-vous de fusionner des menus dans le cadre de l'affichage enfant MDI? Si vous pouvez donc exécuter dans ce numéro

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

Le correctif il fonctionnera autour du problème si c'est celui que vous voyez.

+0

Oui, je suis. Je vais jeter un coup d'oeil et revenir bientôt! – Jayden

+0

Le problème semble définitivement être causé par les éléments de menu de fusion. Le correctif auquel vous faites référence est pour .NET Framework 1.1 et 1.1 SP1. J'utilise .NET Framework 1.0. Je n'arrive pas à trouver un problème similaire documenté pour 1.0? – Jayden

1

Solution:

J'ai trouvé une solution de contournement, ce n'est pas particulièrement élégant, mais semble actuellement travailler:

En vérifiant si le formulaire d'appel est maximisée et en stockant ceci, il est alors possible de minimiser (ou de restaurer) le formulaire appelant avant l'appel .Show() (en évitant le problème), puis en définissant les formes appelées WindowState à maximiser. Définir l'état des formulaires appelés sur maximisé émule le comportement de ce qui devrait normalement se produire (à part un peu de scintillement avec le redimensionnement des formulaires).

code:

'-- 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() 

Je vais continuer d'essayer de trouver une solution cependant. Toute aide appréciée. Merci.