<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      Winform ShowDialog如何讓先前Show的窗體可以交互

      背景描述

      最近項(xiàng)目中有一個(gè)需求,全局有一個(gè)共用的窗體,能夠打開不同模塊的報(bào)告,由于需要兼容不同模塊,代碼復(fù)雜,啟動(dòng)速度慢。優(yōu)化方案為將窗體啟動(dòng)時(shí)就創(chuàng)建好,需要查看報(bào)告時(shí),使用此單例彈窗加載不同模塊下的報(bào)告。

      原項(xiàng)目模塊是通過在主框架(Form1)下加載不同Tab頁(yè)實(shí)現(xiàn)的,因此查看報(bào)告彈窗(Form2)是非模態(tài)Show出來。后來業(yè)務(wù)要求新加入一個(gè)模塊,模塊頁(yè)面是通過模態(tài)方式呈現(xiàn)(Form3),即ShowDialog的方式。

      這就有一個(gè)問題,如果用戶在Form1下先打開Form2,然后又需要在Form3下打開Form2,此時(shí)Form2是無法操作的。如下:

      解決思路

      這個(gè)問題和winform設(shè)計(jì)有關(guān),只能去看看winform源代碼是如何區(qū)別處理Show和ShowDialog。

      看看反編譯后的代碼:
      Show:
       1 public void Show(IWin32Window owner)
       2 {
       3     if (owner == this)
       4     {
       5         throw new InvalidOperationException(SR.GetString("OwnsSelfOrOwner", "Show"));
       6     }
       7 
       8     if (base.Visible)
       9     {
      10         throw new InvalidOperationException(SR.GetString("ShowDialogOnVisible", "Show"));
      11     }
      12 
      13     if (!base.Enabled)
      14     {
      15         throw new InvalidOperationException(SR.GetString("ShowDialogOnDisabled", "Show"));
      16     }
      17 
      18     if (!TopLevel)
      19     {
      20         throw new InvalidOperationException(SR.GetString("ShowDialogOnNonTopLevel", "Show"));
      21     }
      22 
      23     if (!SystemInformation.UserInteractive)
      24     {
      25         throw new InvalidOperationException(SR.GetString("CantShowModalOnNonInteractive"));
      26     }
      27 
      28     if (owner != null && ((int)UnsafeNativeMethods.GetWindowLong(new HandleRef(owner, Control.GetSafeHandle(owner)), -20) & 8) == 0 && owner is Control)
      29     {
      30         owner = ((Control)owner).TopLevelControlInternal;
      31     }
      32 
      33     IntPtr activeWindow = UnsafeNativeMethods.GetActiveWindow();
      34     IntPtr intPtr = (owner == null) ? activeWindow : Control.GetSafeHandle(owner);
      35     IntPtr zero = IntPtr.Zero;
      36     base.Properties.SetObject(PropDialogOwner, owner);
      37     Form ownerInternal = OwnerInternal;
      38     if (owner is Form && owner != ownerInternal)
      39     {
      40         Owner = (Form)owner;
      41     }
      42 
      43     if (intPtr != IntPtr.Zero && intPtr != base.Handle)
      44     {
      45         if (UnsafeNativeMethods.GetWindowLong(new HandleRef(owner, intPtr), -8) == base.Handle)
      46         {
      47             throw new ArgumentException(SR.GetString("OwnsSelfOrOwner", "show"), "owner");
      48         }
      49 
      50         zero = UnsafeNativeMethods.GetWindowLong(new HandleRef(this, base.Handle), -8);
      51         UnsafeNativeMethods.SetWindowLong(new HandleRef(this, base.Handle), -8, new HandleRef(owner, intPtr));
      52     }
      53 
      54     base.Visible = true;
      55 }
      View Code

        

      ShowDialog:
        1 public DialogResult ShowDialog(IWin32Window owner)
        2 {
        3     if (owner == this)
        4     {
        5         throw new ArgumentException(SR.GetString("OwnsSelfOrOwner", "showDialog"), "owner");
        6     }
        7 
        8     if (base.Visible)
        9     {
       10         throw new InvalidOperationException(SR.GetString("ShowDialogOnVisible", "showDialog"));
       11     }
       12 
       13     if (!base.Enabled)
       14     {
       15         throw new InvalidOperationException(SR.GetString("ShowDialogOnDisabled", "showDialog"));
       16     }
       17 
       18     if (!TopLevel)
       19     {
       20         throw new InvalidOperationException(SR.GetString("ShowDialogOnNonTopLevel", "showDialog"));
       21     }
       22 
       23     if (Modal)
       24     {
       25         throw new InvalidOperationException(SR.GetString("ShowDialogOnModal", "showDialog"));
       26     }
       27 
       28     if (!SystemInformation.UserInteractive)
       29     {
       30         throw new InvalidOperationException(SR.GetString("CantShowModalOnNonInteractive"));
       31     }
       32 
       33     if (owner != null && ((int)UnsafeNativeMethods.GetWindowLong(new HandleRef(owner, Control.GetSafeHandle(owner)), -20) & 8) == 0 && owner is Control)
       34     {
       35         owner = ((Control)owner).TopLevelControlInternal;
       36     }
       37 
       38     CalledOnLoad = false;
       39     CalledMakeVisible = false;
       40     CloseReason = CloseReason.None;
       41     IntPtr capture = UnsafeNativeMethods.GetCapture();
       42     if (capture != IntPtr.Zero)
       43     {
       44         UnsafeNativeMethods.SendMessage(new HandleRef(null, capture), 31, IntPtr.Zero, IntPtr.Zero);
       45         SafeNativeMethods.ReleaseCapture();
       46     }
       47 
       48     IntPtr intPtr = UnsafeNativeMethods.GetActiveWindow();
       49     IntPtr intPtr2 = (owner == null) ? intPtr : Control.GetSafeHandle(owner);
       50     IntPtr zero = IntPtr.Zero;
       51     base.Properties.SetObject(PropDialogOwner, owner);
       52     Form ownerInternal = OwnerInternal;
       53     if (owner is Form && owner != ownerInternal)
       54     {
       55         Owner = (Form)owner;
       56     }
       57 
       58     try
       59     {
       60         SetState(32, value: true);
       61         dialogResult = DialogResult.None;
       62         CreateControl();
       63         if (intPtr2 != IntPtr.Zero && intPtr2 != base.Handle)
       64         {
       65             if (UnsafeNativeMethods.GetWindowLong(new HandleRef(owner, intPtr2), -8) == base.Handle)
       66             {
       67                 throw new ArgumentException(SR.GetString("OwnsSelfOrOwner", "showDialog"), "owner");
       68             }
       69 
       70             zero = UnsafeNativeMethods.GetWindowLong(new HandleRef(this, base.Handle), -8);
       71             UnsafeNativeMethods.SetWindowLong(new HandleRef(this, base.Handle), -8, new HandleRef(owner, intPtr2));
       72         }
       73 
       74         try
       75         {
       76             if (dialogResult == DialogResult.None)
       77             {
       78                 Application.RunDialog(this);
       79             }
       80         }
       81         finally
       82         {
       83             if (!UnsafeNativeMethods.IsWindow(new HandleRef(null, intPtr)))
       84             {
       85                 intPtr = intPtr2;
       86             }
       87 
       88             if (UnsafeNativeMethods.IsWindow(new HandleRef(null, intPtr)) && SafeNativeMethods.IsWindowVisible(new HandleRef(null, intPtr)))
       89             {
       90                 UnsafeNativeMethods.SetActiveWindow(new HandleRef(null, intPtr));
       91             }
       92             else if (UnsafeNativeMethods.IsWindow(new HandleRef(null, intPtr2)) && SafeNativeMethods.IsWindowVisible(new HandleRef(null, intPtr2)))
       93             {
       94                 UnsafeNativeMethods.SetActiveWindow(new HandleRef(null, intPtr2));
       95             }
       96 
       97             SetVisibleCore(value: false);
       98             if (base.IsHandleCreated)
       99             {
      100                 if (OwnerInternal != null && OwnerInternal.IsMdiContainer)
      101                 {
      102                     OwnerInternal.Invalidate(invalidateChildren: true);
      103                     OwnerInternal.Update();
      104                 }
      105 
      106                 DestroyHandle();
      107             }
      108 
      109             SetState(32, value: false);
      110         }
      111     }
      112     finally
      113     {
      114         Owner = ownerInternal;
      115         base.Properties.SetObject(PropDialogOwner, null);
      116     }
      117 
      118     return DialogResult;
      119 }
      View Code

       

      關(guān)鍵代碼為:
      1 if (dialogResult == DialogResult.None)
      2 {
      3     Application.RunDialog(this);
      4 }

       

      順著找:
      1 internal static void RunDialog(Form form)
      2 {
      3     Application.ThreadContext.FromCurrent().RunMessageLoop(4, new Application.ModalApplicationContext(form));
      4 }

       

      再看看RunMessageLoop:
       1 internal void RunMessageLoop(int reason, ApplicationContext context)
       2 {
       3     IntPtr userCookie = IntPtr.Zero;
       4     if (Application.useVisualStyles)
       5     {
       6         userCookie = UnsafeNativeMethods.ThemingScope.Activate();
       7     }
       8     try
       9     {
      10         this.RunMessageLoopInner(reason, context);
      11     }
      12     finally
      13     {
      14         UnsafeNativeMethods.ThemingScope.Deactivate(userCookie);
      15     }
      16 }

       

       
       
      找到Inner代碼:
        1 private void RunMessageLoopInner(int reason, ApplicationContext context)
        2 {
        3     if (reason == 4 && !SystemInformation.UserInteractive)
        4     {
        5         throw new InvalidOperationException(SR.GetString("CantShowModalOnNonInteractive"));
        6     }
        7     if (reason == -1)
        8     {
        9         this.SetState(8, false);
       10     }
       11     if (Application.ThreadContext.totalMessageLoopCount++ == 0)
       12     {
       13         Application.ThreadContext.baseLoopReason = reason;
       14     }
       15     this.messageLoopCount++;
       16     if (reason == -1)
       17     {
       18         if (this.messageLoopCount != 1)
       19         {
       20             throw new InvalidOperationException(SR.GetString("CantNestMessageLoops"));
       21         }
       22         this.applicationContext = context;
       23         this.applicationContext.ThreadExit += this.OnAppThreadExit;
       24         if (this.applicationContext.MainForm != null)
       25         {
       26             this.applicationContext.MainForm.Visible = true;
       27         }
       28         DpiHelper.InitializeDpiHelperForWinforms();
       29         AccessibilityImprovements.ValidateLevels();
       30     }
       31     Form form = this.currentForm;
       32     if (context != null)
       33     {
       34         this.currentForm = context.MainForm;
       35     }
       36     bool flag = false;
       37     bool flag2 = false;
       38     HandleRef hWnd = new HandleRef(null, IntPtr.Zero);
       39     if (reason == -2)
       40     {
       41         flag2 = true;
       42     }
       43     if (reason == 4 || reason == 5)
       44     {
       45         flag = true;
       46         bool flag3 = this.currentForm != null && this.currentForm.Enabled;
       47         this.BeginModalMessageLoop(context);
       48         hWnd = new HandleRef(null, UnsafeNativeMethods.GetWindowLong(new HandleRef(this.currentForm, this.currentForm.Handle), -8));
       49         if (hWnd.Handle != IntPtr.Zero)
       50         {
       51             if (SafeNativeMethods.IsWindowEnabled(hWnd))
       52             {
       53                 SafeNativeMethods.EnableWindow(hWnd, false);
       54             }
       55             else
       56             {
       57                 hWnd = new HandleRef(null, IntPtr.Zero);
       58             }
       59         }
       60         if (this.currentForm != null && this.currentForm.IsHandleCreated && SafeNativeMethods.IsWindowEnabled(new HandleRef(this.currentForm, this.currentForm.Handle)) != flag3)
       61         {
       62             SafeNativeMethods.EnableWindow(new HandleRef(this.currentForm, this.currentForm.Handle), flag3);
       63         }
       64     }
       65     try
       66     {
       67         if (this.messageLoopCount == 1)
       68         {
       69             WindowsFormsSynchronizationContext.InstallIfNeeded();
       70         }
       71         if (flag && this.currentForm != null)
       72         {
       73             this.currentForm.Visible = true;
       74         }
       75         if ((!flag && !flag2) || this.ComponentManager is Application.ComponentManager)
       76         {
       77             bool flag4 = this.ComponentManager.FPushMessageLoop((IntPtr)this.componentID, reason, 0);
       78         }
       79         else if (reason == 2 || reason == -2)
       80         {
       81             bool flag4 = this.LocalModalMessageLoop(null);
       82         }
       83         else
       84         {
       85             bool flag4 = this.LocalModalMessageLoop(this.currentForm);
       86         }
       87     }
       88     finally
       89     {
       90         if (flag)
       91         {
       92             this.EndModalMessageLoop(context);
       93             if (hWnd.Handle != IntPtr.Zero)
       94             {
       95                 SafeNativeMethods.EnableWindow(hWnd, true);
       96             }
       97         }
       98         this.currentForm = form;
       99         Application.ThreadContext.totalMessageLoopCount--;
      100         this.messageLoopCount--;
      101         if (this.messageLoopCount == 0)
      102         {
      103             WindowsFormsSynchronizationContext.Uninstall(false);
      104         }
      105         if (reason == -1)
      106         {
      107             this.Dispose(true);
      108         }
      109         else if (this.messageLoopCount == 0 && this.componentManager != null)
      110         {
      111             this.RevokeComponent();
      112         }
      113     }
      114 }
      View Code

       

      關(guān)鍵代碼:
       1 if (reason == 4 || reason == 5)
       2 {
       3         flag = true;
       4         bool flag3 = this.currentForm != null && this.currentForm.Enabled;
       5         this.BeginModalMessageLoop(context);
       6         hWnd = new HandleRef(null, UnsafeNativeMethods.GetWindowLong(new HandleRef(this.currentForm, this.currentForm.Handle), -8));
       7         if (hWnd.Handle != IntPtr.Zero)
       8         {
       9             if (SafeNativeMethods.IsWindowEnabled(hWnd))
      10             {
      11                 SafeNativeMethods.EnableWindow(hWnd, false);
      12             }
      13             else
      14             {
      15                 hWnd = new HandleRef(null, IntPtr.Zero);
      16             }
      17         }
      18         if (this.currentForm != null && this.currentForm.IsHandleCreated && SafeNativeMethods.IsWindowEnabled(new HandleRef(this.currentForm, this.currentForm.Handle)) != flag3)
      19         {
      20             SafeNativeMethods.EnableWindow(new HandleRef(this.currentForm, this.currentForm.Handle), flag3);
      21         }
      22 }

       

      這邊的邏輯其實(shí)就是:如果啟用模態(tài)彈窗,則先把所有窗體禁用,然后找到當(dāng)前需要展示的窗體,啟用它。
      知道了原理,我們依葫蘆畫瓢即可:調(diào)用WinApi中的EnableWindow。
      部分示例代碼:
      1 private void btnOpenOldForm_Click(object sender, EventArgs e)
      2 {
      3     OldFrom.Hide();
      4     OldFrom.Show(this);
      5     OldFrom.BringToFront();
      6     var formhandle = OldFrom.Handle;
      7     NativeMethodHelper.EnableWindow(new HandleRef(null, formhandle), true);
      8 }

       

      附上winapi幫助類:
       1 public class NativeMethodHelper
       2 {
       3     [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
       4     public static extern IntPtr SetActiveWindow(HandleRef hWnd);
       5 
       6     [DllImport("user32.dll", CharSet = CharSet.Auto, EntryPoint = "GetWindowLongPtr")]
       7     public static extern IntPtr GetWindowLongPtr64(HandleRef hWnd, int nIndex);
       8 
       9     public static IntPtr SetWindowLong(HandleRef hWnd, int nIndex, HandleRef dwNewLong)
      10     {
      11         if (IntPtr.Size == 4)
      12         {
      13             return NativeMethodHelper.SetWindowLongPtr32(hWnd, nIndex, dwNewLong);
      14         }
      15         return NativeMethodHelper.SetWindowLongPtr64(hWnd, nIndex, dwNewLong);
      16     }
      17     [DllImport("user32.dll", CharSet = CharSet.Auto, EntryPoint = "SetWindowLong")]
      18     public static extern IntPtr SetWindowLongPtr32(HandleRef hWnd, int nIndex, HandleRef dwNewLong);
      19 
      20     [DllImport("user32.dll", CharSet = CharSet.Auto, EntryPoint = "SetWindowLongPtr")]
      21     public static extern IntPtr SetWindowLongPtr64(HandleRef hWnd, int nIndex, HandleRef dwNewLong);
      22 
      23     /// <summary>
      24     /// 啟用窗體
      25     /// </summary>
      26     /// <param name="hWnd"></param>
      27     /// <param name="enable"></param>
      28     /// <returns></returns>
      29     [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
      30     public static extern bool EnableWindow(HandleRef hWnd, bool enable);
      31 }

       

      執(zhí)行效果:

       

      posted @ 2023-07-03 11:21  天命小豬  閱讀(387)  評(píng)論(0)    收藏  舉報(bào)
      主站蜘蛛池模板: 草草浮力地址线路①屁屁影院| 国产精品一区二区三区卡| 婷婷五月综合丁香在线| 亚洲欧美国产精品专区久久| 国产91精品调教在线播放| 影视先锋av资源噜噜| 成人爽A毛片在线视频淮北| 国产精品爽爽久久久久久| 尤物tv国产精品看片在线| 在线精品亚洲区一区二区| 久久亚洲av午夜福利精品一区| 国产成人一区二区不卡| 国产人伦精品一区二区三| 国产成人免费| 精品超清无码视频在线观看| 亚洲 欧美 综合 另类 中字| a级黑人大硬长爽猛出猛进 | 国产区精品福利在线熟女| 人人妻人人澡人人爽欧美一区双| 91中文字幕一区在线| 激情综合网激情五月我去也| 樱花草视频www日本韩国| 无套内射极品少妇chinese| 久久中文字幕av第二页| 国产久免费热视频在线观看| 日韩精品射精管理在线观看| 亚洲国产日韩a在线亚洲| 午夜久久一区二区狠狠干| 国产中文99视频在线观看| 国产成人精品无码专区| 91麻豆视频国产一区二区| 亚洲色一区二区三区四区| 亚洲av产在线精品亚洲第一站| 国产精品久久国产精麻豆| 久久青草国产精品一区| 欧美偷窥清纯综合图区| 日韩精品 在线一区二区| 亚洲区1区3区4区中文字幕码| 欧美老少配性行为| 成人av天堂男人资源站| 五月丁香六月综合缴清无码|