|
分類:[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
|