Orgdot : arrangeur de fenêtres windows

Description

Mon code est issu d'un constat : les fonctions Mosaïque ... de la barre de tâche ne permettent pas de positionner plus de 2 fenêtres, ni même d'avoir de arrangements fonctionnels dans de pareils cas.

En gros, il récupère la main sur les fenêtres (programmes) actives, puis les redispose sur l'écran selon une config présélectionnée.

Quelques petits details en plus permettent de "démarrer" des programmes directement dans une configuration de fenêtres, de garder l'exécutable dans la zone de notification, ou d'organiser les fenêtres depuis l'icône en notification.

Source / Exemple :


unit SysTrayWIN;

{

Org (dot) Application for automatic-organizing of Windows running applications windows. Developped with Delphi 2.0 Description: If you need to set running applications' windows with a preset windows arrangement Org (dot) might be a usefull solution. It monitors visible applications and take a handle on them. Version: 2.0 Platform: Windows 95 and upper Author: Lionel Tailhardat E-Mail: toolbox@2Ears.net Home Page: www.2Ears.net Created: February 20 2006 Modified: July 23 2007 Comments: French comments. Legal: Copyright (c) 2006-2007, Lionel Tailhardat
NOTE: 1). It is an 'as-is' software 2). Take respect to the author's work
} interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, Buttons, ShellApi; type TSysTrayFORM = class(TForm) BackPanel: TPanel; ModesBEVEL: TBevel; ReduceBTN: TBitBtn; Org1: TBitBtn; Org2: TBitBtn; Org3: TBitBtn; Org4: TBitBtn; Org5: TBitBtn; Org6: TBitBtn; CloseBTN: TBitBtn; MinimizeBTN: TBitBtn; HelpBTN: TBitBtn; AppNameLBL: TLabel; procedure AfficherCacher(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); procedure FormCreate(Sender: TObject); procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); procedure Org1Click(Sender: TObject); procedure Org2Click(Sender: TObject); procedure Org3Click(Sender: TObject); procedure Org4Click(Sender: TObject); procedure Org5Click(Sender: TObject); procedure Org6Click(Sender: TObject); procedure ReduceBTNClick(Sender: TObject); procedure MinimizeBTNClick(Sender: TObject); procedure HelpBTNClick(Sender: TObject); procedure CloseBTNClick(Sender: TObject); procedure FormShow(Sender: TObject); private { Déclarations privées } public { Déclarations publiques } end; type TSetDatas = record Name : String; Arrange : Integer; Win1 : String; Win2 : String; Win3 : String; Win4 : String; end; var SysTrayFORM : TSysTrayFORM; ActualMode : Integer; StartShow : boolean; hWNDNum : Array [1..4] of hWnd; WndCount : Integer; createHided : boolean; implementation uses Systray, About; {$R *.DFM} // ============================================================================= function LstWnd(Handle: hWnd; Info: lParam) : Boolean; stdcall; var WndName : array[0..255] of char; WndInfo : array[0..255] of char; WndStyle : LongInt; IsAWindow : boolean; begin // Référence les applications actives Result :=True; IsAWindow := (Handle <> 0) and (GetWindow(Handle, GW_OWNER) = 0) and (Application.Handle <> Handle) and IsWindowVisible(Handle); WndStyle := GetWindowLong(Handle, GWL_STYLE); if IsAWindow then begin if WndStyle and WS_POPUP = WS_POPUP then IsAWindow := (WndStyle and WS_GROUP = WS_GROUP) and (WndStyle and WS_SYSMENU = WS_SYSMENU) and not (WndStyle and WS_DISABLED = WS_DISABLED) else IsAWindow := True; end; if IsAWindow then begin GetWindowText(Handle, WndName, 255); if WndName = 'Org .' then Exit; Inc(WndCount); hWndNum[WndCount] := Handle; end; if WndCount = 4 then Result := False; end; procedure hWndFind; begin // Détecte une application active WndCount := 0; EnumWindows(@LstWnd,0); end; procedure Organize; var FuncRtn : hDwp; WndNum : integer; X : array[1..4] of integer; Y : array[1..4] of integer; cX : array[1..4] of integer; cY : array[1..4] of integer; Error : integer; sHeight : integer; sWidth : integer; begin // Agence les fenêtres actives hWndFind; sHeight := Screen.Height; sWidth := Screen.Width; Case ActualMode of 1 : WndNum := 2; 2 : WndNum := 2; 3 : WndNum := 3; 4 : WndNum := 4; 5 : WndNum := 3; 6 : WndNum := 4; end; FuncRtn := BeginDeferWindowPos(WndNum); if FuncRtn = Null then begin Error := Application.MessageBox('Ressources matérielles insuffisantes pour développer la commande', 'Org . - Erreur', MB_Ok); Exit; end; Case ActualMode of 1 : begin X[1] := 0; Y[1] := 0; cX[1]:= sWidth; cY[1]:= (sHeight div 2); X[2] := 0; Y[2] := (sHeight div 2); cX[2]:= sWidth; cY[2]:= (sHeight div 2); end; 2 : begin X[1] := 0; Y[1] := 0; cX[1]:= (sWidth div 2); cY[1]:= sHeight; X[2] := (sWidth div 2); Y[2] := 0; cX[2]:= (sWidth div 2); cY[2]:= sHeight; end; 3 : begin X[1] := 0; Y[1] := 0; cX[1]:= (sWidth div 2); cY[1]:= sHeight; X[2] := (sWidth div 2); Y[2] := 0; cX[2]:= (sWidth div 2); cY[2]:= (sHeight div 2); X[3] := (sWidth div 2); Y[3] := (sHeight div 2); cX[3]:= (sWidth div 2); cY[3]:= (sHeight div 2); end; 4 : begin X[1] := 0; Y[1] := 0; cX[1]:= (sWidth div 2); cY[1]:= sHeight; X[2] := (sWidth div 2); Y[2] := 0; cX[2]:= (sWidth div 2); cY[2]:= (sHeight div 3); X[3] := (sWidth div 2); Y[3] := (sHeight div 3); cX[3]:= (sWidth div 2); cY[3]:= (sHeight div 3); X[4] := (sWidth div 2); Y[4] := (2 * (sHeight div 3)); cX[4]:= (sWidth div 2); cY[4]:= (sHeight div 3); end; 5 : begin X[1] := 0; Y[1] := 0; cX[1]:= (sWidth div 2); cY[1]:= (sHeight div 2); X[2] := (sWidth div 2); Y[2] := 0; cX[2]:= (sWidth div 2); cY[2]:= (sHeight div 2); X[3] := 0; Y[3] := (sHeight div 2); cX[3]:= sWidth; cY[3]:= (sHeight div 2); end; 6 : begin X[1] := 0; Y[1] := 0; cX[1]:= (sWidth div 2); cY[1]:= (sHeight div 2); X[2] := (sWidth div 2); Y[2] := 0; cX[2]:= (sWidth div 2); cY[2]:= (sHeight div 2); X[3] := (sWidth div 2); Y[3] := (sHeight div 2); cX[3]:= (sWidth div 2); cY[3]:= (sHeight div 2); X[4] := 0; Y[4] := (sHeight div 2); cX[4]:= (sWidth div 2); cY[4]:= (sHeight div 2); end; end; DeferWindowPos (FuncRtn, hWndNum[1], HWND_TOP, X[1], Y[1], cX[1], cY[1], SWP_SHOWWINDOW); DeferWindowPos (FuncRtn, hWndNum[2], hWndNum[1], X[2], Y[2], cX[2], cY[2], SWP_SHOWWINDOW); if WndNum > 2 then DeferWindowPos (FuncRtn, hWndNum[3], hWndNum[2], X[3], Y[3], cX[3], cY[3], SWP_SHOWWINDOW); if WndNum > 3 then DeferWindowPos (FuncRtn, hWndNum[4], hWndNum[3], X[4], Y[4], cX[4], cY[4], SWP_SHOWWINDOW); EndDeferWindowPos(FuncRtn); // Retour de la main avec OrgDot en avant-plan... Application.BringToFront; end; procedure OrgCaptionOff; begin // RàZ des affichages des boutons d'organisation SysTrayFORM.Org1.Caption :=''; SysTrayFORM.Org2.Caption :=''; SysTrayFORM.Org3.Caption :=''; SysTrayFORM.Org4.Caption :=''; SysTrayFORM.Org5.Caption :=''; SysTrayFORM.Org6.Caption :=''; end; procedure OrgCaptionSet(OrgBTN: integer); begin case OrgBTN of 1 : SysTrayFORM.Org1.Caption := '* * *'; 2 : SysTrayFORM.Org2.Caption := '* * *'; 3 : SysTrayFORM.Org3.Caption := '* * *'; 4 : SysTrayFORM.Org4.Caption := '* * *'; 5 : SysTrayFORM.Org5.Caption := '* * *'; 6 : SysTrayFORM.Org6.Caption := '* * *'; end; end; procedure OrgUse(Sender: TObject); begin // Déclenchement de l'organisation OrgCaptionOff; ActualMode := (Sender as TBitBtn).Tag; (Sender as TBitBtn).Caption := '* * *'; Organize; ModifIconeTray('Org . [' + IntToStr(ActualMode) + '] (Click-G: Organise !, Click-D: Menu)', Application.Icon.Handle); end; // ============================================================================= procedure TSysTrayFORM.AfficherCacher(Sender: TObject); begin // Gestion de l'affichage de la fenêtre Visible := not Visible; if Visible = true then Application.BringToFront; end; procedure TSysTrayFORM.FormClose(Sender: TObject; var Action: TCloseAction); begin // Gestion de l'icône su Systray à la fermeture EnleveIconeTray(); end; procedure TSysTrayFORM.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); var Pos: TPoint; begin // Gestion de la souris sur le Systray GetCursorPos(Pos); Case X of //WM_LBUTTONDBLCLK:; WM_LBUTTONDOWN: Organize; //WM_LBUTTONUP:; //WM_RBUTTONDBLCLK:; WM_RBUTTONDOWN: AfficherCacher(Sender); //WM_RBUTTONUP:; end; end; // ============================================================================= procedure TSysTrayFORM.ReduceBTNClick(Sender: TObject); begin // Commandes de "tout réduire" Keybd_event(VK_LWIN,0,0,0); // Simule l'appui de la touche Windows Keybd_event(VKKeyScan('m'),0,0,0); // Simule l'appui sur la touche M Keybd_event(VK_LWIN,0,KEYEVENTF_KEYUP,0); // Simule le relâchement de la touche Windows Keybd_event(VKKeyScan('m'),0,KEYEVENTF_KEYUP,0); // Simule le relâchement de la touche M end; procedure TSysTrayFORM.FormShow(Sender: TObject); begin // Masque l'application de la barre des tâches ShowWindow(Application.Handle, SW_HIDE); end; procedure TSysTrayFORM.FormCreate(Sender: TObject); var i, o : integer; TaskBarHandle : HWnd; { Handle to the Win95 Taskbar } TaskBarCoord : TRect; { Coordinates of the Win95 Taskbar } CxScreen : integer; { Screen Width } STop, SLeft : integer; { On Create Org. position } begin // Mise en place de l'application { Sets the initial coordinates of the Org. window on its startup } TaskBarHandle := FindWindow('Shell_TrayWnd',Nil); { Get Win95 Taskbar = handle } if TaskBarHandle = 0 then begin { We're running Win 3.x or WinNT w/o Win95 = shell, so just maximize } STop := 10; { Usefull coordinates } SLeft := 10; end else begin { We're running Win95 or WinNT w/Win95 shell } GetWindowRect(TaskBarHandle,TaskBarCoord); { Get coordinates of Win95 = Taskbar } STop := TaskBarCoord.Top - 210; { Usual coordinates / Usual TaskBar coordinates } SLeft := TaskBarCoord.Right - 145; CxScreen := GetSystemMetrics(SM_CXSCREEN); if (TaskBarCoord.Top = 0) and (TaskBarCoord.Left = 0) then { = Taskbar on either top or left } if TaskBarCoord.Right > TaskBarCoord.Bottom then { Taskbar on top } STop := TaskBarCoord.Bottom + 5 else begin { Taskbar on left } STop := TaskBarCoord.Bottom - 210; SLeft := TaskBarCoord.Right + 5; end; if (TaskBarCoord.Top = 0) and (TaskBarCoord.Left <> 0) then begin { = Taskbar on right } STop := TaskBarCoord.Bottom - 210; SLeft := TaskBarCoord.Left - 145; end; end; SysTrayFORM.Top := STop ; SysTrayFORM.Left := SLeft; ActualMode := 1; SysTrayFORM.Org1.Caption :='* * *'; AjouteIconeTray(SysTrayFORM.handle, Application.Icon.Handle, 'Org . [1] (Click-G: Organise !, Click-D: Menu)'); end; procedure TSysTrayFORM.MinimizeBTNClick(Sender: TObject); begin // Déclenchement du masquage de l'application par le Minimize AfficherCacher(Sender); end; procedure TSysTrayFORM.HelpBTNClick(Sender: TObject); begin // Déclenchement de l'aide AboutFORM.ShowModal; end; procedure TSysTrayFORM.CloseBTNClick(Sender: TObject); begin // Déclenchement de l'arrêt de l'application SysTrayFORM.Close; end; // ============================================================================= procedure TSysTrayFORM.Org1Click(Sender: TObject); begin // Organisation par un schéma OrgUse(Sender); end; procedure TSysTrayFORM.Org2Click(Sender: TObject); begin // Organisation par un schéma OrgUse(Sender); end; procedure TSysTrayFORM.Org3Click(Sender: TObject); begin // Organisation par un schéma OrgUse(Sender); end; procedure TSysTrayFORM.Org4Click(Sender: TObject); begin // Organisation par un schéma OrgUse(Sender); end; procedure TSysTrayFORM.Org5Click(Sender: TObject); begin // Organisation par un schéma OrgUse(Sender); end; procedure TSysTrayFORM.Org6Click(Sender: TObject); begin // Organisation par un schéma OrgUse(Sender); end; end.

Conclusion :


Il arrive, comme ennui, que les fenêtres ne passent pas en mode 'Restauré', ce qui oblige l'utilisateur à cliquer 2 fois sur le bouton 'Agrandir' pour maximiser la fenêtre qu'il désire.

Un truc sympa qui découle de cette programmation est que l'on peut exécuter plusieurs programmes et que seuls ceux dont la fenêtre est active sont réorganisés; d'où une manip. intéressante qui peut se faire au final en jonglant entre la fonction 'Tout réduire' (incluse) et l'arrangement.

Sinon, je n'ai pas prévu de mises à jour.

Merci à fabiin et son code 11879 sur Delphi.fr pour la mise en notification, Borland CodeCentral m'a aussi permit d'avancer.

A+

Codes Sources

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.