Как я могу запретить моему приложению получать определенное «сообщение» ?

ВОЗМОЖНОЕ РЕШЕНИЕ НАЙДЕНО!

Я считаю, что нашел решение! Я буду продолжать тестирование, чтобы убедиться, что он действительно работает, но я надеюсь :) Я подробно описал, как я нашел решение, в ИЗМЕНИТЬ ТРИ вопроса!

Для тех, кто желает узнать полную предысторию моей проблемы и то, что я вроде как попробовал в результате ввода этого вопроса, см. Здесь: http://pastebin.com/nTrEAkVj

Я буду редактировать его часто (> 3 раз в день в большинство рабочих дней) по мере продвижения своего исследования и ситуации, поэтому продолжайте проверять, если вы заинтересованы или у вас есть какая-то информация или знания о моей проблеме :)

Краткая справка:

I у меня есть это приложение, которое я сделал, которое может быть разбито, изменив мою заставку или заблокировав мою рабочую станцию, и вообще всякий раз, когда ему будет отправлено сообщение WM_WININICHANGE / WM_SETTINGSCHANGE.

Если я могу постоянно вылетать из моего приложения, меняя заставку, то НЕКОТОРОЙ частью этого является отправка моему приложению НЕКОТОРЫГО типа сообщения (не обязательно сообщения Windows, я имею в виду сообщение в самом общем смысле), которое, в свою очередь, является катастрофически для моего приложения. В связи с этим я пытаюсь найти способ заблокировать любое сообщение, вызывающее мою проблему, от обработки моим приложением. Я понимаю, что это не лучший способ найти решение, поэтому вам не нужно сообщать мне. Посмотрите справочную информацию или спросите, почему, если это вас беспокоит (на то есть веская причина).

Мой вопрос:

есть несколько вещей, о которых любая информация может помочь мне решить мою проблему, помеченных в соответствии с релевантностью (1 - наиболее актуальный, 3 - немного менее полезный):

  1. Я пытаюсь использовать Wndproc ( ), чтобы отфильтровать мое сообщение следующим образом:

     Protected Overrides Sub WndProc (ByRef m As System.Windows.Forms.Message)
    Если CInt (m.Msg)  CInt (26), то
    MyBase.WndProc (м)
    конец, если
    Конец подписки
    

    Однако, согласно Windspector, сообщение WM_WININICHANGE все еще отправляется моему приложению (это имеет смысл), НО оно также возвращается с 0 ... этого не должно происходить, если оно работает должным образом, не должно Ничего не вернуть, не так ли? Информация о том, почему это не работает так, как я ожидал, и о том, как заставить его работать, была бы чрезвычайно полезной!

  2. Я также пробовал использовать фильтры сообщений:

     Открытый класс MyMessageFilter
    Реализует IMessageFilter
    Открытая функция PreFilterMessage (ByRef m As Message) As Boolean реализует IMessageFilter.PreFilterMessage
     'Возвращать true для сообщений, которые вы хотите остановить 

    , а затем добавление к моему методу обработки mybase.load:

    Application.AddMessageFilter (New MyMessageFilter ())

    , однако они, похоже, фильтруют только определенные сообщения, и сообщения, подобные моим, явно не попадают в них. также будет полезна информация о том, невозможно ли использовать какой-либо фильтр для перехвата сообщения WM_ или есть ли другие способы использования фильтров сообщений для достижения моей цели.

  3. ДРУГИМИ способами (кроме этого сообщения Windows с сообщением message.msg = WM_WININICHANGE = 26, которое я нашел) можно было, изменив заставку, отправить ЛЮБОЙ вид сообщения моему приложению? Возможно ли, что другое сообщение о смене заставки также будет фатальным?

Сообщите мне, есть ли ЛЮБАЯ другая информация о моей ситуации, которая может быть полезна, и я сделаю все возможное, чтобы ее получить! Заранее благодарим вас за любую помощь, которую вы можете оказать :)

РЕДАКТИРОВАТЬ:

Это появляется, если я ТОЛЬКО отправляю сообщение WM_CHANGESETTING и заставляю свою программу ждать в течение времени ожидания sendmessagetimeout, с которым я отправил сообщение, тогда моя программа не падает ... похоже, что ОТВЕТ - это то, что вызывает сбой в моем программа ... интересная. Я однозначно близок к своему решению! Я думаю, что еще немного тестирования должно позволить мне выяснить метод, чтобы убедиться, что моя программа не отвечает на сообщение.

ИЗМЕНИТЬ ВТОРОЙ:

Сегодня я обнаружил кое-что ОЧЕНЬ многообещающее: я определил свою функцию wndproc точно так:

Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
    If CInt(m.Msg) <> CInt(26) Then
        MyBase.WndProc(m)
    Else
        MessageBox.Show("Get to work!", "Attention", MessageBoxButtons.OK, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button1, MessageBoxOptions.ServiceNotification)
    End If
End Sub

А затем я попытался запустить свою программу, а затем отправил сообщение WM_SETTINGCHANGE, используя:

SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, IntPtr.Zero, IntPtr.Zero, _
             SendMessageTimeoutFlags.SMTO_ABORTIFHUNG, 5000, IntPtr.Zero)

в другой программе Я сделал. Вы спросите, что случилось? ну, я пробовал это несколько раз, и каждый раз, когда выскакивало окно сообщения (слова, которые я выбрал для него, не имеют значения), я пробовал подождать разное количество времени, прежде чем нажимать ОК, а затем я посмотрел, что случилось с моей основной формой. Ну, в большинстве случаев ничего не изменилось, он все равно вылетал. Но иногда, может быть, 1/5 раза, программа все равно перекодировалась после! Затем, если бы это было так, я бы попытался отправить сообщение еще раз, а затем снова, обычно они терпели неудачу во второй раз во время того же запуска программы, НО иногда снова, примерно еще 1/5 раз казалось, что программа не сбой СНОВА. А потом я дважды пытался его разбить. и это не было ни разу, оно почти всегда тогда никогда не вылетало, независимо от того, сколько раз я пытался отправить сообщение, и независимо от того, как долго я ждал после появления сообщения msgbox.

Я обнаружил, что ожидание около 5 секунд увеличивало мои шансы: моя форма, с помощью которой я вызываю сообщение, все равно будет в фокусе (верхняя панель будет синей) сразу после того, как я нажму кнопку замораживания, а затем появится сообщение вверху, причем верх также синий (я полагаю, в фокусе), оба они все еще «в фокусе» (по крайней мере, синий, ха-ха). Затем примерно через 5 секунд исходная форма теряла фокус, и, увидев это, я пытался нажать ОК.

В настоящее время я думаю, что это небольшое ожидание с последующим подтверждением сообщения в окне иногда позволяет моей программе не аварийно завершить работу, поскольку время ожидания сообщения истекает, поэтому оно не возвращается. Я НЕ знаю, почему возвращаемое сообщение или нет, должно влиять на то, что на самом деле делает моя программа. Это та область, в которой были бы полезны разъяснения :)

ИЗМЕНИТЬ ТРИ:

поэтому я немного больше смотрю в Winspector и обнаружил, что если я жду, пока WM_ERASEBKGND появится в моем окне рабочего стола (это окно, помеченное как «sysListView32 'FolderView'» в Winspector) перед нажатием «ОК» в моем сообщении, тогда программа не выйдет из строя, интересно! Обычно для появления сообщения WM_ERASEBKGND требуется время, близкое к истечению таймаута. это, конечно, после отправки сообщения WM_SETTINGCHANGE из моего самодельного приложения для тестирования.

Итак, после этого я решил еще немного изучить Winspector, потому что, может быть, я смогу найти еще более полезные очереди? Поскольку очевидное ожидание, пока winspector покажет сообщение, отправленное на мой рабочий стол, на самом деле не является исправлением для моей программы.Я обнаружил несколько окон с необычными названиями в моем программном процессе: одно называется «.NET -BroadcastEventWindow.2.0.0.0.378734a.0», а другое - «GDI + Hook Window Class 'GDI + Window'» с подокном под названием «IME» IME по умолчанию '".

Я решаю просмотреть сообщения, поступающие в эти окна, чтобы узнать, получают ли они какие-либо узнаваемые сообщения, такие как WM_SETTINGCHANGE или WM_ERASEBKGND. Оказывается, они не часто получают сообщения: GDI + не получал никаких сообщений, пока я смотрел, я не думаю, но .NET -BroadcastEventWindow получил несколько. Те, которые шли в BroadcastEventWindow, в основном были только WM_appactivate, когда я щелкал окно своего приложения или другое окно после него.

НО ЗАТЕМ ... Я замечаю, что .Net BroadcastEventWindow получает мое сообщение WM_CHANGESETTING !!!! Я смотрю, какие другие сообщения появляются: немного, но я замечаю, что когда приложение вылетает из-за ошибки, появляется сообщение, которое я не узнаю: WM_USER + 7194 (0x201A). Хм, давай посмотрим, что это такое. После того, как я погуглил, я понял, что это похоже на сообщение, определенное приложением / пользователем, а затем, после еще одного поиска связанных с ним проблем, я заметил, что кто-то может использовать фильтр, чтобы отфильтровать это сообщение и решить проблему их ( http://www.pcreview.co.uk/forums/handling-wm_user-messages-t1315625.html ). Мне стоит хотя бы попробовать? поэтому я повторно добавляю фильтр, который пробовал ранее, и меняю значения для фильтрации.Приложение не вылетало !!!!!!!

Затем я пытаюсь разрешить блокировку моей рабочей станции, чтобы увидеть, вызывает ли это ее сбой (потому что раньше это было только с отправкой ей единственного сообщения WM_CHANGESETTING). Оказывается, он все равно вылетел :( НО, я еще раз посмотрел в winspector для этого окна, и, о, да, два НОВЫХ сообщения WM_USER: WM_USER + 7294 (0x207E) и WM_USER + 7189 (0x2015). Поэтому я пытаюсь отфильтровать их тоже...и то при блокировке рабочей станции тоже не вылетает !!! : D

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

Я оставлю вопрос открытым еще немного, пока не убедюсь, что мое решение в порядке и работает хорошо. Спасибо тем из вас, кто дал мне небольшой совет, как действовать на средних этапах моей отладки :)

27
задан Cœur 25 April 2017 в 17:15
поделиться