Last active
August 29, 2015 14:06
-
-
Save egtra/7a3ca22888b970a364f1 to your computer and use it in GitHub Desktop.
非同期ドロップ処理フリースレッドマーシャラー + CFSTR_FILEDESCRIPTOR (Windows Forms)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define UNICODE | |
#define _UNICODE | |
#define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1 | |
#define _CRT_SECURE_CPP_OVERLOAD_SECURE_NAMES 1 | |
#define WINVER 0x0600 | |
#define _WIN32_WINNT 0x0600 | |
#include <string.h> | |
#include <Windows.h> | |
#include <ShlObj.h> | |
#using <System.dll> | |
#using <System.Windows.Forms.dll> | |
using namespace System; | |
using namespace System::Diagnostics; | |
using namespace System::IO; | |
using namespace System::Runtime::InteropServices; | |
using namespace System::Threading; | |
using namespace System::Windows::Forms; | |
namespace ComTypes = System::Runtime::InteropServices::ComTypes; | |
namespace NativeTypes | |
{ | |
[ComVisible(true)] | |
[InterfaceTypeAttribute(ComInterfaceType::InterfaceIsIUnknown)] | |
[GuidAttribute("3D8B0590-F691-11d2-8EA9-006097DF5BD4")] | |
public interface class IDataObjectAsyncCapability | |
{ | |
public: | |
void SetAsyncMode([MarshalAs(UnmanagedType::Bool)] bool fDoOpAsync); | |
[returnvalue:MarshalAs(UnmanagedType::Bool)] | |
bool GetAsyncMode(); | |
void StartOperation(ComTypes::IBindCtx^ pbcReserved); | |
[returnvalue:MarshalAs(UnmanagedType::Bool)] | |
bool InOperation(); | |
void EndOperation(HRESULT hResult, ComTypes::IBindCtx^ pbcReserved, DWORD dwEffects); | |
}; | |
} | |
ref class AsyncDataObject : public DataObject, public NativeTypes::IDataObjectAsyncCapability | |
{ | |
public: | |
virtual void SetAsyncMode([MarshalAs(UnmanagedType::Bool)] bool fDoOpAsync) | |
{ | |
if (fDoOpAsync == false) | |
{ | |
throw gcnew ArgumentException(); | |
} | |
} | |
[returnvalue:MarshalAs(UnmanagedType::Bool)] | |
virtual bool GetAsyncMode() | |
{ | |
return true; | |
} | |
virtual void StartOperation(ComTypes::IBindCtx^ /*pbcReserved*/) | |
{ | |
Debug::WriteLine("StartOperation: " + Thread::CurrentThread->ManagedThreadId); | |
Interlocked::Increment(m_inOperationCount); | |
} | |
[returnvalue:MarshalAs(UnmanagedType::Bool)] | |
virtual bool InOperation() | |
{ | |
return m_inOperationCount > 0; | |
} | |
virtual void EndOperation(HRESULT /*hResult*/, ComTypes::IBindCtx^ /*pbcReserved*/, DWORD /*dwEffects*/) | |
{ | |
Debug::WriteLine("EndOperation: " + Thread::CurrentThread->ManagedThreadId); | |
Interlocked::Decrement(m_inOperationCount); | |
} | |
private: | |
int m_inOperationCount = 0; | |
}; | |
DataObject^ GetFileDescriptorAndContent() | |
{ | |
auto dataObj = gcnew AsyncDataObject; | |
auto buffer = gcnew array<BYTE>(sizeof FILEGROUPDESCRIPTOR); | |
pin_ptr<BYTE> p = &buffer[0]; | |
auto fileGroupDescriptor = reinterpret_cast<FILEGROUPDESCRIPTOR*>(p); | |
fileGroupDescriptor->cItems = 1; | |
fileGroupDescriptor->fgd[0].dwFlags = static_cast<DWORD>(FD_PROGRESSUI | FD_UNICODE); | |
wcscpy_s(fileGroupDescriptor->fgd[0].cFileName, L"test.txt"); | |
dataObj->SetData(CFSTR_FILEDESCRIPTOR, gcnew MemoryStream(buffer)); | |
auto data = gcnew array<BYTE> { 'a', 'b', 'c' }; | |
auto content = gcnew MemoryStream; | |
content->Write(data, 0, data->Length); | |
dataObj->SetData(CFSTR_FILECONTENTS, content); | |
return dataObj; | |
} | |
void OnMouseDown(Object^ sender, MouseEventArgs^ e) | |
{ | |
if ((e->Button & MouseButtons::Left) != MouseButtons()) | |
{ | |
Debug::WriteLine("Before DoDragDrop: " + Thread::CurrentThread->ManagedThreadId); | |
safe_cast<Control^>(sender)->DoDragDrop(GetFileDescriptorAndContent(), DragDropEffects::Copy); | |
Debug::WriteLine("After DoDragDrop: " + Thread::CurrentThread->ManagedThreadId); | |
} | |
} | |
[STAThread] | |
int main(array<System::String ^> ^args) | |
{ | |
auto f = gcnew Form; | |
f->MouseDown += gcnew MouseEventHandler(OnMouseDown); | |
Application::Run(f); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment