2014-12-10 2 views
7

특정 VCL 응용 프로그램이 충돌하는 경우는 거의없고 외관상 자연스럽게 발생합니다. 운영 체제의 일부 외부 트리거에 대한 응답으로 기본 폼의 창 핸들이 다시 작성되기 때문입니다.어떤 외부 이벤트가 TCustomForm.RecreateWnd를 트리거합니까?

주 폼의 창 핸들을 변경하려는 경우이면 확실하게 알 수 있습니다 (백그라운드 스레드가 메시지를이 핸들에 게시하기 때문에).

그러나이 버그를 수정하기 전에이 버그를 재현하는 방법을 알고 싶습니다. 코드가 변경된 경우에만이를 수정하려고합니다. 그럴 경우 충돌이 그럴듯한 원인인지, 증상이보고 된 것과 일치하는지, 코드 변경으로 인해 실제로 수정 될 수 있습니다. (또한 OS가 TCustomForm.RecreateWnd에 대한 호출을 트리거 할 수없는 경우 크래시에 대한 다른 설명을 찾아야합니다. 예, CM_RECREATEWND을 주 양식에 게시 할 수 있지만 질문을 그냥 응답합니다.)

백그라운드 스레드의 메시지를 VCL 스레드에 게시하는 올바른 방법은 AllocateHWnd을 사용하는 숨겨진 메시지 창을 만드는 것입니다. 즉, 제안 된 수정입니다.

자손과 비슷한 오류가 발생했습니다. TCustomListView 여기서 RecreateWnd은 데스크톱 스타일을 변경하여 트리거되었습니다. Windows XP ~ Windows 클래식. 그러나 나는 아직 에 RecreateWnd을 방아쇠를 당기는 그런 방법을 발견 할 수 없었다. (필자는 VCL 코드를 통해 읽는 상당한 시간을 소비했고 내가 모르는 뭔가가 있어야합니다.)

요약 : VCL가에 RecreateWnd를 호출 결국 않는 운영 체제에서 자극 어떤에서

a TCustomForm? (특히 Windows 7에 차이가 있다면이 점에 관심이 있습니다.)

OS의 자극이 있다면 관찰 된 증상의 원인인지 확인할 수 있습니다. 확실하게 없다면 창 레크리에이션이 원인이 아님을 증명할 수 있습니다.

+0

백업 할 수 없지만 다른 VCL 스타일이 적용될 때마다 창 핸들이 변경되는 것을 보았습니다. –

+0

vcl의 소스 코드를 살펴보십시오. 그게 내가 시작할 부분이다. –

+0

@DavidHeffernan 이미 VCL 소스를 읽는 데 온종일 아침을 보냈다. 무언가를 놓치고 있거나 OS가 양식에서 RecreateWnd를 트리거하지 않는다. 나는 누군가가 대답을 알기를 바랬다. –

답변

1

Windows는 소멸중인 다른 창을 소유하거나 부모 역할을하는 양식을 파괴합니다.

이렇게하면 양식 핸들이 손상 될 수 있습니다.

그러나 양식이 아직 남아 있기 때문에 Delphi는 다음 번에 핸들을 다시 작성합니다.

+0

좋은 지적. 이 메커니즘은 VCL 소스처럼 명시 적이지는 않습니다. 소유자 폼이 Delphi 애플리케이션 객체 인 경우 어떻게 될까요? 나는 프로세스의 정상적인 수명 동안 * 파괴되지 않고 재창조되지 않는다고 생각합니다. –

+0

@IanGoldby 사실입니다. Windows는 결코'RecreateWnd'를 호출 할 수 없습니다. 이 메서드는 창 핸들을 다시 만들어야 할 때 내부적으로 호출됩니다. VCL 소스 코드는 양식의 핸들을 다시 만들어야 할 상황 (예 :'FormStyle','BorderStyle','BiDiMode','BorderIcons','Position')을 변경해야하는 상황에 깔려 있습니다. 그러나이 모든 경우 , VCL 자체에서 그 일을합니다. –

+0

중요한 것은 외부에서 발생하는 것에 대한 응답이 아닌 개발자의 응용 프로그램 코드 *에 대한 응답으로 VCL을 수행하는 것입니다 (예 : 사용자가 데스크톱 스타일을 변경하는 경우). –