최근에 코드를 일부 최적화한 결과 효과는 괜찮지만 인터페이스가 깜박이는 것을 발견했습니다. 특히 TreeView 컨트롤이 깜박이고 언어는 C#이고 IDE는 VS2005입니다. 몇 가지 정보를 참조하고 몇 가지 기본 기술(예: 이중 버퍼링 켜기)을 사용한 후에 아무런 효과가 없다는 것을 발견했습니다.
그래서 PRfiler 도구를 사용하여 매번 인터페이스를 업데이트한 후 EndUpdate 작업에 병목 현상이 있음을 알아냈습니다. (이는 인터페이스 업데이트 횟수를 줄이기 위해 사용되지만 여기서는 컨트롤에 요소가 많기 때문에 이상적이지 않습니다.) 업데이트될 때마다 .Net의 하위 레이어가 각각 업데이트되고 다시 그려지기 때문에 속도가 느려지고 깜박거림이 발생할 것으로 생각됩니다. 그러나 이 경우 이중 버퍼링을 사용하면 더 나은 결과를 얻을 수 있습니다. 코드를 다시 보니 업데이트 동작이 너무 잦은 것 같아서 속도를 줄여서 나아지긴 했지만 여전히 동작하지 않았습니다.
계속해서 온라인으로 검색하여 마침내 더 적합한 솔루션을 찾으십시오. 기본 다시 그리기는 매번 캔버스를 지운 다음 모두 다시 그리는 것으로 나타났습니다. 이것이 깜박임의 주요 원인입니다. 따라서 메시지 전송 기능 작동이 과부하되어 이 메시지가 비활성화됩니다. 코드는 다음과 같습니다:
보호된 재정의 void WndProc(참조 메시지 m)
{
if (m.Msg == 0x0014) // 배경 메시지 지우기를 비활성화합니다.
반품;
base.WndProc(ref m);
}
성공!
참고: 업데이트가 자주 발생하지 않고 컨트롤에 너무 많은 요소가 포함되지 않은 경우 이중 버퍼링은 여전히 유용합니다. 요소가 너무 많으면 업데이트할 때마다 시간이 오래 걸립니다. 이중 버퍼링을 사용해도 깜박임 문제를 해결할 수 없습니다. 개인적으로 이상적인 방법은 결국 배경 메시지를 비활성화하고 지우는 것입니다.
첨부: 시도 및 실패 기록 일부
1) setStyle 사용
인터넷에서는 setStyle 함수가 컨트롤의 매개변수를 설정하는 데 사용된다고 합니다. 특히 다음과 같습니다.
SetStyle(ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer, true);
세 가지 옵션 매개변수 중 후자는 전자에 종속되며 공존해야 합니다. 그렇지 않으면 유효하지 않습니다. 그리고 이 기능 자체는 보호되어 있으므로 사용하기 전에 먼저 특정 컨트롤을 상속받아야 합니다.
이 목표는 배경 지우기를 비활성화하고 이중 버퍼링을 활성화하지만 사용자 그리기 옵션이 필요하고 모든 그리기는 사용자가 수행하는 이전의 올바른 솔루션과 일치합니다. 이를 위해서는 컨트롤의 모든 도면을 직접 구현해야 하는데 이는 매우 번거로운 작업입니다. 따라서 이 방법이 완전히 실행 가능하지 않은 것은 아니지만 추가 작업이 필요하므로 권장되지 않습니다. 나도 그것을 사용하지 않았습니다.
2) BeginUpdate 및 EndUpdate 사용
이 작업 쌍은 초기화 중에 대량의 노드를 일괄 추가하는 등 컨트롤을 업데이트하기 위해 일괄 작업이 필요한 시나리오에서 더 나은 효과를 갖습니다. 단점은 즉시 업데이트가 불가능하다는 것입니다. 따라서 노드가 자주 업데이트되어 즉시 인터페이스에 반영되기를 원하는 상황에는 적합하지 않습니다. 사용하고 인터페이스 지우기 메시지를 비활성화하지 않으면 컨트롤이 깜박이는 것처럼 보이고 주로 흰색 배경을 가지며 콘텐츠가 거의 보이지 않게 됩니다(비디오의 복잡성에 따라 다름). EndUpdate에서 인터페이스 업데이트가 완료되기 때문에 너무 많은 작업으로 인해 EndUpdate가 오랫동안 차단되고, 인터페이스가 먼저 지워지고 나중에 업데이트되어 오랫동안 공백으로 나타나는 현상이 발생합니다.
3) ControlStyles.EnableNotifyMessage 옵션을 사용하세요.
이 옵션의 효과는 올바른 솔루션과도 일치합니다. 사용법은 다음과 같습니다.
SetStyle(ControlStyles.EnableNotifyMessage, true);
보호된 재정의 무효 onNotifyMessage(메시지 m)
{
//여기에 필터 메시지 코드를 작성합니다.
}
그러나 실제 실험에서는 아무런 효과가 나타나지 않았으며, 이에 대해 자세히 조사하지도 않았습니다.
-