Hello and thanks as always,
I have a problem to minimize a MDIChild form in an MDI application MDIChild simple
when I call the child form appears active and downplay it, but when I open more forms and I minimize, these are not active, always active appears to minimize the first form, I realized that the message WM_MDIACTIVATE not work, maybe I should overwrite any procedure window?
Thanks a lot!
Related
We are upgrading a Delphi 5 application to Delphi XE7. The application has a number of MDIChild (FormStyle fsMDIChild) forms which open with WindowState wsNormal. When I open one of these forms, and close it again, my main menu (TMainMenu) on the main form (FormStyle fsMDIForm) aligns itself to the right and never goes back again. If I resize the MDIChild form before closing it (eg. click on "Normal" or "Minimize" icon), this does not happen.
This does not happen with the Delphi 5 version, so I assume something gets handled differently with XE 7.
Anyone else experienced this before? If so, how did you fix it?
UPDATE:
I have successfully replicated this problem:
Create a new VCL app
Make main form (MainForm) formStyle MDIForm
Create MainMenu for MainForm with menu items
Create second form (ChildForm)
Make ChildForm formStyle MDIChild
Create MainMenu for ChildForm with menu items
IMPORTANT (THIS IS WHAT BREAKS IT): Select for ChildForm BorderIcons only biSystemMenu and biMaximise
Create button on MainForm which creates and shows ChildForm
Run application
Click button
Maximise ChildForm
Close ChildForm (Has to be maximised otherwise malfunction does not occur)
Observe that MainForm's menu is now right-aligned with an unclickable 'Minimise' icon on the left If biMinimise is added to ChildForm's BorderIcons, the problem disappears.
I'm pretty sure this is a bug. Correct me if I'm wrong.
Thanks
J
The behaviour that you report is not observed when creating a brand new project, and creating forms in the manner that you describe.
Clearly then, there is some code in your project that is causing this issue. You need to do some debugging to identify this problem code. Start by stripping code away until the issue vanishes. The last code that you stripped away should contain the clues to lead you to the cause of thee problem. Continue in this manner until you have isolated the problem.
I have a largish Delphi 6 app that I have ported to Delphi XE3. At one point the main form launches another non-modal form. Sometimes (say 50%) after a second or two the newly created form moves behind the main form. Even thought it is now at the back, the newly created form still has focus so there are no activate/deactivate events. There are a few Timer controls and I have disabled them. It still happens.
I can accept my code is doing this -- but how can I find out what is happening? Is there a way to intercept when then new form moves to the back?
Just to be clear: I want both forms to be used separately. Any of them can appear behind the other. What is happening at the moment is that the z-order seems to be changing.
I have found the answer to this. I discovered I had added a CreateParams override that did this:
// make a taskbar window
inherited CreateParams( params );
params.ExStyle := params.ExStyle or WS_EX_APPWINDOW;
params.WndParent := GetDesktopwindow; // this line caused the problem
Commenting the WndParent solved it. The effect is bizarre though. It is as if there is a timer that goes off about a second after any key or mouse event that forces the window behind others. Thanks to David Heffernan whose comments about stepping CreateParam made me notice it.
I have a small question.
I think there must be a easy way to do it but I just can't find the keyword, so please teach me.
Here is the question:
For example, default ShowMessage pops a window with 'OK' button, then program stops temporarily before you click 'OK'.
This makes sense, but the problem is, you can still interact with other objects before you click 'OK'.
It certainly causes some problems like this:
var
Count: Integer; //initial it to 1
procedure TForm1.Button1Click(Sender: TObject);
begin
ShowMessage(IntToStr(Count));
Inc(Count);
end;
By not closing the message box, program always stops at same place and the variable remains the same.
How do I lock the popping window so you can't interact with other objects?(System forces you to turn your focus back to the popping window if you do so)
Is it possible to achieve this with ShowMessage?
It would be helpful if I can get some tips.
Thanks a lot.
Edit:
Using the unit QDialogs.ShowMessage version causes a non-modal problem. Beware of those units you are not familiar lol.
ShowMessage shows a modal dialog. In other words, it disables its owning window while the dialog shows. And so you cannot interact with the other windows in your app. ShowMessage already does what you want.
If you find that you can interact with other windows in your application whilst the dialog is showing, then you must have got the window ownership wrong.
I have a Delphi 6 application that launches a Wizard after the main form appears. The Wizard is a modal form. One of my users has their Windows desktop extended to more than one monitor. In their case the main form appears on the primary monitor and the Wizard appears on the Extended monitor. This creates confusion because they think the app has frozen when they try to click on the main form. Since the Wizard is open and modal, nothing happens except they hear the warning "ding" tone that tells you a form is not able to receive input.
What can I do to make sure the Wizard form appears on the same monitor as the main form, in this case the primary monitor? I have the Wizard form set to poDesktopCenter.
Manual theory:
Use poMainFormCenter when you want your form to be centered by the Application.MainForm. The application main form is, in short, the first form you can see when you run your application, and you should consider that this main form can be on a different monitor than the active window from which you create and center a new form.
Or if you want to center your form by its Owner, use the poOwnerFormCenter which is IMHO better for user's experience because when you have more than two windows opened by each other, you can move the window to another monitor and create the new window on the monitor where user currently works on.
Practical usecase:
User ran your application on the 1st monitor. The application created the Form2 from its MainForm. User moved that Form2 on the 2nd monitor and from there pressed the button which created another form, Form3.
If you designed your Form3 to use the poMainFormCenter position, the Form3 will be centered by the MainForm which is at this time on a different monitor, what is IMHO confusing.
If you would use code like this for creating and showing Form3:
procedure TForm2.Button1Click(Sender: TObject);
begin
// the Owner parameter Self (or Form2 here) in the Form3 constructor along
// with the Position set to poOwnerFormCenter will ensure you that the form
// will be centered by the current form position, so on the current monitor
// where the user works on as well
Form3 := TForm3.Create(Self);
try
Form3.Position := poOwnerFormCenter;
Form3.ShowModal;
finally
Form3.Free;
end;
end;
You will get Form3 centered by the Form2 but mainly on the same monitor as the Form2 currently lies on, as you currently work on:
My application has many forms, there is also one more important form, that is the main form, the behaviour is in general ok but in same cases (for example when I open a file dialog from a subform) the beahviour is: subform is hidden and mainform is shown.
How to avoid this?
Make sure you either implicitly or explicitly set the PopupParent of both the sub-form and the dialog. If you open both the sub-form and the dialog from some random bit of code somewhere and don't tell Windows about the correct Z-order, stacking issues can happen.