Как поменять фон у Edit-a?

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
arthur2
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1688
Зарегистрирован: 23.01.2008 (Ср) 14:35

Как поменять фон у Edit-a?

Сообщение arthur2 » 30.04.2019 (Вт) 17:24

Создаю эдит:
Код: Выделить всё
    hwTx = CreateWindowExW(392, StrPtr("Edit") _
      , StrPtr("ля-ля-ля",  WS_CHILD Or WS_VISIBLE Or WS_BORDER  _
      , 0, 0, 200, 30 _
      , Me.hwnd, 0, App.hInstance, ByVal 0)

Пытаюсь поменять фон вот так:
Код: Выделить всё
Private Sub Command1_Click()
Dim hdcT As Long
hdcT = GetWindowDC(hwTx)
SetBkColor hdcT, &HFF00&
End Sub

и вот так:
Код: Выделить всё
Private Sub Command2_Click()
      SendMessageW hwnd, ByVal EM_SETBKGNDCOLOR, ByVal 0, ByVal &HFF&
End Sub

Ни то, ни другое результата не даёт.
Меняю фон у родителя - выясняется, что эдит при перерисовке берёт цвет как раз у родителя.
Что я делаю не так?
Вложения
backcolor.zip
(1.98 Кб) Скачиваний: 145
Артур
 
   

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Как поменять фон у Edit-a?

Сообщение Хакер » 01.05.2019 (Ср) 14:49

arthur2 писал(а):SetBkColor hdcT, &HFF00&

Это очень наивно — естественно, это не сработает.

arthur2 писал(а):SendMessageW hwnd, ByVal EM_SETBKGNDCOLOR, ByVal 0, ByVal &HFF&

А EM_SETBKGNDCOLOR — это сообщения для RichEdit-контроля, а не для обычного Edit-а.

Когда Edit самоотрисовывается, он шлёт родительскому окну сообщение WM_CTLCOLOREDIT (если Edit в нормальном состоянии) или WM_CTLCOLORSTATIC (если Edit заблокирован или выключен).

Отреагировав на это сообщение, родительское окно может установить правила отрисовки.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

arthur2
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1688
Зарегистрирован: 23.01.2008 (Ср) 14:35

Re: Как поменять фон у Edit-a?

Сообщение arthur2 » 01.05.2019 (Ср) 15:13

То есть, на автомате нельзя поменять фон?

Помещаю такой же эдит, но не на бейсиковскую форму, а на окно, тоже созданное с помощью CreateWindow. Никакой дополнительной обработки в родительской винпрок нет. Но эдит в этом случае имеет свой, не зависимый от родителя, фон. В чём, собственно, разница? И значит, всё-таки как-то можно добиться от эдита самостоятельной отрисовки?

Если пойти-таки путём ловли WM_CTLCOLOREDIT, я так полагаю, что тогда надо вернуть из винпрок хендл кисти? или неправильно?
Артур
 
   

bon818
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 267
Зарегистрирован: 29.08.2009 (Сб) 4:49
Откуда: Ташкент

Re: Как поменять фон у Edit-a?

Сообщение bon818 » 01.05.2019 (Ср) 15:26

Пример с WM_CTLCOLOREDIT:
Вложения
backcolor.rar
Пример с WM_CTLCOLOREDIT
(26.67 Кб) Скачиваний: 142

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Как поменять фон у Edit-a?

Сообщение Хакер » 01.05.2019 (Ср) 15:37

arthur2 писал(а):Но эдит в этом случае имеет свой, не зависимый от родителя, фон.

Он зависимый от родителя по прежнему, просто чужое окно возвращает через WM_CTLCOLOREDIT другой цвет (белый, например), а VB-шная форма — свой.
Родитель же не обязан в общем случае возвращать через сообщение некий цвет, и им же отрисовывать своё пустое место.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

arthur2
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1688
Зарегистрирован: 23.01.2008 (Ср) 14:35

Re: Как поменять фон у Edit-a?

Сообщение arthur2 » 01.05.2019 (Ср) 16:00

bon818
Спасибо, получилось!

Хакер
Спасибо, механика процесса стала ясней :)
Артур
 
   

arthur2
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1688
Зарегистрирован: 23.01.2008 (Ср) 14:35

Re: Как поменять фон у Edit-a?

Сообщение arthur2 » 01.05.2019 (Ср) 16:26

