zoukankan      html  css  js  c++  java
  • 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;

    }

     

     

  • 相关阅读:
    beta冲刺3/7
    案例分析
    beta冲刺2/7
    beta冲刺1/7
    烟头的待办项
    Spring框架原理概述
    Spring源码环境搭建
    BeanFactory的启动流程
    Spring容器的原理
    Spring Framework 概述
  • 原文地址:https://www.cnblogs.com/fengju/p/6173546.html
Copyright © 2011-2022 走看看