Home | Chi sono | Contattami
 

Progr. lineare

Delphi
 
Componenti
  Database
 
Miei articoli

Windows

Miei articoli 

 

Creare una Pulsantiera Multischermo


Questo programma consiste in una piccola Form nell' angolo in basso a destra dello schermo, proprio sopra la traybar, che contiene 5 pulsanti. All' inizio il primo pulsante è abbassato; successivamente quando premo un altro bottone, viene aperto un nuovo desktop senza finestre di applicazioni aperte. In questo nuovo desktop posso aprire altri programmi e così via per gli altri bottoni. Quando torno su uno dei bottoni, vedrò solo le applicazioni aperte in quel contesto senza le altre.

1. Fondamenta

Il trucco consiste nei seguenti passaggi prima di premere un altro bottone

1) Ottieni gli handles di tutte le finestre visibili (ad eccezione del Desktop, della Taskbar e della applicazione stessa)
2) Nascondere tutte le finestre individuate al passo 1).

Dopo aver premuto il bottone dobbiamo visualizzare tutte le finestre i cui handles erano stati ottenuti nel momento in cui avevamo lasciato il bottone per premerne un altro. Naturalmente se un bottone è premuto per la prima volta non abbiamo handles e quindi avremo un desktop pulito

2. Implementazione

Abbiamo detto che vogliamo ottenere gli handles di tutte le finestre visibili: la chiave è una chiamata alla funzione win32 EnumWindows passando come parametro una funzione di callback chiamata ad esempio “EnumWindowsProc”. Vediamo nel seguito la definizione dell'API EnumWindows

2.1 EnumWindows

L'API win32 EnumWindows enumera tutte le finestre top-level sullo schermo. La funzione prende in input una funzione di callback alla quale passa di volta in volta l'handle della finestra top-level corrente. La funzione va avanti fino all'ultima finestra top-level ma il ciclo si può interrompere se la funzione di callback restituisce False.

type TFNWndProc = function EnumWindowsProc(hWnd: Cardinal; //handle della finestra top-level corrente lParam: Integer //valore lParam della EnumWindows ): Boolean; function EnumWindows(lpEnumFunc: TFNWndEnumProc; lParam: Integer ): Boolean; stdcall;

Andremo ad eseguire

EnumWindows(@EnumWindowsProc, 0);

La funzione EnumWindows cicla su tutte le finestre (visibili o invisibili): per ogni finestra viene effettuata una chiamata alla funzione di callback EnumWindowsProc che deve appunto essere implementata.

2.2 Implementazione della funzione di callback EnumWindowsProc

Una possibile implementazione della funzione EnumWindowsProc può consistere nell' inserimento dei vari handle in una lista. In relazione all' obiettivo che vogliamo raggiungere dobbiamo inserire nella lista gli handle delle seguenti finestre

1) Finestre visibili

IsWindowVisible(hwnd) = True

2) Non la finestra dell' applicazione che stiamo creando

var processed: DWORD; ... GetWindowThreadProcessID( hwnd, @processID ); ... processID <> GetCurrentProcessID

3) Non la finestra della Taskbar

hWnd <> FindWindow('Shell_TrayWnd', Nil)

4) Non la finestra del Desktop

hWnd <> FindWindow('Progman', Nil)

 

3. Codice

unit ProcessView; interface uses Windows, Dialogs, SysUtils, Classes, ShellAPI, TLHelp32, Forms; var HandleList: TStringList; function EnumWindowsProc(hWnd: HWND; lParam: LPARAM): Bool; stdcall; procedure GetProcessList; implementation procedure GetProcessList; var i: integer; begin HandleList.Clear; EnumWindows(@EnumWindowsProc, 0); end; function EnumWindowsProc(hWnd: HWND; lParam: LPARAM): Bool; var processID : DWORD; begin GetWindowThreadProcessID( hwnd, @processID ); if processID <> GetCurrentProcessID then if (hWnd <> FindWindow('Shell_TrayWnd', Nil)) and (hWnd <> FindWindow('Progman', Nil)) then if IsWindowVisible(hwnd) then begin HandleList.Add(IntToStr(HWnd)); Result:=true; end; end; initialization HandleList:=TStringList.Create; finalization HandleList.Free; end. //Nel programma principale useremo una variabile denominata Monitors di tipo “array of TStringList” //la cui dimensione è data dal numero dei bottoni (monitor disponibili) per tenere in memoria //tutti gli handles associati ad ogni bottone. Un' altra variabile denominata CurrentMonitor //memorizza l' indice del monitor attuale. Questo è il codice: unit Unit1; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, ProcessView, StdCtrls, Buttons, Menus, ImgList, AppEvnts; type TForm1 = class(TForm) //these are the buttons (1..5) to switch from a monitor to another /// SpeedButton1: TSpeedButton; SpeedButton2: TSpeedButton; SpeedButton3: TSpeedButton; SpeedButton4: TSpeedButton; SpeedButton5: TSpeedButton; /////////////////////////////////////////////////////////////////////// procedure SpeedButton1Click(Sender: TObject); procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); procedure FormShow(Sender: TObject); procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean); procedure CloseApplicationClick(Sender: TObject); //click on CloseApplication (TMenuItem) private { Private declarations } Monitors: array[1..5] of TStringList; CurrentMonitor: integer; public { Public declarations } end; var Form1: TForm1; implementation {$R *.DFM} //Evento OnClick di tutti i pulsanti procedure TForm1.SpeedButton1Click(Sender: TObject); var i: integer; Rect: TRect; begin // GetProcessList; Monitors[CurrentMonitor].Assign(HandleList); for i := 0 to HandleList.Count - 1 do begin ShowWindow(StrToInt(HandleList.Strings[i]), SW_HIDE); end; CurrentMonitor := StrToInt((Sender as TSpeedButton).Caption); for i := 0 to Monitors[CurrentMonitor].Count - 1 do begin ShowWindow(StrToInt(Monitors[CurrentMonitor].Strings[i]), SW_SHOW); end; end; procedure TForm1.FormCreate(Sender: TObject); var i: integer; begin CurrentMonitor:=1; for i := Low(Monitors) to High(Monitors) do Monitors[i] := TStringList.Create; end; procedure TForm1.FormDestroy(Sender: TObject); var i: integer; begin // for i := Low(Monitors) to High(Monitors) do Monitors[i].Free; end; procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); var i, j: integer; begin for i := Low(Monitors) to High(Monitors) do begin for j := 0 to Monitors[i].Count - 1 do begin ShowWindow(StrToInt(Monitors[i].Strings[j]), SW_SHOW); end; end; end; procedure TForm1.FormShow(Sender: TObject); begin // Height := 61; Width := 173; Top := Screen.Height - Height - 30; Left := Screen.Width - Width; end;

4. Per finire

A completare il programma intervengono le seguenti caratteristiche:

1) Icona nella traybar
2) Non si può eseguire il programma più volte contemporaneamente
3) Non c'è il pulsante nella Taskbar

MultiScreenEmulator
 

 
 
Your Ad Here