00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "KeosWin32Window.h"
00023 #include "KeosOGLException.h"
00024 #include "KeosLogger.h"
00025 #include "KeosConsole.h"
00026
00027 namespace Keos
00028 {
00029
00030
00031
00032
00033
00034
00035 CWin32Window::CWin32Window()
00036 {
00037 m_bIsFullScreen = false;
00038 m_HWnd = 0;
00039 m_bActive = false;
00040 m_bReady = false;
00041 m_bClosed = false;
00042 }
00043
00044
00045 CWin32Window::~CWin32Window()
00046 {
00047 Destroy();
00048 }
00049
00050
00051 void CWin32Window::Create(const String& strName, uint nWidth, uint nHeight, uint nColourDepth, bool bFullScreen)
00052 {
00053 HWND parentHWnd = 0;
00054 HWND externalHandle = 0;
00055 HINSTANCE hInst = GetModuleHandle(KEOS_OGL_LIB);
00056 bool bVsync = false;
00057 uint nDisplayFrequency = 0;
00058 String strTitle = strName;
00059 uint nLeft = 0;
00060 uint nTop = 0;
00061 bool bDepthBuffer = true;
00062
00063
00064 if ( m_HWnd )
00065 Destroy();
00066
00067 if (bFullScreen)
00068 {
00069 m_nColourDepth = nColourDepth;
00070 }
00071 else
00072 {
00073
00074 m_nColourDepth = GetDeviceCaps(GetDC(0), BITSPIXEL);
00075 }
00076
00077 if (!externalHandle)
00078 {
00079 DWORD dwStyle = (bFullScreen ? WS_POPUP : WS_OVERLAPPEDWINDOW) | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
00080 RECT rc;
00081
00082 m_nWidth = nWidth;
00083 m_nHeight = nHeight;
00084
00085 if (!bFullScreen)
00086 {
00087
00088 SetRect(&rc, 0, 0, m_nWidth, m_nHeight);
00089 AdjustWindowRect(&rc, dwStyle, false);
00090 m_nWidth = rc.right - rc.left;
00091 m_nHeight = rc.bottom - rc.top;
00092
00093
00094 if (m_nWidth > (unsigned)GetSystemMetrics(SM_CXSCREEN))
00095 m_nWidth = (unsigned)GetSystemMetrics(SM_CXSCREEN);
00096 if (m_nHeight > (unsigned)GetSystemMetrics(SM_CYSCREEN))
00097 m_nHeight = (unsigned)GetSystemMetrics(SM_CYSCREEN);
00098
00099 if (!nLeft)
00100 {
00101 m_nLeft = (GetSystemMetrics(SM_CXSCREEN) / 2) - (m_nWidth / 2);
00102 }
00103 else
00104 {
00105 m_nLeft = nLeft;
00106 }
00107 if (!nTop)
00108 {
00109 m_nTop = (GetSystemMetrics(SM_CYSCREEN) / 2) - (m_nHeight / 2);
00110 }
00111 else
00112 {
00113 m_nTop = nTop;
00114 }
00115 }
00116 else
00117 {
00118 m_nTop = m_nLeft = 0;
00119 }
00120
00121
00122 WNDCLASS wndClass =
00123 {
00124 CS_HREDRAW | CS_VREDRAW, WndProc, 0, 4, hInst,
00125 LoadIcon( NULL, IDI_APPLICATION ),
00126 LoadCursor( NULL, IDC_ARROW ),
00127 (HBRUSH)GetStockObject( BLACK_BRUSH ), NULL,
00128 TEXT(strTitle.c_str())
00129 };
00130 RegisterClass( &wndClass );
00131
00132
00133
00134 HWND hWnd = CreateWindowEx(bFullScreen ? WS_EX_TOPMOST : 0, TEXT(strTitle.c_str()), TEXT(strTitle.c_str()),
00135 dwStyle, m_nLeft, m_nTop, m_nWidth, m_nHeight, 0L, 0L, hInst, this);
00136 m_HWnd = hWnd;
00137
00138 GetClientRect(m_HWnd, &rc);
00139 m_nWidth = rc.right;
00140 m_nHeight = rc.bottom;
00141
00142 if (bFullScreen)
00143 {
00144 DEVMODE DevMode;
00145 DevMode.dmSize = sizeof(DevMode);
00146 DevMode.dmBitsPerPel = m_nColourDepth;
00147 DevMode.dmPelsWidth = m_nWidth;
00148 DevMode.dmPelsHeight = m_nHeight;
00149 DevMode.dmDisplayFrequency = nDisplayFrequency;
00150 DevMode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY;
00151 if (ChangeDisplaySettings(&DevMode, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)
00152 ILogger::Log("WARNING - ChangeDisplaySettings error");
00153 }
00154 }
00155 else
00156 {
00157 m_HWnd = externalHandle;
00158 RECT rc;
00159 GetClientRect(m_HWnd, &rc);
00160 m_nWidth = rc.right;
00161 m_nHeight = rc.bottom;
00162 m_nLeft = rc.left;
00163 m_nTop = rc.top;
00164 }
00165
00166 ShowWindow(m_HWnd, SW_SHOWNORMAL);
00167 UpdateWindow(m_HWnd);
00168
00169 m_strName = strName;
00170 m_bIsDepthBuffered = bDepthBuffer;
00171 m_bIsFullScreen = bFullScreen;
00172
00173 HDC hdc = GetDC(m_HWnd);
00174
00175 ILogger::Log("Created CWin32Window '%s' : %dx%d, %dbpp",
00176 m_strName.c_str(), m_nWidth, m_nHeight, m_nColourDepth);
00177
00178 PIXELFORMATDESCRIPTOR pfd = {
00179 sizeof(PIXELFORMATDESCRIPTOR),
00180 1,
00181 PFD_DRAW_TO_WINDOW |
00182 PFD_SUPPORT_OPENGL |
00183 PFD_DOUBLEBUFFER,
00184 PFD_TYPE_RGBA,
00185 m_nColourDepth,
00186 0, 0, 0, 0, 0, 0,
00187 0,
00188 0,
00189 0,
00190 0, 0, 0, 0,
00191 32,
00192 8,
00193 0,
00194 PFD_MAIN_PLANE,
00195 0,
00196 0, 0, 0};
00197
00198 int nPixelFormat = ChoosePixelFormat(hdc, &pfd);
00199 if (!nPixelFormat)
00200 OGL_EXCEPT("ChoosePixelFormat", "CWin32Window::Create");
00201
00202 if (!SetPixelFormat(hdc, nPixelFormat, &pfd))
00203 OGL_EXCEPT("SetPixelFormat", "CWin32Window::Create");
00204
00205 HGLRC glrc = wglCreateContext(hdc);
00206 if (!glrc)
00207 OGL_EXCEPT("wglCreateContext", "CWin32Window::Create");
00208 if (!wglMakeCurrent(hdc, glrc))
00209 OGL_EXCEPT("wglMakeCurrent", "CWin32Window::Create");
00210
00211 m_Glrc = glrc;
00212 m_HDC = hdc;
00213
00215
00216
00217
00218
00219
00220
00221 m_bReady = true;
00222 }
00223
00224
00225 void CWin32Window::Destroy(void)
00226 {
00227
00228
00229 if (m_Glrc)
00230 {
00231 wglMakeCurrent(NULL, NULL);
00232 wglDeleteContext(m_Glrc);
00233 m_Glrc = NULL;
00234 }
00235 if (m_HDC)
00236 {
00237 ReleaseDC(m_HWnd, m_HDC);
00238 m_HDC = NULL;
00239 }
00240 if (m_bIsFullScreen)
00241 {
00242 ChangeDisplaySettings(NULL, 0);
00243 }
00244 DestroyWindow(m_HWnd);
00245 m_bActive = false;
00246 }
00247
00248
00249 bool CWin32Window::IsClosed() const
00250 {
00251 return m_bClosed;
00252 }
00253
00254
00255 void CWin32Window::Reposition(int left, int top)
00256 {
00258 }
00259
00260
00261 void CWin32Window::Resize(uint nWidth, uint nHeight)
00262 {
00263 m_nWidth = nWidth;
00264 m_nHeight = nHeight;
00265
00267 }
00268
00269
00270 void CWin32Window::WindowMovedOrResized()
00271 {
00272 RECT temprect;
00273 ::GetClientRect(GetWindowHandle(), &temprect);
00274 Resize(temprect.right - temprect.left, temprect.bottom - temprect.top);
00275 }
00276
00277
00278 void CWin32Window::SwapBuffers(bool bWaitForVSync)
00279 {
00280 ::SwapBuffers((HDC)m_HDC);
00281 }
00282
00283
00284 LRESULT CWin32Window::WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
00285 {
00286 CWin32Window* win;
00287
00288
00289 if ( WM_CREATE != uMsg )
00290 win = (CWin32Window*)GetWindowLong( hWnd, 0 );
00291
00292 switch ( uMsg )
00293 {
00294 case WM_ACTIVATE:
00295 if ( WA_INACTIVE == LOWORD( wParam ) )
00296 win->m_bActive = false;
00297 else
00298 win->m_bActive = true;
00299 break;
00300
00301 case WM_CREATE:
00302 {
00303
00304
00305 LPCREATESTRUCT lpcs = (LPCREATESTRUCT)lParam;
00306 win = (CWin32Window*)(lpcs->lpCreateParams);
00307
00308 SetWindowLong( hWnd, 0, (long)win );
00309 win->m_bActive = true;
00310
00311 return 0;
00312 }
00313 break;
00314
00315 case WM_PAINT:
00316
00317
00318
00319 if ( win->m_bActive && win->m_bReady )
00320 win->Update();
00321 break;
00322
00323 case WM_MOVE:
00324
00325
00326
00327 break;
00328
00329 case WM_ENTERSIZEMOVE:
00330
00331 win->m_bReady = false;
00332 break;
00333
00334 case WM_EXITSIZEMOVE:
00335 win->WindowMovedOrResized();
00336 win->m_bReady = true;
00337 break;
00338
00339 case WM_SIZE:
00340
00341
00342 if ( SIZE_MAXHIDE == wParam || SIZE_MINIMIZED == wParam )
00343 win->m_bActive = false;
00344 else
00345 {
00346 win->m_bActive = true;
00347 if ( win->m_bReady )
00348 win->WindowMovedOrResized();
00349 }
00350 break;
00351
00352 case WM_GETMINMAXINFO:
00353
00354 ((MINMAXINFO*)lParam)->ptMinTrackSize.x = 100;
00355 ((MINMAXINFO*)lParam)->ptMinTrackSize.y = 100;
00356 break;
00357
00358
00359 case WM_KEYDOWN:
00360 switch (wParam)
00361 {
00362 case VK_ESCAPE :
00363 win->m_bClosed = true;
00364 break;
00365 case VK_F1 :
00366 CConsole::Instance().Enable(true);
00367 break;
00368 case VK_F2 :
00369 CConsole::Instance().Enable(false);
00370 break;
00371 }
00372 break;
00373
00374 case WM_CHAR :
00375 CConsole::Instance().SendChar(static_cast<char>(LOWORD(wParam)));
00376 return 0;
00377
00378 case WM_CLOSE:
00379 DestroyWindow( win->m_HWnd );
00380 win->m_bClosed = true;
00381 return 0;
00382 }
00383
00384 return DefWindowProc( hWnd, uMsg, wParam, lParam );
00385 }
00386
00387 }