简体   繁体   English

WndProc中的Form.ShowDialog()之后出现“参数计数不匹配”的情况

[英]“Parameter Count Mismatch” After Form.ShowDialog() Occuring in WndProc override

I've taken someone's open source for a Metro Forms implementation in older versions of Windows; 我已经为旧版本的Windows中的Metro Forms实现获取了某人的开源代码; one that I intend to re-write in the future, but I would like to get 'working' at the moment. 我打算在将来重新编写的那一本书,但目前我想开始工作。

** Edit ** :: I've reinstated a base class of System.Windows.Forms in this context and am still yielding the same result. **编辑** ::在这种情况下,我恢复了System.Windows.Forms的基类,并且仍然产生相同的结果。

Right now I am encountering a Parameter Count Mismatch exception in the WndProc method that has been overridden in said MetroFramework ( Original by theilj / 'Extended' (In-Use)( With some corrections ) by viperneo ) 现在我遇到一个Parameter Count Mismatch的异常WndProc已在被覆盖的方法说MetroFramework原件theilj / “扩展”(使用中)(对于一些勘误的内容)viperneo

I am likely to consult with either or both of these gentlemen in regard to the issue but I figured opening a question with the details might yield faster results. 对于这个问题,我可能会与这两个先生中的一个或两个进行协商,但是我认为打开一个包含细节的问题可能会产生更快的结果。

** Edit ** :: I've removed Form references to the above mentioned projects, and am now only using base forms to generate this application's UI. **编辑** ::我已经删除了对上述项目的窗体引用,现在仅使用基本窗体来生成此应用程序的UI。 I believe my next step is to roll-back User Controls. 我相信我的下一步是回滚用户控件。 I'd rather not. 我宁愿不。

There are a couple of methods involved in this process; 此过程涉及两种方法。 and I have some debugging information to attach; 并且我附有一些调试信息; so here we go. 所以我们开始。

Per 'Wine's documentation ; 根据'葡萄酒的文档 I've found a full list of Windows messages that can be passed to WndProc by default. 我已经找到了默认情况下可以传递到WndProc的Windows消息的完整列表。 It would seem at the moment that my application's WndProc method is receiving messages not listed in this documentation . 目前看来,我的应用程序的WndProc方法正在接收未在本文档中列出的消息。

At the time of the encountered exception, In the thread where the exception is generated, I found the following information: 在遇到异常时,在生成异常的线程中,我发现了以下信息:

Thread: 线:

'Main Thread'

Stack Trace: 堆栈跟踪:

** EDIT ** :: This is the INITIAL stack trace surrounding the exception. **编辑** ::这是围绕异常的INITIAL堆栈跟踪。 Following it is an updated stack trace without the MetroForm implementation. 接下来是没有MetroForm实现的更新的堆栈跟踪。

at System.Reflection.RuntimeMethodInfo.UnsafeInvoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Delegate.DynamicInvokeImpl(Object[] args)
at System.Windows.Forms.Control.InvokeMarshaledCallbackDo(ThreadMethodEntry tme)
at System.Windows.Forms.Control.InvokeMarshaledCallbackHelper(Object obj)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Windows.Forms.Control.InvokeMarshaledCallback(ThreadMethodEntry tme)
at System.Windows.Forms.Control.InvokeMarshaledCallbacks()
at System.Windows.Forms.Control.WndProc(Message& m)
at MetroFramework.Controls.MetroUserControlBase.WndProc(Message& m) in f:\Users\DigitalJedi\Documents\Development\Projects\C#\Supporting Projects\MetroFramework-master\MetroFramework\Controls\MetroControlBase.cs:line 4129

** EDIT ** :: Updated Stack Trace ( Does not appear to differ ): **编辑** ::更新的堆栈跟踪(看起来没有不同):

at System.Reflection.RuntimeMethodInfo.UnsafeInvoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Delegate.DynamicInvokeImpl(Object[] args)
at System.Windows.Forms.Control.InvokeMarshaledCallbackDo(ThreadMethodEntry tme)
at System.Windows.Forms.Control.InvokeMarshaledCallbackHelper(Object obj)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Windows.Forms.Control.InvokeMarshaledCallback(ThreadMethodEntry tme)
at System.Windows.Forms.Control.InvokeMarshaledCallbacks()
at System.Windows.Forms.Control.WndProc(Message& m)
at MetroFramework.Controls.MetroUserControlBase.WndProc(Message& m) in f:\Users\DigitalJedi\Documents\Development\Projects\C#\Supporting Projects\MetroFramework-master\MetroFramework\Controls\MetroControlBase.cs:line 4143

Inside the WndProc Override: 在WndProc替代中:

public class MetroUserControlBase : UserControl, IMetroContainerControl, IMetroControl, IMetroStyledComponent
{
    protected override void WndProc(ref Message m)
    {
        try
        {
            if (DesignMode)
            {
                base.WndProc(ref m);
                return;
            }

            switch (m.Msg)
            {
                //case 0xC2BA:
                    //return;;

                //case WinApi.Messages.WM_CTLCOLORBTN:
                //Debug.WriteLine("WM_CTLCOLORBTN", GetType().Name);
                //break;
                //case WinApi.Messages.WM_CTLCOLORSTATIC:
                //Debug.WriteLine("WM_CTLCOLORSTATIC", GetType().Name);
                //break;
                case WinApi.Messages.WM_CTLCOLOREDIT:
                    Debug.WriteLine("WM_CTLCOLOREDIT", GetType().Name);
                    break;
                case WinApi.Messages.WM_CTLCOLORDLG:
                    Debug.WriteLine("WM_CTLCOLORDLG ", GetType().Name);
                    break;
                case WinApi.Messages.WM_CTLCOLORLISTBOX:
                    Debug.WriteLine("WM_CTLCOLORLISTBOX", GetType().Name);
                    break;
                case WinApi.Messages.WM_CTLCOLORSCROLLBAR:
                    Debug.WriteLine("WM_CTLCOLORSCROLLBAR ", GetType().Name);
                    break;
            }
            // Line 4143
            base.WndProc(ref m);
        }
        catch( Exception e )
        {

        }
    }
}

You'll note that I've commented out the first case statement in the above code; 您会注意到,我已经注释掉了上面代码中的第一个case语句; case 0xC2BA - which is the Msg I receive before this window crashes. case 0xC2BA这是此窗口崩溃之前我收到的消息。 After some time scouring the internet for this code, in either its decimal or hex representation, I've found no indication that this is a normal message; 经过一段时间在互联网上搜索该代码(以十进制或十六进制表示)后,我发现没有迹象表明这是正常消息。 However, I've also not managed to find it defined anywhere in the source code to the project I have inherited from. 但是,我也没有设法在我继承的项目的源代码中的任何地方找到它。

I've taken this a step further up the chain to examine what element of my code is forcing this code to be produced, and apparently, it's coming from the ShowDialog method that I've invoked on the controls parent form. 我已将这一步骤向上了一步,以检查代码的哪些元素强制生成此代码,显然,它来自我在控件父窗体上调用的ShowDialog方法。

I implement the ShowDialog method as such, and I have overriden this ShowDialog method in my own form for the sake of debugging - it has yielded little information: 我这样实现了ShowDialog方法,为了调试起见,我以自己的形式覆盖了此ShowDialog方法-它产生的信息很少:

public partial class BaseProductionDialog : Provectusoft.Forms.MetroForm
{
    protected void PromptAuthentication()
    {
        if (this.DesignMode)
            return;
        else if (this.AuthenticationDialog.Visible)
            throw new Exception("The Media Minutes Live Captioning Production Client Authentication Dialog cannot be shown as it is already visible.");
        else
        {
            // This occurs but never concludes
            DialogResult Result = this.AuthenticationDialog.ShowDialog(this);

            if (Result == System.Windows.Forms.DialogResult.Yes)
            {
                this.BringToFront();

                this.Focus();

                return;
            }
            else
            {
                if (!this.IsAuthenticated)
                {
                    MessageBox.Show("There seems to have been an issue in your authentication. Please try again.");

                    this.PromptAuthentication();

                    return;
                }
                else
                {
                    return;
                }
            }
        }
    }

    public DialogResult ShowDialog(System.Windows.Forms.Form ParentForm)
    {
        if (this.IsAuthenticated)
            return DialogResult.Yes;
        else if( this.InvokeRequired )
            // This never occurs
            return (DialogResult) this.Invoke(new Action(delegate { this.ShowDialog(ParentForm); }));
        else
        {
            // This occurs but never concludes
            DialogResult Result = base.ShowDialog(ParentForm);

            if (this.IsAuthenticated)
                return DialogResult.Yes;
            else
                return DialogResult.No;
        }
    }
}

For the sake of being thorough; 为了彻底; at the time of the exception, the Message instance received from the parent process is as follows: 在发生异常时,从父进程收到的Message实例如下:

Msg = 0xC2BA ( 49850 )
HWnd = 0x1403f2 ( 1311730 )
wparam = 0x0
lparam = 0x0
result = 0x0

At the time of encountering the problem, the overriden method's switch statement has been passed over with no entry into any of the case statements ( unless I uncomment the 0xc2ba lines ). 遇到问题时,重写方法的switch语句已传递,没有任何case语句进入(除非我取消注释0xc2ba行)。

Finally, and I think this should already be clear, the exception is a TargetParameterCountException and the message is Parameter count mismatch . 最后,我认为应该已经很清楚了,例外是TargetParameterCountException ,消息是Parameter count mismatch I've also examined the output window for any information, and the most I get is: 我还检查了输出窗口是否有任何信息,而我得到的最多是:

A first chance exception of type 'System.Reflection.TargetParameterCountException occurred in mscorlib.dll'

I might note that a baseline implementation of the controls I am using ( as per the project they are referenced from ) does work. 我可能会注意到,我正在使用的控件的基准实现(根据引用它们的项目)确实有效。 The supporting 'MetroFramework' solution has a 'demo' project that implements at the very least all of the controls that I use in my own implementation. 支持的“ MetroFramework”解决方案有一个“ demo”项目,该项目至少实现了我在自己的实现中使用的所有控件。

An additional note of probable interest - after catching the exception generated in the WndProc method, if I allow program execution to continue, this form and the parent both still operate nominally, and the exception is never encountered again. 可能感兴趣的另一条记录-在捕获WndProc方法中生成的异常之后,如果我允许程序继续执行,则此窗体和父级都仍按名义运行,并且永远不会再遇到该异常。

Hope someone has some insight, I'm pulling my hair out. 希望有人能提供一些见识,我正在拔头发。 Cheers gentlemen. 先生们,干杯。

The invocation that is generating the error produced above occurs in a thread other than the one in which the exception is generated; 产生上面产生的错误的调用发生在一个线程中,而不是产生异常的线程。 regardless of the accurate call stack that was posted. 不管发布的准确呼叫堆栈如何。

To determine what thread is generating this issue, it is necessary to examine the entirety of all running threads at the time of the exception, and determine whether or not any of those threads were invoking any methods on the control in question; 为了确定哪个线程正在产生此问题,有必要在发生异常时检查所有正在运行的线程的整体,并确定这些线程中是否有任何一个正在调用该控件上的任何方法。 as was the case in this circumstance. 就像在这种情况下一样。

To create a clear answer to this question I will further expand on this answer at a 'better' time ( likely this evening ). 为了给这个问题提供一个明确的答案,我将在一个“更好”的时间(可能是今晚)进一步扩展这个答案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM