Извините за Canvas, действительно пропустил, но Paintbox1.Canvas.Graphic тоже не работает....
То есть чтобы оно "хранилось" вместо Paintbox необходимо использовать Image? Еще раз извините за глупый вопрос, просто не хочется из-за недопонимания переписывать всё...
TPaintBox так устроен, что не хранит изображение, которое в нем нарисовано. Ему просто негде его хранить. Это обычная канва. Чем-то напоминает "узоры на песке", их тоже видно, пока ветер не подует или пока дождь не пойдет. Пока твое окно не перекрыто другими окнами - все видно. Как только окно перекроется - все, что было тобой нарисовано в PaintBox-е сотрется. Чтобы восстановить изображение, тебе придется перерисовать его. Поэтому заполняют TPaintBox обычно в событии OnPaint, то есть, полностью перерисовывают содержимое каждый раз, когда приходит сообщение WM_PAINT.
TImage снимает с тебя заботу о перерисовке своего содержимого. Допустим, по нажатию TButton ты нарисовал линию, свернул программу на таскбар, развернул - линия ровно в том же месте, где и была. PaintBox в аналогичном случае будет пуст.
Вместо Paintbox взял Image, всё отрисовывается хорошо, не исчезает никуда, но StretchDraw упрямится - ошибок не выдает но и не сжимает ничего, когда изображение больше, чем Image, видна лишь часть изображения...
и еще вопросик: Изображение не пропадает, но не делает это вообще: Пишу в событии кнопки первой строкой Img.free и выдает ужасную ошибку: Invalide Pointer operation
А ты задай MyRect побольше (или поменьше) раз в 10, узнаешь, напутал, или нет. А лучше задавай MyRect в зависимости от максимального и минимального из вводимых значений.
Действительно, ошибок не выдает, но это не значит, что работает... думаю я не в том месте его указываю(хотя пробовал в разных) или аргументы не те, посмотрите, пожалуйста, может какие замечания будут по стилю или применению функций, новичок в этом деле, готов учиться на своих ошибках...
procedure TForm1.BitBtn1Click(Sender: TObject); var i,j:integer; a1,a2,buf1,buf2:real; MyRect:TRect; begin //ar1 и ar2-содержат точки фигуры(1-левая грань,2-правая) img.Canvas.Pen.Color:=clBlack; l:=StrtoInt(edit1.text); h:=StrtoInt(edit2.text); //Начальная фигура -прямоугольник(зададим углы) ar1[1,1]:=10; ar1[2,1]:=10; ar1[1,100]:=10; ar1[2,100]:=10+h; ar2[1,1]:=10+l; ar2[2,1]:=10; ar2[1,100]:=10+l; ar2[2,100]:=10+h; //заполним массивы точками из таблицы for i:=1 to 100 do begin if (StringGrid1.Cells[0, i]<>'') and (StringGrid1.Cells[1, i]<>'') then begin a1:=StrToInt(StringGrid1.Cells[0, i]); a2:=StrToInt(StringGrid1.Cells[1, i]); ar1[1,i+1]:=10+Round((l-a1)/2); ar1[2,i+1]:=10+a2; ar2[1,i+1]:=10+Round((l-a1)/2)+a1; ar2[2,i+1]:=10+a2; end; end; //Сортируем массивы по высоте for i:=1 to 100 do for j:=1 to 100 do if ar1[2,i]<ar1[2,j] then begin buf1:=ar1[1,j]; buf2:=ar1[2,j]; ar1[1,j]:=ar1[1,i]; ar1[2,j]:=ar1[2,i]; ar1[1,i]:=buf1; ar1[2,i]:=buf2; end; for i:=1 to 100 do for j:=1 to 100 do if ar2[2,i]<ar2[2,j] then begin buf1:=ar2[1,j]; buf2:=ar2[2,j]; ar2[1,j]:=ar2[1,i]; ar2[2,j]:=ar2[2,i]; ar2[1,i]:=buf1; ar2[2,i]:=buf2; end; //Печать того, что получилось img.Canvas.MoveTo(10,10); for i:=1 to 100 do begin if (ar1[1, i]<>0) and (ar1[2, i]<>0) then begin img.Canvas.LineTo(Round(ar1[1,i]),Round(ar1[2,i])); end; end; img.Canvas.MoveTo(10+l,10); for i:=1 to 100 do begin if (ar2[1, i]<>0) and (ar2[2, i]<>0) then begin img.Canvas.LineTo(Round(ar2[1,i]),Round(ar2[2,i])); end; end; //Отрисовка верхней и нижней граней img.Canvas.MoveTo(10,10); img.Canvas.LineTo(10+l,10); img.Canvas.MoveTo(10,10+h); img.Canvas.LineTo(10+l,10+h); //Перевод изображения из буфера MyRect := Rect(0,0,Image1.ClientWidth,Image1.ClientHeight); Image1.Canvas.StretchDraw(MyRect, Image1.Picture.Graphic); Image1.Canvas.CopyRect(bounds(0,0,img.Width,img.Height), img.Canvas,bounds(0,0,img.Width,img.Height)); end;
Кто так сортировку пишет? У тебя она неправильно сортирует вообще. Видимо, ты откуда-то переписал, причём очень небрежно и не глядя, что там происходит.
for i:=1 to 100 do for j:=i+1 to 100 do
Дальше, а с чего StretchBlt будет работать, если у тебя и буфер, и область вывода, и прямоугольник, который ты выводишь - одного размера? Чему там и куда сжиматься? И зачем ты копируешь из себя в себя?
Насчет изображения понял... Почему-то такие глобальные ошибки сам не замечаешь, путаясь в мелочах, я рисовал от кромки, а чтобы она не была вплотную, сделал отступ в 10 пикселей, переделаю, чтобы всё от середины плясало, поэтому в принципе и сжать-то невозможно было... Спасибо огромное, переделаю, напишу.
А по поводу цикла - это эксперимент был и он удался, если сделать как ты говоришь, то появляются какие-то левые 2 линии по бокам, даже не знаю откуда, но тоже попробую привести к человеческому виду. Еще раз спасибо, будем работать!
Помогите, пожалуйста, с удалением изображения, Img.Destroy напрочь отказывается работать, всё та же ошибка - Invalid Pointer Operation. По идее Create - Destroy, но что-то не так тут...
Форма-то заново не создается и не уничтожается, деструкторы походу оттуда не работают, поэтому и помещал их в кнопку, т.к. в момент нажатия они должны уничтожаться:
procedure TForm1.FormDestroy(Sender: TObject); begin buffer.Free; img.Free; end;
Без ошибок и без результатов.
и вопросик по поводу StretchDraw:
Моя логика, решил не строить от середины, почему-то не удобно: Создаем в памяти изображение нужной ширины+50, и высоты+50: // 50 отведено на небольшие подписи
Это что, это зачем? Зачем копировать ещё раз? Ты сначала зачем-то вывел содержимое Image1 на себя со сжатием, а потом без сжатия туда же скопировал буфер.
Я же тебе сказал, как правильно выводить. А ты забил и сделал свою хрень неправильно. У тебя полное непонимание того, что ты делаешь.
Stretchdraw ожидает в качестве параметра тип .Graphic, img.Canvas такого свойства не имеет, поэтому как туда вставить его я не знаю... в этом и проблема основная.
Вообще уже не знаю что делать, весь мозг сломал, помогите, пожалуйста, переделать.