cs_Loda
Messages postés814Date d'inscriptionvendredi 3 novembre 2000StatutMembreDernière intervention30 juillet 2009
-
23 mai 2007 à 15:50
cs_Loda
Messages postés814Date d'inscriptionvendredi 3 novembre 2000StatutMembreDernière intervention30 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));
// 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.
cs_Loda
Messages postés814Date d'inscriptionvendredi 3 novembre 2000StatutMembreDernière intervention30 juillet 20093 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.
japee
Messages postés1727Date d'inscriptionvendredi 27 décembre 2002StatutModérateurDernière intervention 6 novembre 20218 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;