Экспертная система Delphi.int.ru

Сообщество программистов
Общение, помощь, обмен опытом

Логин:
Пароль:
Регистрация | Забыли пароль?

Delphi.int.ru Expert

Другие разделы портала

Переход к вопросу:

#   

Статистика за сегодня:  


Лучшие эксперты

Подробнее »



Вопрос # 5 713

/ вопрос открыт /

Здравствуйте!
Установлен хук на создание окон(WH_CBT). Если главное окно программы порождает дочернее то хук работает, и выполняет все написанные действия. Проблема в том что когда уже открытое дочернее окно пытается породить другое окно то всё не на долго зависает и программа закрывается с предложением отправить отчёт об ошибке.

Код в DLL откоментирован, для более легкого понимания что я делаю.
Класс создаваемого окна которое вызывает ошибку: #32770

Приложение:
  1. uses
  2. SysUtils,
  3. Classes,
  4. Windows,
  5. Messages;
  6.  
  7.  
  8. var
  9. HookHandle: HHook;
  10. ParentHandle, WindowHandle1, WindowHandle2, WindowHandle3, WindowHandle4: THandle;
  11. TId, HLibrary: DWORD;
  12.  
  13.  
  14. {$R *.res}
  15.  
  16.  
  17.  
  18. function CBTHook(Code: Integer; WParam, LParam: DWord): Longint; stdcall;
  19. begin
  20. Result:=CallNextHookEx(HookHandle, CODE, WParam, LParam);
  21.  
  22.  
  23. case CODE of
  24. HCBT_CREATEWND:
  25. begin
  26.  
  27. if (PCBTCreateWnd(LParam).lpcs.lpszClass = 'ChildEXEClass') and (WindowHandle1 = 0) then
  28. begin
  29. PCBTCreateWnd(LParam).lpcs.cx:= 795;
  30. PCBTCreateWnd(LParam).lpcs.cy:= 575;
  31. PCBTCreateWnd(LParam).lpcs.x:= -1;
  32. PCBTCreateWnd(LParam).lpcs.y:= -10;
  33. WindowHandle1:= WParam;
  34. end
  35. else
  36. if (PCBTCreateWnd(LParam).lpcs.lpszClass = 'ChildEXEClass') and (WindowHandle2 = 0) then
  37. begin
  38. PCBTCreateWnd(LParam).lpcs.cx:= 795;
  39. PCBTCreateWnd(LParam).lpcs.cy:= 575;
  40. PCBTCreateWnd(LParam).lpcs.x:= 485;
  41. PCBTCreateWnd(LParam).lpcs.y:= -10;
  42. WindowHandle2:= WParam;
  43. end
  44. else
  45. if (PCBTCreateWnd(LParam).lpcs.lpszClass = 'ChildEXEClass') and (WindowHandle3 = 0) then
  46. begin
  47. PCBTCreateWnd(LParam).lpcs.cx:= 795;
  48. PCBTCreateWnd(LParam).lpcs.cy:= 575;
  49. PCBTCreateWnd(LParam).lpcs.x:= -1;
  50. PCBTCreateWnd(LParam).lpcs.y:= 420;
  51. WindowHandle3:= WParam;
  52. end
  53. else
  54. if (PCBTCreateWnd(LParam).lpcs.lpszClass = 'ChildEXEClass') and (WindowHandle4 = 0) then
  55. begin
  56. PCBTCreateWnd(LParam).lpcs.cx:= 795;
  57. PCBTCreateWnd(LParam).lpcs.cy:= 575;
  58. PCBTCreateWnd(LParam).lpcs.x:= 485;
  59. PCBTCreateWnd(LParam).lpcs.y:= 420;
  60. WindowHandle4:= WParam;
  61. end
  62. else
  63.  
  64.  
  65. if PCBTCreateWnd(LParam).lpcs.lpszClass = 'MessageBoxRegisterClass' then
  66. begin
  67. PostMessage(WParam, wm_Close, 0, 0);
  68. end
  69. else
  70.  
  71.  
  72. if PCBTCreateWnd(LParam).lpcs.lpszClass = 'LoginWin' then
  73. begin
  74. //
  75. //
  76. end;
  77.  
  78. end;
  79.  
  80.  
  81. HCBT_DESTROYWND:
  82. begin
  83.  
  84.  
  85. if WParam = WindowHandle1 then WindowHandle1:= 0 else
  86. if WParam = WindowHandle2 then WindowHandle2:= 0 else
  87. if WParam = WindowHandle3 then WindowHandle3:= 0 else
  88. if WParam = WindowHandle4 then WindowHandle4:= 0 else
  89. Exit;
  90. end;
  91.  
  92.  
  93.  
  94.  
  95.  
  96. end;
  97. end;
  98.  
  99.  
  100.  
  101.  
  102.  
  103.  
  104. procedure SetCreateWindowHook; stdcall; export;
  105. begin
  106. if HookHandle = 0 then
  107. begin
  108. WindowHandle1:= 0;
  109. WindowHandle2:= 0;
  110. WindowHandle3:= 0;
  111. WindowHandle4:= 0;
  112. HLibrary:= LoadLibrary('MovWin32.dll');
  113. ParentHandle:= FindWindow('ParentEXEClass',nil);
  114. TId:= GetWindowTask(ParentHandle);
  115. HookHandle:=SetWindowsHookEx(WH_CBT, @CBTHook, HLibrary, TId);
  116. end;
  117. end;
  118.  
  119.  
  120.  
  121.  
  122. procedure DelCreateWindowHook; stdcall; export;
  123. begin
  124. if HookHandle <> 0 then
  125. begin
  126. UnhookWindowsHookEx(HookHandle);
  127. HookHandle:=0;
  128. end;
  129. end;


Примечание #1 (3 ноября 2011, 18:03):
Хук разумеется не системный.

Собственно не понятно следующее:
Почему происходит эта ошибка. Я ведь не трогаю в своей DLL окна с классом #32770.
Как локализовать проблему, с чего нужно начинать.
Спасибо всем кто отзовётся.

QWERYTY Вопрос ожидает решения (принимаются ответы, доступен мини-форум)

Вопрос задал: QWERYTY (статус: Посетитель)
Вопрос отправлен: 3 ноября 2011, 17:52
Состояние вопроса: открыт, ответов: 0.


Мини-форум вопроса

Всего сообщений: 7; последнее сообщение — 5 ноября 2011, 10:53; участников в обсуждении: 2.
bugmenot

bugmenot (статус: 3-ий класс), 4 ноября 2011, 16:34 [#1]:

Хрустальный шар говорит мне, что мистическая ошибка - access violation. И еще, #32770 похоже на атом, а не на строку.
виконання програми розпочинається з того самого мiсця, де призупинилося.

QWERYTY

QWERYTY (статус: Посетитель), 4 ноября 2011, 21:28 [#2]:

Не знаю атом там или молекула или ядро, но WNDINFO указывает именно такой класс.

По части access violation, как распознать и вылечить?
ВЕРИТЬ ВО ВНЕЗЕМНЫЕ ЦИВИЛИЗАЦИИ НЕ ОЗНАЧАЕТ ВЕРИТЬ В ИНОПЛАНЕТЯН.
QWERYTY

QWERYTY (статус: Посетитель), 5 ноября 2011, 00:34 [#3]:

#32770 The class for a dialog box.

Это из MSDN.

Так же узнал что # в делфи сообщает что оставшуюся часть строки нужно преобразовать в атом. Вот функции и находят когда указываешь в качестве класса #32770 атом 0x8002.

При чём тут всё это?
ВЕРИТЬ ВО ВНЕЗЕМНЫЕ ЦИВИЛИЗАЦИИ НЕ ОЗНАЧАЕТ ВЕРИТЬ В ИНОПЛАНЕТЯН.
QWERYTY

QWERYTY (статус: Посетитель), 5 ноября 2011, 00:53 [#4]:

Инфа об окне, приводящем к ошибке:

1. Окно не блокирует окно его породившее. Т.е. не происходит так как например при сохранении файлов, когда становится невозможным передвинуть главное окно программы.

2. Окно порождает ещё 8 хендлов разного класса: три кнопки, один эдит и 4 аналога Label в делфи.

3. Окно не имеет заголовка.
ВЕРИТЬ ВО ВНЕЗЕМНЫЕ ЦИВИЛИЗАЦИИ НЕ ОЗНАЧАЕТ ВЕРИТЬ В ИНОПЛАНЕТЯН.
QWERYTY

QWERYTY (статус: Посетитель), 5 ноября 2011, 01:08 [#5]:

Проклятье какое-то.
Это первое что я закодил без вяких манёвров, обходных путей.
И задача была бы решена на прямую, в лоб, если бы не этот БАГ.
Хотел снимать перед открытием этого окна хук, а по закрытии ставить обратно, но при этом почемуто обнуляются переменные в DLL(код где я их сам обнуляю был закоментен), хотя грузится она не динамически.
Ну и разумеется не имею событий по которым я бы мог снимать и ставить хук.
ВЕРИТЬ ВО ВНЕЗЕМНЫЕ ЦИВИЛИЗАЦИИ НЕ ОЗНАЧАЕТ ВЕРИТЬ В ИНОПЛАНЕТЯН.
QWERYTY

QWERYTY (статус: Посетитель), 5 ноября 2011, 10:34 [#6]:

Проблема с этим грёбаным атомом.
Если главное окно программы пытается создать окно с классом #32770, то так же всё подвисает, идёт активная работа с жёстким диском после чего появляется окно что программа будет закрыта.

Я пробовал написать код для окон с классом #32770 в своей DLL, но эффекта 0. Как только пытаешся вызвать окно, немедленно происходит зависон.
ВЕРИТЬ ВО ВНЕЗЕМНЫЕ ЦИВИЛИЗАЦИИ НЕ ОЗНАЧАЕТ ВЕРИТЬ В ИНОПЛАНЕТЯН.
QWERYTY

QWERYTY (статус: Посетитель), 5 ноября 2011, 10:53 [#7]:

А вот эта информация о чём говорит?

Exception information
Code: 0xc0000005 Flags: 0x00000000
Record: 0x0000000000000000 Address: 0x0000000005b63b7f
ВЕРИТЬ ВО ВНЕЗЕМНЫЕ ЦИВИЛИЗАЦИИ НЕ ОЗНАЧАЕТ ВЕРИТЬ В ИНОПЛАНЕТЯН.

Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.

Версия движка: 2.6+ (26.01.2011)
Текущее время: 22 февраля 2025, 11:46
Выполнено за 0.02 сек.