powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / подмена оконной процедуры - крах приложения
8 сообщений из 8, страница 1 из 1
подмена оконной процедуры - крах приложения
    #38652790
iMerlin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Здравствуйте, помогите, пожалуйста, что то никак не могу ухватить что не так сделал.
Есть задача: научить приложение VBA (Access) реагировать на сообщение пользователя (управление внешней программой).
Для этого была сделана DLL, подменяющая оконную процедуру и долженствующая вызвать некоторую функцию при приходе сообщения UserMsg.

DLL имеет три используемые в данном случе функции: NewDialogProc, SetNewProc и int Init.
Init (просто для сведения привел - там вроде все правильно работает) регистрирует UserMsg.
SetNewProc - подменяет оконную процедуру.
NewDialogProc - новая процедура. Ее цель - обеспечить отдельную обработку UserMsg.

При отладке на простеньком MFC приложении обнаружился вылет через долю секунды после запуска.
При пошаговом исполнении оказалось, что происходит переполнение стека и через 10-15 обработанных сообщений стек рушится.

Думаю, я что-то очевидно не так сделал, но сам не могу сообразить что. Подскажите плс, куда копать?

PS: на данном этапе выполнения условие Msg==UserMsg не выполняется, то есть фактически в NewDialogProc выполняется только строка "return OldFunct(hWnd,Msg,wParam,lParam);".


Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
typedef void (*pf_vii)(int,int);
typedef LRESULT (*pf_lhulw)(HWND,UINT,LPARAM,WPARAM);
pf_lhulw OldFunct;
pf_vii NewFunct;
HWND hWndMain;
UINT UserMsg;
HANDLE hEvent;


DWORD NewDialogProc(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam)
{
	if(Msg==UserMsg)
	{
		NewFunct((DWORD)wParam, (DWORD)lParam);
		return TRUE;
	}
	else
	{
		return OldFunct(hWnd,Msg,wParam,lParam);
	}
}



void WINAPI SetNewProc(HWND hWnd, pf_vii funct)
{
	if(OldFunct)return;
	OldFunct=(pf_lhulw)SetWindowLong(hWnd,-4,(DWORD)&NewDialogProc);
	hWndMain=hWnd;
	NewFunct=funct;
}


int Init()
{


	UserMsg=RegisterWindowMessage("4DBB78B9-0C23-412e-951A-2F1735567521_wm");
	if(!UserMsg){MessageBox(NULL,"Can't register message","System error",MB_ICONERROR | MB_OK);return 0;}

	SetLastError(0);
	hEvent=CreateEvent(NULL,1,0,"4DBB78B9-0C23-412e-951A-2F1735567521_ld");
	if(!hEvent){MessageBox(NULL,"Can't create event","System error",MB_ICONERROR | MB_OK);return 0;}
	if(GetLastError()==ERROR_ALREADY_EXISTS){MessageBox(NULL,"Already runned...","User error",MB_ICONERROR | MB_OK);return -1;}
	
	return 0;
}
...
Рейтинг: 0 / 0
подмена оконной процедуры - крах приложения
    #38652807
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не надо свою очередь делать. Читай про хуки http://www.rsdn.ru/article/baseserv/winhooks.xml
...
Рейтинг: 0 / 0
подмена оконной процедуры - крах приложения
    #38652858
iMerlin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Спасибо, но думаю хуками сложней и не удобно. Мне надо в своем процессе просто сделать предобработчик событий и все. Хуки, как мне думается, скорее для слежения за чужим процессом.
...
Рейтинг: 0 / 0
подмена оконной процедуры - крах приложения
    #38652974
iMerlin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Все, всем спасибо, вопрос закрыт: упустил описание CALLBACK в оконных процедурах.
...
Рейтинг: 0 / 0
подмена оконной процедуры - крах приложения
    #38653354
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
iMerlin,

Код: plaintext
1.
UserMsg=RegisterWindowMessage("4DBB78B9-0C23-412e-951A-2F1735567521_wm");



Регистрировать сообщение вовсе не обязательно. Это нужно ТОЛЬКО тогда, когда
сообщение посылается между окнами разных приложений. В таком случае регистрация
сообщения гарантирует, что идентификатор сообщения будет один и тот же в этих
приложениях.
...
Рейтинг: 0 / 0
подмена оконной процедуры - крах приложения
    #38653370
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
iMerlin
Код: plaintext
1.
DWORD NewDialogProc(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam)



Сигнатура этой функции должна быть такой:

LRESULT (CALLBACK* WNDPROC) (HWND, UINT, WPARAM, LPARAM);

DWORD и LRESULT не всегда одно и то же.
Про CALLBACK ты уже заметил.
...
Рейтинг: 0 / 0
подмена оконной процедуры - крах приложения
    #38655008
iMerlin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
MasterZiviMerlin,

Регистрировать сообщение вовсе не обязательно. Это нужно ТОЛЬКО тогда, когда
сообщение посылается между окнами разных приложений. В таком случае регистрация
сообщения гарантирует, что идентификатор сообщения будет один и тот же в этих
приложениях.

Конечно. Внешняя программа и будет это сообщение отсылать - я указывал вначале, что основная задача управлять проектом с помощью внешней программы.

MasterZivDWORD и LRESULT не всегда одно и то же.


Хм... А мне казалось - одно и тоже, по крайней мере на 32-х битах. Ну да ладно, это я тоже поправил.
Сама передача сообщений работает на ура - я сделал маленький тестовый сервер MFC Dialog based, все отлично.
Но возникла другая проблема, сегодня весь день голову ломал:
При запуске этой лабуды в vba опять же крах.
Стал разбираться. При отладке видно, что SetWindowLong с параметром -4 (GWL_WNDPROC) возвращает не адрес оконной процедуры а какуюто белиберду, при попытке обращения к которой естественно идет исключение.
Поменял на +4 (DWL_DLGPROC), стал тестировать - что то странное. На тестовом сервере (который на обычном диалоге) отрабатывает так же как и с параметром -4. На диалоге vba опять грохается, но просмотр стека дает цепочку неидентифицируемых процедур.
В связи с этим два вопроса: кто нибудь имеет опыт подмены диалоговой процедуры в vba?
Объясните пожалуйста, как получилось, что при подмене адреса хоть GWL_WNDPROC, хоть DWL_DLGPROC для "нормального" диалогового окна все проходит правильно. Что, одна процедура вызывает другую что ли?

PS: технология подмены позаимствована из статьи http://www.vbnet.ru/articles/showarticle.aspx?id=76 , там вроде GWL_WNDPROC используется.
...
Рейтинг: 0 / 0
подмена оконной процедуры - крах приложения
    #38661128
iMerlin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Провел исследования: под Spy++ проверил hWnd главного окна - все в порядке, совпадает с тем что дает Application.hWndAccessApp

Беру GetClassName, GetWindowText - все правильно, все совпадает.

Делаю ?hex(GetWindowLong(Application.hWndAccessApp,-4)) - возвращает FFFF0161, spy++ показывает 0x300bb46a
Вот это и рушит все попытки сабклассинга. Почему возвращается ошибочное значение?6258
...
Рейтинг: 0 / 0
8 сообщений из 8, страница 1 из 1
Форумы / C++ [игнор отключен] [закрыт для гостей] / подмена оконной процедуры - крах приложения
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]