2008-11-06 4 views
3

끌기 소스로 앱을 구현 중입니다. DoDragDrop (Win32 호출, MFC 아님)을 호출하면 모달 루프가 시작되고 DoDragDrop이 반환 될 때까지 메인 윈도우에 다시 메시지가 표시되지 않습니다. 불행히도 쉘 (파일)에 드롭을하면 파일 이름이 이미 있습니다. 쉘은 파일을 대체 할 것인지 묻습니다. DoDragDrop이 반환하지 않았으므로 응용 프로그램이 차단 되었기 때문에 다시 그리기가되지 않고 '고정'상태가됩니다.DoDragDrop 내에서 UI를 다시 칠하는 방법

실마리가 있습니까?

+0

위대한 질문입니다. NET에 대한 답변이 있지만 Win32에는 대한 답변이 없습니다. : –

답변

1

다른 스레드에서 드래그 앤 드롭 작업을 실행하는 것이 좋습니다. 이렇게하면 DoDragDrop()은 UI 스레드의 메시지 루프가 아닌 새 스레드의 메시지 루프를 차단합니다. 이 방법을 취할 경우에는 (내 머리 위로 떨어져) 고려해야합니다

  1. 메인 스레드와 드래그 앤 드롭 스레드 모두에서 실행할 수있는 코드를 다시해야합니다 참가자. 결과적으로 주 스레드와 끌어서 놓기 스레드에서 사용하는 모든 데이터 구조를 보호해야합니다. 응용 프로그램이 이미 멀티 스레드 인 경우 이러한 우려 사항에 익숙해야합니다.
  2. 사용자가 셸의 대화 상자에 응답하지 않으면 어떻게되는지 생각해야합니다. UI와 계속 상호 작용할 수 있습니까? 보류중인 작업에서 '삭제'된 데이터를 무효화 할 수 있습니까? 그가 당신의 신청서를 종료 할 수 있습니까?
+0

Matthew 당신의 대답은 말이되지 않습니다. 다른 스레드에서 DoDragDrop을 호출 할 수 없습니다. 모달 루프가 프로그램 메인 스레드에 있어야 마우스 이벤트를 얻을 수 있습니다. –

0

진짜 대답은 내 데이터 개체에 IAsyncOperation을 구현하는 것 같습니다.

2

타이머를 사용해 보셨습니까? DoDragDrop()과 같은 문제가 발생하여 SHFileOperation()과 같은 다른 차단 호출이 발생하고 SetTimer()으로 전화하여 해결했습니다.

편집 : DoDragDrop() 이상의 제어를 원하면 작업자 스레드가 잘 작동합니다. 누군가 제안한대로 DoDragDrop()을 작업자 스레드에서 호출 해 볼 수는 있지만 제대로 캡처하려면 마우스 캡처를 가져올 수 없습니다. 보다 쉬운 해결책은 메인 스레드에서 DoDragDrop()으로 호출하여 작업자 스레드가 주기적으로 WM_USER 메시지를 메인 스레드의 큐에 게시하도록하는 것입니다. DoDragDrop()은 메시지를 검색하여 창 WndProc()으로 보내면 대기열이 비어있는 동안 유휴 처리를 수행 할 수 있습니다. 작업자 스레드에 주 스레드보다 낮은 우선 순위를 부여하면 주 스레드가 유휴 상태가되는 즉시 (즉, DoDragDrop()이 모든 사용자 입력을 처리하고 내부적으로 MsgWaitForMultipleObjects()를 호출하는 즉시 WM_USER 메시지를 실행하고 게시합니다) . 이 방법은 응용 프로그램이 CPU를 완벽하게 제어 할 수 있기 때문에 SetTimer() 메서드보다 좋습니다. 다음 WM_TIMER 메시지가 도착하기 전에 WM_TIMER 처리기에서 돌아온 후 최대 10ms (최소 주파수는 SetTimer())까지 기다릴 필요가 없습니다.

관련 문제