Visual Basic, .NET, ASP, VBScript
 

   
   
     

Форум - Power Basic

Страница: 1 |

 

  Вопрос: Redraw / Refresh Добавлено: 25.07.05 01:32  

Автор вопроса:  ProgLamer
Я научился рисовать текст на контроле с помощью DrawText, а очищать DC от последствий такого рисования еще не научился. Не подскажите как?..

Ответить

  Ответы Всего ответов: 8  

Номер ответа: 1
Автор ответа:
 HOOLIGAN



Вопросов: 0
Ответов: 1066
 Профиль | | #1 Добавлено: 25.07.05 06:55
InvalidateRect или FillRect

Ответить

Номер ответа: 2
Автор ответа:
 ProgLamer



Вопросов: 1
Ответов: 29
 Профиль | | #2 Добавлено: 25.07.05 16:53
Задание: Надо частенько рисовать текст на Label'е.
Решение: Может так?..
Sub Draw_Text(str As Asciiz * 512)
Local hDC    As Dword
Local pPaint As PAINTSTRUCT
Local tRect  As RECT

    GetClientRect hLabel, tRect
    InvalidateRect hLabel, tRect, 1

    'Control Set Text hDlg, %IDC_Label, $Nul

    hDC = BeginPaint(hLabel, pPaint)
        SelectObject(hDC, hFont)
        SetBkMode hDC, %TRANSPARENT
        SetTextColor hDC, %White
        ;DrawText hDC, str, -1, tRect, %DT_LEFT
    EndPaint hLabel, pPaint
End Sub

В теории - должно работать, на практике - нормально работает если разкоментировать строку Control Set Text ...
Ответ: Control Set Text - это очень кривое, но все-таки работающее решение
Итог: Что-то здесь не так.
Вопрос: Что именно?

Ответ: ...

Ответить

Номер ответа: 3
Автор ответа:
 HOOLIGAN



Вопросов: 0
Ответов: 1066
 Профиль | | #3 Добавлено: 25.07.05 18:28
Для начала, BeginPaint и EndPaint вызывают только когда оконная процедура получила сообщение WM_PAINT (система запрашивает, будешь сам перерисовывать окно или нет).
Если инициатива перерисовать (нарисовать текст) исходит от тебя, надо вызывать GetDC/ReleaseDC.

Если здесь в процедуре вставлена InvalidateRect, которая провоцирует сообщение WM_PAINT, то само сообщение придёт не сюда, а в оконную процедуру, выполнятся действия описаные в ней по WM_PAINT, а затем код продолжит своё выполнение в текущей процедуре. Причём WM_PAINT придёт для родителя контрола. Для контрола WM_PAINT не посылается.

Можно сделать так: на каждое WM_PAINT для родителя вызывать твою процедуру перерисовки текста в статике. Естественно заменив BeginPaint и EndPaint на GetDC/ReleaseDC и убрав отсюда InvalidateRect.

InvalidateRect можно вызывать (только не из этой процедуры), когда тебе надо перерисовать контрол. Винда дернет твоего родителя через оконную процедуру, а тот из оконной процедуры вызовет эту твою функцию. Такая схема.

Ахтунг: если в оконной процедуре присутствует обработка WM_PAINT, то из неё надо вернуть TRUE. Это сигнал для винды, что ты сам отрисовал окно, и чтобы она не вмешивалась. Если вернуть FASLE (ноль), то винда посчитает, что должна сама рисовать окно.

Ответить

Номер ответа: 4
Автор ответа:
 ProgLamer



Вопросов: 1
Ответов: 29
 Профиль | | #4 Добавлено: 25.07.05 22:36
Спасибо за уделенное внимание.
Почитал и прикинул, что процедура рисования может выглядит так:
...
Global str As Asciiz * 512
...
Sub Draw_Text(bRedraw As Byte)
    If bRedraw Then
      Local tRect  As RECT
        GetClientRect hLabel, tRect
        InvalidateRect hLabel, tRect, 1
'Exit Sub
    End If
    
  Local hDC    As Dword
  Local pPaint As PAINTSTRUCT

    hDC = BeginPaint(hLabel, pPaint)
        SelectObject(hDC, hFont)
        SetBkMode hDC, %TRANSPARENT
        SetTextColor hDC, %White
        ;DrawText hDC, str, -1, tRect, %DT_LEFT
    EndPaint hLabel, pPaint
End Sub


В оконной процедуре родителя STATIC'а на сообщение WM_PAINT вызываю Draw_Text(%False), в остальных случаях (когда мне нужно перерисовать контрол) вызываю Draw_Text(%True).
Насколько я понимаю, если bRedraw = True, то ф-ция InvalidateRect должна послать WM_PAINT родителю (этого замечено не было). После этого можно было бы выходить из процедуры, поскольку в оконной процедуре она (Draw_Text) еще раз вызывается, но с параметром bRedraw = False
И основа: в уме одно, а на деле - другое ( Не работает )
Что я опять не то придумал?..

Ответить

Номер ответа: 5
Автор ответа:
 HOOLIGAN



Вопросов: 0
Ответов: 1066
 Профиль | | #5 Добавлено: 25.07.05 23:57
Не работает - это что? программа не запускается, или не компилируется, или статик не рисуется, или рисуется, но затем стирается, или не тем цветом, или фон не тот, или... Сто причин и проявлений может быть. Что не работает?

Ответить

Номер ответа: 6
Автор ответа:
 ProgLamer



Вопросов: 1
Ответов: 29
 Профиль | | #6 Добавлено: 26.07.05 10:55
Прошу прощения, не уточнил: всё компилируется и запускается, рисуется тем цветом, но рисуется поверх предыдущего текста... Если же форму скрыть/отобразить - всё ОК (STATIC очищеный и на нем первый раз можно рисовать, а потом снова поверх). Что происходит, когда форма самостоятельно перерисовывается, и как бы это повторить...

Ответить

Номер ответа: 7
Автор ответа:
 HOOLIGAN



Вопросов: 0
Ответов: 1066
 Профиль | | #7 Добавлено: 26.07.05 11:29
Если новая надпись ложится поверх старой, и старая проступает снизу, - вызови FillRect перед вызовом DrawText, чтобы залить область рисования, и таким образом стереть предыдущий текст.

Ответить

Номер ответа: 8
Автор ответа:
 ProgLamer



Вопросов: 1
Ответов: 29
 Профиль | | #8 Добавлено: 26.07.05 22:47
Еспользовал FillRect - результат положительный

HOOLIGAN, спасибо за общение :)

Ответить

Страница: 1 |

Поиск по форуму



© Copyright 2002-2011 VBNet.RU | Пишите нам