bool CGraphics::InitWindow(const int &iWidth, const int &iHeight, const bool &bWindowed) { // Inicializamos las variables miembro de la clase m_bIsWindowed = bWindowed; m_iWidth = iWidth; m_iHeight = iHeight; DWORD dwWindowStyle; // Damos el estilo de la ventana dependiendo si es // en modo ventana o pantalla completa if (m_bIsWindowed) dwWindowStyle = WS_OVERLAPPEDWINDOW | WS_VISIBLE; else dwWindowStyle = WS_POPUP | WS_VISIBLE; WNDCLASSEX wc; ZeroMemory(&wc, sizeof(WNDCLASSEX)); // Configuramos las propiedades de la ventana wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.cbSize = sizeof(WNDCLASSEX); wc.hbrBackground = (HBRUSH)NULL; wc.hCursor = LoadCursor(g_hInstance, IDC_ARROW); wc.hInstance = g_hInstance; wc.lpfnWndProc = WindowProc; wc.lpszClassName = L"LMADGameEngine"; wc.lpszMenuName = NULL; wc.style = CS_OWNDC; // Registramos la ventana para que el sistema operativo // tenga conocimiento de ella RegisterClassEx(&wc); // Creamos la ventana en memoria m_hWnd = CreateWindowEx( NULL, L"LMADGameEngine", g_wStrWindowTitle, dwWindowStyle, CW_USEDEFAULT, CW_USEDEFAULT, m_iWidth, m_iHeight, NULL, NULL, g_hInstance, NULL); // Inicializamos Direct3D if (!InitGraphicsMode()) return false; // Voila! ShowWindow(m_hWnd, g_nCmdShow); return true; }
GlobalGraphicsHack() : bmp(1, 1, PixelFormat32bppARGB), gfx(&bmp) { InitGraphicsMode(&gfx); }
// Should be called from WM_PAINT. Recursively paints a given window and // all its children. Control must be the top-level window associated // with HWND. // Note: maybe should be split into BeginPaint()/Paint()/EndPaint() // calls so that the caller can do more drawing after Paint() void Painter::Paint(HWND hwnd, bool isDirty) { CrashAlwaysIf(hwnd != wnd->hwndParent); PAINTSTRUCT ps; HDC dc = BeginPaint(hwnd, &ps); Region clip; // TODO: be intelligent about only repainting changed // parts for perf. Note: if cacheBmp changes, we need // to repaint everything Graphics gDC(dc); gDC.GetClip(&clip); ClientRect r(hwnd); // TODO: fix showing black parts when resizing a window. // my theory is that we see black background on right/bottom // of the window when we resize the window because the os paints // it black and we take too long to perform the whole paint so the // black part persists long enough for human eye to notice. // To fix that we could try to paint the black part immediately // to gDC using the same color as the background. This is problematic // for two reasons: // - I don't know which part exactly needs to be repainted // - it can be tricky if background is a gradient // I thought I could just do PaintBackground(&gDC, Rect(0, 0, r.dx, r.dy)) // but that generates flickr which leads me to believe that either // Graphics::FillRectangle() ignores clip region or clip region is not set // properly. Current solution detects a resize, paints a background and the // last version of page, which somewhat eliminates the problem but also // sometimes causes flickr // See http://www.catch22.net/tuts/flicker for info on win repainting if (cacheBmp && !sizeDuringLastPaint.Equals(Size(r.dx, r.dy))) { PaintBackground(&gDC, Rect(0, 0, r.dx, r.dy)); gDC.DrawImage(cacheBmp, 0, 0); sizeDuringLastPaint = Size(r.dx, r.dy); } if (BitmapNotBigEnough(cacheBmp, r.dx, r.dy)) { ::delete cacheBmp; cacheBmp = ::new Bitmap(r.dx, r.dy, &gDC); isDirty = true; } //TODO: log clipBounds for debugging //Rect clipBounds; //clip.GetBounds(&cliBounds) // draw to a bitmap cache unless we were asked to skip // this step and just blit cached bitmap because the caller // knows it didn't change if (isDirty) { Graphics g((Image*)cacheBmp); InitGraphicsMode(&g); g.SetClip(&clip, CombineModeReplace); PaintBackground(&g, Rect(0, 0, r.dx, r.dy)); PaintWindowsInZOrder(&g, wnd); } // TODO: try to manually draw only the part that falls within // clipBounds or is it done automatically by DrawImage() ? gDC.DrawImage(cacheBmp, 0, 0); EndPaint(hwnd, &ps); }