0

Currently in my application the user is able to create windows (no controls on the as of yet) which are docked to a pagecontrol. Each editor has a set of toolboxes associated with them. This set is reset upon editor construction and modified as toolboxes are closed and opened. When the page control changes tab the state of the toolboxes is saved, they are closed and then the toolboxes for the new tab are restored.

My application is crashing (seemingly randomly at first) when you change tab. I believe it is when you change tab very fast (the speed of a double click) the processing of the toolboxes in the PageControl.OnChange event doesnt complete before the next PageControl.OnChange event starts and I end up with two events running in 'parallel'. My questions are:

1) Does this sound like a plausible theory? I am aware there is a GUI processing thread does delphi work by dispatching new threads to deal with events?

2) How would you suggest going about fixing this? Hold the messages until the first method finishes (it is a very quick method so there shouldnt be any use lag really)?

Here is some code incase anyone would like to look at the problem from another angle.

This is the code for the onchange event.

procedure TMainForm.PageDockingAreaChange(Sender: TObject);
var
  count : integer;

  // Shortcut variables
  FormShortcut : TForm;
  WelcomeShortcut : TWelcomePageForm;
  BaseEditorShortcut : TBaseEditor;

begin

  // Set nil values
  FormShortcut := nil;
  WelcomeShortcut := nil;
  BaseEditorShortcut := nil;

  // Create shortcut value
  FormShortcut := Self.GetActiveForm;
  if (FormShortcut is TWelcomePageForm) then WelcomeShortcut := TWelcomePageForm(FormShortcut);
  if (FormShortcut is TBaseEditor) then BaseEditorShortcut := TBaseEditor(FormShortcut);

  // Hide all tabs when welcome page is visible
  if (WelcomeShortcut <> nil) then
    begin

      // Clear any existing toolboxes
      Self.ToolboxClearAll;

    end;
  {endif}

  // Try to execute toolbox setup
  try

    // Load toolbox state
    Self.ToolboxSetup(BaseEditorShortcut);

  except

    // Display fatal error to the user
    ShowMessage('Fatal Error : Unable to load toolboxes.');

  end;

  // Update last active editor
  if (BaseEditorShortcut = nil) then
    Self.LastActiveEditor := nil
  else
    Self.LastActiveEditor := BaseEditorShortcut;
  {endif}

end;

This method closes all toolboxes and frees them in turn.

procedure TMainForm.ToolboxClearAll;
var
  count : integer;
begin

  // Save toolbox state if needed
  if Assigned(Self.LastActiveEditor) then
    Self.LastActiveEditor.SaveToolboxState;

  // Close and free all toolboxes
  for count := 0 to length(Self.ActiveToolboxes)-1 do
    Self.ToolboxCloseAndFree(Self.ActiveToolboxes[count]);

  // Reset array size (should already be done though)
  SetLength(Self.ActiveToolboxes, 0);

end;
James_Hill
  • 167
  • 1
  • 4
  • 13
  • 4
    No. This is not a plausible theory. Unless of course you are pumping messages yourself. Are you? – David Heffernan May 18 '14 at 18:13
  • The point is that GUI messages all arrive in the GUI thread. So unless you yield control, they will not interleave. – David Heffernan May 18 '14 at 18:29
  • 1
    `ShowMessage()` pumps the message queue, so that could cause interleaving handlers, at least. – Remy Lebeau May 18 '14 at 19:12
  • @Remy That's quite interesting. Must be an issue for any input event handler that shows modal dialog. – David Heffernan May 18 '14 at 19:44
  • Can you be more precise about what you mean when you say *"my application is crashing"*? Please describe what happens, if there are any error messages, whether this happens during debug or running a release version, whether you can replicate the behaviour in the IDE, and if so, whether doing so provides any error messages. Does your application use any worker threads? Do you make any calls to `Application.ProcessMessages`? Are you using any third-party components? Notwithstanding any of that, you should probably recompile with MadExcept(http://madshi.net) and see if it tells you anything. – J... May 18 '14 at 21:17
  • @DavidHeffernan: yes. Modal dialogs run their own message loops internally. – Remy Lebeau May 18 '14 at 21:37
  • @remy Well, clearly. I suppose that what happens is that the owner is disabled and so the input event that is queued to the owner is thus ignored. That presumably means ShowMessage pumps but will not interleave events for the now disabled owner. – David Heffernan May 18 '14 at 21:55
  • @DavidHeffernan: it depends on the message. A disabled window cannot receive *input* messages generated by the user, but it can still receive messages in general as long as they are dispatchable. For example, timer messages. – Remy Lebeau May 19 '14 at 00:25
  • @remy but for this question ShowMessage won't lead to input message interleaving – David Heffernan May 19 '14 at 05:01
  • @J... No error message was occurring, windows just threw a 'no longer responsive' dialog and then shutdown the application, there was no error message being displayed. The application has no thread objects included (only started this iteration a day or so ago), Application.ProcessMessages is not called (would never use that thing!) and the third party components in use are the JVCL components for managing docking. DavidHeffernan and remy use input occurs on the main application editor tabs, the toolboxes are the cause of this issue and they receive no user input. – James_Hill May 21 '14 at 16:25
  • @James_Hill Can you be precise? What was the exact windows message - was it *"xxx Application is not responding"* or *"xxx Application has stopped working and needs to close"*? If the application was simply not responding then you have a blocking call or unresolved deadlock somewhere. – J... May 21 '14 at 21:31
  • @J... There was no message, I got the processing image for the mouse cursor and then a few seconds later (without clicking anything) the application shuts down. I have worked around the code by forcibly delaying the speed of double clicking now and it doesn't seem like I can replicate the bug anymore. – James_Hill May 22 '14 at 17:46

0 Answers0