기쁘게도 Windows 10의 UAP앱에선 드래그 앤 드롭 기능을 사용할 수 있다.
그 방법에 대해선 아래 링크에 나와있다.
아주 쉽다.
http://familie-smits.com/development-tips/drag-drop-now-supported-in-universal-apps?hc_location=ufi
그러나 여전히 C++은 찬밥이다. 비러머글. C++샘플 따위 제공하지 않는다.
하지만 짧은 코드이므로 C++로 구현하는것도 전혀 어렵지 않다.
XAML코드는 똑같이 copy & paste해주면 된다.
<Grid Background=”{ThemeResource ApplicationPageBackgroundThemeBrush}”
AllowDrop=”True” DragEnter=”Grid_DragEnter” DragOver=”Grid_DragEnter” Drop=”Grid_Drop”>
<TextBlock x:Name=”DropFromExplorerText” Text=”Drop here a file” VerticalAlignment=”Center” HorizontalAlignment=”Center” Foreground=”Black”/>
</Grid>
간단하다. 빈 그리드 하나 만들어줬고 그 안에 드래그앤드롭으로 받은 파일의 패스를 출력해주기 위한 텍스트블럭을 하나 생성하는 코드다.
그리고 소스코드 부분을 보자.
마우스로 파일을 끌어서 앱위로 진입하는 순간 이벤트가 발생하고 이쪽 핸들러가 호출된다.
void MainPage::Grid_DragEnter(Platform::Object^ sender, Windows::UI::Xaml::DragEventArgs^ e)
{
e->AcceptedOperation = Windows::ApplicationModel::DataTransfer::DataPackageOperation::Copy;
OutputDebugString(L”OnDragEnter\n”);
}
여기서 AcceptedOperation 프로퍼티에 이후 드래그로 끌어온 컨텐트를 어떻게 처리할건지 설정한다.
프로퍼티 설정을 하지 않으면 드래그앤드롭 이벤트는 그대로 버려진다.
AcceptedOperation 프로퍼티에 Windows::ApplicationModel::DataTransfer::DataPackageOperation::Copy를 설정했으므로 이후 아래 핸들러가 호출된다.
void MainPage::Grid_Drop(Platform::Object^ sender, Windows::UI::Xaml::DragEventArgs^ e)
{
Windows::UI::Xaml::DragOperationDeferral^ d = e->GetDeferral();
auto ui = task_continuation_context::use_current();
create_task(e->DataView->GetStorageItemsAsync()).then([this,d,ui](IVectorView<Windows::Storage::IStorageItem^>^ fileList)
{
for each (Windows::Storage::IStorageItem^ f in fileList)
{
DropFromExplorerText->Text = f->Path;
Platform::String^ Msg = DropFromExplorerText->Text + L”\n”;
const WCHAR* wchMsg = Msg->Data();
OutputDebugString(wchMsg);
}
d->Complete();
},ui);
}
Windows::ApplicationModel::DataTransfer::DataPackageView::GetStorageItemsAsync()함수를 호출해서 IVectorView<Windows::Storage::IStorageItem^>객체를 받아와야하는데 비동기 함수다.
C#처럼 await를 할 수 없으니 create_task에다 넣어서 비동기로 처리한다.
람다함수 안의 코드가 드래드앤드롭으로 전달된 파일들이 처리되는 부분이다.
파일목록을 받았으면 Windows::UI::Xaml::DragOperationDeferral::Complete()를 반드시 호출해야한다.
호출하지 않으면…궁금하면 직접 해보시라.
MainPage.xaml.h
MainPage.xam.cpp
그리고 주의사항.
현재 Windows Insider에서 배포되는 Windows 10 Technical Preview의 빌드번호는 10041이다. 그리고 같은 페이지에서 Preview SDK를 다운로드 할 수 있다.
이 SDK는 10041빌드 전용이라고 봐야한다.
현재 10041이후의 빌드에서 SDK를 설치하고 위 코드를 실행하면 빌드는 되지만 ABI선언과 실제 구현된 바이너리가 맞지 않아 스택체크에서 걸리는걸 볼 수 있다. C#버전도 정상작동하지 않는다.
빌드가 올라갈때마다 WinRT API들도 계속 업데이트되고 있는것으로 보인다.
그러니 Windows 10 앱을 개발하고 싶다면 10041빌드를 유지해야한다.