Предыдущая тема :: Следующая тема |
Автор |
Сообщение |
Sasha_builder Гость
|
Добавлено: Пт Фев 15 2002 01:52 Заголовок сообщения: Опять WM_PAINT: как с ним работать в Builder3 |
|
|
Приветствую всех!
Я уже пытался спрашивать на эту тему, сейчас я постараюсь показать свою задачу на конкретном примере:
Вот простой проект:
[code] //---file CNMain.h---
#ifndef CNMainH #define CNMainH
//------------------------------------------------- #inc.. #include #include
//-------------------------------------------------- class TForm1 : public TForm { __published: // IDE-managed Components TButton *btnCircle;
void __fastcall btnCircleClick(TObject *Sender); private: // User declarations public: // User declarations virtual __fastcall TForm1(TComponent* Owner);
/* protected: void __fastcall OnWMPaint(TWMPaint& Message); BEGIN_MESSAGE_MAP MESSAGE_HANDLER(WM_PAINT, TWMPaint, OnWMPaint) END_MESSAGE_MAP(TForm) */ }; //------------------------------------.. TForm1 *Form1; //------------------------------------------------ #endif
.. CNMain.cpp---
#include #pragma hdrstop
#include "CNMain.h" //---------------------------------------------------- #p.. resource "*.dfm" TForm1 *Form1;
__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) {
}
//--------------------------------------------.. __fastcall TForm1::OnWMPaint(TWMPaint& Message) { Canvas-Ellipse(0, 0, 300, 300); } */ //------------------------------------------------------
voi.. __fastcall TForm1::btnCircleClick(TObject *Sender) { Canvas-Ellipse(0, 0, 300, 300); } //------------------------------------------------------
.. создает окно. Есть кнопка "Circle", при ее нажатии рисуется окружность во все окно. Однако проблема в том, что окружность не перисовывается при повреждении (например, при наложении другого окна).
Теория говорит, нужно что-то делать с сообщением WM_PAINT. Я попробовал "привязать" свою функцию к этому сообщению (см. заремаренные участки текста программы). При этом окружность возникает сразу же при запуске программы, то есть не ждет нажатия кнопки. И кажется что окно постоянно получает это сообщение, так как изображение мелькает.
Может кто нибудь подсказать, где ошибка и как решить эту проблему?
Спасибо!
PS Мужики, не стесняйтесь в выражениях, ругайте самыми крепкими ругательсвами и называйте самыми уничижительными прозвищами (ламер/чайник и т.п.), только дайте решение |
|
Вернуться к началу |
|
|
IL
Зарегистрирован: 21.05.2002 Сообщения: 19 Откуда: Ryazan
|
Добавлено: Пт Фев 15 2002 11:16 Заголовок сообщения: Re: Опять WM_PAINT: как с ним работать в Builder3 |
|
|
Ты заменяеш функцию VCL которая отвечает на сообщение windows WM_PAINT на свойю функцию которая умеет только рисовать на конве а на самом деле там должно делаться очень многое. Попробуй использовать событие окна OnPaint(); |
|
Вернуться к началу |
|
|
Alexy
Зарегистрирован: 22.10.2003 Сообщения: 48
|
Добавлено: Сб Фев 16 2002 15:44 Заголовок сообщения: Re: Опять WM_PAINT: как с ним работать в Builder3 |
|
|
Теория говорит вот что:
1. Каждое окно может быть действительным или недействительным, в зависимости от того требуется ли перерисовка. Причём необязательно, чтобы недействительным было всё окно - таким может быть какой-нибудь регион внутри окна. 2. OS не несёт ответственности за перерисовку клиентской области окна, за исключением областей стёртых указателем крысы 3. WM_PAINT будет находиться в очереди сообщений до тех пор, пока окно содержит хотя бы один регион требующий перерисовки. Ни ::GetMessage(.....), ни ::PeekMessage(..., PM_REMOVE) его из очереди не удалят. Т.е. SomeClass::WM_PAINT_Handler(....) { drawSomething(); } будет выполняться либо до посинения, либо пока кто-нибудь не догадается удалить WM_PAINT из очереди одним из способов: 1. Пара функций HDC BeginPaint(HWND, LPPAINTSTRUCT); EndPaint(HWND, const LPPAINTSTRUCT);
Пример: SomeWindow::WM_PAINT_Handler() { PAINTSTRUCT dummy;
HDC hDC = ::BeginPaint(this-hWnd, &dummy); // можно рисовать, но только в пределах // недействительного региона // build paint class with hDC handle if necessary. // draw ::EndPaint(this-hWnd, &dummy);
Иногда пользуются более грубым способом: :BeginPaint(this-hWnd, &dummy); ::EndPaint(this-hWnd, &dummy);
HDC hDC = GetDC(this-hWnd) или например CDC* paint = СDC::FromHandle(hDC); // вся клиетская область окна доступна для рисования
2. RECT rc; ::GetWindowRect(hWnd, &rc); ::ValidateRect(hWnd, &rc);
или HRGN invalidRegion = recieve or calculate/build invalid region of window ::ValidateRgn(hWnd, invalidRegion);
Для обработчиков WM_PAINT конвенциональным считается первый способ.
Реальная ситуация может быть сложнее, это зависит от стоения используемой библиотеки, поэтому программирование под windows стоит начинать учить с OS API, а не с библиотек типа MFC или Borland Builder. |
|
Вернуться к началу |
|
|
Sasha_builder Гость
|
Добавлено: Сб Фев 16 2002 19:53 Заголовок сообщения: Спасибо, ребята, решение уже найдено |
|
|
event OnPaint |
|
Вернуться к началу |
|
|
|