/**=============================================================================
Mostra come ho implementato il passaggio dalla visualizzazione nella classica
finestra ridimensionabile di Win32 (WS_OVERLAPPEDWINDOW) a quella a schermo
pieno (WS_POPUP) impiegando le funzioni GetWindowLong() e SetWindowLong() con
GWL_STYLE.
=============================================================================**/
#include <windows.h>
const char *kStrNomeClasseProg = "schermopienoenon_class";
const char *kStrTitoloFP = "Schermo pieno e non";
DWORD kStileInizFP = WS_OVERLAPPEDWINDOW; // volendo, provare anche con WS_POPUP
BOOL kFPHaMenu = FALSE;
const INT kWInizFP = 480;
const INT kHInizFP = 360;
HINSTANCE gHInst = NULL;
LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wPar, LPARAM lPar );
BOOL RegistraClasse();
BOOL CreaFinestraPrincipale( HWND *hwnd, INT mostra );
int Errore( int codice, HWND parent );
int WINAPI WinMain( HINSTANCE hInst, HINSTANCE hPInst, LPSTR cmdLn, int show ) {
HWND hwnd = NULL;
MSG msg = {0};
gHInst = hInst;
if( !RegistraClasse() )
return Errore( 1, NULL );
if( !CreaFinestraPrincipale(&hwnd,show) )
return Errore( 2, NULL );
MessageBox( hwnd,
"Premi \"S\" per la finestra a schermo pieno. \n"
"Premi \"F\" per la finestra standard di Windows. ",
kStrTitoloFP, MB_ICONINFORMATION );
while( GetMessage(&msg,NULL,0,0) > 0 ) {
TranslateMessage( &msg );
DispatchMessage( &msg );
}
return 0;
}
/*==============================================================================
Con questa funzione la finestra hwnd viene impostata a schermo pieno in stile
WS_POPUP oppure nella visualizzazione "classica" in stile WS_OVERLAPPEDWINDOW.
E' preferibile che lo stile della finestra al lancio del programma sia
WS_OVERLAPPEDWINDOW. In caso contrario, la finestra "classica" verra' collocata
alle coordinate 10,10, con dimensioni 480x360 (window rect, non client rect!).
Il parametro popup sia TRUE per passare alla visualizzazione a schermo pieno,
FALSE per passare alla visualizzazione "classica".
==============================================================================*/
void CambiaStileFinestra( HWND hwnd, BOOL popup ) {
// static, per conservare il rect precedente della finestra "classica"
static RECT gRFin = { 10, 10, 10+kWInizFP, 10+kHInizFP };
DWORD stile = GetWindowLong( hwnd, GWL_STYLE );
RECT r;
if( popup ) {
if( !(stile&WS_OVERLAPPEDWINDOW) ) {
return; // lo stile e' gia' quello richiesto
}
else {
LONG ws = GetSystemMetrics(SM_CXSCREEN);
LONG hs = GetSystemMetrics(SM_CYSCREEN);
GetWindowRect( hwnd, &gRFin ); // conserva il rect corrente
stile = (stile&(~WS_OVERLAPPEDWINDOW)) | WS_POPUP;
SetRect( &r, 0, 0, ws, hs );
AdjustWindowRect( &r, stile, FALSE );
OffsetRect( &r, (ws-(r.right-r.left))/2, (hs-(r.bottom-r.top))/2 );
}
}
else {
if( (stile&WS_OVERLAPPEDWINDOW) ) {
return; // lo stile e' gia' quello richiesto
}
else {
CopyRect( &r, &gRFin ); // recupera il rect precedente
stile = (stile&(~WS_POPUP)) | WS_OVERLAPPEDWINDOW;
}
}
SetWindowLong( hwnd, GWL_STYLE, stile );
MoveWindow( hwnd, r.left, r.top, r.right-r.left, r.bottom-r.top, TRUE );
}
LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wPar, LPARAM lPar ) {
switch( msg ) {
case WM_KEYDOWN:
if( wPar=='S' || wPar=='F' )
CambiaStileFinestra( hwnd, wPar=='S' );
else if( wPar == VK_ESCAPE )
SendMessage( hwnd, WM_CLOSE, 0, 0 );
break;
case WM_CLOSE:
PostQuitMessage( 0 );
break;
default:
return DefWindowProc( hwnd, msg, wPar, lPar );
}
return 0;
}
BOOL RegistraClasse() {
WNDCLASS wc = {0};
wc.lpfnWndProc = WndProc;
wc.hInstance = gHInst;
wc.hCursor = LoadCursor( NULL, IDC_ARROW );
wc.hbrBackground = (HBRUSH)(COLOR_BACKGROUND);
wc.lpszClassName = kStrNomeClasseProg;
return RegisterClass( &wc ) != 0;
}
BOOL CreaFinestraPrincipale( HWND *hwnd, int mostra ) {
LONG ws = GetSystemMetrics(SM_CXSCREEN);
LONG hs = GetSystemMetrics(SM_CYSCREEN);
BOOL popup = kStileInizFP == WS_POPUP;
HWND hwndTmp = NULL;
RECT rFin;
LONG margine;
if( popup )
SetRect( &rFin, 0, 0, ws, hs );
else SetRect( &rFin, 0, 0, kWInizFP, kHInizFP );
if( FALSE == AdjustWindowRect(&rFin,kStileInizFP,kFPHaMenu) )
return FALSE;
OffsetRect( &rFin,
-rFin.left+(ws-(rFin.right-rFin.left))/2,
-rFin.top+(hs-(rFin.bottom-rFin.top))/2 );
hwndTmp = CreateWindow(
kStrNomeClasseProg, kStrTitoloFP, kStileInizFP, rFin.left, rFin.top,
rFin.right-rFin.left, rFin.bottom-rFin.top, 0, 0, gHInst, NULL );
if( hwndTmp != NULL ) {
ShowWindow( hwndTmp, mostra );
*hwnd = hwndTmp;
return TRUE;
}
return FALSE;
}
int Errore( int codice, HWND parent ) {
static const char *msg[] = {
"Nessun errore. ",
"Classe non registrata. ",
"Finestra non creata. "
};
MessageBox( parent, msg[codice], kStrTitoloFP, MB_ICONERROR );
return codice;
}
/*==============================================================================
INFORMAZIONI (FORSE) UTILI
00000000 11001111 00000000 00000000 // WS_OVERLAPPEDWINDOW in binario
10000000 00000000 00000000 00000000 // WS_POPUP in binario
valori restituiti da GetWindowLong( hwnd, GWL_STYLE ):
00010100 11001111 00000000 00000000 // lancio con WS_OVERLAPPEDWINDOW
10010100 00000000 00000000 00000000 // dopo la modifica con WS_POPUP
10010100 00000000 00000000 00000000 // lancio con WS_POPUP
00010100 11001111 00000000 00000000 // dopo la modifica con WS_OVERLAPPEDWINDOW
flag apparentemente aggiunte da CreateWindow():
00010100 00000000 00000000 00000000
==============================================================================*/