Хакер
Может, заодно, расскажешь, почему едит не шлёт WM_CTLCOLOREDIT, когда текст в нём меняется или снимается выделение, а то прозрачные эдиты получаются кривыми. viewtopic.php?f=1&t=56533 Там, вроде, доковырялись до некоего компромисса, но способ получился всё же какой-то нестандартный и эдит с ним при редактировании мерцает.
Артур
 
   

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Как поменять фон у Edit-a?

Сообщение Хакер » 01.05.2019 (Ср) 18:51

arthur2 писал(а):Хакер
Может, заодно, расскажешь, почему едит не шлёт WM_CTLCOLOREDIT, когда текст в нём меняется или снимается выделение, а то прозрачные эдиты получаются кривыми.


У меня всё шлётся: и при правке текста, и при изменении выделения (в том числе и при сбрасывании выделения).
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

arthur2
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1688
Зарегистрирован: 23.01.2008 (Ср) 14:35

Re: Как поменять фон у Edit-a?

Сообщение arthur2 » 01.05.2019 (Ср) 19:59

Да, действительно, всё шлётся - это я уже подзабыл.
Код: Выделить всё
    Select Case uMsg
    Case WM_CTLCOLOREDIT
         Debug.Print " WM_CTLCOLOREDIT"
         If hwnd = hwndF Then
            SetBkMode wParam, 1
         Else
             winProc = CallWindowProc(PrevProc, hwnd, uMsg, wParam, lParam)
         End If
'    Case WM_PAINT
    Case WM_ERASEBKGND
       If hwnd = hwndTx Then
              winProc = 0
       Else
              winProc = CallWindowProc(PrevProc, hwnd, uMsg, wParam, lParam)
       End If
    Case Else
       winProc = CallWindowProc(PrevProc, hwnd, uMsg, wParam, lParam)
    End Select
Только в этом коде эдит не перерисовывается, когда стираются буквы или снимается выделение.
The trick предложил "схитрить" и искусственно вызывать перерисовку фона:
Код: Выделить всё
Case WM_CTLCOLOREDIT
        Static RC       As RECT     ' Прямоугольник окна текстбокса
        Static isRedraw As Boolean  ' Флаг перерисовки родителя
       
        ' Если флаг перерисовки родителя не установлен, тогда перерисовываем фон под собой
        If Not isRedraw Then
            ' Проецируем координаты рабочей области на родителя
            GetClientRect lParam, RC
            MapWindowPoints lParam, hwnd, RC, 2
            ' Рисуем фон родителя под текстбоксом
            isRedraw = True
            RedrawWindow hwnd, RC, 0, RDW_INVALIDATE Or RDW_UPDATENOW Or RDW_ALLCHILDREN
            isRedraw = False
                       ' Исключаем всю область, т.к. предыдущий вызов уже отрисовал текст
            ExcludeClipRect wParam, 0, 0, RC.iRight, RC.iBottom
        Else
            ' Установка прозрачной кисти и типа фона текста
            SetBkMode wParam, TRANSPARENT
            Ret = GetStockObject(NULL_BRUSH)
        End If
Это работает. Но при наборе эдит мерцает. Да и должен же быть какой-то стандартный способ? А то эта хитрость, хоть и остроумна, но как-то всё же костыль...
Артур
 
   

arthur2
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1688
Зарегистрирован: 23.01.2008 (Ср) 14:35

Re: Как поменять фон у Edit-a?

Сообщение arthur2 » 01.05.2019 (Ср) 22:18

В общем, всё равно засада.

Если при WM_CTLCOLOREDIT возвращать ноль, то фон эдита становится белым (вероятно, не белым, а системным фоном окна?). Если возвращать CallWindowProc, то фон берётся у формы-родителя.

А вот если возвращать хэндл кисти, то фон перерисовывается, но только та его часть, которая не занята текстом.

Можно, конечно, установить SetBkMode wParam, TRANSPARENT, тогда перерисовывается весь фон. Но тогда другая засада - не затирается удалённый текст.
Артур
 
   

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Как поменять фон у Edit-a?

Сообщение Хакер » 01.05.2019 (Ср) 22:40

arthur2 писал(а):Но тогда другая засада - не затирается удалённый текст.

В примере bon818 у нижнего текстбокса я наблюдаю нормальное поведение.

