目前位置: VCer资源中心 >>> VCer代码 >>> Windows界面

[本帖已阅读2298次 分值90 回复0次] 张贴资源 发回信箱 控制面板

给IE窗口的Input框右键菜单加入新的功能

提供者:ISeekYou 张贴时间:2004-05-21 21:46:37.0 出处:vcer.net 作者:不祥

给IE窗口的Input框右键菜单加入新的功能(2004-05-21 21:46:37.0)


那时


 
级别: VCer排长
头衔: VCer会员

经验: 751
作品: 15
分会: 华中分会
注册: 2004-02-09 19:39:54.0
登录: 2008-05-14 10:14:29.0

部分内容需要参考上面的,为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;

}

注:转载文章需注明来源:VCer.net 文章地址:http://vcer.net/2268.html

  如果你觉得VCer.net不错,而且你愿意为VCer.net捐赠一元钱,那么点击后面的捐赠按钮吧:) vcer.net捐赠

[回复该贴] [加入个人书签]
[投票结果]

A: 评分 10 100% (1 票)
B: 评分 5 0% (0 票)
C: 评分 0 0% (0 票)
D: 评分 -5 0% (0 票)
E: 评分 -10 0% (0 票)