Как отследить WM_PAINT в TextBox

Язык Visual Basic на платформе .NET.

Модераторы: Ramzes, Sebas

Joo
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 762
Зарегистрирован: 14.08.2008 (Чт) 11:55
Откуда: Казахстан

Как отследить WM_PAINT в TextBox

Сообщение Joo » 22.09.2008 (Пн) 11:02

Блин раньше все легко решалось сабклассингом, но тут кашмар какой-то, как бы я не переопределял onPaint, и как бы встроенными возможностями сабклассинга не оперировал событие onPaint или WM_PAINT не сробатывает при вводе текста :shock:

Народ подскажите ламеру, как это сделать на .NET?
"Им будет не просто, тем кто полагается на истину авторитета, вместо того чтобы полагаться на авторитет Истины"
Джеральд Месси, Египтолог

Viper
Артефакт VBStreets
Артефакт VBStreets
Аватара пользователя
 
Сообщения: 4394
Зарегистрирован: 12.04.2005 (Вт) 17:50
Откуда: Н.Новгород

Re: Как отследить WM_PAINT в TextBox

Сообщение Viper » 22.09.2008 (Пн) 14:42

WndProc переопределить, например.
Весь мир матрица, а мы в нем потоки байтов!

Joo
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 762
Зарегистрирован: 14.08.2008 (Чт) 11:55
Откуда: Казахстан

Re: Как отследить WM_PAINT в TextBox

Сообщение Joo » 22.09.2008 (Пн) 16:45

Viper писал(а):WndProc переопределить, например.

А ты сам пробовал?
Я делал так, переопределял WndProc, но событие WM_PAINT не срабатывет!!! Даже установка UserPaint в True не помогает!
Код: Выделить всё
Public Class MyTextBox
    Inherits TextBox
    Private Const WM_PAINT = &HF

    Public Sub New()
        'И даже эта писанина не помогает
        Me.SetStyle(ControlStyles.UserPaint, True)
        Me.SetStyle(ControlStyles.AllPaintingInWmPaint, True)
        Me.SetStyle(ControlStyles.ResizeRedraw, True)
        Me.SetStyle(ControlStyles.OptimizedDoubleBuffer, True)
    End Sub

    Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
        Select Case m.Msg
            Case WM_PAINT
                'Сюда не ходит :(
                Debug.Print("PAINT")
        End Select
        MyBase.WndProc(m)
    End Sub
End Class
"Им будет не просто, тем кто полагается на истину авторитета, вместо того чтобы полагаться на авторитет Истины"
Джеральд Месси, Египтолог

Nord777
Гуру
Гуру
Аватара пользователя
 
Сообщения: 1144
Зарегистрирован: 22.02.2004 (Вс) 13:15
Откуда: Подольск

Re: Как отследить WM_PAINT в TextBox

Сообщение Nord777 » 22.09.2008 (Пн) 18:37

Scarabey ты лучше скажи, КАК ИМЕННО ты хочешь надругаться над бедным текстбоксом? :) Конечная цель?
Microsoft Visual Studio 2008
Microsoft .NET Framework 3.5

Viper
Артефакт VBStreets
Артефакт VBStreets
Аватара пользователя
 
Сообщения: 4394
Зарегистрирован: 12.04.2005 (Вт) 17:50
Откуда: Н.Новгород

Re: Как отследить WM_PAINT в TextBox

Сообщение Viper » 23.09.2008 (Вт) 7:12

Scarabey
Код: Выделить всё
Private Const WM_PAINT As Long = &HF
    Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
        Select Case m.Msg
            Case WM_PAINT
                 Debug.Print("WM_PAINT")
        End Select
        MyBase.WndProc(m)
    End Sub
End Class
А почему у меня этот код успешно срабатывает? И да, а что же такое надо над TextBox то сделать?
Весь мир матрица, а мы в нем потоки байтов!

Joo
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 762
Зарегистрирован: 14.08.2008 (Чт) 11:55
Откуда: Казахстан

Re: Как отследить WM_PAINT в TextBox

Сообщение Joo » 23.09.2008 (Вт) 17:12

Nord777 писал(а):Scarabey ты лучше скажи, КАК ИМЕННО ты хочешь надругаться над бедным текстбоксом? :) Конечная цель?

Собственно не над TextBox'ом, хотя можно и над ним, а над RichTextBox'ом
Viper писал(а):Scarabey
Код: Выделить всё
Private Const WM_PAINT As Long = &HF
    Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
        …
    End Sub
End Class
А почему у меня этот код успешно срабатывает? И да, а что же такое надо над TextBox то сделать?

