Avatar billede hugopedersen Nybegynder
12. juni 2011 - 18:17 Der er 12 kommentarer og
1 løsning

Delphi form on top of alting

Kan man tvinge en Delphi form til at være on top af alting - og jeg mener alting :-)
Det er en passwordform jeg bruger til at afkræve et password for at få lov at starte applikationen. Men det skal være sådan at når programmet er startet og formen vises, så skal den være on top af alle andre ting der måtte være startet.
Avatar billede kroning Nybegynder
12. juni 2011 - 18:31 #1
Sæt FormStyle til fsStayOnTop
Avatar billede hugopedersen Nybegynder
12. juni 2011 - 18:37 #2
Beklager - det gør det ikke.
Avatar billede kroning Nybegynder
12. juni 2011 - 18:42 #3
Mystisk, på min Windows 7 virker det. Bruger Delphi 7
Avatar billede hrc Mester
12. juni 2011 - 19:19 #4
Hvad med dette her (fundet på nettet - ser ud til at virke)?

//StayOnTop mode
SetWindowPos(handle, hwnd_TopMost,0,0,0,0, swp_NoMove or swp_NoSize)

.. den normale ser vistnok sådan ud:

//Normal Mode
SetWindowPos(handle, hwnd_NoTopMost,0,0,0,0, swp_NoMove or swp_NoSize);
12. juni 2011 - 22:01 #5
HJ HP,

Havde selv det problem for nogen projecter siden.

