Страница: 1 |
|
Вопрос: Redraw / Refresh
|
Добавлено: 25.07.05 01:32
|
|
Автор вопроса: ProgLamer
|
Я научился рисовать текст на контроле с помощью DrawText, а очищать DC от последствий такого рисования еще не научился. Не подскажите как?..
Ответить
|
Номер ответа: 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
  rawText 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
  rawText 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
|
Не работает - это что? программа не запускается, или не компилируется, или статик не рисуется, или рисуется, но затем стирается, или не тем цветом, или фон не тот, или... Сто причин и проявлений может быть. Что не работает?
Ответить
|
Номер ответа: 7 Автор ответа: HOOLIGAN
Вопросов: 0 Ответов: 1066
|
Профиль | | #7
|
Добавлено: 26.07.05 11:29
|
Если новая надпись ложится поверх старой, и старая проступает снизу, - вызови FillRect перед вызовом DrawText, чтобы залить область рисования, и таким образом стереть предыдущий текст.
Ответить
|
Страница: 1 |
Поиск по форуму