跟踪全局鼠标事件以进行拖放处理
可能重复:
从.NET应用程序拖放到资源管理器
在我的应用程序中,需要用户能够从ListView
中的文件拖放到Windows资源管理器。 这些文件位于服务器上,因此我需要下载它们以放置哪个用户点。 为此,我决定设置钩子WH_MOUSE_LL
来跟踪全局鼠标事件,以获取用户放置文件的文件夹句柄,然后使用它获取加载文件的绝对路径。 这里是带HOOK功能的id DLL:
[StructLayout(LayoutKind.Sequential)]
public class MouseHookStruct
{
public POINT pt;
public int hwnd;
public int wHitTestCode;
public int dwExtraInfo;
}
[StructLayout(LayoutKind.Sequential)]
private struct MSLLHOOKSTRUCT
{
public POINT pt;
public uint mouseData;
public uint flags;
public uint time;
public IntPtr dwExtraInfo;
}
private enum MouseMessages
{
WM_LBUTTONDOWN = 0x0201,
WM_LBUTTONUP = 0x0202,
WM_MOUSEMOVE = 0x0200,
WM_MOUSEWHEEL = 0x020A,
WM_RBUTTONDOWN = 0x0204,
WM_RBUTTONUP = 0x0205
}
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern int CallNextHookEx(int idHook, int nCode,
IntPtr wParam, IntPtr lParam);
public int LowLevelMouseProc(int nCode, IntPtr wParam, IntPtr lParam)
{
//Marshall the data from the callback.
//MouseHookStruct MyMouseHookStruct = (MouseHookStruct)Marshal.PtrToStructure(lParam, typeof(MouseHookStruct));
MSLLHOOKSTRUCT MyMouseHookStruct = (MSLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(MSLLHOOKSTRUCT));
if (nCode >= 0 &&
MouseMessages.WM_LBUTTONDOWN == (MouseMessages)wParam)
{
String strCaption = "x = " +
MyMouseHookStruct.pt.x.ToString("d") +
" y = " +
MyMouseHookStruct.pt.y.ToString("d");
//You must get the active form because it is a static function.
Console.WriteLine(strCaption);
}
return CallNextHookEx(hHook, nCode, wParam, lParam);
}
}
}
然后我用SetWindowsHookEx
注册它:
[DllImport("kernel32.dll")]
public static extern IntPtr LoadLibrary(string dllToLoad);
IntPtr pDll = LoadLibrary(@"C:UsersвоваDocumentsvisual studio 2010ProjectsMouseHookMouseHookbinDebugMouseHook.dll");
MouseHookProcedure = new HookProc(msHookObj.LowLevelMouseProc);
hHook = SetWindowsHookEx(WH_MOUSE,
MouseHookProcedure,
pDll,
0);
结果我的应用程序不跟踪全局事件。 请帮忙,我做错了什么?
谢谢
我决定使用你的建议regrding拖放,所以我来使用Shell API。 但我有问题:因为我的文件不在系统中,我不能使用CF_HDROP格式进行传输。 因此,我明白我必须使用CFSTR_FILECONTENTS。
这是我的代码:
public class DataObjectEx :
DataObject, System.Runtime.InteropServices.ComTypes.IDataObject
{
private static readonly TYMED[] ALLOWED_TYMEDS =
new TYMED[] {
TYMED.TYMED_ENHMF,
TYMED.TYMED_GDI,
TYMED.TYMED_HGLOBAL,
TYMED.TYMED_ISTREAM,
TYMED.TYMED_MFPICT};
public void FormDataObject(ListViewItem item)
{
var formatmumber=(Int16)DataFormats.GetFormat(NativeMethods.CFSTR_FILECONTENTS).Id;
//формируем структуру для shell
formatetc = new FORMATETC();
formatetc.cfFormat = formatmumber;
formatetc.ptd = IntPtr.Zero;
formatetc.dwAspect = DVASPECT.DVASPECT_CONTENT;
formatetc.lindex = -1;
formatetc.tymed = TYMED.TYMED_ISTREAM;
//формируем структуру для передачи данных в shell
medium = new STGMEDIUM();
medium.tymed = TYMED.TYMED_ISTREAM;
MemoryStream = GetFileContents(item);
//IStream ob1;
medium.unionmember = Marshal.GetComInterfaceForObject(iStream, typeof(MemoryStream));
//medium.unionmember = iStream;
((System.Runtime.InteropServices.ComTypes.IDataObject)ob).SetData(ref formatetc, ref medium, true);
}
在行中:IStream iStream =(IStream)GetFileContents(item); - 函数GetFileContents(item) - 连接到服务器并发送文件下载请求
public static MemoryStream get_file_Istream(string file_id)
{
string data = "cmd=get_file&id=" + file_id + "&token=" + Token.curent_token;
string Uri = URL.address;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Uri);
request.Method = "POST";
request.AllowAutoRedirect = true;
request.ContentType = "application/x-www-form-urlencoded";
byte[] EncodedPostParams = Encoding.UTF8.GetBytes(data);
request.ContentLength = EncodedPostParams.Length;
request.GetRequestStream().Write(EncodedPostParams, 0, EncodedPostParams.Length);
request.GetRequestStream().Close();
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
MemoryStream mm = new MemoryStream();
response.GetResponseStream().CopyTo(mm);
return mm;
//ResponseStream = response.GetResponseStream();
}
我从来没有做过这样的事情,只是大致了解它是如何工作的。 我收到下一个错误:
传递的类型必须是一个接口。 参数名称:t。 在这一行上:medium.unionmember = Marshal.GetComInterfaceForObject(iStream,typeof(MemoryStream));
- 该方法或操作未执行。 在这一行:((System.Runtime.InteropServices.ComTypes.IDataObject)ob).SetData(ref formatetc,ref medium,true);
从上次错误,据我了解 - 我桅实施方法SetDate,但我没有找到任何信息,我互联网。 至于第一个错误,我认为它与坏参数类型(MemoryStram insted Istream)相关联,
任何人有想法如何解决它们?
Thenaks
链接地址: http://www.djcxy.com/p/61731.html