Avatar billede athlon-pascal Juniormester
01. november 2003 - 15:52 Der er 2 kommentarer og
2 løsninger

PopupMenu der popper "opad" (bogstavligt)

Jeg har en TSpeedButton (sbtnStatus) og en TPopupMenu (pmStatus) med nogle MenuItems.

I sbtnStatus' OnClick-event har jeg følgende kode:
procedure TForm1.sbtnStatusClick(Sender: TObject);
var
  PopupPos: TPoint;
begin
  PopupPos := sbtnStatus.ClientToScreen(Point(sbtnStatus.Left, sbtnStatus.Top + sbtnStatus.Height));
  pmStatus.Popup(PopupPos.X, PopupPos.Y);
end;

Det virker fint, Popup-menuen popper op når man kliker på sbtnStatus. Den kommer frem nedenfor sbtnStatus, den popper altså "nedad".

Nu vil jeg gerne have den til at poppe "opad", så den kommer ovenfor sbtnStatus.
Jeg vil prøve at "tegne" hvad jeg mener:
______________
|    Item1              |
|    Item2              |
|    Item3              |
|_____________|___
|      sbtnStatus        |
|________________|

Hvordan gør man det?

Jeg ved det er muligt, for IM-programmet Miranda IM (www.miranda-im.org), der er et Win32-opensource-program skrevet i C, har den funktion i sin statusbar (også når man gør Miranda IM's vindue lille, og flytter det op i toppen af skærmen, så det er ingen forklaring)...

Jeg bruger Delphi 7 Personal under Windows XP.

På forhånd tak :-)
Avatar billede stoney Nybegynder
01. november 2003 - 23:28 #1
Hvis jeg har forstået dig korrekt burde følgende virke (med 3 items i popup)

procedure TForm1.sbtnStatusClick(Sender: TObject);

begin

  pmstatus.Popup(form1.Left + sbtnstatus.Left + 3,form1.Top + sbtnstatus.top - (pmstatus.Items.Count * 12 - 2));
end;

Du må selv finde den "rigtige formel" med flere items i popup ( altså (pmstatus.Items.Count * 12 - 2));

Stoney
Avatar billede athlon-pascal Juniormester
01. november 2003 - 23:37 #2
Problemet er bare, at man ikke kan finde højden på hverken de enkelte menuitems eller menuen :-(

Og dit forslag med at regne sig frem og gå ud fra en fast menuitem-højde holder ikke, da koden ikke nødvendigvis kun skal bruges på min computer...
Og jeg går altså ind for, at programmer skal se ordentlige ud uanset hvilket theme (med mindre det er en fejl i det enkelte theme) og hvilken font den enkelte bruger har valgt...
Avatar billede stoney Nybegynder
01. november 2003 - 23:49 #3
kan du ikke bare checke hvilken hvilken font/størrelse brugeren
måtte have på sin maskine ?

Stoney
Avatar billede athlon-pascal Juniormester
02. november 2003 - 22:25 #4
Jeg har nu fundet en løsning via Windows API, der gør det jeg vil, på http://www.delphi3000.com/articles/article_3647.asp
Da artiklen ikke bare kan læses, men kræver at man registrerer sig (selv da kan man kun læse op til 50 gratis artikler), er her den kode jeg er nået frem til:

type
  TForm1 = class(TForm)
    sbtnStatus: TSpeedButton;
    procedure sbtnStatusClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  protected
    procedure WMCommand(var Msg: TWMCommand); message WM_COMMAND;
  public
    pmStatus: TPopUpMenu;
  end;

const
  WM_STATUSOFFLINE = WM_USER + 101;
  WM_STATUSONLINE = WM_USER + 102;

implementation

{$R *.dfm}

procedure TForm1.WMCommand(var Msg: TWMCommand);
begin
  case Msg.ItemID of
    WM_STATUSOFFLINE:
      sbtnStatus.Caption := 'Offline';
    WM_STATUSONLINE:
      sbtnStatus.Caption := 'Online';
  end;

  inherited;
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  IndlaegRec: TIndlaegNoteRec;
begin
  pmStatus := TPopUpMenu.Create(Self);

  pmStatus.AutoPopup  := FALSE;
  pmStatus.AutoHotkeys := maManual;

  AppendMenu(pmStatus.Handle, MF_STRING or MF_UNCHECKED, WM_STATUSOFFLINE, '&Offline');
  AppendMenu(pmStatus.Handle, MF_STRING or MF_UNCHECKED, WM_STATUSONLINE, '&Online');
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  pmStatus.Free;
end;

procedure TForm1.sbtnStatusClick(Sender: TObject);
var
  Msg : LongBool;
  PopupPos: TPoint;
begin
  PopupPos := sbtnStatus.ClientToScreen(Point(sbtnStatus.Left, sbtnStatus.Top));
  Msg := TrackPopupMenuEx(pmStatus.Handle, TPM_LEFTALIGN or TPM_LEFTBUTTON or TPM_BOTTOMALIGN or TPM_RETURNCMD, PopupPos.X, PopupPos.Y, Handle, nil);
  if Msg then
    SendMessage(Handle, WM_COMMAND, Integer(Msg), 0);
end;
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester