Powerful Graphics Software Tools for Financial, Scientific and Industrial Applications




bullet Do you support time format axis labels, such as MM/DD/YY?

Yes and no. We have two routines to label axes with time/date formats: WGLabelAxisMonth, WGLabelAxisDayWk. We do not have a routine to automatically label axes in the MM/DD/YY format. Use WGLabelAxisStrings to label axes with any type of labels that can be represented as strings.

bullet Is it possible to allow label functions such as WGLabelAxis to place the labels in a vertical direction like it can be done using WGText? WGText has that last argument nOrientation.

Give the WGChangeFont routine a try. It has an orient parameter where you can specify an angle. I believe this function will work for axes labels, both text and numeric, even though it is not documented as such.



bullet How do I add or remove items (both symbols and text) from a legend if I hide or show a particular [line plot, etc.] object that is included in the legend? Calling WGShowObject with TRUE or FALSE will not affect the legend display to reflect the visible objects in the graph.

True, calling WGShowObject on a plotting object will not affect the visibility of specific items in a legend window. There are 2 alternative methods for handling the display of objects in the legend window:.

A.) Forgo the use of our WGLegend... routines and manually create a legend window yourself with a combination of a rectangle (WGRectangleNorm), lines (WGLineNorm), symbols (WGPolygonNorm), and text (WGTextNorm).

B.) The routine WGChangeString can be used to modify the text strings found in the legend window. If you are using line plot objects, you can accomplishing hiding and/or showing the line object and legend symbols by changing the line style to PS_NULL, by making a call to WGChangeLineStyle. Changing the line style back to something other than PS_NULL will again make the line plot visible in the graph and its associated symbol visible in the legend window.

The sample code below creates a legend window that initially contains 3 items; one of the line plots is hidden in both the graph and legend by using a line style of PS_NULL. In addition, 4 legend strings are initially defined, but the 4th string text is NULL (""):

// set line style of actual plot to RED
WGSetLineStyle(pGrDesc, hdc, PS_NULL, 2, C_GREEN);
hLine2 = WGLinePlot(pGrDesc, hdc, hData4, FALSE, TRUE); 

hStr1 = GlobalAlloc(GPTR, 4 * LG_MAXLEN);
lpLegendStr = (LPSTR)GlobalLock (hStr1);

// Initialize legends
lstrcpy(lpLegendStr, "Measured Values");
lstrcpy(lpLegendStr + LG_MAXLEN, "Predicted Values");
lstrcpy(lpLegendStr + 2 * LG_MAXLEN, "Residuals");
lstrcpy(lpLegendStr + 3 * LG_MAXLEN, "");

