Bonjour,
Je cherche l'API ou le méthode pour maintenir une application sur le bureau, à la façon d'un widget.
Pas au dessus des autres, simplement ancré sur le bureau, même si l'on clique sur l'icone "Bureau".
Une idée ?
Merci
Bonjour,
Je cherche l'API ou le méthode pour maintenir une application sur le bureau, à la façon d'un widget.
Pas au dessus des autres, simplement ancré sur le bureau, même si l'on clique sur l'icone "Bureau".
Une idée ?
Merci
jouer avec StayOnTop, forcer le bringtofront lors du OnDeactivate de l'application, ...
le Ondeactivate ne convient pas car je ne souhaite pas avoir une application toujours activé, mais plutot en tache de fond sur le bureauEnvoyé par ShaiLeTroll
Quand on clique sur l'icone bureua on ne passe pas dans l'evenement onMinimize de l'application.
Le bureau semble se redessiner par dessus les applications sans leur demander de se minimizer
Je n'ai jamais dit qu'elle serait active !!!
tu confonds BringToFront et SetFocus ... as-tu essayé de voir si le bureau provoquait on moins le passage dans Application.OnDeactivate ...
Sinon, j'ai fait un petit programme qui affiche un Hint au dessus de l'heure, et lorsque clique sur l'icone du bureau, le message reste affiché (c'est pas un hint mais une Form contenant un HTMLMemo de TMS), bon en fait la fiche est en fsStayOnTop, je fais ceci pour afficher ma fenêtre, ce qui fait que cela s'affiche sans garder le focus ...
et comme c'était un programme sans icone dans la barre des taches, je pense qu'il y a un impact lié à ce code
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 FGWHandle := GetForegroundWindow(); try FormStyle := fsStayOnTop; Show(); finally SetForegroundWindow(FGWHandle); end;
J'essaye de me battre pour comprendre, mais l'affectation de fsStayOnTop dans le OnCreate semble bien forcé, mais on y arrive à le faire céder à un moment ... mais doit y avoir une API ...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 SetWindowLong (Application.Handle, GWL_EXSTYLE, GetWindowLong (Application.Handle, GWL_EXSTYLE) or WS_EX_TOOLWINDOW and not WS_EX_APPWINDOW);
EDIT : Hum, tant que la fiche ne recoit JAMAIS le focus, et bien, elle reste quoi qu'il arrive, donc si tu veux faire un truc qui s'affiche tout le temps, en mettant Enabled à False (cela limitera ton programme à un strict affichage), eh ben, cela semble fonctionner ...
on passe bien dans le Ondeactivate avec le "bureau"
Malheureusement pas qu'avec lui :/
Je ne souhaite pas etre en fsStayOnTop et c'est bien tout le soucis..bref je patauge sur ce coup là
Essaye cette combinaison (il faut faire un petit exe séparé du reste de ton projet ...)
Cela laisse la dernière fenêtre active comme active, et la fenêtre reste en permanence affiché ... en tout cas cela donne bien chez moi ... c'est le seul moyen que j'ai trouvé,
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14 FGWHandle := GetForegroundWindow(); try SetWindowLong (Application.Handle, GWL_EXSTYLE, GetWindowLong (Application.Handle, GWL_EXSTYLE) or WS_EX_TOOLWINDOW and not WS_EX_APPWINDOW); TheForm := T...Form.Create(Application); TheForm.FormStyle := fsStayOnTop; // mieux vaut une affectation ici et laisser Normal dans l'IDE TheForm.Enabled := False; TheForm.BorderStyle := bsNone; TheForm.Show(); finally SetForegroundWindow(FGWHandle); end;
Le code fonctionne, mais je dois vraiment très mal me faire comprendre
Je ne souhaite pas créer une fenetre inactive au premier plan, je voudrais qu'elle passe derrière les autres, qu'elle soit comme intégrée au bureau, mais indéboulonnable de là.
Honte, ... j'ai lu "Par dessus des autres" au lieu de "Pas au dessus des autres", un peu à la façon de Post-it®*© ... hum ...
Désolé, oui rien à voir ...,
Effectivement, un truc sympa ..., j'aurais tendance à dire qu'il faut soit même dessiner sur le bureau ... gérer cela SANS form ...
tient, je viens tenter cela, bon le soucis c'est que le dessin ne reste pas, il va falloir sur choper un event quand le bureau doit se rafraichir ...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 procedure TFrmWindowsRegions.BtnDrawOnDesktopClick(Sender: TObject); var hDesktopWindow: HWND; hDesktopWindowDC: HDC; hSolidBrush: HBRUSH; begin // GetDesktopWindow() fourni le Handle du Bureau // GetWindowDC(...) si tu lui fourni le Handle du Bureau, tu obtiens une sorte de Canvas pour dessiner dessus // DrawFrameControl(...) tu lui fourni ton Canvas, et ça devrait simuler le dessin d'une fenêtre ... // ReleaseDC(...) Comme d'habitude, on laisse la place propre ... hDesktopWindow := GetDesktopWindow(); hDesktopWindowDC := GetWindowDC(HDesktopWindow); if hDesktopWindowDC > 0 then begin hSolidBrush := CreateSolidBrush($00FF0000); FrameRect (hDesktopWindowDC, Rect(0, 0, 100, 100), hSolidBrush); DeleteObject(hSolidBrush); DrawFrameControl(hDesktopWindowDC, Rect(10, 10, 90, 90), DFC_BUTTON, 0); ReleaseDC(hDesktopWindow, hDesktopWindowDC); end; end;
salut
je serait toi ,je pencherai pour une solution a partir du creatparams
@+ Phil
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 procedure TSnowFlakeForm.CreateParams(var Params: TCreateParams); begin inherited CreateParams(Params);// jusque la c'est simple ;) with Params do begin WndParent := GetDesktopWindow; // ici on affact le fenetre parent Style := Style AND NOT WS_CAPTION; // pas de caption a ton appli ExStyle := ExStyle or WS_EX_TOOLWINDOW OR WS_EX_TRANSPARENT; //pas de bouton dans la taskbar et transparent ExStyle := ExStyle or WS_EX_TOPMOST ;// Toujours au desus des autres // dans ton cas tu n'en a pas besoin c'est valable pour les screensaver end; end;
Est-ce que la surchage du CreateParams serait plus efficace que ceci ?
J'ai tenté, cela donne un effet intéressant ... en tout cas, c'est une bonne idée ... mais lorsque tu clicque sur l'icone du bureau, la fenêtre se réduit comme les autres ...
Code : Sélectionner tout - Visualiser dans une fenêtre à part Windows.SetParent(Handle, GetDesktopWindow());
c'est surtout la transparence qui joue pour l'effet incrusté dans le bureau, ... ce WS_EX_TOPMOST fonctionne mieux que StayOnTop, ...
salut
a priorie cela devrai faire a peu de chose pres la meme chose
si j'ai bien compris il affect uniquement le handle du parent
par contre j'ai pas tester il doit y avoir d'autre otion a ajouter comme
l'inposibilite de retailler la fenetre ou de la minimizer et autre joyeuseté
@+ Phil
Je remonte un peu le sujet
En fait je ne trouve pas de solution "propre".
Il semble qu'il ni est pas de paramètres qui permettent de faire ça à la création de la Form (rien trouvé du coté de .CreateParams ).
Lorsque l'on clique sur l'icone bureau (ToggleDesktop) les applications ne semblent pas être minimisées, c'est le bureau qui est redessiné devant, donc impossible de récupérer l'information sur l'application elle-même.
Reste deux pistes:
1 -Faire un Hook et "trapper" l'utilisation de ToggleDesktop, cette idée est exclue car il faut une dll complémentaire et trop lourde par rapport au besoin.
2 - Trouver comment dire a Windows de redessinner l'application avec le bureau. Cela doit bien exister les Widgets Yahoo le font si on les configures pour.
Merci pour vos idées
salut
as tu essayé de creer ta fenetre uniquement avec les api windows ?
@+ Phil
SAlut
pfff je fait n'importe quoi avec mes fenetre ... enfin bref
Ca fait 15 edit que je fait sur ce message ...
Alors voila en fait il semblerai que Windows supprime de notre champs de vision les fenetre en les envoyant en (-32000,-32000), j'ai decouvert ca avec WinInspector
Je suis en train de regarder pour intercepter le message WM_WINDOWPOSCHANGING cause de tout ceci (c'est un appele a SetWindowPos) le probleme c'est que le "afficher Bureau" ne doit pas etre le seul a y fair appelle.
Voila un bout de code avec ca tu declenche sur l'evenement WindowPosChanging
Et voila les valeur pour les flags
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33 unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) private { Déclarations privées } //WM_WINDOWPOSCHANGING procedure ZapWindow(var msg : TWMWindowPosChanging); message WM_WINDOWPOSCHANGING; public { Déclarations publiques } end; var Form1: TForm1; implementation {$R *.dfm} Procedure TForm1.ZapWindow(var msg : TWMWindowPosChanging); Var ParamMess : PWindowPos; begin inherited; ParamMess := msg.WindowPos; //tous les parametre transmit a SetWindowPos se retrouve dans ParamMess ;) end; End.
Par contre j'ai du faire une erreur d'interpretation pour le -32000, je le retrouve pas dans les appéls, humm j'ai du ratter un Swp_NoMove... pourtant ...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 SWP_ASYNCWINDOWPOS =16384 SWP_DEFERERASE =8192 SWP_DRAWFRAME =32 SWP_FRAMECHANGED =32 SWP_HIDEWINDOW =128 SWP_NOACTIVATE =16 SWP_NOCOPYBITS =256 SWP_NOMOVE =2 SWP_NOOWNERZORDER =512 SWP_NOREDRAW =8 SWP_NOREPOSITION =512 SWP_NOSENDCHANGING =1024 SWP_NOSIZE =1 SWP_NOZORDER =4 SWP_SHOWWINDOW =64 HWND_BOTTOM =1 HWND_NOTOPMOST =4294967294 HWND_TOP =0 HWND_TOPMOST =4294967295
J'ai retrouvé le Log, je le met ici, c uniquement la partie pour afficher le bureau.
Window messages created by Winspector
WM_WINDOWPOSCHANGING
hwnd: 0x0006046c
hwndInsertAfter: 0x00020506
Position: -32000, -32000
Size: 160, 24
SWP_NOACTIVATE | SWP_FRAMECHANGED | SWP_SHOWWINDOW | SWP_NOCOPYBITS
Message Sent
Time: 22:22:11.0437
WM_GETMINMAXINFO
Maximixed size: 1286, 1030
Maximixed position: -3, -3
Minimum tracking size: 112, 27
Maximum tracking size: 1292, 1036
Message Sent
Time: 22:22:11.0437
WM_GETMINMAXINFO Return value
Maximised size: 1286, 1030
Maximised position: -3, -3
Minimum tracking size: 112, 27
Maximum tracking size: 1292, 1036
Continue processing: False
Message Sent
Time: 22:22:11.0437
WM_WINDOWPOSCHANGING Return value
Continue processing: False
Message Sent
Time: 22:22:11.0437
WM_NCCALCSIZE
Indicate client area: True
Proposed area: -32000, -32000, -31840, -31976
Previous area: 22, 22, 502, 331
Client area: 25, 63, 499, 328
hwnd: 0x0006046c
hwndInsertAfter: 0x00020506
Position: -32000, -32000
Size: 160, 24
SWP_NOACTIVATE | SWP_FRAMECHANGED | SWP_NOCOPYBITS
Message Sent
Time: 22:22:11.0437
WM_NCCALCSIZE Return value
Continue processing: False
Message Sent
Time: 22:22:11.0437
WM_WINDOWPOSCHANGED
hwnd: 0x0006046c
hwndInsertAfter: 0x00020506
Position: -32000, -32000
Size: 160, 24
SWP_NOACTIVATE | SWP_FRAMECHANGED | SWP_NOCOPYBITS
Message Sent
Time: 22:22:11.0437
WM_MOVE
xPos: 33536
yPos: 33536
Message Sent
Time: 22:22:11.0437
WM_MOVE Return value
Return: 0x00000000
Message Sent
Time: 22:22:11.0437
WM_SIZE
Style: SIZE_MINIMIZED
Width: 0
Height: 0
Message Sent
Time: 22:22:11.0437
WM_WINDOWPOSCHANGING
hwnd: 0x0006046c
hwndInsertAfter: HWND_TOP
Position: 0, 0
Size: 160, 289
SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE
Message Sent
Time: 22:22:11.0437
WM_GETMINMAXINFO
Maximixed size: 1286, 1030
Maximixed position: -3, -3
Minimum tracking size: 112, 27
Maximum tracking size: 1292, 1036
Message Sent
Time: 22:22:11.0437
WM_GETMINMAXINFO Return value
Maximised size: 1286, 1030
Maximised position: -3, -3
Minimum tracking size: 112, 27
Maximum tracking size: 1292, 1036
Continue processing: False
Message Sent
Time: 22:22:11.0437
WM_WINDOWPOSCHANGING Return value
Continue processing: False
Message Sent
Time: 22:22:11.0437
WM_SIZE Return value
Return: 0x00000000
Message Sent
Time: 22:22:11.0437
WM_WINDOWPOSCHANGED Return value
Continue processing: False
Message Sent
Time: 22:22:11.0437
SWP_FRAMECHANGED -> ceci explique pourquoi on a pas d'action au niveau de la fenetre du moins pas de OnRepaint
SWP_NOACTIVATE -> pas de OnActivate non plus
SWP_SHOWWINDOW -> pas de OnHide
SWP_NOCOPYBITS ->pas de restauration de la zone Client
A++
Qwaz
RE
C'est encore plus compliqué et plus simple a la fois.
J'ai pas encore la finalité exact mais ca jou avec le message
Les fenetres prennent la "couleur" du fond comme si tout devenait transparent.
Code : Sélectionner tout - Visualiser dans une fenêtre à part procedure EraseBck(Var msg : TWMERASEBKGND);
Voila les messages recu par le DeskTop
Window messages created by Winspector
WM_PAINT
wParam: 0x00000000
lParam: 0x00000000
Message Posted
Time: 23:28:33.0968
WM_NCPAINT
Update region handle: 0xf2041430
Message Sent
Time: 23:28:33.0968
WM_NCPAINT Return value
Processed: False
Message Sent
Time: 23:28:33.0968
WM_ERASEBKGND
HDC: 0x01010053
Message Sent
Time: 23:28:33.0968
LVM_GETBKCOLOR
wParam: 0x00000000
lParam: 0x00000000
Message Sent
Time: 23:28:33.0968
LVM_GETBKCOLOR Return value
Background colour: none
Message Sent
Time: 23:28:33.0968
WM_ERASEBKGND Return value
Processed: True
Message Sent
Time: 23:28:33.0968
LVM_GETBKCOLOR
wParam: 0x00000000
lParam: 0x00000000
Message Sent
Time: 23:28:33.0968
LVM_GETBKCOLOR Return value
Background colour: none
Message Sent
Time: 23:28:33.0968
WM_NCPAINT
Draw entire frame: true
Message Sent
Time: 23:28:33.0968
WM_NCPAINT Return value
Processed: False
Message Sent
Time: 23:28:33.0968
Edit: Bouais j'ai essayer d'intercepter chacun des messages present mais la fenetre ne les recoie jamais au moment du Afficher Bureau, uniquement au moment de faire revenir la fenetre.
Désolé d'avoir pourri ton post /Edit
Edit2: Un dernier teste
Ca "marche" mais qu'un seul fois au 2eme appele de Affiche Bureau ca ne marche plus .. peut etre une piste. /edit2
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11 procedure TForm1.Timer1Timer(Sender: TObject); begin //If Form1.Left < 0 Then //begin // form1.Left := 0; //marche pas // form1.top := 0; //end; setwindowpos(self.Handle,hwnd_top,0,0,400,400,swp_showwindow+SWP_DRAWFRAME); end;
edit3:
C'est quand meme bizard par ce que si tu fait ca
la fenetre reste toujours au dessus meme avec affiche Bureau
Code : Sélectionner tout - Visualiser dans une fenêtre à part setwindowpos(self.Handle,hwnd_topMost,0,0,400,400,SWP_NOOWNERZORDER + SWP_NOACTIVATE+swp_showwindow+SWP_DRAWFRAME);
J'ai essayer de metre la fenetre juste au dessus du bureau en mettant son handle a la place de hwnd_topmost mais ca ne foctionne pas. /edit3
++
salut
a mon avis y'a que deux message a redefinir
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 WM_SETTINGCHANGE : begin if(wParam = SPI_SETWORKAREA) then UpdatePosition(Self.handle); end; ... WM_DISPLAYCHANGE: begin AreaWidth := GetDeviceCaps(screendc, HORZRES); AreaHeight := GetDeviceCaps(screendc, VERTRES); end; ... // un exemple de positionnement selon la barre de tache Procedure ... UpdatePosition(aHwnd : HWND ); var gl_rect : Trect; begin GetWindowRect(FindWindow('Shell_TrayWnd', 0),gl_rect); if(gl_rect.left <= 0) then begin if(gl_rect.top <= 0) then begin if(gl_rect.right = AreaWidth + 2) then // EN HAUT SetWindowPos(aHwnd,0,AreaWidth - (self.whidth),gl_rect.bottom,self.whidth,self.heigth, 0) else // A GAUCHE SetWindowPos(aHwnd, 0, gl_rect.right, AreaHeight - self.heigth,self.width,self.heigth, 0); end else // EN BAS SetWindowPos(aHwnd, 0, AreaWidth - (self.Width),gl_rect.top - self.Heigth,self.Width,self.Heigth, 0); end else // A DROITE SetWindowPos(aHwnd, 0, gl_rect.left - self.Width,AreaHeight - self.Heigth,self.Width,self.Heigth, 0); end;
Petit up de la question, car toujours pas trouvé
Pas que ce soit vital, mais bon
Merci à tous
Même avec un Timer, tu n'arrive pas forcer un Minimize puis un Maximize ?
Etrangement j'arrive a la sisser sur le bureau en "topMost", à la condition de la retirer de la barre des taches
Dans le Onshow de la form
Et moi je cherche la même chose mais en NOTOPMOSTShowWindow(Application.Handle, SW_HIDE);
SetWindowPos(self.Handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE or SWP_NOMOVE );
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager