Delphi: Brugerdefineret vinduesmenu: Msg.CmdType og $ FFF0 præcisering nødvendig

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg laver nogle afslutninger på min Windows-applikation udviklet i Delphi XE6.


I øjeblikket bliver jeg forvirret om vinduessystemmenuen, jeg mener den menu, der vises, når du klikker på ikonet i titellinjen til venstre.


Jeg har defineret to procedurer:


// this inserts one additional command into the menu
procedure InsertCommand(Sender: TObject);

// this is obviously a handler of mouse clicks on that menu
procedure OnSysCommand(var Msg: TWMSysCommand); message WM\_SYSCOMMAND;





Definitionerne følger:


const
  ALWAYS\_ON\_TOP\_ID = 1000;

var
  HandleMenu: THandle;
  sAlwaysOnTop: string;

procedure TFormMain.InsertCommand(Sender: TObject);
begin
  // get the system menu handle and store it into form-level defined variable
  HandleMenu := GetSystemMenu(Handle, False);

  // just to make it nicer, I add a separator line
  AppendMenu(HandleMenu, MF\_SEPARATOR, 0, '');

  // append "Always on Top" language localized string at the end of the menu
  AppendMenu(HandleMenu, MF\_STRING, ALWAYS\_ON\_TOP\_ID, PChar(sAlwaysOnTop));
end;


procedure TFormMain.OnSysCommand(var Msg: TWMSysCommand);
begin

  if Msg.CmdType = ALWAYS\_ON\_TOP\_ID then
    if GetMenuState(HandleMenu, ALWAYS\_ON\_TOP\_ID, MF\_BYCOMMAND) and MF\_CHECKED = MF\_CHECKED
      then begin
        FormStyle := fsNormal;
        CheckMenuItem(HandleMenu, ALWAYS\_ON\_TOP\_ID, MF\_UNCHECKED);
      end else begin
        FormStyle := fsStayOnTop;
        CheckMenuItem(HandleMenu, ALWAYS\_ON\_TOP\_ID, MF\_CHECKED);
      end;

  inherited;
end;





Jeg læser nu, at den rigtige brug er:


Msg.CmdType and $FFF0


men hvis jeg bruger det, stopper min kode med at arbejde.


Fra den officielle MSDN-kilde citerer jeg: [14]



  I WM\_SYSCOMMAND meddelelser bruges de fire lavordede bit af wParam parameteren internt af systemet. For at opnå det korrekte resultat, når du tester værdien af ​​wParam, skal en applikation kombinere værdien 0xFFF0 med værdien wParam ved hjælp af bitwise AND-operatøren.



Spørgsmålet er, skal jeg undgå $FFF0 masken eller er der en mere korrekt måde?

Bedste reference


Dokumentationen er korrekt, hvorfor din kode stopper med at arbejde , når du tester bitvis og med $ FFF0 er den konstante du definerer ikke god.


const
  ALWAYS\_ON\_TOP\_ID = 1000;


1000 i hexadecimal er 3E8, den hexadecimale ciffer med laveste orden skal være 0 for de laveste fire bits at være 0. IOW, binær 1111 er hexadecimal F, så du skal forlade det sidste ciffer til systemet.


Indstil din konstant i hexadecimal, så du ikke vil begå en fejl. Pas på at holde dig fri af SC\_... området (som er $ F000 ... $ F ###) når du definerer din konstant.


const
  ALWAYS\_ON\_TOP\_ID = $100; {256}


så nu kan du sikkert teste


  if Msg.CmdType and $FFF0 = ALWAYS\_ON\_TOP\_ID then
    ...