Форум: "KOL";
Текущий архив: 2007.08.12;
Скачать: [xml.tar.bz2];
ВнизВызов 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) или строки вроде этой: ("ƒ", "œ", #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 вся ветка
Форум: "KOL";
Текущий архив: 2007.08.12;
Скачать: [xml.tar.bz2];
Память: 0.53 MB
Время: 0.058 c