Show quoted text 9 lines
-----Original Message-----
From: Michal Bukovjan
Sent: 20 August 1999 07:53 PM
To:
Subject: Re: [RE: [Re: [lazarus] wndproc]]
We are interested (as I understand it) in the possibility to have
Lazarus for
both Win32 and Linux, and use any arbitrary widget for visuals.
yes
Show quoted text 5 lines
This means that we should avoid all Win32 stuff in core components like
TComponent, TControl, TWinControl, and the basic set of controls,
so that it
is possible to write an application (using standard components) once and
compile under Win32 and Linux without no code change.
Depends on what you mean. HWND is not Win32 specific. It looks like it because of its name but it is actually a generic handle to the widget via the widget-manager. Wndproc looks win32 specific because of the name, but it is not. It is really a generic virtual message interceptor, the *only* NON_PLATFORM_SPECIFIC way to intercept messages before they hit the handlers. We could call it "PreviewHandler" instead of wndproc, but lets keep the same name for compatability. So YES, lets avoid where possible win32 specifics, but we need to decide on what are actually win32 specific and what are actually very useful non-specific members with win32 sounding names that we need to keep.
I say SHOULD, but if neccessary, we may opt to insert some Win32
specific code
and let it become dummy under anything else.
In the end CreateParams will have a different implementation with win32 that GTK but this is the ONLY difference that needs to exist in the FCL with regards to instantiating a widget via the widget-manager.
Show quoted text 5 lines
There was a discussion on that topic recently, including whether
we should use
IFDEFs and such, which resulted in those gtkint.pp, win32int.pp
units and all
this stuff.
I had thought of this. Another way is to have a global WidgetManager object that can be called upon to doo widget-manager specific stuff.
The differing CreateParams implementations for the default controls could exist either way, although it would result in high-coupling to the widget-manager as more fancy controls are invented; same problem for includes as newer controls are implemented.
$IFDEF is really the only way although a $IFDEF could be $IFDEF}{$INCLUDE
Also if I get my way regarding CreateWnd in most cases (apart from the default control set) no developer will need widget-specific code at all it will be hidden in the FCL and so yes; and I think you are right, IFDEF's are the way to go.
So I think the possibility to use existing Delphi components
descendants that
work and use Win32 specific stuff (i.e. Windows messages) will be, ..er..,
somewhat limited to Windows, and useless under Linux.
I hope that even under linux, if a component moves, a WM_MOVERESIZE or something message will be sent.
Show quoted text 11 lines
While this may be valid from Windows point of view (the
application will not
be portable, author decides), if such thing would be found in
core components,
that would handicap other widget platforms. And the other way
around, we could
certainly use some GTK specific stuff in core components, the
other, including
Win32 users, would be handicapped instead. Not speaking about
Motif/Lesstif,
Qt, or whatever.
I pale with horror. You just said to start with that: "We are interested (as I understand it) in the possibility to have Lazarus for both Win32 and Linux, and use any arbitrary widget for visuals."
and then
"This means that we should avoid all Win32 stuff in core components"
woah!
Stop. I am not a moron :-)
Well, no!
I am not the one who decides about
this in the end,
anyway (that is the core component maintainer).
Hmmm surely they implement, but the group decides?
Show quoted text 7 lines
That is just my
point of view.
And since you seem to know the Win32 widgets stuff well, it may
be inevitable
to have some Win32 support integrated after all, if you say so, be it by
IFDEFs. IMHO, that is the solution Sibyl chose, as I looked into
their code.
The win32 model is actually more abstracted than the GTK model; if we follow the windows/delhi there is no danger of shutting ourselves in. The deception is that the names of the win32 abstractions are not abstract names but names specific to the impementation of the abstraction. But whats in a name? We can certainly live with it.
The mere fact that GTK does not need all of win32 model is evidence of its abstraction. The fact that a windows delphi implementation and many many components cannot be implemented with the GTK model is evidence of it lack of abstraction. This is an example of our first difficulty in runnig lazarus with a non-GTK widget set. If we want widget-choice we had better go for abstraction.
The reason delphi works like this is because they extended the windows abstraction even further so it can be used in what I am calling the GTK way (with seperate handlers - much nicer than wndproc WHEN you've got the choice) as well as via the windows way.
> > 2) Leave out some Delphi solutions which had to be created/were suited
for
> > Windows, and supply our own, more versatile ones (be their
> > Delphi-incompatible).
Where you say windows, also say "OS/2" + other hitherto unexamined widget sets.
Show quoted text 9 lines
> > Again, remember that Delphi is VERY designed for
> > Windows, and if we want Lazarus for as much platforms as possible, we
> > definitely will need to abandon some Delphi approaches.
>
> If we want Lazarus for as much platforms as possible, we
definitely do not
> need to rule out platform approaches.
??? What do you mean ?
That we don't want to remove things just because windows uses them. That doesn't make them win32 specific. That we don't want to become GTK specific.
Show quoted text 17 lines
> > The shiny example of the 2) is Handle, which is rarely found
> > anywhere beyond
> > Windows, and since Windows get COMized, not even there in the
future (my
> > guess).
>
> The handle is "some" reference to the "real" object that is
managed by the
> bound GTK. This is going to be used with whatever gui we bind to. OK,
> handle isn't the best name UNDER GTK but its a better name under some
others
> (like Win or OS2).
Yes. But while it is an integer under Win32 (32-bit), it is meant to be a
pointer under GTK (which happens to be 32-bit on IA32). Then, I
am not sure
about 64bit platforms. (The compiler might take care about that, though).
The fact that it is a pointer in GTK should be kept "secret". Are you really sure it is an integer in win32. I think it is actually a pointer, but if it is presented as an integer no-one will mess about without. I also think that 16 bit windows handles were near pointers.
Show quoted text 7 lines
> The only reason for thinking a .wndproc slows things down is if
you think
> what's in the wndproc isn't needed - and yes its faster if you do less.
>
You are absolutely right on this one. Still I claim that the HUGE case
statement is NOT effective. In my opinion, it is not the best approach,
although it is usable.
You are also right, but with Delphi applications, the Case statement is not huge simply because of the nice event handlers.
It is true that many components DO use it, as they have no other
choice under
Windows, anyway (or do they?).
You are right, in many cases there is no choice (except even worse filthy hacks that really are win32 specific)
[BTW Once I did some self-modifying code that changed the virtual method table at runtime to intercept something I needed!. *cough* but thats Borlands fault! I'm not proud of it]
[What I am proud of is modifying the sysutils at runtime to intercept the GetDate GetTime, Now (etc) calls to work round a winNT 16bit bug where the calendar didn't run at the same rate as the clock!!! True! The date wrapped round before the lock did, and the calendar got further and further out!) (My unit meant you could leave your program as-is, merely by linking with the unit would fix the problem)
Show quoted text 6 lines
> If you like, let each component have a flag which says whether or not
> wndproc can be skipped. The GTK callback handler could check
this flag and
> only call wndproc if it is not set.
Hmm, that could be a viable solution :-)
It would delay the decision anyway!
Now, as I remember, intercepting owner's or parent's WndProc (I know that
trick) is generally considered a dirty hack and should be used with great
care.
true
Again, the form designer in Lazarus may use a completely different
approach, since it has to be Linux-compatible. In Linux, there is
no Win32 API
to intercept any WndProc !
There will be a wndproc. The form designer intercepts nicely:
procedure TControl.WndProc(var Message: TMessage);
var
Form: TForm;
begin
if csDesigning in ComponentState then
begin
Form := GetParentForm(Self);
if (Form nil) and (Form.Designer nil) and
Form.Designer.IsDesignMsg(Self, Message) then Exit;
end;
Nice, eh? Yep a slowdown, but only at design time.
Enough. Just once again - if the WndProc is really inevitable, it may be
there, after all. But we should double-check the need for any OS
platform-specific code.
Well, as I keep saying, only the name is os-specific (well, it applys to OS/2 as well), the abstract concept is a sound one, that may also be needed by future widget managers, but is certainly needed now as a pre-message handler interceptor.
In fact the whole wndproc dispatch system is really a direct implementation of an object-class system in straight C.
Intercepting wndprocs is the way to override methods within this system. And this system is a neat way of marrying object pascal to any object system used by any widget set.
Sam