windows9x下点击鼠标时,鼠标点中的窗口得到焦点并激活,原窗口失去焦点并失活,现在我想禁止鼠标将活动窗口设置到本程序的主窗口。如果直接在程序中检测到窗口切换到本窗口后就重新设置原窗口活动,由于许多程序(原窗口)在OnKillFocus与OnSetFocus执行了许多额外操作,所以“失而复得”不能满足我的应用要求。我采用全局钩子也只拦到本窗口设置焦点与激活的消息,并且消息参数中的原焦点窗口是NULL,原活动窗口也是NULL。丢弃这些消息只是本窗口不得到焦点也不激活,但旧窗口已经失去焦点并失活! 我试过鼠标钩子也没有实现。有什么办法让鼠标点击本窗口时本窗口不激活而且旧窗口也不失去焦点呢?

解决方案 »

  1.   

    int CNoFocusDlg::OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT message) 
    {
    return MA_NOACTIVATEANDEAT ;
    }
    处理 WM_MOUSEACTIVATE消息,返回MA_NOACTIVATEANDEAT的结果就可以禁止通过鼠标点击来激活窗口了如果通过任务条也不能激活的话,那就在
    void CNoFocusDlg::OnActivateApp(BOOL bActive, HTASK hTask) 
    {
    HWND hWnd = (HWND)0x330636;
    ::BringWindowToTop( hWnd ); // 不行还可以用SetForeGroudWindow
    // 另外还可以辅助 ShowWindow()
    }
      

  2.   

    to : strip(阿飞)谢谢你!但我应用上面的方法只是使本窗口没激活,还是没有阻止原活动窗口失去焦点并失活,原窗口还是进行了OnKillFocus的额外处理。如果这时我把焦点移回去以保持原窗口为活动窗口,它还会再进行OnSetFocus的额外处理。而这种“失而复得”导致的额外处理才是真正不能满足我的要求的原因,我想让新窗口不激活的同时原窗口根本就不要失去焦点。
      

  3.   

    我没有做试验,但是是否可以通过拦截两个窗口的WM_SETFOCUS和
    WM_KILLFOCUS来实现,比如用PerTranslateMessage()函数。
      

  4.   

    我采用全局钩子也只拦到本窗口设置焦点与激活的消息,并且消息参数中的原焦点窗口是NULL,原活动窗口也是NULL。丢弃这些消息只是本窗口不得到焦点也不激活,但旧窗口已经失去焦点并失活! 我的全局钩子也未拦到原窗口KillFocus,我试过鼠标钩子也没有实现。 
      

  5.   

    返回MA_NOACTIVATE原窗口是不会失去焦点的,就像输入法窗口效果一样.
      

  6.   

    www.programsalon.com,touchweb里有个软键盘窗口,就使用了MA_NOACTIVATE
      

  7.   

    to hello008(paladin):
        谢谢!但我在WINDOWS ME和WINDOWS 2000下都测试过,无论返回MA_NOACTIVATE还是返回MA_NOACTIVATEANDEAT都使本窗口不得到焦点的同时原窗口确实失去了焦点,并且没有窗口显示为活动窗口了。难道是我做错了。
        还感谢你告诉了我一个好的新网址: 编程沙龙www.programsalon.com,不过要成为会员要么提供许多源码要么付款,都需要时间,你能给我touchweb的源码或一个例程吗?   100分不够可开窗口再加,多谢帮忙,不胜感谢 !
      

  8.   

    你在pretranslatemessage函数中检测鼠标消息,如果鼠标位置不在当前窗口区域的话,就不处理此消息。
    你将你要干的事情说出来,或许有比你提的更好的方法,不一定要想你说的
    “有什么办法让鼠标点击本窗口时本窗口不激活而且旧窗口也不失去焦点呢? ”
    那样做
      

  9.   

    只用下面这段就可以达到你的要求啊
    void CNoFocusDlg::OnActivateApp(BOOL bActive, HTASK hTask) 

    HWND hWnd = (HWND)0x330636; 
    ::BringWindowToTop( hWnd ); // 不行还可以用SetForeGroudWindow 
    // 另外还可以辅助 ShowWindow() 
    }第二: w2k和win9x有区别,是吗? (我没有win9x)
      

  10.   

    to : strip(阿飞)     我还是不行 !而且OnActivateApp不见效果 !    你能否将那个CNoFocusDlg工程ZIP后发到我的邮箱[email protected]我再测试一下?    谢谢了!
      

  11.   

    to hello008:
        我参考了你给我介绍的在www.programsalon.com里的touchweb里那个软键盘窗口,就使用了MA_NOACTIVATE而原窗口不失去焦点。
        但我分析后发现,它的焦点切换只在应用程序本身,即切换前后的子窗口都是同一进程的子窗口,其父窗口都是本进程的主窗口,当然没问题。
        若改造成当焦点在外部窗口时点击本窗口,我还没完成,估计本窗口不得到焦点的同时外部窗口也应该是已失去焦点的。
      

  12.   

    我用钩子拦截了WH_CALLWNDPROC,发现在鼠标点击切换窗口的过程中,是原窗口先收到WM_ACTIVATE消息(wParam指示失活),再收到WM_ACTIVATEAPP消息(wParam指示失活),再收到WM_KILLFOCUS消息,然后才是新窗口收到WM_MOUSEACTIVATE消息,如果新窗口对这个消息返回MA_NOACTIVATE或MA_NOACTIVATEANDEAT,则不再有其它消息;如果新窗口对WM_MOUSEACTIVATE消息的处理返回MA_ACTIVATE,则接下来新窗口还收到WM_ACTIVATEAPP消息(wParam指示激活),然后是WM_ACTIVATE消息(wParam指示鼠标激活),然后是WM_SETFOCUS消息。由此看来,在新窗口处理WM_MOUSEACTIVATE消息之前,旧窗口已经处理了WM_KILLFOCUS消息将焦点丢弃,所以对WM_MOUSEACTIVATE返回MA_NOACTIVATEANDEAT,新窗口就不会收到WM_SETFOCUS因而就将使没有窗口拥有焦点了。当然对于旧窗口与新窗口是同一主窗口下的不同子窗口,就另当别论了。更为可恶的是,WH_CALLWNDPROC钩住的消息只能监视,不能修改也不能丢弃,因而没法让原窗口不处理WM_KILLFOCUS消息。诸位大侠如有解,极盼赐教,并万分感谢!
      

  13.   

    今天不行了,..zzzZZZZ..我尽量今天中午发给你