Как запретить закрытие окна консоли
От: YourLastSong  
Дата: 25.12.11 11:30
Оценка:
Здравствуйте, уважаемые господа.

Существует ли вообще возможность сделать так, чтобы пользователь не мог закр. программу при нажатии на кнопку Close в заголовке окна консоли или выполнять при этом какой-то опр. код (например, сообщение о том, что в данный момент этого делать не стоит)?

Заранее благодарю за возможные ответы.
Re: Как запретить закрытие окна консоли
От: YourLastSong  
Дата: 25.12.11 11:46
Оценка:
Я думал использовать вот такой вариант, но он не работает, к сожалению.

HMENU hm;
HWND ConsoleWnd = FindWindow (NULL, "2_0_1");
hm = GetSystemMenu( ConsoleWnd, FALSE );
DeleteMenu(hm, SC_CLOSE , MF_BYCOMMAND);
DrawMenuBar(ConsoleWnd);
Re[2]: Как запретить закрытие окна консоли
От: CEMb  
Дата: 25.12.11 12:16
Оценка:
Здравствуйте, YourLastSong, Вы писали:

YLS>Я думал использовать вот такой вариант, но он не работает, к сожалению.


YLS>
YLS>HMENU hm;
YLS>HWND ConsoleWnd = FindWindow (NULL, "2_0_1");
YLS>hm = GetSystemMenu( ConsoleWnd, FALSE );
YLS>DeleteMenu(hm, SC_CLOSE , MF_BYCOMMAND);
YLS>DrawMenuBar(ConsoleWnd);
YLS>


А может всё окно задизаблить?
Re: Как запретить закрытие окна консоли
От: irbis3003  
Дата: 25.12.11 12:19
Оценка: -1
Здравствуйте, YourLastSong, Вы писали:

YLS>Здравствуйте, уважаемые господа.


YLS>Существует ли вообще возможность сделать так, чтобы пользователь не мог закр. программу при нажатии на кнопку Close в заголовке окна консоли или выполнять при этом какой-то опр. код (например, сообщение о том, что в данный момент этого делать не стоит)?


YLS>Заранее благодарю за возможные ответы.


в делфях на событие формы CloseQuery ставишь CanClose в значение false.
Окно не закроется.
Re: Как запретить закрытие окна консоли
От: ononim  
Дата: 25.12.11 12:32
Оценка: +2
SetConsoleCtrlHandler?
Как много веселых ребят, и все делают велосипед...
Re[2]: Как запретить закрытие окна консоли
От: irbis3003  
Дата: 25.12.11 12:37
Оценка:
Здравствуйте, irbis3003, Вы писали:

I>Здравствуйте, YourLastSong, Вы писали:


YLS>>Здравствуйте, уважаемые господа.


YLS>>Существует ли вообще возможность сделать так, чтобы пользователь не мог закр. программу при нажатии на кнопку Close в заголовке окна консоли или выполнять при этом какой-то опр. код (например, сообщение о том, что в данный момент этого делать не стоит)?


YLS>>Заранее благодарю за возможные ответы.


I>в делфях на событие формы CloseQuery ставишь CanClose в значение false.

I>Окно не закроется.

а, блин, не форма, консоль..
Re: Как запретить закрытие окна консоли
От: rsdn_gurin  
Дата: 25.12.11 12:40
Оценка:
Здравствуйте, YourLastSong, Вы писали:

YLS>Здравствуйте, уважаемые господа.


YLS>Существует ли вообще возможность сделать так, чтобы пользователь не мог закр. программу при нажатии на кнопку Close в заголовке окна консоли или выполнять при этом какой-то опр. код (например, сообщение о том, что в данный момент этого делать не стоит)?


YLS>Заранее благодарю за возможные ответы.


