Форум программистов, компьютерный форум, киберфорум
C# Windows Forms
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.60/15: Рейтинг темы: голосов - 15, средняя оценка - 4.60
213 / 139 / 8
Регистрация: 18.08.2010
Сообщений: 1,018

Метод Form.ShowDialog() не приостанавливает работу потока

13.12.2012, 19:58. Показов 3105. Ответов 3
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Метод Form.ShowDialog() интересен для меня тем, что при его вызове в коде программа останавливается на этом методе и не идет по строкам, которые ниже метода. То есть, как бы происходит приостанавливание выполнения кода. Но при этом сама программа не подвисает и форма, которая вызвала этот метод, тоже не подвисшая. Значит поток, в котором был вызван этот метод, не приостанавливается. Но тогда почему программа не выполняется, а ждет закрытия ShowDialog() ? Пожалуйста, просветите. Уже давно интересует этот вопрос чисто с любопытной точки зрения. Но вот сегодня возникла задача, когда необходимо реализовать нечно подобное в моем классе (чтобы при вызове метода поток не блокировался, но программа не шла дальше по коду, а останавливалась на методе, ожидая определенного знака от класса). И потому теперь этот вопрос, как самостоятельно сделать подобное, меня интересует вдвойне

P.S. Вот собственно сам класс. Мне нужно, чтобы при вызове метода Show() он не возвращал моментально DialogResult, а делал это только после того, как пользователь щелкнет по контекстном меню.

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
using System;
using System.Windows.Forms;
using System.Drawing;
 
namespace CarModelFactory
{
    class KnownColorsMenu
    {
        private ContextMenuStrip contextMenuStripColor;
        private Color selectedColor;
 
        public KnownColorsMenu()
        {
            this.contextMenuStripColor = new System.Windows.Forms.ContextMenuStrip();//formContainer.components);
            this.contextMenuStripColor.BackColor = System.Drawing.SystemColors.ControlText;
            this.contextMenuStripColor.Name = "contextMenuStripColor";
            this.contextMenuStripColor.ShowImageMargin = false;
            //this.contextMenuStripColor.Size = new System.Drawing.Size(36, 4);
            AddItemsColors();
        }
 
        public Color SelectedColor { get { return selectedColor; } }
 
        private void AddItemsColors()
        {
            foreach (string colorName in Enum.GetNames(typeof(KnownColor)))
            {
                ToolStripMenuItem item = new ToolStripMenuItem(colorName);
                item.BackColor = Color.FromName(colorName);
                item.Click += new EventHandler(item_Click);
                this.contextMenuStripColor.Items.Add(item);
            }
        }
 
        void item_Click(object sender, EventArgs e)
        {
            ToolStripMenuItem item = (ToolStripMenuItem)sender;
            selectedColor = item.BackColor;
        }
 
        public DialogResult Show()
        {
            this.contextMenuStripColor.Show(Cursor.Position);
            //как вот здесь не выходить из метода, но при этом и не приостанаваливать работу потока? (так как это реализовано в методе Form.ShowDialog())
            if (какое_то_условие)//если пользователь не клацнул по контекстном меню, то возвращаем в DialogResult значение Cancel
            {
                return DialogResult.Cancel;
            }
            else//если пользователь клацнул по какому нибудь пункту в контекстном меню, то возвращаем в DialogResult значение OK
            {
                return DialogResult.OK;
            }
        }
    }
}
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
13.12.2012, 19:58
Ответы с готовыми решениями:

Метод Show приостанавливает выполнение макроса
Метод UserForm1.Showприостанавливает выполнение макроса, как этого избежать?

Exception при Form.ShowDialog()
Message: External component has thrown an exception. Description: System.Runtime.InteropServices.SEHException: External component has...

