1

システムメニューに項目を追加する次のコードがあります。私の問題は、システム メニューに追加されたポップアップ メニューを DeleteMenu(SysMenu, cLANGMENU, MF_BYCOMMAND) が削除していないことです。理解できないのは、追加された項目 (スキャン コンポーネント) では機能するのに、「プログラム言語」では機能しない理由です。

procedure TForm1.Button1Click(Sender: TObject);
const aBaseItem : string = 'Programm-Sprache';
      cSepSYSTEM_MENU = wm_user + 100;
      cScanCompSystemMenu = wm_user + 101;
      cLANGMENU = wm_user + 102;
      SC_ITEM = $FF00;
var
  MenuItemInfo: TMenuItemInfo;
  PopupMenu: HMENU;
  Result: Boolean;
  SysMenu: HMenu;
  iPos, NumItems : Integer;
  wTemp1, wtemp2 : string;
  Buffer: array[0..79] of Char;
begin
  {Create the popup menu}
  PopupMenu := CreatePopupMenu;
  {Insert an item into it}
  for iPos := 5 downto 0 do
  begin
    FillChar(MenuItemInfo, SizeOf(MenuItemInfo), iPos);
      with MenuItemInfo do
      begin
        cbSize := SizeOf(MenuItemInfo);
        fMask := MIIM_TYPE or MIIM_ID;
        fType := MFT_STRING;
        wID := SC_ITEM + iPos;
        dwTypeData := PChar(inttostr(iPos));
        cch := Length(dwTypeData) * 2 + 2; //4; {'Item' is 4 chars}
      end;
    Result := InsertMenuItem(PopupMenu, 0, True, MenuItemInfo);
    Assert(Result, 'InsertMenuItem failed');
  end;

  SysMenu := GetSystemMenu(Handle, False);
  //why this isn't working???
  if not DeleteMenu(SysMenu, cLANGMENU, MF_BYCOMMAND) then
   begin
     ShowMessage('System Error Message: '+ SysErrorMessage(GetLastError)) ;
     //error message is - operation completed succesfully
   end;

  {Insert the popup into the system menu}
  FillChar(MenuItemInfo, SizeOf(MenuItemInfo), 0);
  with MenuItemInfo do
  begin
    cbSize := SizeOf(MenuItemInfo);
    fMask := MIIM_SUBMENU or MIIM_TYPE or MIIM_ID;
    fType := MFT_STRING;
    hSubMenu := PopupMenu;
    wId := cLANGMENU;
    dwTypeData :=  PChar('Test');//Before editing the question it was Program Language
    cch := Length(dwTypeData) * 2 + 2; //7; {'SubMenu' is 7 chars}
  end;

  Assert(SysMenu <> 0);
  Result := InsertMenuItem(SysMenu, GetMenuItemCount(SysMenu), True, MenuItemInfo);
  Assert(Result, 'InsertMenuItem failed');


      SysMenu := GetSystemMenu(Handle, False);
  //delete menu if exists - this is working
  DeleteMenu(SysMenu,cSepSYSTEM_MENU,MF_SEPARATOR);
  DeleteMenu(SysMenu,cScanCompSystemMenu,MFT_STRING);
  //add new ones
  InsertMenu(SysMenu, Word(-1), MF_SEPARATOR, cSepSYSTEM_MENU, '');
  FillChar(MenuItemInfo, SizeOf(TMenuItemInfo), #0);
  with MenuItemInfo do
   begin
   cbSize := SizeOf(TMenuItemInfo);
    fMask := MIIM_TYPE or MIIM_ID or MIIM_STATE;
    fType := MFT_STRING;
    wId := cScanCompSystemMenu;
    dwTypeData := PChar('Scan components');
    cch := Length('Scan components');
   end;
  Result := InsertMenuItem(SysMenu, GetMenuItemCount(SysMenu), True, MenuItemInfo);
  Assert(Result, 'InsertMenuItem failed');
end;

LE: このコードは複数回実行されるため、追加されたアイテムを毎回削除する必要があります。LE2: このコードは Delphi(Object Pascal) で書かれていますが、Windows から WinApi 関数を呼び出します。おそらく、これに集中的に取り組んでいて、C/C++ プログラマーである誰かが助けてくれるでしょう。

4

3 に答える 3

4

The documentation indicates that you need to set the miim_ID flag to use wID. Without it, the OS ignores that field, so the menu item you create doesn't get the ID value you specify. Thus, your further attempts to refer to that item by that ID fail.

You set that flag when you add the "Scan components" item, but you omit it for the "Test" item.

You could make it easier on yourself by calling GetSystemMenu(Handle, True). That will reset the menu each time you call it, so you don't have to undo any prior customization.

于 2012-07-30T14:32:42.457 に答える
1

Rob Kennedy と David Heffernan からの回答に基づいて、解決しました。解決策は、メニュー項目を削除することではなく、システム メニューの新しい新しいハンドルを取得することです。以下のコード:

procedure TForm1.Button1Click(Sender: TObject);
const 
      cSepSYSTEM_MENU = wm_user + 100;
      cScanCompSystemMenu = wm_user + 101;
      cLANGMENU = 65444;
      SC_ITEM = $FF00;
var
  MenuItemInfo: TMenuItemInfo;
  PopupMenu: HMENU;
  Result: Boolean;
  SysMenu: HMenu;
  iPos, NumItems : Integer;
  wTemp1, wtemp2 : string;
  Buffer: array[0..79] of Char;
  subMenu : HMENU;
begin

  SysMenu := GetSystemMenu(Handle, True);
  SysMenu := GetSystemMenu(Handle, False);

  //add new ones
  InsertMenu(SysMenu, Word(-1), MF_SEPARATOR, cSepSYSTEM_MENU, '');
  FillChar(MenuItemInfo, SizeOf(TMenuItemInfo), #0);
  with MenuItemInfo do
   begin
   cbSize := SizeOf(TMenuItemInfo);
    fMask := MIIM_TYPE or MIIM_ID or MIIM_STATE;
    fType := MFT_STRING;
    wId := cScanCompSystemMenu;
    dwTypeData := PChar('Scan components');
    cch := Length('Scan components');
   end;
  Result := InsertMenuItem(SysMenu, GetMenuItemCount(SysMenu), True, MenuItemInfo);
  Assert(Result, 'InsertMenuItem failed');

  {Create the popup menu}
  PopupMenu := CreatePopupMenu;
  {Insert an item into it}
  for iPos := Random(10) downto 0 do
  begin
    FillChar(MenuItemInfo, SizeOf(MenuItemInfo), 0);
      with MenuItemInfo do
      begin
        cbSize := SizeOf(MenuItemInfo);
        fMask := MIIM_TYPE or MIIM_ID;
        fType := MFT_STRING;
        wID := SC_ITEM + iPos;
        dwTypeData := PChar(inttostr(iPos));
        cch := Length(dwTypeData) * 2 + 2; //4; {'Item' is 4 chars}
      end;
    Result := InsertMenuItem(PopupMenu, 0, True, MenuItemInfo);
    Assert(Result, 'InsertMenuItem failed');
  end;

  FillChar(MenuItemInfo, SizeOf(MenuItemInfo), 0);
  with MenuItemInfo do

  begin
    cbSize := SizeOf(MenuItemInfo);
    fMask := MIIM_SUBMENU or MIIM_TYPE;
    fType := MFT_STRING;
    hSubMenu := PopupMenu;
    wId := cLANGMENU;
    dwTypeData :=  PChar('Programm-Language');
    cch := Length(dwTypeData) * 2 + 2; //7; {'SubMenu' is 7 chars}
  end;

  Assert(SysMenu <> 0);
  Result := InsertMenuItem(SysMenu, GetMenuItemCount(SysMenu), True, MenuItemInfo);
  Assert(Result, 'InsertMenuItem failed');
end;
于 2012-07-31T07:26:47.157 に答える
1

Delphi XE2 - ボタンをクリックすると、Program Language毎回システム メニュー項目が追加Scan componentsされ、削除されたと言っても効果はありません。

「プログラム言語」にはサブメニュー項目0 -> 5があるのに対し、サブメニューのないトップレベルのメニュー項目であるためだとScan components思います。最初にそれらを削除すると、削除できるはずだと思います親メニュー (うーん、それは自分の子をクリーンアップするべきではありませんか?)。

申し訳ありませんが、キャッチするフライトがあり、Delphi のバージョンが異なると動作が異なるように見えるため、これをコーディング/検証する時間がありません。 .

もっとお役に立てれば幸いです。

于 2012-07-30T10:46:22.590 に答える