View Issue Details

IDProjectCategoryView StatusLast Update
0017519LazarusLCLpublic2013-07-13 07:12
ReporterSven BarthAssigned ToFelipe Monteiro de Carvalho 
PrioritynormalSeverityminorReproducibilityalways
Status resolvedResolutionfixed 
Product Version0.9.29 (SVN)Product Build 
Target VersionFixed in Version1.1 (SVN) 
Summary0017519: [WinCE] Regression: "New" sub menu is opened if MenuItem.Command=11
DescriptionWith the changes to the LCL WinCE menu system a regression occured: If menu items are changed dynamically (might be triggered by designed menus as well, perhaps) and a menuitem happens to have the command "11" the "New" menu from Windows Mobile is opened.

I don't know whether there are other "special" item IDs that should be avoided, but the patch mentioned in one of the other bug reports places the save ones from 200 on.
Additional InformationThe following closed bug reports are about the same issue (from the time the old menu system was used):

- 0013192
- 0011457

Attached is an example. Press the button "Add / Remove" until "Command: 11" appears in the menu. Then click on "MyMenu->ClickMe". The "new" menu will now appear.
Tagswince
Fixed in Revision42069
LazTarget-
WidgetsetWinCE
Attached Files
  • menutest2.zip (2,876 bytes)
  • menuitem_command_pool.patch (4,605 bytes)
    Index: lcl/include/menuitem.inc
    ===================================================================
    --- lcl/include/menuitem.inc	(revision 40800)
    +++ lcl/include/menuitem.inc	(working copy)
    @@ -107,7 +107,7 @@
       FChecked := False;
       FVisible := True;
       FEnabled := True;
    -  FCommand := UniqueCommand;
    +  FCommand := TWSMenuItemClass(WidgetSetClass).OpenCommand;
       FImageIndex := -1;
       FBitmapIsValid := True;
       FRightJustify := False;
    @@ -206,7 +206,7 @@
         FreeAndNil(FMenuItemHandlers[HandlerType]);
       if FParent <> nil then
         FParent.FItems.Remove(Self);
    -  if FCommand <> 0 then CommandPool[FCommand] := False;
    +  if FCommand <> 0 then TWSMenuItemClass(WidgetSetClass).CloseCommand(FCommand);
       //debugln('TMenuItem.Destroy B ',dbgsName(Self));
       inherited Destroy;
     end;
    Index: lcl/interfaces/wince/wincewsmenus.pp
    ===================================================================
    --- lcl/interfaces/wince/wincewsmenus.pp	(revision 40800)
    +++ lcl/interfaces/wince/wincewsmenus.pp	(working copy)
    @@ -51,6 +51,8 @@
           var AForm: TForm): Boolean;
         {$endif}
       published
    +    class function OpenCommand: LongInt; override;
    +    class procedure CloseCommand(ACommand: LongInt); override;
         class procedure AttachMenu(const AMenuItem: TMenuItem); override;
         class function CreateHandle(const AMenuItem: TMenuItem): HMENU; override;
         class procedure DestroyHandle(const AMenuItem: TMenuItem); override;
    @@ -86,7 +88,7 @@
       end;
     
     const
    -  // IDs corresponding to the file winceres.rc
    +  // IDs corresponding to the file wincemenures.rc
       MenuBarID_Items  = 20000;
       MenuBarID_PopUp_Item = 20001;
       MenuBarID_Item_Popup = 20002;
    @@ -96,6 +98,7 @@
       MenuBarID_Empty = 20006;
       MenuBarID_L = 1001;
       MenuBarID_R = 1002;
    +  MenuBarID_BASE = 1003;
     var
       MenuItemsList: TStringList;
       MenuHandleList, MenuLCLObjectList: TFPList;
    @@ -579,7 +582,6 @@
       begin
         GetWindowRect(mbi.hwndMB, R);
         Windows.SystemParametersInfo(SPI_GETWORKAREA, 0, @WR, 0);
    -
         if WR.Bottom > R.Top then
           SetWindowPos(wnd, 0, 0, 0, WR.Right - WR.Left, R.Top - WR.Top, SWP_NOZORDER or SWP_NOREPOSITION or SWP_NOMOVE);
       end;
    @@ -893,6 +895,19 @@
           Break;
         end;
     end;
    +
    +class function TWinCEWSMenuItem.OpenCommand: LongInt;
    +begin
    +  Result := inherited OpenCommand;
    +  Result := Result + MenuBarID_BASE;
    +end;
    +
    +class procedure TWinCEWSMenuItem.CloseCommand(ACommand: LongInt);
    +begin
    +  ACommand := ACommand - MenuBarID_BASE;
    +  inherited CloseCommand(ACommand);
    +end;
    +
     {$endif}
     
     class procedure TWinCEWSMenuItem.AttachMenu(const AMenuItem: TMenuItem);
    Index: lcl/menus.pp
    ===================================================================
    --- lcl/menus.pp	(revision 40800)
    +++ lcl/menus.pp	(working copy)
    @@ -457,19 +457,6 @@
       WSMenus,
       Forms {KeyDataToShiftState};
     
    -{ Menu command management }
    -
    -var
    -  CommandPool: TBits = nil;
    -
    -function UniqueCommand: LongInt;
    -begin
    -  if CommandPool = nil then
    -    CommandPool := TBits.Create(16);
    -  Result := CommandPool.OpenBit;
    -  CommandPool[Result] := True;
    -end;
    -
     { Easy Menu building }
     
     procedure AddMenuItems(AMenu: TMenu; const Items: array of TMenuItem);
    @@ -596,7 +583,4 @@
       Result := FPosition < FMenuItem.Count;
     end;
     
    -finalization
    -  FreeThenNil(CommandPool);
    -
     end.
    Index: lcl/widgetset/wsmenus.pp
    ===================================================================
    --- lcl/widgetset/wsmenus.pp	(revision 40800)
    +++ lcl/widgetset/wsmenus.pp	(working copy)
    @@ -55,6 +55,8 @@
     
       TWSMenuItem = class(TWSLCLComponent)
       published
    +    class function  OpenCommand: LongInt; virtual;
    +    class procedure CloseCommand(ACommand: LongInt); virtual;
         class procedure AttachMenu(const AMenuItem: TMenuItem); virtual;
         class function  CreateHandle(const AMenuItem: TMenuItem): HMENU; virtual;
         class procedure DestroyHandle(const AMenuItem: TMenuItem); virtual;
    @@ -105,8 +107,31 @@
     
     implementation
     
    +{ Menu command management }
    +
    +var
    +  CommandPool: TBits = nil;
    +
    +function UniqueCommand: LongInt;
    +begin
    +  if CommandPool = nil then
    +    CommandPool := TBits.Create(16);
    +  Result := CommandPool.OpenBit;
    +  CommandPool[Result] := True;
    +end;
    +
     { TWSMenuItem }
     
    +class function TWSMenuItem.OpenCommand: LongInt;
    +begin
    +  Result := UniqueCommand;
    +end;
    +
    +class procedure TWSMenuItem.CloseCommand(ACommand: LongInt);
    +begin
    +  CommandPool[ACommand] := False;
    +end;
    +
     class procedure TWSMenuItem.AttachMenu(const AMenuItem: TMenuItem);
     begin
     end;
    @@ -238,4 +263,6 @@
       Done := True;
     end;
     
    +finalization
    +  FreeThenNil(CommandPool);
     end.
    

Relationships

duplicate of 0013192 resolvedFelipe Monteiro de Carvalho Patches WinCE any time show in main menu Windows CE NEW menu 

Activities

2010-09-30 11:36

 

menutest2.zip (2,876 bytes)

Felipe Monteiro de Carvalho

2010-10-12 15:44

developer   ~0041747

In which device did you test?

In the Smartphone WinCE 5 emulator adding items doesn't work at all

In the PocketPC WinCE 5 emulator only the first item adding works

With statically created menus everything works fine.

In no cases I have seen any "New" menu. A screenshot would also help.

In general I haven't really tested adding menus dynamically, only changing already present menus.

thanks,

Sven Barth

2010-10-12 17:47

manager   ~0041756

I've tested it on a Windows Mobile 5.0 Motorola Symbol device (English version). I'll check whether I can reproduce it on my own phone or an emulator.
I can't send you a screenshot from the affected device before Friday, cause it is currently not with me.

Besides that issue adding/removing items dynamically in a submenu works without problems.

Regards,
Sven

Felipe Monteiro de Carvalho

2010-10-13 18:02

developer   ~0041775

The problem is that changing this is too risky. The menus in WinCE are very problematic and it took a loooong time to get them working well for static menus. I'll postpone fixing this until 0.9.30 is released.

