View Issue Details

IDProjectCategoryView StatusLast Update
0015616LazarusLCLpublic2010-01-29 08:02
ReporterZeljan Rikalo Assigned ToPaul Ishenin  
PrioritynormalSeverityfeatureReproducibilityalways
Status closedResolutionfixed 
Product Version0.9.29 (SVN) 
Fixed in Version0.9.29 (SVN) 
Summary0015616: Application.OnModalBegin() Application.OnModalEnd() is missing (patch attached)
DescriptionWe are missing those two events for delphi compatibility.
Patch is attached (against r 23582).
TagsNo tags attached.
Fixed in Revision23584
LazTarget-
Widgetset
Attached Files

Activities

2010-01-28 19:23

 

applicationmodalstarted.diff (7,943 bytes)   
Index: lcl/forms.pp
===================================================================
--- lcl/forms.pp	(revision 23582)
+++ lcl/forms.pp	(working copy)
@@ -1142,6 +1142,7 @@
     FLastKeyDownKey: Word;
     FLastKeyDownShift: TShiftState;
     FMainForm : TForm;
+    FModalInstances: Integer;
     FMouseControl: TControl;
     FNavigation: TApplicationNavigationOptions;
     FOldExceptProc: TExceptProc;
@@ -1159,6 +1160,8 @@
     FOnEndSession : TNotifyEvent;
     FOnQueryEndSession : TQueryEndSessionEvent;
     FOnMinimize: TNotifyEvent;
+    FOnModalBegin: TNotifyEvent;
+    FOnModalEnd: TNotifyEvent;
     FOnRestore: TNotifyEvent;
     FOnShortcut: TShortcutEvent;
     FOnShowHint: TShowHintEvent;
@@ -1256,6 +1259,8 @@
     procedure Initialize; override;
     function MessageBox(Text, Caption: PChar; Flags: Longint): Integer;
     procedure Minimize;
+    procedure ModalStarted;
+    procedure ModalFinished;
     procedure Restore;
     procedure Notification(AComponent: TComponent; Operation: TOperation); override;
     procedure ProcessMessages;
@@ -1356,6 +1361,8 @@
     property OnEndSession: TNotifyEvent read FOnEndSession write FOnEndSession;
     property OnQueryEndSession: TQueryEndSessionEvent read FOnQueryEndSession write FOnQueryEndSession;
     property OnMinimize: TNotifyEvent read FOnMinimize write FOnMinimize;
+    property OnModalBegin: TNotifyEvent read FOnModalBegin write FOnModalBegin;
+    property OnModalEnd: TNotifyEvent read FOnModalEnd write FOnModalEnd;
     property OnRestore: TNotifyEvent read FOnRestore write FOnRestore;
     property OnDropFiles: TDropFilesEvent read FOnDropFiles write FOnDropFiles;
     property OnHelp: THelpEvent read FOnHelp write FOnHelp;
Index: lcl/include/customform.inc
===================================================================
--- lcl/include/customform.inc	(revision 23582)
+++ lcl/include/customform.inc	(working copy)
@@ -2346,74 +2346,78 @@
   if GetCapture <> 0 then
     SendMessage(GetCapture, LM_CANCELMODE, 0, 0);
   ReleaseCapture;
+  Application.ModalStarted;
+  try
+    Include(FFormState, fsModal);
+    ActiveWindow := GetActiveWindow;
+    SavedFocusState := SaveFocusState;
+    Screen.FSaveFocusedList.Insert(0, Screen.FFocusedForm);
+    Screen.FFocusedForm := Self;
+    Screen.MoveFormToFocusFront(Self);
+    Screen.MoveFormToZFront(Self);
+    ModalResult := 0;
 
-  Include(FFormState, fsModal);
-  ActiveWindow := GetActiveWindow;
-  SavedFocusState := SaveFocusState;
-  Screen.FSaveFocusedList.Insert(0, Screen.FFocusedForm);
-  Screen.FFocusedForm := Self;
-  Screen.MoveFormToFocusFront(Self);
-  Screen.MoveFormToZFront(Self);
-  ModalResult := 0;
-
-  try
-    if WidgetSet.GetLCLCapability(lcModalWindow) = LCL_CAPABILITY_NO then
-      DisabledList := Screen.DisableForms(Self)
-    else
-      DisabledList := nil;
-    Show;
     try
-      TWSCustomFormClass(WidgetSetClass).ShowModal(Self);
-      repeat
-        { Delphi calls Application.HandleMessage
-          But HandleMessage processes all pending events and then calls idle,
-          which will wait for new messages. Under Win32 there is always a next
-          message, so it works there. The LCL is OS independent, and so it uses
-          a better way: }
-        try
-          WidgetSet.AppProcessMessages; // process all events
-        except
-          if Application.CaptureExceptions then
-            Application.HandleException(Self)
-          else
-            raise;
-        end;
-        if Application.Terminated then
-          ModalResult := mrCancel;
-        if ModalResult <> 0 then
-        begin
-          CloseModal;
-          if ModalResult<>0 then break;
-        end;
-        Application.Idle(true);
-      until False;
+      if WidgetSet.GetLCLCapability(lcModalWindow) = LCL_CAPABILITY_NO then
+        DisabledList := Screen.DisableForms(Self)
+      else
+        DisabledList := nil;
+      Show;
+      try
+        TWSCustomFormClass(WidgetSetClass).ShowModal(Self);
+        repeat
+          { Delphi calls Application.HandleMessage
+            But HandleMessage processes all pending events and then calls idle,
+            which will wait for new messages. Under Win32 there is always a next
+            message, so it works there. The LCL is OS independent, and so it uses
+            a better way: }
+          try
+            WidgetSet.AppProcessMessages; // process all events
+          except
+            if Application.CaptureExceptions then
+              Application.HandleException(Self)
+            else
+              raise;
+          end;
+          if Application.Terminated then
+            ModalResult := mrCancel;
+          if ModalResult <> 0 then
+          begin
+            CloseModal;
+            if ModalResult<>0 then break;
+          end;
+          Application.Idle(true);
+        until False;
 
