beginnings of drag and drop #33

Merged
IoI_xD merged 8 commits from dnd into master 2026-07-23 11:45:02 +09:00
Showing only changes of commit fbbf52af04 - Show all commits

better handling of already-initialized COM
Some checks failed
pyrite-dev/milsko/pipeline/head There was a failure building this commit

IoI_xD 2026-07-22 13:31:19 -07:00

View file

@ -31,8 +31,7 @@ static struct symtbl {
LPCWSTR pwzMimeProposed, LPCWSTR pwzMimeProposed,
DWORD dwMimeFlags, DWORD dwMimeFlags,
LPWSTR* ppwzMimeOut, LPWSTR* ppwzMimeOut,
_Reserved_ DWORD dwReserved _Reserved_ DWORD dwReserved);
);
} wsymtbl; } wsymtbl;
static int is_plgblt_reliable = 0; static int is_plgblt_reliable = 0;
@ -1118,7 +1117,6 @@ static HRESULT STDMETHODCALLTYPE GDIDT_Drop(IDropTarget* this_, IDataObject* pDa
return S_OK; return S_OK;
} }
static IDropTargetVtbl DropTarget_Vtbl = { static IDropTargetVtbl DropTarget_Vtbl = {
GDIDT_QueryInterface, GDIDT_QueryInterface,
GDIDT_AddRef, GDIDT_AddRef,
@ -1149,19 +1147,6 @@ static int MwLLGDICallInitImpl(void) {
void* ntdll; void* ntdll;
HRESULT hr; HRESULT hr;
CoInitialize(NULL);
hr = OleInitialize(NULL);
if(!SUCCEEDED(hr)) {
if(hr == RPC_E_CHANGED_MODE) {
CoUninitialize();
hr = OleInitialize(NULL);
CoInitialize(NULL);
} else {
printf("OleInitialize failed; %08lx\n", hr);
return 1;
}
}
memset(&wsymtbl, 0, sizeof(wsymtbl)); memset(&wsymtbl, 0, sizeof(wsymtbl));
wsymtbl.lib_dwmapi = MwDynamicOpen("dwmapi.dll"); wsymtbl.lib_dwmapi = MwDynamicOpen("dwmapi.dll");
@ -1174,15 +1159,58 @@ static int MwLLGDICallInitImpl(void) {
is_plgblt_reliable = 1; is_plgblt_reliable = 1;
} }
wsymtbl.has_drag_and_drop = MwFALSE;
/* Drag and Drop initialization */
{
hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
/* The only other error - COM already being initialized - can be ignored */
if(hr == RPC_E_CHANGED_MODE) {
goto no_dnd;
}
if(!SUCCEEDED(hr) && hr != S_FALSE) {
printf("CoInitialize error: %08lx\n", hr);
goto dnd_error;
}
hr = OleInitialize(NULL);
if(!SUCCEEDED(hr)) {
if(hr == RPC_E_CHANGED_MODE) {
no_dnd:
printf("Cannot do drag and drop; Microsoft hates you and if you use COM anywhere else it has to be apartment threaded.\n");
goto dnd_error;
} else {
printf("OleInitialize failed; %08lx. Drag and Drop won't be supported.\n", hr);
goto dnd_error;
}
}
wsymtbl.has_drag_and_drop = MwTRUE; wsymtbl.has_drag_and_drop = MwTRUE;
if(!(wsymtbl.shell32lib = LoadLibrary("shell32.dll"))) {goto dnd_error;}; if(!(wsymtbl.shell32lib = LoadLibrary("shell32.dll"))) {
if(!(wsymtbl.ole32lib = LoadLibrary("ole32.dll"))) {goto dnd_error;}; goto dnd_error;
if(!(wsymtbl.urlmonlib = LoadLibrary("Urlmon.dll"))) {goto dnd_error;}; };
if(!(wsymtbl.ole32lib = LoadLibrary("ole32.dll"))) {
goto dnd_error;
};
if(!(wsymtbl.urlmonlib = LoadLibrary("Urlmon.dll"))) {
goto dnd_error;
};
#define SHELL32_FUNC(x) if(!(wsymtbl.x = (void*)GetProcAddress(wsymtbl.shell32lib, #x))) {printf(#x "not found, drag and drop will not be supported"); goto dnd_error;} #define SHELL32_FUNC(x) \
#define OLE32_FUNC(x) if(!(wsymtbl.x = (void*)GetProcAddress(wsymtbl.ole32lib, #x))) {printf(#x "not found, drag and drop will not be supported"); goto dnd_error;} if(!(wsymtbl.x = (void*)GetProcAddress(wsymtbl.shell32lib, #x))) { \
#define URLMON_FUNC(x) if(!(wsymtbl.x = (void*)GetProcAddress(wsymtbl.urlmonlib, #x))) {printf(#x "not found, drag and drop will not be supported"); goto dnd_error;} printf(#x "not found, drag and drop will not be supported"); \
goto dnd_error; \
}
#define OLE32_FUNC(x) \
if(!(wsymtbl.x = (void*)GetProcAddress(wsymtbl.ole32lib, #x))) { \
printf(#x "not found, drag and drop will not be supported"); \
goto dnd_error; \
}
#define URLMON_FUNC(x) \
if(!(wsymtbl.x = (void*)GetProcAddress(wsymtbl.urlmonlib, #x))) { \
printf(#x "not found, drag and drop will not be supported"); \
goto dnd_error; \
}
SHELL32_FUNC(DragQueryFileW); SHELL32_FUNC(DragQueryFileW);
SHELL32_FUNC(DragQueryFileA); SHELL32_FUNC(DragQueryFileA);
@ -1191,7 +1219,9 @@ static int MwLLGDICallInitImpl(void) {
URLMON_FUNC(FindMimeFromData); URLMON_FUNC(FindMimeFromData);
wsymtbl.has_drag_and_drop = MwTRUE; wsymtbl.has_drag_and_drop = MwTRUE;
}
dnd_error: dnd_error:
/* TODO: check properly */ /* TODO: check properly */
return 0; return 0;
} }