Вот проблема, с которой я столкнулся:
Мне нужно переключить курсор на (скажем)
IDC_WAIT
, пока я не закончу выполнение каких-либо действий.SetCursor
действует только до движения мыши.WM_SETCURSOR
действует только после перемещения мыши.
Вы могли подумать, что я мог бы просто сделать оба из вышеперечисленного, одновременно вызывая SetCursor
и изменяя поведение WM_SETCURSOR
, так что я заставляю курсор менять до некоторого момента в будущем.
Но я не могу просто так сделать. Почему? Поскольку SetCursor
применяется ко всему приложению, случайное окно не знает (да и не должно) знать правильный курсор во всем приложении. Чтобы отправить WM_SETCURSOR
окну, которое на самом деле находится под курсором, необходимо выполнить соответствующие проверки попадания, и неясно, как это сделать правильно.
Как правильно переключать курсоры и обратно в Win32? Каждый пример, который я вижу, тривиален и игнорирует эти проблемы.
SetCursor
, чтобы изменить ее во всем приложении. Ничто здесь не останавливает цикл сообщений - это фоновая операция в другом потоке, который запускается / останавливается основным потоком, - но как люди заставляют это работать? - person user541686   schedule 24.02.2021SetCursor
. он обеспечивает немедленную обратную связь. Если пользователь наводит указатель мыши на что-то, что не отключено, курсор снова возвращается в нормальное состояние. Пользователь привык к тому, что курсор меняется при его перемещении, поэтому я не вижу в этом проблемы. - person Jonathan Potter   schedule 24.02.2021WM_SETCURSOR
для всего, что находится под курсором, а затем он определит курсор. - person user541686   schedule 24.02.2021WM_SETCURSOR
сообщение окну под курсором. - person Jonathan Potter   schedule 24.02.2021WindowFromPoint
и выполняю проверку попадания, и все это вручную ...); Я пытался ответить на ваш вопрос, почему вы не должны слепо звонитьSetCursor
. - person user541686   schedule 24.02.2021IDC_APPSTARTING
тоже должен измениться наIDC_WAIT
.) И, учитывая, что несколько операций могут завершиться не по порядку, выяснить, к чему вернуться, не очевидно. Я пишу для этого код, и хотя у меня что-то есть, оно по своей сути нетривиально, склонно к гонкам и неполно, и кажется, чтоWM_SETCURSOR
не обрабатывается последовательно. - person user541686   schedule 24.02.2021WM_SETCURSOR
сообщениях (и вы успешно реализовали это), но если вы когда-нибудь захотите установить курсор внеWM_SETCURSOR
, вы не знаете, каким должен быть курсор на самом деле, потому что теперь у вас нет такого же контроля, как у того, где сейчас находится мышь? - person dialer   schedule 24.02.2021WM_SETCURSOR
вручную, но он работает нестабильно, и я все еще пытаюсь отладить, связана ли ошибка с этим или нет. - person user541686   schedule 24.02.2021WM_SETCURSOR
сообщений. Они, вероятно, никогда не звонятSetCursor
за пределамиWM_SETCURSOR
. Конечный пользователь заметит это, только если будет пристально смотреть на курсор, не перемещая его. API тоже не может сильно помочь, так как не знает, насколько сложным вы решили быть в вашем случае. - person dialer   schedule 24.02.2021WM_SETCURSOR
сначала отправляется самому внутреннему элементу управления. Если этот элемент управления не имеет твердого мнения о том, каким должен быть курсор, он может запросить у своего родителя выбор с более низким приоритетом (фактически, это то, что делаетDefWindowProc
).GetCursorPos
+WindowFromPoint
+ ОтправкаWM_SETCURSOR
всякий раз, когда вы считаете, что состояние курсора могло измениться, должно позаботиться обо всем остальном. Если это у вас глючит, то, может быть, это другой вопрос. - person dialer   schedule 25.02.2021GetCapture
). - person dialer   schedule 25.02.2021WM_SETCURSOR
, но на самом деле все не так просто. Порядок, а такжеSendMessage
по сравнению сSendMessageCallback
имеет значение. Я все это открываю прямо сейчас. - person user541686   schedule 25.02.2021WM_SETCURSOR
и (быстро) уметь определять, какие курсор должен быть. Код, который там находится, не имеет абсолютно ничего общего с winapi или какими-либо предполагаемыми сложностями. Это может быть простоif (data->Prio1TaskRunning) SetCursor(A); else if (data->Prio2TaskRunning) SetCursor(B);
. (продолжение ...) - person dialer   schedule 25.02.2021