FAQ VCL
Меню

:: Меню ::
:: На главную ::
:: FAQ ::
:: Заметки ::
:: Практика ::
:: Win API ::
:: Проекты ::
:: Скачать ::
:: Секреты ::
:: Ссылки ::

:: Сервис ::
:: Написать ::

:: MVP ::

:: RSS ::

Яндекс.Метрика

Как опpеделить, существует ли на экpане всплывающее меню?

// Способ первый
{...}
if AnyPopup then
begin
  // есть всплывающее меню
end;
{...}

// Способ второй
// Меню - это окно с классом '#32768', но его HWND никак не равен
// его hMenu. Способ основан на поиске окна с классом '#32768'.
procedure TForm1.Timer1Timer(Sender: TObject);
var
  h: HWND;
begin
  // 0x8000 is the atom for a menu class. When an application calls this function,
  // the function checks whether a context menu is being displayed that the application created.
  h := FindWindowEx(0, 0, MAKEINTATOM($8000), nil);
  Caption := IntToStr(h);
end;

// Способ третий
// Способ основан на перехвате сообщения WM_ENTERIDLE, когда WParam = MSGF_MENU,
// то lParam будет содержать HWND меню. Сообщение WM_ENTERIDLE уведомляет главное
// окно что система пpостаивает из-за отобpажения модального диалога или меню.
// Сообщение приходит когда открывается MainMenu, не не приходит для PopupMenu.
type
  TForm1 = class(TForm)
  private
    procedure WMEnterIdle(var Msg: TWMEnterIdle); message WM_ENTERIDLE;
  end;

implementation

procedure TForm1.WMEnterIdle(var Msg: TWMEnterIdle);
begin
  inherited;

  if Msg.Msg = WM_ENTERIDLE then
    if Msg.Source = MSGF_MENU then
      Caption := IntToStr(Msg.IdleWnd);
end;


Как узнать о нажатии non-menu клавиши в момент когда меню показано?

type
  TForm1 = class(TForm)
    {...}
  private
    procedure WMMenuChar(var Msg: TMessage); message WM_MENUCHAR;
  end;

procedure TForm1.WMMenuChar(var Msg: TMessage);
begin
   Form1.Caption := 'Non standard menu key pressed';
   Msg.Result := 1;
end;


Как заставить системное меню выпасть в указанном месте?

procedure TForm1.Button1Click(Sender: TObject);
const
  WM_POPUPSYSTEMMENU = $313;
begin
  SendMessage(Handle, WM_POPUPSYSTEMMENU, 0,
              MakeLong( Mouse.CursorPos.X, Mouse.CursorPos.Y));
end;


Как удалить пункт системного меню?

procedure TForm1.Button1Click(Sender: TObject);
var
  Handle: THandle;
begin
  Handle := GetSystemMenu(Self.Handle, False);
  RemoveMenu(Handle, 1, MF_BYPOSITION);
  RemoveMenu(Handle, 2, MF_BYPOSITION);
end;


Как ограничить количество отображаемых пунктов длинного меню?

type
  TForm1 = class(TForm)
    PopupMenu1: TPopupMenu;
    N01: TMenuItem;
    N11: TMenuItem;
    N21: TMenuItem;
    N31: TMenuItem;
    N41: TMenuItem;
    N51: TMenuItem;
    N61: TMenuItem;
    N71: TMenuItem;
    N81: TMenuItem;
    N91: TMenuItem;
    {...}
  end;

implementation

procedure TForm1.FormCreate(Sender: TObject);
var
  Info: TMenuInfo;
begin
  FillChar(Info, SizeOf(Info), 0);
  Info.cbSize := SizeOf(Info);
  Info.fMask := MIM_MAXHEIGHT;

  if GetMenuInfo(PopupMenu1.Handle, Info) then
  begin
    Info.cyMax := 150;
    SetMenuInfo(PopupMenu1.Handle, Info);
  end;
end;


Как выделить нужный пункт при открытии меню?

procedure TForm1.PopupMenu1Popup(Sender: TObject);
var
  i, j: Integer;
begin
  for i := 0 to TPopupMenu(Sender).Items.Count-1 do
    if TPopupMenu(Sender).Items[i].Default then
    begin
      for j := 0 to i do
        PostMessage(GetWindowDC(PopupMenu1.Handle), WM_KEYDOWN, 40, 0);
      Break;
    end;
end;

При использовании материала - ссылка на сайт обязательна