none
為何使用GetCaretPos函數無法取得滑鼠座標? RRS feed

  • 問題

  • 作業平台: Windows XP SP3
    程式平台: Microsoft Visual Basic 2008 Express Edition
    程式片段:
        Public Structure POINTAPI
            Dim x As Int32
            Dim y As Int32
        End Structure
    
        Public Declare Function GetCaretPos Lib "user32" (ByRef lpPoint As POINTAPI) As Integer
    
        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            Dim p As POINTAPI
            GetCaretPos(p)
            Debug.Print("x:{0}, y:{1}", p.x, p.y)
        End Sub

    問題描述:上面這段程式碼我在VB6是可以用的,型態我也有調整過了,但是在VB.NET語言下都是印出0座標。

    請問,我程式碼中哪邊有錯誤呢? 另外我搜尋.net GetCaretPos的中文資料不多(英文看不是很懂),所以到貴討論區尋求解答。
    2009年10月9日 下午 01:43

解答

  • 這個 API 應該不用自己定義 StructLayout。照這個網址提供的宣告就可以用了:
    http://www.pinvoke.net/default.aspx/user32.getcaretpos

    問題也許出在:你的視窗上有可以接受游標 focus 的 window control 嗎?例如;TextBox。
    你的視窗必須是前景視窗,且獲得 input focus。
    如果你想要在 Windows 程式中取得另一個 console 視窗的游標位置,GetCaretPos 在這裡並沒有用處。


    http://huan-lin.blogspot.com/
    • 已標示為解答 js155036 2009年10月11日 上午 11:35
    2009年10月11日 上午 02:25
  • 你要重新確認的是你的標題。
    1. 抓滑鼠座標:GetCursorPos
    2. 抓游標座標:GetCaretPos ,且須有 TextBox / RichTextBox 等會有游標的畫面,才抓得到游標。


    論壇是網友平等互助 保證解答請至 微軟技術支援服務
    • 已標示為解答 js155036 2009年10月11日 上午 11:34
    2009年10月11日 上午 09:59

所有回覆

  • hi
    如果要取得form中的滑鼠座標,有比較快的做法(不用API),在mousemove事件

    private void Form1_MouseMove(object sender, MouseEventArgs e)
            {
                textBox1.Text = "X座標:"+e.X +Environment.NewLine+"Y座標:"+ e.Y;
            }

    參考
    http://msdn.microsoft.com/zh-tw/library/system.windows.forms.control.mousemove.aspx
    http://www.dotblogs.com.tw/ricochen/Default.aspx
    2009年10月9日 下午 02:13
  • 首先,感謝您的回覆,

    原本我是想在Win Console中取得,後來用Win Forms也不行,

    所以我希望能在Win Console 中取得座標,感恩。
    2009年10月9日 下午 02:22
  • 關於你的結構宣告,線上手冊有範例:
    傳遞結構
    ms-help://MS.MSDNQTR.v90.cht/dv_fxinterop/html/9b92ac73-32b7-4e1b-862e-6d8d950cf169.htm

    Visual Basic 複製程式碼
    Imports System.Runtime.InteropServices
    
    <StructLayout(LayoutKind.Sequential)> Public Structure Point
        Public x As Integer
        Public y As Integer
    End Structure
    
    Public Structure <StructLayout(LayoutKind.Explicit)> Rect
        <FieldOffset(0)> Public left As Integer
        <FieldOffset(4)> Public top As Integer
        <FieldOffset(8)> Public right As Integer
        <FieldOffset(12)> Public bottom As Integer
    End Structure
    
    Class Win32API    
        Declare Auto Function PtInRect Lib "user32.dll" _
        (ByRef r As Rect, p As Point) As Boolean
    End Class
    


    論壇是網友平等互助 保證解答請至 微軟技術支援服務
    2009年10月9日 下午 02:41
  • 再次感謝大大回覆,我採用了這個範例的結構後,依然無法取得值,
    目前在Console下做測試。

    測試的程式碼為:

        Class Win32API
            Declare Function GetCaretPos Lib "user32.dll" (ByRef lpPoint As Point) As Boolean
    
        End Class
    
        Public Structure Point
            Dim x As Int32
            Dim y As Int32
        End Structure
    
        Sub Main()
            Dim p As Point
            Debug.Print(Win32API.GetCaretPos(p))
            Debug.Print(p.x)
            Console.Read()
        End Sub

    繼續請求大大們。
    2009年10月9日 下午 03:29
  • 重點在前面的這個:
    <StructLayout(LayoutKind.Sequential)>

    原因可以看一下:
    http://tlcheng.spaces.live.com/blog/cns!145419920BFD55A7!1012.entry
    論壇是網友平等互助 保證解答請至 微軟技術支援服務
    2009年10月9日 下午 03:44
  • 感謝大大的回答,我去查了一下這個方法,
    並套用範例,測試程式碼如下:
        <StructLayout(LayoutKind.Explicit)> Public Structure POINTAPI
            <FieldOffset(0)> Public x As Int32
            <FieldOffset(4)> Public y As Int32
        End Structure
    
        Public Declare Function GetCaretPos Lib "user32" (ByRef lpPoint As POINTAPI) As Integer
    
        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            Dim p As New POINTAPI
            GetCaretPos(p)
            Debug.Print("x:{0}, y:{1}", p.x, p.y)
        End Sub

    但是取回滑鼠座標值依然是0,0,

    或者我還不清楚此API是要如何定義它的結構,

    問題會是出在FieldOffset定義嗎?

    繼續麻煩大大了。
    2009年10月10日 下午 08:59
  • 這個 API 應該不用自己定義 StructLayout。照這個網址提供的宣告就可以用了:
    http://www.pinvoke.net/default.aspx/user32.getcaretpos

    問題也許出在:你的視窗上有可以接受游標 focus 的 window control 嗎?例如;TextBox。
    你的視窗必須是前景視窗,且獲得 input focus。
    如果你想要在 Windows 程式中取得另一個 console 視窗的游標位置,GetCaretPos 在這裡並沒有用處。


    http://huan-lin.blogspot.com/
    • 已標示為解答 js155036 2009年10月11日 上午 11:35
    2009年10月11日 上午 02:25
  • Hi,
    真搞不定可以考慮用
    MousePosition
    Console.WriteLine(System.Windows.Forms.Control.MousePosition.ToString)

    謙卑學習,持之以恆,才能不斷的Level Up http://www.dotblogs.com.tw/larrynung/
    2009年10月11日 上午 04:03
  • 你要重新確認的是你的標題。
    1. 抓滑鼠座標:GetCursorPos
    2. 抓游標座標:GetCaretPos ,且須有 TextBox / RichTextBox 等會有游標的畫面,才抓得到游標。


    論壇是網友平等互助 保證解答請至 微軟技術支援服務
    • 已標示為解答 js155036 2009年10月11日 上午 11:34
    2009年10月11日 上午 09:59
  • 謝謝你的觀念教學,我瞭解這部分了。
    2009年10月11日 上午 11:31
  • 謝謝大大回覆,但是在Console中無法使用System.Windows,我剛測試無法匯入,還是有其他方法可以使用?

    2009年10月11日 上午 11:33
  • 感恩,經過你這麼一說,

    我還有Michael Tsai MVP的解說,

    我完全懂了,

    而且已經可以用了,

    但是我標題不修正,讓跟我有錯誤的人一樣能從這篇文章中找到解答,

    謝謝各位大大的回答,我會繼續努力的。
    2009年10月11日 上午 11:34