Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: отображение messagebox  (Прочитано 13198 раз)
0 Пользователей и 1 Гость смотрят эту тему.
lex452
Интересующийся

ru
Offline Offline

« : 11-02-2011 18:40 » 

подскажите как сделать чтобы  messagebox отображался посередине формы???
Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #1 : 11-02-2011 20:19 » 

lex452, передать в качестве параметра объект родительской формы.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
lex452
Интересующийся

ru
Offline Offline

« Ответ #2 : 12-02-2011 13:32 » 

как именно, есть форма Form1, при нажатии кнопки появляется MessageBox.Show("Тест");
как сделать чтобы оно появилось посередине формы Form1???
Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #3 : 12-02-2011 14:50 » 

lex452, есть такая замечательная вещь, как MSDN. Он может устанавливаться локально, им можно пользоваться через интернет http://msdn.microsoft.com Это справочник.

Все твои вопросы во всех темах (кроме просмотра больших файлов) - это вопросы, ответы на которые есть в этом справочнике.

Как я вчера отвечал на твой вопрос:
1) Я открыл MSDN.
2) Нашёл там описание MessageBox.Show.
3) Нашёл там такой вариант вызова этой функции, который принимает ссылку на родительское окно.
4) Прочитал, что в этом случае окно message box размещается относительного родительского окна, а не относительно рабочего стола.
5) Написал тебе ответ.

Продолжать читать справочник за тебя и потом пересказывать его сюда мне как-то не хочется. Поэтому не плоди темы по мелким стандартно решаемым вопросам, начни пользоваться справочниками.

Более того, когда ты пишешь вызов MessageBox.Show, Visual Studio предлагает подсказки, указывает варианты с разными параметрами. Пользуйся этими подсказками тоже.
« Последнее редактирование: 12-02-2011 14:53 от Dimka » Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
lex452
Интересующийся

ru
Offline Offline

« Ответ #4 : 13-02-2011 10:02 » 

Я читал MSDN, нашел все свойства Вызывал его MessageBox.Show(Form.ActiveForm,"Hello World")  или  MessageBox.Show(this,"Hello World") сообщение выскакивает посреди экрана а не по середине формы
Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #5 : 13-02-2011 14:51 » new

lex452, понятно. Указание родительской формы блокирует форму, но не ориентирует стандартный message box относительно неё.

Если хорошо подумать, то это логично. Бывают и достаточно маленькие формы, расположенные так, что центрированный относительно них message box не влезет в экран.

Поэтому остаётся два пути:

1) Создать собственный модальный dialog box (форму), настроить его, как хочется, и использовать вместо стандартного message box. Тут следует учитывать, что message box бывают оконными, задачными и общесистемными. Первые блокируют родительское окно, но сохраняют работоспособность других окон приложения, работающих в других потоках. Вторые блокируют всю задачу (все её потоки). Третьи блокируют все окна на экране у всех задач. Ещё следует учитывать, что стандартный message box обрабатывает комбинации клавиш "скопировать в буфер обмена" и копирует в буфер обмена выведенный текст, заголовок окна и кнопки (в текстовом виде). Т.е. полная собственная реализация message box не так проста.

2) Параллельно с вызовом message box запустит демона, который найдёт окно открытого message box и пошлёт ему системные сообщения, изменяющие его положение на экране. Этот вариант будет работать только для оконных message box, при котором другие потоки задачи не блокируются. И этот вариант обладает рядом рисков, связанных с нахождением нужного окна. Во-первых, если искать окно по заголовку, таких окон с одинаковым заголовком может оказаться несколько. Во-вторых, пользователь может нажать Enter или Esc достаточно быстро, чтобы message box закрылся сразу же после открытия, и демон, чтобы не зависнуть, должен этот случай предусматривать.


Первый вариант трудоёмкий, но не сложный.

Второй вариант интереснее. На скорую руку собранное решение выглядит примерно так:
Код: (C#)
        class MessageBox
        {
            struct Rect
            {
                public int Left;
                public int Top;
                public int Right;
                public int Bottom;
            }

            [System.Runtime.InteropServices.DllImport("user32.dll")]
            static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

            [System.Runtime.InteropServices.DllImport("user32.dll")]
            static extern int GetWindowRect(IntPtr hWnd, ref Rect lpRect);

            [System.Runtime.InteropServices.DllImport("user32.dll")]
            static extern int SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);

            private class DaemonParameters
            {
                public IntPtr ParentWindow;
                public string MessageBoxTitle;
            }

            private static void MoveMessageBox(IntPtr messageBox, DaemonParameters parameters)
            {
                Rect messageBoxArea = new Rect();
                int foundMessageBox = GetWindowRect(messageBox, ref messageBoxArea);
                if (foundMessageBox != 0)
                {
                    Rect parentWindowArea = new Rect();
                    int foundParentWindow = GetWindowRect(parameters.ParentWindow, ref parentWindowArea);
                    if (foundParentWindow != 0)
                    {
                        int widthDifference = (parentWindowArea.Right - parentWindowArea.Left) - (messageBoxArea.Right - messageBoxArea.Left);
                        int heightDifference = (parentWindowArea.Bottom - parentWindowArea.Top) - (messageBoxArea.Bottom - messageBoxArea.Top);
                        int x = parentWindowArea.Left + widthDifference / 2;
                        int y = parentWindowArea.Top + heightDifference / 2;
                        SetWindowPos(messageBox, IntPtr.Zero, x, y, 0, 0, 0x0001);
                    }
                }
            }

            private static IntPtr FindMessageBox(DaemonParameters parameters)
            {
                return FindWindow(null, parameters.MessageBoxTitle);
            }

            private static void RunDaemon(object param)
            {
                try
                {
                    DaemonParameters parameters = param as DaemonParameters;
                    bool isDone = false;
                    while(!isDone)
                    {
                        System.Threading.Thread.Sleep(1);
                        IntPtr handle = FindMessageBox(parameters);
                        if (handle != IntPtr.Zero)
                        {
                            MoveMessageBox(handle, parameters);
                            isDone = true;
                        }
                    }
                }
                catch(System.Threading.ThreadAbortException)
                {
                }
            }

            private static System.Threading.Thread BeginDaemon(DaemonParameters parameters)
            {
                System.Threading.Thread thread = new System.Threading.Thread(new System.Threading.ParameterizedThreadStart(RunDaemon));
                thread.Start(parameters);
                return thread;
            }

            private static void EndDaemon(System.Threading.Thread thread)
            {
                if (thread.IsAlive)
                {
                    thread.Abort();
                }
            }

            public static System.Windows.Forms.DialogResult Show(System.Windows.Forms.Form parentWindow, string text, string caption)
            {
                DaemonParameters parameters = new DaemonParameters();
                parameters.ParentWindow = parentWindow.Handle;
                parameters.MessageBoxTitle = caption;
                System.Threading.Thread daemonThread = BeginDaemon(parameters);
                System.Windows.Forms.DialogResult result = System.Windows.Forms.MessageBox.Show(parentWindow, text, caption);
                EndDaemon(daemonThread);
                return result;
            }
        }
При этом стандартный класс MessageBox перекрывается собственным. Всякие параметры, связанные с украшательствами, можно добавить самостоятельно. Обязательно нужно указывать заголовок message box, при этом у разных message box должны быть разные заголовки, иначе не будет работать. Но если заменить алгоритм поиска окна, используя вместо FindWindow что-нибудь другое - например через GetWindow или т.п. функции перебирать все окна и потом разными запросами идентифицировать нужное, то и это ограничение можно обойти.
« Последнее редактирование: 13-02-2011 14:54 от Dimka » Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines