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

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

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

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

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

Быстрый Фон:

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

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

Мой вопрос:

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

Я пытаюсь использовать Wndproc () для фильтрации моего сообщения следующим образом:

Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
    If CInt(m.Msg) <> CInt(26) then
        MyBase.WndProc(m)
    end if
End Sub

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

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

Public Class MyMessageFilter
    Implements IMessageFilter
    Public Function PreFilterMessage(ByRef m As Message) As Boolean Implements IMessageFilter.PreFilterMessage
        ' Return true for messages that you want to stop  << someone elses comment       
        Return m.Msg = 26
    End Function
End Class

а затем добавив в мой метод обработки mybase.load:

Application.AddMessageFilter (New MyMessageFilter ())

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

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

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

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

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

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

Сегодня я обнаружил кое-что ОЧЕНЬ многообещающее: я определил свою функцию 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), прежде чем нажать «OK» на моем msgbox , то программа не вылетит, интересно! Обычно для отправки сообщения WM_ERASEBKGND требуется время, близкое к Тайм-ауту для sendmessage timeout. это, конечно, после отправки сообщения WM_SETTINGCHANGE из моего домашнего приложения для тестирования.

Итак, после этого я решил немного поближе познакомиться с Winspector, потому что, может быть, есть еще более полезные очереди, которые я могу найти? Поскольку очевидно, что ожидание, пока winspector покажет сообщение, отправленное на мой рабочий стол, для моей программы совсем не является исправлением. Я обнаружил несколько необычно именованных окон в процессе моей программы: одно называется ".NET -BroadcastEventWindow.2.0.0.0.378734a.0", а другое - "GDI + Класс окна перехвата '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

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

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

Ответы на вопрос(2)

Ваш ответ на вопрос