Microsoft MVP성태의 닷넷 이야기
COM 개체 관련: 13. 비동기 Drag & Drop 구현 : IAsyncOperation [링크 복사], [링크+제목 복사],
조회: 21611
글쓴 사람
정성태 (techsharer at outlook.com)
홈페이지
첨부 파일
 

보통 Drag & Drop을 구현하면 동기방식으로 구현을 하게 되지요. 반면에, 탐색기를 살펴보게 되면 비동기로 파일 이동/복사가 되는 것을 확인할 수 있습니다.

해당 기능을 구현하기 위한 관련 토픽은 다음과 같습니다.

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/shell/programmersguide/shell_basics/shell_basics_programming/transferring/datascenarios.asp

예제 코드만 없을 뿐... 위의 문서대로 하시면 어렵지 않게 구현하실 수 있습니다.
하지만, 역시 스레드 사용으로 인해 COM 개체와 연관되는 경우라면 마샬링을 해야 하는 불편함이 따르게 되는군요.

암튼.... 순서는 이렇습니다.

Source 측에서 먼저 시작.

1. 구현하신 IDataObject 인터페이스 클래스에 IAsyncOperation을 상속받으세요.
2. 물론, IDataObject의 QueryInterface에서 IAsyncOperation에 대한 처리도
추가하시고.
3. DoDragDrop 하기 전에, IDataObject 인스턴스의 SetAsyncMode(TRUE);를
호출.
4. SetAsyncMode는 다음과 같이 간단하게 구현.
    virtual HRESULT STDMETHODCALLTYPE SetAsyncMode(
        /* [in] */ BOOL fDoOpAsync)
 {
  m_bAsyncInOperation = FALSE;
  m_bAsyncMode = fDoOpAsync;
  return S_OK;
 }
5. DoDragDrop 호출.

이젠 제어권이 Drop 쪽으로 넘어갑니다.

6. DragEnter에서 pDataObject 인자를 보관.
7. OnDrop에서
 CComQIPtr<IAsyncOperation> pAsync = m_pDataObject;
 if ( pAsync != NULL )
 {
  BOOL bAsync = FALSE;
  pAsync->GetAsyncMode( &bAsync );

  if ( bAsync == TRUE )
  {
   pAsync->StartOperation( NULL ); // 이 부분에서 순간 긴장. 인자형식이
IBindCtx인데, 다행히 아직 미구현. 무조건 NULL
   ThreadStart(); // 스레드 시작.
   return TRUE;
  }
 }

비동기 지원함을 알게 된 Drop 쪽에서 스레드 시작하고 바로 리턴.

다시 제어권이 Source 쪽으로 넘어갑니다. 즉, DoDragDrop을 호출했던 바로 다음
라인으로 가겠죠.
동기 처리인 경우, DoDragDrop 호출 후 IDataObject와 IDragSource를 바로
Release 할 텐데.
비동기인 경우에는 그래선 안되죠.

8. 인터페이스 해제 보류
       BOOL bDoing;
       pDragObj->InOperation( &bDoing );
       if ( bDoing == TRUE )
       {
       } else {
        pDragSrc->Release();
        pDragObj->Release();
       }

위와 같은 형식으로 처리를 하고 리턴해야 합니다.
그럼, 언제 IDataObject와 IDragSouce를 해제해 주느냐?
다시 순서를 ThreadStart 쪽으로 옮겨 보겠습니다.

9. 스레드에서.
void Threadstart()
{
   ; 데이터 추출 호출 측에서 pDragSrc와 pDataObj에 대해서 아직 Release를
안했으므로,
   ; 여전히 DragEnter에서 받아들였던 IDataObject 인스턴스는 유효하게
됩니다.
   // 데이터 추출

   ; 마지막에 반드시 호출
    pAsync->EndOperation( S_OK, NULL, 0 );
}


다시... 호출 측의 IDataObject로 가서. IAsyncOperation::EndOperation이
호출되어져서.
10. EndOperation에서 IDataSource와 IDataObject를 Release해 줍니다.

비동기 처리가 항상 그렇듯이... 실제 구현하면서 처리해야 할 것들이 아마 제법
늘어날 것입니다.








[최초 등록일: ]
[최종 수정일: 7/5/2021]

Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
by SeongTae Jeong, mailto:techsharer at outlook.com

비밀번호

댓글 작성자
 




... 106  107  [108]  109  110  111  112  113  114  115  116  117  118  119  120  ...
NoWriterDateCnt.TitleFile(s)
11224정성태6/13/201718145.NET Framework: 661. Json.NET의 DeserializeObject 수행 시 속성 이름을 동적으로 바꾸는 방법파일 다운로드1
11223정성태6/12/201716830개발 환경 구성: 318. WCF Service Application과 WCFTestClient.exe
11222정성태6/10/201720552오류 유형: 399. WCF - A property with the name 'UriTemplateMatchResults' already exists.파일 다운로드1
11221정성태6/10/201717519오류 유형: 398. Fakes - Assembly 'Jennifer5.Fakes' with identity '[...].Fakes, [...]' uses '[...]' which has a higher version than referenced assembly '[...]' with identity '[...]'
11220정성태6/10/201722908.NET Framework: 660. Shallow Copy와 Deep Copy [1]파일 다운로드2
11219정성태6/7/201718218.NET Framework: 659. 닷넷 - TypeForwardedFrom / TypeForwardedTo 특성의 사용법
11218정성태6/1/201721021개발 환경 구성: 317. Hyper-V 내의 VM에서 다시 Hyper-V를 설치: Nested Virtualization
11217정성태6/1/201716914오류 유형: 397. initerrlog: Could not open error log file 'C:\...\MSSQL12.MSSQLSERVER\MSSQL\Log\ERRORLOG'
11216정성태6/1/201719022오류 유형: 396. Activation context generation failed
11215정성태6/1/201719959오류 유형: 395. 관리 콘솔을 실행하면 "This app has been blocked for your protection" 오류 발생 [1]
11214정성태6/1/201717697오류 유형: 394. MSDTC 서비스 시작 시 -1073737712(0xC0001010) 오류와 함께 종료되는 문제 [1]
11213정성태5/26/201722481오류 유형: 393. TFS - The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel.
11212정성태5/26/201721818오류 유형: 392. Windows Server 2016에 KB4019472 업데이트가 실패하는 경우
11211정성태5/26/201720856오류 유형: 391. BeginInvoke에 전달한 람다 함수에 CS1660 에러가 발생하는 경우
11210정성태5/25/201721300기타: 65. ActiveX 없는 전자 메일에 사용된 "개인정보 보호를 위해 암호화된 보안메일"의 암호화 방법
11209정성태5/25/201768220Windows: 143. Windows 10의 Recovery 파티션을 삭제 및 새로 생성하는 방법 [16]
11208정성태5/25/201727945오류 유형: 390. diskpart의 set id 명령어에서 "The specified type is not in the correct format." 오류 발생
11207정성태5/24/201728260Windows: 142. Windows 10의 복구 콘솔로 부팅하는 방법
11206정성태5/24/201721552오류 유형: 389. DISM.exe - The specified image in the specified wim is already mounted for read/write access.
11205정성태5/24/201721269.NET Framework: 658. C#의 tail call 구현은? [1]
11204정성태5/22/201730807개발 환경 구성: 316. 간단하게 살펴보는 Docker for Windows [7]
11203정성태5/19/201718738오류 유형: 388. docker - Host does not exist: "default"
11202정성태5/19/201719809오류 유형: 387. WPF - There is no registered CultureInfo with the IetfLanguageTag 'ug'.
11201정성태5/16/201722555오류 유형: 386. WPF - .NET 3.5 이하에서 TextBox에 한글 입력 시 TextChanged 이벤트의 비정상 종료 문제 [1]파일 다운로드1
11200정성태5/16/201719331오류 유형: 385. WPF - 폰트가 없어 System.IO.FileNotFoundException 예외가 발생하는 경우
11199정성태5/16/201721155.NET Framework: 657. CultureInfo.GetCultures가 반환하는 값
... 106  107  [108]  109  110  111  112  113  114  115  116  117  118  119  120  ...