//*************************************************************
//* *
//* 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);
}
/**************************************************************************/