Sven Barth

2010-10-24 12:11

manager   ~0042048

Take your time. In our business application I'll just check for "Command = 11" and recreate the MenuItem if that is true.

I can also reproduce this on a Windows Mobile 6.1 (real device) and on an emulated Windows Mobile 5.0. I'll attach the screenshot after this note (It's good that the emulator is supported by Wine :P ).

Regards,
Sven

2010-10-24 12:12

 

John vd Waeter

2010-11-01 10:30

reporter   ~0042541

Sven, do you mind sharing the code that checks for "Command=11" and if so, recreates the menu?
I have static menus on different forms, yet indeed the "new" menu appears on one of them (and works too ;-))
tia!
John

Sven Barth

2010-11-01 11:56

manager   ~0042546

@John: that's simple. If a menu item has a Command with 11 then just recreate it, insert it at the old items position and remove the old one. ;)

And it's nice that I'm not the only one who has that problem. :P

Regards,
Sven

John vd Waeter

2010-11-01 12:23

reporter   ~0042547

Last edited: 2010-11-01 13:55

Ehm... that was my intention yes... the question is: where do I check this? The forms are autocreated and I feel the command-values are already set at designtime. Should I use the OnShow-event to do this? (hence my question for the code-snippet).

Normally I love to find out and try myself, but there is so much time involved in dealing with things that just don't work as one expects... (that is: testing on pocketpc AND smartphone, emulators 5, 6.1 and 6.5 and a couple of real devices...)

John

Zaher Dirkey

2013-04-14 09:50

reporter   ~0066951

It is same bug resolved in the past by shifting the command id
http://bugs.freepascal.org/view.php?id=11457
here
http://svn.freepascal.org/cgi-bin/viewvc.cgi?view=revision&root=lazarus&revision=18738

The best idea i think is to make UniqueCommand in the WedgetSet, So in WINCE wedgetset we shift the number by X to reserve it for system command and also for wincemenures.rc IDs

Zaher Dirkey

2013-04-15 15:45

reporter  

menuitem_command_pool.patch (4,605 bytes)
Index: lcl/include/menuitem.inc
===================================================================
--- lcl/include/menuitem.inc	(revision 40800)
+++ lcl/include/menuitem.inc	(working copy)
@@ -107,7 +107,7 @@
   FChecked := False;
   FVisible := True;
   FEnabled := True;
-  FCommand := UniqueCommand;
+  FCommand := TWSMenuItemClass(WidgetSetClass).OpenCommand;
   FImageIndex := -1;
   FBitmapIsValid := True;
   FRightJustify := False;
@@ -206,7 +206,7 @@
     FreeAndNil(FMenuItemHandlers[HandlerType]);
   if FParent <> nil then
     FParent.FItems.Remove(Self);
