
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[216.73.216.234] |
![]() |
|
Страницы: (3) [1] 2 3 все ( Перейти к последнему сообщению ) |
Сообщ.
#1
,
|
|
|
Добрый день.
Помогите решить проблемы! Есть простенькая программа, рисующая круги в PaintBox... И всё вроде бы работало нормально, пока я не заметил, что если какое либо приложение нашло на мою форму то изображение "затирается"... Я поискал ответа на этом форуме, но там всё как то слишком обще сказано и не понятно мне... =) И вторая проблема - сохранение изображения из PaintBox. Поиск помог отрыть кусок кода для сохранения. Вот он: ![]() ![]() void __fastcall paintBoxToFile( TPaintBox * aPaintBox, AnsiString aFileName ){ // Создаем bitmap Graphics::TBitmap * bmp = new Graphics::TBitmap(); try{ // Устанавливаем размеры и формат bmp->PixelFormat = pf24bit; bmp->Height = aPaintBox->ClientHeight; bmp->Width = aPaintBox->ClientWidth; // Запоминаем старый handle HANDLE oldHandle = aPaintBox->Canvas->Handle; try{ // Устанавливаем handle bitmap'а aPaintBox->Canvas->Handle = bmp->Canvas->Handle; // Заставляем вывести изображение // Если не будет обработчика, то на этом месте программа упадет aPaintBox->OnPaint( aPaintBox ); } __finally{ // Восстанавливаем handle aPaintBox->Canvas->Handle = oldHandle; } // Сохраняем в файл bmp->SaveToFile( aFileName ); } __finally{ // Удаляем bitmap delete bmp; } } Но объясните мне как заставить PaintBox вывести изображение? Потому что файл сохраняется, но он пустой... То есть белый. Заранее спасибо! |
Сообщ.
#2
,
|
|
|
Цитата Yura93 @ если какое либо приложение нашло на мою форму то изображение "затирается"... Потому что файл сохраняется, но он пустой... Значит обработчик OnPaint реализован неправильно |
Сообщ.
#3
,
|
|
|
Суть такая:
- создаёшь временный битмап bmp размерами с пайнтбокс - создаёшь некий метод Draw(), который рисует именно на этом битмапе - в событии PaintBox->OnPaint() просто отображаешь этот битмап на канве пайнтбокса PaintBox->Canvas->Draw(0, 0, bmp) - ну а сохранить битмап в файл проблему не составит |
Сообщ.
#4
,
|
|
|
Цитата Сан Иваныч @ Суть такая: ... А какой тогда смысл вообще юзать PaintBox ? Проще заменить его на TImage - рисуешь один раз картинку, при этом автоматом создаться битмап, и перерисовывается автоматически без всяких OnPaint, и об удалении битмапа думать не нужно |
Сообщ.
#5
,
|
|
|
да, как предложил leo лучше сделай. PaintBox постоянно перерисовываеться, а c TImage нарисовал и забыл
![]() |
Сообщ.
#6
,
|
|
|
PaintBox в данном случае имеет смысл, если недолгая отрасовка, и смысла нету картинку держать, или она хранится другим способом, например чараз api или какой-то специфической компонентой, или библиотекой. При этом можно повесить обработчик и рисовать не всю область, а только то, что нуждается в отрисовке при желании. В простом вар-те - да, лучше положить timage и не извращаться.
|
Сообщ.
#7
,
|
|
|
Вы меня не так поняли!
![]() Из всех возможный событий у меня используются только OnMouseDown, OnMouseUp, OnMouseMove. Если ны нажал и водишь мышкой по PaintBox то рисуется след из кругов. Их цвет и размер можно менять. А я хочу чтобы нарисованное сообщение можно было сохранить. И чтобы оно не затиралось другими приложениями. В данном случае Image не подходит потому что у него нет свойство OnMouseMove. И если надо вот кусок кода отвечающий за отрисовку: ![]() ![]() void __fastcall TForm1::PaintBox1MouseMove(TObject *Sender, TShiftState Shift, int X, int Y) { if(MouseD){ Size=StrToInt(Edit1->Text); if(CheckBox3->Checked){ PenW=StrToInt(Edit2->Text); } else{ PenW=0; PenC=Panel2->Color; } PaintBox1->Canvas->Brush->Color=Panel2->Color; PaintBox1->Canvas->Pen->Color=PenC; PaintBox1->Canvas->Pen->Width=PenW; if(RadioGroup1->ItemIndex==0){ PaintBox1->Canvas->Ellipse(X - Size,Y - Size, X + Size, Y + Size); } else{ PaintBox1->Canvas->Rectangle(X - Size,Y - Size, X + Size, Y + Size); } } } |
Сообщ.
#8
,
|
|
|
Цитата Yura93 @ В данном случае Image не подходит потому что у него нет свойство OnMouseMove. У тебя какой Builder ? на 6 ке есть. PS. Можно легко научить его этому Так или так : ![]() ![]() // *.h файл class TForm1 : public TForm { //... public: // User declarations __fastcall TForm1(TComponent* Owner); TWndMethod OldWndProc; void __fastcall NewWndProc(TMessage &Msg); }; // *.cpp файл //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { OldWndProc = Image1->WindowProc; Image1->WindowProc = NewWndProc; } //--------------------------------------------------------------------------- void __fastcall TForm1::NewWndProc(TMessage &Msg) { POINT p; switch (Msg.Msg) { case WM_MOUSEMOVE : { p.x = Msg.LParamLo; p.y = Msg.LParamHi; } case WM_DESTROY : { Image2->WindowProc = OldWndProc; break; } } OldWndProc(Msg); } |
Сообщ.
#9
,
|
|
|
CodeGear2009
|
Сообщ.
#10
,
|
|
|
Цитата Yura93 @ Вы меня не так поняли! ![]() Из всех возможный событий у меня используются только OnMouseDown, OnMouseUp, OnMouseMove Это ты не так понял назначение TPaintBox, который в отличие от TImage, нигде не хранит нарисованное изображение и поэтому оно должно каждый раз, целиком перерисовываться, и нигде нибудь, а именно в OnPaint. А если рисовать в PaintBox'е не в OnPaint, а по каким-то "левым" событиям, то при любой перерисовке окна, инициированной виндой (при перекрытии, изменении размеров и т.п.) - все твои "художества" потеряются, что собс-но у тебя и происходит Поэтому тебе нужен именно TImage, который сохраняет все, что тобой нарисовано, в своем Picture.Bitmap, и соответственно автоматически отображает этот битмап на экране по виндовым запросам WM_PAINT. И события OnMouse... в TImage должны быть, по крайней мере в BCB 6 они есть, и поэтому твое заявление Цитата Yura93 @ В данном случае Image не подходит потому что у него нет свойство OnMouseMove - скорее всего неверно |
Сообщ.
#11
,
|
|
|
А что должно быть в событии OnPaint?
|
Сообщ.
#12
,
|
|
|
Цитата Yura93 @ А что должно быть в событии OnPaint? то что ты хочешь видеть в своем PainBox'е. |
Сообщ.
#13
,
|
|
|
Цитата popsa @ то что ты хочешь видеть в своем PainBox'е. Ёмко но не понятно... Приведите пример кода... |
Сообщ.
#14
,
|
|
|
к примеру напиши в своем примере в обработчике OnPaint
![]() ![]() ![]() PaintBox1->Canvas->Pen->Color=clRed; PaintBox1->Canvas->Pen->Width=3; PaintBox1->Canvas->Rectangle(40,30, 100, 100); |
Сообщ.
#15
,
|
|
|
Стоп! Когда наступает событие OnPaint?
|