캔버스 멋지다! - 페이지 90

 
Nikolai Semko #:

캔버스는 픽셀 배열이 바인딩된 객체입니다. 리소스는 이 픽셀 배열을 바인딩하는 역할을 합니다(bool CCanvas::Create() 참조)
항상 캔버스를 삭제하고 다시 만드는 것은 좋지 않습니다.
캔버스가 필요할 때 만들고 프로그램이 끝날 때와 같이 더 이상 필요하지 않을 때 삭제하는 것이 좋습니다.

캔버스 개체를 만든 후에는 정리하고, 매 프레임마다 픽셀 배열을 덮어쓰고, 캔버스 크기를 조정하고, 원하는 곳으로 이동할 수 있습니다.

고마워요, 조금 더 명확해졌지만 전부는 아닙니다. 캔버스 개체를 만든 후 ObjectDelete() 를 사용하여 차트에서 개체를 삭제하면 이 개체에 연결된 픽셀 배열이 그대로 유지된다는 것을 올바르게 이해했나요? 다른 이름의 새 캔버스 개체를 다시 만들면 메모리에 새 픽셀 배열이 생성되므로 이론적으로 전체 메모리를 채울 수 있습니까?

아니면 이전 픽셀 배열은 매번 마지막으로 생성 된 캔버스 객체에 단순히 다시 바인딩됩니까 (캔버스 클래스의 사용 된 인스턴스의 모든 기능이 작동하기 시작하기 때문에)?

 
leon_17 #:

고마워요, 조금 더 명확해졌지만 전부는 아닙니다. 캔버스 개체를 만든 후 ObjectDelete()를 사용하여 차트에서 개체를 삭제하면이 개체에 바인딩 된 픽셀 배열은 그대로 유지되고.... 다른 이름의 새 캔버스 개체를 다시 만들면 메모리에 새 픽셀 배열이 생성되므로 이론적으로 모든 메모리를 채울 수 있습니까?

물론 소유자가 없는 리소스는 늘어날 것입니다.

leon_17 #:

또는 여전히 이전 픽셀 배열은 매번 마지막으로 생성된 칸버스 객체에 다시 바인딩됩니다(사용된 칸버스 클래스 인스턴스의 모든 함수가 작동하기 시작하기 때문입니다).

상상력이 대단하네요. 부럽습니다. 저는 그런 생각을 하지 못했을 겁니다. :))

그러나 소유자가 없는 리소스의 이름을 저장하면 새 비트맵 객체에 다시 바인딩할 수 있습니다. 그러나 이것은 정신 분열증 분야에서 나온 것입니다.

 
Nikolai Semko #:

그러나 소유자가 없는 리소스의 이름을 저장하면 새 비트맵 객체에 다시 바인딩할 수 있습니다. 하지만 이것은 정신분열증 분야에서 나온 이야기입니다.

제 말을 취소합니다. 그런 것이 유용할 수 있는 경우를 찾은 것 같습니다.
 
Nikolai Semko #:
그 말은 취소할게요. 이것이 유용 할 수있는 경우를 찾은 것 같습니다.

고마워요, 저는 Destroy () 대신 ObjectDelete ()를 사용하면 메모리에서 어떤 일이 일어나는지 이해하고 싶었습니다. 그리고 그런 경우 새 캔버스 객체에 대해 매번 새 이름이 생성되면 그래픽 리소스 (소유자가없는 픽셀 배열 및 기타 모든 것)가 배가된다는 것을 깨달았습니다.

그리고ObjectDelete()를 사용하지만 같은 이름의 캔버스 객체를 만들면 픽셀 배열이 오래되었거나 여전히 새 것입니까?

추신 질문은 아마도 어리석은 일이지만 캔버스


의 메커니즘을 이해하려면이 질문이 필요합니다 .

 
leon_17 #:

고마워요, Destroy () 대신 ObjectDelete () 를 사용하면 메모리에서 어떤 일이 발생하는지 이해하고 싶었습니다. 그리고 매번 새 캔버스 객체에 대해 새 이름을 생성하면 그래픽 리소스(소유자가 없는 픽셀 배열 등)가 증가한다는 사실을 깨달았습니다.

간단한 스크립트를 작성하면 이를 쉽게 확인할 수 있습니다.
 
Nikolai Semko #:
간단한 스크립트를 작성하면 쉽게 확인할 수 있습니다.

방법을 알려주실 수 있나요?

 
leon_17 #:

방법을 알려주실 수 있나요?

이렇게요:

#define protected public
#include <Canvas\Canvas.mqh>
#undef protected

void OnStart() {
   while(!IsStopped()) {
      int Width =(ushort)ChartGetInteger(0,CHART_WIDTH_IN_PIXELS);  // получаем Ширину окна
      int Height=(ushort)ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS); // получаем Высоту окна
      CCanvas canvas;
      if(!canvas.CreateBitmapLabel("MyCanva"+string(rand()),0,0,Width,Height,COLOR_FORMAT_ARGB_NORMALIZE)) {
         Print("Error creating canvas: ",GetLastError());
      }
      canvas.FillRectangle(rand()%Width/2,rand()%Height/2,Width/2+rand()%Width/2,Height/2+rand()%Height/2,ARGB(128,rand()%255,rand()%255,rand()%255));
      canvas.Update();
      Comment("Задействовано памяти: - " + string(TerminalInfoInteger(TERMINAL_MEMORY_USED))+ " Mb");
      Sleep(500);
      ObjectDelete(canvas.m_chart_id,canvas.m_objname);
   }
}

그리고 댓글을 보세요:

!!! 이 스크립트를 실행한 후 터미널을 다시 로드하여 고아 리소스를 위한 메모리를 확보하는 것을 잊지 마세요.


 
Nikolai Semko #:

이렇게요:

그리고 댓글을 보세요:

!!! 이 스크립트를 실행한 후에는 터미널을 다시 로드하여 고아 리소스를 위한 메모리를 확보하는 것을 잊지 마세요.


도움을 주셔서 대단히 감사합니다! 나는 전에 이런 식으로 메모리로 작업 한 적이 없으므로 테스트 할 것입니다.
터미널을 다시로드 할 때 고아 리소스가 삭제된다는 힌트 주셔서 감사합니다! 그런 많은 것들이 아직 나에게 분명하지 않습니다.

추신 :이 예제의 모든 것이 완벽합니다! 살펴볼 것, 생각할 것, 실험 할 기회가 있습니다 ... 코드가 짧습니다.

 
캔버스가 Expert Advisor에서 사용되는 경우 차트에서 Expert Advisor를 제거하고 터미널을 닫을 때 Destroy()를 실행해야 하나요 ? 이것도 확인하는 방법을 모르겠습니다. 제 말은 고정된 개체가 있는 작업 캔버스를 의미합니다. 거기에서 메모리의 차이는 오류 내에 있습니다 ( Destroy () 를 수행 할 경우와 수행하지 않는 경우).
 
leon_17 Expert Advisor를 제거하고 터미널을 닫을 때 Destroy( )를 실행해야 하나요 ? 이것도 확인하는 방법을 모르겠습니다. 제 말은 고정된 개체가 있는 작업 캔버스를 의미합니다. 거기에서 메모리의 차이는 오류 내에 있습니다 ( Destroy ()수행하거나 수행하지 않는 경우).

그럴 필요는 없습니다. 캔버스 소멸자에서는 자동으로 실행됩니다:

                    ~iCanvas() { Destroy(); ChartRedraw();};