Addin.cpp
上传用户:tao_1987
上传日期:2019-03-05
资源大小:16k
文件大小:2k
- // Addin.cpp : Implementation of CAddin
- #include "stdafx.h"
- #include "WordSpy.h"
- #include "Addin.h"
- /////////////////////////////////////////////////////////////////////////////
- // CAddin
- BYTE jmp[5]={0};//保存长跳转指令
- BYTE enter[5]={0};//保存DoDragDrop函数的入口指令
- PFNQueryContinueDrag pfnQueryContinueDrag=NULL;
- PFNDoDragDrop pfnDoDragDrop=NULL;
- HANDLE hProcess=NULL;
- HWND hDropWindow=NULL;
- DWORD WINAPI MsgThread(LPVOID para)
- {
- return MessageBox(NULL,_T("禁止拖放内容到Word文档窗口外"),_T("警告"),MB_ICONSTOP);
- }
- HRESULT WINAPI MyQueryContinueDrag(IDropSource *This,BOOL fEscapePressed,DWORD grfKeyState)
- {
- HRESULT hRes=DRAGDROP_S_CANCEL;
-
- //查看当前鼠标位置的窗口句柄
- POINT pt;
- GetCursorPos(&pt);
- //如果不是文档窗口就不允许拖放,将它Cancel掉
- if(WindowFromPoint(pt)==hDropWindow)
- hRes=pfnQueryContinueDrag(This,fEscapePressed,grfKeyState);
- else
- {
- //启一个线程来显示MessageBox,
- //因为直接调用MessageBox会导致主线程消息循环阻塞,程序死锁!
- CreateThread(NULL,256,MsgThread,NULL,0,NULL);
- }
-
- return hRes;
- }
- HRESULT WINAPI MyDoDragDrop(IDataObject * pDataObject,IDropSource * pDropSource,DWORD dwOKEffect,DWORD * pdwEffect)
- {
- HRESULT hRet=S_FALSE;
- IDropSourceVtbl *pVtbl=*(IDropSourceVtbl**)pDropSource;
- //如果Vtbl中的QueryContinueDrag函数指针没有指向我们的函数
- if((pVtbl->QueryContinueDrag!=&MyQueryContinueDrag))
- {
- //保存真正的QueryContinueDrag函数的地址
- pfnQueryContinueDrag=pVtbl->QueryContinueDrag;
- //虚函数表项为常量(编译时确定),所以我们要修改它的属性
- DWORD dwOld=0;
- VirtualProtect(&pVtbl->QueryContinueDrag,4,PAGE_READWRITE,&dwOld);
- //让它指向我们的函数
- *(&pVtbl->QueryContinueDrag)=&MyQueryContinueDrag;
- VirtualProtect(&pVtbl->QueryContinueDrag,4,dwOld,NULL);//改回表项属性为常量
- }
- //调用DoDragDrop时鼠标通常在当前的文档窗口上,
- //记录窗口的句柄,以备MyQueryContinueDrag中比较用
- POINT pt;
- GetCursorPos(&pt);
- hDropWindow=WindowFromPoint(pt);
-
- memcpy((LPVOID)pfnDoDragDrop,enter,5);//写回DoDragDrop的前5个字节的指令
- FlushInstructionCache(hProcess,(LPVOID)pfnDoDragDrop,5);//刷新指令cache中相关地址指令的内容
- //调用DoDragDrop实现拖放功能
- hRet=DoDragDrop(pDataObject,pDropSource,dwOKEffect,pdwEffect);
-
- memcpy((LPVOID)pfnDoDragDrop,jmp,5);//写回长跳转指令到DoDragDrop的前5个字节
- FlushInstructionCache(hProcess,(LPVOID)pfnDoDragDrop,5);//刷新指令cache中相关地址指令的内容
- return hRet;
- }