-  if FCommand <> 0 then CommandPool[FCommand] := False;
+  if FCommand <> 0 then TWSMenuItemClass(WidgetSetClass).CloseCommand(FCommand);
   //debugln('TMenuItem.Destroy B ',dbgsName(Self));
   inherited Destroy;
 end;
Index: lcl/interfaces/wince/wincewsmenus.pp
===================================================================
--- lcl/interfaces/wince/wincewsmenus.pp	(revision 40800)
+++ lcl/interfaces/wince/wincewsmenus.pp	(working copy)
@@ -51,6 +51,8 @@
       var AForm: TForm): Boolean;
     {$endif}
   published
+    class function OpenCommand: LongInt; override;
+    class procedure CloseCommand(ACommand: LongInt); override;
     class procedure AttachMenu(const AMenuItem: TMenuItem); override;
     class function CreateHandle(const AMenuItem: TMenuItem): HMENU; override;
     class procedure DestroyHandle(const AMenuItem: TMenuItem); override;
@@ -86,7 +88,7 @@
   end;
 
 const
-  // IDs corresponding to the file winceres.rc
+  // IDs corresponding to the file wincemenures.rc
   MenuBarID_Items  = 20000;
   MenuBarID_PopUp_Item = 20001;
   MenuBarID_Item_Popup = 20002;
@@ -96,6 +98,7 @@
   MenuBarID_Empty = 20006;
   MenuBarID_L = 1001;
   MenuBarID_R = 1002;
+  MenuBarID_BASE = 1003;
 var
   MenuItemsList: TStringList;
   MenuHandleList, MenuLCLObjectList: TFPList;
@@ -579,7 +582,6 @@
   begin
     GetWindowRect(mbi.hwndMB, R);
     Windows.SystemParametersInfo(SPI_GETWORKAREA, 0, @WR, 0);
-
     if WR.Bottom > R.Top then
       SetWindowPos(wnd, 0, 0, 0, WR.Right - WR.Left, R.Top - WR.Top, SWP_NOZORDER or SWP_NOREPOSITION or SWP_NOMOVE);
   end;
@@ -893,6 +895,19 @@
       Break;
     end;
 end;
+
+class function TWinCEWSMenuItem.OpenCommand: LongInt;
+begin
+  Result := inherited OpenCommand;
+  Result := Result + MenuBarID_BASE;
+end;
+
+class procedure TWinCEWSMenuItem.CloseCommand(ACommand: LongInt);
+begin
+  ACommand := ACommand - MenuBarID_BASE;
+  inherited CloseCommand(ACommand);
+end;
+
 {$endif}
 
 class procedure TWinCEWSMenuItem.AttachMenu(const AMenuItem: TMenuItem);
Index: lcl/menus.pp
===================================================================
--- lcl/menus.pp	(revision 40800)
+++ lcl/menus.pp	(working copy)
@@ -457,19 +457,6 @@
   WSMenus,
   Forms {KeyDataToShiftState};
 
-{ Menu command management }
-
-var
-  CommandPool: TBits = nil;
-
-function UniqueCommand: LongInt;
-begin
-  if CommandPool = nil then
-    CommandPool := TBits.Create(16);
-  Result := CommandPool.OpenBit;
-  CommandPool[Result] := True;
-end;
-
 { Easy Menu building }
 
 procedure AddMenuItems(AMenu: TMenu; const Items: array of TMenuItem);
@@ -596,7 +583,4 @@
   Result := FPosition < FMenuItem.Count;
 end;
 
-finalization
-  FreeThenNil(CommandPool);
-
 end.
Index: lcl/widgetset/wsmenus.pp
===================================================================
--- lcl/widgetset/wsmenus.pp	(revision 40800)
+++ lcl/widgetset/wsmenus.pp	(working copy)
@@ -55,6 +55,8 @@
 
   TWSMenuItem = class(TWSLCLComponent)
   published
