/***************************************************************************** * * 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 "olch2d.h" #include "olch3d.h" #include "profile.h" #include "resource.h" Xrt3dData* pData3d = NULL; double dHoleValue = XRT3D_HUGE_VAL; HANDLE ghInst = NULL; HWND gMainHwnd = NULL; HWND hDlgProfile = NULL; HXRT3D chart3d = NULL; HXRT2D chart2d = NULL; HBRUSH hbrushBack = NULL; HANDLE hApply = NULL; HANDLE hStartX = NULL; HANDLE hStartY = NULL; HANDLE hEndX = NULL; HANDLE hEndY = NULL; HANDLE hInterpolate = NULL; HANDLE hInterSpin = NULL; BOOL bRepaint = FALSE; int nChart3dVisible = 0; SelectedPoint ptStart; SelectedPoint ptEnd; Counter ctInterpolate; int y3dOffset = 0; char szErrorBuf[256]; static char *szHeader3d[] = { "To define a profile, use the left mouse button to select a", "start point and then drag it to an end point. To select the", "desired view, use the middle (or both right and left) mouse button.", "To move the entire profile line, use the right mouse button.", NULL }; BOOL CALLBACK Profile2dDlg(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_INITDIALOG : return TRUE ; case WM_SIZE: SendMessage(XrtGetWindow(chart2d), message, wParam, lParam); SetWindowPos(XrtGetWindow(chart2d), HWND_TOP, 0, 0, LOWORD(lParam), HIWORD(lParam), SWP_SHOWWINDOW); break; default: break; } return FALSE ; } // create the chart 2d profile popup window void CreateProfileDialog() { RECT rect; if (hDlgProfile) { // once is enough return; } hDlgProfile = CreateDialog(ghInst, "Profile2dDlg", gMainHwnd, MakeProcInstance ((FARPROC) Profile2dDlg, ghInst)) ; GetClientRect(hDlgProfile, &rect); chart2d = XrtCreateWindow("Profile2d", rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, hDlgProfile, ghInst); XrtSetValues(chart2d, XRT_REPAINT, (int) FALSE, NULL); XrtSetPropString(chart2d, XRT_HEADER_FONT, "Arial,10"); XrtSetPropString(chart2d, XRT_AXIS_FONT, "Arial,10"); XrtSetValues(chart2d, XRT_LEGEND_SHOW, (int) FALSE, XRT_XANNOTATION_METHOD, XRT_ANNO_VALUE_LABELS, XRT_HEADER_ADJUST, XRT_ADJUST_LEFT, XRT_HEADER_BORDER, XRT_BORDER_ETCHED_IN, XRT_HEADER_BORDER_WIDTH, 4, XRT_GRAPH_BORDER, XRT_BORDER_SHADOW, XRT_GRAPH_BORDER_WIDTH, 5, XRT_GRAPH_BACKGROUND_COLOR, RGB(0xAA, 0xE8, 0xF0), XRT_BACKGROUND_COLOR, RGB(0x87, 0x97, 0xAB), NULL); XrtSetValues(chart2d, XRT_REPAINT, (int) TRUE, NULL); } // calculate the default 3d data for the chart Xrt3dData* CalculateDefault3dData() { int i, j; int nRows = 21; int nColumns = 21; double x, y, value; Xrt3dGridData* pGridData = (Xrt3dGridData*) Xrt3dMakeGridData(nRows, nColumns, 0.0, 1.0, 1.0, 0.0, 0.0, TRUE); if (!pGridData) { return (Xrt3dData*) NULL; } for (i = 0; i < nRows; i++) { for (j = 0; j < nColumns; j++) { x = (double) i - 10.0; y = (double) j - 10.0; value = sqrt(exp(sqrt(y*y) - sqrt(x*x))) + sqrt(exp(sqrt(x*x) - sqrt(y*y))); pGridData->values[i][j] = (value > 100.0) ? 100.0 : value; } } return (Xrt3dData*) pGridData; } // setup the 3d data for the chart void Setup3dData(char* szfilename) { char szBuffer[256]; BOOL bAutoScale; double zmin, zmax; HMENU hmenu; pData3d = (Xrt3dData *) NULL; // load 3d profile data from file pData3d = Xrt3dMakeDataFromFile(szfilename, szBuffer); if (!pData3d) { pData3d = CalculateDefault3dData(); if (!pData3d) { MessageBox(NULL, "No profile data", NULL, MB_OK); return; } } Xrt3dSetValues(chart3d, XRT3D_REPAINT, (int) FALSE, NULL); Xrt3dSetPropString(chart3d, XRT3D_HEADER_FONT, "Arial,8"); Xrt3dSetValues(chart3d, XRT3D_XAXIS_TITLE, "X Axis", XRT3D_YAXIS_TITLE, "Y Axis", XRT3D_ZAXIS_TITLE, "Z Axis", XRT3D_XROTATION, (double) 25.0, XRT3D_ZROTATION, (double) 320.0, XRT3D_PERSPECTIVE_DEPTH, (double) 5.0, XRT3D_DRAW_MESH, (int) TRUE, XRT3D_DRAW_SHADED, (int) TRUE, XRT3D_DRAW_CONTOURS, (int) TRUE, XRT3D_DRAW_ZONES, (int) TRUE, XRT3D_LEGEND_SHOW, (int) FALSE, XRT3D_HEADER_STRINGS, szHeader3d, XRT3D_HEADER_ADJUST, XRT3D_ADJUST_LEFT, XRT3D_HEADER_BORDER, XRT3D_BORDER_ETCHED_IN, XRT3D_HEADER_BORDER_WIDTH, 4, XRT3D_GRAPH_BORDER, XRT3D_BORDER_SHADOW, XRT3D_GRAPH_BORDER_WIDTH, 5, XRT3D_GRAPH_BACKGROUND_COLOR, RGB(0xAA, 0xE8, 0xF0), XRT3D_BACKGROUND_COLOR, RGB(0x87, 0x97, 0xAB), XRT3D_AXIS_STROKE_SIZE, 70, XRT3D_XGRID_LINES, XRT3D_XY_PLANE, XRT3D_YGRID_LINES, XRT3D_XY_PLANE, XRT3D_ZGRID_LINES, XRT3D_XZ_PLANE | XRT3D_YZ_PLANE, XRT3D_SURFACE_DATA, pData3d, NULL); Xrt3dSetValues(chart3d, XRT3D_REPAINT, (int) TRUE, NULL); dHoleValue = (pData3d->g.type == XRT3D_DATA_GRID) ? pData3d->g.noval : pData3d->ig.noval; ProcessInputData(pData3d); XrtGetValues(chart2d, XRT_YMIN_USE_DEFAULT, &bAutoScale, NULL); if (!bAutoScale) { Xrt3dGetValues(chart3d, XRT3D_ZMIN, &zmin, XRT3D_ZMAX, &zmax, NULL); XrtSetValues(chart2d, XRT_YMIN, zmin, XRT_YMAX, zmax, NULL); } // initialize the menu items hmenu = GetMenu(gMainHwnd); CheckMenuItem(hmenu, IDM_DRAWMESH, MF_CHECKED); CheckMenuItem(hmenu, IDM_DRAWSHADED, MF_CHECKED); CheckMenuItem(hmenu, IDM_DRAWCONTOURS, MF_CHECKED); CheckMenuItem(hmenu, IDM_DRAWZONES, MF_CHECKED); CheckMenuItem(hmenu, IDM_AUTOSCALE, (bAutoScale) ? MF_CHECKED : MF_UNCHECKED); nChart3dVisible = 4; return; } // Create all the controls used in the main windows void CreateControls(HWND parent) { HDC hdc; TEXTMETRIC tm; int cxChar, cyChar; int editWidth; int editHeight; int controlHeight; int xPos, yPos; COLORREF crBack; char szText[30]; hdc = GetDC(parent) ; SetMapMode(hdc, MM_TEXT); SelectObject(hdc, GetStockObject (SYSTEM_FIXED_FONT)) ; GetTextMetrics(hdc, &tm) ; cxChar = tm.tmAveCharWidth ; cyChar = tm.tmHeight + tm.tmExternalLeading ; editWidth = cxChar * 8; editHeight = cyChar * 3 / 2; controlHeight = cyChar * 7 / 2; 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. */ /* WS_VISIBLE | WS_CHILD | WS_CLIPSIBLINGS, */ chart3d = Xrt3dCreateWindow("profile3d", 0, 0, 0, 0, parent, ghInst); y3dOffset = controlHeight; xPos = cxChar * 3; yPos = cyChar * 3 / 2; strcpy(szText, "0"); hStartX = CreateWindow("EDIT", szText, WS_VISIBLE | WS_CHILD | WS_BORDER | WS_GROUP | WS_TABSTOP, xPos, yPos, editWidth, editHeight, parent, NULL, ghInst, NULL); xPos += (editWidth + (cxChar * 3)); hStartY = CreateWindow("EDIT", szText, WS_VISIBLE | WS_CHILD | WS_BORDER | WS_TABSTOP, xPos, yPos, editWidth, editHeight, parent, NULL, ghInst, NULL); xPos += (editWidth + (cxChar * 3)); hEndX = CreateWindow("EDIT", szText, WS_VISIBLE | WS_CHILD | WS_BORDER | WS_TABSTOP, xPos, yPos, editWidth, editHeight, parent, NULL, ghInst, NULL); xPos += (editWidth + (cxChar * 3)); hEndY = CreateWindow("EDIT", szText, WS_VISIBLE | WS_CHILD | WS_BORDER | WS_TABSTOP, xPos, yPos, editWidth, editHeight, parent, NULL, ghInst, NULL); xPos += (editWidth + (cxChar * 1)); sprintf(szText, "%d", DEFAULT_NUM_INTERPOLATE); hInterpolate = CreateWindow("EDIT", szText, WS_VISIBLE | WS_CHILD | WS_BORDER | WS_TABSTOP, xPos, yPos, editWidth, editHeight, parent, NULL, ghInst, NULL); xPos += (editWidth + (cxChar / 8)); hInterSpin = CreateWindow("SCROLLBAR", "", WS_VISIBLE | WS_CHILD | SBS_VERT | WS_TABSTOP, xPos, yPos, (cxChar*2), editHeight, parent, NULL, ghInst, NULL); SetScrollRange(hInterSpin, SB_CTL, MIN_INTERPOLATE, MAX_INTERPOLATE, FALSE) ; SetScrollPos(hInterSpin, SB_CTL, DEFAULT_NUM_INTERPOLATE, FALSE) ; ctInterpolate.min = MIN_INTERPOLATE; ctInterpolate.max = MAX_INTERPOLATE; ctInterpolate.value = DEFAULT_NUM_INTERPOLATE; xPos += (cxChar * 3); hApply = CreateWindow("BUTTON", "Apply", WS_VISIBLE | WS_CHILD | WS_TABSTOP, xPos, yPos, cxChar * 7, editHeight, 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(chart3d, 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 * 7 / 2; chartWidth = width; chartHeight = height - controlHeight - 1; // place chart in bottom portion of window SetWindowPos(Xrt3dGetWindow(chart3d), HWND_BOTTOM, 0, controlHeight + 1, chartWidth, chartHeight, SWP_SHOWWINDOW | SWP_NOZORDER); InvalidateRect(gMainHwnd, NULL, TRUE); } // draw controls routine void DrawControls(HWND hwnd, HDC hdc) { TEXTMETRIC tm; RECT rect; HBRUSH hbrush; char szText[100]; int cxChar, cyChar; int chartWidth; int controlHeight; int yLine; SetMapMode(hdc, MM_TEXT); SelectObject (hdc, GetStockObject(SYSTEM_FIXED_FONT)) ; GetTextMetrics (hdc, &tm) ; cxChar = tm.tmAveCharWidth ; cyChar = tm.tmHeight + tm.tmExternalLeading ; controlHeight = cyChar * 7 / 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); hbrush = CreateSolidBrush(GetSysColor(COLOR_BTNFACE)); rect.left = 0; rect.top = 1; rect.right = chartWidth; rect.bottom = controlHeight; FillRect(hdc, &rect, hbrush); DeleteObject(hbrush); SetBkMode(hdc, TRANSPARENT); yLine = rect.top + (cyChar / 4); strcpy(szText, "Start Point:"); TextOut(hdc, rect.left + cxChar, yLine, szText, strlen(szText)); strcpy(szText, "End Point:"); TextOut(hdc, rect.left + (cxChar * 23), yLine, szText, strlen(szText)); strcpy(szText, "Interpolate:"); TextOut(hdc, rect.left + (cxChar * 45), yLine, szText, strlen(szText)); yLine = rect.top + (cyChar * 13 / 8); strcpy(szText, "X:"); TextOut(hdc, rect.left + cxChar, yLine, szText, strlen(szText)); strcpy(szText, "Y:"); TextOut(hdc, rect.left + (cxChar * 12), yLine, szText, strlen(szText)); strcpy(szText, "X:"); TextOut(hdc, rect.left + (cxChar * 23), yLine, szText, strlen(szText)); strcpy(szText, "Y:"); TextOut(hdc, rect.left + (cxChar * 34), yLine, szText, strlen(szText)); ShowWindow(hApply, SW_SHOW); ShowWindow(hStartX, SW_SHOW); ShowWindow(hStartY, SW_SHOW); ShowWindow(hEndX, SW_SHOW); ShowWindow(hEndY, SW_SHOW); ShowWindow(hInterpolate, SW_SHOW); ShowWindow(hInterSpin, SW_SHOW); } // Main window WndProc LRESULT CALLBACK MainWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { static int xPos; static int yPos; HWND hwndCtrl; HDC hdc; PAINTSTRUCT ps; HMENU hmenu; int nCheck; double zmin, zmax; int nUpDown; Xrt3dCallbackStruct* pcb; RECT rectPainted; 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, 15); break; case IDM_ABOUTOLECTRACHART: WinHelp(hwnd, "OLCH-DMO.HLP", HELP_CONTEXT, 19); break; case IDM_DRAWMESH: hmenu = GetMenu(hwnd); Xrt3dGetValues(chart3d, XRT3D_DRAW_MESH, &nCheck, NULL); nCheck = (nCheck ? 0 : 1); CheckMenuItem(hmenu, IDM_DRAWMESH, (nCheck ? MF_CHECKED : MF_UNCHECKED)); Xrt3dSetValues(chart3d, XRT3D_DRAW_MESH, nCheck, NULL); nChart3dVisible += (nCheck ? 1 : -1); return(0); case IDM_DRAWSHADED: hmenu = GetMenu(hwnd); Xrt3dGetValues(chart3d, XRT3D_DRAW_SHADED, &nCheck, NULL); nCheck = (nCheck ? 0 : 1); CheckMenuItem(hmenu, IDM_DRAWSHADED, (nCheck ? MF_CHECKED : MF_UNCHECKED)); Xrt3dSetValues(chart3d, XRT3D_DRAW_SHADED, nCheck, NULL); nChart3dVisible += (nCheck ? 1 : -1); return(0); case IDM_DRAWCONTOURS: hmenu = GetMenu(hwnd); Xrt3dGetValues(chart3d, XRT3D_DRAW_CONTOURS, &nCheck, NULL); nCheck = (nCheck ? 0 : 1); CheckMenuItem(hmenu, IDM_DRAWCONTOURS, (nCheck ? MF_CHECKED : MF_UNCHECKED)); Xrt3dSetValues(chart3d, XRT3D_DRAW_CONTOURS, nCheck, NULL); nChart3dVisible += (nCheck ? 1 : -1); return(0); case IDM_DRAWZONES: hmenu = GetMenu(hwnd); Xrt3dGetValues(chart3d, XRT3D_DRAW_ZONES, &nCheck, NULL); nCheck = (nCheck ? 0 : 1); CheckMenuItem(hmenu, IDM_DRAWZONES, (nCheck ? MF_CHECKED : MF_UNCHECKED)); Xrt3dSetValues(chart3d, XRT3D_DRAW_ZONES, nCheck, NULL); return(0); case IDM_DRAWSOLID: hmenu = GetMenu(hwnd); Xrt3dGetValues(chart3d, XRT3D_SOLID_SURFACE, &nCheck, NULL); nCheck = (nCheck ? 0 : 1); CheckMenuItem(hmenu, IDM_DRAWSOLID, (nCheck ? MF_CHECKED : MF_UNCHECKED)); Xrt3dSetValues(chart3d, XRT3D_SOLID_SURFACE, nCheck, NULL); if (nCheck) { XrtSetValues(chart2d, XRT_TYPE, XRT_TYPE_AREA, XRT_YORIGIN_PLACEMENT, XRT_ORIGIN_MIN, NULL); } else { XrtSetValues(chart2d, XRT_TYPE, XRT_TYPE_PLOT, NULL); } nChart3dVisible += (nCheck ? 1 : -1); return(0); case IDM_AUTOSCALE: hmenu = GetMenu(hwnd); nCheck = GetMenuState(hmenu, IDM_AUTOSCALE, MF_BYCOMMAND) & MF_CHECKED; nCheck = (nCheck ? 0 : 1); CheckMenuItem(hmenu, IDM_AUTOSCALE, (nCheck ? MF_CHECKED : MF_UNCHECKED)); if (nCheck) { XrtSetValues(chart2d, XRT_YMIN_USE_DEFAULT, TRUE, XRT_YMAX_USE_DEFAULT, TRUE, NULL); } else { Xrt3dGetValues(chart3d, XRT3D_ZMIN, &zmin, XRT3D_ZMAX, &zmax, NULL); XrtSetValues(chart2d, XRT_YMIN, zmin, XRT_YMAX, zmax, NULL); } return(0); case IDM_PRINTCHART: PrintCharts(chart2d, chart3d); return(0); // handle messages from button and spin controls default: #ifdef _WIN32 hwndCtrl = (HWND)lParam; #else hwndCtrl = (HWND)LOWORD(lParam); #endif if (hwndCtrl == hApply) { // assume button has been clicked ProcessEditValues(); } } return(0); case WM_VSCROLL: #ifdef _WIN32 hwndCtrl = (HWND)lParam; #else hwndCtrl = (HWND)HIWORD(lParam); #endif if (hwndCtrl != hInterSpin) { break; } switch(wParam) { case SB_LINEUP: nUpDown = 1; break; case SB_LINEDOWN: nUpDown = -1; break; default: nUpDown = 0; break; } if (nUpDown == 0) { break; } ProcessInterpolateValue(nUpDown); return(0); case WM_LBUTTONDOWN: xPos = LOWORD(lParam); yPos = HIWORD(lParam); StartDrag(chart3d, xPos, yPos); break; case WM_LBUTTONUP: xPos = LOWORD(lParam); yPos = HIWORD(lParam); EndDrag(chart3d, xPos, yPos); break; case WM_MOUSEMOVE: xPos = LOWORD(lParam); yPos = HIWORD(lParam); ApplyDrag(chart3d, xPos, yPos); ApplyMoveLine(chart3d, xPos, yPos); break; case WM_RBUTTONDOWN: xPos = LOWORD(lParam); yPos = HIWORD(lParam); StartMoveLine(chart3d, xPos, yPos); break; case WM_RBUTTONUP: xPos = LOWORD(lParam); yPos = HIWORD(lParam); EndMoveLine(chart3d, xPos, yPos); break; case WM_SIZE: // resize the chart SizeChart(hwnd, (int) LOWORD(lParam), (int) HIWORD(lParam)); return(0); case WM_PAINT: hdc = BeginPaint(hwnd, &ps); DrawControls(hwnd, hdc); EndPaint(hwnd, &ps); break; case XRT3DN_REPAINTED: pcb = (Xrt3dCallbackStruct*) lParam; rectPainted = pcb->rectDamaged; ReDrawProfileLine(&rectPainted); return(0); case XRT3DN_MODIFY_START: EndDrag(chart3d, xPos, yPos); EndMoveLine(chart3d, xPos, yPos); return(0); case XRT3DN_MODIFY_END: return(0); /* * To properly handle colors the chart needs to be * notified about any system palette changes. */ case XRT3DN_PALETTECHANGED: SendMessage(Xrt3dGetWindow(chart3d), 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(chart3d), WM_QUERYNEWPALETTE, 0, 0); break; case WM_PALETTECHANGED: SendMessage(Xrt3dGetWindow(chart3d), 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, "profileicon"); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = GetStockObject(BLACK_BRUSH); wc.lpszMenuName = (LPSTR) "ProfileMenu"; wc.lpszClassName = (LPSTR) "Olchart_Profile"; if (!RegisterClass(&wc)) { MessageBox(NULL, "Cannot RegisterClass()", "Err! - TEST", MB_OK | MB_ICONEXCLAMATION); return(FALSE); } } hAccel = LoadAccelerators(hInstance, "ProfileAccelerators"); ghInst = hInstance; // create main window gMainHwnd = CreateWindow("Olchart_Profile", "Olectra Chart Demo - Profile", WS_OVERLAPPEDWINDOW, 0, 0, 700, 400, NULL, NULL, ghInst, NULL); if (!gMainHwnd) { return 0; } // create all controls in main window CreateControls(gMainHwnd); // setup the 3d data Setup3dData("profile.dat"); 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); XrtDestroy(chart2d); Xrt3dDestroy(chart3d); DeleteObject(hbrushBack); return(msg.wParam); }