Delphi: What is Application.Handle?

What is TApplication.Handle ?

  • Where is he from?
  • Why does he exist?
  • And most importantly: why do all forms have it as a handle to the parent window?

Help Delphi says:

TApplication.Handle

Provides access to the window handle of the main form (window) of the application.

 property Handle: HWND; 

Description

Use Handle when calling the Windows API functions requiring a parent handle window. For example, a DLL that displays its own top-level popup for windows requires a parent window to display its windows in an expression. Using the Handle property makes such windows part of the application so that they are minimized, restored, enabled, and disabled by the application.

If I focus on the words "window handle to the main form of the application," and I think it means the window handle to the main form of the application, then I can compare:

  • "window handle of the main form of the application",
  • window handle MainForm Application

but they do not match:

 Application.MainForm.Handle: 11473728 Application.Handle: 11079574 

So what is Application.Handle ?

  • Where is he from?
  • What is Windows & reg; window handle?
  • If Windows & reg; window handle Application MainForm , then why they do not match?
  • If this is not a handle to the Application MainForm window, then what is it?
  • More importantly: why is he the primary parent of each form?
  • And most importantly: why does everything happen with haywire if I try to have a form that has no analogues (so that it can appear on the TaskBar) or try to use something like IProgressDialog?

Indeed, I ask: what is the design rationale that makes Application.Handle existing? If I can understand why, then how it should become obvious.




Refresh Understanding the game from twenty questions:

Saying that the decision to create a window appears on the taskbar, making its owner null , Peter Below said in 2000 :

This can cause some problems with modal forms shown on secondary forms.

If the user disconnects from the application, and the modal form is up and then back to the form that showed it, the modal form can hide under the form. This can be dealt with by making sure the modal form was born on the form that showed it (using `params.WndParent``, as mentioned above)

But this is not possible in the standard dialogs from the Dialogs block and exceptions that require more effort to make them work correctly (basically processing Application.OnActivate , looks for modal forms born for the Application through GetLastActivePopup and bringing them to the top of the Z-order through SetWindowPos ).

  • Why does a modal form end with other forms?
  • What mechanism usually brings the modal form to the fore and why doesn’t it work here?
  • Window & reg; responsible for displaying window stacks. What went wrong with Windows & reg; doesn't show the correct windows?

He also talked about using the new advanced Windows style, which makes the window appear on the taskbar (when the usual rules of its irrelevance are insufficient, impractical or undesirable), adding the advanced style WS_EX_APPWINDOW

 procedure TForm2.CreateParams(var Params: TCreateParams); begin inherited CreateParams( params ); Params.ExStyle := Params.ExStyle or WS_EX_APPWINDOW; end; 

But then he warns:

If you click on the button of the taskbar of the secondary form, while another active application, it will still lead to the appearance of all forms of applications. if you do not want to have an option

Who brings all forms to the front when the form owner is still Application.Handle . Is this an app ? Why is he doing this? Instead, should this not be done? What the disadvantage is not ; I see a drawback to do (the system menu does not work properly, the thumbnails of the buttons on the taskbar are inaccurate, the Windows® shell cannot minimize windows.




In another Application post, Mike Edenfield says the parent window sends a message summary, maximization, and message recovery to another window :

This will add a taskbar button for your form, but there are still a few small details for the pen. Most obviously, your form still receives the reduction / maximization information that is sent to the parents of the form (main application form). To avoid this, you can set the message handler for WM_SYSCOMMAND by adding a line, for example:

 procedure WMSysCommand(var Msg: TMessage); WM_SYSCOMMAND; procedure TParentForm.WMSysCommand(var Msg: TMessage); begin if Msg.wParam = SC_MINIMIZE then begin // Send child windows message, don't // send to windows with a taskbar button. end; end; 

Note that this handler is in the PARENT form of the one you want to keep independent of> the rest of the application in order to avoid sending a minimization message. You can add similar code for SC_MAXIMIZE, SC_RESTORE, etc.

How to minimize / maximize / restore messages for my Windows & reg; windows do not go to my window? This is because messages destined for the window are sent by Windows & reg; window owner? And in this case, all forms in the Delphi application "belong" to the Application ? Does this mean that the owner is null:

 procedure TForm2.CreateParams(var Params: TCreateParams); begin inherited; Params.WndParent := 0; //NULL end; 

will delete Application , and this Handle window due to interference in my form, and should Windows send me my messages mimimize / maximize / restore again?




Perhaps if we were comparing and comparing the “normal” Windows application now, this did the way Borland originally designed Delphi applications to do something — with respect to this Application object and its main loop.

  • What solution was Application ?
  • What changes were made in later versions of Delphi so that these same problems do not exist?
  • Has the change in later versions of Delphi not changed other problems that were so much solved in the design of the application?
  • How can these new applications work without an application blocking them?

Obviously, Borland realized the flaw in its original design. What was their initial design, what was the problem in solving it, what was the drawback, which was redesigned and how does it solve the problem?

+43
delphi delphi-5
Feb 05 '10 at 3:16
source share
3 answers

The reason for the application window is a bit of a rough story. When developing Delphi 1, we knew that we wanted to use "SDI" (windows scattered across the desktop) for the IDE model. We also knew that Windows was sucking (and still doing) this model. However, we also noticed that Visual Basic was using this model at the time, and it seemed to work well. After further study, we found that VB used a special “hidden” parking window, which was used as the “owner” (Windows sometimes erodes the concept of parent and owner, but this difference is similar to VCL) for all other visible windows.

So we solved the “problem” when the windows containing the main menu were rarely focused, so Alt-F processing for the “File” menu simply did not work. Using this central parking window as an intermediary, we could more easily track and route messages to the appropriate windows.

This scheme also solved another problem, when usually several top-level windows were completely independent. By making the application the "owner" handler of all these windows, all of them will behave in a consistent manner. For example, you may have noticed that when you select any application window, all application windows move to the foreground and keep their z-order relative to each other. It will also minimize and restore the application as a functional grouping.

This is a consequence of using this model. We could manually do all this work so that everything was in order, but the design philosophy was not to invent Windows, but to use it where we could. This is why TButton or TEdit is really the class and style of the User window, BUTTON and EDIT, respectively.

As Windows evolved, this “SDI” model became sloppy. In fact, Windows itself began to become "hostile" to this style of application. Starting from Windows Vista and continuing through to 7, the user shell does not seem to work with the application using the parking window. So, we decided to shuffle things in VCL to eliminate the parking window and move its function to the main form. This revealed several chicken and egg problems, as a result of which we need to have a parking window available early enough in the initialization of the application so that other windows can “attach” to it, but the main form itself cannot be built soon enough. TApplication had to slip through a few hoops to make it work, and there were a few subtle edge cases that caused the problem, but most of the problems were worked out. However, for any application that you are moving forward, it will remain using the old parking window model.

+47
Feb 05 '10 at 17:55
source share

All VCL applications have a “hidden” top-level window called Application. This is automatically created when the application starts. Among other things, this is the main Windows message handler for VCL - hence Application.ProcessMessages.

The presence of a hidden top-level application window causes some strange things, a noticeably incomplete system menu that appears on the taskbar, and incorrect finger nail windows in Vista. Later versions of Delphi fix this.

However, not all windows should have it as a parent; Windows just works better if that is the case. However, any form created using Application.CreateForm will have it as its parent, and it will also belong to the Application object. Because they belong, they will be released after the application is released. This happens behind the scenes in Forms.DoneApplication

+11
Feb 05 '10 at 4:01
source share

From a look at the source in forms.pas (Delphi 2009), it looks like they create a “main” window in win32 gui applications to resolve calls

  • TApplication.Minimize
  • TApplication.Restore
  • etc.

It seems that messages passed to Application.Handle are redirected according to MainForm if they exist. This will allow the application to respond to minimization, etc., if the main window has not been created. By changing the project source, you can create a delphi application without a main window.

In this case, TApplication methods will work even if you have not created the main window. Not sure if I grab all the targets, but I don’t have time to go through all the TApplication code.

For all questions:

  • Where is he from? This is the handle to the window created in TApplication.Create

  • What are Windows descriptors? fake window that every gui delphi application requires as part of the TApplication abstraction

  • Is this a window handle to the main form of the application? No

  • If this is not a mainform application descriptor, then what is it? See above

  • : why is he the ultimate parent of each form? , believing that you are right that its final parent, I assume that this is so because it makes it easy to find all forms in your application (listing the children of this "main" form).

  • , and most importantly: why everything goes with difficulty, if I try to get a form without a unified I think because the hidden "main" form receives system messages that it should convey to its children and / or the main form, but cannot find an incomparable form .

Anyway, I take it upon myself. You can probably learn more by looking at the TApplication declaration and code in forms.pas . The bottom line is what I see is a convenient abstraction.

Respectfully,

Don

+7
Feb 05 '10 at 4:01
source share



All Articles