Webブラウザ上のリンクを、PCのブラウザにドラッグ&ドロップすると「.urlファイル」が作成されます。
作成される前にWindows側でドラッグ&ドロップした内容を取得していると考えています。
しかし、CreateWindowにて表示したウィンドウには、Webブラウザのリンクをドラッグ&ドロップしようとすると、マウスカーソルが「No」になりドラッグ&ドロップが出来ません。
ドラッグ&ドロップを出来るようにするには、どうすれば良いでしょうか。
CreateWindowsへのドラッグ&ドロップ(ファイルではない)
Re: CreateWindowsへのドラッグ&ドロップ(ファイルではない)
ウィンドウに対してドラッグ & ドロップを有効にするコードは、以下のサイトが参考になると思います。
http://eternalwindows.jp/ole/oledrag/oledrag01.html
ドラッグされてきたオブジェクトの情報が IDropTarget::DragEnter で取得できるので、そのときに何の種類のオブジェクトを許可して、カーソルを何に替えるか、などを決めることができます。
Web ブラウザーからのハイパーリンクの判別方法がちょっと難しいですね。↓ のページ等を参考にしたのですがちゃんと動いてくれないので、もうちょっと調べてみます。その間にどなたか別の方から回答があればいいのですが。
What a drag: Dragging a Uniform Resource Locator (URL) – The Old New Thing
https://blogs.msdn.microsoft.com/oldnew ... 0/?p=23133
c++ - Drag-and-drop from IE 9 into my application - Stack Overflow
http://stackoverflow.com/questions/1447 ... pplication
http://eternalwindows.jp/ole/oledrag/oledrag01.html
ドラッグされてきたオブジェクトの情報が IDropTarget::DragEnter で取得できるので、そのときに何の種類のオブジェクトを許可して、カーソルを何に替えるか、などを決めることができます。
Web ブラウザーからのハイパーリンクの判別方法がちょっと難しいですね。↓ のページ等を参考にしたのですがちゃんと動いてくれないので、もうちょっと調べてみます。その間にどなたか別の方から回答があればいいのですが。
What a drag: Dragging a Uniform Resource Locator (URL) – The Old New Thing
https://blogs.msdn.microsoft.com/oldnew ... 0/?p=23133
c++ - Drag-and-drop from IE 9 into my application - Stack Overflow
http://stackoverflow.com/questions/1447 ... pplication
Re: CreateWindowsへのドラッグ&ドロップ(ファイルではない)
URL の情報が文字列として送られてくることが分かりましたので、以下のコードで、その文字列を MessageBox で表示することができました。
Win10 上の Chrome、Firefox、IE、Edge で動作確認済みです。
ただし IE には追加の考慮が必要です。既定では、IE の保護モードが有効なときにはドラッグ & ドロップが許可されません。
Understanding and Working in Protected Mode Internet Explorer
https://msdn.microsoft.com/en-us/librar ... s.85).aspx
Win10 上の Chrome、Firefox、IE、Edge で動作確認済みです。
#include <windows.h>
#include <atlbase.h>
static WCHAR window_name[] = L"window.drag-n-drop";
const UINT WM_POPUPMSGBOX = WM_USER + 1;
class CDropTarget : public IDropTarget {
private:
const DWORD preferredEffect = DROPEFFECT_LINK;
LONG refcount;
HWND owner;
bool supported;
public:
CDropTarget(HWND hwnd)
: refcount(1), owner(hwnd), supported(false) {}
virtual ~CDropTarget() {}
// IUnknown
STDMETHODIMP_(ULONG) AddRef() {
return InterlockedIncrement(&refcount);
}
STDMETHODIMP_(ULONG) Release() {
if (InterlockedDecrement(&refcount) == 0) {
delete this;
return 0;
}
return refcount;
}
#pragma warning(push)
#pragma warning(disable : 4838)
STDMETHODIMP QueryInterface(REFIID riid, void **ppvObject) {
const QITAB QITable[] = {
QITABENT(CDropTarget, IDropTarget),
{ 0 },
};
return QISearch(this, QITable, riid, ppvObject);
}
#pragma warning(pop)
// IDropTarget
STDMETHODIMP DragEnter(IDataObject *pDataObj,
DWORD grfKeyState,
POINTL pt,
DWORD *pdwEffect) {
FORMATETC formatetc = {};
formatetc.cfFormat = CF_UNICODETEXT;
formatetc.dwAspect = DVASPECT_CONTENT;
formatetc.lindex = -1;
formatetc.tymed = TYMED_HGLOBAL;
if (SUCCEEDED(pDataObj->QueryGetData(&formatetc))) {
supported = true;
*pdwEffect = preferredEffect;
}
else {
supported = false;
*pdwEffect = DROPEFFECT_NONE;
}
return S_OK;
}
STDMETHODIMP DragOver(DWORD grfKeyState,
POINTL pt,
DWORD *pdwEffect) {
*pdwEffect = supported ? preferredEffect : DROPEFFECT_NONE;
return S_OK;
}
STDMETHODIMP DragLeave() {
return S_OK;
}
STDMETHODIMP Drop(IDataObject *pDataObj,
DWORD grfKeyState,
POINTL pt,
DWORD *pdwEffect) {
FORMATETC formatetc = {};
formatetc.cfFormat = CF_UNICODETEXT;
formatetc.ptd = nullptr;
formatetc.dwAspect = DVASPECT_CONTENT;
formatetc.lindex = -1;
formatetc.tymed = TYMED_HGLOBAL;
STGMEDIUM medium = {};
HRESULT hr = pDataObj->GetData(&formatetc, &medium);
if (SUCCEEDED(hr)) {
*pdwEffect = preferredEffect;
LPVOID locked = GlobalLock(medium.hGlobal);
if (locked) {
CComBSTR msg(static_cast<LPCWSTR>(locked));
PostMessage(owner, WM_POPUPMSGBOX, 0, reinterpret_cast<LPARAM>(msg.Detach()));
GlobalUnlock(medium.hGlobal);
}
ReleaseStgMedium(&medium);
}
else {
*pdwEffect = DROPEFFECT_NONE;
}
return hr;
}
};
void OnCreate(HWND hwnd) {
if (SUCCEEDED(OleInitialize(nullptr))) {
CDropTarget *target = new CDropTarget(hwnd);
if (target) {
SetWindowLongPtr(hwnd,
GWLP_USERDATA,
reinterpret_cast<LONG_PTR>(target));
RegisterDragDrop(hwnd, target);
}
}
}
void OnDestroy(HWND hwnd) {
RevokeDragDrop(hwnd);
auto p = GetWindowLongPtr(hwnd, GWLP_USERDATA);
if (p) {
reinterpret_cast<CDropTarget*>(p)->Release();
}
OleUninitialize();
PostQuitMessage(0);
}
void OnPopup(HWND hwnd, LPARAM lParam) {
CComBSTR msg;
msg.Attach(reinterpret_cast<BSTR>(lParam));
MessageBox(hwnd, msg, L"Dropped!", MB_OK);
}
LRESULT CALLBACK WindowProc(HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam) {
switch (uMsg) {
case WM_CREATE:
OnCreate(hwnd);
break;
case WM_DESTROY:
OnDestroy(hwnd);
break;
case WM_POPUPMSGBOX:
OnPopup(hwnd, lParam);
break;
default:
return DefWindowProc(hwnd, uMsg, wParam, lParam);
break;
}
return 0;
}
int WINAPI WinMain(HINSTANCE hinst,
HINSTANCE hinstPrev,
LPSTR lpszCmdLine,
int nCmdShow) {
WNDCLASSEX wc = {};
wc.cbSize = sizeof(WNDCLASSEX);
wc.lpfnWndProc = WindowProc;
wc.hInstance = hinst;
wc.hCursor = LoadCursor(nullptr, IDC_ARROW);
wc.hbrBackground = reinterpret_cast<HBRUSH>(BLACK_BRUSH);
wc.lpszClassName = window_name;
if (RegisterClassEx(&wc)) {
HWND hwnd = CreateWindow(window_name,
window_name,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
400,
150,
/*hWndParent*/nullptr,
/*hMenu*/nullptr,
hinst,
/*lpParam*/nullptr);
if (hwnd) {
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
MSG msg = {};
while (GetMessage(&msg, nullptr, 0, 0) > 0) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}
return 0;
}
Understanding and Working in Protected Mode Internet Explorer
https://msdn.microsoft.com/en-us/librar ... s.85).aspx
IE からのドラッグ & ドロップを有効にするには、許可するためのポリシー設定を exe ファイル毎にレジストリに追加する必要があります。プログラム内から書き込むのがベストですが、とりあえず以下のようなバッチファイルを作ったところ IE でも動きました。Allowing Drag and Drop Operations in your Application
By default, Protected Mode prompts the user before allowing web content to be copied to a higher integrity process.
You can register your application to avoid this prompt and silently accept web content from a drag-and-drop operation by creating a DragDrop policy. DragDrop policies must have a globally unique identifier (GUID) associated with them. Use CreateGuid to create a new GUID for your policy. Next, add a key to the following location.
set SUBKEY=HKLM\SOFTWARE\Microsoft\Internet Explorer\Low Rights\DragDrop
set APPGUID={任意の GUID}
reg add "%SUBKEY%\%APPGUID%" /f /v Policy /t REG_DWORD /d 3
reg add "%SUBKEY%\%APPGUID%" /f /v AppName /t REG_SZ /d your_application.exe
reg add "%SUBKEY%\%APPGUID%" /f /v AppPath /t REG_SZ /d X:\path_to_exe
Re: CreateWindowsへのドラッグ&ドロップ(ファイルではない)
えみさん
ご教示頂き、誠にありがとうございます!!m(_ _*)m
実は、質問書いた後に「IDropTarget」に辿り着き、何とか自力で作成出来ました。すみません。。。
「createWindowに設定するだけで出来ないんかぁぁぁい!!」となりました(汗)
>ただし IE には追加の考慮が必要です。既定では、IE の保護モードが有効なときにはドラッグ & ドロップが許可されません。
なんと!?
私のIEだと出来ていたので、絶対気付けないないようですね・・・。とても助かります。ありがとうございます!!
ご教示頂き、誠にありがとうございます!!m(_ _*)m
実は、質問書いた後に「IDropTarget」に辿り着き、何とか自力で作成出来ました。すみません。。。
「createWindowに設定するだけで出来ないんかぁぁぁい!!」となりました(汗)
>ただし IE には追加の考慮が必要です。既定では、IE の保護モードが有効なときにはドラッグ & ドロップが許可されません。
なんと!?
私のIEだと出来ていたので、絶対気付けないないようですね・・・。とても助かります。ありがとうございます!!