Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2007.08.12;
Скачать: CL | DM;

Вниз

Вызов CHM справки из MessageBox   Найти похожие ветки 

 
[e]Bu$ter ©   (2006-12-18 00:40) [0]

По порядку:
В разработанной программе такая идея: если пользователь запускает её без параметров, то я она показывают ему MessageBox с флагами MB_ICONINFORMATION or MB_HELP.
Как и положено, при таком вызове функции, появлятеся диалог с кнопками [OK] и [HELP]. По [OK] диалог закрывается, а по [HELP] должен открываться раздел "Синтаксис командной строки" чтоб пользовательно понял как правильно нужно запускать программу. Когда же он наконец её запустит, то по F1 ему нужно показывать уже другой раздел справки - как пользоваться программой.

Вторая задачи, благодаря функции AssignHtmlHelp работает отлично, а вот первая нет - не знаю как заставить MessageBox открывать определённый топик в справке (и как вообще открывать через него справку).
Если сейчас нажимать в нем кнопку [help] то винда говорит, мол

> program.exe - обнаружена обшибка. Проложение будет закрыты.
> Приносим извинения за неудобство.
> ...


Вопросы:
№1: Кто виноват?
№2: Что делать?

Заране благодарю за помощь.

P.S.
WindowsXP2+
Delphi 7
KOL 2.39.1


 
Vladimir Kladov   (2006-12-18 04:50) [1]

Как ваш код вызывает Applet.CallHelp ?


 
[e]Bu$ter ©   (2006-12-18 10:17) [2]

Нет, он ничего не вызывает.
Когда F1 жмёшь, оно "само" открывается, я ничего не делаю :)


 
Vladimir Kladov   (2006-12-18 16:26) [3]

ну так вызовите


 
[e]Bu$ter ©   (2006-12-18 18:14) [4]

Как я по вашему могу это сделать? Т.е. где можно вызвать CallHelp?
У MessageBox ведь нет вроде "mtHelp" в списке возвращаемых значений, как узнать, что пользователь нажал именно эту кнопку (help)? И почему сейчас, когда её жмёшь, выполняется недопустимая операция?
Вот в чём восрос!


 
Vladimir Kladov   (2006-12-18 20:36) [5]

MB_HELP Windows 95/98, Windows NT 4.0 and later: Adds a Help button to the message box. When the user clicks the Help button or presses F1, the system sends a WM_HELP message to the owner.

Выделенное понятно?


 
[e]Bu$ter ©   (2006-12-18 23:19) [6]

Понятно! Большое спасибо.

Проверил в KOLForm1Message

if msg.message = WM_HELP
 then beep(1000, 200);

WM_HELP туда приходит - всё пищит. Но сразу после этого (т.е. в тот момент, когда должна открываться справка), программа выполняет "недопустимую операцию" :(

Понятное дело, что даже если вызывать её из события вручную, то всё-равно, после её открытия - "недопустипая операция".


 
[e]Bu$ter ©   (2006-12-18 23:28) [7]

Я почему такой упрямый: если за работу с CHM справкой, в данном случае, отвечает KOL, то может быть и ошибка эта идёт от туда? Или KOL тут непричём?


 
Vladimir Kladov   (2006-12-19 18:17) [8]

Есть такая фишка, как Search|Find error. Или на худой конец Tools | Debugger options | Language Exceptions | Stop on Delphi Exceptions (включить). И понять, что за AV, и почему оно.


 
[e]Bu$ter ©   (2006-12-20 00:35) [9]

Владимир, не всё так печально! Я знаю про эти фишки, и даже иногда ими пользуюсь (та которая "на худой конец", вроде как даже влкючена по дефолту). Но за подсказку спасибо, как-то со своим кодом я и без этого справляюсь обычно.

Вообщем, с их помощью удалось найти где это AV (кстати, как оно расшифровывается?) Но понять "что за оно", а главное "почему оно" у меня не получилось. Хотя, намёк всё же кое-какой есть:

Удалось выяснить, что ошибку вызывает KOL в процедуре CallWinHelp.

После первого входа в неё, ни одно условие не выполнаяется и в самом её конце выполняется
WinHelp( Applet.Handle, PChar( Applet.GetHelpPath ), Cmd, Context );
после чего, появляется сообщение, которе невозможно было заметить при обыкновенном запуске
---------------------------
Windows Help
---------------------------
Cannot find the E:\dev\program\program.hlp file. Do you want to try to find this file yourself?
---------------------------
Да   Нет  
---------------------------

* намёк я вижу в расширении файла, который оно не может найти

Потом, оно заходит в KOLForm1Message смотрит какой я там возвращаю result (ради эксперимента было false) и идёт обратно в CallWinHelp где на строке
Form.OnHelp( CtxCtl, Context, Popup ); и выполняется "недопустимая операция".

Продолжая эксперимент, я убрал свой обработчик KOLForm1Message и запустил отладку ещё раз. В этом случае оно сразу успешно дошло до Form.OnHelp( CtxCtl, Context, Popup ); и вывалилось с той же ошибкой.

В form.OnHelp у меня ничего нет. Попытки добавить что-то ни к чему не привели.

К сожалению, это всё на что я способен в данной ситауции в это время суток. :(

Скажите, есть надежда, что мы разберёмся чего там происходит?


 
Vladimir Kladov   (2006-12-20 20:21) [10]

просто назначьте OnHelp. Насчет того, почему hlp ищется, а не chm: у вас AssignHtmlHelp вызывается? (до MessageBox"а)


 
[e]Bu$ter ©   (2006-12-21 16:21) [11]


VK> просто назначьте OnHelp.


B> В form.OnHelp у меня ничего нет. Попытки добавить что-то
B> ни к чему не привели

Я пробовал. Ничего не происходило. Всё продолжало падать.


VK> у вас AssignHtmlHelp вызывается? (до MessageBox"а)

Это тоже писал, вызывается, и по F1 всё работает как надо! (включая закрытие справки, при выходе из программы).

Однако, случайно вы меня натолкнули на другую мысль! Дома проверю, отпишу...


 
[e]Bu$ter ©   (2006-12-24 15:06) [12]

Жально, но предоположение не оправдалось.

Чего я только не пробовал, но так ничего и не заработало. Но с проблемой разобрался детально.

• При вызове MessageBox"a в параметр hWnd подставлял и applet.Handle и form.Handle - но при нажатии в нём кнопки Справка, всегда появлялся AV. Если сделать hWnd = 0, то ничего не происходит.
• AssignHtmlHelp вызывается до MessageBox"a (до этого он действительно вызвалось позже. Но не смотря на то, что сейчас ошибка просиходит в процедуре CallHtmlHelp, она всё равно происходит сразу после вызова Form.OnHelp (не важно какой за ним идёт следующий оператор).
• При выполнении CallHtmlHelp, условие Assigned( Form.OnHelp ) всегда истинно, независимо от того назначен ли обработчик на это событие. Поэтому событие onHelp всегда вызывается, но в обработчик KOLForm1Help управление не доходит.
____________________________________________________

Обновился до версии KOL 2.49 (для тестирования, использую PAS_VERSION, но в ASM ошибка там же).

В итоге, AV стал вызываться из
function TControl.ParentForm: PControl;
строкой

 repeat
   Result := Result.fParent;
 until (Result = nil) or not Result.fIsControl; <- вот тут


Сам ParentForm вызывается всё из того же
CallHtmlHelp( Context: Integer; CtxCtl: PControl );,
только уже в строке
Form := CtxCtl.ParentForm;
От сюда понятно, что здесь уже совсем не важно назначен ли обрабочик на событие onHelp, т.к. AV появляется задолго до вызова Form.OnHelp, в котором он происходил раньше (в старой версии KOL).

Вообщем, грабли всё ещё на месте, правда немного другие.
Озадачивался ли кто нибудь этой проблемой? Что посоветуете делать?


 
Vladimir Kladov   (2006-12-24 17:31) [13]

Вы отладчиком пользуетесь? В нем есть возможность просматривать значения переменных. Например, @ Self. Если Handle=0, это исключения не даст. А вот если Applet=nil, то запросто.


 
[e]Bu$ter ©   (2006-12-24 19:49) [14]


> Вы отладчиком пользуетесь?

Благодаря этому глюку, начал активно пользоваться! А до этого, я уже писал, со своим кодом всегда управлялся без отладчика. Не потому что спец крутой, а потому, что задачи у меня обычно простые :)

Ещё раз код функции в которой происходит AV:
function TControl.ParentForm: PControl;
begin
 Result := @Self; {1}
 if Result.fIsControl then {2}
 repeat
   Result := Result.fParent; {3}
 until (Result = nil) or not Result.fIsControl; {4}
end;

AV выскакивает в [4] и всё останавливается на этой строке.

Смотрю переменные в соответсвующих строках
[1]: Result = $680012FE
[2]: flsControl = inaccessible value
[3]: Result = $680012FE; fParent = inaccessible value
[4]: Result = $680012FE; flsControl = inaccessible value

Поставил "бряк" на эту функцию и запустил программу. Во всех переменных что-то есть. Вот собсвтенно и причина пораждавшая AV.

Осталось выяснить, почему когда эта функция вызвается, нужные свойства оказываются уже недоступны.

__________________________________________

Запустил программу полностью, подсунув через Menu -> Run -> Parametrs... нужные для успешного запуска опции. Т.е. теперь как бы и Applet и form созданы.

Отрываю тот диалог, который показывается если параметры ком. строки при запуске заданы были не верно, и жму в нём кнопку "Справка".
Получаю AV в функции
function WndProcHelp( Sender: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
на строке

...
   begin
     {$IFDEF USE_PROP}
     Ctl := Pointer( GetProp( HI.hItemHandle, ID_SELF ) );
     {$ELSE}
     Ctl := Pointer( GetWindowLong( HI.hItemHandle, GWL_USERDATA ) );
     {$ENDIF}
     while Ctl <> nil do
     begin
       Ctx := Ctl.fHelpContext; {<-- вот тут}
       if Ctx <> 0 then break;
       Ctl := Ctl.Parent;
     end;
   end
....


Стазу смотрю отладчиком
fHelpContext = inaccessible value

Что теперь делать то? Я в отчаяньи...


 
Vladimir Kladov   (2006-12-24 20:27) [15]

в вашем цикле нет проверки, что достигнут nil.
inaccessible для поля или члена бывает, если указатель объекта/структуры указывает в никуда.


 
[e]Bu$ter ©   (2006-12-24 20:52) [16]


> в вашем цикле нет проверки, что достигнут nil.

В каком именно, первом repeat или втором while?  

И позвольте, разьве это мой цикл? :) Это ж всё из kol.pas


 
Vladimir Kladov   (2006-12-25 17:09) [17]

В вашем- потому что вы его здесь привели. Смотрите, уже в этой строчке
if Result.fIsControl then {2}
[2]: flsControl = inaccessible value
Скорее всего @Self - это уже что-то левое. Можно в Watch-окне (ctrl+shift+W) посмотреть значение переменных Applet, Form1 или что у вас там (если MCK, то Form1.Form) и сравнить с @Self.


 
[e]Bu$ter ©   (2006-12-26 21:55) [18]

Сначала немного дополню предыдущие посты, дабы уточнить картину:
MessageBox вызывается сразу за AssignHtmlHelp в самом начале обработчика KOLForm1FormCreate. Но даже если вызывать его когда программа уже полнотью запущена, .... дальше я уже писал в предыдущем посте [14].

Вот содержимое Self взятое на строке {2} (на ней сейчас всё остановлено):
 Result := @Self; {1}
 if Result.fIsControl then {2}
 repeat
   Result := Result.fParent; {3}
 until (Result = nil) or not Result.fIsControl; {4}


после того как я нажал в MB"е кнопку "Справка":

(264638, $14F6D8, $14F070, 16448, (0, 0), 0, 0, 0, 0, 1244428, 1244444, 2, 0, True, 4278190080, True, True, (out of bound) -1, nil, True, $680012FE, True, True, True, 264638, (out of bound) -40, (out of bound) -10, True, False, 1372272, 16448, nil, $FFFFFFFF, $148398, $14DCA0, $40C6C8, $14F070, $14F6D8, $12FEF0, $77D8057F, True, 67109897, -134201207, 1073758344, $40, False, False, False, -1, 1244940, $77D80537, 264638, $408904, $4088F8, $4040, nil, True, True, True, False, True, True, 64, False, 190, True, 2298740740, 2297954368, True, 4210688, [], True, -536854382, True, -1774649326, True, $1451C000, False, $14DCA0, 4245192, nil, nil, nil, nil, nil, nil, False, False, nil, nil, False, False, 0, 0, nil, nil, nil, 0, (0, 0, 0, 0, (0, 0), (0, 0)), 1373736, 1373800, 0, 1245120, True, True, True, False, 5, $7FFDE000, $7C90E64E, $FFFFFFFE, 9, True, $D70012FF, True, True, 1404, 256, $FDE00000, True, -2141935304, $12FFC8, 200, -8295372, -1459617793, $7C816F, (0, 0), False, False, $40A51C00, nil, False, True, $1000000, $C4000024, $20000000, $14000000, $6000000, False, $340000, $10000, nil, nil, $20000, nil, (nil, $2100000, 0, 412, 0, 0, 0, 18779, 11609, 940, 0, 50, 0, 992, 0, 718, 0, 0, 0, 228, 2, 33538, 1712, 0, 70, 0, 1784, 0, 742, 0, 0, 0, 54738, 53644, 2528, 0, 0, 70, 0, 0, 2600, 0, 742, 0, 0, 0), $D10, $D58, $10, $D4, $1, (276, 3960, 1, 2, 4236, (796, 1)), $13A8, $2, $23F8, 124, 2, 1682469715, 44, 1, $1, 1, 5, 132, 1, [lvoButton,lvoNoSortHeader,lvoMultiselect..lvoGridLines], (out of bound) 44, $56000000, 0, 0, nil, nil, 0, 0, nil, caNone, False, $2000, False, True, (1140850688, 1543518720), (1224759040, 1476414976), (1543524352, 1761629952), (1392537088, 1929410560), 23552, 0, 0, $FC000000, $9C000000, $5B000000, (2553108809, 838860802, 3422552064, -838860798, 33554434, 3825205248, 2, 2, ("ѓ", "њ", #5, #0, #0, "F", #0, #0, #0, "д", #5, #0, #0, "ж", #2, #0, #0, #3, #0, #0, #0, "Т", "Х", "Њ", "С", "М", #8, #0, #0, "F", #0, #0), 5120, 9, -6656, 67108866, 771751936, 4242041517, 11, 17920, 0, 0, 0, 68), 12, $5000003, 167

Как я понимаю, это всякие свойства формы. Т.е. Self как будто-бы куда-то правильно указывает...

Но в строке {1}, да и в {2} тоже, result всё ещё "равен" inaccessible value. После выполнения строки {3}, везде появляются какие-то значения, но видимо - "левые". Отсюда и AV.

Как-то это всё побороть?


 
Vladimir Kladov   (2006-12-27 18:01) [19]

я что-то сильно сомневаюсь, что в свойствах формы будет (out of bound) или строки вроде этой: ("&#402;", "&#339;", #5, #0, #0, "F",
Я же сказал, как проверить: сравнить @ Self как указатель с указателем формы, апплета, что там еще есть.


 
[e]Bu$ter ©   (2006-12-28 00:22) [20]

Владимир, извините, очень не хочется вынуждать вас опускаться до моего уровня и разьяснять "на пальцах", что и как нужно делать (я так понимаю, сейчас мы занимается удалённой пооошааагооовооой отладкой) в этой ситуации, но я к сожалению не совсем понимаю, что значит

> сравнить @ Self как указатель с указателем формы, апплета,
> что там еще есть.

Где его взять, этот "указатель формы"? И что значит "@self как узазатель"? И почему выпишете "@" и "Self" через пробел? Вообщем, вопросов много...

Сейчас однозначно ясно, что до выполнения строки (первый раз)
Result := Result.fParent;
у Result, все свойства (поля, члены?) содержат вразумительные значения. Но на очеденой (в нашем случае - всегда самой первой) итерации, Result начинает указывать вникуда, и естественно, следующая строка
until (Result = nil) or not Result.fIsControl;
порождает AV.

Вам, как отцу KOL (и не только :)), зная механизмы работы библиотеки гораздо проще понять почему (из-за чего) это просиходит. Прошу у вас помощи. Новогодний релиз прогорит по ходу...


 
[e]Bu$ter ©   (2007-01-01 13:48) [21]

1) Как я только в Watch List не добавлял этот @Selft, но значение у него появилось там только один раз. Я правда так и не понял как это получилось, но тогда оно точно не совпадало со значением (адресом) form1.form. Подозрительно то, что оба они имели какие-то старнные по виду значения первое EEEEFEFE, а другое FEEEEEFE (данные приблизительные).
Во всех остальных попытках @Self "был равен" Variable "Self" inaccessible here due to optimization.

2) Зная, что сообщение WM_HELP "perent"у" посылается когда ещё форма до конца не создана (в самом начале KOLForm1FormCreate), возникает вопрос: а возможно ли тут в принципе реализовать так задуманное? Что считается parent"ом когда формы ещё нет?


 
Vladimir Kladov   (2007-01-01 14:56) [22]

Так о том и речь. Чтобы форсировать создание дескриптора окна, надо не просто к Handle обратиться, но вызвать GetWindowHandle. А если Applet"у ничего не присвоено, то чего вы хотите от него вообще.



Страницы: 1 вся ветка

Текущий архив: 2007.08.12;
Скачать: CL | DM;

Наверх




Память: 0.55 MB
Время: 0.036 c
15-1184160100
IMHO
2007-07-11 17:21
2007.08.12
Слово о дефиците


15-1184343999
tesseract
2007-07-13 20:26
2007.08.12
Питер буду часов в 8 утра.


9-1157611526
Kobik.
2006-09-07 10:45
2007.08.12
Z-Буфер и полноэкранный режим


2-1184347870
nord489
2007-07-13 21:31
2007.08.12
Работа с файлами


1-1181139901
Terr
2007-06-06 18:25
2007.08.12
Проблема с выбором драйвера базы данных