И вообще, сложно что-то посоветовать, пока ты не сказал, что ты хочешь.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

arthur2
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1688
Зарегистрирован: 23.01.2008 (Ср) 14:35

Re: Как поменять фон у Edit-a?

Сообщение arthur2 » 01.05.2019 (Ср) 23:04

Хакер писал(а):В примере bon818 у нижнего текстбокса я наблюдаю нормальное поведение.
Верхний - эдит, нижний - бейсиковский текстбокс. Впрочем, я наблюдаю у них практически одинаковое поведение - текст ни у того, ни у другого не затирается.

Хакер писал(а):И вообще, сложно что-то посоветовать, пока ты не сказал, что ты хочешь.
Хочу очень простого - хочу менять у своего эдита цвет фона.
Артур
 
   

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Как поменять фон у Edit-a?

Сообщение Хакер » 01.05.2019 (Ср) 23:16

arthur2 писал(а):Верхний - эдит, нижний - бейсиковский текстбокс. Впрочем, я наблюдаю у них практически одинаковое поведение - текст ни у того, ни у другого не затирается.

Я знаю. Это призыв сравнить тактику обработки оконных сообщений между двумя окнами. У меня у нижнего всё затирается. Прекрасное поведение без каких-либо багов.

arthur2 писал(а):Хочу очень простого - хочу менять у своего эдита цвет фона.

И что именно происходит не так, когда ты подсовываешь ему цветную кисть?
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

arthur2
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1688
Зарегистрирован: 23.01.2008 (Ср) 14:35

Re: Как поменять фон у Edit-a?

Сообщение arthur2 » 01.05.2019 (Ср) 23:44

Хакер писал(а):Это призыв сравнить тактику обработки оконных сообщений между двумя окнами. У меня у нижнего всё затирается
У меня они ведут себя почти одинаково. Верхний позволяет снять выделение, но не всегда, и обновляется, если стереть текст полностью. А нижний и этого не делает :)

Хакер писал(а):И что именно происходит не так, когда ты подсовываешь ему цветную кисть?
Фон меняется, но строки, занятые текстом, остаются белыми.
Артур
 
   

bon818
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 267
Зарегистрирован: 29.08.2009 (Сб) 4:49
Откуда: Ташкент

Re: Как поменять фон у Edit-a?

Сообщение bon818 » 02.05.2019 (Чт) 2:22

arthur2 писал(а):В общем, всё равно засада.

Если заменить константу &H50800004 на WS_CHILD Or WS_VISIBLE (и для полного сходства (+ or ES_AUTOHSCROLL or WS_BORDER)) то поведение текстбоксов будут идентичны. И все работает как задумано.
Но я понял, что у текстбоксов начинаются проблемы, если применить стиль ES_MULTILINE.
arthur2 Вы используете стиль ES_MULTILINE ?

arthur2
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1688
Зарегистрирован: 23.01.2008 (Ср) 14:35

Re: Как поменять фон у Edit-a?

Сообщение arthur2 » 02.05.2019 (Чт) 10:32

bon818
Да, мне нужен и мультилайн эдит, и однострочный тоже. Но разницы в их поведении относительно перерисовки фона я не заметил.

У меня не перерисовываются оба текстбокса.
Clipboard03.jpg
Clipboard03.jpg (26.29 Кб) Просмотров: 4311


А раз у вас с Хакером они ведут себя нормально, то тогда ещё больше засада - получается, что разное поведение вообще не понятно от чего.

Пока что удалось понять следующее (если, конечно, удалось правильно):
Фон под текстом и остальной фон эдита перерисовывается разными кистями.
Вот так и фон текста, и фон эдита рисуются кистью по умолчанию:
Код: Выделить всё
Case WM_CTLCOLOREDIT
        winProc = 0
        Exit Function

Вот так - и тот и другой фон рисуется кистью родителя:
Код: Выделить всё
Case WM_CTLCOLOREDIT
        winProc = CallWindowProc(PrevProc, hwnd, uMsg, wParam, lParam)
        Exit Function

Интересней всего вот так:
Код: Выделить всё
Case WM_CTLCOLOREDIT
        Call CallWindowProc(PrevProc, hwnd, uMsg, wParam, lParam)
        winProc = 0
        Exit Function
Тогда фон под текстом рисуется кистью родителя, а фон самого эдита - кистью по умолчанию.

Получается, что CallWindowProc здесь получает ту кисть, которой рисуется фон под текстом, чтобы ей же дорисовать остальной фон.
Артур
 
   

coderx
Новичок
Новичок
 
Сообщения: 29
Зарегистрирован: 05.09.2005 (Пн) 10:44
Откуда: Узбекистан

Re: Как поменять фон у Edit-a?

Сообщение coderx » 02.05.2019 (Чт) 10:41

Можете посмотреть от моей библиотеки: https://github.com/XusinboyBekchanov/MyFbFramework

Вот скомпилированное приложения:
Вложения
UnicodeEdit.zip
(182.45 Кб) Скачиваний: 160

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Как поменять фон у Edit-a?

Сообщение Хакер » 02.05.2019 (Чт) 12:05

arthur2 писал(а):получается, что разное поведение вообще не понятно от чего.


От чего?

От того же, отчего калькулятор режется:
Изображение

От того же, отчего в диалоге, в котором сто лет было всё равно, вдруг всё разъехалось:
Изображение
Изображение

От того, что люди с навозом вместо мозга наняли других людей с навозом вместо мозга на работу над новой версией ОС.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

arthur2
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1688
Зарегистрирован: 23.01.2008 (Ср) 14:35

Re: Как поменять фон у Edit-a?

Сообщение arthur2 » 02.05.2019 (Чт) 12:13

В общем, для непрозрачного эдита решил :)

backcolor.zip
(6.72 Кб) Скачиваний: 152

Код: Выделить всё
If uMsg = WM_CTLCOLOREDIT Then
     SetBkColor wParam, BkColor 'перерисовываю фон под текстом
     WinProc = hBrush 'возвращаю кисть для перерисовки остального фона
     Exit Function


Но вопрос с прозрачным эдитом или с эдитом с фоном-картинкой так и недорешен.
Последний раз редактировалось arthur2 02.05.2019 (Чт) 13:14, всего редактировалось 1 раз.
Артур
 
   

arthur2
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1688
Зарегистрирован: 23.01.2008 (Ср) 14:35

Re: Как поменять фон у Edit-a?

Сообщение arthur2 » 02.05.2019 (Чт) 12:26

coderx
Спасибо :) ФриБейсик, правда, для меня иностранный :oops:

Хакер
Это да :) Меня тоже многие вещи в новых осях бесят.
Артур
 
   

coderx
Новичок
Новичок
 
Сообщения: 29
Зарегистрирован: 05.09.2005 (Пн) 10:44
Откуда: Узбекистан

Re: Как поменять фон у Edit-a?

Сообщение coderx » 02.05.2019 (Чт) 12:29

arthur2 писал(а):coderx
Спасибо ФриБейсик, правда, для меня иностранный

WinAPI же везде одинаковый. У меня сейчас под рукой VisualBasic'а не быль, поэтому не мог тестировать.

arthur2
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1688
Зарегистрирован: 23.01.2008 (Ср) 14:35

Re: Как поменять фон у Edit-a?

Сообщение arthur2 » 02.05.2019 (Чт) 13:12

coderx
Ну так я скачал и даже посмотрел. Просто с чужим языком в любом случае трудно разобраться. WinProc я просто не нашёл :oops:
Артур
 
   

bon818
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 267
Зарегистрирован: 29.08.2009 (Сб) 4:49
Откуда: Ташкент

Re: Как поменять фон у Edit-a?

Сообщение bon818 » 02.05.2019 (Чт) 14:25

arthur2 писал(а):вопрос с прозрачным эдитом или с эдитом с фоном-картинкой так и недорешен.

Возможно, придется всю перерисовку брать под собственный контроль.

Если Вам не принципиально использовать именно Edit, то можно воспользоваться RichTextBox'ом, там все просто и предсказуемо (например, реализован WS_EX_TRANSPARENT):
viewtopic.php?f=1&t=56087&p=6790165#p6790165

arthur2
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1688
Зарегистрирован: 23.01.2008 (Ср) 14:35

Re: Как поменять фон у Edit-a?

Сообщение arthur2 » 02.05.2019 (Чт) 14:43

Ну, то что рич обеспечивает прозрачность без танцев с бубном, это я в курсе :)
Артур
 
   


Вернуться в Visual Basic 1–6

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

Сейчас этот форум просматривают: SemrushBot, Yandex-бот и гости: 60

    TopList