Правила и условия применимости `AttachThreadInput`

#c #c #winapi #visual-c

#c #c #winapi #visual-c

Вопрос:

Это простая модификация исходного кода win32, сгенерированного из базового шаблона:

 if (!InitInstance(hInstance,true)
{
    return false;
}

std::thread{ [hInstance,main_thread= GetCurrentThreadId()] {
    MSG msg{};

    if (!InitInstance(hInstance,true)
    {
        return;
    }

    auto const current_thread{ GetCurrentThreadId() };
    HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_WIN32APP));

    if (!AttachThreadInput(main_thread, current_thread, true))
        return;
    // Main message loop:
    while (GetMessage(amp;msg, nullptr, 0, 0))
    {
        if (!TranslateAccelerator(msg.hwnd, hAccelTable, amp;msg))
        {
            TranslateMessage(amp;msg);
            DispatchMessage(amp;msg);
        }
    }
    AttachThreadInput(main_thread, current_thread, false);
} }.join();
 

Создаются и отображаются два окна. Но очевидно, что сообщения, отправленные в окно, созданное в основном потоке, не обрабатываются. Чего не хватает? Я ничего не смог найти в тонах документов msdn и множестве сообщений на форуме. Все, что я могу найти на форумах, — это множество жалоб SetFocus и модальных диалогов, а это не то, что я ищу.

Заранее благодарю.

Комментарии:

1. Какова цель этого кода? Почему вы пытаетесь запустить два потока пользовательского интерфейса? Почему вы соединяете механизм обработки ввода потоков вместе?

2. AttachThreadInput Редко требуется вызов. Когда это необходимо, вы уже знаете, что он делает. Вы не вызываете его, а затем спрашиваете, что он делает. Поскольку вы здесь, вот ответ: AttachThreadInput — это все равно, что взять два потока и объединить их деньги на совместный банковский счет, где обе стороны должны присутствовать, чтобы снять какие-либо деньги .

3. Сообщения для главного окна не обрабатываются, поскольку основной поток не обрабатывает сообщения. AttachThreadInput называется AttachThreadInput, поскольку он присоединяет состояние ввода. Это не «AttachThreadMessageProcessing».

4. Каким образом и что именно он присоединяет? Мне нужно точно и конкретно понимать, что делает функция; потому что, очевидно, она делает не много вещей, а только одну. Предоставленная ссылка не отвечает на мой вопрос. Что AttachedTreadInput делать? Какие входные данные, как следует из названия, должны быть присоединены? Я хочу, чтобы один поток обрабатывал очереди сообщений для объектов, созданных в разных потоках.

5. Как сказано в названии функции: он синхронизирует ввод. В документах говорится, что «События клавиатуры и мыши, полученные обоими потоками, обрабатываются в том порядке, в котором они были получены». Если пользователь щелкает в одном окне, нажимает клавишу, а затем щелкает в другом окне и нажимает вторую клавишу, то второму окну не будет присвоено событие второго ключа, пока первое окно не завершит обработку события первого ключа. Приложениям редко приходится это делать. Это очень нишевый сценарий. (Это делает приложение менее отзывчивым, поскольку второе окно зависает, если первое окно зависло.)

Ответ №1:

ОК. Мне пришлось вернуться назад и сосредоточиться на точной формулировке первоначального дока. Термин «Ввод» относится к HID. Мое замешательство было вызвано необходимостью наличия очередей сообщений для обоих потоков. Таким образом, в случае ввода разные сообщения (псевдо) одновременно отправляются в оба потока. Оба потока будут наблюдать скрытые события; их восприятие событий будет разным из-за разной последовательности полученных сообщений.

Спасибо всем за подсказки.