Addin.cpp
上传用户:tao_1987
上传日期:2019-03-05
资源大小:16k
文件大小:2k
源码类别:

DNA

开发平台:

C/C++

  1. // Addin.cpp : Implementation of CAddin
  2. #include "stdafx.h"
  3. #include "WordSpy.h"
  4. #include "Addin.h"
  5. /////////////////////////////////////////////////////////////////////////////
  6. // CAddin
  7. BYTE jmp[5]={0};//保存长跳转指令
  8. BYTE enter[5]={0};//保存DoDragDrop函数的入口指令
  9. PFNQueryContinueDrag pfnQueryContinueDrag=NULL;
  10. PFNDoDragDrop pfnDoDragDrop=NULL;
  11. HANDLE hProcess=NULL;
  12. HWND hDropWindow=NULL;
  13. DWORD WINAPI MsgThread(LPVOID para)
  14. {
  15. return MessageBox(NULL,_T("禁止拖放内容到Word文档窗口外"),_T("警告"),MB_ICONSTOP);
  16. }
  17. HRESULT WINAPI MyQueryContinueDrag(IDropSource *This,BOOL fEscapePressed,DWORD grfKeyState)
  18. {
  19. HRESULT hRes=DRAGDROP_S_CANCEL;
  20. //查看当前鼠标位置的窗口句柄
  21. POINT pt;
  22. GetCursorPos(&pt);
  23. //如果不是文档窗口就不允许拖放,将它Cancel掉
  24. if(WindowFromPoint(pt)==hDropWindow)
  25. hRes=pfnQueryContinueDrag(This,fEscapePressed,grfKeyState);
  26. else
  27. {
  28. //启一个线程来显示MessageBox,
  29. //因为直接调用MessageBox会导致主线程消息循环阻塞,程序死锁!
  30. CreateThread(NULL,256,MsgThread,NULL,0,NULL);
  31. }
  32. return hRes;
  33. }
  34. HRESULT WINAPI MyDoDragDrop(IDataObject * pDataObject,IDropSource * pDropSource,DWORD dwOKEffect,DWORD * pdwEffect)
  35. {
  36. HRESULT hRet=S_FALSE;
  37. IDropSourceVtbl *pVtbl=*(IDropSourceVtbl**)pDropSource;
  38. //如果Vtbl中的QueryContinueDrag函数指针没有指向我们的函数
  39. if((pVtbl->QueryContinueDrag!=&MyQueryContinueDrag))
  40. {
  41. //保存真正的QueryContinueDrag函数的地址
  42. pfnQueryContinueDrag=pVtbl->QueryContinueDrag;
  43. //虚函数表项为常量(编译时确定),所以我们要修改它的属性
  44. DWORD dwOld=0;
  45. VirtualProtect(&pVtbl->QueryContinueDrag,4,PAGE_READWRITE,&dwOld);
  46. //让它指向我们的函数
  47. *(&pVtbl->QueryContinueDrag)=&MyQueryContinueDrag;
  48. VirtualProtect(&pVtbl->QueryContinueDrag,4,dwOld,NULL);//改回表项属性为常量
  49. }
  50. //调用DoDragDrop时鼠标通常在当前的文档窗口上,
  51. //记录窗口的句柄,以备MyQueryContinueDrag中比较用
  52. POINT pt;
  53. GetCursorPos(&pt);
  54. hDropWindow=WindowFromPoint(pt);
  55. memcpy((LPVOID)pfnDoDragDrop,enter,5);//写回DoDragDrop的前5个字节的指令
  56. FlushInstructionCache(hProcess,(LPVOID)pfnDoDragDrop,5);//刷新指令cache中相关地址指令的内容
  57. //调用DoDragDrop实现拖放功能
  58. hRet=DoDragDrop(pDataObject,pDropSource,dwOKEffect,pdwEffect);
  59. memcpy((LPVOID)pfnDoDragDrop,jmp,5);//写回长跳转指令到DoDragDrop的前5个字节
  60. FlushInstructionCache(hProcess,(LPVOID)pfnDoDragDrop,5);//刷新指令cache中相关地址指令的内容
  61. return hRet;
  62. }