2009-08-24 6 views
15

내 응용 프로그램 내에서 다른 스레드의 대화 상자에 메시지를 보내려고합니다. 대화 상자에 std :: exception 파생 클래스 참조를 전달하려고합니다. 이 같은PostMessage를 통해 문자열을 보내는 방법은 무엇입니까?

뭔가 :

try { 
     //do stuff 
} 
catch (MyException& the_exception) { 
    PostMessage(MyhWnd, CWM_SOME_ERROR, 0, 0); //send the_exception or the_exception.error_string() here 
} 

내가, the_exception.error_string()

LPARAM CMyDlg::SomeError(WPARAM, LPARAM) 
{ 
    show_error(????? 
    return 0; 
} 

도 괜찮을 것 PostMessage를를 사용하여 std::string the_exception.error_string() 전달에 오류를 내 대화 상자에서 메시지를 수신하고 보여주고 싶은 추측.

답변

12

문자열이 스택의 스레드 로컬 일 가능성이 있으므로 PostMessage에서 문자열의 주소를 전달할 수 없습니다. 다른 스레드가 그것을 집어들 때까지, 그것은 파괴되었을 수있었습니다.

대신 new를 통해 새 문자열 또는 예외 객체를 만들고 해당 주소를 다른 스레드 (PostMessage의 WPARAM 또는 LPARAM 매개 변수를 통해 전달)에 전달해야합니다. 그러면 다른 스레드가 객체를 소유하고이를 파괴 할 책임이 있습니다. 주위에 당신은 단순히 저장할 수 메시지를 게시 한 후

try 
{ 
    //do stuff 
} 
catch (MyException& the_exception) 
{ 
    PostMessage(MyhWnd, CWM_SOME_ERROR, 0, new string(the_exception.error_string)); 
} 


LPARAM CMyDlg::SomeError(WPARAM, LPARAM lParam) 
{ 
    // Put in shared_ptr so it is automatically destroyed. 
    shared_ptr<string> msg = reinterpret_cast<string*>(lParam); 

    // Do stuff with message 

    return 0; 
} 
+1

안녕하세요, 답장을 보내 주셔서 감사합니다. LPARAM에 캐스트를 잊어 버렸습니다. PostMessage (MyhWnd, CWM_SOME_ERROR, 0, reinterpret_cast (새 문자열 (the_exception.error_string)))); 대신 auto_ptr을 사용하는 방법 : std :: auto_ptr msg (reinterpret_cast (lParam)); 소유권 이전을 나타내므로 – rec

+0

서식이 잘못되었습니다. 줄 바꿈 테스트 줄 바꿈 테스트 – rec

+1

메모리 누수가 아닙니까? 새 문자열()을 어디에서 파기하고 있습니까? –

1

프로세스 내에서 void * 포인터를 전달하고 개체 수명에 대한주의 만 있으면됩니다.

SendMessage가 void * cast로 LPARAM에 전달할 수 있으며 클라이언트는 문자열 유형으로 다시 캐스팅합니다. sendMessage 첨부가 synchronous이기 때문에, 당신은 안전하다 :

지정된 윈도우가 에 의해 호출 스레드, 창 절차가 서브 루틴으로 즉시 호출을 만든 경우

. 지정한 창 이 다른 스레드에 의해 생성 된 경우 시스템이 해당 스레드로 전환하고 이 해당 창 절차를 호출합니다. 스레드간에 전송 된 메시지는 수신 스레드가 메시지 검색 코드를 실행할 때만 처리됩니다. 에 문자열의 복사본을 만들 : 송신 스레드는 수신 스레드 때까지 프로세스 메시지

당신이 다음 호출이 비동기이기 때문에 오프 명시 적으로 손을해야 할 것이다 PostMessage를 사용하려는 경우를 을 차단 힙과 PostMessage를 호출하여 삭제 책임을 대화 (대화 상자)에 전달했습니다.

프로세스가 종료되면 (MyhWnd는 다른 프로세스에 속함) 전체적으로 다른 이야기이며 메시지를 전역 원자와 같은 것으로 마샬링해야합니다.

+0

좋습니다, 집에 갈 시간입니다. 나는 OP가 SendMessage에 대해 묻는 것처럼 대답했고, 요점은 그것이 PostMessage ... –

+1

SendMessage가 동기적이고 소유권 이전에 대해 걱정할 필요가 없다는 것을 지적하는 것이 좋습니다.그러나 SendMessage는 재진입 가능합니다. 즉, SendMessage에 대한 호출 중에 스레드가 메시지를 펌핑 할 수 있으므로 다른 스레드로 전달하는 것이 wndprocs 내에서 돌연변이 될 수 없도록주의해야합니다. – Michael

+0

IMO 정답입니다 : SendMessage를 사용하고 수신 스레드에서 메시지를 가져올 때 메시지를 복사하십시오. 간단한 문자열 패스 (나는 짧은 것으로 추정되는 문자열)에 대해 복잡한 PostMessage/동기화 문제로 폭탄을 설치할 필요가 없습니다. – Roel

0

을만큼 당신이 당신의 창 (또는 CMyDlg의 인스턴스가) 계속 될 것이라고 알고 : 여기

는이 작업을 수행 할 수있는 방법을 보여 일부 샘플 코드 멤버 변수의 오류 문자열을 메시지 처리기에서 읽습니다.