Если внимательно прочитать мой первый пост, то станет понятно что я жду этого события еще и при изменении текста, по крайней мере видимого.
И я кажется нашел причину такого странного поведения, и она меня не радует.

Конечная цель: Сделать контрол, на основе TextBox либо RichTextBox, в котором была бы встроенная подсветка синтаксиса, подчеркивание слов с орфографическими ошибками и т.д.

Когда я делал подобное на ассемблере (только подсветка), то там все было просто, в событии WM_PAINT, вызывался стандартный обработчик события, а поверх нужным цветом отрисовывались нужные слова, обрабатывалась только видимая часть текста и посему была очень хорошая скорость и качество.
"Им будет не просто, тем кто полагается на истину авторитета, вместо того чтобы полагаться на авторитет Истины"
Джеральд Месси, Египтолог

Nord777
Гуру
Гуру
Аватара пользователя
 
Сообщения: 1144
Зарегистрирован: 22.02.2004 (Вс) 13:15
Откуда: Подольск

Re: Как отследить WM_PAINT в TextBox

Сообщение Nord777 » 23.09.2008 (Вт) 17:23

Тогда непонятно зачем тебе перекрывать OnPaint.
RichTextBox позволяет раскрашивать текст.
Microsoft Visual Studio 2008
Microsoft .NET Framework 3.5

Joo
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 762
Зарегистрирован: 14.08.2008 (Чт) 11:55
Откуда: Казахстан

Re: Как отследить WM_PAINT в TextBox

Сообщение Joo » 23.09.2008 (Вт) 19:17

Nord777 писал(а):Тогда непонятно зачем тебе перекрывать OnPaint.
RichTextBox позволяет раскрашивать текст.

И на это несколько причин, первая причина это я, а вторая все мои… в общем не важно
Если раскрашивать средствами RichTextBox , сразу появляется геморрой с Undo/Redo, оно мне надо? Нет. Кто так делал, тот меня поймет. Я, уже молчу про скорость. И еще RichTextBox не позволяет, на сколько, я знаю, волнистую линию под словом накарябать.

И еще хочу сразу сказать, почему невозможно отследить WM_PAINT, при вводе текста, поделюсь так сказать соображениями. С тех времен когда суровые программисты писали только в машинных кодах и не признавали даже ассемблера, много воды утекло, программист стал ленивее, капризнее и … что-то я с далека начал, переносимся дальше когда уже все забыли, что Билли спер, и перепродал ДОС, и во всю процветала Windows, суровые программисты уже стали не настолько суровы и их вполне устраивал C++ в перемешку с Assembler'ом, и программировали окошки на WinAPI... Опять далеко… Перенесемся чуть дальше, появился .NET и WInAPI обозвали неуправляемым кодом, понаписав кучу новых компонент. Но некоторые функции и контролы в .NET до сих пор работают и создаются с помощью тех же API, что и раньше но в .NET обвертке, а если API, значит, ими управляет система, перерисовывает, к примеру, а API это неуправляемый код и поэтому давать программисту вмешиваться в этот процесс не как нельзя. Хм, спросите вы меня, но срабатывает же WM_PAINT, да срабатывает но срабатывает далеко не то что нужно, срабатывает WM_PAINT обвертки. Я подозреваю найдутся те кто скажет, а и х… с ней мы её старым дедовским способом субклассируем через SetWindowLong, у меня тоже такая шальная мысль пробежала в голове, но есть некая особенность…. Блин, я сегодня наверное перекурил MSDN'а, и прочей документации… Ладно продолжим. Кто знает, что такое писать на WinAPI, тот меня поймет и сразу скажет, чего нельзя поменять окну во время его жизни? Правильно нельзя поменять его стиля, который указывается при его создании. И что у него, окна, неизменно с момента его создания и до момента его уничтожени? Правильно его уникальный идентификатор, хендл, hWnd, короче кому как нравится. Но программисты на .NET скажут, фиг там, можно любой стиль поменять окну во время выполнения программы, и у других компонентов получается, даже построенных на API, хотя это и противоречит программированию на API, как так? Ядро вроде одно, на асме не меняются стили окон в рантайм, а в .NET запросто, а оказалось все просто, при изменении таких хитрых стилей, обвертка тупо создает новое окно с новыми стилями, а старое удаляет. Все. Сменили стиль, а хендл(hWnd) то тоже сменился, не верите проверьте! Какой из этого вывод? А вывод, НЕЛЬЗЯ использовать SetWindowLong для субклассирования окна под обверткой в .NET, а то в один прекрасный момент программа пойдет в разнос. Из всего вышеизложенного, любой обладающий логическим мышлением человек поймет, что отследить WM_PAIN у .NET контролов, в частности у TextBox и RichTextBox, построенных на старых API невозможно.

