2 buggs in MDI Child code + source code solution {v6.53}

Viewing 20 posts - 1 through 20 (of 22 total)
  • Author
    Posts
  • #33515
    Pontus
    Participant

    v6.53

    unit sSkinProvider;

    procedure TsSkinProvider.NewWndProc(var Message: TMessage);

    //Bugg #1; MDI Child with a MainMenu will not paint correctly!
    //Line 2658
    if (SkinData.CtrlSkinState and ACS_LOCKED = ACS_LOCKED) or (SkinData.CtrlSkinState and ACS_MNUPDATING = ACS_MNUPDATING) or ((Form.Menu <> nil) and (Form.Menu.WindowHandle = 0)) then Exit; {v6.53}

    //Alter to this
    if (SkinData.CtrlSkinState and ACS_LOCKED = ACS_LOCKED) or (SkinData.CtrlSkinState and ACS_MNUPDATING = ACS_MNUPDATING) or ((Form.Menu <> nil) and (Form.Menu.WindowHandle = 0) and (Form.FormStyle<>fsMDIChild)) then Exit; {v6.53}

    //Bugg #2; Closing a not maximized MDI Child with it's [X] will give you an access violation
    //Line 2984
    Application.ProcessMessages;

    //Comment out line 2984
    // Application.ProcessMessages;

    If line 2984 can't be commented out, this line will break;
    //Line 3499
    else if BetWeen(CurrentHT, HTUDBTN, HTUDBTN + TitleButtons.Count – 1) then begin

    Because TitleButtons will be nil. It is freed at line 1360 after Application.ProcessMessages executes;
    //Line 1360
    if Assigned(FTitleButtons) then FreeAndNil(FTitleButtons);

    So to keep line 2984 as it is, line 3499 must be altered;
    //Line 3499 alter to this
    else if (TitleButtons<>nil) and BetWeen(CurrentHT, HTUDBTN, HTUDBTN + TitleButtons.Count – 1) then begin

    also; every line that contains TitleButtons.Count must be secured with (TitleButtons<>nil) since we don't know if TitleButtons will be nil or not.

    [ 1. Create new MDI children under the Windows menu.
    2. Note that the caption does not display correctly.
    3. If you clear the MainMenu property on the MDI child and then run the application you will get a correct caption but an access violation if you try to close the MDU Child window.

    Apply the above suggested source code corrections and all works as expected.

    [Edit>]

    Best regards,
    /Pontus

    #41480
    HeDiBo
    Participant

    This is another example why one should never ever use Application.ProcessMessages. You absolutely loose control over all your visual elements and anything can happen. We've learned this the hard way.

    Let's look at an example from AC6.53:
    Lines 2141 and 2142 of acDials.pas read:
    Application.ProcessMessages;
    SystemMenu.UpdateItems;

    Are you sure the SystemMenu.UpdateItems will go right? Isn't there anything the user can have done in the past, that surfaces because of the Application.ProcessMessages and now will invalidate the System Menu? Or make it impossible to do UpdateItems correctly?

    That's why we never ever use Application.ProcessMessages.

    Unfortunately AC contains 9 instances of this statement.

    #41481
    Pontus
    Participant

    Hi!
    You're right. If you need to use Application.ProcessMessages there's always a better way. Not easier but better.

    I really like AC and I'd like it to be at it's best. That's why I presented a solution to the two unwanted side effects (buggs). And I really hope it makes it into the next release or I'll have to patch sSkinProvider.pas every time util it does.

    Perhaps we (the users of AC) should put together test cases (applications) that can be used to ensure certain functionality. In my case I would put together an MDI test app that ensures that the expected functionality works ok. Then the devlopers of AC can run these apps and check that nothing is broken in the new release.

    I'm sure there are many minimalistic apps in this forum that proves the existense of a bugg or two.

    /Pontus

    #41485
    HeDiBo
    Participant

    QUOTE (Pontus @ Jan 22 2010, 07:00 PM) <{POST_SNAPBACK}>
    Perhaps we (the users of AC) should put together test cases (applications) that can be used to ensure certain functionality. In my case I would put together an MDI test app that ensures that the expected functionality works ok. Then the devlopers of AC can run these apps and check that nothing is broken in the new release.

    I'm sure Serge (who is the developer of AC) has an extensive test set that he runs before releasing a new version. But we may be able to help him with specifiic test cases, indeed

    #41514
    Support
    Keymaster

    Hello and thanks for messages, problem will be solved in the nearest release.
    I know that ProcessMessages is not a good way, but sometimes this procedure is used for solving problems which can't be solved by other way or solution is not found.

    #41516
    Pontus
    Participant

    Hi!
    You can use ProcessMessages in this case, but you'll have to make sure that you check whether objects are still there or not.

    Best regards,
    /Pontus

    #41517
    Support
    Keymaster

    QUOTE (Pontus @ Jan 27 2010, 02:32 PM) <{POST_SNAPBACK}>
    You can use ProcessMessages in this case, but you'll have to make sure that you check whether objects are still there or not.


    Yes, of course, thank you

    #41523
    Peter007de
    Participant

    Hello all,

    i get a AV if i close my application.
    compiled with : Delphi 7
    madExcept version : 3.0k
    callstack crc : $63554f7e, $d827b1b5, $d827b1b5
    contact name : …
    exception number : 1
    exception class : EAccessViolation
    exception message : Access violation at address 63554F7E. Read of
    address 63554F7E.

    main thread ($b5c):
    63554f7e +00 ???
    7c91e470 +10 ntdll.dll KiUserCallbackDispatcher
    00403ccc +08 CockpitV2.exe System TObject.Free
    004dc797 +07 CockpitV2.exe Controls DoneControls
    004dca23 +23 CockpitV2.exe Controls Finalization
    004047d6 +36 CockpitV2.exe System FinalizeUnits
    0044f140 +54 CockpitV2.exe madExcept InterceptFinalizeUnits
    00404a9d +59 CockpitV2.exe System @Halt0
    007c1890 +f8 CockpitV2.exe CockpitV2 182 +25 initialization

    This problem is not on every PC.
    And if you debug in delphi is also no problem
    Maybe Application.ProcessMessage Problem is fault ?

    #41531
    Support
    Keymaster

    Hello
    ProcessMessages is called only when Border Icon of the form is clicked or when MDI-child closed.
    Do you know when your error occurs? Could you receive a more detailed log-file with a call stack?

    #41540
    Anonymous

    QUOTE
    //Bugg #2; Closing a not maximized MDI Child with it's [X] will give you an access violation


    QUOTE ( @ Jan 27 2010, 02:30 PM) <{POST_SNAPBACK}>
    Hello and thanks for messages, problem will be solved in the nearest release.
    I know that ProcessMessages is not a good way, but sometimes this procedure is used for solving problems which can't be solved by other way or solution is not found.

    I get this AV also with a new Version (6.54). Direct after ProcessMessages.

    #41560
    Support
    Keymaster

    Are you sure? Could you upload the demo there? (Sources and Exe)
    Thanks.

    #41579
    HeDiBo
    Participant

    This is a sure place to get an AV:

    Module sFrameBar.pas contains:

    CODE
    if Assigned(acMagnForm) then SendMessage(acMagnForm.Handle, SM_ALPHACMD, MakeWParam(0, AC_REFRESH), 0);
    if Steps > 0 then Application.ProcessMessages;
    end;
    FadingForbidden := False;
    inc(sHeight, BorderWidth + 2 * integer(BorderStyle = bsSingle));
    if VertScrollBar.Range <> sHeight then VertScrollBar.Range := sHeight;
    Arranging := False;
    UpdateWidths;
    if Showing then
    RedrawWindow(Handle, nil, 0, RDW_ALLCHILDREN or RDW_INVALIDATE or RDW_ERASE or RDW_FRAME);
    if Assigned(acMagnForm) then SendMessage(acMagnForm.Handle, SM_ALPHACMD, MakeWParam(0, AC_REFRESH), 0);
    MouseForbidden := False;
    Application.ShowHint := AppShowHint;
    ShowHintStored := False;

    If anywhere before the Steps > 0 test the user has closed the form containing the sFrameBar or has closed the acMagnForm, he/she will get an access violation.
    This is just one example. Have a look in sPageControl for another one.

    #41596
    Support
    Keymaster

    Do you know a solution for updating controls in the animation process?
    Animation will not exists without ProcessMessages procedure I think…

    #41597
    HeDiBo
    Participant

    QUOTE (Support @ Feb 3 2010, 12:39 PM) <{POST_SNAPBACK}>
    Do you know a solution for updating controls in the animation process?


    In this topic OnPaint cannot contain Application ProcessMessages I included a testfile AppHang.rar.

    That archive contains two components: a threaded timer (TThreadedTimer) and an animated bitmap (TAuAnimBmp) that uses the timer to refresh. It does not use an Application.ProcessMessages statement.

    Maybe that's the idea you're looking for.

    The threaded timer is Open Source, so you can include it in the AC components.

    #41625
    Support
    Keymaster

    Thank you, I'll try to use TThreadedTimer. Can I change this code and use a changed code in the package?

    #41626
    HeDiBo
    Participant

    QUOTE (Support @ Feb 9 2010, 11:31 AM) <{POST_SNAPBACK}>
    Thank you, I'll try to use TThreadedTimer. Can I change this code and use a changed code in the package?


    I've included the author's license file, so you can see for yourself, it's totally free to use and modify (the author qualifies it as freeware).[attachment=3747:README.TXT]

    #41629
    Support
    Keymaster

    Thank you.
    I have have a problem with killing the TThreadedTimer…
    Do you know how to make this timer terminated and destroyed automatically when animation is finished?

    #41631
    HeDiBo
    Participant

    QUOTE (Support @ Feb 9 2010, 12:36 PM) <{POST_SNAPBACK}>
    Thank you.
    I have have a problem with killing the TThreadedTimer…
    Do you know how to make this timer terminated and destroyed automatically when animation is finished?


    In the OnCreate event in TAuAnimBmp the timer is created:

    FTimer := TThreadedTimer.Create(Self);

    In the OnDestroy event of TAuAnimBmp the timer is destroyed again:

    FTimer.Enabled := false; // This will suspend the thread
    FTimer.Free; // And this will kill the thread.

    Hope this helps.

    #41703
    Support
    Keymaster

    Thank you.
    Problem occurs in automatic self-destroying when timer used for a form hiding animation effect.
    Seems you hadn't it earlier

    #41704
    HeDiBo
    Participant

    QUOTE (Support @ Feb 15 2010, 12:50 PM) <{POST_SNAPBACK}>
    Problem occurs in automatic self-destroying when timer used for a form hiding animation effect.
    Seems you hadn't it earlier Could be, I didn't have that because the modal form in which the timer was used could only be destroyed manually.

Viewing 20 posts - 1 through 20 (of 22 total)
  • You must be logged in to reply to this topic.