Hello,
in our application I have Main Menu that is dynamically changed by active form and others conditions. But problem is, that when add new menu item by Insert method it call NCPaint method and it paint a gray empty bar instead menu.
...
MainMenu1.BeginUpdate;
InsertItemToMainMenu();//After this step I can see gray bar instead main menu
MainMenu1.EndUpdate; //After this step it is OK.
...
I tried to suppress paint in non client area by override WMNCPaint. Now it is not flickered, but form loose transparent windows style (Windows 7 aero or Windows 10) .
Is it any way how to update Main meu without flickering?
Thanks
Petr
Does this concern TAdvMainMenu?
If so, is this TAdvMainMenu used directly coupled to the Form.Menu or a TAdvMainMenu used on a TAdvToolBar?
Hi Bruno,
Yes it is problem of TAdvMenu in normal Delphi MainMenu, it is not necessary use BeginUpdate and EndUpdate, so behaviour is a little different.
I tested it with small application without Tollbars.
See code:
unit Main;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.Menus, Vcl.StdCtrls, AdvMenus,
AdvAppStyler;
type
TFMain = class(TForm)
MainMenu1: TAdvMainMenu;
File1: TMenuItem;
A1: TMenuItem;
Help1: TMenuItem;
B1: TMenuItem;
Button1: TButton;
AdvFormStyler1: TAdvFormStyler;
procedure Button1Click(Sender: TObject);
private
DisableNCPaint: Boolean;
procedure InsertMenuItem;
protected
procedure WMNCPaint(var Message: TWMNCPaint); message WM_NCPaint;
public
{ Public declarations }
end;
var
FMain: TFMain;
implementation
{$R *.dfm}
procedure TFMain.Button1Click(Sender: TObject);
begin
// MainMenu1.DirectUpdate := true;
MainMenu1.BeginUpdate;
InsertMenuItem;
MainMenu1.EndUpdate;
end;
procedure TFMain.InsertMenuItem;
var MI: TMenuItem;
begin
MI := TMenuItem.Create(MainMenu1);
MI.Caption := 'C';
DisableNCPaint := true;
MainMenu1.Items.Insert(1, MI);
DisableNCPaint := false;
end;
procedure TFMain.WMNCPaint(var Message: TWMNCPaint);
begin
if not DisableNCPaint then
inherited
else
begin
inherited;
// Message.Result := 0;
RedrawWindow(Handle,nil,Message.RGN,{RDW_ERASE or }RDW_NOFRAME or RDW_NOERASE);
end;
end;
end.
DFM File:
object FMain: TFMain
Left = 0
Top = 0
Caption = 'FMain'
ClientHeight = 260
ClientWidth = 635
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
Menu = MainMenu1
OldCreateOrder = False
PixelsPerInch = 96
TextHeight = 13
object Button1: TButton
Left = 16
Top = 96
Width = 75
Height = 25
Caption = 'Button1'
TabOrder = 0
OnClick = Button1Click
end
object MainMenu1: TAdvMainMenu
Version = '2.6.5.1'
Left = 88
Top = 24
object File1: TMenuItem
Caption = 'File'
object A1: TMenuItem
Caption = 'A'
end
end
object Help1: TMenuItem
Caption = 'Help'
object B1: TMenuItem
Caption = 'B'
end
end
end
end
I have tested this here but I cannot notice anything special. I have replace the TAdvMainMenu but I do not see any difference. When I introduce the WMNCPaint, there is some light flicker I can see because you call RedrawWindow(). But when testing this without WNNCPaint() override, I see no flicker at all.
If a problem persists and if the behavior of TAdvMainMenu is different from TMainMenu, please provide some sample source project with which we can reproduce this here.
Ou, my inserted images has been lost. :-(