From 9777fcaf88f0f791fdd6b78f86fde4ac066d1c1e Mon Sep 17 00:00:00 2001 From: Don Heyse Date: Fri, 7 Feb 2003 21:24:39 +0000 Subject: [PATCH] Johns changes for layers, fgSetWindow, and fgSetupPixelFormat. git-svn-id: svn+ssh://svn.code.sf.net/p/freeglut/code/trunk/freeglut/freeglut@48 7f0cb862-5218-0410-a997-914c9d46530a --- freeglut-1.3/freeglut_main.c | 92 +++++++++++++---- freeglut-1.3/freeglut_menu.c | 10 +- freeglut-1.3/freeglut_state.c | 61 ++++++++++-- freeglut-1.3/freeglut_window.c | 213 ++++++++++++++++++++++------------------ 4 files changed, 249 insertions(+), 127 deletions(-) diff --git a/freeglut-1.3/freeglut_main.c b/freeglut-1.3/freeglut_main.c index 455ebf1..9d98284 100644 --- a/freeglut-1.3/freeglut_main.c +++ b/freeglut-1.3/freeglut_main.c @@ -32,7 +32,7 @@ #define G_LOG_DOMAIN "freeglut-main" #include "../include/GL/freeglut.h" -#include "../include/GL/freeglut_internal.h" +#include "freeglut_internal.h" /* * TODO BEFORE THE STABLE RELEASE: @@ -51,6 +51,7 @@ * Calls a window's redraw method. This is used when * a redraw is forced by the incoming window messages. */ + static void fghRedrawWindowByHandle #if TARGET_HOST_UNIX_X11 ( Window handle ) @@ -75,10 +76,9 @@ static void fghRedrawWindowByHandle freeglut_return_if_fail( window->State.Visible == TRUE ); /* - * Set the window as the current one. Calling glutSetWindow() - * might seem slow and generally redundant, but it is portable. + * Set the window as the current one. */ - glutSetWindow( window->ID ); + fgSetWindow( window ); /* * Do not exagerate with the redisplaying @@ -115,7 +115,7 @@ static void fghReshapeWindowByHandle /* * Remember about setting the current window... */ - glutSetWindow( window->ID ); + fgSetWindow( window ); /* * Check if there is a reshape callback hooked @@ -160,7 +160,7 @@ static void fghcbDisplayWindow( SFG_Window *window, SFG_Enumerator *enumerator ) /* * OKi, this is the case: have the window set as the current one */ - glutSetWindow( window->ID ); + fgSetWindow( window ); /* * Do not exagerate with the redisplaying @@ -180,7 +180,7 @@ static void fghcbDisplayWindow( SFG_Window *window, SFG_Enumerator *enumerator ) */ if( window->State.NeedToResize ) { - glutSetWindow( window->ID ); + fgSetWindow( window ); fghReshapeWindowByHandle( window->Window.Handle, @@ -208,7 +208,7 @@ static void fghcbDisplayWindow( SFG_Window *window, SFG_Enumerator *enumerator ) RedrawWindow( window->Window.Handle, NULL, NULL, - RDW_NOERASE | RDW_INTERNALPAINT | RDW_INVALIDATE + RDW_NOERASE | RDW_INTERNALPAINT | RDW_INVALIDATE | RDW_UPDATENOW ); } @@ -557,7 +557,7 @@ void FGAPIENTRY glutMainLoopEvent( void ) /* * We're going to send a callback to a window. Make it current. */ - glutSetWindow( window->ID ); + fgSetWindow( window ); /* * Sending this event, the X server can notify us that the window has just @@ -725,8 +725,19 @@ void FGAPIENTRY glutMainLoopEvent( void ) { if ( fgCheckActiveMenu ( window, window->ActiveMenu ) == TRUE ) /* Inside the menu, invoke the callback and deactivate the menu*/ { + /* Save the current window and menu and set the current window to the window whose menu this is */ + SFG_Window *save_window = fgStructure.Window ; + SFG_Menu *save_menu = fgStructure.Menu ; + fgSetWindow ( window ) ; + fgStructure.Menu = window->ActiveMenu ; + + /* Execute the menu callback */ fgExecuteMenuCallback ( window->ActiveMenu ) ; fgDeactivateMenu ( window ) ; + + /* Restore the current window and menu */ + fgSetWindow ( save_window ) ; + fgStructure.Menu = save_menu ; } else /* Outside the menu, deactivate the menu if it's a downclick */ { @@ -768,7 +779,7 @@ void FGAPIENTRY glutMainLoopEvent( void ) /* * Set the current window */ - glutSetWindow( window->ID ); + fgSetWindow( window ); /* * Remember the current modifiers state @@ -839,7 +850,7 @@ void FGAPIENTRY glutMainLoopEvent( void ) /* * Get ready to calling the keyboard/special callbacks */ - glutSetWindow( window->ID ); + fgSetWindow( window ); /* * GLUT API tells us to have two separate callbacks... @@ -1119,7 +1130,7 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPara if ( ( window == NULL ) && ( uMsg != WM_CREATE ) ) return( DefWindowProc( hWnd, uMsg, wParam, lParam ) ); -/* if ( uMsg != 0x000f ) printf ( "message <%x>\n", uMsg ) ; */ +/* printf ( "Window %3d message <%04x> %12d %12d\n", window?window->ID:0, uMsg, wParam, lParam ) ; */ /* * Check what type of message are we receiving */ @@ -1145,7 +1156,7 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPara /* * Setup the pixel format of our window */ - fgSetupPixelFormat( window, FALSE ); + fgSetupPixelFormat( window, FALSE, PFD_MAIN_PLANE ); /* * Create the OpenGL rendering context now @@ -1323,7 +1334,7 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPara /* * Make sure the current window is set... */ - glutSetWindow( window->ID ); + fgSetWindow( window ); /* * Execute the active mouse motion callback now @@ -1341,7 +1352,7 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPara /* * Make sure the current window is set */ - glutSetWindow( window->ID ); + fgSetWindow( window ); /* * Execute the passive mouse motion callback @@ -1415,8 +1426,19 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPara { if ( fgCheckActiveMenu ( window, window->ActiveMenu ) == TRUE ) /* Inside the menu, invoke the callback and deactivate the menu*/ { + /* Save the current window and menu and set the current window to the window whose menu this is */ + SFG_Window *save_window = fgStructure.Window ; + SFG_Menu *save_menu = fgStructure.Menu ; + fgSetWindow ( window ) ; + fgStructure.Menu = window->ActiveMenu ; + + /* Execute the menu callback */ fgExecuteMenuCallback ( window->ActiveMenu ) ; fgDeactivateMenu ( window ) ; + + /* Restore the current window and menu */ + fgSetWindow ( save_window ) ; + fgStructure.Menu = save_menu ; } else /* Outside the menu, deactivate the menu if it's a downclick */ { @@ -1458,7 +1480,7 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPara /* * Set the current window */ - glutSetWindow( window->ID ); + fgSetWindow( window ); /* * Remember the current modifiers state. @@ -1499,7 +1521,7 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPara /* * Set the current window */ - glutSetWindow( window->ID ); + fgSetWindow( window ); /* * Remember the current modifiers state. This is done here in order @@ -1569,7 +1591,7 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPara /* * Set the current window */ - glutSetWindow( window->ID ); + fgSetWindow( window ); /* * Remember the current modifiers state. This is done here in order @@ -1678,6 +1700,40 @@ LRESULT CALLBACK fgWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPara // lRet = DefWindowProc( hWnd, uMsg, wParam, lParam ) ; break ; + /* + * Other messages that I have seen and which are not handled already + */ + case WM_SETTEXT : /* 0x000c */ + lRet = DefWindowProc( hWnd, uMsg, wParam, lParam ); /* Pass it on to "DefWindowProc" to set the window text */ + break ; + + case WM_GETTEXT : /* 0x000d */ + /* Ideally we would copy the title of the window into "lParam" */ +/* strncpy ( (char *)lParam, "Window Title", wParam ) ; + lRet = ( wParam > 12 ) ? 12 : wParam ; */ /* the number of characters copied */ + lRet = DefWindowProc( hWnd, uMsg, wParam, lParam ); + break ; + + case WM_GETTEXTLENGTH : /* 0x000e */ + /* Ideally we would get the length of the title of the window */ + lRet = 12 ; /* the number of characters in "Window Title\0" (see above) */ + break ; + + case WM_ERASEBKGND : /* 0x0014 */ + lRet = DefWindowProc( hWnd, uMsg, wParam, lParam ); + break ; + + case WM_SYNCPAINT : /* 0x0088 */ + /* Another window has moved, need to update this one */ + window->State.Redisplay = TRUE ; + lRet = DefWindowProc( hWnd, uMsg, wParam, lParam ); /* Help screen says this message must be passed to "DefWindowProc" */ + break ; + + case WM_NCPAINT : /* 0x0085 */ + /* Need to update the border of this window */ + lRet = DefWindowProc( hWnd, uMsg, wParam, lParam ); /* Pass it on to "DefWindowProc" to repaint a standard border */ + break ; + default: /* * Handle unhandled messages diff --git a/freeglut-1.3/freeglut_menu.c b/freeglut-1.3/freeglut_menu.c index c50cea5..0527c73 100644 --- a/freeglut-1.3/freeglut_menu.c +++ b/freeglut-1.3/freeglut_menu.c @@ -32,7 +32,7 @@ #define G_LOG_DOMAIN "freeglut-menu" #include "../include/GL/freeglut.h" -#include "../include/GL/freeglut_internal.h" +#include "freeglut_internal.h" /* * TODO BEFORE THE STABLE RELEASE: @@ -420,7 +420,7 @@ void fgActivateMenu( SFG_Window* window, int button ) menu->X = x ; menu->Y = y ; - glutSetWindow ( window->ID ) ; + fgSetWindow ( window ) ; if( x > ( glutGet( GLUT_WINDOW_WIDTH ) - menu->Width ) ) menu->X = glutGet( GLUT_WINDOW_WIDTH ) - menu->Width; @@ -665,7 +665,7 @@ void FGAPIENTRY glutAddSubMenu( const char* label, int subMenuID ) /* * Fill in the appropriate values */ - menuEntry->Text = strdup( label ); + menuEntry->Text = strdup( label ); menuEntry->SubMenu = subMenu; menuEntry->ID = -1; @@ -708,7 +708,7 @@ void FGAPIENTRY glutChangeToMenuEntry( int item, const char* label, int value ) if( menuEntry->Text != NULL ) free( menuEntry->Text ); - menuEntry->Text = strdup( label ); + menuEntry->Text = strdup( label ); menuEntry->ID = value; menuEntry->SubMenu = NULL; @@ -748,7 +748,7 @@ void FGAPIENTRY glutChangeToSubMenu( int item, const char* label, int subMenuID if( menuEntry->Text != NULL ) free( menuEntry->Text ); - menuEntry->Text = strdup( label ); + menuEntry->Text = strdup( label ); menuEntry->SubMenu = subMenu; menuEntry->ID = -1; diff --git a/freeglut-1.3/freeglut_state.c b/freeglut-1.3/freeglut_state.c index affa1ee..bd0b1e6 100644 --- a/freeglut-1.3/freeglut_state.c +++ b/freeglut-1.3/freeglut_state.c @@ -32,7 +32,7 @@ #define G_LOG_DOMAIN "freeglut-state" #include "../include/GL/freeglut.h" -#include "../include/GL/freeglut_internal.h" +#include "freeglut_internal.h" /* * TODO BEFORE THE STABLE RELEASE: @@ -124,6 +124,10 @@ int FGAPIENTRY glutGet( GLenum eWhat ) { int returnValue ; GLboolean boolValue ; + + if ( eWhat == GLUT_INIT_STATE ) + return ( fgState.Time.Set ) ; + freeglut_assert_ready; /* @@ -375,10 +379,13 @@ int FGAPIENTRY glutGet( GLenum eWhat ) /* * ...then we've got to correct the results we've just received... */ - winRect.left += GetSystemMetrics( SM_CXSIZEFRAME ) - 1; - winRect.right -= GetSystemMetrics( SM_CXSIZEFRAME ) - 1; - winRect.top += GetSystemMetrics( SM_CYSIZEFRAME ) - 1 + GetSystemMetrics( SM_CYCAPTION ); - winRect.bottom -= GetSystemMetrics( SM_CYSIZEFRAME ) + 1; + if ( fgStructure.Window->Parent == NULL ) + { + winRect.left += GetSystemMetrics( SM_CXSIZEFRAME ) - 1; + winRect.right -= GetSystemMetrics( SM_CXSIZEFRAME ) - 1; + winRect.top += GetSystemMetrics( SM_CYSIZEFRAME ) - 1 + GetSystemMetrics( SM_CYCAPTION ); + winRect.bottom -= GetSystemMetrics( SM_CYSIZEFRAME ) + 1; + } /* * ...and finally return the caller the desired value: @@ -397,7 +404,7 @@ int FGAPIENTRY glutGet( GLenum eWhat ) /* * Check if the current display mode is possible */ - return( fgSetupPixelFormat( fgStructure.Window, TRUE ) ); + return( fgSetupPixelFormat( fgStructure.Window, TRUE, PFD_MAIN_PLANE ) ); case GLUT_WINDOW_FORMAT_ID: /* @@ -606,6 +613,9 @@ int FGAPIENTRY glutLayerGet( GLenum eWhat ) */ switch( eWhat ) { + +#if TARGET_HOST_UNIX_X11 + case GLUT_OVERLAY_POSSIBLE: /* * Nope, overlays are not possible. @@ -642,6 +652,45 @@ int FGAPIENTRY glutLayerGet( GLenum eWhat ) */ return( -1 ); +#elif TARGET_HOST_WIN32 + + case GLUT_OVERLAY_POSSIBLE: + /* + * Check if an overlay display mode is possible + */ + return( fgSetupPixelFormat( fgStructure.Window, TRUE, PFD_OVERLAY_PLANE ) ); + + case GLUT_LAYER_IN_USE: + /* + * The normal plane is always in use + */ + return( GLUT_NORMAL ); + + case GLUT_HAS_OVERLAY: + /* + * No window is allowed to have an overlay + */ + return( FALSE ); + + case GLUT_TRANSPARENT_INDEX: + /* + * Return just anything, which is always defined as zero + */ + return( 0 ); + + case GLUT_NORMAL_DAMAGED: + /* + * Actually I do not know. Maybe. + */ + return( FALSE ); + + case GLUT_OVERLAY_DAMAGED: + /* + * Return minus one to mark that no layer is in use + */ + return( -1 ); +#endif + default: /* * Complain to the user about the obvious bug diff --git a/freeglut-1.3/freeglut_window.c b/freeglut-1.3/freeglut_window.c index 28e19f1..6553477 100644 --- a/freeglut-1.3/freeglut_window.c +++ b/freeglut-1.3/freeglut_window.c @@ -32,7 +32,7 @@ #define G_LOG_DOMAIN "freeglut-window" #include "../include/GL/freeglut.h" -#include "../include/GL/freeglut_internal.h" +#include "freeglut_internal.h" /* * TODO BEFORE THE STABLE RELEASE: @@ -214,7 +214,7 @@ XVisualInfo* fgChooseVisual( void ) * Setup the pixel format for a Win32 window */ #if TARGET_HOST_WIN32 -GLboolean fgSetupPixelFormat( SFG_Window* window, GLboolean checkOnly ) +GLboolean fgSetupPixelFormat( SFG_Window* window, GLboolean checkOnly, unsigned char layer_type ) { PIXELFORMATDESCRIPTOR* ppfd, pfd; int flags, pixelformat; @@ -232,56 +232,56 @@ GLboolean fgSetupPixelFormat( SFG_Window* window, GLboolean checkOnly ) /* * It might be the case for us to use double buffering */ - if( fgState.DisplayMode & GLUT_DOUBLE ) - flags |= PFD_DOUBLEBUFFER; + if( fgState.DisplayMode & GLUT_DOUBLE ) + flags |= PFD_DOUBLEBUFFER; - /* - * Specify which pixel format do we opt for... - */ + /* + * Specify which pixel format do we opt for... + */ # pragma message( "fgSetupPixelFormat(): there is still some work to do here!" ) - pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); - pfd.nVersion = 1; - pfd.dwFlags = flags; - pfd.iPixelType = PFD_TYPE_RGBA; - pfd.cColorBits = 24; - pfd.cRedBits = 0; - pfd.cRedShift = 0; - pfd.cGreenBits = 0; - pfd.cGreenShift = 0; - pfd.cBlueBits = 0; - pfd.cBlueShift = 0; - pfd.cAlphaBits = 0; - pfd.cAlphaShift = 0; - pfd.cAccumBits = 0; - pfd.cAccumRedBits = 0; - pfd.cAccumGreenBits = 0; - pfd.cAccumBlueBits = 0; - pfd.cAccumAlphaBits = 0; + pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); + pfd.nVersion = 1; + pfd.dwFlags = flags; + pfd.iPixelType = PFD_TYPE_RGBA; + pfd.cColorBits = 24; + pfd.cRedBits = 0; + pfd.cRedShift = 0; + pfd.cGreenBits = 0; + pfd.cGreenShift = 0; + pfd.cBlueBits = 0; + pfd.cBlueShift = 0; + pfd.cAlphaBits = 0; + pfd.cAlphaShift = 0; + pfd.cAccumBits = 0; + pfd.cAccumRedBits = 0; + pfd.cAccumGreenBits = 0; + pfd.cAccumBlueBits = 0; + pfd.cAccumAlphaBits = 0; #if 0 - pfd.cDepthBits = 32; - pfd.cStencilBits = 0; + pfd.cDepthBits = 32; + pfd.cStencilBits = 0; #else - pfd.cDepthBits = 24; - pfd.cStencilBits = 8; + pfd.cDepthBits = 24; + pfd.cStencilBits = 8; #endif - pfd.cAuxBuffers = 0; - pfd.iLayerType = PFD_MAIN_PLANE; - pfd.bReserved = 0; - pfd.dwLayerMask = 0; - pfd.dwVisibleMask = 0; - pfd.dwDamageMask = 0; - - /* - * Fill in the color bits... - */ - pfd.cColorBits = (BYTE) GetDeviceCaps( window->Window.Device, BITSPIXEL ); - ppfd = &pfd; + pfd.cAuxBuffers = 0; + pfd.iLayerType = layer_type; + pfd.bReserved = 0; + pfd.dwLayerMask = 0; + pfd.dwVisibleMask = 0; + pfd.dwDamageMask = 0; + + /* + * Fill in the color bits... + */ + pfd.cColorBits = (BYTE) GetDeviceCaps( window->Window.Device, BITSPIXEL ); + ppfd = &pfd; /* * Choose the pixel format that matches our demand */ - pixelformat = ChoosePixelFormat( window->Window.Device, ppfd ); + pixelformat = ChoosePixelFormat( window->Window.Device, ppfd ); if( pixelformat == 0 ) return( FALSE ); @@ -294,14 +294,58 @@ GLboolean fgSetupPixelFormat( SFG_Window* window, GLboolean checkOnly ) /* * Finally, set the window's pixel format */ - if( SetPixelFormat( window->Window.Device, pixelformat, ppfd ) == FALSE ) - return( FALSE ); - - return( TRUE ); + return ( SetPixelFormat( window->Window.Device, pixelformat, ppfd ) ) ; } #endif /* + * Sets the OpenGL context and the fgStructure "Current Window" pointer to the window + * structure passed in. + */ +void fgSetWindow ( SFG_Window *window ) +{ +#if TARGET_HOST_UNIX_X11 + /* + * Make the selected window's GLX context the current one + */ + glXMakeCurrent( + fgDisplay.Display, + window->Window.Handle, + window->Window.Context + ); + +#elif TARGET_HOST_WIN32 + /* + * Release the previous' context's device context + */ + if( fgStructure.Window != NULL ) + ReleaseDC( fgStructure.Window->Window.Handle, fgStructure.Window->Window.Device ); + + if ( window ) + { + /* + * We will care about releasing the device context later + */ + window->Window.Device = GetDC( window->Window.Handle ); + + /* + * Set the new current context: + */ + wglMakeCurrent( + window->Window.Device, + window->Window.Context + ); + } +#endif + + /* + * Remember that we have changed the current window state + */ + fgStructure.Window = window; +} + + +/* * Opens a window. Requires a SFG_Window object created and attached * to the freeglut structure. OpenGL context is created here. */ @@ -456,7 +500,7 @@ void fgOpenWindow( SFG_Window* window, const char* title, int x, int y, int w, i /* * Set the newly created window as the current one... */ - glutSetWindow( window->ID ); + fgSetWindow( window ); /* * Move the viewport a bit down and right from top-left corner to hide the decorations @@ -560,7 +604,7 @@ void fgOpenWindow( SFG_Window* window, const char* title, int x, int y, int w, i /* * Set the newly created window as the current one */ - glutSetWindow( window->ID ); + fgSetWindow( window ); } /* @@ -651,17 +695,25 @@ int FGAPIENTRY glutCreateSubWindow( int parentID, int x, int y, int w, int h ) */ void FGAPIENTRY glutDestroyWindow( int windowID ) { - /* - * Grab the freeglut window pointer from the structure - */ - SFG_Window* window = fgWindowByID( windowID ); - freeglut_return_if_fail( window != NULL ); - - /* - * There is a function that performs all needed steps - * defined in freeglut_structure.c. Let's use it: - */ - fgAddToWindowDestroyList( window, TRUE ); + fgExecutionState ExecState = fgState.ExecState ; + + /* + * Grab the freeglut window pointer from the structure + */ + SFG_Window* window = fgWindowByID( windowID ); + freeglut_return_if_fail( window != NULL ); + + /* + * There is a function that performs all needed steps + * defined in freeglut_structure.c. Let's use it: + */ + fgAddToWindowDestroyList( window, TRUE ); + + /* + * Since the "fgAddToWindowDestroyList" function could easily have set the "ExecState" + * to stop, let's set it back to what it was. + */ + fgState.ExecState = ExecState ; } /* @@ -700,42 +752,7 @@ void FGAPIENTRY glutSetWindow( int ID ) return; } -#if TARGET_HOST_UNIX_X11 - /* - * Make the selected window's GLX context the current one - */ - glXMakeCurrent( - fgDisplay.Display, - window->Window.Handle, - window->Window.Context - ); - -#elif TARGET_HOST_WIN32 - /* - * Release the previous' context's device context - */ - if( fgStructure.Window != NULL ) - ReleaseDC( fgStructure.Window->Window.Handle, fgStructure.Window->Window.Device ); - - /* - * We will care about releasing the device context later - */ - window->Window.Device = GetDC( window->Window.Handle ); - - /* - * Set the new current context: - */ - wglMakeCurrent( - window->Window.Device, - window->Window.Context - ); - -#endif - - /* - * Remember that we have changed the current window state - */ - fgStructure.Window = window; + fgSetWindow ( window ) ; } /* @@ -852,7 +869,7 @@ void FGAPIENTRY glutIconifyWindow( void ) /* * Set the current window's title */ -void FGAPIENTRY glutSetWindowTitle( char* title ) +void FGAPIENTRY glutSetWindowTitle( const char* title ) { freeglut_assert_ready; freeglut_assert_window; @@ -901,7 +918,7 @@ void FGAPIENTRY glutSetWindowTitle( char* title ) /* * Set the current window's iconified title */ -void FGAPIENTRY glutSetIconTitle( char* title ) +void FGAPIENTRY glutSetIconTitle( const char* title ) { freeglut_assert_ready; freeglut_assert_window; @@ -985,7 +1002,7 @@ void FGAPIENTRY glutReshapeWindow( int width, int height ) { GetWindowRect ( fgStructure.Window->Parent->Window.Handle, &winRect ) ; x -= winRect.left + GetSystemMetrics( SM_CXSIZEFRAME ) ; - y -= winRect.top + GetSystemMetrics( SM_CXSIZEFRAME ) + GetSystemMetrics( SM_CYCAPTION ) ; + y -= winRect.top + GetSystemMetrics( SM_CYSIZEFRAME ) + GetSystemMetrics( SM_CYCAPTION ) ; } /* -- 1.7.10.4