Конференция "KOL" » ToolBar+TrackBar=AccessViolation [Delphi, Windows]
 
  • QAZ (22.06.09 13:56) [0]
    если положить TrackBar на ToolBar то при наведении мыши вылетает нафиг все :(
  • Vladimir Kladov © (22.06.09 21:52) [1]
    Ну и не лодите его на тулбар. Можно панелями без бордюров отрегулировать так, что будет казаться, что он на нем лежит. А можно использовать KOLTracker.
  • Dy1 (23.06.09 01:04) [2]

    > А можно использовать KOLTracker

    где взять? На kolmck.net пишет не найден
  • Galkov (23.06.09 14:03) [3]
    Владимир, вообще-то это плохо, что CommnonControl не может наследовать такого же.

    Неужели отсутствие простенького условия проверки "на самого себя" настолько уж экономит код, что надо создавать реальные виндячие окна.

    По-моему, всему есть пределы разумного.
  • Vladimir Kladov © (23.06.09 15:53) [4]
    Galkov

    Вообще ничего не понял. Какой проверки на себя, какое наследование?
  • Vladimir Kladov © (23.06.09 15:57) [5]
    Dy1

    KolTracker на сайте переименовал, теперь должен браться.
  • Galkov (24.06.09 13:44) [6]

    > Вообще ничего не понял

    Вот те раз :shock:
    Мне казалось что все давно все знают, но есть какие-то очень давние "философские причины" против эдакого фикса....

    function WndProcNotify( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
    var NMhdr: PNMHdr;
       Child: PControl;
    begin
     Result := False;
     ..............
       // вот оно - дерево
       if (Child <> nil)and(Child<>Self_) then // а вот - мужик в пиджаке
       begin
         Msg.hwnd := Child.fHandle;
         Result := EnumDynHandlers( Child, Msg, Rslt );
       end;
     end;
    end;



    У того самого Child-а тоже может сидеть в аттачах WndProcNotify (что как раз и фиксится промежуточной панелью), который найдет теперь уже сам себя.
    Ну и будет этим заниматься по исчерпании стека.
  • Vladimir Kladov © (24.06.09 16:18) [7]
    Нет, этого фикса я не помню. А с чего это вдруг, это документировано в MSDN, что какие-то нотификации WM_NOTIFY для тулбара приходят не к его родителю, а к нему самому? Или это оно только в KOL так бывает?
  • Galkov (24.06.09 18:45) [8]
    А вот тут я уже ничего не понял в вопросе :)

    Мне казалось, что все, всегда, везде, и всю жизнь - к родителю.
    И это, вроде бы, никак вышеизложенному коду не противоречит.

    Обнаружил это безобразие я еще когда "подрихтовывал" TabControl под NEW_ALIGN
    Внедрил TControl.TC_InsertControl, и получил возможность влепить в качестве странички - тот же TabControl напрямую,  "мимо промежуточной панели".
    Да и возможность прилепить к нему ToolBar с Align=caBottom - тоже стала осмысленной (правильный align) именно в тот момент.

    Ну должен же я был разобраться - а вдруг это мое творчество
    Не, не мое.
    Вот не помню только, отписывался ли....
  • Galkov (24.06.09 19:29) [9]
    Не знаю... На всякий случай, может быть так:

    > У того самого Child-а тоже может сидеть в аттачах WndProcNotify

    Не, вовсе не потому, что он создан через _NewCommonControl !!!
    А потому что какой-то Child этого нашего Child-а ТОЖЕ создан через _NewCommonControl

    Ну или, если ссылаться на старт-топера:
    1) аттач WndProcNotify сидит на главной форме, и положил его туда конструктор ToolBar-а
    2) А Child-ом и является этот самый ToolBar
    3) Но среди аттачей ToolBar-а тоже есть WndProcNotify, потому что положил его туда уже конструктор TrackBar-а.
    4) Ну вот TrackBar и есть тот самый Child для Child-а того WndProcNotify, который приаттачен к форме.
  • Galkov (25.06.09 15:39) [10]
    В общем, пока суд да дело, я сделал ASM-версию этого фикса, и теперь знаю точную цену вопроса.
    Она - 6 байт кода. С учетом выравнивания - 4 байта. Короче - не получилось :(

    function WndProcNotify( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
    asm
           CMP      word ptr [EDX].TMsg.message, WM_NOTIFY
           JNE      @@ret_false
           PUSHAD
           MOV      ECX, [EDX].TMsg.lParam
           {$IFDEF USE_PROP}
           PUSH     offset[ID_SELF]
           PUSH     [ECX].TNMHdr.hwndFrom
           CALL     GetProp
           {$ELSE}
           PUSH     GWL_USERDATA
           PUSH     [ECX].TNMHdr.hwndFrom
           CALL     GetWindowLong
           {$ENDIF}
           SUB      EAX,[ESP+28]     // saved EAX=Self_
           JZ       @@ret_false_ECX  // Child=Self_ ???
           ADD      [ESP+28],EAX
           JZ       @@ret_false_ECX  // Child=nil ???
           POPAD
           PUSH     [EAX].TControl.fHandle
           POP      [EDX].TMsg.hwnd
           JMP      TControl.EnumDynHandlers
    @@ret_false_ECX:
           POPAD
    @@ret_false:
           XOR      EAX, EAX
    end;



    Тестировал на примере коллеги из соседнего топика: http://pda.delphimaster.net/?id=1243251080&n=10,
    приклеивши к нему по-быстрому пару "убийственных" срок:

    PBar       := NewProgressBar(TabControl).SetSize(160, 20);
    PBar.Align := caBottom;



    В общем, Владимир, теперь это уже получается законченное предложение, наверное.
  • Vladimir Kladov © (25.06.09 21:05) [11]
    Разве ж я возражаю по поводу размера? Просто надо было мне понять, что происходит. Получается, такая же штука случалась при попытке положить любой коммон контрол на любой другой коммон контрол в качестве дочернего. Просто ни разу не приключалось такого, чтобы мне такое удочерение пригодилось.

    Фикс на Паскале работает хорошо.

    Galkov
    А это что?
    ...

          SUB      EAX,[ESP+28]     // saved EAX=Self_
          JZ       @@ret_false_ECX  // Child=Self_ ???
          ADD      [ESP+28],EAX



    Если Child <> Self_ то в EAX какое-то число <> 0 (равное EAX-Self_),
    далее это число добавляется зачем-то к Self_ ... что будет-то?
    Может, вторая команда сравнения должна быть
    ADD EAX, [ESP+28] ?
  • Galkov (25.06.09 21:35) [12]

    > А это что?

    А это все нормально, по-моему: в EAX было не какое-то число, а Child. И стало после SUB соответственно: Child-Self_
    Прибавление (ADD) должно давать результат не в EAX, а именно в [ESP+28] нужный нам Child: (Child-Self_)+Self_=Child
    Потому-что последующий POPAD именно его в EAX и поместит (и очень нужные нам EDX, ECX - тоже).
    И одновременно и признак ZF показывает чего надо - равенство нулю Child-а

    Да не, все тут нормально вроде.
  • QAZ (26.06.09 10:53) [13]
    ура ! Galkov респект
    хоть ктото задумывается о том как должно быть, а не то что "подсунь панель" и все нормал .тем более что в VCL и диалогах таких прогонов нет

    кстати а как там таб контрол без панели сделать ?
  • Galkov (26.06.09 13:52) [14]

    > кстати а как там таб контрол без панели сделать ?


    program TabTest;
    uses KOL;
    var TabControl: PControl;
    begin
     Applet     := NewForm(nil,'My Super-Puper-Test-Editor').SetSize(320,240);
     TabControl := NewTabEmpty(Applet,[],nil).SetAlign(caClient);
     TabControl.TC_InsertControl(0,'Page 0',0,NewEditbox(TabControl,[eoMultiline]).SetAlign(caClient));
     TabControl.TC_InsertControl(1,'Page 1',0,NewEditbox(TabControl,[eoMultiline]).SetAlign(caClient));
     Run(Applet);
    end.

  • Vladimir Kladov © (26.06.09 16:33) [15]
    ОК, поправку понял. Надо было первоначальный и паскалевский исходник глядеть.

    QAZ
    Панель -очень неплохой вариант. Когда вы обнаружите проблемы с выравниванием на тулбаре. Решение этой проблемы не то что с 6, а то и с 600 байтами может не получится, так не проще ли сделать панельку.
  • QAZ (27.06.09 18:34) [16]
    да панель у меня уже 2 года используеца
    просто если есть ошибка, почемуб ее не исправить а не игнорировать (страно что тракбар вообще не в составе кол)
    иначе она ещо гденить проявица,и хватит уже байты считать - компактная глюкавость хуже чем сотня лишних байтов
  • Vladimir Kladov © (27.06.09 22:26) [17]
    Не в составе, потому что редко нужен. А когда нужен, оказывается, что лучше без него.
 
Конференция "KOL" » ToolBar+TrackBar=AccessViolation [Delphi, Windows]
Есть новые Нет новых   [119008   +13][b:0][p:0.002]