beginnings of drag and drop #33
1 changed files with 105 additions and 75 deletions
commit
fbbf52af04
|
|
@ -12,27 +12,26 @@ typedef struct userdata {
|
||||||
|
|
||||||
static struct symtbl {
|
static struct symtbl {
|
||||||
void* lib_dwmapi;
|
void* lib_dwmapi;
|
||||||
void *shell32lib;
|
void* shell32lib;
|
||||||
void *ole32lib;
|
void* ole32lib;
|
||||||
void *urlmonlib;
|
void* urlmonlib;
|
||||||
|
|
||||||
MwBool has_drag_and_drop;
|
MwBool has_drag_and_drop;
|
||||||
HRESULT(WINAPI* DwmSetWindowAttribute)(HWND hwnd, DWORD dwAttribute, LPCVOID pvAttribute, DWORD cbAttribute);
|
HRESULT(WINAPI* DwmSetWindowAttribute)(HWND hwnd, DWORD dwAttribute, LPCVOID pvAttribute, DWORD cbAttribute);
|
||||||
UINT (WINAPI *DragQueryFileW)(HDROP hDrop,UINT iFile,LPWSTR lpszFile,UINT cch);
|
UINT(WINAPI* DragQueryFileW)(HDROP hDrop, UINT iFile, LPWSTR lpszFile, UINT cch);
|
||||||
UINT (WINAPI *DragQueryFileA)(HDROP hDrop,UINT iFile,LPSTR lpszFile,UINT cch);
|
UINT(WINAPI* DragQueryFileA)(HDROP hDrop, UINT iFile, LPSTR lpszFile, UINT cch);
|
||||||
void (WINAPI *ReleaseStgMedium)(LPSTGMEDIUM unnamedParam1);
|
void(WINAPI* ReleaseStgMedium)(LPSTGMEDIUM unnamedParam1);
|
||||||
HRESULT (WINAPI *OleInitialize)(LPVOID pvReserved);
|
HRESULT(WINAPI* OleInitialize)(LPVOID pvReserved);
|
||||||
HRESULT (WINAPI *RegisterDragDrop)(HWND hwnd, LPDROPTARGET pDropTarget);
|
HRESULT(WINAPI* RegisterDragDrop)(HWND hwnd, LPDROPTARGET pDropTarget);
|
||||||
HRESULT (WINAPI *FindMimeFromData)(
|
HRESULT(WINAPI* FindMimeFromData)(
|
||||||
LPBC pBC,
|
LPBC pBC,
|
||||||
LPCWSTR pwzUrl,
|
LPCWSTR pwzUrl,
|
||||||
LPVOID pBuffer,
|
LPVOID pBuffer,
|
||||||
DWORD cbSize,
|
DWORD cbSize,
|
||||||
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;
|
||||||
|
|
@ -1078,23 +1077,23 @@ static HRESULT STDMETHODCALLTYPE GDIDT_Drop(IDropTarget* this_, IDataObject* pDa
|
||||||
for(i = 0; i < count; i++) {
|
for(i = 0; i < count; i++) {
|
||||||
wchar_t path[MAX_PATH];
|
wchar_t path[MAX_PATH];
|
||||||
char path_normal[MAX_PATH];
|
char path_normal[MAX_PATH];
|
||||||
char *mime_type_normal;
|
char* mime_type_normal;
|
||||||
wchar_t *mime_type = NULL;
|
wchar_t* mime_type = NULL;
|
||||||
int mime_type_size;
|
int mime_type_size;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
wsymtbl.DragQueryFileW(hDrop, i, path, MAX_PATH);
|
wsymtbl.DragQueryFileW(hDrop, i, path, MAX_PATH);
|
||||||
wsymtbl.DragQueryFileA(hDrop, i, path_normal, MAX_PATH);
|
wsymtbl.DragQueryFileA(hDrop, i, path_normal, MAX_PATH);
|
||||||
hr = wsymtbl.FindMimeFromData( NULL, path, NULL, 0,
|
hr = wsymtbl.FindMimeFromData(NULL, path, NULL, 0,
|
||||||
NULL, FMFD_DEFAULT , &mime_type, 0x0 );
|
NULL, FMFD_DEFAULT, &mime_type, 0x0);
|
||||||
|
|
||||||
mime_type_size = WideCharToMultiByte(CP_ACP, 0, mime_type, -1, NULL, 0, NULL, FALSE);
|
mime_type_size = WideCharToMultiByte(CP_ACP, 0, mime_type, -1, NULL, 0, NULL, FALSE);
|
||||||
mime_type_normal = malloc(sizeof(mime_type_size));
|
mime_type_normal = malloc(sizeof(mime_type_size));
|
||||||
WideCharToMultiByte(CP_ACP, 0, mime_type, -1, mime_type_normal, mime_type_size, NULL, FALSE);
|
WideCharToMultiByte(CP_ACP, 0, mime_type, -1, mime_type_normal, mime_type_size, NULL, FALSE);
|
||||||
|
|
||||||
if(mime_type_size == 0) {
|
if(mime_type_size == 0) {
|
||||||
printf("Error converting mime type to multi-byte: %ld\n",GetLastError());
|
printf("Error converting mime type to multi-byte: %ld\n", GetLastError());
|
||||||
} else {
|
} else {
|
||||||
if(self->handle->common.known_mime_types) {
|
if(self->handle->common.known_mime_types) {
|
||||||
for(n = 0; n < arrlen(self->handle->common.known_mime_types); n++) {
|
for(n = 0; n < arrlen(self->handle->common.known_mime_types); n++) {
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue