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+
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.