Search the Community
Showing results for tags 'forms'.
Found 2 results
-
New Behaviour Weird: My new VCL Forms (ALL) (in new projects) using "SHOW" procedure always in TOPMOST on ZOrder after SetWindowPos usage
programmerdelphi2k posted a topic in VCL
hi People, I don't know what to think to solve the current problem I got myself into! From the beginning... doing some tests with the "SetWindowPos(...)" MSWin-API function, I realized that my new forms created and called from the main form, using the "SHOW" procedure, were no longer being in the background!!! That is, the new forms are always in the foreground, regardless of whether or not the "FormStyle = fsStayOnTop" is set!!!! to clarify further: all new forms are "FormStyle=fsNormal"... ALL, either formMain, or a formSecond called in formMain! none of the form properties (at all) were changed, it's all default by Delphi. nothing nothing nothing is being changed The new VCL projects are creating forms always in TOPMOST after my tests with the function call "SetWindowPos(...)" that I made in a test project!!! After a moment of total madness (laughs), I tried checking the Embarcadero Registry (HLM/HCU) to see if any properties were defined during the tests, but I didn't find anything strange.... I tried to check some configuration file in the Embarcadero folder (in the user's system folders), but I didn't find anything that gave any information either! Finally, I went to the extreme and completely uninstalled RAD Studio, deleted folders, files and keys in the Registry... everything! And I did a reinstall from scratch! But nothing solved it... my new forms still having the TOPMOST property, this way, creating and calling the sub-forms through the "SHOW" procedure, always placing the sub-forms on the application's main form! Finally, my suspicion is that I bugged MSWindows and now Delphi will always be using create forms as TOPMOST... Has anyone been through this situation or can indicate a way to reverse this situation? watch the two videos using same code Video 1: before tests with SetWindowPos Form1 (main form) call Form2 (second form) using Form2.SHOW; clicking in Form2, it came to front clicking in Form1, it came to front OK!!! all it's working! Video 2: after tests with SetWindowPos Form1 (main form) call Form2 (second form) using Form2.SHOW; clicking in Form2, it came to front clicking in Form1, it DONT came to front now FORM2 is always on TOP.... 😠Here the code used in my tests, nothing more than this 2 forms in tests (main and second forms) had all properties default and none code, basically empty! this code was in my Form1 procedure TMeuFormParaTest.Button1Click(Sender: TObject); begin SetWindowPos(Handle, HWND_TOPMOST, Left, Top, Width, Height, SWP_NOACTIVATE or SWP_NOMOVE or SWP_NOSIZE); end; procedure TMeuFormParaTest.Button2Click(Sender: TObject); begin SetWindowPos(Handle, HWND_BOTTOM, Left, Top, Width, Height, SWP_NOACTIVATE or SWP_NOMOVE or SWP_NOSIZE); end; after this code, all changed in my Delphi... new projects have its forms using "FormXXX.SHOW" as TOPMOST, and over my form caller (normally my Form-Main) AHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH! Im crazy with this! attached my project test with 2 forms and almost none code! VCL_Forms_always_TOPMOST_Now_in_New_Projects.zip ... -
VCL or FMX: My sample using Thread running in another forms for some tasks...
programmerdelphi2k posted a topic in General Help
My sample using Thread running in another forms some tasks... not 100% perfect or SAFE... but works if you take a care about my "little code" of course, needs to know "what going on..." and to do some changes for a specific usage... then, dont blame me, this it's just a simple sample. ok? take the idea and do better!!! maybe a "container using Observer Pattern" would help here, but "arrays" was good for me in this time! try close all forms, or simply the mainform 🙂 you CAN click many time on Button and raise yourS threadS... 1x, 2x, 3x, etc... dont abuse :))) // ---- FormMain ----- var MainForm : TMainForm; LHowManyThreadRunning: integer = 0; // Global vars was just for my test... dont use it, at all!!! implementation {$R *.dfm} uses uFormWithThread; var LArrForms: TArray<TForm>; LTop : integer = 0; LLeft : integer = 0; procedure MyDestroyForms; begin for var F in LArrForms do if (F <> nil) then FreeAndNil(F); end; procedure TMainForm.Bnt_Call_Form_ThreadClick(Sender: TObject); var i: integer; begin i := Length(LArrForms); LArrForms := LArrForms + [TFormWithThread.Create(nil)]; LArrForms[i].Top := LTop; LArrForms[i].Left := LLeft; LArrForms[i].Show; // LTop := LTop; LLeft := LLeft + LArrForms[i].Width; end; procedure TMainForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean); begin CanClose := LHowManyThreadRunning = 0; end; procedure TMainForm.FormDestroy(Sender: TObject); begin MyDestroyForms; end; procedure TMainForm.Btn_Try_Close_All_Form_ShowingClick(Sender: TObject); begin for var F in LArrForms do if (F <> nil) then F.Close; end; initialization ReportMemoryLeaksOnShutdown := true; end. // --- Secondary Forms... var FormWithThread: TFormWithThread; implementation {$R *.dfm} uses uMyThread, uFormMain; var LArrThreads: TArray<TMyThread>; function MyCanClose: Boolean; begin result := false; // while (Length(LArrThreads) > 0) do begin // trying kill the thread... LArrThreads[0].Terminate; LArrThreads[0].WaitFor; LArrThreads[0].Free; // // if ok, remove it from list delete(LArrThreads, 0, 1); end; // LHowManyThreadRunning := Length(LArrThreads); result := LHowManyThreadRunning = 0; end; procedure TFormWithThread.Btn_RunThreadClick(Sender: TObject); var i: integer; begin i := Length(LArrThreads); LArrThreads := LArrThreads + [TMyThread.Create(MyUpdateButtonCaption)]; // Memo1.Lines.Add(TimeToStr(now) + ' CurrentThread: ' + TThread.CurrentThread.ThreadID.ToString + ' ... App'); // LArrThreads[i].Start; // LHowManyThreadRunning := LHowManyThreadRunning + 1; MyAnimation.StartAnimation; end; procedure TFormWithThread.FormCloseQuery(Sender: TObject; var CanClose: Boolean); begin LHowManyThreadRunning := Length(LArrThreads); CanClose := LHowManyThreadRunning = 0; // if not CanClose then CanClose := MyCanClose; end; procedure TFormWithThread.MyUpdateButtonCaption(const AValue: string); begin Memo1.Lines.Add(TimeToStr(now) + ' CurrentThread: ' + TThread.CurrentThread.ThreadID.ToString + ' ' + AValue); end; end. unit uMyThread; interface uses System.SysUtils, System.Classes, System.Threading; type TMyProcReference = reference to procedure(const AValue: string); TMyThread = class(TThread) strict private FProc : TMyProcReference; FLCounter : integer; FLThreadID: string; protected procedure Execute; override; procedure DoTerminate; override; public constructor Create(const AProc: TMyProcReference = nil); overload; end; implementation { TMyThread } constructor TMyThread.Create(const AProc: TMyProcReference = nil); begin inherited Create(true); // FProc := AProc; FLThreadID := ThreadID.ToString; FLCounter := 0; end; procedure TMyThread.DoTerminate; begin FLThreadID := ThreadID.ToString; // if Assigned(FProc) then TThread.Queue(nil, procedure begin FProc('This is the end! FLThreadID: ' + FLThreadID + ' LCounter: ' + FLCounter.ToString); end); end; procedure TMyThread.Execute; begin while not Terminated do begin FLThreadID := ThreadID.ToString; // if (FLCounter = 100) then break; // if Assigned(FProc) then TThread.Queue(nil, procedure begin FProc('FLThreadID: ' + FLThreadID + ' LCounter: ' + FLCounter.ToString); end); // // simulating a process... "LCounter just for test n process" FLCounter := FLCounter + 1; sleep(500); end; end; end.