Form MostTop lors RunTime

Résolu
cs_Loda Messages postés 814 Date d'inscription vendredi 3 novembre 2000 Statut Membre Dernière intervention 30 juillet 2009 - 23 mai 2007 à 15:50
cs_Loda Messages postés 814 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.

4 réponses

cs_Loda Messages postés 814 Date d'inscription vendredi 3 novembre 2000 Statut Membre Dernière intervention 30 juillet 2009 3
23 mai 2007 à 16:26
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.
0
japee Messages postés 1727 Date d'inscription vendredi 27 décembre 2002 Statut Modérateur Dernière intervention 6 novembre 2021 8
23 mai 2007 à 17:27
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 +
0
cs_Loda Messages postés 814 Date d'inscription vendredi 3 novembre 2000 Statut Membre Dernière intervention 30 juillet 2009 3
24 mai 2007 à 09:04
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.
0
cs_Loda Messages postés 814 Date d'inscription vendredi 3 novembre 2000 Statut Membre Dernière intervention 30 juillet 2009 3
24 mai 2007 à 10:48
je crois que j'ai mis la main sur une solution. je la finit et je la posterais.

A+
0
Rejoignez-nous