Как получить хендл чужого окна?
От: Leonid_CSIT  
Дата: 11.01.07 13:24
Оценка:
Здравствуйте!

Пишу экранную клавиатуру.

Все хорошо печатается в блокноте и других подобных приложениях, но если мне нужно, что то написать в EditBox (текстовом поле) (например, в поле поиска VS), то пишется все в основном окне (в случаи с VS пишет там, где код).

Для получения хендела окна использую ::GetForegroundWindow();

Может, кто знает, как добраться до EditBox`а?

Заранее большое спасибо!
Re: Как получить хендл чужого окна?
От: Andrew S Россия http://alchemy-lab.com
Дата: 11.01.07 13:40
Оценка:
L_C>Для получения хендела окна использую ::GetForegroundWindow();

L_C>Может, кто знает, как добраться до EditBox`а?


GetForegroundWindow, GetWindowThreadProcessId, AttachThreadInput и GetFocus.
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re: Как получить хендл чужого окна?
От: SergH Россия  
Дата: 11.01.07 13:43
Оценка:
Здравствуйте, Leonid_CSIT, Вы писали:

L_C>Здравствуйте!


L_C>Пишу экранную клавиатуру.


L_C>Все хорошо печатается в блокноте и других подобных приложениях, но если мне нужно, что то написать в EditBox (текстовом поле) (например, в поле поиска VS), то пишется все в основном окне (в случаи с VS пишет там, где код).


L_C>Для получения хендела окна использую ::GetForegroundWindow();


L_C>Может, кто знает, как добраться до EditBox`а?


Подход неверный. Забей на окна, используй SendInput
Делай что должно, и будь что будет
Re[2]: Как получить хендл чужого окна?
От: Leonid_CSIT  
Дата: 11.01.07 13:46
Оценка:
Здравствуйте, Andrew S, Вы писали:

L_C>>Для получения хендела окна использую ::GetForegroundWindow();


L_C>>Может, кто знает, как добраться до EditBox`а?


AS>GetForegroundWindow, GetWindowThreadProcessId, AttachThreadInput и GetFocus.


Вроде так и делаю, может что то не так?!!!


HWND hwnd = ::GetForegroundWindow();
    
    if(IsWindow(hwnd))
    {
        if(hwnd != this->m_hWnd)
        {
            if(m_hwndFocus != hwnd)
            {
                DWORD t1 = GetWindowThreadProcessId(hwnd, NULL);
                DWORD t2 = GetCurrentThreadId();
                if(IsWindow(m_hwndFocus))
                {
                    AttachThreadInput(t2, t1, FALSE);
                }
                m_hwndFocus = hwnd;
                AttachThreadInput(t2, t1, TRUE);
                ::SetFocus(hwnd);
            }
        }
    }
Re[2]: Как получить хендл чужого окна?
От: Leonid_CSIT  
Дата: 11.01.07 13:50
Оценка:
Здравствуйте, SergH, Вы писали:

SH>Здравствуйте, Leonid_CSIT, Вы писали:


L_C>>Здравствуйте!


L_C>>Пишу экранную клавиатуру.


L_C>>Все хорошо печатается в блокноте и других подобных приложениях, но если мне нужно, что то написать в EditBox (текстовом поле) (например, в поле поиска VS), то пишется все в основном окне (в случаи с VS пишет там, где код).


L_C>>Для получения хендела окна использую ::GetForegroundWindow();


L_C>>Может, кто знает, как добраться до EditBox`а?


SH>Подход неверный. Забей на окна, используй SendInput


Я использую keybd_event, это почти тоже самое что и SendInput
Re[3]: Как получить хендл чужого окна?
От: SergH Россия  
Дата: 11.01.07 13:55
Оценка:
Здравствуйте, Leonid_CSIT, Вы писали:

L_C>Я использую keybd_event, это почти тоже самое что и SendInput


Тогда не понимаю, зачем тебе окна — оно само всё разрулит. Единственное, о чём нужно позаботиться — чтобы твоё собственное окно-клавиатура не оказалась текущей
Делай что должно, и будь что будет
Re[4]: Как получить хендл чужого окна?
От: Leonid_CSIT  
Дата: 11.01.07 14:03
Оценка:
Здравствуйте, SergH, Вы писали:

SH>Здравствуйте, Leonid_CSIT, Вы писали:


L_C>>Я использую keybd_event, это почти тоже самое что и SendInput


SH>Тогда не понимаю, зачем тебе окна — оно само всё разрулит. Единственное, о чём нужно позаботиться — чтобы твоё собственное окно-клавиатура не оказалась текущей


должно но не хочет.


BOOL CMyKeyboardDlg::PreTranslateMessage(MSG* pMsg)
{
    HWND hwnd = ::GetForegroundWindow();
    
    if(IsWindow(hwnd))
    {
        if(hwnd != this->m_hWnd)
        {
            if(m_hwndFocus != hwnd)
            {
                DWORD t1 = GetWindowThreadProcessId(hwnd, NULL);
                DWORD t2 = GetCurrentThreadId();
                if(IsWindow(m_hwndFocus))
                {
                    AttachThreadInput(t2, t1, FALSE);
                }
                m_hwndFocus = hwnd;
                AttachThreadInput(t2, t1, TRUE);
                ::SetFocus(hwnd);
            }
        }
    }
    // TODO: Add your specialized code here and/or call the base class

    return CDialog::PreTranslateMessage(pMsg);
}



void CMyKeyboardDlg::ReleaseFocus() 
{
    if(IsWindow(m_hwndFocus))
    {
        HWND wnd = ::GetForegroundWindow();
        if(IsWindow(wnd))
        {
            if(wnd == m_hwndFocus)
            {
                return;
            }
        }
        ::SetForegroundWindow(m_hwndFocus);
        ::SetFocus(m_hwndFocus);
    }
}


Ну и наконец что то типа этого:
ReleaseFocus();
::keybd_event(VkKeyScan(_T('g')), 0, 0, 0);
Re: Как получить хендл чужого окна?
От: McQwerty Россия  
Дата: 11.01.07 16:37
Оценка:
Здравствуйте, Leonid_CSIT, Вы писали:

L_C>Пишу экранную клавиатуру.


L_C>Все хорошо печатается в блокноте и других подобных приложениях, но если мне нужно, что то написать в EditBox (текстовом поле) (например, в поле поиска VS), то пишется все в основном окне (в случаи с VS пишет там, где код).


Как не активировать окно обсуждалось здесь
Автор: McQwerty
Дата: 02.12.05
.
Re[2]: Как получить хендл чужого окна?
От: Leonid_CSIT  
Дата: 11.01.07 18:31
Оценка:
Здравствуйте, McQwerty, Вы писали:

MQ>Здравствуйте, Leonid_CSIT, Вы писали:


L_C>>Пишу экранную клавиатуру.


L_C>>Все хорошо печатается в блокноте и других подобных приложениях, но если мне нужно, что то написать в EditBox (текстовом поле) (например, в поле поиска VS), то пишется все в основном окне (в случаи с VS пишет там, где код).


MQ>Как не активировать окно обсуждалось здесь
Автор: McQwerty
Дата: 02.12.05
.


Ваш ответ в обсуждении которое вы мне посоветовали прочетать, я прочетал. Не помогло!

Вот как у меня реализовано не активность и так чтобы окно было поверх всех:

void CMyKeyboardDlg::OnWindowPosChanging(WINDOWPOS* lpwndpos)
{
    SetWindowPos(&wndTopMost, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
    CDialog::OnWindowPosChanging(lpwndpos);

    // TODO: Add your message handler code here
}


P.S.

Если использовать за место моего примера, то что вы предлагали в том обсуждении, то вообще не работает.
SetWindowPos(&wndTopMost, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOSIZE | SWP_NOZORDER);

или
SetWindowPos(NULL, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOSIZE | SWP_NOZORDER);
Re[3]: Как получить хендл чужого окна?
От: Andrew S Россия http://alchemy-lab.com
Дата: 11.01.07 20:49
Оценка:
L_C>>>Для получения хендела окна использую ::GetForegroundWindow();

L_C>>>Может, кто знает, как добраться до EditBox`а?


AS>>GetForegroundWindow, GetWindowThreadProcessId, AttachThreadInput и GetFocus.


L_C>Вроде так и делаю, может что то не так?!!!


Вам нужно получать фокус, а не устанавливать? Если так, тогда приведенный вами код выглядит по меньшей мере странно.


L_C>
L_C>HWND hwnd = ::GetForegroundWindow();
    
L_C>    if(IsWindow(hwnd))
L_C>    {
L_C>        if(hwnd != this->m_hWnd)
L_C>        {
L_C>            if(m_hwndFocus != hwnd)
L_C>            {
L_C>                DWORD t1 = GetWindowThreadProcessId(hwnd, NULL);
L_C>                DWORD t2 = GetCurrentThreadId();
L_C>                if(IsWindow(m_hwndFocus))
L_C>                {
L_C>                    AttachThreadInput(t2, t1, FALSE);
L_C>                }
L_C>                m_hwndFocus = hwnd;
L_C>                AttachThreadInput(t2, t1, TRUE);
L_C>                ::SetFocus(hwnd);
L_C>            }
L_C>        }
L_C>    }
L_C>
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[4]: Как получить хендл чужого окна?
От: Leonid_CSIT  
Дата: 12.01.07 07:32
Оценка:
Здравствуйте, Andrew S, Вы писали:

L_C>>>>Для получения хендела окна использую ::GetForegroundWindow();


L_C>>>>Может, кто знает, как добраться до EditBox`а?


AS>>>GetForegroundWindow, GetWindowThreadProcessId, AttachThreadInput и GetFocus.


L_C>>Вроде так и делаю, может что то не так?!!!


AS>Вам нужно получать фокус, а не устанавливать? Если так, тогда приведенный вами код выглядит по меньшей мере странно.



L_C>>
L_C>>HWND hwnd = ::GetForegroundWindow();
    
L_C>>    if(IsWindow(hwnd))
L_C>>    {
L_C>>        if(hwnd != this->m_hWnd)
L_C>>        {
L_C>>            if(m_hwndFocus != hwnd)
L_C>>            {
L_C>>                DWORD t1 = GetWindowThreadProcessId(hwnd, NULL);
L_C>>                DWORD t2 = GetCurrentThreadId();
L_C>>                if(IsWindow(m_hwndFocus))
L_C>>                {
L_C>>                    AttachThreadInput(t2, t1, FALSE);
L_C>>                }
L_C>>                m_hwndFocus = hwnd;
L_C>>                AttachThreadInput(t2, t1, TRUE);
L_C>>                ::SetFocus(hwnd);
L_C>>            }
L_C>>        }
L_C>>    }
L_C>>


Это я уже экспериментировал Да SetFocus тут не нужен, прошу прощение. Скачал для примера исходники подобной клавиатуры с http://www.codeproject.com, там был SetFocus ( там такая же проблема). Но проблема остается в студии не работает, в Excel, Word тоже, вообщем во всех случаях, когда есть фрейм и есть любое поле для ввода текста. В этом случаи поле для ввода теряет фокус при нажатии на мою клавиатуру. В других случаях такого не наблюдал. В диалоговом окне, где много полей ввода все нормально.

Я даже знаю в чем проблема: мое окно становится на время активным, что с виндовской клавиатурой не случается. Хотя у меня есть такой код:


void CMyKeyboardDlg::OnWindowPosChanging(WINDOWPOS* lpwndpos)
{
    SetWindowPos(&wndTopMost, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_SHOWWINDOW | SWP_NOOWNERZORDER);
    CDialog::OnWindowPosChanging(lpwndpos);

    // TODO: Add your message handler code here
}


Может он не в том месте, или необходимо что то еще сделать?

P.S.
Может кто знает откуда можно скачать рабочий пример экранной клавиатуры?
Re: Как получить хендл чужого окна?
От: Leonid_CSIT  
Дата: 12.01.07 08:09
Оценка:
Здравствуйте, Leonid_CSIT, Вы писали:

L_C>Здравствуйте!


L_C>Пишу экранную клавиатуру.


L_C>Все хорошо печатается в блокноте и других подобных приложениях, но если мне нужно, что то написать в EditBox (текстовом поле) (например, в поле поиска VS), то пишется все в основном окне (в случаи с VS пишет там, где код).


L_C>Для получения хендела окна использую ::GetForegroundWindow();


L_C>Может, кто знает, как добраться до EditBox`а?


L_C>Заранее большое спасибо!


Всем большое спасибо, сам разобрался надо было просто добавить:

int CMyKeyboardDlg::OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT message)
{
    // TODO: Add your message handler code here and/or call default

    return MA_NOACTIVATE; //CDialog::OnMouseActivate(pDesktopWnd, nHitTest, message);
}
Re[2]: Как получить хендл чужого окна?
От: McQwerty Россия  
Дата: 13.01.07 13:18
Оценка:
Здравствуйте, Leonid_CSIT, Вы писали:

L_C>Всем большое спасибо, сам разобрался надо было просто добавить:


L_C>
L_C>int CMyKeyboardDlg::OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT message)
L_C>{
L_C>    // TODO: Add your message handler code here and/or call default

L_C>    return MA_NOACTIVATE; //CDialog::OnMouseActivate(pDesktopWnd, nHitTest, message);
L_C>}
L_C>


Если-бы ты действительно посмотрел код примера, который я тебе рекомендовал, то увидел-бы следующее:

    case WM_MOUSEACTIVATE:
        return MA_NOACTIVATE;
    break;


Я ведь не просто так рекомендацию давал.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.