hLegend = WGLegendPtr(pGrDesc, hdc, 0.01, 0.79, 0.61, 0.99,

Now, based on a user action, the graph is updated to display the 4th plotting object - a line plot, and the 4th legend string is updated using WGChangeString. The last parameter in WGChangeString in this case specifies which legend string to change:

void UpdateGraph(void)
WGChangeLineStyle(pGraph1, hLine2, PS_SOLID, 0);
WGRedrawObject(pGraph1, hLine2, TRUE);

WGChangeString(pGraph1, hLegend, "Fourth", 3);
WGRedrawObject(pGraph1, hLegend, TRUE);

bulletHow do I remove an object from the legend rectangle?

There is no simple way to remove items from a legend, but there is a work-around. You will be able to temporarily remove an item from a legend (and the graph), but you will not be able to get the legend to redraw to take up the space left by the missing legend.

What you need to do is hide the line plot object as ususal with WGShowObject. Then, to remove the item (string + line) from the legend, call WGChangeLineColor for the line object, changing it to be the same as the bg color for the legend, and then redraw both the line plot object and the legend object. Some pseudo code that I tested under C in the demo program BIGDEMO is:

WGChangeLineColor(pGraph2, hLine, C_WHITE, 0);
WGRedrawObject(pGraph2, hLeg, TRUE); 
WGRedrawObject(pGraph2, hLine, TRUE);

I added this code to execute in response to a right mouse click, and it successfully removed the line from the graph, and removed both the line symbol and the string from the legend rectangle. The same idea can be used to add the items back in again.



bullet What are the differences between the 3 metafile types supported in WGSavePageMeta?

The 3 supported metafile types and their descriptions are:

MF_WIN Standard Windows metafile
MF_PL Placeable metafile
MF_ENH Enhanced metafile

Graphs saved as metafiles can be imported by various applications. In general, the placeable metafile type is the best to use for both 16-bit and 32-bit applications, since a number of application programs support the import of this type. The MF_WIN type is an older type that placeable has improved upon. The enhanced metafile type is a new type, which can be imported only into 32-bit applications which support this format.

A placeable metafile is a standard Windows metafile that has an additional 22-byte header. The header contains information about the aspect ratio and original size of the metafile, permitting applications to display the metafile in its intended form. Some popular applications can import only placeable metafiles.

The enhanced metafile format has been introduced in Win32 API. It is not supported for 16-bit programs and it is not implemented in Win32s API.

bulletHow do I register my copy of a Quinn-Curtis product?

You should have received a registration card inserted right in the front of the manual (page 1). The registration card is a tear-off card found on the bottom of a cardboard page that has our licensing agreement printed on it. If you fill out and send in the card, you will then be added to our registration database, which entitles you to technical support and puts you on our mailing list for receiving new product update and revision announcements. You can also register on-line at our web site.

bullet Can I use RGB colors for line plots, and if so, how?

Yes, you can use RGB colors for line plots, etc. First create the object as usual using one of the pure colors (i.e. C_BLUE) and after the object is created, make a call to WGChangeLineColorRGB

bullet Why can't I have a line width greater than 1 when using a line style other than PS_SOLID? Is this a bug?

This is not a bug. The Windows API does not support line styles other than SOLID with line widths greater than 1. I believe this limitation is removed under Windows NT through a different implementation, but we have not made any adjustments in our software.

bullet How do I highlight a section of a graph by "backlighting" a portion of a graph, allowing the background behind a section of a data trace to have a specified color?

Use the WGRectangle function to create a "highlight" rectangle. Then be sure to create this rectangle with this function before you create your data plot (with WGLinePlot, for example), so that the rectangle will be drawn behind the data plot object. You can change the size and/or the position of this highlight rectangle at a later time with a call to WGChangeObjectCoord.

bullet(VB ONLY) I want to plot values, sampled by an a/d, real time. These values are stored and then plotted on a static plot when the measurement is finished. I would like to use either cursors or zooming to select an area of the static plot. However the functions which switch on the zoom or cursors are not declared in the file WRGLOBAL.BAS. They are declared in VBGLOBAL.BAS, but both files cannot be included in the same project because of the double declaration of many functions.

Some background will help you to understand why you can't easily use zooming and data cursors in a Real-Time application. A Charting Tools application uses the VBHOOK.DLL for mouse events, etc., which includes the implementation for both the zooming and data cursor routines. Since RT Graphs can not properly be zoomed, and since data cursors can not "trace" real-time data sets, both zooming and data cursors are not supported for real-time graphs. A RT Tools application uses the VBRTHOOK.DLL, which does not include zooming and data cursor routines for that reason. The problem comes in cases like yours, where the application is truly a RT application, but uses both real-time graphs and static graphs together (which is perfectly correct, yet rare).
Since VBRTHOOK is the hook file used for this app., you do not have immediate access to the zooming and cursor routines for your static graph.

The resolution to this is a modification of the VBRTHOOK.DLL to include zooming and cursor support, and adding the function declarations for these routines to the WRGLOBAL.BAS file. You are correct in your assessment that both the WRGLOBAL.BAS file and the VBGLOBAL.BAS file cannot be used together in a VB project, since they have duplicate functions. The steps you need to perform to get things working are quite straightforward, and a general outline is as follows:

1.) Copy the function declarations for the zooming and cursor routines out of VGLOBAL.BAS (the 32-bit or 16-bit section) and add them to the declaration section of WRGLOBAL.BAS. Be sure to change the library name referenced in each declaration from VBHOOK32.DLL to VBRTHK32.DLL (or VBHOOK.DLL to VBRTHOOK.DLL).
2.) Implement zooming in VBRTHK32.DLL by:
- copying the code used for zooming and data cursors from the VBHOOK.C file into the VBRTHOOK.C. Be sure to include VBCURSOR.H. Most of the code is in the WGGraphMouseEvent routine, and in some additional support functions at the end.
3.) Rebuild the VBRTHK32.DLL with the changes, copy it to the proper directory, and everything should work fine.
- be sure to add VBCURSOR.C to the project file before rebuilding.