В С# это можно сделать следующим кодом. В C, C++ это сделать
еще проще, так как в коде используется только WinAPI

  public static class NativeMethods
  {
    [DllImport("user32.dll")]
    static extern IntPtr GetSystemMenu(IntPtr hWnd, [MarshalAs(UnmanagedType.Bool)] bool bRevert);
    [DllImport("user32.dll")]
    static extern int GetMenuItemCount(IntPtr hMenu);
    [DllImport("user32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    static extern bool DrawMenuBar(IntPtr hWnd);
    [DllImport("user32.dll")]
    [return : MarshalAs(UnmanagedType.Bool)]
    static extern bool RemoveMenu(IntPtr hMenu, uint uPosition, uint uFlags);

    private const Int32 MF_BYPOSITION = 0x400;
    private const Int32 MF_REMOVE = 0x1000;

    public static void RemoveCloseButton()
    {
      IntPtr hWin = Process.GetCurrentProcess().MainWindowHandle;
      if (hWin != IntPtr.Zero)
      {
        IntPtr hMenu = GetSystemMenu(hWin, false);
        if (hMenu != IntPtr.Zero)
        {
          int n = GetMenuItemCount(hMenu);
          int max = 20;
          while (n > 0 && max > 0)
          {
            RemoveMenu(hMenu, (uint)(n - 1), MF_BYPOSITION | MF_REMOVE);
            n = GetMenuItemCount(hMenu);
            --max;
          }
          DrawMenuBar(hWin);
        }
      }
    }
  }
Re[2]: Как запретить закрытие окна консоли
От: YourLastSong  
Дата: 25.12.11 13:04
Оценка:
Получается, надо сделать так:

void RemoveCloseButton()
{
    HMENU hm;
    HWND ConsoleWnd = FindWindow (NULL, "2_0_1");
    hm = GetSystemMenu (ConsoleWnd, false);
    int n = GetMenuItemCount (hm);
    int max = 20;
    while (n > 0 && max > 0)
    {
        RemoveMenu(hm, (unsigned int)(n - 1), MF_BYPOSITION | MF_REMOVE);
        n = GetMenuItemCount(hm);
        --max;
    }
    DrawMenuBar(ConsoleWnd);
}


Верно, да?
Re: Как запретить закрытие окна консоли
От: YourLastSong  
Дата: 25.12.11 13:56
Оценка:
А как лучше всего вернуть данную кнопку обратно?

SetMenu?

EnableMenuItem?
Re: Как запретить закрытие окна консоли
От: YourLastSong  
Дата: 25.12.11 18:58
Оценка:
Что-то у меня не получается.

Кнопка, которая была удалена при помощи DeleteMenu, не может быть восстановлена при помощи функции EnableMenuItem, что ли?
Re: Как запретить закрытие окна консоли
От: Centaur Россия  
Дата: 26.12.11 04:04
Оценка: +2
Здравствуйте, YourLastSong, Вы писали:

YLS>Существует ли вообще возможность сделать так, чтобы пользователь не мог закр. программу при нажатии на кнопку Close в заголовке окна консоли или выполнять при этом какой-то опр. код (например, сообщение о том, что в данный момент этого делать не стоит)?


То, что вы хотите, нельзя делать по морально-этическим принципам.
Re[2]: Как запретить закрытие окна консоли
От: Tujh Голландия  
Дата: 26.12.11 12:06
Оценка: +1
Здравствуйте, YourLastSong, Вы писали:
YLS>А как лучше всего вернуть данную кнопку обратно?
YLS>SetMenu?
YLS>EnableMenuItem?
Вам уже ответили правильным посылом.
SetConsoleCtrlHandler
Не нужно удалять кнопку, достаточно обработать её нажатие. А то в консоли еще и Ctrl+C/Ctrl+Break есть, которые могут закрыть приложение без нажатия на крестик.
Re[3]: Как запретить закрытие окна консоли
От: YourLastSong  
Дата: 26.12.11 17:32
Оценка:
T>Вам уже ответили правильным посылом

При необходимости в основном потоке программы создаю новый поток:

_beginthread (thread, 0, NULL);


Функция потока выглядит след. образом:

HANDLE hStopProgram_Command;
HANDLE hProgram_Stopped;

BOOL WINAPI ConsoleHandler (DWORD CEvent)
{
    switch (CEvent)
    {
        case CTRL_C_EVENT:
            MessageBox (0, "ctrl+c", "Stopping", 0);
            break;
        case CTRL_BREAK_EVENT:
            MessageBox (0, "ctrl+break", "Stopping", 0);
            break;
        case CTRL_CLOSE_EVENT:
            MessageBox (0, "exit", "Stopping", 0);
            break;
        case CTRL_LOGOFF_EVENT:
            MessageBox (0, "logoff", "Stopping", 0);
            break;
        case CTRL_SHUTDOWN_EVENT:
            MessageBox (0, "shutdown", "Stopping", 0);
        break;
    }
    SetEvent (hStopProgram_Command);
    WaitForSingleObject (hProgram_Stopped, INFINITE);
    return TRUE;
}

void thread (void *args)
{
    DWORD dRes;
    hStopProgram_Command = CreateEvent (NULL, TRUE, FALSE, NULL);
    hProgram_Stopped = CreateEvent (NULL, TRUE, FALSE, NULL);
  
    SetProcessShutdownParameters (0x4FF, SHUTDOWN_NORETRY);
  
    if (SetConsoleCtrlHandler ((PHANDLER_ROUTINE)ConsoleHandler,TRUE) == FALSE)
    {
        dRes = GetLastError ();
        printf ("(MAIN): Unable to install handler! (err = %i)\n", dRes);
        return;
    }
    while (true)
    {
        dRes = WaitForSingleObject (hStopProgram_Command, INFINITE);
        if (dRes != WAIT_ABANDONED)
            break;
    }
    SetEvent (hProgram_Stopped);
}


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

Можно ли это обойти?
Re[2]: Как запретить закрытие окна консоли
От: GarryIV  
Дата: 26.12.11 17:41
Оценка:
Здравствуйте, Centaur, Вы писали:

YLS>>Существует ли вообще возможность сделать так, чтобы пользователь не мог закр. программу при нажатии на кнопку Close в заголовке окна консоли или выполнять при этом какой-то опр. код (например, сообщение о том, что в данный момент этого делать не стоит)?


C>То, что вы хотите, нельзя делать по морально-этическим принципам.


Если юзер важнее программы то нельзя, а если наоборот то можно.
WBR, Igor Evgrafov
Re[3]: Как запретить закрытие окна консоли
От: YourLastSong  
Дата: 26.12.11 17:56
Оценка:
GIV>Если юзер важнее программы то нельзя, а если наоборот то можно

Каким образом?

Просто если в опр. момент прервать работу программы, то при следующем её откр. данные будут совершенно не те, что хотелось бы, вот я и хочу уточнять у пользователя, хочет ли он всё же выйти или нет.
Re[4]: Как запретить закрытие окна консоли
От: GarryIV  
Дата: 26.12.11 22:54
Оценка:
Здравствуйте, YourLastSong, Вы писали:

GIV>>Если юзер важнее программы то нельзя, а если наоборот то можно


YLS>Каким образом?


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


Мы тут о морали а ты про данные какие-то.
WBR, Igor Evgrafov
Re[4]: Как запретить закрытие окна консоли
От: Centaur Россия  
Дата: 27.12.11 06:26
Оценка:
Здравствуйте, YourLastSong, Вы писали:

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


Значит, нужно программу организовать так, чтобы её аварийное завершение не портило данные пользователя. Потому что, если вы переспросите пользователя, хочет ли он выйти, он скажет «да, б#@, вы что, меня за идиота держите?». А если вы отберёте у пользователя кнопку закрытия, он вытащит из кармана Task Manager.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.