-      Result := ModalResult;
-      if HandleAllocated and (GetActiveWindow <> Handle) then
-        ActiveWindow := 0;
+        Result := ModalResult;
+        if HandleAllocated and (GetActiveWindow <> Handle) then
+          ActiveWindow := 0;
+      finally
+        Screen.EnableForms(DisabledList);
+        { guarantee execution of widgetset CloseModal }
+        TWSCustomFormClass(WidgetSetClass).CloseModal(Self);
+        Hide;
+        // free handles to save resources and to reduce overhead in the interfaces
+        // for bookkeeping changing between Show and ShowModal.
+        // (e.g.: the gtk interface creates some specials on ShowModal, so the
+        //  combination ShowModal, Close, Show makes problems.)
+        DestroyHandle;
+      end;
     finally
-      Screen.EnableForms(DisabledList);
-      { guarantee execution of widgetset CloseModal }
-      TWSCustomFormClass(WidgetSetClass).CloseModal(Self);
-      Hide;
-      // free handles to save resources and to reduce overhead in the interfaces
-      // for bookkeeping changing between Show and ShowModal.
-      // (e.g.: the gtk interface creates some specials on ShowModal, so the
-      //  combination ShowModal, Close, Show makes problems.)
-      DestroyHandle;
+      if Screen.FSaveFocusedList.Count > 0 then
+      begin
+        Screen.FFocusedForm := TCustomForm(Screen.FSaveFocusedList.First);
+        Screen.FSaveFocusedList.Remove(Screen.FFocusedForm);
+      end
+      else
+        Screen.FFocusedForm := nil;
+      Exclude(FFormState, fsModal);
+      RestoreFocusState(SavedFocusState);
+      if ActiveWindow <> 0 then
+        SetActiveWindow(ActiveWindow);
     end;
   finally
-    if Screen.FSaveFocusedList.Count > 0 then
-    begin
-      Screen.FFocusedForm := TCustomForm(Screen.FSaveFocusedList.First);
-      Screen.FSaveFocusedList.Remove(Screen.FFocusedForm);
-    end
-    else
-      Screen.FFocusedForm := nil;
-    Exclude(FFormState, fsModal);
-    RestoreFocusState(SavedFocusState);
-    if ActiveWindow <> 0 then
-      SetActiveWindow(ActiveWindow);
+    Application.ModalFinished;
   end;
 end;
 
Index: lcl/include/application.inc
===================================================================
--- lcl/include/application.inc	(revision 23582)
+++ lcl/include/application.inc	(working copy)
@@ -102,6 +102,7 @@
   FShowButtonGlyphs := sbgAlways;
   FShowMenuGlyphs := sbgAlways;
   FMainForm := nil;
+  FModalInstances := 0;
   FMouseControl := nil;
   FHintColor := DefHintColor;
   FHintPause := DefHintPause;
@@ -286,6 +287,20 @@
   WidgetSet.AppMinimize;
 end;
 
+procedure TApplication.ModalStarted;
+begin
+  Inc(FModalInstances);
+  if (FModalInstances = 1) and Assigned(FOnModalBegin) then
+    FOnModalBegin(Self);
+end;
+
+procedure TApplication.ModalFinished;
+begin
+  Dec(FModalInstances);
+  if (FModalInstances = 0) and Assigned(FOnModalEnd) then
+    FOnModalEnd(Self);
+end;
+
 {------------------------------------------------------------------------------
   Method: TApplication.Restore
   Params: None
applicationmodalstarted.diff (7,943 bytes)   

Paul Ishenin

2010-01-29 04:08

manager   ~0033990

Thanks, applied with modifications.

Zeljan Rikalo

2010-01-29 08:02

developer   ~0034000

tnx

Issue History

Date Modified Username Field Change
2010-01-28 19:23 Zeljan Rikalo New Issue
2010-01-28 19:23 Zeljan Rikalo File Added: applicationmodalstarted.diff
2010-01-28 19:23 Zeljan Rikalo LazTarget => -
2010-01-29 04:08 Paul Ishenin Fixed in Revision => 23584
2010-01-29 04:08 Paul Ishenin Status new => resolved
2010-01-29 04:08 Paul Ishenin Fixed in Version => 0.9.29 (SVN)
2010-01-29 04:08 Paul Ishenin Resolution open => fixed
2010-01-29 04:08 Paul Ishenin Assigned To => Paul Ishenin
2010-01-29 04:08 Paul Ishenin Note Added: 0033990
2010-01-29 08:02 Zeljan Rikalo Status resolved => closed
2010-01-29 08:02 Zeljan Rikalo Note Added: 0034000