GetCursorPos VB声明 
Declare Function GetCursorPos Lib "user32" Alias "GetCursorPos" (lpPoint As POINTAPI) As Long 
说明 
获取鼠标指针的当前位置 
返回值 
Long,非零表示成功,零表示失败。会设置GetLastError 
参数表 
参数 类型及说明 
lpPoint POINTAPI,随同指针在屏幕像素坐标中的位置载入的一个结构 

解决方案 »

  1.   

    用 多个 Timer 控件. 不断的判断 鼠标坐标.
      

  2.   

    各位兄弟,用timer控件的话,会占用大量系统资源。我想QQ的实现方法应该不是这样吧。
      

  3.   

    mmyyjj(myj)兄,请帮忙找找好么,兄弟先谢过了!
      

  4.   

    至少我现在没有见过不用Timer控件(包括用API写的 具有类似功能的)实现的
      

  5.   

    可是用Timer控件做不间断扫描的话,真的很耗费系统资源啊
    难道就没有更好一点的方法么?!我记得以前看过好象可以用sendmessage的api 解决这个问题的。可是本人对api的认识仅处于入门阶段,还希望众位多帮帮忙,谢谢拉!~~~~~~``
      

  6.   

    我做了一个类似的,也是用TIMER,不觉得会占用太多系统资源,
      

  7.   

    请问 nebular(星云) :
        你觉得在timer的interval设置多少比较合适?!我的机子不是很牛,是已经列入淘汰之列的PII。:(
    还有,我想在窗体失去最当前位置时,将它隐藏,不知道该如何实现?!
        谢谢大家!
      

  8.   

    Private Declare Function GetCursorPos Lib "user32" (lpPoint As POINTAPI) As Long
    Private Declare Function GetWindowRect Lib "user32" (ByVal hwnd As Long, lpRect As RECT) As Long
    Private Declare Function PtInRect Lib "user32" (lpRect As RECT, ByVal ptx As Long, ByVal pty As Long) As Long
    Private Declare Function SetWindowPos Lib "user32" (ByVal hwnd As Long, ByVal hWndInsertAfter _
        As Long, ByVal X As Long, ByVal Y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long
    Private Declare Function MoveWindow Lib "user32" (ByVal hwnd As Long, ByVal X As Long, _
        ByVal Y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal bRepaint As Long) As LongConst HWND_TOPMOST = -1
     
    Private Type POINTAPI
            X As Long
            Y As Long
    End Type
    Private Type RECT
            Left As Long
            Top As Long
            Right As Long
            Bottom As Long
    End Type
    Private Is_Move_B As Boolean 
    Private Is_Movestar_B As Boolean
    Private MyRect As RECT
    Private MyPoint As POINTAPI
    Private Movex As Long, Movey As Long  
    Private max As Long   
    我想看到这应该差不多了
      

  9.   

    asglw(figo) 兄:
    能否对代码做个说明啊,我对API不怎么了解的。
    先谢过拉!
      

  10.   

    asglw(figo) 提供的API可以實現妳要的功能:GetCursorPos   獲得鼠標指針在屏幕坐標上的位置
    GetWindowRect  獲得窗口在屏幕坐標中的位置
    PtInRect       判斷指定的點是否在指定的巨型內部\
    SetWindowPos   用于實現使窗體始終在最前面
    MoveWindow     用來移動窗體不過妳還要在form中加一個Timer控件用于檢測鼠標
      

  11.   

    没听说过不用Timer的,难道是用HOOK(应该也不行啊)?
      

  12.   

    各位兄弟,我的问题已基本得到解决,在此先谢过大家,特别是asglw(figo) 和thorkhan(灰滿) 两位!
    不过在编码过程中有个问题,就是在使用PtInRect函数时,系统老说“DLL 调用约定错误”,不知道是和缘故?!代码如下:
    Option Explicit
    Private Type POINTAPI
        x As Long
        y As Long
    End TypePrivate Type RECT
        Left As Long
        Top As Long
        Right As Long
        Bottom As Long
    End TypePrivate Declare Function GetCursorPos Lib "user32" (lpPoint As POINTAPI) As Long
    Private Declare Function GetWindowRect Lib "user32" (ByVal hwnd As Long, lpRect As RECT) As Long
    Public Declare Function PtInRect Lib "user32" (lpRect As RECT, pt As POINTAPI) As LongPublic Sub ShowCursorPos()
        Dim t As POINTAPI
        Dim t1 As RECT
        Dim tlng As Long
        
        GetCursorPos t
        GetWindowRect Form1.hwnd, t1
        tlng = PtInRect(t1, t)
        If tlng <> 0 Then
            Form1.Caption = "鼠标在窗体内!"
        Else
            Form1.Caption = "鼠标不在窗体内!"
        End If
    End Sub最后还有一个问题,就是在窗体失去当前位置时,如何使窗体做出反应(比如让窗体移动)?!
    是不是要获得窗体在Z轴序列上的位置,判断是否是当前位置,如不是,则做出反应。现在就是不知道哪个API可以获得窗体在Z轴序列上的位置,在次请问大家,谢谢!
      

  13.   

    QQ的窗体是始终在前的,否则,当你把鼠标移动到屏幕边缘的时候如果QQ窗体被覆盖,将不会产生你的事件,试试运行一个MediaPlayer或者是全屏幕的程序.这是第一点.
    第二点,既然窗体是始终在前的,这时候你就可以希望使用LostFocus事件,可是呢,好像不行,因为鼠标离开窗体并不产生这个事件,你可以查询一下windows消息,需要重载窗口函数.
    第三点,关于当鼠标拖动窗口到屏幕边缘的时候,窗体自动附着(鼠标还没有松开),这时候需要在拦截窗口移动消息是加以判断,适当的时候重设窗体矩形.
      

  14.   

    Public Declare Function PtInRect Lib "user32" (lpRect As RECT, pt As POINTAPI) As Long
    ====================================================================
    应改为“Private ……”
    原因是:在窗体模块中申明API只能用“Private”
      

  15.   

    这与窗体永远在前无关!!!QQ这么做只是为了方便用户,是窗体不会跑到其他窗体的后面
    没看见QQ不自动隐藏的时候,窗体也是永远在前的但是它的窗体既然已经是永远在前的
    所以它用那种方法比较方便因为窗体的大小是通过“GetWindowRect”来取得的,所以可以不管Z轴的顺序
      

  16.   

    TO dbcontrols(泰山__抛砖引玉):原代码已经发到你的邮箱里了,请尽力帮忙看看,谢谢拉!
    TO  zyl910(910:分儿,我来了!):我的代码是放在模块里的,而且把Public 改成Private,也是没有用的,在执行到“tlng = PtInRect(t1, t)”时,系统仍然会提示“DLL 调用约定错误!”
    TO zyl910(910:分儿,我来了!)AND  printer(打印机) :对不起,我没有清楚表达我的意思,我的想法是在窗体(比如Form1)失去焦点时,引发一个事件,比如form1.move等等。一开始我以为form1在失去焦点时,它在Z轴序列上的位置会变化,然后我们可以通过检测这个改变而调用相应的过程。
    TO printer(打印机) :对于你讲的“关于当鼠标拖动窗口到屏幕边缘的时候,窗体自动附着(鼠标还没有松开),这时候需要在拦截窗口移动消息是加以判断,适当的时候重设窗体矩形.”我有些不明白,比如当我们把窗体移动到左边屏幕时,系统会产生个什么样的消息,我们又如何拦截这个消息呢?!其中会用到什么API呢?!TO 大家:兄弟愚钝,希望各位兄弟多多帮忙,不要嫌我太罗嗦!多谢拉!:)
      

  17.   

    朋友,這種做法很多,我有一獨創控件,本也是想寫一類似QQ聊天程序,給我mail address,我將該控件先給你用用。
      

  18.   

    你去看一下北京希望电子出版社的<<编程高手>>
    有例子
      

  19.   

    TO  vbsnake(泡泡龙) :这本书有电子版的么?!可以从哪里下载?!
    谢谢!
      

  20.   

    To: zyl910(910:分儿,我来了!) 
    =====================================
    当然,窗体不是永远再前也是可以的阿,可是如果有另外的应用程序窗体是全屏幕时,怎么实现当鼠标移动到屏幕边缘的时候,自动激活(扩展)这个QQ窗口?我想你不会笨到使用Timer来查询吧。您试试看将TenctntQQ的总是在前选项取消复选,然后将你的IE最大化,移动你的鼠标到边缘会不会显示那个TencentQQ,保证你看不到。
      

  21.   

    TO: yjyb(炎冰) 
    ==== 第一 ================================
    就好像一个Mouse_Enter,Mouse_Leave事件一样,不知道你是不是说得这样的效果。如何产生呢,网上有这样的源代码,不知道你有没有看见过一个axButton这样控件,含有源代码的,写得很清晰。思路是,设置一个时钟,平时的时候,时钟被禁止,当产生Mouse_Enter事件的时候,启用它,并且时刻查询鼠标是否被自己所拥有(WindowFromPoint函数),一旦不再被自己拥有,激发事件Mouse_Leave,设置成员级变量为假,标志着鼠标不在窗口上;并且禁用这个时钟,如果需要,可是修改QQ窗口的大小,变成一个细条。当鼠标移动到这个QQ细条的时候,产生MouseMove事件,如果成员级标志变量为假,则置真,激发事件Mouse_Enter=== 第二 关于窗口函数====================================
    以下代码可以帮助你
    ------模块:-------------------------
    Option ExplicitPublic Const GWL_WNDPROC = (-4)Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hWnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long) As Long
    Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As LongPublic prevWndProc As LongFunction WndProc(ByVal hWnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
        Dim sMsg As String
        
        On Error Resume Next
        Debug.Print sMsg & "(=&H" & Hex(Msg) & ")"
        ' If 需要拦截 then 
           '这里:如果需要拦截这个消息的话,在这里加入自己的代码
        ' Else
        WndProc = CallWindowProc(prevWndProc, hWnd, Msg, wParam, lParam)
        'End if
    End Function----窗体---------------Option ExplicitPrivate Sub Form_Load()
        prevWndProc = GetWindowLong(Me.hWnd, GWL_WNDPROC)
        SetWindowLong Me.hWnd, GWL_WNDPROC, AddressOf WndProc
    End SubPrivate Sub Form_Unload(Cancel As Integer)
        SetWindowLong Me.hWnd, GWL_WNDPROC, prevWndProc
    End Sub
      

  22.   

    TO  printer(打印机):你所提到的Mouse_Enter,Mouse_Leave两个事件,我在MSDN中没有找到,真的有这两个事件么?!那个axButton控件我也没有见过,不过你说的方法倒是给我很大的启发,非常感谢!:)
    对了,在翻看MSDN的资料时,没有找到Deactivate事件的说明,不知道这个事件起什么作用?
      

  23.   

    TO  printer(打印机):你所提到的Mouse_Enter,Mouse_Leave两个事件,我在MSDN中没有找到,真的有这两个事件么?!那个axButton控件我也没有见过,不过你说的方法倒是给我很大的启发,非常感谢!:)
    对了,在翻看MSDN的资料时,没有找到Deactivate事件的说明,不知道这个事件起什么作用?
      

  24.   

    TO  printer(打印机):另外,请恕小弟愚钝,我把你给的代码仔细的看了好几遍,并拿出WINDOWS API参考大全,好好的研究了下。发现我完全不懂代码会起到怎么样的作用。真的不懂,你能作一下比较详细的说明么?!:(
    (唉,我好笨啊!555555)