#include "mungal4.h" #pragma hdrstop #include "l4mfdview.h" namespace { const char mfdViewClass[] = "RPMFDView"; const char mfdViewProp[] = "RPMFDViewBlit"; struct MFDViewBlit { BITMAPINFOHEADER header; void *pixels; int sourceWidth; int sourceHeight; }; LRESULT CALLBACK MFDViewWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_PAINT: { PAINTSTRUCT ps; HDC hdc = BeginPaint(hwnd, &ps); const MFDViewBlit *blit = (const MFDViewBlit *) GetPropA(hwnd, mfdViewProp); if (blit != NULL && blit->pixels != NULL) { RECT client; GetClientRect(hwnd, &client); SetStretchBltMode(hdc, COLORONCOLOR); StretchDIBits( hdc, 0, 0, client.right, client.bottom, 0, 0, blit->sourceWidth, blit->sourceHeight, blit->pixels, (const BITMAPINFO *) &blit->header, DIB_RGB_COLORS, SRCCOPY ); } EndPaint(hwnd, &ps); } return 0; case WM_CLOSE: // Part of the cockpit; just hide it. ShowWindow(hwnd, SW_HIDE); return 0; case WM_ERASEBKGND: return 1; } return DefWindowProcA(hwnd, message, wParam, lParam); } } MFDSplitView::MFDSplitView( const char *title, int source_width, int source_height, int client_width, int client_height, int x, int y ) { Check_Pointer(this); sourceWidth = source_width; sourceHeight = source_height; pixels = new unsigned long[source_width * source_height]; memset(pixels, 0, source_width * source_height * sizeof(unsigned long)); MFDViewBlit *blit = new MFDViewBlit; memset(blit, 0, sizeof(MFDViewBlit)); blit->header.biSize = sizeof(BITMAPINFOHEADER); blit->header.biWidth = source_width; blit->header.biHeight = -source_height; // top-down blit->header.biPlanes = 1; blit->header.biBitCount = 32; blit->header.biCompression = BI_RGB; blit->pixels = pixels; blit->sourceWidth = source_width; blit->sourceHeight = source_height; blitInfo = blit; HINSTANCE instance = GetModuleHandleA(NULL); static Logical class_registered = False; if (!class_registered) { class_registered = True; WNDCLASSA window_class; memset(&window_class, 0, sizeof(window_class)); window_class.style = CS_HREDRAW | CS_VREDRAW; window_class.lpfnWndProc = MFDViewWndProc; window_class.hInstance = instance; window_class.hCursor = LoadCursor(NULL, IDC_ARROW); window_class.hbrBackground = (HBRUSH) GetStockObject(BLACK_BRUSH); window_class.lpszClassName = mfdViewClass; RegisterClassA(&window_class); } DWORD style = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX; RECT bounds; bounds.left = 0; bounds.top = 0; bounds.right = client_width; bounds.bottom = client_height; AdjustWindowRect(&bounds, style, FALSE); window = CreateWindowExA( 0, mfdViewClass, title, style, x, y, bounds.right - bounds.left, bounds.bottom - bounds.top, NULL, NULL, instance, NULL ); if (window != NULL) { SetPropA((HWND) window, mfdViewProp, blitInfo); ShowWindow((HWND) window, SW_SHOWNOACTIVATE); } else { DEBUG_STREAM << "MFDSplitView: window creation failed (" << title << ")\n" << std::flush; } } MFDSplitView::~MFDSplitView() { Check_Pointer(this); if (window != NULL) { RemovePropA((HWND) window, mfdViewProp); DestroyWindow((HWND) window); window = NULL; } delete (MFDViewBlit *) blitInfo; blitInfo = NULL; delete [] pixels; pixels = NULL; } Logical MFDSplitView::TestInstance() const { return pixels != NULL; } void MFDSplitView::Repaint() { Check_Pointer(this); if (window != NULL) { InvalidateRect((HWND) window, NULL, FALSE); } }