// // ‘”Ќ ÷»я: WndProc(HWND, UINT, WPARAM, LPARAM) // // Ќј«Ќј„≈Ќ»≈: обрабатывает сообщени¤ в главном окне. // // WM_COMMAND Ч обработать меню приложени¤ // WM_PAINT Ч отрисовать главное окно // WM_DESTROY Ч отправить сообщение о выходе и вернутьс¤ // // LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { HWND edit; switch (message) { case WM_COMMAND: { int wmId = LOWORD(wParam); // –азобрать выбор в меню: switch (wmId) { case IDM_ABOUT: DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About); break; case IDM_EXIT: DestroyWindow(hWnd); break; case ID_BUTTON_MOVE: if (HIWORD(wParam) == BN_CLICKED) { edit = GetDlgItem(hWnd,ID_EDIT_MOVEX); TCHAR X[5]; TCHAR Y[5]; GetWindowText(edit, X, 5); edit = GetDlgItem(hWnd, ID_EDIT_MOVEY); GetWindowText(edit, Y, 5); if (wcslen(X) != 0 && wcslen(Y) != 0) { moveClock(_wtof(X),_wtof(Y)); InvalidateRect(hWnd, 0, true); } } break; case ID_BUTTON_SCALE: if (HIWORD(wParam) == BN_CLICKED) { TCHAR prop[5]; TCHAR X[5]; TCHAR Y[5]; edit = GetDlgItem(hWnd, ID_EDIT_SCALEPROPORTIONS); GetWindowText(edit, prop, 5); edit = GetDlgItem(hWnd, ID_EDIT_SCALEX); GetWindowText(edit, X, 5); edit = GetDlgItem(hWnd, ID_EDIT_SCALEY); GetWindowText(edit, Y, 5); if (wcslen(prop) != 0 && wcslen(X) != 0 && wcslen(Y) != 0) { scaleClock(_wtof(prop), _wtof(X), _wtof(Y)); InvalidateRect(hWnd, 0, true); } } break; case ID_BUTTON_ROTATE: if (HIWORD(wParam) == BN_CLICKED) { TCHAR X[5]; TCHAR Y[5]; TCHAR A[5]; edit = GetDlgItem(hWnd, ID_EDIT_ROTATEX); GetWindowText(edit, X, 5); edit = GetDlgItem(hWnd, ID_EDIT_ROTATEY); GetWindowText(edit, Y, 5); edit = GetDlgItem(hWnd, ID_EDIT_ROTATEANGLE); GetWindowText(edit, A, 5); if (wcslen(X) != 0 && wcslen(Y) != 0 && wcslen(A) != 0) { rotateClock(_wtof(X), _wtof(Y), (_wtof(A) / 180.0)*3.14); InvalidateRect(hWnd, 0, true); } } break; case ID_BUTTON_RESET: if (HIWORD(wParam) == BN_CLICKED) { reset(); InvalidateRect(hWnd, 0, true); } break; default: return DefWindowProc(hWnd, message, wParam, lParam); } } break; case WM_PAINT: { PAINTSTRUCT ps; HDC hdc = BeginPaint(hWnd, &ps); draw(hdc); EndPaint(hWnd, &ps); } break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; }
void demo(MGLDC *dc) { int numpages,aPage,vPage; int sizex,sizey,bits; rect_t fullView,oldView; pixel_format_t pf; palette_t pal[256]; MGLDC *memdc; /* The first way to do simple page flipping is using two display * pages for 'double' buffering. The MGL has functions to set the * system into double buffered modes and flip pages for you, so * this method is very easy. We use MGL_doubleBuffer() to change * to double buffered mode and MGL_swapBuffers() to change display * pages. */ if (!MGL_doubleBuffer(dc)) MGL_fatalError("Double buffereing not available!"); mainWindow(dc,"Page Flip Demo"); statusLine("Method 1: Double buffering with two pages"); MGL_swapBuffers(dc,true); /* Draw to the hidden page */ mainWindow(dc,"Page Flip Demo"); statusLine("Method 1: Double buffering with two pages"); initAnimation(); do { /* Clear the entire display device before drawing the next frame */ MGL_clearViewport(); /* Draw the clock at the current location and move it */ drawClock(); moveClock(); /* Swap the display buffers */ MGL_swapBuffers(dc,true); } while (!checkEvent()); waitEvent(); /* Return to single buffered mode */ MGL_singleBuffer(dc); /* The second way to use page flipping is with multiple display * pages (3+) to do multi-buffering. Because we are using multiple * display pages, we can turn off the wait for retrace flag when we * swap visual pages. In order for triple buffering to work properly, * we need to be doing a complete re-paint of the screen each frame * without doing a screen clear (otherwise you will see flicker). * Games like Quake and Duke3D repaint the entire frame from top to * bottom without any overdraw, which allows them to use triple * buffering techniques like this. We simulate this here by rendering * to a system buffer and blitting to the screen constantly to achieve * a similar effect for this sample program. * * Note that VBE/Core 3.0 and VBE/AF 2.0 include full support for * hardware triple buffering that can be used to eliminate this problem. * When these standards are ratified, the MGL will be updated to support * this and you will be able to do 'real' triple buffering without * any flicker on the screen. */ numpages = MGL_maxPage(dc)+1; if (numpages < 3) return; /* Get the display device size, color depth and pixel format so that we * can create a compatible memory device context. Note that we also * need to copy the palette from the display DC to the memory DC. */ sizex = MGL_sizex(dc); sizey = MGL_sizey(dc); bits = MGL_getBitsPerPixel(dc); MGL_getPixelFormat(dc,&pf); if ((memdc = MGL_createMemoryDC(sizex+1,sizey+1,bits,&pf)) == NULL) MGL_fatalError(MGL_errorMsg(MGL_result())); if (bits == 8) { MGL_getPalette(dc,pal,256,0); MGL_setPalette(memdc,pal,256,0); MGL_realizePalette(memdc,256,0,true); } MGL_makeCurrentDC(memdc); /* Make the fullViewport for the display DC the full screen, as the * above code has changed it to a smaller value. */ fullView.left = 0; fullView.top = 0; fullView.right = sizex+1; fullView.bottom = sizey+1; MGL_setViewportDC(dc,fullView); /* Draw the main window display on the memory buffer */ mainWindow(memdc,"Page Flip Demo"); statusLine("Method 2: Multi-buffering with 3+ pages"); initAnimation(); MGL_setActivePage(dc,aPage = 1); MGL_setVisualPage(dc,vPage = 0,false); MGL_getViewport(&oldView); do { /* Clear the fullViewport before drawing the next frame */ MGL_clearViewport(); /* Draw the clock at the current location and move it */ drawClock(); moveClock(); /* Copy the memory device to the display device */ MGL_setViewport(fullView); MGL_bitBlt(dc,memdc,fullView,0,0,MGL_REPLACE_MODE); MGL_setViewport(oldView); /* Swap the hardware display buffers */ aPage = (aPage+1) % numpages; vPage = (vPage+1) % numpages; MGL_setActivePage(dc,aPage); MGL_setVisualPage(dc,vPage,false); } while (!checkEvent()); waitEvent(); }