/***************************************************************************** * * Copyright (c) 1999, KL GROUP INC. All Rights Reserved. * http://www.klgroup.com * * This file is provided for demonstration and educational uses only. * Permission to use, copy, modify and distribute this file for * any purpose and without fee is hereby granted, provided that the * above copyright notice and this permission notice appear in all * copies, and that the name of KL Group not be used in advertising * or publicity pertaining to this material without the specific, * prior written permission of an authorized representative of * KL Group. * * KL GROUP MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY * OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE, OR NON-INFRINGEMENT. KL GROUP SHALL NOT BE LIABLE FOR ANY * DAMAGES SUFFERED BY USERS AS A RESULT OF USING, MODIFYING OR * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. */ #include #include #include #include #include "olch3d.h" #include "resource.h" Xrt3dData* pData3d = NULL; HANDLE ghInst; HWND gMainHwnd; HXRT3D hChart; HBRUSH hbrushBack; HANDLE hScatter3D; /* Uses DrawMesh, could also use DrawShaded */ HANDLE hScatter2D; /* Uses DrawContours, could also use DrawZones */ HANDLE hDropLines; char *legend_labels[] = { "Bats", "Bees", "Birds", NULL }; /* Obtain space for one series and calculate the 3d data points */ void CalculateScatterSeries(Xrt3dPointData* pPointData, int nSeries, int nNumPoints) { int j; double x, y; Xrt3dPoint3D* pPoint3D; /* Allocate the points */ Xrt3dMakePointDataSeries(&(pPointData->series[nSeries]), nNumPoints); /* Populate the series with some generic data */ for (j = 0; j < nNumPoints; j++) { pPoint3D = &(pPointData->series[nSeries].points[j]); /* Scatter the data slightly */ if (j % 2) { x = j + j/(nSeries+1); y = nSeries + x/8; } else { x = j - j % 3; y = nSeries + 0.5 + x/8; } pPoint3D->x = x; pPoint3D->y = y; pPoint3D->z = 7500 - (3*x*y + x*x*x + y*y*y); } } /* Optains a point data structure and calculates the 3d data for the chart */ Xrt3dData* CalculateScatter() { int nNumSeries = 3; double dHoleValue = XRT3D_HUGE_VAL; /* Create the series with no point data in each series (last param = FALSE) */ Xrt3dPointData* pPointData = (Xrt3dPointData *) Xrt3dMakePointData(nNumSeries, 1, dHoleValue, FALSE); /* Create each series */ CalculateScatterSeries(pPointData, 0, 10); CalculateScatterSeries(pPointData, 1, 5); CalculateScatterSeries(pPointData, 2, 8); return (Xrt3dData*) pPointData; } /* Create all the controls used in the main windows */ void CreateControls(HWND parent) { HDC hdc; TEXTMETRIC tm; int cxChar, cyChar; int controlWidth; COLORREF crBack; hdc = GetDC (parent) ; SetMapMode(hdc, MM_TEXT); SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT)) ; GetTextMetrics (hdc, &tm) ; cxChar = tm.tmAveCharWidth ; cyChar = tm.tmHeight + tm.tmExternalLeading ; controlWidth = cxChar * 16; ReleaseDC (parent, hdc) ; /* * Create the 3d chart and their controls. * The size and position of the chart will be recalculated * during the WM_SIZE message. */ hChart = Xrt3dCreateWindow("simple", 0, 0, 0, 0, parent, ghInst); hScatter3D = CreateWindow("BUTTON", "3D Scatter", WS_VISIBLE | WS_CHILD | BS_AUTOCHECKBOX, cxChar, cyChar/2, controlWidth, cyChar, parent, NULL, ghInst, NULL); hScatter2D = CreateWindow("BUTTON", "2D Scatter", WS_VISIBLE | WS_CHILD | BS_AUTOCHECKBOX, cxChar+4+controlWidth, cyChar/2, controlWidth, cyChar, parent, NULL, ghInst, NULL); hDropLines = CreateWindow("BUTTON", "Drop Lines", WS_VISIBLE | WS_CHILD | BS_AUTOCHECKBOX, cxChar+4+(controlWidth*2), cyChar/2, controlWidth, cyChar, parent, NULL, ghInst, NULL); /* Get the current background color used by the demo and * use that color for the background of the rest of the window. */ Xrt3dGetValues(hChart, XRT3D_BACKGROUND_COLOR, &crBack, NULL); hbrushBack = CreateSolidBrush(crBack); #ifdef _WIN32 SetClassLong(gMainHwnd, GCL_HBRBACKGROUND, (long) hbrushBack); #else SetClassWord(gMainHwnd, GCW_HBRBACKGROUND, (WORD) hbrushBack); #endif } /* Resize/reposition the chart based on the new size of the main window */ void SizeChart(HWND hwnd, int width, int height) { HDC hdc; TEXTMETRIC tm; int cyChar; int chartHeight; int chartWidth; int controlHeight; hdc = GetDC(hwnd); SetMapMode(hdc, MM_TEXT); SelectObject(hdc, GetStockObject (SYSTEM_FIXED_FONT)); GetTextMetrics(hdc, &tm); ReleaseDC(hwnd, hdc); cyChar = tm.tmHeight + tm.tmExternalLeading; controlHeight = cyChar * 2; chartWidth = width; chartHeight = height - (controlHeight * 4); /* place chart in bottom portion of window */ SetWindowPos(Xrt3dGetWindow(hChart), HWND_BOTTOM, 0, (controlHeight * 2), chartWidth, chartHeight, SWP_SHOWWINDOW | SWP_NOZORDER); InvalidateRect(gMainHwnd, NULL, TRUE); } /* Draw routine */ void DrawChart(HWND hwnd, HDC hdc) { TEXTMETRIC tm; RECT rect; HBRUSH hbrush; int cxChar, cyChar; int chartWidth; int controlHeight; SetMapMode(hdc, MM_TEXT); SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT)) ; GetTextMetrics (hdc, &tm) ; cxChar = tm.tmAveCharWidth ; cyChar = tm.tmHeight + tm.tmExternalLeading ; controlHeight = cyChar * 2; GetClientRect(hwnd, &rect); chartWidth = rect.right - rect.left; /* place controls in top portion of window */ MoveToEx(hdc, 0, controlHeight, NULL); LineTo(hdc, chartWidth, controlHeight); #ifdef _WIN32 hbrush = CreateSolidBrush(GetSysColor(COLOR_BTNFACE)); #else hbrush = CreateSolidBrush(GetSysColor(COLOR_WINDOW)); #endif rect.left = 0; rect.top = 0; rect.right = chartWidth; rect.bottom = controlHeight; FillRect(hdc, &rect, hbrush); DeleteObject(hbrush); ShowWindow(hScatter3D, SW_SHOW); ShowWindow(hScatter2D, SW_SHOW); ShowWindow(hDropLines, SW_SHOW); } /* Main window WndProc */ LRESULT CALLBACK MainWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { HWND hwndCtrl; HDC hdc; PAINTSTRUCT ps; int nCheck; switch(msg) { case WM_COMMAND: /* handle commands */ switch(LOWORD(wParam)) { case IDM_EXIT: DestroyWindow(hwnd); break; case IDM_ABOUTDEMO: case IDMHELP: WinHelp(hwnd, "OLCH-DMO.HLP", HELP_CONTEXT, 7); break; case IDM_ABOUTOLECTRACHART: WinHelp(hwnd, "OLCH-DMO.HLP", HELP_CONTEXT, 19); break; /* handle messages from check buttons */ default: #ifdef _WIN32 hwndCtrl = (HWND)lParam; #else hwndCtrl = (HWND)LOWORD(lParam); #endif if (hwndCtrl == hScatter3D) { nCheck = (int) SendMessage(hwndCtrl, BM_GETCHECK, 0, 0L); /* Either XRT3D_DRAW_MESH or XRT3D_DRAW_SHADED * enables 3D Scatter. */ Xrt3dSetValues(hChart, XRT3D_DRAW_MESH, nCheck, NULL); } else if (hwndCtrl == hScatter2D) { nCheck = (int) SendMessage(hwndCtrl, BM_GETCHECK, 0, 0L); /* Either XRT3D_DRAW_CONTOURS or XRT3D_DRAW_ZONES enables * 3D Scatter, but the 3D view takes precedence if enabled. */ Xrt3dSetValues(hChart, XRT3D_DRAW_CONTOURS, nCheck, NULL); } else if (hwndCtrl == hDropLines) { /* Drop lines only show in the 3D view */ nCheck = (int) SendMessage(hwndCtrl, BM_GETCHECK, 0, 0L); Xrt3dSetValues(hChart, XRT3D_DRAW_DROP_LINES, nCheck, NULL); } break; } return(0); case WM_SIZE: /* resize the chart */ SizeChart(hwnd, (int) LOWORD(lParam), (int) HIWORD(lParam)); return(0); case WM_PAINT: hdc = BeginPaint(hwnd, &ps); DrawChart(hwnd, hdc); EndPaint(hwnd, &ps); break; /* * To properly handle colors the chart needs to be * notified about any system palette changes. */ case XRT3DN_PALETTECHANGED: SendMessage(Xrt3dGetWindow(hChart), WM_QUERYNEWPALETTE, 0, 0); break; case WM_QUERYNEWPALETTE: /* Make sure the window is at the top of the Z-order so that the background palettes can be realized before any other application gets a chance to realize a palette. */ /* In Windows for Workgroups, this message can be received before the window is moved to the top of the Z-order causing the first WM_PALETTECHANGED message to be sent not to this window but the window which was "previously" at the top of the Z-order. */ BringWindowToTop(hwnd); SendMessage(Xrt3dGetWindow(hChart), WM_QUERYNEWPALETTE, 0, 0); break; case WM_PALETTECHANGED: SendMessage(Xrt3dGetWindow(hChart), msg, wParam, lParam); break; case WM_DESTROY: PostQuitMessage(0); return(0); } return(DefWindowProc(hwnd, msg, wParam, lParam)); } /* Entry point for main program */ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { WNDCLASS wc; MSG msg; HACCEL hAccel; if (!hPrevInstance) { memset(&wc, 0, sizeof(wc)); wc.lpfnWndProc = (WNDPROC) MainWndProc; wc.hInstance = hInstance; wc.hIcon = LoadIcon(hInstance, "simpleicon"); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = GetStockObject(BLACK_BRUSH); wc.lpszMenuName = (LPSTR) "SCATTERMENU"; wc.lpszClassName = (LPSTR) "Chart3D_Scatter"; if (!RegisterClass(&wc)) { MessageBox(NULL, "Cannot RegisterClass()", "Err! - TEST", MB_OK | MB_ICONEXCLAMATION); return(FALSE); } } hAccel = LoadAccelerators(hInstance, "ScatterAccelerators"); ghInst = hInstance; /* Create main window */ gMainHwnd = CreateWindow("Chart3D_Scatter", "Olectra Chart 3D - Scatter Chart Demo", WS_OVERLAPPEDWINDOW, 0, 0, 650, 450, NULL, NULL, ghInst, NULL); if (!gMainHwnd) { return 0; } /* Create all controls in main window */ CreateControls(gMainHwnd); /* Calculate and set the 3d data for the chart */ pData3d = CalculateScatter(); Xrt3dSetValues(hChart, XRT3D_SURFACE_DATA, pData3d, NULL); Xrt3dSetValues(hChart, XRT3D_TYPE, XRT3D_TYPE_SCATTER, NULL); /* Fix the Z axis minimum at zero so drop lines don't adjust the cube * (we could have chosen instead to modify XRT3D_ZORIGIN). */ Xrt3dSetValues(hChart, XRT3D_ZMIN, 0.0, NULL); /* Put the legend in a corner, turn on a border */ Xrt3dSetValues(hChart, XRT3D_LEGEND_ANCHOR, XRT3D_ANCHOR_NORTHWEST, XRT3D_LEGEND_BORDER, XRT3D_BORDER_PLAIN, XRT3D_LEGEND_BORDER_WIDTH, 1, NULL); /* Add one legend label for every series */ Xrt3dSetValues(hChart, XRT3D_LEGEND_STRINGS, legend_labels, NULL); /* Give the plotcube a color for contrast */ Xrt3dSetValues(hChart, XRT3D_DATA_AREA_BACKGROUND_COLOR, RGB(240, 248, 255), NULL); /* Start with the drop lines enabled */ Xrt3dSetValues(hChart, XRT3D_DRAW_DROP_LINES, TRUE, NULL); /* Set the axis titles */ Xrt3dSetValues(hChart, XRT3D_XAXIS_TITLE, "X Axis", NULL); Xrt3dSetValues(hChart, XRT3D_YAXIS_TITLE, "Y Axis", NULL); Xrt3dSetValues(hChart, XRT3D_ZAXIS_TITLE, "Z Axis", NULL); /* Turn on check box for 3D Scatter (it's "mesh" - on by default) */ SendMessage(hScatter3D, BM_SETCHECK, 1, 0L); /* Turn on check box for Droplines */ SendMessage(hDropLines, BM_SETCHECK, 1, 0L); ShowWindow(gMainHwnd, nCmdShow); UpdateWindow(gMainHwnd); while (GetMessage(&msg, NULL, 0, 0)) { if (!TranslateAccelerator(gMainHwnd, hAccel, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } } /* Remember to free up memory */ Xrt3dDestroyData(pData3d, TRUE); Xrt3dDestroy(hChart); DeleteObject(hbrushBack); return(msg.wParam); }