+    class function  OpenCommand: LongInt; virtual;
+    class procedure CloseCommand(ACommand: LongInt); virtual;
     class procedure AttachMenu(const AMenuItem: TMenuItem); virtual;
     class function  CreateHandle(const AMenuItem: TMenuItem): HMENU; virtual;
     class procedure DestroyHandle(const AMenuItem: TMenuItem); virtual;
@@ -105,8 +107,31 @@
 
 implementation
 
+{ Menu command management }
+
+var
+  CommandPool: TBits = nil;
+
+function UniqueCommand: LongInt;
+begin
+  if CommandPool = nil then
+    CommandPool := TBits.Create(16);
+  Result := CommandPool.OpenBit;
+  CommandPool[Result] := True;
+end;
+
 { TWSMenuItem }
 
+class function TWSMenuItem.OpenCommand: LongInt;
+begin
+  Result := UniqueCommand;
+end;
+
+class procedure TWSMenuItem.CloseCommand(ACommand: LongInt);
+begin
+  CommandPool[ACommand] := False;
+end;
+
 class procedure TWSMenuItem.AttachMenu(const AMenuItem: TMenuItem);
 begin
 end;
@@ -238,4 +263,6 @@
   Done := True;
 end;
 
+finalization
+  FreeThenNil(CommandPool);
 end.

Zaher Dirkey

2013-04-15 15:45

reporter   ~0066969

I made patch to move UniqueCommand and CommandPool to WSMenus unit and call it from MenuItem,
So in Wince WinCEWSMenus override it and shift the command number by MenuBarID_BASE, this bug was fixed.

Felipe Monteiro de Carvalho

2013-07-13 07:12

developer   ~0068824

Thanks, applied

Issue History

Date Modified Username Field Change
2010-09-30 11:36 Sven Barth New Issue
2010-09-30 11:36 Sven Barth File Added: menutest2.zip
2010-09-30 11:36 Sven Barth Widgetset => WinCE
2010-10-01 14:03 Felipe Monteiro de Carvalho Status new => assigned
2010-10-01 14:03 Felipe Monteiro de Carvalho Assigned To => Felipe Monteiro de Carvalho
2010-10-12 15:44 Felipe Monteiro de Carvalho LazTarget => -
2010-10-12 15:44 Felipe Monteiro de Carvalho Note Added: 0041747
2010-10-12 15:44 Felipe Monteiro de Carvalho Status assigned => feedback
2010-10-12 15:45 Felipe Monteiro de Carvalho Status feedback => confirmed
2010-10-12 17:47 Sven Barth Note Added: 0041756
2010-10-13 18:02 Felipe Monteiro de Carvalho Note Added: 0041775
2010-10-24 12:11 Sven Barth Note Added: 0042048
2010-10-24 12:12 Sven Barth File Added: screenshot-wince-new-menu.jpg
2010-11-01 10:30 John vd Waeter Note Added: 0042541
2010-11-01 11:56 Sven Barth Note Added: 0042546
2010-11-01 12:23 John vd Waeter Note Added: 0042547
2010-11-01 13:55 John vd Waeter Note Edited: 0042547
2011-02-07 17:10 Felipe Monteiro de Carvalho Relationship added duplicate of 0013192
2013-04-14 09:01 Zaher Dirkey Tag Attached: wince
2013-04-14 09:50 Zaher Dirkey Note Added: 0066951
2013-04-15 15:45 Zaher Dirkey File Added: menuitem_command_pool.patch
2013-04-15 15:45 Zaher Dirkey Note Added: 0066969
2013-07-13 07:12 Felipe Monteiro de Carvalho Fixed in Revision => 42069
2013-07-13 07:12 Felipe Monteiro de Carvalho Note Added: 0068824
2013-07-13 07:12 Felipe Monteiro de Carvalho Status confirmed => resolved
2013-07-13 07:12 Felipe Monteiro de Carvalho Fixed in Version => 1.1 (SVN)
2013-07-13 07:12 Felipe Monteiro de Carvalho Resolution open => fixed