bulletCan WCT/RT functions be called from a user written DLL?

Yes. Link QCWINIT and HOOK with your DLL instead of your .EXE file.



bullet How do I add a graphical object to my graph AFTER it has been already built?

Use WGShowObject(..., FALSE) to initially create the object and make it invisible. Then, at a later time, use WGShowObject(..., TRUE) to display the specified object.


How to add annotations (text strings or arrows, etc.) to graph at run-time, after the graph is already built (i.e. outside of the graph building routine)?

Same as above, but using WGText, WGTextNorm, WGArrow, WGArrowNorm, etc. routines to draw annotations. The position of objects can be changed with the functions WGChangeObjectCoord and WGChangeObjectCoordNorm.


HGOBJ hLine1, hArrow1;

hLine1 = WGLine(...) // create line object in graph
hArrow1 = WGArrow(...) // create arrow object in graph
WGShowObject(pGrDesc, hLine1, FALSE) // make line invisible
WGShowObject(pGrDesc, hArrow1, FALSE)// make arrow invisible
do graphs
// later time(based on user action)
WGShowObject(pGrDesc, hLine1, TRUE) 
WGShowObject(pGrDesc, hArrow1, TRUE) 
// now the line and arrow will be visible 


bullet How do I add/delete graphical objects from my graph, outside of my graph building routine?

For additions, see the question above. Deletions can be done with WGDeleteObject, as well.

bulletHow to create an object (line, arrow, text, etc.) based on user action, after the graph was built?

Objects cannot be actually added after the graph is built. The way around this is to create some extra dummy objects and make them invisible (WGShowObject). When needed, position them correctly (WGChangeObjectCoord) and make them visible.

bulletHow to make a line plot (etc.) appear only after the user selects data to plot and sets the plot object parameters?

1. Create a line plot object in your graph building routine, it may be based on a dummy empty data set. Keep its handle for future actions.
2. Make this object invisible using WGShowObject
3. When the user selects data arrays, create the new data set based on them.
4. Connect this data set to the hidden plot object with WGReconnectDataSet (see example in DYNDEMO).
5. Select the line plot object using WGSelObject
6. Call WGEditObject as in HOOK.C - this will bring up the dialog.
7. Finally, make the object visible with WGShowObject.

bullet Do you have a line marker function that will not place markers at every data point but will place them at a specified interval or skip factor?

No, but this can be accomplished quite easily. Create an additional data set to be used for the "sampled" line marker plot, and define the data such that it only contains the data points (x and y values) of the points you want marked. You can the plot this with either the WGLineMarkerPlot function or use WGScatterPlot in conjunction with WGLinePlot on the original data set.

bulletHow to save and restore user changes to a graph?

For every object create small descriptors containing the values of the parameters used to create it. Save the current state of every object in these descriptors. When building the graph again, use these saved values.



bulletHow do I change the orientation of my printout for QC graphs?

Currently there is no way to change the printer output orientation through code; You MUST invoke the printer dialog (WGPrinterSetup) to change the printer orientation, or change the output orientation of your default printer. We use the common printer dialog to set printer settings. Calling WGPrinterSetup invokes this dialog, which is the default dialog that is associated with the selected printer driver. From this dialog, you can change the default printer settings, including the orientation. If you don't call WGPrinterSetup before printing, the output will use the default settings and the printer specified as DEFAULT (Control Panel, Printers). Also, calling WGSetPrintOptions (or WGPrintOptionsDlg) will allow you to set other printer parameters associated with the Quinn-Curtis page window.

bulletHow can I print multiple graphs on a page?

You have two options for printing with our tools - to print a single graph (WGPrintGraph) or to print all of the graph windows "contained" on a page window (WGPrintPage). Therefore, to print multiple graphs on a single output page, create them using separate calls to WGCreateGraph, in the same page window (1 call to WGCreatePage) and use WGPrintPage or select Print Current Page from the Page Menu.


bulletHow to print a graph together with some other things (as part of a document)?

Save it as a metafile (or to clipboard) and the import it into the document.

bullet How to print (or send to metafile) a graph without showing it on the screen?

