Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Зацикливание сообщений при работе с хуком 
:(
    Опции темы
dizzy1984
Дата 13.1.2013, 08:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 675
Регистрация: 15.2.2007

Репутация: 10
Всего: 25



Доброе время суток. Хочу написать программку, передающую мне управление при клике мышки на определенном графическом элементе экрана. Написал хук, написал программку. Для уведомления программки хуком выбрал PostMessage. Сделал логирование. Начал проверять записи лога, обнаружил проблему при следующем сценарии действий : если кликнуть мышкой по окну, затем быстро переместить ее и снова кликнуть по тому же окну, образуется бесконечный цикл сообщений отправки и получения.
 Вот как выглядит, если кликать медленно или быстро, но не двигая мышкой
 
Цитата

 Message 50539 sended
 received 50539 message!
 

 Здесь первое сообщение пишется в хуке, второе в программе. Сколько кликнул — столько и пар сообщений (хотя если быстро кликать некоторые проглатываются, видимо, это уже происходит на уровне системы).
 Ну а при описанной выше ситуации лог такой же, но постоянно растет, пока не сделать alt-tab. Тогда он останавливается...
 Работаю с хуками второй раз, не могу представить в чем тут проблема. Есть догадка, что в описанном случае PostMessage из хука вызывается до обработки программой первого посланного PostMessage (из-за синхронной обработки перемещения мышки), однако, по моим представлениям, он просто мирно добавится в свою очередь и будет там вторым... лежать.
 Прошу помощи!
 Вот код хука
Код

//cpp
#include "stdafx.h"
#include "ptksmonmh.h"
#include <atlstr.h>
#include <fstream>

HINSTANCE hinst;
HHOOK hh;

#pragma data_seg( ".SHARDATA" )
UINT msg = 0;
HWND mainwnd = 0;
#pragma data_seg()

BOOL APIENTRY DllMain( HINSTANCE h, DWORD, LPVOID )
{
    hinst = h;
    return TRUE;
}

LRESULT CALLBACK MouseHook( int code, WPARAM wp, LPARAM lp )
{
    if ( code < 0 )
    {
        return ::CallNextHookEx( hh, code, wp, lp );
    }

    if ( wp == WM_LBUTTONDOWN )
    {        
        ::PostMessage( mainwnd, msg, NULL, NULL );
        CString tmp;
        tmp.Format( "Message %d sended\n", msg );
        std::ofstream o( "c:\\log.txt", std::ios::app );
        //::OutputDebugString( tmp );
        o << tmp;
        o.flush();
    }    
    
    return ::CallNextHookEx( hh, code, wp, lp );
}

UINT RegisterMouseMessage( HWND mw )
{
    mainwnd = mw;
    return msg = ::RegisterWindowMessage( "ptksmonmsg" );
}

bool InstallMouseHook()
{
    
    return ( hh = ::SetWindowsHookEx( WH_MOUSE, MouseHook, hinst, 0 ) ) != NULL;
}

bool UnInstallMouseHook()
{
    return UnhookWindowsHookEx( hh ) != 0;
}

//h
__declspec(dllexport) LRESULT CALLBACK MouseHook( int code, WPARAM wp, LPARAM lp );
//__declspec(dllexport) UINT RegisterMouseMessage();
__declspec(dllexport) bool InstallMouseHook();
__declspec(dllexport) UINT RegisterMouseMessage( HWND mw );
__declspec(dllexport) bool UnInstallMouseHook();




 Вот программки
Код

int Ctestdllmfc2010Dlg::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
    if (CDialogEx::OnCreate(lpCreateStruct) == -1)
        return -1;

    mh = ::LoadLibrary( _T( "ptksmonmh.dll" ) );

    UINT (* rmm)(int);
    rmm = reinterpret_cast<UINT (*)(int)>( ::GetProcAddress( mh, _T( "RegisterMouseMessage" ) ) );
    mm = rmm( reinterpret_cast<int>( m_hWnd ) );
    
    CString tm;
    tm.Format( "mm is %d\n", mm );
    //TRACE( tm );

    bool (*imh)();
    imh = reinterpret_cast<bool (*)()>( ::GetProcAddress( mh, _T( "InstallMouseHook" ) ) );
    imh();

    return 0;
}

void Ctestdllmfc2010Dlg::OnDestroy()
{
    CDialogEx::OnDestroy();
    
    bool (* uimh)();
    uimh = reinterpret_cast<bool (*)()>( ::GetProcAddress( mh, _T( "UnInstallMouseHook" ) ) );
    uimh();

    ::FreeLibrary( mh );
}

BOOL Ctestdllmfc2010Dlg::PreTranslateMessage(MSG* pMsg)
{
    if ( pMsg->message == mm )
    {
        CString tmp;
        tmp.Format( "received %d message!\n", mm );
        //TRACE( tmp );
        std::ofstream o( "c:\\log.txt", std::ios::app );
        o << tmp;        
         //::MessageBeep( MB_ICONERROR );
    }

    return CDialogEx::PreTranslateMessage(pMsg);
}


Это сообщение отредактировал(а) dizzy1984 - 13.1.2013, 08:37
PM MAIL   Вверх
Dem_max
Дата 13.1.2013, 18:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1780
Регистрация: 12.4.2007

Репутация: 1
Всего: 39



В коде нет ничего такого из за чего могут быть зацикливания.


--------------------
Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte")
PM MAIL   Вверх
Dem_max
Дата 13.1.2013, 19:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1780
Регистрация: 12.4.2007

Репутация: 1
Всего: 39



Да и избавься уже от этого, это плохой тон
Код

#pragma data_seg( ".SHARDATA" )
UINT msg = 0;
HWND mainwnd = 0;
#pragma data_seg()



--------------------
Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte")
PM MAIL   Вверх
dizzy1984
Дата 14.1.2013, 04:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 675
Регистрация: 15.2.2007

Репутация: 10
Всего: 25



Почему?
PM MAIL   Вверх
Earnest
Дата 15.1.2013, 12:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 87
Всего: 183



Действительно, почему? Не переносимо? Ну так если не надо переносить... Расшаренная память бывает очень удобна...


--------------------
...
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Visual C++/MFC/WTL | Следующая тема »


 




[ Время генерации скрипта: 0.0762 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.