2010-05-19 6 views
1

응용 프로그램에서 MainForm이 아닌 양식으로 Windows 메시지를 보내려면 어떻게해야합니까? 아래 코드를 사용하면 액세스 위반이 발생합니다.비 주 양식으로 창 메시지를 보내는 방법

procedure TMainForm.SendMessageToAnotherForm; 
begin 
    SendMessage(MyForm.Handle,WM_MY_MESSAGE,0,0); 
end; 

MyForm은 이미 만들어져 있으며 최상위 창입니다.

편집 : 또한 PostMessage를 시도했지만 동일한 액세스 위반이 발생하고 WM_MY_MESSAGE가 유효합니다. 다른 위치에서 MainForm과 통신하기 때문에 유효합니다.

+0

SendMessage 또는 PostMessage를 사용하여 모든 양식 또는 Windows 컨트롤에 메시지를 보낼 수 있습니다. 위의 코드는 WM_MY_MESSAGE 값이 정확하고 메시지가 MyForm에서 올바르게 처리되면 정확합니다. – kludg

+2

"액세스 위반을 제공합니다"는 액세스 위반 및 주소를 알지 못하면 의미가 없습니다. 그것은 "내 차가 더 이상 정보 없이는 의미없는 우스운 소리를 냈다"는 것과 같습니다. –

답변

7

위의 코드로 액세스 위반을 얻는 가장 큰 이유는 MyForm = nil 또는 와일드 포인터입니다. SendMessage 호출로 코드 줄에 중단 점을 설정하고 확인하십시오. MyForm이 유효한 참조 인 경우 액세스 위반은 MyForm의 메시지 처리로 인해 발생합니다.

2

메시지가 처리 될 때까지 SendMessage이 대기한다는 것을 알고 있습니까? 즉, 대상 창의 메시지 대기열이 메시지를 처리 ​​할 수 ​​있어야합니다.

이벤트 처리기 (ButtonClick 등)에서이 메서드를 호출하면 PostMessage을 사용하는 것이 좋습니다.

+0

대상 창이 메시지를 보내는 코드와 동일한 스레드 컨텍스트에있는 경우 (UI 이벤트 핸들러가 다른 UI 창으로 메시지를 보낼 때 VCL 환경의 경우) 메시지 대기열이 사용되지 않고, 대상 윈도우의 메시지 프로 시저가 직접 호출됩니다. SendMessage()를 이벤트 핸들러에서 사용할 수 없으면 깨질 수있는 VCL의 내부에 SendMessage()에 대한 많은 호출이 있습니다. –

+0

@Remy : 나는 그것을 몰랐다. 정보 주셔서 감사합니다. –

+0

이 동작은 SendMessage() 설명서의 : "호출하는 스레드가 지정한 창을 만든 경우 해당 창 프로 시저가 서브 루틴으로 즉시 호출됩니다. 지정된 창을 다른 스레드에서 만든 경우 시스템은 해당 스레드로 전환합니다 적절한 창 프로 시저를 호출합니다. 스레드간에 전송 된 메시지는 수신 스레드가 메시지 검색 코드를 실행할 때만 처리됩니다. " –

관련 문제