метод showdialog
при нажатии на кнопку Size происходит открытие новой формы private void Size_Click(object sender, EventArgs e) { ...

3
 Аватар для kesean
292 / 291 / 108
Регистрация: 04.09.2010
Сообщений: 638
13.12.2012, 21:13
Попробуйте так:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
        string contextResult = "";
        public DialogResult Show()
        {
            this.contextMenuStripColor.ItemClicked += new ToolStripItemClickedEventHandler(contextMenuStripColor_ItemClicked);
            this.contextMenuStripColor.Closed += new ToolStripDropDownClosedEventHandler(contextMenuStripColor_Closed);
            bool ok = false;
            this.contextMenuStripColor.Show(Cursor.Position);
            while (true)
            {
                if (contextResult != "")
                {
                    if (contextResult == "no_select")
                        break;
                    else
                    {
                        ok = true;
                        break;
                    }
                }
                Application.DoEvents();
            }
            contextResult = "";
            if (!ok)//если пользователь не клацнул по контекстном меню, то возвращаем в DialogResult значение Cancel
            {
                return DialogResult.Cancel;
            }
            else//если пользователь клацнул по какому нибудь пункту в контекстном меню, то возвращаем в DialogResult значение OK
            {
                return DialogResult.OK;
            }
        }
 
        void contextMenuStripColor_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {
            contextResult = e.ClickedItem.Name;
        }
 
        void contextMenuStripColor_Closed(object sender, ToolStripDropDownClosedEventArgs e)
        {
            if (e.CloseReason != ToolStripDropDownCloseReason.ItemClicked)
                contextResult = "no_select";
        }
Хотя это через ж... А почему бы просто не делать выбор через форму, которая имеет метод ShowDialog?
1
Почетный модератор
Эксперт .NET
 Аватар для NickoTin
8726 / 3678 / 404
Регистрация: 14.06.2010
Сообщений: 4,513
Записей в блоге: 9
13.12.2012, 23:35
Tolias28, нужно написать свой обработчик очереди сообщений, тогда выполнение зациклится на нем.

Получится что-то вроде этого:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
    class KnownColorsMenu
    {
        [StructLayout( LayoutKind.Sequential )]
        public struct MSG
        {
            public IntPtr hwnd;
            public int message;
            public IntPtr wParam;
            public IntPtr lParam;
            public int time;
            public int pt_x;
            public int pt_y;
        }
 
        [DllImport( "user32.dll", SetLastError = true, CharSet = CharSet.Unicode )]
        [return: MarshalAs( UnmanagedType.Bool )]
        public static extern bool EnableWindow(
            IntPtr hWnd,
            [MarshalAs( UnmanagedType.Bool )]
            bool bEnable
            );
 
        [DllImport( "user32.dll", SetLastError = true )]
        [return: MarshalAs( UnmanagedType.Bool )]
        static extern bool WaitMessage( );
 
        [DllImport( "user32.dll", SetLastError = true, CharSet = CharSet.Unicode )]
        public static extern bool PeekMessage( [In, Out] ref MSG msg, IntPtr hwnd, int msgMin, int msgMax, int remove );
 
        [DllImport( "user32.dll", SetLastError = true, CharSet = CharSet.Unicode )]
        public static extern bool TranslateMessage( [In, Out] ref MSG msg );
 
        [DllImport( "user32.dll", SetLastError = true, CharSet = CharSet.Unicode )]
        public static extern IntPtr DispatchMessage( [In] ref MSG msg );
 
        [DllImport( "user32.dll", SetLastError = true, CharSet = CharSet.Unicode )]
        [return: MarshalAs( UnmanagedType.Bool )]
        static extern bool IsDialogMessage( IntPtr hDlg, [In] ref MSG lpMsg );
 
        IWin32Window parent;
        bool flag = true;
 
        public void Show( IWin32Window window )
        {
            EnableWindow( window.Handle, false );
            this.contextMenuStripColor.Show( Cursor.Position );
            parent = window;
 
            var msg = new MSG( );
            var hWnd = this.contextMenuStripColor.Handle;
 
            for ( ; flag; WaitMessage( ) )
            {
                while ( PeekMessage( ref msg, IntPtr.Zero, 0, 0, 1 ) )
                {
                    if ( !IsDialogMessage( hWnd, ref msg ) )
                    {
                        Debug.WriteLine( hWnd + " " + msg.hwnd );
                        TranslateMessage( ref msg );
                        DispatchMessage( ref msg );
                    }
                }
            }
        }
 
        private ContextMenuStrip contextMenuStripColor;
        private Color selectedColor;
 
        public KnownColorsMenu()
        {
            this.contextMenuStripColor = new System.Windows.Forms.ContextMenuStrip();//formContainer.components);
            this.contextMenuStripColor.BackColor = System.Drawing.SystemColors.ControlText;
            this.contextMenuStripColor.Name = "contextMenuStripColor";
            this.contextMenuStripColor.ShowImageMargin = false;
 
 
            this.contextMenuStripColor.Closed += ( s, e ) => {
                flag = false;
                EnableWindow( parent.Handle, true );
            };
 
            AddItemsColors();
        }
 
        public Color SelectedColor { get { return selectedColor; } }
 
        private void AddItemsColors()
        {
            foreach (string colorName in Enum.GetNames(typeof(KnownColor)))
            {
                ToolStripMenuItem item = new ToolStripMenuItem(colorName);
                item.BackColor = Color.FromName(colorName);
                item.Click += new EventHandler(item_Click);
                this.contextMenuStripColor.Items.Add(item);
            }
        }
 
        void item_Click(object sender, EventArgs e)
        {
            ToolStripMenuItem item = (ToolStripMenuItem)sender;
            selectedColor = item.BackColor;
        }
    }
Для чтения:
1
213 / 139 / 8
Регистрация: 18.08.2010
Сообщений: 1,018
17.12.2012, 18:37  [ТС]
Спасибо за просветление! Тема интересная. Узнал для себя больше о WinAPI, чем знал до этого


kesean и SSTREGG, ваши оба примера отлично работают, только в примере от kesean я обнаружил один недостаток: во все время открытого контекстного меню идет активная нагрузка на процессор, что не очень хорошо. Ну это и понятно, ведь в цикле без конца идет проверка на то, был ли выбран элемент контекстного меню
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
17.12.2012, 18:37
Помогаю со студенческими работами здесь

Устаревший метод showDialog() в DatePickerDialog
Я изучаю только андроид и у меня возникла проблема. Мой eclipse показывает что метод showDialog() устарел и не хочет запускать программу в...

Исключение "Невозможно получить доступ к управлению Form1" при использовании ShowDialog с другого потока!
Суть в том, что есть у меня класс типу своего MessageBox, в нем есть статический метод Show(), в котором создается объект этого класса и...

Многопоточность: вызвать метод главного потока из второстепенного потока
Здравствуйте. Эта тема всеми избита, знаю. Но у меня очень ограничено время, поэтому рискую и пишу вопрос тут: Пишу приложение...

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

Вызывть метод одного потока из другого потока
Здравствуйте, подскажите пожалуйста, как можно реализовать такую штуку : есть один поток(1), который вызывает метод у обьекта, этот...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
4
Ответ Создать тему
Новые блоги и статьи
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Символьное дифференцирование
igorrr37 13.02.2026
/ * Программа принимает математическое выражение в виде строки и выдаёт его производную в виде строки и вычисляет значение производной при заданном х Логарифм записывается как: (x-2)log(x^2+2) -. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru