Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Username: Password: oppure
Cambiamento stile finestra - main.c

main.c

Caricato da: AldoBaldo
Scarica il programma completo

  1. /**=============================================================================
  2. Mostra come ho implementato il passaggio dalla visualizzazione nella classica
  3. finestra ridimensionabile di Win32 (WS_OVERLAPPEDWINDOW) a quella a schermo
  4. pieno (WS_POPUP) impiegando le funzioni GetWindowLong() e SetWindowLong() con
  5. GWL_STYLE.
  6. =============================================================================**/
  7.  
  8. #include <windows.h>
  9.  
  10. const char *kStrNomeClasseProg = "schermopienoenon_class";
  11. const char *kStrTitoloFP = "Schermo pieno e non";
  12. DWORD kStileInizFP = WS_OVERLAPPEDWINDOW; // volendo, provare anche con WS_POPUP
  13. BOOL kFPHaMenu = FALSE;
  14. const INT kWInizFP = 480;
  15. const INT kHInizFP = 360;
  16.  
  17. HINSTANCE gHInst = NULL;
  18.  
  19. LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wPar, LPARAM lPar );
  20. BOOL RegistraClasse();
  21. BOOL CreaFinestraPrincipale( HWND *hwnd, INT mostra );
  22. int Errore( int codice, HWND parent );
  23.  
  24. int WINAPI WinMain( HINSTANCE hInst, HINSTANCE hPInst, LPSTR cmdLn, int show ) {
  25.     HWND hwnd = NULL;
  26.     MSG msg   = {0};
  27.  
  28.     gHInst = hInst;
  29.  
  30.     if( !RegistraClasse() )
  31.         return Errore( 1, NULL );
  32.  
  33.     if( !CreaFinestraPrincipale(&hwnd,show) )
  34.         return Errore( 2, NULL );
  35.  
  36.     MessageBox( hwnd,
  37.                "Premi \"S\" per la finestra a schermo pieno. \n"
  38.                "Premi \"F\" per la finestra standard di Windows. ",
  39.                kStrTitoloFP, MB_ICONINFORMATION );
  40.  
  41.     while( GetMessage(&msg,NULL,0,0) > 0 ) {
  42.         TranslateMessage( &msg );
  43.         DispatchMessage( &msg );
  44.     }
  45.  
  46.     return 0;
  47. }
  48.  
  49. /*==============================================================================
  50. Con questa funzione la finestra hwnd viene impostata a schermo pieno in stile
  51. WS_POPUP oppure nella visualizzazione "classica" in stile WS_OVERLAPPEDWINDOW.
  52. E' preferibile che lo stile della finestra al lancio del programma sia
  53. WS_OVERLAPPEDWINDOW. In caso contrario, la finestra "classica" verra' collocata
  54. alle coordinate 10,10, con dimensioni 480x360 (window rect, non client rect!).
  55. Il parametro popup sia TRUE per passare alla visualizzazione a schermo pieno,
  56. FALSE per passare alla visualizzazione "classica".
  57. ==============================================================================*/
  58.  
  59. void CambiaStileFinestra( HWND hwnd, BOOL popup ) {
  60.     // static, per conservare il rect precedente della finestra "classica"
  61.     static RECT gRFin = { 10, 10, 10+kWInizFP, 10+kHInizFP };
  62.  
  63.     DWORD stile = GetWindowLong( hwnd, GWL_STYLE );
  64.     RECT r;
  65.  
  66.     if( popup ) {
  67.         if( !(stile&WS_OVERLAPPEDWINDOW) ) {
  68.             return; // lo stile e' gia' quello richiesto
  69.         }
  70.         else {
  71.             LONG ws = GetSystemMetrics(SM_CXSCREEN);
  72.             LONG hs = GetSystemMetrics(SM_CYSCREEN);
  73.  
  74.             GetWindowRect( hwnd, &gRFin ); // conserva il rect corrente
  75.  
  76.             stile = (stile&(~WS_OVERLAPPEDWINDOW)) | WS_POPUP;
  77.  
  78.             SetRect( &r, 0, 0, ws, hs );
  79.             AdjustWindowRect( &r, stile, FALSE );
  80.             OffsetRect( &r, (ws-(r.right-r.left))/2, (hs-(r.bottom-r.top))/2 );
  81.         }
  82.     }
  83.     else {
  84.         if( (stile&WS_OVERLAPPEDWINDOW) ) {
  85.             return; // lo stile e' gia' quello richiesto
  86.         }
  87.         else {
  88.             CopyRect( &r, &gRFin ); // recupera il rect precedente
  89.  
  90.             stile = (stile&(~WS_POPUP)) | WS_OVERLAPPEDWINDOW;
  91.         }
  92.     }
  93.  
  94.     SetWindowLong( hwnd, GWL_STYLE, stile );
  95.     MoveWindow( hwnd, r.left, r.top, r.right-r.left, r.bottom-r.top, TRUE );
  96. }
  97.  
  98. LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wPar, LPARAM lPar ) {
  99.     switch( msg ) {
  100.         case WM_KEYDOWN:
  101.             if( wPar=='S' || wPar=='F' )
  102.                 CambiaStileFinestra( hwnd, wPar=='S' );
  103.             else if( wPar == VK_ESCAPE )
  104.                 SendMessage( hwnd, WM_CLOSE, 0, 0 );
  105.             break;
  106.  
  107.         case WM_CLOSE:
  108.             PostQuitMessage( 0 );
  109.             break;
  110.  
  111.         default:
  112.             return DefWindowProc( hwnd, msg, wPar, lPar );
  113.     }
  114.  
  115.     return 0;
  116. }
  117.  
  118. BOOL RegistraClasse() {
  119.     WNDCLASS wc      = {0};
  120.  
  121.     wc.lpfnWndProc   = WndProc;
  122.     wc.hInstance     = gHInst;
  123.     wc.hCursor       = LoadCursor( NULL, IDC_ARROW );
  124.     wc.hbrBackground = (HBRUSH)(COLOR_BACKGROUND);
  125.     wc.lpszClassName = kStrNomeClasseProg;
  126.  
  127.     return RegisterClass( &wc ) != 0;
  128. }
  129.  
  130. BOOL CreaFinestraPrincipale( HWND *hwnd, int mostra ) {
  131.     LONG ws = GetSystemMetrics(SM_CXSCREEN);
  132.     LONG hs = GetSystemMetrics(SM_CYSCREEN);
  133.     BOOL popup = kStileInizFP == WS_POPUP;
  134.     HWND hwndTmp = NULL;
  135.     RECT rFin;
  136.     LONG margine;
  137.  
  138.     if( popup )
  139.         SetRect( &rFin, 0, 0, ws, hs );
  140.     else SetRect( &rFin, 0, 0, kWInizFP, kHInizFP );
  141.  
  142.     if( FALSE == AdjustWindowRect(&rFin,kStileInizFP,kFPHaMenu) )
  143.         return FALSE;
  144.  
  145.     OffsetRect( &rFin,
  146.                 -rFin.left+(ws-(rFin.right-rFin.left))/2,
  147.                 -rFin.top+(hs-(rFin.bottom-rFin.top))/2 );
  148.  
  149.     hwndTmp = CreateWindow(
  150.         kStrNomeClasseProg, kStrTitoloFP, kStileInizFP, rFin.left, rFin.top,
  151.         rFin.right-rFin.left, rFin.bottom-rFin.top, 0, 0, gHInst, NULL );
  152.  
  153.     if( hwndTmp != NULL ) {
  154.         ShowWindow( hwndTmp, mostra );
  155.         *hwnd = hwndTmp;
  156.         return TRUE;
  157.     }
  158.  
  159.     return FALSE;
  160. }
  161.  
  162. int Errore( int codice, HWND parent ) {
  163.     static const char *msg[] = {
  164.         "Nessun errore. ",
  165.         "Classe non registrata. ",
  166.         "Finestra non creata. "
  167.     };
  168.  
  169.     MessageBox( parent, msg[codice], kStrTitoloFP, MB_ICONERROR );
  170.  
  171.     return codice;
  172. }
  173.  
  174. /*==============================================================================
  175. INFORMAZIONI (FORSE) UTILI
  176.  
  177. 00000000 11001111 00000000 00000000 // WS_OVERLAPPEDWINDOW in binario
  178. 10000000 00000000 00000000 00000000 // WS_POPUP in binario
  179.  
  180. valori restituiti da GetWindowLong( hwnd, GWL_STYLE ):
  181.  
  182. 00010100 11001111 00000000 00000000 // lancio con WS_OVERLAPPEDWINDOW
  183. 10010100 00000000 00000000 00000000 // dopo la modifica con WS_POPUP
  184.  
  185. 10010100 00000000 00000000 00000000 // lancio con WS_POPUP
  186. 00010100 11001111 00000000 00000000 // dopo la modifica con WS_OVERLAPPEDWINDOW
  187.  
  188. flag apparentemente aggiunte da CreateWindow():
  189.  
  190. 00010100 00000000 00000000 00000000
  191. ==============================================================================*/