Newsgroup: it.comp.programmare.win32
Titolo: ShowWindow su Vista

Salve,
sapreste indicarmi una API come ShowWindow che però consenta di
nascondere la finestra dell'applicazione anche su Windows Vista?
L'istruzione ShowWindow(hInstance, SW_HIDE);
Funziona bene su XP ma non su Vista...
Grazie

No...@email.it
 wrote in news:7ab25f16-87f3-4be9-953f-
876667...@i24g2000prf.googlegroups.com
:

ShowWindow prende come parametro l'handle di una finestra, non un 
hInstance.
Ho applicazioni che usano questa API per nascondere la finestra 
principale e non ho avuto problemi su Vista.
-- 
Valter Minute
(the reply address of this message is invalid)
(l'indirizzo di reply di questo messaggio non è valido)

 hInstance.
Si, quello era una porzione di codice che ho preso da internet.
Nella mia applicazione passo l'handle della finestra ed infatti su Xp
funziona bene, ma su Vista rimane minimizzata sulla tray bar
Ciao

L'istruzione che uso io è:
ShowWindow(FindWindow("ConsoleWindowClass", NULL), SW_HIDE);

 ShowWindow(FindWindow("ConsoleWindowClass", NULL), SW_HIDE);
Se il processo a cui vuoi mandare il messaggio di SW_HIDE gira con un 
integrity level superiore a quello del processo che spedisce il 
messaggio, questo verrà filtrato da "UIPI" (user interface privilege 
isolation.
UIPI è un sistema per evitare "luring attack" ossia attacchi di 
elevazioni di privilegio che impediscono di pilotare una applicazione 
che ha più privilegi.
Gli integrity level sono un meccanismo per cui il sistema operativo 
impedisce l'accesso:
- in lettura e scrittura verso processi di livello più alto
- in scrittura (ma non lettura) verso oggetti di livello più alto
Per oggetti si intende oggetti kernel, quindi file, registry, thread, 
mutex, etc.
Di default un processo ha:
- integrity level medium se lanciato da un utente
- integrity level high se lanciato da un amministratore (token elevato)
Se spieghi meglio lo scenario, vediamo che si può fare ...
-- 
Raffaele Rialdi
Microsoft .NET MVP 
http://mvp.support.microsoft.com
 -
http://italy.mvps.org
 UGIdotNET - User Group Italiano .NET
http://www.ugidotnet.org
 Weblog: 
http://blogs.ugidotnet.org/raffaele

Salve,
non capisco perché non funzioni questo semplice codice.
Creo un nuovo progetto, metto un button sulla form e scrivo:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
    ShowWindow(FindWindow("Form1", "Form1"), SW_HIDE);
}
Infatti sia il nome della classe che la caption del form č Form1.
Al click perň la finestra non si nasconde.
Saluti 

 Se spieghi meglio lo scenario, vediamo che si può fare ...
In pratica, ho notato che su vista le applicazioni che fanno uso della 
prompt di dos vengono eseguite qualche secondo dopo l'avvio del programma.
Infatti usando ShowWindowAsync sono riuscito a risolvere il problema.
Adesso però volevo applicarlo al C++ Builder ma non riesco a capire perché 
non funzioni.
Saluti 

 Form1.
Il nome della classe è TForm1, non Form1.
-- 
Stefano Frosio
www.esse-effe.com

 Il nome della classe è TForm1, non Form1.
Ma quello non è il tipo?
Comunque ho provato:
ShowWindow(FindWindow("TForm1", "Form1"), SW_HIDE);
ma rimane ridotta a icona sulla barra delle applicazioni 

 ma rimane ridotta a icona sulla barra delle applicazioni
Tu hai chiesto come mai non funzionasse la ShowWindow, non come 
togliere l'applicazione dalla taskbar. Per quello devi fare:
ShowWindow(Application->Handle, SW_HIDE);
E' comunque possibile che ricompaia in certe situazioni, quindi, 
se serve, devi monitorare alcuni eventi come il ripristino della 
finestra.
HTH,
-- 
Stefano Frosio
www.esse-effe.com

 ShowWindow(Application->Handle, SW_HIDE);
Ma unitamente all'altra a quanto pare infatti:
ShowWindowAsync(FindWindow("TForm1", NULL), SW_HIDE);
ShowWindow(Application->Handle, SW_HIDE);
Fa quello che chiedo, se metto solo la seconda non accade niente.
Ciao 

 non funzioni.
Nel senso che chiami la ShowWindowAsync ma non ti funziona? Non conosco 
C++ Builder ma non vedo perché ci dovrebbero essere differenze.


 C++ Builder ma non vedo perché ci dovrebbero essere differenze.
Si, ma in questo modo funziona:
ShowWindowAsync(FindWindow("TForm1", NULL), SW_HIDE);
ShowWindow(Application->Handle, SW_HIDE);
Ovvero chiamandole entrambe (purtroppo io ho XP e per testarlo su vista devo 
inviare il programma a casa di un mio amico quindi non so se anche nella 
seconda funzione vada invocata la versione con Async, ma credo di si).
Ciao

 si).
Sto facendo delle prove e non funziona nuovamente...
Addirittura ho spostato le istruzioni nel click di un button e ancora prima 
di cliccare l'applicazione si riduce sulla barra delle applicazioni (quindi 
parte senza richiesta ed oltre tutto fa un'altra cosa).
C++ Builder 3 è l'ambiente più scadente che abbia mai usato, meno male che 
mi è costato 25 mila lire a suo tempo. 

 non cambia molto)
Aspetta il compilatore/linguaggio non importano.
Il subsystem (Console o Win32) dipende dal linker.
In VC++ l'impostazione è nella configurazione progetto - linker - 
System "SubSystem"
Linkando da riga di comando l'opzione è /SUBSYSTEM:CONSOLE o 
/SUBSYSTEM:WINDOWS


 parte senza richiesta ed oltre tutto fa un'altra cosa).
Hai provato con l'API GetConsoleWindow() ?  (restituisce un HWND)
Le API per la gestione delle Console sono queste:
http://msdn.microsoft.com/en-us/library/ms682073(VS.85).aspx


 Hai provato con l'API GetConsoleWindow() ?  (restituisce un HWND)
Questa istruzione non compila:
ShowWindowAsync(GetConsoleWindow(), SW_HIDE);
Errore:
[C++Error] Prova.cpp(10): Call to undefined function 'GetConsoleWindow'.
Ho incluso windows.h come richiesto 

Vorrei che l'applicazione all'avvio si nascondesse e rimanesse in esecuzione 
un ciclo infinito. Attualmente ho provato cosi ma non si nasconde, 
probabilmente perché il metodo Button1Click non viene eseguito in maniera 
completa, a causa del ciclo.
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
     Application->OnActivate = Button1Click;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
        ShowWindowAsync(FindWindow("TForm1", NULL), SW_HIDE);
        ShowWindowAsync(Application->Handle, SW_HIDE);
         while (true) {
            // Altre istruzioni, che comunque non sono presenti in questo 
programma di prova
             Sleep(100);
    };
}
Il form rimane visible e il pulsante non viene disegnato completamente...
C'è un modo per far partire il ciclo dopo che le varie operazioni di 
inizializzazione siano state terminate? 


MSDN dice: "define _WIN32_WINNT as 0x0500 or later"
L'hai fatto prima della windows.h?


 L'hai fatto prima della windows.h?
Ho messo:
#define _WIN32_WINNT 0x0500;
Mi dice:
[C++Warning] Prova.cpp(14): Redefinition of '_WIN32_WINNT' is not identical.
Se lo metto prima dei vari #include mi si apre un file (winbase.h) e segna 
errore a questa riga:
#if(_WIN32_WINNT >= 0x0400) // Riga 112 di winbase.h
[C++Error] winbase.h(112): ) expected. 

 [C++Error] winbase.h(112): ) expected.
Se lo metti prima di ogni altra cosa non dovrebbe darti questo errore.
Le possibilità sono:
- potrebbe essere definito nelle proprietà del progetto (compilatore)
- se usi 
vs.net
 mettilo in cima a stdafx.h
Potresti usare #undef ma rischi che ci siano incongruenze tra i .h 
compilati con un valore ed un altro.
Mi sembra ricordare che in 
vs.net
 2005/2008 la _WIN32_WINNT è già 
definita di default sopra 0x500. Suppongo tu stia usando una versione 
precedente. Corretto?


Noixe ha scritto:

togli il ; finale
#define _WIN32_WINNT 0x0500
ciao

 #define _WIN32_WINNT 0x0500
Si, quello va tolto, ma la funzione non viene trovata lo stesso.
Comunque mi interessa di puù riuscire a far nascondere il programma e 
lasciarlo in esecuzione col ciclo infinito 

Noixe ha scritto:

Dovresti specificare un po' meglio la situazione.
Non ho capito se usi una applicazione win ed una console assieme oppure 
l'una o l'altra.
Poi quel FindWindow() mi lascia un po' perplesso, devi nascondere 
un'altra applicazione non creata da te?
Nel caso fossi tu a creare la/le appl, la cosa più semplice è creare una 
app win e se non deve interagire con l'utente (ma se dovessi chiuderla?) 
non creare alcuna finestra o, al limite, crearla senza lo stile WS_VISIBLE.
es. senza finestra
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR 
lpCmdLine, int nCmdShow)
{
   while(true) {
     // il tuo codice
     }
   return EXIT_SUCCESS;
}
Il builder non lo conosco, ma dovrebbe comunque esserci una impostazione 
di visibilità del form (se intendi usare la vcl), chessò:
Form1.Visible = false;
o qualcosa del genere.
ciao

 operazioni di inizializzazione siano state terminate?
Usa un thread parallelo.


 o qualcosa del genere.
Si c'è l'ho provata a settare false ma rimane tutto visibile (a prescindere 
dal ciclo etc...) 

 che hai postato.
In che senso, è semplice.
Cerco un modo per mantenere il ciclo ma solo dopo che il Button sia stato 
disegnato (credo sia questo che non consenta di nascondere la form) 

 di nascondere la form)
No, non è quello. Comunque ti consiglio di usare un thread 
parallelo, come già detto.
-- 
Stefano Frosio
www.esse-effe.com

Noixe ha scritto:

E' sbagliato il principio, comunque...
per metterci una pezza, attiva un timer e fai eseguire il tuo ciclo 
infinito al verificarsi dell'evento.
Nel tuo codice resta visibile perché, nel ciclo infinito, non rilasci il 
controllo all'os e quindi la tua applicazione non risponde più agli eventi.
Ciao

 compare nessuna finestra.
Si, l'ho modificata adesso e in effetti l'applicazione si nasconde, ma 
stranamente, non crea il file di testo che dovrebbe creare (e che viene 
creato non appena commento l'istruzione ShowMainForm...) 

 l'istruzione ShowMainForm...)
Non penso sia strano. Dove hai inserito la creazione del file?
-- 
Stefano Frosio
www.esse-effe.com

 Non penso sia strano. Dove hai inserito la creazione del file?
All'inizio del metodo Button1Click, prima di entrare nel ciclo while.
Ma il punto è che se non setto ShowMainForm a false, il programma funziona 
correttamente. 

 Hai provato con l'API GetConsoleWindow() ?  (restituisce un HWND)
Ora, a parte il nascondere la mia applicazione, mi servirebbe poter 
nascondere una serie di finestre di prompt di dos che vengono eseguite con 
system:
system ("dir C:\ > mydir.txt");
ShowWindow(Cosa_metto_qui?, SW_HIDE);
Oppure sai indicarmi qualche altra soluzione che non si basi sulla chiamata 
di ShowWindow? 

 programma funziona correttamente.
Perchè in quel caso il form principale si attiva. Tira via tutto 
e metti il tuo "ciclo" nel costruttore del form (o addirittuna 
in WinMain a questo punto). Il pulsante non serve a nulla. 
Comunque, come ti ho già detto due volte, la soluzione ideale è 
l'utilizzo di un thread parallelo.
-- 
Stefano Frosio
www.esse-effe.com

 di un thread parallelo.
Non ho esperienza con la programmazione dei thread.
Ciao 

 di ShowWindow?
Intanto devi aprire la command creando il processo. In questo modo 
ottieni l'handle al processo che è utile per sapere quando questo 
termina e l'eventuale hwnd:
- Usa ShellExecuteEx e crea il processo con cmd.exe passando come 
command line /K "dir c:\ > mydir.txt"
- Guarda se hwnd di ShellExecuteInfo contiene l'hwnd alla console
- se si, usalo per nasconderla
- se no, chiami EnumWindows e nella callback chiami ogni volta 
GetWindowThreadProcessId. Se l'id del processo corrisponde a quello 
della ShellExecute, hai HWND giusto.
Se vuoi provare la command line, apri una cmd e prova:
start cmd /k "dir c:\ > mydir.txt"


 start cmd /k "dir c:\ > mydir.txt"
Questo per creare in processo invece di usare ShellExecuteEx? 

 Questo per creare in processo invece di usare ShellExecuteEx?
digita quella stringa dentro una command prompt.
start apre una nuova finestra di cmd.exe. In pratica crei un processo 
proprio come fa ShellExecuteEx
digita start /? per l'help


 proprio come fa ShellExecuteEx
Si, conosco start, ma non sapevo che con /k il la finestra rimaneva aperta 
(per consentire di catturare l'handle direi).
Ciao