Мерцание PopupMenu
    
  ![]()  | 
Наши проекты:
 Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту  | 
|
| ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS | 
| [216.73.216.5] | 
 
 | 
		
  | 
    ПРАВИЛА РАЗДЕЛА · FAQ раздела Delphi · Книги по Delphi
  
    Мерцание PopupMenu
    
  | 
         
         
         
          
           Сообщ.
           #1
          
          , 
          
         
         
        
       | 
    |
| 
         | 
      
          Добрый день! 
        
      Возникла необходимость скрывать пункты PopupMenu в момент, когда оно раскрыто. Но это приводит к сильному мерцанию, избавиться от которого не удается. Как можно избавиться от мерцания PopupMenu? ![]() ![]() procedure TForm1.PopupMenu1Popup(Sender: TObject); begin   Timer1.Enabled := True; end; procedure TForm1.Timer1Timer(Sender: TObject); var   i: Integer; begin   Timer1.Enabled := False;   for i := PopupMenu1.Items.Count-1 downto 0 do     if i mod 2 = 0 then       PopupMenu1.Items[i].Visible := False; end; DFM Скрытый текст ![]() ![]() object Form1: TForm1   Left = 0   Top = 0   Caption = 'Form1'   ClientHeight = 109   ClientWidth = 258   Color = clBtnFace   Font.Charset = DEFAULT_CHARSET   Font.Color = clWindowText   Font.Height = -11   Font.Name = 'Tahoma'   Font.Style = []   OldCreateOrder = False   PopupMenu = PopupMenu1   PixelsPerInch = 96   TextHeight = 13   object Timer1: TTimer     Enabled = False     Interval = 500     OnTimer = Timer1Timer     Left = 64     Top = 24   end   object PopupMenu1: TPopupMenu     OnPopup = PopupMenu1Popup     Left = 16     Top = 24     object N11: TMenuItem       Caption = '1'     end     object N21: TMenuItem       Caption = '2'     end     object N31: TMenuItem       Caption = '3'     end     object N41: TMenuItem       Caption = '4'     end     object N51: TMenuItem       Caption = '5'     end     object N61: TMenuItem       Caption = '6'     end     object N71: TMenuItem       Caption = '7'     end     object N81: TMenuItem       Caption = '8'     end     object N91: TMenuItem       Caption = '9'     end     object N01: TMenuItem       Caption = '0'     end     object N12: TMenuItem       Caption = '1'     end     object N22: TMenuItem       Caption = '2'     end     object N32: TMenuItem       Caption = '3'     end     object N42: TMenuItem       Caption = '4'     end     object N52: TMenuItem       Caption = '5'     end     object N62: TMenuItem       Caption = '6'     end     object N72: TMenuItem       Caption = '7'     end     object N82: TMenuItem       Caption = '8'     end     object N92: TMenuItem       Caption = '9'     end     object N02: TMenuItem       Caption = '0'     end     object N13: TMenuItem       Caption = '1'     end     object N23: TMenuItem       Caption = '2'     end     object N33: TMenuItem       Caption = '3'     end     object N43: TMenuItem       Caption = '4'     end     object N53: TMenuItem       Caption = '5'     end     object N63: TMenuItem       Caption = '6'     end     object N73: TMenuItem       Caption = '7'     end     object N83: TMenuItem       Caption = '8'     end     object N93: TMenuItem       Caption = '9'     end     object N03: TMenuItem       Caption = '0'     end     object N14: TMenuItem       Caption = '1'     end     object N24: TMenuItem       Caption = '2'     end     object N34: TMenuItem       Caption = '3'     end     object N44: TMenuItem       Caption = '4'     end     object N54: TMenuItem       Caption = '5'     end     object N64: TMenuItem       Caption = '6'     end     object N74: TMenuItem       Caption = '7'     end     object N84: TMenuItem       Caption = '8'     end     object N94: TMenuItem       Caption = '9'     end     object N04: TMenuItem       Caption = '0'     end     object N15: TMenuItem       Caption = '1'     end     object N25: TMenuItem       Caption = '2'     end     object N35: TMenuItem       Caption = '3'     end     object N45: TMenuItem       Caption = '4'     end     object N55: TMenuItem       Caption = '5'     end     object N65: TMenuItem       Caption = '6'     end     object N75: TMenuItem       Caption = '7'     end     object N85: TMenuItem       Caption = '8'     end     object N95: TMenuItem       Caption = '9'     end     object N05: TMenuItem       Caption = '0'     end     object N16: TMenuItem       Caption = '1'     end     object N26: TMenuItem       Caption = '2'     end     object N36: TMenuItem       Caption = '3'     end     object N46: TMenuItem       Caption = '4'     end     object N56: TMenuItem       Caption = '5'     end     object N66: TMenuItem       Caption = '6'     end     object N76: TMenuItem       Caption = '7'     end     object N86: TMenuItem       Caption = '8'     end     object N96: TMenuItem       Caption = '9'     end     object N06: TMenuItem       Caption = '0'     end   end end PAS Скрытый текст ![]() ![]() unit Unit1; interface uses   Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,   Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.Menus, Vcl.ExtCtrls; type   TForm1 = class(TForm)     Timer1: TTimer;     PopupMenu1: TPopupMenu;     N11: TMenuItem;     N21: TMenuItem;     N31: TMenuItem;     N41: TMenuItem;     N51: TMenuItem;     N61: TMenuItem;     N71: TMenuItem;     N81: TMenuItem;     N91: TMenuItem;     N01: TMenuItem;     N12: TMenuItem;     N22: TMenuItem;     N32: TMenuItem;     N42: TMenuItem;     N52: TMenuItem;     N62: TMenuItem;     N72: TMenuItem;     N82: TMenuItem;     N92: TMenuItem;     N02: TMenuItem;     N13: TMenuItem;     N23: TMenuItem;     N33: TMenuItem;     N43: TMenuItem;     N53: TMenuItem;     N63: TMenuItem;     N73: TMenuItem;     N83: TMenuItem;     N93: TMenuItem;     N03: TMenuItem;     N14: TMenuItem;     N24: TMenuItem;     N34: TMenuItem;     N44: TMenuItem;     N54: TMenuItem;     N64: TMenuItem;     N74: TMenuItem;     N84: TMenuItem;     N94: TMenuItem;     N04: TMenuItem;     N15: TMenuItem;     N25: TMenuItem;     N35: TMenuItem;     N45: TMenuItem;     N55: TMenuItem;     N65: TMenuItem;     N75: TMenuItem;     N85: TMenuItem;     N95: TMenuItem;     N05: TMenuItem;     N16: TMenuItem;     N26: TMenuItem;     N36: TMenuItem;     N46: TMenuItem;     N56: TMenuItem;     N66: TMenuItem;     N76: TMenuItem;     N86: TMenuItem;     N96: TMenuItem;     N06: TMenuItem;     procedure PopupMenu1Popup(Sender: TObject);     procedure Timer1Timer(Sender: TObject);   private     { Private declarations }   public     { Public declarations }   end; var   Form1: TForm1; implementation {$R *.dfm} procedure TForm1.PopupMenu1Popup(Sender: TObject); begin   Timer1.Enabled := True; end; procedure TForm1.Timer1Timer(Sender: TObject); var   i: Integer; begin   Timer1.Enabled := False;   for i := PopupMenu1.Items.Count-1 downto 0 do     if i mod 2 = 0 then       PopupMenu1.Items[i].Visible := False; end; end.  | 
    
| 
         
         
         
          
           Сообщ.
           #2
          
          , 
          
         
         
        
       | 
    |
| 
         | 
      
          Я не заметил мерцания  
        
      Добавлено Как вариант, попробуйте ![]() ![]() procedure TForm1.Timer1Timer(Sender: TObject); var   i: Integer; begin   Timer1.Enabled := False; LockWindowUpdate(PopupMenu1.Handle);   for i := PopupMenu1.Items.Count-1 downto 0 do     if i mod 2 = 0 then       PopupMenu1.Items[i].Visible := False; LockWindowUpdate(0); end;  | 
    
| 
         
         
         
          
           Сообщ.
           #3
          
          , 
          
         
         
        
       | 
    |
| 
         | 
      
          Это я уже делал, не помогает.   
        
       | 
    
| 
         
         
         
          
           Сообщ.
           #4
          
          , 
          
         
         
        
       | 
    |
| 
         | 
      
          Свойство DoubleBuffered стоит?   
        
       | 
    
| 
         
         
         
          
           Сообщ.
           #5
          
          , 
          
         
         
        
       | 
    |
| 
         | 
      
          У меню его в принципе нет, а выставлять его для формы нет никакого смысла. 
        
      Вся проблема в методе TMenuItem.MenuChanged, внутри которого есть строка ![]() ![]() if Assigned(FOnChange) then FOnChange(Self, Source, Rebuild); она вызывает метод MenuItem.SubItemChanged, который на каждый чих пересоздает меню. ![]() ![]() ... RebuildHandle; ... Захотим, например, скрыть 20 пунктов в цикле, меню будет 20 раз пересоздано, отсюда и дикое мерцание...  | 
    
| 
         
         
         
          
           Сообщ.
           #6
          
          , 
          
         
         
        
       | 
    |
| 
         | 
      
          Ну во первых LockWindowUpdate(PopupMenu1.Handle); 
        
      PopupMenu1.Handle - это не хэндл окна меню, это хэндл самого меню. Чтобы получить хэндл окна надо хотя бы GetForegroundWindow сказать. Во сторых согласно майкросовтовских гуидлайнам у меню не должно быть 1. скролов (из-за большого количества пунктов меню) 2. двойного уровня сабменю 3. динамического изменения элементов в момент отображения Все это делает крайне не удобным работу с меню и если в GUI есть хотя бы один из этих пунктов, надо что-то менять.  | 
    
| 
         
         
         
          
           Сообщ.
           #7
          
          , 
          
         
         
        
       | 
    |
| 
         | 
      
          В этом и прелесть задачи - если нельзя, но очень хочется, то можно   
        
        На самом деле прогресс наметился, на тестовом приложении с таймером я добился нужного результата. В боевую прикладу перенести не получается, буду дальше копать...  |