Løste det ved at i MAIN-formen (efter alle de andre forme var indlæst) kaldte MAIN-formen en en psvHTMLdialog boks (som egentlig er en Twebbrowser i større eller mindre forklædning. HTML-koden var/er standard HTML-kode men du loader et loader et Javascript ind sammen ved kaldet fra Delphi. Hvis du DISABLE'R venstre muse-knap i PSV-**-boksen er den praktisk taget "U_kode-læsbar" (dvs. koden kan ikke vises ). Gør det sammen med den indlæste jS. Alternativet er, at du "bare lader" psv-**-boksen være simpel INPUT-boks (lidt a al: MessageDialog (bortset fra at du kan pynte din egen boks efter eget hoved") og lader Delphi klare fortolkningen af dine input..., så kan du slippe for al meget sikkerhed.


Husker ikke præcist hvordan jeg løste det - det er mange måneder siden. Men det kan lade sig gøre - ved jeg (af egen erfaring..)

KRistian
Avatar billede hugopedersen Nybegynder
13. juni 2011 - 10:51 #6
Desværre HRC så sætter det kun boksen til at være on top af selve applikationen - ikke til at være on top af alt.

Jeg er ude efter det samme som man kan med taskmanager hvis der er valgt 'Always on top'
Avatar billede hrc Mester
13. juni 2011 - 23:00 #7
I mit testprogram virker det. Mainformen er aldeles øverst, ligesom processoversigten plejer at være det. På ære! Jeg har placeret denne ene linje i mainformens OnCreate:

SetWindowPos(handle, hwnd_TopMost,0,0,0,0, swp_NoMove or swp_NoSize)

Er du sikker på du har fjernet dine egne forsøg på at få den øverst? Har du prøvet med et helt "rent" projekt?

Jeg kører Windows 7 uden themes. Mon det spiller ind?
Avatar billede js_delphi Nybegynder
14. juni 2011 - 04:11 #8
Hej,

jeg har i et program to forme, som ALTID skal vaere "on top", men kun i min applikation.
De normale tiltag som f.eks. StayOnTop osv. virkede OK, lige indtil der blev trykket ALT+TAB i Windows, hvis ikke andre programmer var aabne.
I dette tilfaelde forsvandt mine forme, indtil man "kaldte" dem igen ved foerst at kalde Form.Close og derefter Form.Show!

Ved at soege paa nettet fandt jeg ud af, at det angiveligt var (er) et Windows problem (det med, at de forsvinder ved ALT+TAB), som kunne loeses ved at kalde denne kode i OnActivate i de to forme:

SetWindowPos(Self.Handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE or SWP_NOMOVE or SWP_NOSIZE);

Det virker efter min hensigt (at holde formene "on top", men kun i min applikation) i 99.9% af tiden.
Pludselig ligger disse to forme dog ovenpaa ALT i Windows (det, som du gerne vil opnaa).

Jeg har ikke kunnet finde noget system i, hvornaar det virker, og hvornaar ikke, og jeg har egentlig besluttet mig til ikke at spilde mere tid paa denne "detalje".

For mig er det en bug i Windows eller Delphi, som af og til minder mig om, at en Windows maskine skal genstartes af og til :-(

Mit program koerer ioevrigt paa 5-10 forskellige computere, som alle koerer Windows XP. Om alle disse arbejdsstationer har problemet, kan jeg ikke sige. 

Bruger selv Delphi 2006 og Windows XP.

Jeg foelger spaendt denne traad...
Avatar billede hugopedersen Nybegynder
14. juni 2011 - 09:24 #9
I min dpr fil har jeg

if TfrmPassword.Execute('Password') then
  begin
    Application.Initialize;
    Application.BringToFront;
    Application.CreateForm(TfrmHamlist, frmHamlist);
    Application.Run;
  end
else
  begin
    Application.MessageBox('You are not authorized to use the application.', 'Password Protected Delphi application');
  end;

I TfrmPassword har jeg
class function TfrmPassword.Execute(aCode: string; const aHeader: string = ''): boolean;
begin
  with TfrmPassword.Create(Application, aCode, aHeader) do
  try
    Result := ShowModal = mrOk;
  finally
    Free;
  end;
end;

constructor TfrmPassword.Create(aOwner: TComponent; aCode: string; aHeader: string);
begin
  Inherited Create(aOwner);
  SetWindowPos(Handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE);
  fCode := aCode;
  txtResult.Text := '';
  if aHeader <> '' then
    Caption := aHeader
  else
    Caption := SMsgPassword;
end;

Hvis jeg ændrer lidt i DPR filen så TfrmHamlist er vist når jeg kalder password formen, så er den on top af TfrmHamlist men jeg kan stadig trykke på et program i baggrunden og få det til at svinge til forgrunden.
Avatar billede hrc Mester
14. juni 2011 - 10:19 #10
Hvorfor gøre det så besværligt? Bare kald login-formen fra main-formen og send en PostQuitMessage hvis det er forkert. Hvis du vil have tegnet mainformen i baggrunden, så kan jeg også vise hvordan:

const
  WM_LATEUPDATE = WM_USER + $01;

procedure FormLateUpdate(var aMessage: TMessage); message WM_LATEUPDATE;

procedure TfrmMain.FormLateUpdate(var aMessage: TMessage);
begin
  with TfrmLogin.Create(self) do
    try
      if ShowModal = mrOK then
      begin
        // login OK
      end
      else
        PostQuitMessage(1);
    finally
      Release;
    end;
  end;
end;

procedure TfrmMain.FormCreate(Sender: TObject);
begin
  ...
  Application.ProcessMessages;
  PostMessage(self.Handle,WM_KINGOLATEUPDATE,0,0);
end;

Jeg vil i øvrigt mene at Application.initialize skal op før login-formen.
Avatar billede hugopedersen Nybegynder
14. juni 2011 - 13:28 #11
PostQuitMessage(1) er det samme nummer som custommessagen får?
Jeg har flere custommessages i mit projekt nemlig. (vil jeg ikke bare kunne skrive WM_LATEUPDATE)

Men hvor om alting er, så ser det ud til at jeg kan styre det på din måde HRC.

Har rodet med Application.Initialize men kunne ikke se nogen umiddelbar forskel.
Avatar billede hrc Mester
14. juni 2011 - 13:50 #12
Du vælger bare et nummer. Det skal bare være WM_USER + et eller andet unikt i forhold til dit program.

Application.Initialize går gennem alle units initialization sektioner og det er ret minimalt hvad der er der.
Avatar billede hugopedersen Nybegynder
14. juni 2011 - 19:07 #13
Fik det til at fungere fornuftig ved hjælp af HRC's input
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