Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381
// ------------------------------------------------------------------// Windows 2000 Graphics API Black Book// Chapter 1 - Listing 1.5 (StretchBlt Zooming Demo)//// Created by Damon Chandler <dmc27@ee.cornell.edu>// Updates can be downloaded at: <www.coriolis.com>//// Please do not hesistate to e-mail me at dmc27@ee.cornell.edu// if you have any questions about this code.// ------------------------------------------------------------------
// Modified by Aleksey Bragin (aleksey at studiocerebral.com)// to support non-uniform scaling, and output via sretchdibits// (type something in the command line to invoke this mode,// in future it will be source BPP)
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>#include <windows.h>#include <stdio.h>//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
HWND HListBox = NULL;HWND VListBox = NULL;const int ID_LISTBOX = 101;const int ID_LISTBOX2 = 102;BOOL useDIBits=FALSE; // How to display the image - via StretchDIBits
HINSTANCE HInst;HINSTANCE HPrevInst;TCHAR *cmdline;const char* WndClassName = "GMainWnd";LRESULT CALLBACK MainWndProc(HWND HWnd, UINT Msg, WPARAM WParam, LPARAM LParam);
int APIENTRY WinMain(HINSTANCE HInstance, HINSTANCE HPrevInstance, LPTSTR lpCmdLine, int nCmdShow){ HInst = HInstance; HPrevInst = HPrevInstance; cmdline = lpCmdLine;
WNDCLASS wc; memset(&wc, 0, sizeof(WNDCLASS));
wc.style = CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS; wc.lpfnWndProc = MainWndProc; wc.hInstance = HInstance; wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = reinterpret_cast<HBRUSH>(COLOR_BTNFACE + 1); wc.lpszClassName = WndClassName;
if (RegisterClass(&wc)) { HWND HWnd = CreateWindow(WndClassName, TEXT("StretchBlt NonUniform Zooming Demo"), WS_OVERLAPPEDWINDOW | WS_CAPTION | WS_VISIBLE | WS_CLIPSIBLINGS, 0, 0, 675, 560, NULL, NULL, HInst, NULL);
if (HWnd) { HListBox = CreateWindowEx(WS_EX_CLIENTEDGE, "LISTBOX", "", LBS_NOTIFY | WS_CHILD | WS_VISIBLE, 530, 5, 130, 150, HWnd, reinterpret_cast<HMENU>(ID_LISTBOX), HInst, NULL); VListBox = CreateWindowEx(WS_EX_CLIENTEDGE, "LISTBOX", "", LBS_NOTIFY | WS_CHILD | WS_VISIBLE, 530, 5+170, 130, 150, HWnd, reinterpret_cast<HMENU>(ID_LISTBOX2), HInst, NULL);
if (HListBox && VListBox) {// horizontal zoom SNDMSG(HListBox, LB_ADDSTRING, 0, reinterpret_cast<LPARAM>("Zoom 25%")); SNDMSG(HListBox, LB_ADDSTRING, 0, reinterpret_cast<LPARAM>("Zoom 50%")); SNDMSG(HListBox, LB_ADDSTRING, 0, reinterpret_cast<LPARAM>("Zoom 75%")); SNDMSG(HListBox, LB_ADDSTRING, 0, reinterpret_cast<LPARAM>("Zoom 100%")); SNDMSG(HListBox, LB_ADDSTRING, 0, reinterpret_cast<LPARAM>("Zoom 125%")); SNDMSG(HListBox, LB_ADDSTRING, 0, reinterpret_cast<LPARAM>("Zoom 150%")); SNDMSG(HListBox, LB_ADDSTRING, 0, reinterpret_cast<LPARAM>("Zoom 200%")); SNDMSG(HListBox, LB_ADDSTRING, 0, reinterpret_cast<LPARAM>("Zoom 300%"));// vertical zoom SNDMSG(VListBox, LB_ADDSTRING, 0, reinterpret_cast<LPARAM>("Zoom 25%")); SNDMSG(VListBox, LB_ADDSTRING, 0, reinterpret_cast<LPARAM>("Zoom 50%")); SNDMSG(VListBox, LB_ADDSTRING, 0, reinterpret_cast<LPARAM>("Zoom 75%")); SNDMSG(VListBox, LB_ADDSTRING, 0, reinterpret_cast<LPARAM>("Zoom 100%")); SNDMSG(VListBox, LB_ADDSTRING, 0, reinterpret_cast<LPARAM>("Zoom 125%")); SNDMSG(VListBox, LB_ADDSTRING, 0, reinterpret_cast<LPARAM>("Zoom 150%")); SNDMSG(VListBox, LB_ADDSTRING, 0, reinterpret_cast<LPARAM>("Zoom 200%")); SNDMSG(VListBox, LB_ADDSTRING, 0, reinterpret_cast<LPARAM>("Zoom 300%"));
}
ShowWindow(HWnd, nCmdShow); UpdateWindow(HWnd);
MSG msg; while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } } } return 0;}//------------------------------------------------------------------
// image relatedBITMAP bmp;BITMAPINFO bmInfo;char *bbits = NULL; // bitmap bitsconst char* filename = "LENA.BMP";HDC HMemDC = NULL;HBITMAP HOldBmp = NULL;
// zooming relatedfloat zoom_factor_h = 0.5;float zoom_factor_v = 0.5;RECT RDest = {5, 5, 0, 0};enum {ID_ZOOM25, ID_ZOOM50, ID_ZOOM75, ID_ZOOM100, ID_ZOOM125, ID_ZOOM150, ID_ZOOM200, ID_ZOOM300};
LRESULT CALLBACK MainWndProc(HWND HWnd, UINT Msg, WPARAM WParam, LPARAM LParam){ switch (Msg) { case WM_CREATE: { // check commandline if (strlen(cmdline) != 0) {
useDIBits = TRUE; } else useDIBits = FALSE;
// create a memory DC HMemDC = CreateCompatibleDC(NULL); if (HMemDC) { // load a bitmap from file HBITMAP HBmp = static_cast<HBITMAP>( LoadImage(HInst, filename, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE) ); if (HBmp) { // extract dimensions of the bitmap GetObject(HBmp, sizeof(BITMAP), &bmp);
// fill the BITMAPINFO stucture for further use by StretchDIBits bmInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmInfo.bmiHeader.biWidth = bmp.bmWidth; bmInfo.bmiHeader.biHeight = bmp.bmHeight; bmInfo.bmiHeader.biPlanes = 1;//bmp.bmPlanes; bmInfo.bmiHeader.biBitCount = bmp.bmBitsPixel; bmInfo.bmiHeader.biCompression = BI_RGB; bmInfo.bmiHeader.biSizeImage = 0; bmInfo.bmiHeader.biXPelsPerMeter = 0; bmInfo.bmiHeader.biClrImportant = 0; bmInfo.bmiHeader.biClrUsed = 0;
// associate the bitmap with the memory DC HOldBmp = static_cast<HBITMAP>( SelectObject(HMemDC, HBmp) );
if (useDIBits) { bbits = new char[bmp.bmHeight*bmp.bmWidthBytes*(bmp.bmBitsPixel / 8)]; //GetDIBits(HMemDC, HBmp, 0, bmp.bmHeight, bbits, &bmInfo, DIB_RGB_COLORS);
// Here goes a temp hack, since GetDIBits doesn't exist in ReactOS yet FILE *f = fopen(filename, "rb"); BITMAPFILEHEADER bmpHeader;
fread(&bmpHeader, sizeof(BITMAPFILEHEADER), 1, f); fread(&bmInfo, sizeof(BITMAPINFO), 1, f); fseek(f, bmpHeader.bfOffBits, SEEK_SET); fread(bbits, bmp.bmHeight*bmp.bmWidthBytes*(bmp.bmBitsPixel / 8), 1, f);
fclose(f); } } } } case WM_COMMAND: { if (WParam == MAKEWPARAM(ID_LISTBOX, LBN_SELCHANGE) || WParam == MAKEWPARAM(ID_LISTBOX2, LBN_SELCHANGE)) { switch (SNDMSG(HListBox, LB_GETCURSEL, 0, 0)) { case ID_ZOOM25: zoom_factor_h = 0.25; break; case ID_ZOOM50: zoom_factor_h = 0.50; break; case ID_ZOOM75: zoom_factor_h = 0.75; break; case ID_ZOOM100: zoom_factor_h = 1.00; break; case ID_ZOOM125: zoom_factor_h = 1.25; break; case ID_ZOOM150: zoom_factor_h = 1.50; break; case ID_ZOOM200: zoom_factor_h = 2.00; break; case ID_ZOOM300: zoom_factor_h = 3.00; break; }
switch (SNDMSG(VListBox, LB_GETCURSEL, 0, 0)) { case ID_ZOOM25: zoom_factor_v = 0.25; break; case ID_ZOOM50: zoom_factor_v = 0.50; break; case ID_ZOOM75: zoom_factor_v = 0.75; break; case ID_ZOOM100: zoom_factor_v = 1.00; break; case ID_ZOOM125: zoom_factor_v = 1.25; break; case ID_ZOOM150: zoom_factor_v = 1.50; break; case ID_ZOOM200: zoom_factor_v = 2.00; break; case ID_ZOOM300: zoom_factor_v = 3.00; break; }
// calculate the new width and height const int new_width = static_cast<int>(zoom_factor_h * bmp.bmWidth); const int new_height = static_cast<int>(zoom_factor_v * bmp.bmHeight);
// is zooming in? bool zoom_in = (new_width > RDest.right - RDest.left);
// caculate the area that needs to be updated RECT RUpdate = { RDest.left, RDest.top, RDest.left + max(new_width, RDest.right - RDest.left), RDest.top + max(new_height, RDest.bottom - RDest.top) };
// adjust the dimenstions of the // destination rectangle RDest.right = RDest.left + new_width; RDest.bottom = RDest.top + new_height;
// create an update region from the XOR combination // of the update and destination rectangles HRGN HUpdateRgn = CreateRectRgnIndirect(&RUpdate); HRGN HDestRgn = CreateRectRgnIndirect(&RDest); int result = CombineRgn(HUpdateRgn, HUpdateRgn, HDestRgn, RGN_XOR);
// incite a repaint if (result != NULLREGION && result != ERROR) { InvalidateRgn(HWnd, HUpdateRgn, true); RedrawWindow(HWnd, &RDest, NULL, RDW_NOERASE | RDW_INVALIDATE); } else if (result == NULLREGION) { InvalidateRect(HWnd, &RUpdate, zoom_in ? false : true); }
// clean up DeleteObject(HUpdateRgn); DeleteObject(HDestRgn); } break; } case WM_PAINT: { PAINTSTRUCT ps; const HDC Hdc = BeginPaint(HWnd, &ps);#if 0 try#endif { // // TODO: add palette support (see Chapter 9)... // if (useDIBits) { if (RDest.right - RDest.left > 0) { if (zoom_factor_h < 1.0 || zoom_factor_v < 1.0) { SetStretchBltMode(Hdc, COLORONCOLOR); }
// render the zoomed image StretchDIBits(Hdc, RDest.left, RDest.top, RDest.right - RDest.left, RDest.bottom - RDest.top, 0, 0, bmp.bmWidth, bmp.bmHeight, bbits, &bmInfo, DIB_RGB_COLORS, SRCCOPY); } } else { if (RDest.right - RDest.left > 0) {
// use BitBlt when not zooming if (zoom_factor_h == 1.0 && zoom_factor_v == 1.0) { BitBlt(Hdc, RDest.left, RDest.top, RDest.right - RDest.left, RDest.bottom - RDest.top, HMemDC, 0, 0, SRCCOPY); } else { if (zoom_factor_h < 1.0 || zoom_factor_v < 1.0) { SetStretchBltMode(Hdc, COLORONCOLOR); }
// render the zoomed image StretchBlt(Hdc, RDest.left, RDest.top, RDest.right - RDest.left, RDest.bottom - RDest.top, HMemDC, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY); } } } }#if 0 catch (...)#endif { EndPaint(HWnd, &ps); } EndPaint(HWnd, &ps); break; } case WM_DESTROY: { // clean up DeleteObject(SelectObject(HMemDC, HOldBmp)); DeleteDC(HMemDC);
if (bbits) delete[] bbits;
PostQuitMessage(0); return 0; } } return DefWindowProc(HWnd, Msg, WParam, LParam);}//------------------------------------------------------------------