HSP単体では無理でしたが、ChatGPT(無料版)に聞いてDLLを作成したらなんとできてしまいました
以下のC++ソースをVisualStudioのダイナミックリンクライブラリで作成し、
プロパティの「C/C++」の項目から「プリコンパイル済みヘッダーを使用しない」に設定してx86でリリースビルドします
プロジェクトにReleaseというディレクトリが作成されるのでその中のDLLを「OLEDragDrop.dll」にリネームし、HSPのフォルダに入れるだけです
なおC++側のソースは一切理解できていません
・C++
// OLEDragDrop.cpp - HSP3用OLE Drag & Drop DLL
#include <windows.h>
#include <ole2.h>
#include <shobjidl.h>
#include <string>
// HSP3のscreen 0ウィンドウ用グローバル変数
HWND hHspWnd = NULL;
// IDropTargetの実装クラス
class DropTarget : public IDropTarget {
LONG refCount;
public:
DropTarget() : refCount(1) {}
// COM参照カウント
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppv) override {
if (riid == IID_IUnknown || riid == IID_IDropTarget) {
*ppv = static_cast<IDropTarget*>(this);
AddRef();
return S_OK;
}
*ppv = NULL;
return E_NOINTERFACE;
}
ULONG STDMETHODCALLTYPE AddRef() override {
return InterlockedIncrement(&refCount);
}
ULONG STDMETHODCALLTYPE Release() override {
LONG count = InterlockedDecrement(&refCount);
if (count == 0) delete this;
return count;
}
// ドロップされたデータの処理
HRESULT STDMETHODCALLTYPE DragEnter(IDataObject* pDataObj, DWORD, POINTL, DWORD* pdwEffect) override {
*pdwEffect = DROPEFFECT_COPY;
return S_OK;
}
HRESULT STDMETHODCALLTYPE DragOver(DWORD, POINTL, DWORD* pdwEffect) override {
*pdwEffect = DROPEFFECT_COPY;
return S_OK;
}
HRESULT STDMETHODCALLTYPE DragLeave() override {
return S_OK;
}
HRESULT STDMETHODCALLTYPE Drop(IDataObject* pDataObj, DWORD, POINTL, DWORD* pdwEffect) override {
FORMATETC fmt = { CF_UNICODETEXT, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
STGMEDIUM stg;
if (SUCCEEDED(pDataObj->GetData(&fmt, &stg))) {
// データ取得
LPWSTR data = (LPWSTR)GlobalLock(stg.hGlobal);
if (data) {
SendTextToHSP(data);
GlobalUnlock(stg.hGlobal);
}
ReleaseStgMedium(&stg);
}
*pdwEffect = DROPEFFECT_COPY;
return S_OK;
}
void SendTextToHSP(LPCWSTR text) {
if (!hHspWnd) return;
COPYDATASTRUCT cds;
cds.dwData = 1;
cds.cbData = (wcslen(text) + 1) * sizeof(WCHAR);
cds.lpData = (void*)text;
SendMessage(hHspWnd, WM_COPYDATA, (WPARAM)NULL, (LPARAM)&cds);
}
};
// DLL エクスポート関数
extern "C" __declspec(dllexport) BOOL RegisterHSPDrop(HWND hWnd) {
hHspWnd = hWnd;
CoInitialize(NULL);
DropTarget* dt = new DropTarget();
return SUCCEEDED(RegisterDragDrop(hWnd, dt));
}
extern "C" __declspec(dllexport) BOOL UnregisterHSPDrop(HWND hWnd) {
return SUCCEEDED(RevokeDragDrop(hWnd));
}
BOOL APIENTRY DllMain(HMODULE, DWORD ul_reason_for_call, LPVOID) {
if (ul_reason_for_call == DLL_PROCESS_ATTACH) {
CoInitialize(NULL);
}
else if (ul_reason_for_call == DLL_PROCESS_DETACH) {
CoUninitialize();
}
return TRUE;
}
・HSP
// DLLロード
#uselib "OLEDragDrop.dll"
#func RegisterHSPDrop "RegisterHSPDrop" int
#func UnregisterHSPDrop "UnregisterHSPDrop" int
#define WM_COPYDATA 0x004A
*main
screen 0, 640, 480 ; メインウィンドウ
title "OLE Drag & Drop HSP3"
hspWnd = hwnd ; HSP3のウィンドウハンドル取得
// OLE D&Dを登録
RegisterHSPDrop hspWnd
mes stat
// WM_COPYDATAを受け取る
oncmd gosub *on_copydata, WM_COPYDATA
// 終了時にD&Dを解除
onexit *cleanup
stop
*on_copydata
p1 = wparam ; 送信元のハンドル
p2 = lparam ; COPYDATASTRUCT構造体のポインタ
; HSPのメモリ領域にデータをコピー
sdim localData, 12
dupptr localData, p2, 12, 2 ; COPYDATASTRUCTのサイズ(標準は12バイト)
size = lpeek(localData, 4) ; データサイズ取得
textptr = lpeek(localData, 8) ; テキストデータのポインタ
; UTF-16をSJISに変換
sdim test_wide, size*2+1
sdim text, size*2+1
dupptr test_wide,textptr,size,2
text = cnvwtos(test_wide)
mes text
return
*cleanup
UnregisterHSPDrop hspWnd
end