Но, отчаиваться рано, выход всегда есть, нужно просто написать свою .NET обвертку, где уже будешь ты решать, когда создавать окно, а когда его уничтожать, тем самым получив полный контроль над компонентом.
"Им будет не просто, тем кто полагается на истину авторитета, вместо того чтобы полагаться на авторитет Истины"
Джеральд Месси, Египтолог

Nord777
Гуру
Гуру
Аватара пользователя
 
Сообщения: 1144
Зарегистрирован: 22.02.2004 (Вс) 13:15
Откуда: Подольск

Re: Как отследить WM_PAINT в TextBox

Сообщение Nord777 » 23.09.2008 (Вт) 22:56

Блин, я сегодня наверное перекурил MSDN'а, и прочей документации…
Наверно :D

Кто мешает тебе обрабатывать не только WM_PAINT, а еще и например WM_CHAR....
Microsoft Visual Studio 2008
Microsoft .NET Framework 3.5

Joo
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 762
Зарегистрирован: 14.08.2008 (Чт) 11:55
Откуда: Казахстан

Re: Как отследить WM_PAINT в TextBox

Сообщение Joo » 24.09.2008 (Ср) 4:13

Nord777 писал(а):Кто мешает тебе обрабатывать не только WM_PAINT, а еще и например WM_CHAR....


Хорошо, но WM_CHAR тоже не достаточно обрабатывать, он не всегда, когда нужно срабатывает. Это раз, а во вторых это не очень красиво...
"Им будет не просто, тем кто полагается на истину авторитета, вместо того чтобы полагаться на авторитет Истины"
Джеральд Месси, Египтолог

Nord777
Гуру
Гуру
Аватара пользователя
 
Сообщения: 1144
Зарегистрирован: 22.02.2004 (Вс) 13:15
Откуда: Подольск

Re: Как отследить WM_PAINT в TextBox

Сообщение Nord777 » 24.09.2008 (Ср) 21:46

Это раз, а во вторых это не очень красиво...
Красота - понятие растяжимое. То есть ты считаешь, что при нажатии кнопки на клавиатуре, винда должна посылать окну WM_PAINT вместо WM_CHAR(WM_KEYDOWN)? Или сразу оба сообщения? И по твоему мнению так красивее и логичнее?
Microsoft Visual Studio 2008
Microsoft .NET Framework 3.5

Joo
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 762
Зарегистрирован: 14.08.2008 (Чт) 11:55
Откуда: Казахстан

Re: Как отследить WM_PAINT в TextBox

Сообщение Joo » 26.09.2008 (Пт) 5:26

Nord777 писал(а):Красота - понятие растяжимое. То есть ты считаешь, что при нажатии кнопки на клавиатуре, винда должна посылать окну WM_PAINT вместо WM_CHAR(WM_KEYDOWN)? Или сразу оба сообщения? И по твоему мнению так красивее и логичнее?

Как ни странно, но посылает :wink: достаточно написать это дело на C, ASM или тупо субклассировать на VB6 и сразу все работает ))
Когда система посылает WM_PAINT? Когда нужно что-то перерисовать, а буковки, может тебя это шокирует, тоже перерисовываются. Не веришь, напиши на VB6.
"Им будет не просто, тем кто полагается на истину авторитета, вместо того чтобы полагаться на авторитет Истины"
Джеральд Месси, Египтолог

Nord777
Гуру
Гуру
Аватара пользователя
 
Сообщения: 1144
Зарегистрирован: 22.02.2004 (Вс) 13:15
Откуда: Подольск

Re: Как отследить WM_PAINT в TextBox

Сообщение Nord777 » 26.09.2008 (Пт) 16:45

Как ни странно, но посылает достаточно написать это дело на C, ASM или тупо субклассировать на VB6 и сразу все работает
Да тут вобщем то и писать ничего не надо. Хоть раз пользовался утилитой Microsoft Spy++ ? Вот запусти её и посмотри кто кому и что посылает.

Microsoft Spy++
Microsoft Control Spy 2.0

Добавлено чуть позже:
Что бы не возникло недопонимания, я говорю об элементе управления с именем класса Edit в системе Windows XP.
Я не говорю о каком то суперперегруженном контроле, который в обработчике WM_CHAR(или любом другом) посылает сам себе сообщение WM_PAINT.
Элемент управления с именем класса Edit(а это и есть нативный текстбокс) можно обнаружить к примеру в Блокноте.
Microsoft Visual Studio 2008
Microsoft .NET Framework 3.5


Вернуться в Visual Basic .NET

Кто сейчас на конференции

Сейчас этот форум просматривают: Google-бот и гости: 2

    TopList  
cron