[lazarus] Win32 menu does not work

Michael Van Canneyt michael.vancanneyt at wisa.be
Tue Jun 24 04:32:45 EDT 2003




On Tue, 24 Jun 2003, Mattias Gaertner wrote:

> On Tue, 24 Jun 2003 10:19:29 +0200
> "Micha Nelissen" <mdvpost at hotmail.com> wrote:
>
> > Hi.
> >
> > > After some debugging I found out that MENUINFO.WID is a 32 bit
> > > integer, but it contains a 16 bit application defined value. It seems
> > > the application is responsible for providing an increasing set of
> > > numbers in this identifier. Currently (see win32object.inc:2610) it
> > > is assigned a pointer which is a 32 bit value and thus too wide. It
> > > could be that the upper 16 bits are used for the
> > > WM_COMMAND.wNotifyCode but I am not sure.
> >
> > I have confirmed my above statements. The attached (very ugly) patch shows
> > how to make the menus work. It basically cuts off the high part of the
> > pointer, forcing it to be a 16 bit value as windows expects. Ideally, one
> > would keep a counter of some sort to keep track of used menu item ids
> > (also known as commands).
> >
> > The patch attached proves that using 16 bit integers, the menus will work.
> > Apply it in the lazarus/lcl/interfaces/win32 directory.
>
> Thanks. Applied.
>
>
> > I would like to hear your comments in the patch (probably not correct
> > coding style), it's a bit ugly (using pointers for the item ids), but the
> > current code is just wrong (with respect to the menu item ids).
>
> I can't test it, so I can't say much. Can you create a short list which
> example and/or component does/does not work and what needs to be done? Just
> start it, it does not need to be complete. Maybe this will help other win32
> devels.

As for the above patch: there should be the possibility to store the
command ID in the menu item records, and the application should keep
track of these commands. In Delphi, it is done using the TBits class:

var
  CommandPool: TBits;

function UniqueCommand: Word;
begin
  Result := CommandPool.OpenBit;
  CommandPool[Result] := True;
end;

and in TMenuItem.Create:

...
  FCommand := UniqueCommand;
..

When the menu item is destroyed, the bit is freed again:

  if FCommand <> 0 then
    CommandPool[FCommand] := False;

Just clipping the lower 16 bits may work most of the time,
but does not guarantee a unique ID.

Michael.






More information about the Lazarus mailing list