Form MostTop lors RunTime [Résolu]

Messages postés
900
Date d'inscription
vendredi 3 novembre 2000
Statut
Membre
Dernière intervention
30 juillet 2009
- - Dernière réponse : cs_Loda
Messages postés
900
Date d'inscription
vendredi 3 novembre 2000
Statut
Membre
Dernière intervention
30 juillet 2009
- 24 mai 2007 à 10:48
Salut tout le monde!

je cherche à faire une form Most On Top. cad une fenêtre qui reste audessus des autres applications.

mais je voudrais pouvoir changer ceci au RunTime. (le but est de laisser que certain fenêtre visible lorsque je reduit l'application)

<hr size= "2" width="100%" />Note: Je sais le faire pour une fenêtre que je crée et qui ne change pas.
procedure TfrmMostOnTop.CreateParams(var Params: TCreateParams);
begin
  inherited;
  Params.ExStyle := Params.ExStyle or WS_EX_APPWINDOW or WS_EX_TOPMOST;
  Params.WndParent := GetDesktopWindow;
end;
pas de blem. ça marche bien.
<hr size="2" width="100%" />
mais si je fait un truc similaire au runtime, j'ai des problèmes:
- je ne peux pas clicker sur ma fiche !! (bouton, memo, ...)
- la bar de titre (caption bar) ne s'active pas
- Je ne voit pas la fenêtre lorsque je la déplace.

<hr size ="2" width="100%" />
mon code:
procedure TfrmOdaBase.SetMostOnTop(const Value: boolean);
const
  FLAG_MOSTTOP = WS_EX_TOPMOST or WS_EX_APPWINDOW;
begin

  if value = fMostOnTop then exit;
  fMostOnTop := Value;

  Parent := nil;
  //Delphi doc:
  // Setting ParentWindow has no effect if Parent is not nil

  if value then begin

   // task bar button:
   ParentWindow := GetDesktopwindow;

    FormStyle := fsStayOnTop;
    //MostOnTop win MUST be StayOnTop

    // set flag
    SetWindowLong(
      Handle,
      GWL_EXSTYLE,
      (GetWindowLong(Handle,GWL_EXSTYLE) or FLAG_MOSTTOP));

  end else begin

//    ParentWindow := fOrgParentWindowHWD;
    ParentWindow := 0;

    FormStyle := fsNormal;

    // UNset flag
   SetWindowLong(
      Handle,
      GWL_EXSTYLE,
      (GetWindowLong(Handle,GWL_EXSTYLE) and not (FLAG_MOSTTOP)));

  end;

  {msdn doc:
  If you have changed certain window data using SetWindowLong,
  you must call SetWindowPos to have the changes take effect.
  Use the following combination for uFlags:
  SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED.

  this combinaison of flags, allow to not change the WinPOS.

  Note: if you use SWP_NOZORDER, the windows does not "get visible".
  }

  SetWindowPos (Handle, 0,0 ,0 ,0 ,0,
    SWP_NOMOVE OR SWP_NOSIZE OR SWP_FRAMECHANGED);//}

end;

j'ai aussi essayer avec SetWindowPos(handle, HWND_TOPMOST, ...). Même genre de problème.
<hr size="2" width="100%" />
Avez-vous le même comportement sur votre machine?

je m'y prend comme un pied ou quoi?

Une idée sur le "pourquoi du comment" ?

une solution altérnative? parceque moi je commence à me dire que c'est pas possible...

Loda

PS: je sais que ce n'est pas recommandé de changer le form style au runtime, mais bon.

<hr size="2" width="100%" />Se poser les bonnes questions est le premier pas pour trouver les bonnes réponses.
Afficher la suite 

4 réponses

Messages postés
900
Date d'inscription
vendredi 3 novembre 2000
Statut
Membre
Dernière intervention
30 juillet 2009
3
0
Merci
précision:

- je ne peux pas clicker sur ma fiche !! (bouton, memo, ...)
en fait, je ne peux pas cliquer sur les compo qui prenne le focus. Mais les trucs genre TSpeedButton, c'est OK.
Commenter la réponse de cs_Loda
Messages postés
1709
Date d'inscription
vendredi 27 décembre 2002
Statut
Modérateur
Dernière intervention
15 novembre 2019
1
0
Merci
Salut Loda,

J'ai pas trop le temps de tester ton code, mais voici une fonction perso faisant appel à l'api qui me donne toute satisfaction, et sans problème au runtime :

procedure SetOnTop(const OnTop: Boolean = True);
const
  TabHwndInsertAfter: array[Boolean] of HWND = (HWND_NOTOPMOST, HWND_TOPMOST);
begin
  SetWindowPos(Application.Handle,
               TabHwndInsertAfter[OnTop],
               0, 0, 0, 0,
               SWP_NOACTIVATE or SWP_NOMOVE or SWP_NOSIZE);
end;

qu'on peut tester avec un TCheckBox ainsi :

procedure TForm1.cbOnTopClick(Sender: TObject);
begin
  SetOnTop(cbOnTop.Checked);
end;

En espérant que ça résoud ton problème,

A +
Commenter la réponse de japee
Messages postés
900
Date d'inscription
vendredi 3 novembre 2000
Statut
Membre
Dernière intervention
30 juillet 2009
3
0
Merci
salut Japee,

j'avais essayé qqch du genre, sans grand résultat. D'abord, c'est pour l'applic et je cherche qqch pour une form...

ensuite, si je passe le handle d'une form, cela ne marche pas. Le parentWindow doit être le bureau pour que cela marche bien.

merci quand même,

Loda
<hr size="2" width="100%" />Se poser les bonnes questions est le premier pas pour trouver les bonnes réponses.
Commenter la réponse de cs_Loda
Messages postés
900
Date d'inscription
vendredi 3 novembre 2000
Statut
Membre
Dernière intervention
30 juillet 2009
3
0
Merci
je crois que j'ai mis la main sur une solution. je la finit et je la posterais.

A+
Commenter la réponse de cs_Loda