Esempio n. 1
0
void VID_Shutdown (void)
{
	if (vid_initialized)
	{
		//if (modestate == MS_FULLDIB)
		//	ChangeDisplaySettings (NULL, CDS_FULLSCREEN);

		PostMessage (HWND_BROADCAST, WM_PALETTECHANGED, (WPARAM)mainwindow, (LPARAM)0);
		PostMessage (HWND_BROADCAST, WM_SYSCOLORCHANGE, (WPARAM)0, (LPARAM)0);

		AppActivate(false, false);
		//DestroyDIBWindow ();
		//DestroyFullscreenWindow ();
		//DestroyFullDIBWindow ();

		if (hwnd_dialog)
			DestroyWindow (hwnd_dialog);

		if (mainwindow)
			DestroyWindow(mainwindow);

		//vid_testingmode = 0;
		vid_initialized = 0;
	}
}
Esempio n. 2
0
void CheckActive (HWND hWnd) // jit - for some reason, we sometimes don't get events for the window becaming active/inactive, so just check the forground window all the time...
{
	HWND foreground = GetForegroundWindow();
	static qboolean newwindow = true;
	static qboolean lastactive = false;
	qboolean active = false;
	qboolean minimized = false; // foreground should be null when minimized?

	if (!hWnd)
		return;

	if (foreground == hWnd)
	{
		active = true;
	}

	if (lastactive != active)
	{
		AppActivate(active, minimized, newwindow);

		if (reflib_active)
			re.AppActivate(active);

		newwindow = false;
		lastactive = active;
	}
}
Esempio n. 3
0
void VID_Shutdown (void) {
#ifdef _WIN32

	extern void AppActivate(BOOL fActive, BOOL minimize);

	AppActivate(false, false);

#endif

#ifdef GLSL
	SHD_Shutdown();
#endif

	RE_Shutdown( true );
}
Esempio n. 4
0
// Searchs and activates a window given its title or class name
//##ModelId=474D3026011A
bool CSendKeys::AppActivate(LPCTSTR WindowTitle, LPCTSTR WindowClass)
{
  HWND w;

  w = ::FindWindow(WindowClass, WindowTitle);
  if (w == NULL)
  {
    // Must specify at least a criteria
    if (WindowTitle == NULL && WindowClass == NULL)
      return false;

    // << Code to serialize the windowtitle/windowclass in order to send to EnumWindowProc()
    size_t l1(0), l2(0);
    if (WindowTitle)
      l1 = _tcslen(WindowTitle);
    if (WindowClass)
      l2 = _tcslen(WindowClass);

    LPTSTR titleclass = new TCHAR [l1 + l2 + 5];

    memset(titleclass, '\0', l1+l2+5);

    if (WindowTitle)
      _tcscpy(titleclass, WindowTitle);

    titleclass[l1] = 0;

    if (WindowClass)
      _tcscpy(titleclass+l1+1, WindowClass);

    // >>

    enumwindow_t t;

    t.hwnd = NULL;
    t.str  = titleclass;
    ::EnumWindows(enumwindowsProc, (LPARAM) & t);
    w = t.hwnd;
    delete [] titleclass;
  }

  if (w == NULL)
    return false;

  return AppActivate(w);
}
Esempio n. 5
0
/*
====================
MainWndProc

main window procedure
====================
*/
LONG WINAPI MainWndProc (
    HWND    hWnd,
    UINT    uMsg,
    WPARAM  wParam,
    LPARAM  lParam)
{
	LONG			lRet = 0;

	if ( uMsg == MSH_MOUSEWHEEL )
	{
		if ( ( ( int ) wParam ) > 0 )
		{
			Key_Event( K_MWHEELUP, true, sys_msg_time );
			Key_Event( K_MWHEELUP, false, sys_msg_time );
		}
		else
		{
			Key_Event( K_MWHEELDOWN, true, sys_msg_time );
			Key_Event( K_MWHEELDOWN, false, sys_msg_time );
		}
        return DefWindowProc (hWnd, uMsg, wParam, lParam);
	}

	switch (uMsg)
	{
	case WM_MOUSEWHEEL:
		/*
		** this chunk of code theoretically only works under NT4 and Win98
		** since this message doesn't exist under Win95
		*/
		if ( ( short ) HIWORD( wParam ) > 0 )
		{
			Key_Event( K_MWHEELUP, true, sys_msg_time );
			Key_Event( K_MWHEELUP, false, sys_msg_time );
		}
		else
		{
			Key_Event( K_MWHEELDOWN, true, sys_msg_time );
			Key_Event( K_MWHEELDOWN, false, sys_msg_time );
		}
		break;

	case WM_HOTKEY:
		return 0;

	case WM_CREATE:
		cl_hwnd = hWnd;

		MSH_MOUSEWHEEL = RegisterWindowMessage("MSWHEEL_ROLLMSG"); 
        return DefWindowProc (hWnd, uMsg, wParam, lParam);

	case WM_PAINT:
		SCR_DirtyScreen ();	// force entire screen to update next frame
        return DefWindowProc (hWnd, uMsg, wParam, lParam);

	case WM_DESTROY:
		// let sound and input know about this?
		cl_hwnd = NULL;
        return DefWindowProc (hWnd, uMsg, wParam, lParam);

	case WM_ACTIVATE:
		{
			int	fActive, fMinimized;

			// KJB: Watch this for problems in fullscreen modes with Alt-tabbing.
			fActive = LOWORD(wParam);
			fMinimized = (BOOL) HIWORD(wParam);

			AppActivate( fActive != WA_INACTIVE, fMinimized);

			if ( reflib_active )
				GLimp_AppActivate( !( fActive == WA_INACTIVE ) );
		}
        return DefWindowProc (hWnd, uMsg, wParam, lParam);

	case WM_MOVE:
		{
			int		xPos, yPos;
			RECT r;
			int		style;

			if (!vid_fullscreen->value)
			{
				xPos = (short) LOWORD(lParam);    // horizontal position 
				yPos = (short) HIWORD(lParam);    // vertical position 

				r.left   = 0;
				r.top    = 0;
				r.right  = 1;
				r.bottom = 1;

				style = GetWindowLong( hWnd, GWL_STYLE );
				AdjustWindowRect( &r, style, FALSE );

				Cvar_SetValue( "vid_xpos", xPos + r.left);
				Cvar_SetValue( "vid_ypos", yPos + r.top);
				vid_xpos->modified = false;
				vid_ypos->modified = false;
				if (ActiveApp)
					IN_Activate (true);
			}
		}
        return DefWindowProc (hWnd, uMsg, wParam, lParam);

// this is complicated because Win32 seems to pack multiple mouse events into
// one update sometimes, so we always check all states and look for events
	case WM_LBUTTONDOWN:
	case WM_LBUTTONUP:
	case WM_RBUTTONDOWN:
	case WM_RBUTTONUP:
	case WM_MBUTTONDOWN:
	case WM_MBUTTONUP:
#ifdef ENABLE_MOUSE4_MOUSE5 // mattx86: mouse4_mouse5
	case WM_XBUTTONDOWN:
	case WM_XBUTTONUP:
#endif
	case WM_MOUSEMOVE:
		{
			int	temp;

			temp = 0;

			if (wParam & MK_LBUTTON)
				temp |= 1;

			if (wParam & MK_RBUTTON)
				temp |= 2;

			if (wParam & MK_MBUTTON)
				temp |= 4;

#ifdef ENABLE_MOUSE4_MOUSE5 // mattx86: mouse4_mouse5
			if (wParam & MK_XBUTTON1)
				temp |= 8;

			if (wParam & MK_XBUTTON2)
				temp |= 16;
#endif

			IN_MouseEvent (temp);
		}
		break;

	case WM_SYSCOMMAND:
		if ( wParam == SC_SCREENSAVE )
			return 0;
        return DefWindowProc (hWnd, uMsg, wParam, lParam);
	case WM_SYSKEYDOWN:
		if ( wParam == 13 )
		{
			if ( vid_fullscreen )
			{
				Cvar_SetValue( "vid_fullscreen", !vid_fullscreen->value );
			}
			return 0;
		}
		// fall through
	case WM_KEYDOWN:
		Key_Event( MapKey( lParam ), true, sys_msg_time);
		break;

	case WM_SYSKEYUP:
	case WM_KEYUP:
		Key_Event( MapKey( lParam ), false, sys_msg_time);
		break;

	case MM_MCINOTIFY:
		{
			LONG CDAudio_MessageHandler(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
			lRet = CDAudio_MessageHandler (hWnd, uMsg, wParam, lParam);
		}
		break;

	default:	// pass all unhandled messages to DefWindowProc
        return DefWindowProc (hWnd, uMsg, wParam, lParam);
    }

    /* return 0 if handled message, 1 if not */
    return DefWindowProc( hWnd, uMsg, wParam, lParam );
}
Esempio n. 6
0
// Sends a key string
//##ModelId=474D302600AD
bool CSendKeys::SendKeys(LPCTSTR KeysString, bool Wait)
{
  WORD MKey, NumTimes;
  TCHAR KeyString[300] = {0};
  bool retval  = false;
  int  keyIdx;

  LPTSTR pKey = (LPTSTR) KeysString;
  TCHAR  ch;

  m_bWait = Wait;

  m_bWinDown = m_bShiftDown = m_bControlDown = m_bAltDown = m_bUsingParens = false;

  while (ch = *pKey)
  {
    switch (ch)
    {
    // begin modifier group
    case _TXCHAR('('):
      m_bUsingParens = true;
      break;

    // end modifier group
    case _TXCHAR(')'):
      m_bUsingParens = false;
      PopUpShiftKeys(); // pop all shift keys when we finish a modifier group close
      break;

    // ALT key
    case _TXCHAR('%'):
      m_bAltDown = true;
      SendKeyDown(VK_MENU, 1, false);
      break;

    // SHIFT key
    case _TXCHAR('+'):
      m_bShiftDown = true;
      SendKeyDown(VK_SHIFT, 1, false);
      break;

    // CTRL key
    case _TXCHAR('^'):
      m_bControlDown = true;
      SendKeyDown(VK_CONTROL, 1, false);
      break;

    // WINKEY (Left-WinKey)
    case '@':
      m_bWinDown = true;
      SendKeyDown(VK_LWIN, 1, false);
      break;

    // enter
    case _TXCHAR('~'):
      SendKeyDown(VK_RETURN, 1, true);
      PopUpShiftKeys();
      break;

    // begin special keys
    case _TXCHAR('{'):
      {
        LPTSTR p = pKey+1; // skip past the beginning '{'
        size_t t;

        // find end of close
        while (*p && *p != _TXCHAR('}'))
          p++;

        t = p - pKey;
        // special key definition too big?
        if (t > sizeof(KeyString))
          return false;

        // Take this KeyString into local buffer
        _tcsncpy(KeyString, pKey+1, t);

        KeyString[t-1] = _TXCHAR('\0');
        keyIdx = -1;

        pKey += t; // skip to next keystring

        // Invalidate key
        MKey = INVALIDKEY;

        // sending arbitrary vkeys?
        if (_tcsnicmp(KeyString, _T("VKEY"), 4) == 0)
        {
          p = KeyString + 4;
          MKey = _ttoi(p);
        }
        else if (_tcsnicmp(KeyString, _T("BEEP"), 4) == 0)
        {
          p = KeyString + 4 + 1;
          LPTSTR p1 = p;
          DWORD frequency, delay;

          if ((p1 = _tcsstr(p, _T(" "))) != NULL)
          {
            *p1++ = _TXCHAR('\0');
            frequency = _ttoi(p);
            delay = _ttoi(p1);
            ::Beep(frequency, delay);
          }
        }
        // Should activate a window?
        else if (_tcsnicmp(KeyString, _T("APPACTIVATE"), 11) == 0)
        {
          p = KeyString + 11 + 1;
          AppActivate(p);
        }
        // want to send/set delay?
        else if (_tcsnicmp(KeyString, _T("DELAY"), 5) == 0)
        {
          // Advance to parameters
          p = KeyString + 5;
          // set "sleep factor"
          if (*p == _TXCHAR('='))
            m_nDelayAlways = _ttoi(p + 1); // Take number after the '=' character
          else
            // set "sleep now"
            m_nDelayNow = _ttoi(p);
        }
        // not command special keys, then process as keystring to VKey
        else
        {
          MKey = StringToVKey(KeyString, keyIdx);
          // Key found in table
          if (keyIdx != -1)
          {
            NumTimes = 1;

            // Does the key string have also count specifier?
            t = _tcslen(KeyNames[keyIdx].keyName);
            if (_tcslen(KeyString) > t)
            {
              p = KeyString + t;
              // Take the specified number of times
              NumTimes = _ttoi(p);
            }

            if (KeyNames[keyIdx].normalkey)
              MKey = ::VkKeyScan(KeyNames[keyIdx].VKey);
          }
        }

        // A valid key to send?
        if (MKey != INVALIDKEY)
        {
          SendKey(MKey, NumTimes, true);
          PopUpShiftKeys();
        }
      }
      break;

      // a normal key was pressed
    default:
      // Get the VKey from the key
      MKey = ::VkKeyScan(ch);
      SendKey(MKey, 1, true);
      PopUpShiftKeys();
    }
    pKey++;
  }

  m_bUsingParens = false;
  PopUpShiftKeys();
  return true;
}
Esempio n. 7
0
//	main window procedure
static LRESULT WINAPI MainWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) {
	switch ( uMsg ) {
	case WM_CREATE:
		GMainWindow = hWnd;
		if ( r_fullscreen->integer ) {
			WIN_DisableAltTab();
		} else {
			WIN_EnableAltTab();
		}
		break;

	case WM_DESTROY:
		// let sound and input know about this?
		GMainWindow = NULL;
		if ( r_fullscreen->integer ) {
			WIN_EnableAltTab();
		}
		break;

	case WM_CLOSE:
		Cbuf_ExecuteText( EXEC_APPEND, "quit" );
		break;

	case WM_ACTIVATE:
		AppActivate( LOWORD( wParam ) != WA_INACTIVE, !!HIWORD( wParam ) );
		break;

	case WM_MOVE:
		if ( !r_fullscreen->integer ) {
			int xPos = ( short )LOWORD( lParam );	// horizontal position
			int yPos = ( short )HIWORD( lParam );	// vertical position

			RECT r;
			r.left   = 0;
			r.top    = 0;
			r.right  = 1;
			r.bottom = 1;

			int style = GetWindowLong( hWnd, GWL_STYLE );
			AdjustWindowRect( &r, style, FALSE );

			Cvar_SetValue( "vid_xpos", xPos + r.left );
			Cvar_SetValue( "vid_ypos", yPos + r.top );
			vid_xpos->modified = false;
			vid_ypos->modified = false;
			if ( ActiveApp ) {
				IN_Activate( true );
			}
		}
		break;

	case WM_SYSCOMMAND:
		if ( wParam == SC_SCREENSAVE ) {
			return 0;
		}
		break;

	case WM_SYSKEYDOWN:
		if ( wParam == 13 ) {
			if ( r_fullscreen ) {
				Cvar_SetValue( "r_fullscreen", !r_fullscreen->integer );
				Cbuf_AddText( "vid_restart\n" );
			}
			return 0;
		}
		// fall through
		break;

	case MM_MCINOTIFY:
		if ( CDAudio_MessageHandler( hWnd, uMsg, wParam, lParam ) == 0 ) {
			return 0;
		}
		break;
	}

	if ( IN_HandleInputMessage( uMsg, wParam, lParam ) ) {
		return 0;
	}

	return DefWindowProc( hWnd, uMsg, wParam, lParam );
}
Esempio n. 8
0
LONG WINAPI MainWndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	int				fActive, fMinimized;
	int				temp;
	LONG			lRet = 0;
	PAINTSTRUCT		ps;
	HDC				hdc;

	switch (uMsg)
	{
		case WM_CREATE:
			break;

		case WM_MOVE:
			window_x = (int) LOWORD(lParam);
			window_y = (int) HIWORD(lParam);
			VID_UpdateWindowStatus ();

			//if ((modestate == MS_WINDOWED) && !in_mode_set && !Minimized)
			//	VID_RememberWindowPos ();

			break;

   	    case WM_CLOSE:
		// this causes Close in the right-click task bar menu not to work, but right
		// now bad things happen if Close is handled in that case (garbage and a
		// crash on Win95)
			//if (!in_mode_set)
			{
				if (MessageBox (mainwindow, "Are you sure you want to quit?", "Confirm Exit",
							MB_YESNO | MB_SETFOREGROUND | MB_ICONQUESTION) == IDYES)
				{
					Host_Quit ();
				}
			}
			break;

		case WM_ACTIVATE:
			fActive = LOWORD(wParam);
			fMinimized = (BOOL) HIWORD(wParam);
			AppActivate(!(fActive == WA_INACTIVE), fMinimized);

		// fix the leftover Alt from any Alt-Tab or the like that switched us away
			ClearAllStates ();

			/*if (!in_mode_set)
			{
				if (windc)
					MGL_activatePalette(windc,true);

				VID_SetPalette(vid_curpal);
			}*/

			break;

		case WM_PAINT:
			hdc = GetDC (mainwindow);	// FIXME
			hdc = BeginPaint(hWnd, &ps);

			//Com_Printf ("WM_PAINT\n");	// TESTING

			/*
			if (!in_mode_set && host_initialized) {
				SCR_InvalidateScreen ();
				SCR_UpdateScreen ();
			}
			*/

			EndPaint(hWnd, &ps);
			break;

		case WM_KEYDOWN:
		case WM_SYSKEYDOWN:
			if (!in_mode_set)
				IN_TranslateKeyEvent (lParam, true);
			break;

		case WM_KEYUP:
		case WM_SYSKEYUP:
			if (!in_mode_set)
				IN_TranslateKeyEvent (lParam, true);
			break;

	// this is complicated because Win32 seems to pack multiple mouse events into
	// one update sometimes, so we always check all states and look for events
		case WM_LBUTTONDOWN:
		case WM_LBUTTONUP:
		case WM_RBUTTONDOWN:
		case WM_RBUTTONUP:
		case WM_MBUTTONDOWN:
		case WM_MBUTTONUP:
		case WM_XBUTTONDOWN:
		case WM_XBUTTONUP:
		case WM_MOUSEMOVE:
			if (!in_mode_set)
			{
				temp = 0;

				if (wParam & MK_LBUTTON)
					temp |= 1;

				if (wParam & MK_RBUTTON)
					temp |= 2;

				if (wParam & MK_MBUTTON)
					temp |= 4;

				// Win2k/XP let us bind button4 and button5
				if (wParam & MK_XBUTTON1)
					temp |= 8;

				if (wParam & MK_XBUTTON2)
					temp |= 16;

				IN_MouseEvent (temp);
			}
			break;

		// JACK: This is the mouse wheel with the Intellimouse
		// Its delta is either positive or neg, and we generate the proper
		// Event.
		case WM_MOUSEWHEEL: 
			if (in_mwheeltype != MWHEEL_DINPUT)
			{
				in_mwheeltype = MWHEEL_WINDOWMSG;

				if ((short) HIWORD(wParam) > 0) {
					Key_Event(K_MWHEELUP, true);
					Key_Event(K_MWHEELUP, false);
				} else {
					Key_Event(K_MWHEELDOWN, true);
					Key_Event(K_MWHEELDOWN, false);
				}
			}
			break;

		default:
            /* pass all unhandled messages to DefWindowProc */
            lRet = DefWindowProc (hWnd, uMsg, wParam, lParam);
	        break;

	}

    /* return 0 if handled message, 1 if not */
    return lRet;
}
Esempio n. 9
0
/* main window procedure */
LONG WINAPI MainWndProc (HWND    hWnd, UINT    uMsg, WPARAM  wParam, LPARAM  lParam) {
	extern void VID_UpdateWindowStatus (void);

    LONG lRet = 1;
	int fActive, fMinimized, temp;
	extern unsigned int uiWheelMessage;

	// VVD: didn't restore gamma after ALT+TAB on some ATI video cards (or drivers?...)
	// HACK!!! FIXME {
	extern int	restore_gamma;
	static time_t time_old;
	static float old_gamma;
	if (restore_gamma == 2) {
		if (time(NULL) - time_old > 0) {
			Cvar_SetValue(&v_gamma, old_gamma);
			restore_gamma = 0;
		}
	}
	// }

	if (uMsg == uiWheelMessage) {
		uMsg = WM_MOUSEWHEEL;
		wParam <<= 16;
	}

    switch (uMsg) {
#ifdef USINGRAWINPUT
		case WM_INPUT:
			// raw input handling
			IN_RawInput_MouseRead((HANDLE)lParam);
			break;
#endif

		case WM_KILLFOCUS:
            break;

    	case WM_SIZE:
			break;

		case WM_CREATE:

			mainwindow = hWnd;
			break;

   	    case WM_DESTROY:
			// let sound and input know about this?
			mainwindow = NULL;

//			PostQuitMessage (0);
			break;

		case WM_MOVE:
			{
				int		xPos, yPos;
				RECT r;
				int		style;

				if ( !r_fullscreen.integer )
				{
					xPos = (short) LOWORD(lParam);    // horizontal position 
					yPos = (short) HIWORD(lParam);    // vertical position 

					r.left   = 0;
					r.top    = 0;
					r.right  = 1;
					r.bottom = 1;
    
					style = GetWindowLong( hWnd, GWL_STYLE );
					AdjustWindowRect( &r, style, FALSE );
    
					Cvar_SetValue( &vid_xpos, xPos + r.left );
					Cvar_SetValue( &vid_ypos, yPos + r.top );
					vid_xpos.modified = false;
					vid_ypos.modified = false;
				}

				VID_UpdateWindowStatus();
			}
			break;

   	    case WM_CLOSE:
			if (MessageBox (mainwindow, "Are you sure you want to quit?", "ezQuake : Confirm Exit",
						MB_YESNO | MB_SETFOREGROUND | MB_ICONQUESTION) == IDYES)
			{
				Host_Quit ();
			}

	        break;

		case WM_ACTIVATE:
			fActive = LOWORD(wParam);
			fMinimized = (BOOL) HIWORD(wParam);
			AppActivate(!(fActive == WA_INACTIVE), fMinimized);

			// VVD: didn't restore gamma after ALT+TAB on some ATI video cards (or drivers?...)
			// HACK!!! FIXME {
			if (restore_gamma == 1) {
				time_old = time(NULL);
				restore_gamma = 2;
				old_gamma = v_gamma.value;
				Cvar_SetValue(&v_gamma, old_gamma + 0.01);
			}
			// }
			// fix the leftover Alt from any Alt-Tab or the like that switched us away
			ClearAllStates ();

			break;

		case WM_SYSKEYDOWN:
			if ( wParam == 13 )
			{
				if ( glw_state.vid_canalttab )
				{
					Cvar_LatchedSetValue( &r_fullscreen, !r_fullscreen.integer );
					Cbuf_AddText( "vid_restart\n" );
				}
				return 0;
			}
			// fall through
		case WM_KEYDOWN:
#ifdef WITH_KEYMAP
			IN_TranslateKeyEvent (lParam, wParam, true);
#else // WITH_KEYMAP
			Key_Event (IN_MapKey(lParam), true);
#endif // WITH_KEYMAP else
			break;

		case WM_KEYUP:
		case WM_SYSKEYUP:
#ifdef WITH_KEYMAP
			IN_TranslateKeyEvent (lParam, wParam, false);
#else // WITH_KEYMAP
			Key_Event (IN_MapKey(lParam), false);
#endif // WITH_KEYMAP else
			break;

		case WM_SYSCHAR:
			// keep Alt-Space from happening
			break;
		// this is complicated because Win32 seems to pack multiple mouse events into
		// one update sometimes, so we always check all states and look for events
		case WM_LBUTTONDOWN:
		case WM_LBUTTONUP:
		case WM_RBUTTONDOWN:
		case WM_RBUTTONUP:
		case WM_MBUTTONDOWN:
		case WM_MBUTTONUP:
		case WM_XBUTTONDOWN:
		case WM_XBUTTONUP:
#ifdef MM_CODE
		case WM_LBUTTONDBLCLK:
		case WM_RBUTTONDBLCLK:
		case WM_MBUTTONDBLCLK:
		case WM_XBUTTONDBLCLK:
#endif // MM_CODE
			temp = 0;

			if (wParam & MK_LBUTTON)
				temp |= 1;

			if (wParam & MK_RBUTTON)
				temp |= 2;

			if (wParam & MK_MBUTTON)
				temp |= 4;

			if (wParam & MK_XBUTTON1)
				temp |= 8;

			if (wParam & MK_XBUTTON2)
				temp |= 16;

			IN_MouseEvent (temp);

			break;

		// JACK: This is the mouse wheel with the Intellimouse
		// Its delta is either positive or neg, and we generate the proper Event.
		case WM_MOUSEWHEEL:
			if (in_mwheeltype != MWHEEL_DINPUT)
			{
				in_mwheeltype = MWHEEL_WINDOWMSG;

				if ((short) HIWORD(wParam) > 0) {
					Key_Event(K_MWHEELUP, true);
					Key_Event(K_MWHEELUP, false);
				} else {
					Key_Event(K_MWHEELDOWN, true);
					Key_Event(K_MWHEELDOWN, false);
				}

				// when an application processes the WM_MOUSEWHEEL message, it must return zero
				lRet = 0;
			}
			break;

		case WM_MWHOOK:
			MW_Hook_Message (lParam);
			break;

		case MM_MCINOTIFY:
			lRet = CDAudio_MessageHandler (hWnd, uMsg, wParam, lParam);
			break;

		default:
			/* pass all unhandled messages to DefWindowProc */
			lRet = DefWindowProc (hWnd, uMsg, wParam, lParam);
			break;
	}

	/* return 1 if handled message, 0 if not */
	return lRet;
}
Esempio n. 10
0
int CGame::WindowProc (
    HWND    hWnd,
    UINT    uMsg,
    WPARAM  wParam,
    LPARAM  lParam)

{
	LONG			lRet = 0;

	int				temp = 0;
	HDC				hdc;
	PAINTSTRUCT		ps;
	// static int		recursiveflag;
	bool fAltDown;


	g_pVCR->TrapWindowProc( uMsg, wParam, lParam );


	if ( !engine )
	{
		return DefWindowProc( hWnd, uMsg, wParam, lParam );
	}

#ifndef USE_DI_MOUSE
	if ( uMsg == m_uiMouseWheel )
	{
		eng->TrapKey_Event( ( ( int ) wParam ) > 0 ? K_MWHEELUP : K_MWHEELDOWN, true );
		eng->TrapKey_Event( ( ( int ) wParam ) > 0 ? K_MWHEELUP : K_MWHEELDOWN, false );
        return lRet;
	}
#endif

	switch (uMsg)
	{
		case WM_SETFOCUS:
			if ( launcherui->IsActive() )
			{
				launcherui->RequestFocus();
			}
			break;
		case WM_CREATE:
			::SetForegroundWindow(hWnd);
			break;

#ifndef USE_DI_MOUSE
		case WM_MOUSEWHEEL:
			eng->TrapKey_Event( ( short ) HIWORD( wParam ) > 0 ? K_MWHEELUP : K_MWHEELDOWN, true );
			eng->TrapKey_Event( ( short ) HIWORD( wParam ) > 0 ? K_MWHEELUP : K_MWHEELDOWN, false );
			break;
#endif

		case WM_SYSCOMMAND:

	        if ( ( wParam == SC_SCREENSAVE ) || 
				 ( wParam == SC_CLOSE ) ) 
			{
			    return lRet;
			}
        
			if ( !videomode->GetInModeChange() )
			{
				engine->S_BlockSound ();
				engine->S_ClearBuffer ();
			}

			lRet = DefWindowProc (hWnd, uMsg, wParam, lParam);

			if ( !videomode->GetInModeChange() )
			{
				engine->S_UnblockSound ();
			}
			break;

		case WM_SIZE:
			if (wParam == SIZE_MINIMIZED)
			{
				MoveWindow( hWnd, 0, -20, 0, 20, FALSE );
			}
			break;
			
		case WM_MOVE:
			game->SetWindowXY( (int)LOWORD( lParam ), (int)HIWORD( lParam ) );
			videomode->UpdateWindowPosition();
			break;

		case WM_SYSCHAR:
			// keep Alt-Space from happening
			break;

		case WM_ACTIVATEAPP:
			AppActivate( wParam ? true : false );
			break;

		case WM_PAINT:
			hdc = BeginPaint(hWnd, &ps);
			EndPaint(hWnd, &ps);
			break;

#ifndef USE_DI_KEYBOARD
		case WM_KEYDOWN:
		case WM_SYSKEYDOWN:
			if ( !videomode->GetInModeChange() )
			{
				eng->TrapKey_Event (MapKey(lParam), true );
			}
			break;
#endif

		case WM_SYSKEYUP:
			fAltDown = ( HIWORD(lParam) & KF_ALTDOWN ) ? true : false;

			// Check for ALT-TAB and ALT-ESC
			if (fAltDown && (wParam == VK_TAB || wParam == VK_ESCAPE))
			{
				if (!videomode->IsWindowedMode())
				{
					ShowWindow(hWnd, SW_MINIMIZE);
					break;
				}
			}

#ifndef USE_DI_KEYBOARD
		case WM_KEYUP:
			if ( !videomode->GetInModeChange() )
			{
				eng->TrapKey_Event (MapKey(lParam), false );
			}
			break;
#endif

#ifndef USE_DI_MOUSE
	// this is complicated because Win32 seems to pack multiple mouse events into
	// one update sometimes, so we always check all states and look for events
		case WM_MOUSEMOVE:
			if ( !videomode->GetInModeChange() )
			{
				temp |= FieldsFromMouseWParam( wParam );
				eng->TrapMouse_Event ( temp, true );
			}
			break;
		case WM_LBUTTONDOWN:
		case WM_RBUTTONDOWN:
		case WM_MBUTTONDOWN:
		case MS_WM_XBUTTONDOWN:
			if ( !videomode->GetInModeChange() )
			{
				temp |= FieldsFromMouseWParam( wParam );
				eng->TrapMouse_Event ( temp, true );
			}
			break;

		case WM_LBUTTONUP:
		case WM_RBUTTONUP:
		case WM_MBUTTONUP:
		case MS_WM_XBUTTONUP:
			if ( !videomode->GetInModeChange() )
			{
				temp = FieldsFromMouseUpMsgAndWParam( uMsg, wParam ) | FieldsFromMouseWParam( wParam );
				eng->TrapMouse_Event ( temp, false );
			}
			break;
#endif

   	    case WM_CLOSE:
			if ( !videomode->GetInModeChange() )
			{
				if ( eng->GetState() == DLL_ACTIVE )
				{
					eng->Unload();
					gui->SetQuitting();
				}
			}
			lRet = 0;
			break;

		default:
            /* pass all unhandled messages to DefWindowProc */
            lRet = DefWindowProc (hWnd, uMsg, wParam, lParam);
	        break;
    }

    /* return 0 if handled message, 1 if not */
    return lRet;

}
Esempio n. 11
0
static void IN_HandleEvents( void )
{
	Uint16 *wtext = NULL;
	SDL_PumpEvents();
	SDL_Event event;

	while( SDL_PollEvent( &event ) ) {
		switch( event.type ) {
			case SDL_KEYDOWN:
				key_event( &event.key, true );

				// Emulate copy/paste
				#if defined( __APPLE__ )
					#define KEYBOARD_COPY_PASTE_MODIFIER KMOD_GUI
				#else
					#define KEYBOARD_COPY_PASTE_MODIFIER KMOD_CTRL
				#endif
				
				if( event.key.keysym.sym == SDLK_c ) {
					if( event.key.keysym.mod & KEYBOARD_COPY_PASTE_MODIFIER ) {
						Key_CharEvent( KC_CTRLC, KC_CTRLC );
					}
				}
				else if( event.key.keysym.sym == SDLK_v ) {
					if( event.key.keysym.mod & KEYBOARD_COPY_PASTE_MODIFIER ) {
						Key_CharEvent( KC_CTRLV, KC_CTRLV );
					}
				}

				break;

			case SDL_KEYUP:
				key_event( &event.key, false );
				break;

			case SDL_TEXTINPUT:
				// SDL_iconv_utf8_ucs2 uses "UCS-2-INTERNAL" as tocode and fails to convert text on Linux
				// where SDL_iconv uses system iconv. So we force needed encoding directly

				#if SDL_BYTEORDER == SDL_LIL_ENDIAN
					#define UCS_2_INTERNAL "UCS-2LE"
				#else
					#define UCS_2_INTERNAL "UCS-2BE"
				#endif

				wtext = (Uint16 *)SDL_iconv_string( UCS_2_INTERNAL, "UTF-8", event.text.text, SDL_strlen( event.text.text ) + 1 );
				if( wtext ) {
					wchar_t charkey = wtext[0];
					int key = ( charkey <= 255 ) ? charkey : 0;
					Key_CharEvent( key, charkey );
					SDL_free( wtext );
				}
				break;

			case SDL_MOUSEMOTION:
				mouse_motion_event( &event.motion );
				break;

			case SDL_MOUSEBUTTONDOWN:
				mouse_button_event( &event.button, true );
				break;

			case SDL_MOUSEBUTTONUP:
				mouse_button_event( &event.button, false );
				break;

			case SDL_MOUSEWHEEL:
				mouse_wheel_event( &event.wheel );
				break;

			case SDL_QUIT:
				Cbuf_ExecuteText( EXEC_NOW, "quit" );
				break;

			case SDL_WINDOWEVENT:
				switch( event.window.event ) {
					case SDL_WINDOWEVENT_SHOWN:
						AppActivate( true );
						break;
					case SDL_WINDOWEVENT_HIDDEN:
						AppActivate( false );
						break;
					case SDL_WINDOWEVENT_CLOSE:
						break;
					case SDL_WINDOWEVENT_FOCUS_GAINED:
						input_focus = true;
						break;
					case SDL_WINDOWEVENT_FOCUS_LOST:
						input_focus = false;
						break;
					case SDL_WINDOWEVENT_MOVED:
						// FIXME: move this somewhere else
						Cvar_SetValue( "vid_xpos", event.window.data1 );
						Cvar_SetValue( "vid_ypos", event.window.data2 );
						vid_xpos->modified = false;
						vid_ypos->modified = false;
						break;
				}
				break;
		}
	}
}
Esempio n. 12
0
/////////////////////////////////////////////////////////////////////////////
// AppWndProc( hwnd, uiMessage, wParam, lParam )
//
// The window proc for the app's main (tiled) window.  This processes all
// of the parent window's messages.
//
LONG FAR PASCAL _export AppWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
    PAINTSTRUCT ps;
    HDC hdc;
    BOOL f;

		//is it the registered message?  (this proc is called after the creation
		//of the msgApp).

	 if (msg == msgApp) {				
 		 if (bShowRendering) {
		 	HDC hdc = GetDC(hwndApp);
		 	AppPaint(hwndApp, hdc);
		 	ReleaseDC(hwndApp, hdc);
		 	bShowRendering = (int)wParam;	//sent a 0 to turn off bShowRendering.
		 }
	    return 0L;
	 }
		
		//well, how about standard Windows messages?

    switch (msg)
    {
    case WM_CREATE:
			//let WM_SIZE do all the work.
	      break;

    case WM_ACTIVATEAPP:
		    bAppActive = (BOOL)wParam;
			wt_reset_input();
			// *** Remap the system colors and deal with the palette
			AppActivate(bAppActive);

			if (hpalApp)
			{
				HDC hdc = GetDC(hwnd);

				UnrealizeObject(hpalApp);
				SelectPalette(hdc, hpalApp, FALSE);
				RealizePalette(hdc);

				ReleaseDC(hwnd, hdc);
			}
			break;

    case WM_SIZE:			
			wt_reset_input();
		   nBitmapW = LOWORD(lParam);			//new size.
		   nBitmapH = HIWORD(lParam);

			nBitmapW /= StretchFactor;
			nBitmapH /= StretchFactor;

			//Windows DIBs, including WinG bitmaps, are always a multiple of 
			//32-bits wide.  For us, using the typical 8-bit per pixel bitmap,
			//that means we need to ensure the width is a multiple of 4.  This
			//is important because the WT engine treats a bitmap's width and 
			//pitch as one - there is no way for WT to draw into a bitmap
			//using a width different than the pitch.  So we force the bitmap's
			//width to be a multiple of 4, to be both Windows and WT compatible.
			//Note we could have patched WT to deal with the concept of a 
			//bitmap pitch, but that's too much change.

			nBitmapW = ((nBitmapW+3)/4)*4;

			if(Buffer)
			{						//resizing, minimizing, maximizing.
			 	HBITMAP hbm;
			   int Counter;

				//Create a new 8-bit WinGBitmap with the new size
				BufferHeader.Header.biWidth = nBitmapW;
				BufferHeader.Header.biHeight = nBitmapH * Orientation;

				//probably don't need to do this, but do it anyway.
			   for(Counter = 0;Counter < 256;Counter++) {
				    	BufferHeader.aColors[Counter].rgbRed   = ColorTable[Counter].rgbRed;
				    	BufferHeader.aColors[Counter].rgbGreen = ColorTable[Counter].rgbGreen;
				    	BufferHeader.aColors[Counter].rgbBlue  = ColorTable[Counter].rgbBlue;
				    	BufferHeader.aColors[Counter].rgbReserved = 0;
				}

				hbm = WinG.pCreateBitmap(Buffer,
					(BITMAPINFO *)&BufferHeader, &pBuffer);

				//  Select it in and delete the old one
				hbm = (HBITMAP)SelectObject(Buffer, hbm);
				DeleteObject(hbm);

   			PatBlt(Buffer, 0,0,nBitmapW,nBitmapH, BLACKNESS);

	         wt_set_fb_mem(pBuffer);		//tell WT about new bitmap address.
			   wt_reinit(nBitmapW,nBitmapH);  //and about new bitmap size.
				wt_render();					//and have WT render a frame.

			}
			else						//first time.
			{
				//  Create a new WinGDC and 8-bit WinGBitmap

				HBITMAP hbm;
			   int Counter;

				//  Get WinG to recommend the fastest DIB format

				if(WinG.pRecommendDIBFormat((BITMAPINFO *)&BufferHeader))
				{
					//  make sure it's 8bpp and remember the orientation

					BufferHeader.Header.biBitCount = 8;
					BufferHeader.Header.biCompression = BI_RGB;
					Orientation = BufferHeader.Header.biHeight;
					if (Orientation > 0) {
						DebugMsg("WT requires a top-down bitmap!\nYou are about to hit a brick wall at 90 MPH!");
						PostQuitMessage(1);		//works but slams palette.  bummer.
					}
				}
				else
				{
					//  set it up ourselves
	
					BufferHeader.Header.biSize = sizeof(BITMAPINFOHEADER);
					BufferHeader.Header.biPlanes = 1;
					BufferHeader.Header.biBitCount = 8;
					BufferHeader.Header.biCompression = BI_RGB;
					BufferHeader.Header.biSizeImage = 0;
					BufferHeader.Header.biClrUsed = 0;
					BufferHeader.Header.biClrImportant = 0;
				}

				BufferHeader.Header.biWidth = nBitmapW;
				BufferHeader.Header.biHeight = nBitmapH * Orientation;

//#define BAD_PALETTE_CODE
#ifdef BAD_PALETTE_CODE
//This code sets an incorrect palette, but at least you can still use
//regular windows tools.  Good for debugging.
			   HDC Screen;
			   RGBQUAD *pColorTable;

				//  create an identity palette from the DIB's color table

				//  get the 20 system colors as PALETTEENTRIES
    
			    Screen = GetDC(0);

			    GetSystemPaletteEntries(Screen,0,10,LogicalPalette.aEntries);
			    GetSystemPaletteEntries(Screen,246,10,
								LogicalPalette.aEntries + 246);

				ReleaseDC(0,Screen);

				// initialize the logical palette and DIB color table

			    for(Counter = 0;Counter < 10;Counter++)
			    {
			    	// copy the system colors into the DIB header
			    	// WinG will do this in WinGRecommendDIBFormat,
			    	// but it may have failed above so do it here anyway
			    	
			    	BufferHeader.aColors[Counter].rgbRed =
			    					LogicalPalette.aEntries[Counter].peRed;
			    	BufferHeader.aColors[Counter].rgbGreen =
			    					LogicalPalette.aEntries[Counter].peGreen;
			    	BufferHeader.aColors[Counter].rgbBlue =
			    					LogicalPalette.aEntries[Counter].peBlue;
			    	BufferHeader.aColors[Counter].rgbReserved = 0;

   					LogicalPalette.aEntries[Counter].peFlags = 0;

			    	BufferHeader.aColors[Counter + 246].rgbRed =
		    					LogicalPalette.aEntries[Counter + 246].peRed;
			    	BufferHeader.aColors[Counter + 246].rgbGreen =
		    					LogicalPalette.aEntries[Counter + 246].peGreen;
			    	BufferHeader.aColors[Counter + 246].rgbBlue =
		    					LogicalPalette.aEntries[Counter + 246].peBlue;
			    	BufferHeader.aColors[Counter + 246].rgbReserved = 0;

   					LogicalPalette.aEntries[Counter + 246].peFlags = 0;
   				}

            for (i=0; i<256; i++) {
               ColorTable[i].rgbRed = 0;
               ColorTable[i].rgbGreen = 0;
               ColorTable[i].rgbBlue = 0;
            }

            nColors = wt_load_palette();
            for (i=0; i<nColors; i++) {
               int r,g,b;
               wt_get_palette_entry(i,&r,&g,&b);
               ColorTable[i].rgbRed = r;
               ColorTable[i].rgbGreen = g;
               ColorTable[i].rgbBlue = b;
            }
            pColorTable = &ColorTable[0];

			    for(Counter = 10;Counter < 246;Counter++)
			    {
			    	// copy from the original color table to the WinGBitmap's
			    	// color table and the logical palette

			    	BufferHeader.aColors[Counter].rgbRed =
    					LogicalPalette.aEntries[Counter].peRed =
    						pColorTable[Counter].rgbRed;
			    	BufferHeader.aColors[Counter].rgbGreen =
    					LogicalPalette.aEntries[Counter].peGreen =
    						pColorTable[Counter].rgbGreen;
			    	BufferHeader.aColors[Counter].rgbBlue =
    					LogicalPalette.aEntries[Counter].peBlue =
    						pColorTable[Counter].rgbBlue;
			    	BufferHeader.aColors[Counter].rgbReserved = 0;
  					LogicalPalette.aEntries[Counter].peFlags = PC_NOCOLLAPSE;
			    }

			    hpalApp = CreatePalette((LOGPALETTE *)&LogicalPalette);
#else
//GOOD_PALETTE_CODE
//Working palette code.  Has correct colors. And identity.  Same frame
//rate as bad palette code.  This really hoses Windows colors, so
//a GUI debugger's windows are really hard to read.  I couldn't read the
//Symantec IDDE's windows - so I #ifdef'd the bad palette code in for
//debugging.
//Anyway, this code works.  Need 3 things for identity, as far as I can tell:
//1. you have to be writing to your bitmap using a specific palette, 
//2. this palette has to be made into a Windows palette, and selected.
//3. this palette has to be copied into the BitmapInfo header of the WinG
//   bitmap, before creating it (actually as a parameter to creating it).
//
				ClearSystemPalette();
				CreateWTPalette();

			    for(Counter = 0;Counter < 256;Counter++) {
				    	BufferHeader.aColors[Counter].rgbRed   = ColorTable[Counter].rgbRed;
				    	BufferHeader.aColors[Counter].rgbGreen = ColorTable[Counter].rgbGreen;
				    	BufferHeader.aColors[Counter].rgbBlue  = ColorTable[Counter].rgbBlue;
				    	BufferHeader.aColors[Counter].rgbReserved = 0;
				}
#endif
			    
				//  Create a WinGDC and Bitmap, then select away
				Buffer = WinG.pCreateDC();
				hbm = WinG.pCreateBitmap(Buffer,
					(BITMAPINFO *)&BufferHeader, &pBuffer);

				//  Store the old hbitmap to select back in before deleting
				gbmOldMonoBitmap = (HBITMAP)SelectObject(Buffer, hbm);

   			PatBlt(Buffer, 0,0,nBitmapW,nBitmapH, BLACKNESS);

            wt_set_fb_mem(pBuffer);		//hack to get around WT's code.
            strcpy(szDefaultWorldFileName, szModulePath);
            strcat(szDefaultWorldFileName, DEFAULT_WORLD_FILEPATH);
            wt_init(szDefaultWorldFileName, nBitmapW,nBitmapH); 
				AppSetCaption(DEFAULT_WORLD_FILETITLE);

            wt_render();
			}
			bWTinitialized = TRUE;		
            break;

		case WM_KEYDOWN:
						//set WT's keyboard array, then do a WT cycle.
				switch (wParam) {
					case VK_UP:
						kbPressed[kbUpArrow] = 1; break;
					case VK_DOWN:
						kbPressed[kbDownArrow] = 1; break;
					case VK_LEFT:
						kbPressed[kbLeftArrow] = 1; break;
					case VK_RIGHT:
						kbPressed[kbRightArrow] = 1; break;
					case VK_CONTROL:
						kbPressed[kbCtrl] = 1; break;
					case VK_ESCAPE:
						kbPressed[kbEsc] = 1; 
						//DestroyWindow() here?  let's check to ensure that func
						//  will send the proper msgs to close stuff.
						break;
					case VK_SPACE:
						kbPressed[kbSpace] = 1; break;
					case VK_SHIFT:
						kbPressed[kbLeftShift] = 1; break;
					case VK_TAB:
						kbPressed[kbAlt] = 1; break;
				}

					//tried using wt_input/wt_render/InvalidateRect sequence
					//here, but was sometimes jerky (missed frames, actually), 
					//if there was too much keyboard activity.  
					//I think windows was collapsing queued/pending
					//WM_PAINT messages, so that the app got one instead of a 
					//sudden stream.  Anyhow now I draw immediately, and it works
					//great.  Note that AppIdle() processing is required to
					//have acceleration/deceleration/monsters/events occur without
					//keyboard input.  I guess a timer could also be used.
					//So I ended up using this helper routine to repaint.

				AppDoCycle();
				break;

		case WM_KEYUP:
						//set WT's keyboard array, then do a WT cycle.
				switch (wParam) {
					case VK_UP:
						kbPressed[kbUpArrow] = 0; break;
					case VK_DOWN:
						kbPressed[kbDownArrow] = 0; break;
					case VK_LEFT:
						kbPressed[kbLeftArrow] = 0; break;
					case VK_RIGHT:
						kbPressed[kbRightArrow] = 0; break;
					case VK_CONTROL:
						kbPressed[kbCtrl] = 0; break;
					case VK_ESCAPE:
						kbPressed[kbEsc] = 0; break;
					case VK_SPACE:
						kbPressed[kbSpace] = 0; break;
					case VK_SHIFT:
						kbPressed[kbLeftShift] = 0; break;
					case VK_TAB:
						kbPressed[kbAlt] = 0; break;
				}

				AppDoCycle();
				break;

		case WM_LBUTTONDOWN:
				break;

		case WM_RBUTTONDOWN:
				break;

      case WM_MOUSEMOVE:
        	break;

      case WM_COMMAND:
            return AppCommand(hwnd,msg,wParam,lParam);

		case WM_DESTROY:
            PostQuitMessage(0);
            break;

      case WM_CLOSE:
		 	   break;

      case WM_PALETTECHANGED:
		    	if ((HWND)wParam == hwnd)
					break;

	    // fall through to WM_QUERYNEWPALETTE

		case WM_QUERYNEWPALETTE:
		    hdc = GetDC(hwnd);

		    if (hpalApp)
				SelectPalette(hdc, hpalApp, FALSE);
	
		    f = RealizePalette(hdc);
		    ReleaseDC(hwnd,hdc);
	
		    if (f)
				InvalidateRect(hwnd,NULL,TRUE);
	
		    return f;
	
	     case WM_PAINT:
		    hdc = BeginPaint(hwnd,&ps);
			 SelectPalette(hdc, hpalApp, FALSE);
			 RealizePalette(hdc);
		    AppPaint (hwnd,hdc);
	       EndPaint(hwnd,&ps);
	       return 0L;
	    }
	return DefWindowProc(hwnd,msg,wParam,lParam);
}
Esempio n. 13
0
LONG CALLBACK AppWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
/****************************************************************************
*
* Function:     AppWndProc
*
* Description:  Main window proc for application.
*
****************************************************************************/
{
    PAINTSTRUCT ps;
    HDC         hdc;

    switch (msg) {
        case WM_ACTIVATEAPP:
            fAppActive = (BOOL)wParam;
            if (!includeStatic) {
                AppActivate(fAppActive);
                }
            break;
        case WM_COMMAND:
            switch (wParam) {
                case MENU_OPEN:
                    OpenBitmapFile(hwnd);
                    break;
                case MENU_ABOUT:
                    DialogBox(hInstApp,"AppAbout",hwnd,(DLGPROC)AppAbout);
                    break;
                case MENU_EXIT:
                    PostMessage(hwnd,WM_CLOSE,0,0L);
                    break;
                case MENU_STRETCH_TOWINDOW:
                    stretchBlt = !stretchBlt;
                    CheckMenuItems(hwnd);
                    InvalidateRect(hwnd, NULL, FALSE);
                    break;
                case MENU_STATIC_COLORS:
                    if (includeStatic) {
                        /* Enable use of static colors */
                        includeStatic = false;
                        AppActivate(true);
                        }
                    else {
                        /* Remap the system colors to normal */
                        includeStatic = true;
                        AppActivate(false);
                        }
                    CheckMenuItems(hwnd);

                    /* Rebuild the MGL device context to re-build the
                     * palette for the loaded bitmap.
                     */
                    CreateMGLDeviceContexts(hwnd);
                    InvalidateRect(hwnd, NULL, FALSE);
                    break;
                case MENU_ANIMATE_PALETTE:
                    animatePalette = !animatePalette;
                    CheckMenuItems(hwnd);
                    break;
                }
            return 0;
        case WM_CREATE:
            CreateMGLDeviceContexts(hwnd);
            break;
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
        case WM_PALETTECHANGED:
            if ((HWND)wParam == hwnd)
                break;
            /* Fall through to WM_QUERYNEWPALETTE */
        case WM_QUERYNEWPALETTE:
            if (winDC && memDC) {
                LoadBitmapPalette(winDC,memDC);
                InvalidateRect(hwnd,NULL,TRUE);
                return 1;
                }
            return 0;
        case WM_PAINT:
            if (!winDC)
                break;
            hdc = BeginPaint(hwnd,&ps);
            PatBlt(hdc,0,0,MGL_sizex(winDC)+1,MGL_sizey(winDC)+1,WHITENESS);
            if (memDC) {
                if (stretchBlt) {
                    MGL_stretchBltCoord(winDC,memDC,
                        0,0,MGL_sizex(memDC)+1,MGL_sizey(memDC)+1,
                        0,0,MGL_sizex(winDC)+1,MGL_sizey(winDC)+1,MGL_REPLACE_MODE);
                    }
                else {
                    MGL_bitBltCoord(winDC,memDC,
                        0,0,MGL_sizex(memDC)+1,MGL_sizey(memDC)+1,
                        0,0,MGL_REPLACE_MODE);
                    }
                }
            EndPaint(hwnd,&ps);
            return 0;
        }
    return DefWindowProc(hwnd,msg,wParam,lParam);
}