Sunday, February 10, 2008

GTK2 planned not before Lazarus 1.2?

Sometimes people ask: Why don't the Lazarus developers want to fix the gtk2 bug before Lazarus 1.0?

The Lazarus developers have limited resources, so in order to have Lazarus 1.0 sooner rather than later, some decisions were made to reduce the work load (scope) for Lazarus 1.0. Some of this is mentioned on the wiki.

Basically, this means we think that no new features are needed for Lazarus 1.0. That doesn't mean that there will be no new features until then, but that we won't delay the release of Lazarus 1.0 because of it.

The gtk2 interface could be regarded as a feature too, because in most cases the gtk1 interface works just fine or better (except it looks dated). I must admit it is getting more troublesome recently, because some distroes now ship with gtk2 only. Currently the gtk widgetset is more stable and has less bugs with Lazarus than gtk2. Until that situation has changed gtk1 will remain the default. As soon as gtk2 is better (i.e. less bugs and more stable) than gtk1, it will come the default. But this is no priority for the Lazarus team, it rather focuses on other bugs.

Fortunately Lazarus is open source and with your contributions you can steer the path of Lazarus. For example Andrew Haines and Ales Katona understood that and have contributed a lot of gtk2 patches, trying to improve the gtk2 widgetset, so that it become the default for Lazarus 1.0. If a couple of other people start helping, I have no doubt that Lazarus 1.0 will eventually be with gtk2.

New 0.9.26 features. Part 1. SendMessage and PostMessage

If you ever wrote some big application or component, I am sure you met the problem of postponed execution of some code. Delphi programmers usually used 2 solutions: timers and Windows message system abilities. This article is about message system approach. Note that Lazarus has a third solution: Application.QueueAsyncCall.

I suppose you already know something about the Windows message system. And you are familiar with SendMessage and PostMessage commands. They are used to deliver messages to controls. SendMessage sends message dirrectly to control window procedure. PostMessage adds message to the message queue, so control will get it only after processing all other pending messages.

Group of message numbers from 0 to WM_USER are used by Windows itself. So if you want to use message system in personal purpose you should use message numbers >= WM_USER.

Lets return to Lazarus where you want to indirectly perform some actions. Very usual task is when you need to destroy some control (your form for example) in event handler. Ofcource your application crash if you call Free in event handler - so you need to call Free somehow after event handler. But how? Call PostMessage in event handler and process posted message in message handler.

Delphi example:

const
MY_MESSAGE = WM_USER + 1; // <-- your message number
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject); // <-- some event handler
private
procedure MyMsgHandler(var Message: TMessage); message MY_MESSAGE; // <-- message handler
end;

...

procedure TForm1.Button1Click(Sender: TObject);
begin
... //code before
PostMessage(Handle, MY_MESSAGE, 1, 0); // <-- here you post message to message queue
... // code after
end;

procedure TForm1.MyMsgHandler(var Message: TMessage);
begin
Free;
end;

If you used similar constructions in Delphi, you should know that they did not work in Lazarus. In the win32 widgetset code all WM_USER messages were blocked for some reasons:
- other widgetsets had no support for PostMessage and SendMessage
- few WM_USER messages were used by Windows and cause errors in LCL

After releasing 0.9.24 we reevaluated our decision since gtk and qt supported PostMessage and SendMessage. Then an implementation for Carbon appeared. Of course it would be a joke to block messages under Windows when all other widgetsets (where messages are aliens) support them. Now you can use PostMessage and SendMessage with few limitations:
- use Message numbers >= LM_USER
- sending messages outside application does not work (you cannot send message to another application)

And the last - if you need example - look at lazarus\examples\messages.