Windows mobile上获取输入光标位置

 

用户在输入过程中,光标的位置在不停变化,如何得到这个位置来进行一些操作呢?似乎很简单,GetCaretPos,这个函数能得到光标的位置。

看看MSDN上如何说的:

GetCaretPos

See Also

SetCaretPos | POINT | Carets Functions

 

Requirements

OS Versions: Windows CE 1.0 and later.
Header: Winuser.h.
Link Library: Caret.lib.

This function copies the caret's position, in client coordinates, to the specified POINT structure.

BOOL GetCaretPos(

  LPPOINT lpPoint

);

Parameters

lpPoint

[out] Long pointer to the POINT structure that is to receive the client coordinates of the caret.

Return Values

Nonzero indicates success. Zero indicates failure. To get extended error information, call GetLastError.

Remarks

The caret position is always given in the client coordinates of the window that contains the caret.

If an application calls GetCaretPos from a thread that does not own the caret, GetCaretPos fails with an error value of ERROR_ACCESS_DENIED.

 

很遗憾,实际的结果,此函数对于本进程是有效的,对于别的进程缺无能为力,真的会得到错误值ERROR_ACCESS_DENIED

看看windows上有什么好方法吧。

网上找找,通用的大概有两种方法:1)使用AttachThreadInput将本进程注入到输入焦点窗口进程(当然要先找到焦点窗口),这样就能使用GetCaretPos了;2)使用GetGUIThreadInfo可以获得位置信息。

还是很遗憾,wince对于这两个函数都不支持。

在绝望地摸索了一段时间后,通过曲线救国的方式,事情似乎有了转机。

微软提供了两个函数GetWindowLongSetWindowLong,这个函数可以得到和设置指定窗口的一些信息,包括窗口进程的地址。

先准备一些料,包饺子用的,后面会用到:

static WNDPROC g_pOldWndProc = NULL;

static WNDPROC g_pOldEditProc = NULL;

 

static UINT    g_uGetFocusMessage = RegisterWindowMessage(_T("GetFocusMessage"));

static UINT    g_uGetCaretMessage = RegisterWindowMessage(_T("GetCaretMessage"));

static UINT    g_uGetRectMessage  = RegisterWindowMessage(_T("GetRectMessage"));

 

static POINT   g_ptCaret;

static RECT    g_rcEdit;

 

 

static LRESULT WINAPI GetFocusWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)

{

    if(uMsg == g_uGetFocusMessage)

    {

        return (LRESULT)GetFocus();

    }

    else

    {

        return CallWindowProc(g_pOldWndProc, hWnd, uMsg, wParam, lParam);

    }

}

 

static LRESULT WINAPI GetCaretPosWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)

{

    if(uMsg == g_uGetCaretMessage)

    {

        return (LRESULT)GetCaretPos(&g_ptCaret);

    }

    else if(uMsg == g_uGetRectMessage)

    {

        return (LRESULT)GetWindowRect(hWnd, &g_rcEdit);

    }

    else

    {

        return CallWindowProc(g_pOldEditProc, hWnd, uMsg, wParam, lParam);

    }

}

 

现在假设一上层窗口,拥有输入Edit,我们用下面的方法可以得到输入光标的坐标:

HWND hWnd = GetForegroundWindow();

if(hWnd)

{

    g_pOldWndProc = (WNDPROC)GetWindowLong(hWnd, GWL_WNDPROC);

 

    //设置一个新的窗口进程

    SetWindowLong(hWnd, GWL_WNDPROC, (LONG)GetFocusWindowProc);

    HWND hEdit = (HWND)SendMessage(hWnd, g_uGetFocusMessage, 0, 0);

    if(hEdit)

    {

        g_pOldEditProc = (WNDPROC)GetWindowLong(hEdit, GWL_WNDPROC);

        SetWindowLong(hEdit, GWL_WNDPROC, (LONG)GetCaretPosWindowProc);

       

        SendMessage(hEdit, g_uGetRectMessage, 0, 0);

        BOOL b = (BOOL)SendMessage(hEdit, g_uGetCaretMessage, 0, 0);

 

        if(b)

        {

            //此处利用g_rcEditg_ptCaret就可以得到光标相对于屏幕的位置

        }

 

        SetWindowLong(hEdit, GWL_WNDPROC, (LONG)g_pOldEditProc);

        g_pOldEditProc = NULL;

    }

 

    //用完了,要恢复

    SetWindowLong(hWnd, GWL_WNDPROC, (LONG)g_pOldWndProc);

    g_pOldWndProc = NULL;

}

 

 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值