views:

691

answers:

7
+2  A: 

Yup, you pretty much have it figured out. Using windowless controls means that you lose everything Windows can do to help you. Having more than a couple on a single actual window is pain.

Ignacio Vazquez-Abrams
i would lose what Windows can do for me, but there are frameworks and widget libraries out there that can do it. Is Delphi one of those widget libraries? Can Delphi be asked to support controls that are not windowed?
Ian Boyd
All those widget libraries either use windowed controls, or they do all the hard work themselves with a single windowed control.
Ignacio Vazquez-Abrams
+4  A: 

Yes, it is futile.
And it's not Delphi's fault, you're just fighting Windows itself.
If you need a control that behaves like a windowed control, use a windowed one.
And you're right, trying to recreate the whole API stack of windowed controls from scratch is a pain.

François
Other applications that managed to do it; are they fighting Windows itself? It can be done, if the widget library you're using supports windowless controls. Delphi seems to start with the notion that every control must be windowed. i don't know what language Internet Explorer, Chrome, Firefox, and Blender were written in, but obviously in an environment whose widget library supports windowless controls. Is there a mechanism for Delphi to support such windowless controls (aka widgets)?
Ian Boyd
Ian, you're making the mistake of thinking that those programs are using ready-made widget libraries. Those programs have *their own* libraries specially designed for the task.
Rob Kennedy
@Rob. That may be, but widget libraries that exist. GTK+, wxWidgets, Juce, Qt, Swing. There are other libraries: WinForms, MFC. Does VCL fit into the former (windowless) or the latter (Windowed)?
Ian Boyd
Are you sure the GTK+ and wxWidgets libraries don't use window handles? I suspect they do. I don't know about the Java controls, though. They might not, because they always live inside a Java container. So, again we see that windowless controls require a special-purpose container.
Rob Kennedy
@Ian: wxWidgets on Windows can use window handles (compiled as wxMSW) but need not do so (when compiled as wxUniversal). If it doesn't then focus management has to be implemented by the framework. But native look and feel can only be achieved 100% by using native i.e. windowed controls, so wxUniversal will always be the inferior choice. So wxWidgets should go into the latter category.
mghie
@Rob: of course the windowless control require a special container. i was just hoping Borland made that container called TForm.
Ian Boyd
A: 

I have no idea of what your problem really is, here, but I think this little history may be relevant...

We have an application which fills out a dozen forms. The user may fill out additional forms, and also change values filled out by the application it self.

Now, in our first implementation, we used windowed components for every single input field, so that the fields could receive focus and input. That turned out to be a big problem, because all this windows took a lot of resources.

We now have windowless controls for every input field. That means that all we end up with, is a combined drawing of the form and its input fields. When the user clicks inside the drawing, or uses some keystrokes to move/set focus, we create a new windowed control for the clicked field. When the user moves to the next input field, we destroy the first window, and create a new one. This way we only have one windowed control which again gave us a nice speed improvement.

Again - I have no idea of what you really want to manage. TWinControl is a TWinControl for a reason, but there may be a solution to what you want, what ever that would be...

Vegar
Look at the text box you type into in your browser. That text box is not a Windows window. It does not have it's own window handle, or window procedure. The keystrokes **are** sent to a Windows window, but the window they are sent to is the whole page. You don't need a Windows class to create a control, you just need a control library that is not based on a Windows class. The ie team recreated all the usual controls as windowless versions (text box, button, checkbox, etc). Those are not Windows controls, they are Windowless.
Ian Boyd
well, you can do pretty much what ever you want in Delphi, but part of the point of using Delphi, is to get a head start given by the VCL. It is possible to use other widget libraries with delphi, and some even let you use part of the delphi ide features, like the palette and inspector (eg http://www.twinforms.com/products/wxformsdelphi/index.php).
Vegar
+3  A: 

It's futile to build windowless controls and fit them into Delphi's VCL framework.

You bring up Internet Explorer as an example. But in that case, it's entirely in charge of everything that resides on it. It has its own internal notion of what the active control is, but think about what it looks like from the outside: It's just one giant control. When you ask the OS what has focus, the single browser control has it, no matter which of the browser's subcontrols appears to have focus.

When you press Tab, it looks to the OS as though the browser has simply consumed a tab character, just like edit controls do. Edit controls move the cursor over a few spaces and add tab characters to their internal buffers; browser controls move the cursor to another region of the display.

You're thinking of doing all this on a Delphi TForm. Delphi forms already have a framework for managing the active control and handling keystrokes, and you're going to have to fight it all. If you want windowless controls, go the Internet Explorer route and build your own container control to hold them so that you can remain in charge of everything that happens inside it.

Your container can be a VCL control, but the things you put on it probably can't — they'll still be expecting to use the VCL focus- and keyboard-handling rules. Notice how you can't put ordinary Windows controls in Internet Explorer, either. Anything you put there needs to go through specific ActiveX interfaces. Maybe you'll need interfaces, too, or maybe you can just make your own set of control classes that descend from some special ancestor class you design to work with your container. Don't start with TGraphicControl; it's too entrenched in the VCL to be usable as the basis for your offshoot control library.

It will be a lot of work, but then again, so was Internet Explorer.

Rob Kennedy
"Delphi forms already have a framework for managing the active control and handling keystrokes, and you're going to have to fight it all." Thank you. That was really what i was hoping for. Delphi was written from the ground up to not have windowless controls. And if i were to attempt to some programming to create a windowless control: i would be fighting Delphi every step of the way.
Ian Boyd
Also, there is one control that Microsoft didn't convert to a windowless version - the combo box. You'll notice that comboboxes always appear "on top" of any other html content - no matter how much you play with z-orders. That's because it's still a Windows windowed control.
Ian Boyd
i created some controls. i wanted them to be windowless so they would be "lightweight", also because it allowed them to be partially transparent. But when it came time to TAB navigate to them, i realized that TControls are not interactive. And although they would respond to keyboard events sent to them, i had to convince Delphi that they were controls worthy of its focus.
Ian Boyd
To do what you want, you'll need to provide a windowed container for your controls. That doesn't preclude you from putting other windowed controls in your container; they'll just have to know how to cooperate with your container. Internet Explorer's combo box is no exception. It has a window handle, but it's still specially tailored to live inside IE. It's not a standard Windows combo box. IE provides ActiveX interfaces so you can adapt other controls to fit inside IE as well.
Rob Kennedy
The final question, i guess, would be: is it possible to use Delphi at all for windowless controls? Assuming i wrote (or imported) windowless version of every control (button, edit box, checkbox, treeview, listivew, statusbar, etc). Further assume that i created a descendant of TForm that did understand child `TControl`'s: isn't `TApplication` too used to the idea of a TForm? i notice that `TScreen` also has an `ActiveControl: TWinControl`, would i have to create new versions of TApplication and TScreen, and everything else? In other words...futile?
Ian Boyd
Of course you can use Delphi. You can write whatever you want. But the VCL, just like the OS itself, expects things that can receive focus to have window handles. How far do you want to take this? If you're going to replace Screen.ActiveControl, are you also going to replace GetActiveWindow? What's the difference? Neither one is aware of your container's contents.
Rob Kennedy
At the most fundamentel level, i think i need to keep TApplication. i believe (perhaps mistakenly) that the IDE depends on the presence of a TApplication object. The IDE parses the project source file, and knows how to add/remove forms based on `Application.Create`. It seems to me that i could throw a lot away, but i have to keep TApplication. In a .NET application there is an Application object that sets up a message pump, similar to Delphi. But when you create a WPF application, there is System.Windows.Application object. i'm afraid i'd have to rewrite Application to support windowless.
Ian Boyd
+1  A: 

Most of these programs were most likely not originally developed using RAD type tools so had no choice but to re-invent the wheel. One of the largest advantages of Delphi is the deep VCL and 3rd party component support to provide the look you desire.

One technique that I have used with great success to reduce the amount of window handles used in a complex (tax preparation) form based application was to draw the text on a canvas, and moved a single TCustomEdit decendant to the position the user was editing. It was trivial to capture the TAB/Up/Down keys and move the edit to the appropriate position. The challenge we discovered was in drawing a hot rectangle around the mouse hovered field. We ended up with a grid array of TObject, where the array element would be nil (no field), a TLIst (grid contains multiple fields) or a a class that contained our field descriptor. This reduced the amount of range checks we had to perform since it was more likely that the box only contained a single field, or at most 4 fields.

skamradt
Wow - are we working on the same software, or something...? :-)
Vegar
A: 

I think fgGUI may help you out.

Do check its Wiki first.

I think you can use this framework for your application in Delphi as it is written totally in Pascal. Actually it is based on FreePascal ;)

HTH

Yogi Yang 007
From the homepage: "Meaning every widget (component) has it's own window handle." /facepalm
Ian Boyd
+1  A: 

fpGUI Toolkit is an example of what you want. The latest fpGUI code in the source code repository is based on a multi-windowed design. That simple means every widget/component has a window handle, but Windows or Linux does nothing with that window, other that basic notification messages (mouseenter, mouseexit, etc). fpGUI still has full control over where each component goes, if they are focusable, how they look etc. Some widgets/components in fpGUI are non-windowed components too. eg: TfpgScrollbar, TfpgMainMenu, the button in a ComboBox etc.

If you want a true non-windowed version, mean there is only one top-level window that has a window handle, all other widgets/components inside that window doesn't actually exist to the OS (they have no window handles), then fpGUI can help too. The initial design of fpGUI Toolkit was based on such a design. Again, look in the source code repository for the v0.4 branch of code. I that design, fpGUI had to handle absolutely everything, creating mouseenter/mouseleave events, translate co-ordinate systems for container components, handle (fake) component focus states etc... Yes the initial design is a LOT of work, but then you have a very portable framework which can easily be applied to other OSes too.

And yes, fpGUI is fully implemented in the Object Pascal language using the Free Pascal compiler to give me cross-platform support. Currently fpGUI runs on Windows, Linux (32 & 64-bit), Windows Mobile and Embedded Linux (ARM) devices.

Graeme Geldenhuys
I think most important for the OP is the "Introduction" section in your linked page, where you explain *why* *you* *abandoned* that design for a one-handle-per-widget design.
mghie