//************************************************************* //* * //* Copyright (c) QUINN-CURTIS, Inc., 1992 - 1998 * //* * //************************************************************* //* * //* Filename : easygraf.c * //* Author : RQ * //* Revision : 3.0 * //* Date : August 15, 1998 * //* Product : Charting Tools for Windows * //* * //* Description: Example of building one graph with * //* Windows Charting Tools * //* * //************************************************************* /* This example demonstrates how easy it is to add charting capability to a Windows program. Most of the work is done by the DrawP1G1 graph building function. A single, simple graph is created in a parent page window. Once it has been created, the page can be moved and resized in typical windows fashion. A number of dialog boxes are automatically made available for editing graph objects such as: * line plot characteristics * data * x axis characteristics * y axis characteristics * x axis label characteristics * y axis label characteristics * plotting area positioning and background colors * titles (x axis, y axis and graph) A dialog box is selected by double clicking on the object you wish to edit. A menu also appears at the top of the graph ("PageMenu" in the resource file) which can, among other things, save the graph as a Windows Metafile (suitable for importing into spreadsheets and word processors), set up a printer, then send the graph to a printer. The project for this demo includes: EASYGRAF.C EASYGRAF.RC HOOK.C QCWINIT.C MWCT32D.LIB */ #include <windows.h> #include <stdlib.h> #include <math.h> #include "qcwin.h" #include "menus.h" #include <time.h> #define NUMP1 100 // number of data points HINSTANCE hInst; // global instance handle HGLOBAL hX1, hY1; // global memory handles to data char szAppName[] = "Demo"; /* Class Name used in call to CreateWindow. */ // Prototypes of forward referenced functions LRESULT CALLBACK MainWndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); BOOL InitApplication(HINSTANCE); BOOL InitInstance(HINSTANCE, int); void CALLBACK StartGraphs1 (PPAGE_DEF pPageDesc); void CALLBACK DrawP1G1 (PGRAPH_DEF pGrDesc, HDC hdc); BOOL CALLBACK AboutProc (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); realtype randreal(void); /******************************************************* FUNCTION: WinMain (HINSTANCE, HINSTANCE, LPSTR, int) PURPOSE: calls initialization function, processes message loop ********************************************************/ int PASCAL WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { MSG msg; if (!hPrevInstance) if (!InitApplication(hInstance)) return (FALSE); if (!InitInstance(hInstance, nCmdShow)) return (FALSE); // Message loop while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); }; return (msg.wParam); } /******************************************************* FUNCTION: InitApplication (HINSTANCE) PURPOSE: Initializes window data and registers window classes ********************************************************/ BOOL InitApplication (HINSTANCE hInstance) { WNDCLASS wc; // main window class wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = MainWndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = LoadIcon(hInstance, "LOGO"); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH) GetStockObject( LTGRAY_BRUSH); wc.lpszMenuName = "MainMenu"; // main window menu wc.lpszClassName = szAppName; return (RegisterClass(&wc)); } /******************************************************* FUNCTION: InitInstance(HINSTANCE, int) PURPOSE: Saves instance handle and creates main window ********************************************************/ BOOL InitInstance (HINSTANCE hInstance, int nCmdShow) { HWND hwnd; // save current instance - MUST BE HERE hInst = hInstance; hwnd = CreateWindow ( szAppName, // Create main window "Quinn-Curtis Easy Demo", // Main window title WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL ); if (!hwnd) return (FALSE); ShowWindow(hwnd, nCmdShow); UpdateWindow(hwnd); return (TRUE); } /************************************************************************* Main window procedure **************************************************************************/ LRESULT CALLBACK MainWndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_RBUTTONDOWN: // When the right mouse button is pressed, the // page is created in the current window WGCreatePage("PAGE1", // page ID string hwnd, // handle to the parent window hInst, // application instance handle "First Graph", // Window title string StartGraphs1, // pointer to graph creation function "PageMenu", // Name of page window menu in resource file C_LIGHTGRAY, // window background color MM_PROPORT, // window sizing mode 0L, // window style - default PAGE_CLIENT, // window initial size and position option 0, 0, 0, 0); // initial window size and position // if used (not used here) return 0; case WM_COMMAND: { if (wParam == IDM_ABOUT) { DialogBox(hInst, /* current instance */ "AboutBox", /* resource to use */ hwnd, /* parent window handle */ (DLGPROC)AboutProc); /* AboutProc() instance address */ } } return 0; case WM_PAINT: // paint main window { PAINTSTRUCT ps; HDC hdc = BeginPaint(hwnd, &ps); RECT rect; int verWCTMain, verWCTSec; // version of Charting Tools char szVer[50] = {"Charting Tools version " }; char szVerNum [10]; LPSTR pDate; // function calls to repaint main window go here GetClientRect (hwnd, &rect); SetTextAlign (hdc, TA_BASELINE | TA_CENTER); TextOut(hdc, rect.right / 2, rect.bottom / 2, "Press Right Mouse Button !", 26); // Display version of the tools verWCTMain = WGGetVersion (&verWCTSec); wsprintf (szVerNum, "%d.%d", verWCTMain, verWCTSec); lstrcat (szVer, szVerNum); if ((verWCTMain > 2) || (verWCTSec >= 20)) { pDate = WGGetDate(); lstrcat (szVer, ", "); lstrcat (szVer, pDate); } SetWindowText (hwnd, szVer); EndPaint(hwnd, &ps); } return 0; case WM_DESTROY: WGCleanup(TRUE); // clean up charting tools memory // and free data arrays PostQuitMessage(0); return 0; } return (DefWindowProc(hwnd, message, wParam, lParam)); } /********************************************************************** Routine StartGraphs1 is called by the Quinn-Curtis Windows Charting Tools when a page is created. It must be filled by the user, normally with functions WGCreateGraph that initialize individual graphs. ***********************************************************************/ void CALLBACK StartGraphs1(PPAGE_DEF pPageDesc) { int i; realtype z; static BOOL fInit = TRUE; LPREAL lpX1, lpY1; // create simulation data for plot /*--------------------------------------------------------------*/ if (fInit) // do not initialize data twice { // allocate global data arrays hX1 = GlobalAlloc (GPTR, sizeof (realtype) * NUMP1); hY1 = GlobalAlloc (GPTR, sizeof (realtype) * NUMP1); // get pointers to data arrays lpX1 = (LPREAL) GlobalLock(hX1); lpY1 = (LPREAL) GlobalLock(hY1); // create x and y data to be plotted for (i = 0; i < NUMP1; i++) { z = (realtype) i; lpX1 [i] = z; lpY1 [i] = 20 + 15.0 * cos(M_PI * z / (4.0+ 0.3 * randreal())) + 3.0 * randreal(); } fInit = FALSE; } /*--------------------------------------------------------------*/ // Initialize graph WGCreateGraph (pPageDesc, DrawP1G1, // points to function which builds graph 0.005, 0.005, // window relative position inside parent page window 0.99, 0.99, C_WHITE, // white background C_RED, // red border 1); // border width in pixels } /******************************************************* Builds the graph using Q-C Windows Charting Calls ********************************************************/ void CALLBACK DrawP1G1 (PGRAPH_DEF pGrDesc, HDC hdc) { HGOBJ hAxisX, hAxisY; // axes handles HDATA hDataSet; // data set handle // define a dataset hDataSet = WGDefineDataSet ("60 Cycle Noise", hX1, hY1, NUMP1); // define the plotting area of the graph WGSetPlotArea(pGrDesc, hdc, 0.15, 0.15, 0.9, 0.80, C_LIGHTGRAY); // axes to be drawn in solid, black, 1 pixels thick WGSetLineStyle(pGrDesc, hdc, PS_SOLID, 1, C_BLACK); // set current font to Arial, 12 points, bold WGSetTextByName (C_BLACK, "Arial", 12, TEXT_BOLD); // analyze the data set and automatically scale the // plot area, draw and label the axes WGAutoAxes(pGrDesc, hdc, hDataSet, AS_ROUNDCLOSE, INTF_ZERO, &hAxisX, &hAxisY, NULL, NULL); // set line style of actual plot to RED WGSetLineStyle(pGrDesc, hdc, PS_SOLID, 2, C_RED); // plot the data WGLinePlot (pGrDesc, hdc, hDataSet, FALSE, FALSE); // Write axes titles WGTitleAxis(pGrDesc, hdc, hAxisX, POS_BELOW, "Sample Interval"); WGTitleAxis(pGrDesc, hdc, hAxisY, POS_LEFT, "Volts"); // set current font to Arial, 16 points, bold, italic WGSetTextByName (C_GREEN, "Arial", 16, TEXT_BOLD | TEXT_ITAL); // Write graph title WGTitleGraph(pGrDesc, hdc, "Input Waveform"); } /***********************************************************************/ /* random real number generator in the range of 0.0 to 1.0 */ /***********************************************************************/ realtype randreal(void) { return (realtype)rand()/(realtype)RAND_MAX; } /************************************************************************** FUNCTION: AboutProc(HWND, UINT, WPARAM, LPARAM) PURPOSE: Processes messages for "About" dialog box ****************************************************************************/ BOOL CALLBACK AboutProc (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_INITDIALOG: return (TRUE); case WM_COMMAND: if (wParam == IDOK || wParam == IDCANCEL) { EndDialog(hDlg, TRUE); return (TRUE); } break; } return (FALSE); } /**************************************************************************/