закрытие программы при помощи ctrl-c

178
28 апреля 2018, 18:15

Доброй ночи, форумчане. Такой вопрос: Как в переодичной функции обратного типа(CALLBACK WindProc()) закрывать окно при помощи CTRL+C? Знаю что можно через функцию SetConsoleCtrlHandler, не пойму как ее там вызвать. Буду благодарен за содействие.

Answer 1

У Вас какая-то путаница.

С помощью функции SetConsoleCtrlHandler вы говорите виндам, какую вашу функцию винды должны вызывать когда пользователь нажмёт на консоли (т.е. "в чёрном окне") комбинацию клавиш Ctrl-C. Если вам надо выйти из программы, можно вызвать функцию ExitProcess (если вам хочется выйти побыстрее) или PostQuitMessage (если вы хотите завершить основной цикл, вернуться в WinMain и уже оттуда выйти с помощью return). Если вам надо закрыть окно не выходя из программы, это делается функцией DestroyWindow (если это обычное окно) или EndDialog (если это модальное окно диалога).

"Стандартный метод" завершения программы: закрыть главное окно с помощью CloseWindow или с помощью PostMessage(hwnd, WM_CLOSE, 0, 0), а в процедуре главного окна, в обработчике WM_DESTROY, вызвать PostQuitMessage(0).

Answer 2

Давайте разбираться дальше.

В виндах есть обычные окна и есть консоли (чёрные окна с буквочками, без рисунков). Ctrl-C это сочетание клавиш, предназначенное для закрытия консоли. Обычное окно таким сочетанием клавиш не закрывается. Обычное окно можно закрыть сочетанием клавиш Alt-F4. А сочетание клавиш Ctrl-C в обычных окнах, как правило, используется для того, чтобы копировать текст в буфер обмена.

Такая путаница пошла из-за того, что консоль Windows сделана похожей на консоли DOS и UNIX. В виндах есть куча функций, предназначенных для работы с консолями, и не действующих в обычных окнах. SetConsoleCtrlHandler одна из них.

Если всё-таки хочется, чтобы обычное окно закрывалось по Ctrl-C, нужно обрабатывать это Ctrl-C как любую обычную комбинацию клавиш. Например, вот так:

case WM_KEYDOWN:
    if (wparam == 'C')
    {
        if (GetKeyState(VK_CONTROL) & 0x8000)
        {
            DestroyWindow(hwnd);
            return 0;
        }
    }
    break;

Но есть одна проблема: если в окне есть edit box'ы и текстовый курсор находится в одном из них, то сочетание Ctrl-C будет обработано этим edit box'ом как положено (будет скопирован текст в буфер обмена). Если вы хотите, чтобы сочетание Ctrl-C использовалось не как положено, а для закрытия вашего окна (а это, вообще говоря, неправильный дизайн программы), надо предварительно "искалечить" все edit box'ы в окне с помощью субклассинга (см. SetWindowLongPtr, GWLP_WNDPROC) так, чтобы они не реагировали на Ctrl-C. Альтернативный вариант - перехватывать сообщение WM_KEYDOWN прямо в главном цикле обработки сообщений, чтобы оно вообще не доходило до edit box'ов:

while (GetMessage(&msg, NULL, 0, 0))
{
    if (msg.message == WM_KEYDOWN && msg.wParam == 'C' &&
            (GetKeyState(VK_CONTROL) & 0x8000) != 0)
    {
        ExitProcess(0);
    }
    else
    {
        как обычно
    }
}
READ ALSO
Подключить Opengl 4.3 к qt

Подключить Opengl 4.3 к qt

Как прикрутить Opengl 43 к проекту qt

180
Генерация случайного символа и замена в char array

Генерация случайного символа и замена в char array

Допустим у нас есть некий массив:

171
Баг препроцессора или VisualStudio

Баг препроцессора или VisualStudio

В библиотеке описано несколько классовТак же заданы символы препроцессра, и определен экспортируемый макрос

194