Use WGCreateInvisiblePage instead of WGCreatePage.



bulletHow do I add a (static) vertical line to my RT graph?

Use WGLine or WGLineNorm (call WGSetLineStyle first to set line attributes). The line will eventually become partially erased by your real-time plot updates, so use WGRedrawObject(..., ...,hLine) at periodic update (timer) intervals to refresh the line.

bullet Can I combine both RT graphs and static plots created with the Charting Tools in the same graph window (use the same plotting area)?

Yes. As explained in the FAQ above, that static plots may be erased when the real-time plot is updated with new data. You can periodically refresh the static data plots by calling WGRedrawObject.

bullet How can I change the color of the text used on buttons created with WRSetButtonControl, WRSetButtonGroup?

Use WGSetTextByName or WGSetTextParams first. All of the demo programs referenced in the doc. under WRSetButtonControl - ACQDEMO, FETALMON, SCADA, use one of the two functions. (WGChangeTextColor does not work for button controls, so you can't change the color after the button control is already built without closing and recreating it, or looking at the source code and writing directly into the control's structure.)

bullet How can I change the range of values used for a scroll bar control?

This is not supported without closing and re-creating the graph with different settings for the scroll bar control. You also have the option, if you have the source code, to look at the creation of the scroll bar control and determine how to write the limit and range parameters to the scroll bar structure yourself.

bullet I want to clear the plotting area of the graph and start updating my real-time graph from the starting (left-hand) edge again with new values, without closing or deleting the graph window.

Use WRResetScroll.


bullet How do I change the line color/style of a line in a dynamic scrolling graph?

Use WGChangeLineColor, WGChangeLineStyle, where parameter n will correspond to the channel number (trace #).

bullet Can I have two (or more) different scrolling plots in one graph that use different Y axis scales?

Yes. Multiple Y axes are supported in a RT Graph - i.e. two different scrolling graphs (plots) can be plotted against two Y axes with different scales. To accomplish this, the sequence of calls is basically the same as explained above for the Charting Tools, Simply create the X axis and the first Y axis, then plot a data set using WRSetScrollGraph, then create the second Y axis by setting its intercept and drawing it, then plot your second graph.

EXAMPLE (Modified SWEEPDEM, DrawP1G2 routine)

// First Sweep Graph

WGSetPlotArea(pGrDesc, hdc, 0.2, 0.18, 0.90, 0.82, C_GRAY);

WGScalePlotArea (pGrDesc, 20.0, -2.0, 0.0, 2.0);

WGSetXYIntercepts (pGrDesc, 20.0, -2.0);

hAxisX = WGDrawXAxis(pGrDesc, hdc, 5.0, 5, POS_MIDDLE);
hAxisY = WGDrawYAxis(pGrDesc, hdc, 1.0, 1, POS_LEFT);

WGLabelAxis(pGrDesc, hdc, hAxisX, POS_BELOW, NF_DECIMAL, 
WGLabelAxis(pGrDesc, hdc, hAxisY, POS_LEFT, NF_DECIMAL, 
1, LL_ON, NULL);

WRSetSweepGraph (pGrDesc, ...);

// Second Sweep Graph 
WGScalePlotArea (pGrDesc, 20.0, 0.0, 0.0, 10.0);

WGSetXYIntercepts (pGrDesc, 0.0, 0.0);

hAxisY2 = WGDrawYAxis(pGrDesc, hdc, 0.5, 1, POS_RIGHT);
WGLabelAxis(pGrDesc, hdc, hAxisY2, POS_RIGHT, NF_DECIMAL, 
             1, LL_ON, NULL);

WRSetSweepGraph (pGrDesc, ...);
bullet I am using the Real-Time Graphics Tools with Visual C++ and MFC. I converted my software from Visual C++ version 2.x to VC++ 4.x. Whey are the axes grid lines and alarm lines no longer refreshed in the real-time graphs?

There is a bug in MFC 4.2 which interferes with timer callbacks. IN the RT Tools, the grid lines and alarm lines are updated in our DLLs using timer messages. This bug and the work around is documented in the Microsoft Knowledge Base article Q154652, dated Sept. 1996.

The work around to the problem is to override PreTranslateMessage in the thread that owns the timer. In a simple MFC program this means overriding the PreTranslateMessage member function of the CWinApp derived class.