部分内容需要参考上面的,为Edit框右键菜单添加新项
和设置Edit窗口一样,也需要设置一个窗口过程钩子来截获WM_CONTEXTMENU消息,不过设置的窗口过程有所不同。新的窗口过程如下:
LRESULT CALLBACK IEWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
HOOKSHARED *hkShared;
HANDLE hMapObject;
WNDPROC oldWndProc = (WNDPROC)::GetProp(hWnd, ADPISA_oldProc);
hkShared = HooKGetSharedMem(&hMapObject);
if( uMsg == hkShared->uIEDoPaste )
{
POINT pt;
pt.y = HIWORD( lParam );
pt.x = LOWORD( lParam );
IEDoPaste(hWnd,pt);
}
HooKReleaseSharedMem(hkShared,hMapObject);
switch(uMsg)
{
case WM_CONTEXTMENU:
{
// 在右键弹出时,判断是否为Input框,主要函数GetDocInterface(hWnd)得到IHTMLDocment2接口,然后调用IsInputEdit函数判断
POINT pt;
pt.x = GET_X_LPARAM(lParam);
pt.y = GET_Y_LPARAM(lParam);
PPT = pt;
CoInitialize( NULL );
IHTMLDocument2* pDoc = GetDocInterface(hWnd);
ScreenToClient(hWnd,&pt);
if( IsInputEdit( pDoc, pt) )
bIsEdit = true;
CoUninitialize();
return CallWindowProc(oldWndProc, hWnd, uMsg, wParam, lParam);
}
case WM_INITMENUPOPUP:
{
// 在初始化菜单时,添加新的项
HOOKSHARED *hkShared;
HANDLE hMapObject;
hkShared=HooKGetSharedMem(&hMapObject);
HWND hHost = FindWindow(hkShared->lpHostClassName,hkShared->lpHostWindowText);
HooKReleaseSharedMem(hkShared,hMapObject);
if(!hHost)
{
// 如果主程序已经退出,则删除添加的菜单项,恢复其窗口过程
if( nInsert && bIsEdit)
{
HMENU hMenu = ( HMENU )wParam;
nInsert --;
RemoveMenu( hMenu, GetMenuItemCount( hMenu ) - 1, MF_BYPOSITION );
RemoveMenu( hMenu, GetMenuItemCount( hMenu ) - 1, MF_BYPOSITION );
RemoveMenu( hMenu, GetMenuItemCount( hMenu ) - 1, MF_BYPOSITION );
RemoveMenu( hMenu, GetMenuItemCount( hMenu ) - 1, MF_BYPOSITION );
RemoveMenu( hMenu, GetMenuItemCount( hMenu ) - 1, MF_BYPOSITION );
RemoveMenu( hMenu, GetMenuItemCount( hMenu ) - 1, MF_BYPOSITION );
}
SetWindowLong(hWnd, GWL_WNDPROC,(DWORD)(ULONG)oldWndProc);
RemoveProp(hWnd, ADPISA_oldProc);
// FreeLibrary( GetModuleHandle( lpModuleFileName) );
return CallWindowProc(oldWndProc, hWnd, uMsg, wParam, lParam);
}
HMENU hmenuChart = CreatePopupMenu();
if( nInsert == 0 && bIsEdit)
{ //添加菜单项
nInsert ++;
AppendMenu( ( HMENU )wParam, MF_SEPARATOR , (UINT) hmenuChart, "" );
AppendMenu((HMENU)wParam, MF_STRING , (UINT) hmenuChart, "加密(&E)");
AppendMenu((HMENU)wParam, MF_STRING , (UINT) hmenuChart, "签名(&S)");
AppendMenu((HMENU)wParam, MF_STRING , (UINT) hmenuChart, "加密签名");
AppendMenu((HMENU)wParam, MF_SEPARATOR , (UINT) hmenuChart, "");
AppendMenu((HMENU)wParam, MF_STRING , (UINT) hmenuChart, "解密(&J)");
}
return CallWindowProc(oldWndProc, hWnd, uMsg, wParam, lParam);
}
case WM_ENTERMENULOOP:
bMenuloop = true;
return CallWindowProc(oldWndProc, hWnd, uMsg, wParam, lParam);
case WM_EXITMENULOOP:
bMenuloop = false;
bIsEdit = false;
return CallWindowProc(oldWndProc, hWnd, uMsg, wParam, lParam);
case WM_MENUSELECT:
{
HMENU hMenu = (HMENU)lParam;
if( HIWORD( wParam ) != 0xFFFF && hMenu != NULL )
{
int count = GetMenuItemCount(hMenu);
GetMenuItemRect(NULL,hMenu,count - 5,&(rectMenu[0]));
GetMenuItemRect(NULL,hMenu,count - 4,&(rectMenu[1]));
GetMenuItemRect(NULL,hMenu,count - 3,&(rectMenu[2]));
GetMenuItemRect(NULL,hMenu,count - 1,&(rectMenu[3]));
}
return CallWindowProc(oldWndProc, hWnd, uMsg, wParam, lParam);
}
case WM_LOADLIB:
{
HMODULE hmod = ::LoadLibraryA(lpModuleFileName);
if(!hmod)
{
SetWindowLong(hWnd, GWL_WNDPROC,(DWORD)(ULONG)oldWndProc);
RemoveProp(hWnd, ADPISA_oldProc);
}
return 0L;
}
default:
return CallWindowProc(oldWndProc, hWnd, uMsg, wParam, lParam);
}
}
另外,需要设置一个鼠标钩子,用来判断鼠标点的区域是否为点中了菜单。因为IE窗口内并没有COMMAND消息...也许有别的实现方法,不过我目前只知道如此
hkSharedInit->g_hMOUSEHook = SetWindowsHookEx(WH_MOUSE, IEMouseProc, g_hinstDll, 0);
鼠标钩子过程函数如下
LRESULT CALLBACK IEMouseProc( int nCode, WPARAM wParam, LPARAM lParam )
{
BOOL bStartingCR = false;
HOOKSHARED *hkShared;
HHOOK hMouseProc;
HANDLE hMapObject;
HWND hCurWnd;
hkShared = HooKGetSharedMem(&hMapObject);
hMouseProc = hkShared->g_hMOUSEHook;
hCurWnd = ADPISAhkReadCurrentFocus();
if( nCode == HC_ACTION )
{
if( wParam == WM_LBUTTONDOWN && bMenuloop && bIsEdit )
{
POINT pt = ((PMOUSEHOOKSTRUCT)lParam)->pt;
if( hCurWnd )
{ //分别来判断鼠标是否点中每个菜单,并响应函数
if( PtInRect( &rectMenu[0],pt ) )
{
PostMessage(hkShared->g_HostWnd,hkShared->uMsgEncrypt,(WPARAM)hCurWnd,( PPT.y << 16 ) + PPT.x);
}
else if( PtInRect( &rectMenu[1],pt ) )
{
PostMessage(hkShared->g_HostWnd,hkShared->uMsgSign,(WPARAM)hCurWnd,( PPT.y << 16 ) + PPT.x);
}
else if( PtInRect( &rectMenu[2],pt ) )
{
PostMessage(hkShared->g_HostWnd,hkShared->uMsgEnSign,(WPARAM)hCurWnd,( PPT.y << 16 ) + PPT.x);
}
else if( PtInRect( &rectMenu[3],pt ) )
{
PostMessage(hkShared->g_HostWnd,hkShared->uMsgDecrypt,(WPARAM)hCurWnd,( PPT.y << 16 ) + PPT.x);
}
}
}
}
HooKReleaseSharedMem(hkShared,hMapObject);
return CallNextHookEx(hMouseProc,nCode,wParam,lParam);
}
上面需要的两个函数如下:
IHTMLDocument2* GetDocInterface(HWND hWnd)
{
HINSTANCE hInst = ::LoadLibrary( _T("OLEACC.DLL") );
IHTMLDocument2* pDoc=NULL;
if ( hInst != NULL )
{
if ( hWnd != NULL )
{
CComPtr<IHTMLDocument2> spDoc;
LRESULT lRes;
UINT nMsg = ::RegisterWindowMessage( _T("WM_HTML_GETOBJECT") );
::SendMessageTimeout( hWnd, nMsg, 0L, 0L, SMTO_ABORTIFHUNG, 1000, (DWORD*)&lRes );
LPFNOBJECTFROMLRESULT pfObjectFromLresult = (LPFNOBJECTFROMLRESULT)::GetProcAddress( hInst, _T("ObjectFromLresult") );
if ( pfObjectFromLresult != NULL )
{
HRESULT hr;
hr = (*pfObjectFromLresult)( lRes, IID_IHTMLDocument, 0, (void**)&spDoc );
if ( SUCCEEDED(hr) )
{
CComPtr<IDispatch> spDisp;
CComQIPtr<IHTMLWindow2> spWin;
spDoc->get_Script( &spDisp );
spWin = spDisp;
spWin->get_document( &spDoc.p );
spWin->get_document( &pDoc );
CComQIPtr<IServiceProvider> isp = pDoc;
CComQIPtr<IWebBrowser2> iwb2;
isp->QueryService(IID_IWebBrowserApp,IID_IWebBrowser2, (void**)&iwb2);
}
}
} // else Internet Explorer is not running
::FreeLibrary( hInst );
} // else Active Accessibility is not installed
else //如果没有安装MSAA
MessageBox(NULL,_T("请您安装Microsoft Active Accessibility"),"错误",MB_OK);
return pDoc;
}
bool IsInputEdit(IHTMLDocument2* pDoc,POINT pt)
{
if( pDoc == NULL )
return false;
CComPtr<IHTMLElement> pElement;
// ClientToScreen();
HRESULT hr=pDoc->elementFromPoint(pt.x,pt.y,&pElement);//取得鼠标所在的元素
bool isEdit = false;
if(SUCCEEDED(hr))
{
CComPtr<IHTMLInputTextElement> pTextElement;
hr=pElement->QueryInterface( IID_IHTMLInputTextElement, (void**)&pTextElement );
//是否有表单输入元素
if(SUCCEEDED(hr))
{
CComBSTR type;
hr=pTextElement->get_type(&type);
if( type ==_T("password") || type ==_T("text") )
isEdit = true;
}
else
{
CComPtr<IHTMLTextAreaElement> pAreaElement;
hr = pElement->QueryInterface(IID_IHTMLTextAreaElement, (void**)&pAreaElement);
if( SUCCEEDED( hr ) )
isEdit = true;
}
}
if( isEdit )
return true;
else return false;
}