| 
                 分類:[C/C++] 
 
 こんにちは。
IDropTargetを実装した他アプリに対して、
ファイルパスをドロップさせようとしています。
DLL側のIDropTarget::Dropの呼び出しで
IEが落ちるので
この部分に問題ありと見ているのですが、
何が原因なのかが分かりません。
直前のIShellFolder::GetUIObjectOfは
大丈夫だとは思うのですが。
どなたかお分かりになられる方、
宜しくお願いします。
環境
Vista  
Visual C++ 2008 Express Editions 
Excel2007(VBA) 
テストなのでIEを対象にしています。
--- drop.cpp ---
	#include <windows.h> 
	#include <oleidl.h> 
	#include <objidl.h> 
	#include <shobjidl.h>
	#include <shlobj.h>
	#include <string.h>
	
	#pragma data_seg("shared")
	HHOOK g_hHook = NULL;
	#pragma data_seg()
	#pragma comment( lib, "shell32.lib" )
	#pragma comment(linker, "/section:shared,rws")
	HINSTANCE g_hDLL;
	BOOL APIENTRY DllMain( HINSTANCE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved )
	{
	    switch (ul_reason_for_call){
		case DLL_PROCESS_ATTACH:
		    g_hDLL = hModule;
		    break;
		case DLL_THREAD_ATTACH:
		    break;
		case DLL_THREAD_DETACH:
		    break;
		case DLL_PROCESS_DETACH:
		    break;
	    }
	    return TRUE;
	}
	LRESULT CALLBACK DropProc(int nCode, WPARAM wParam, LPARAM lParam)
	{
		MSG *pmsg = (MSG*)lParam; 
	if(nCode == HC_ACTION && pmsg->message == WM_NULL)
	 {
	         
		::UnhookWindowsHookEx(g_hHook);
		::CoInitialize( NULL ); 
		
		IDropTarget *pDrop = (IDropTarget *) ::GetProp(pmsg->hwnd, L"OleDropTargetInterface");
		pDrop->AddRef();
		IShellFolder* pDesktop_Shell;
		IShellFolder* pFolder_Shell;
		IDataObject* pData;
		
	    ITEMIDLIST *Folder_pid1;
	    ITEMIDLIST *File_pid1;
	                        
		::SHGetDesktopFolder(&pDesktop_Shell);
		
		pDesktop_Shell->ParseDisplayName(NULL,NULL, L"C:\\Temp", NULL, &Folder_pid1, NULL); 
					
		pDesktop_Shell->BindToObject(Folder_pid1, NULL, IID_IShellFolder, reinterpret_cast<void **>(&pFolder_Shell)); 
		pDesktop_Shell->Release();
		pFolder_Shell->ParseDisplayName( NULL, NULL, L"Google.html", NULL,  &File_pid1,  NULL); 
		HRESULT hr = pFolder_Shell->GetUIObjectOf( NULL, 1, const_cast<LPCITEMIDLIST *>(&File_pid1), IID_IDataObject, NULL, reinterpret_cast<void **>(&pData)); 
		// 戻り値確認。
		::SetProp (pmsg->hwnd,L"pDrop",(HANDLE)hr);
		::ILFree ( Folder_pid1 );
		::ILFree ( File_pid1 );
		pFolder_Shell->Release();
		POINTL pt;		
		pt.x = 10;
		pt.y = 10;
		pDrop->Drop (pData, MK_LBUTTON, pt, (DWORD *)DROPEFFECT_LINK  );
				
		pDrop->Release();
		
		::CoUninitialize(); 
	 
	 }
	 return ::CallNextHookEx(g_hHook, nCode, wParam, lParam);
	} 
	 
	BOOL WINAPI hookINST(HWND hWnd)
	{
		BOOL foo = true;
		g_hHook = ::SetWindowsHookEx(WH_GETMESSAGE, (HOOKPROC)DropProc, g_hDLL, ::GetWindowThreadProcessId( hWnd, NULL));
	                                         
	    if(g_hHook == NULL)
		{
			foo = false;
		}else{
			::PostMessage(hWnd, WM_NULL, 0, 0);
		}
		return foo;
	}
--- drop.def ---
LIBRARY drop
EXPORTS 
 hookINST @1
--- VBA ---
Option Explicit
Private Declare Function RemoveProp Lib "user32" Alias "RemovePropA" _
        (ByVal hWnd As Long, ByVal lpString As String) As Long
Private Declare Function hookINST Lib "drop" (ByVal hWnd As Long) As Long
Sub hoge()
    Dim objIE As Object
    Dim lngResult As Long
    Dim hWndIE As Long
    ChDrive ThisWorkbook.Path
    ChDir ThisWorkbook.Path
    Set objIE = CreateObject("InternetExplorer.application")
    objIE.Visible = True
    hWndIE = objIE.hWnd
    If hookINST(hWndIE) Then
        lngResult = RemoveProp(hWndIE, "pDrop")
        If lngResult = 0 Then Exit Sub
    End If
End Sub
  |