Measurement Studio for VC++

cancel
Showing results for 
Search instead for 
Did you mean: 

Charting zoom/pan control

Using Measurement Studio 7.0 with C#, I wasn't able to set my Chart into "Zoom mode" like I could in 6.0 with VB6. The only solution is to shift-click/ctrl-click.

Previously, I would use this code to create tool buttons the user could click on to set the chart into zoom mode and pan mode:

Private Sub Toolbar1_ButtonClick(ByVal Button As ComctlLib.Button)
Dim i As Integer
Select Case Button.Key
Case "ChartToolZoom":
For i = 0 To NUM_STRIP_CHARTS
strip1(i).TrackMode = cwGTrackZoomRectXY
Next
' set new mouse icon
FrmDataGraph.MousePointer = vbCrosshair

Case "ChartToolPan":
For i = 0 To NUM_STRIP_CHARTS
strip1(i).Tr
ackMode = cwGTrackPanPlotAreaXY
Next
' set new mouse icon
FrmDataGraph.MousePointer = vbSizeAll
Case "ChartToolZoomOut":
For i = 0 To NUM_STRIP_CHARTS
strip1(i).Axes(1).AutoScaleNow
strip1(i).Axes(2).AutoScaleNow
strip1(i).TrackMode = cwGTrackAllEvents ' cwGTrackDragCursor
Next
FrmDataGraph.MousePointer = vbDefault
'GraphHistory
Case "ChartToolPrint":
'CmdPrint_Click
End Select
End Sub

Any help setting up such a tool interface again with 7.0 would be greatly appreciated. Also, is there an easy way to print a chart?

Thanks,
Martin
0 Kudos
Message 1 of 5
(6,158 Views)
First, regarding the question about printing, here are several suggested links from MSDN about .NET Framework support for printing:



An example of how to print the graph with PrintDocument would be to add a PrintDocument component to your form, double click on the PrintDocument to generate an event for the PrintPage event, then do something like this (assuming you have a WaveformGraph or ScatterGraph called graph):

private void OnPrintDocumentPrintPage(object sender, PrintPageEventArgs e)
{
Rectangle bounds = new Rectangle(e.MarginBounds.Location, graph.Size);
ComponentDrawArgs args = new ComponentDrawArgs(e.Graphics, bounds);
graph.Draw(args);
}

When you're ready to print, call the Print method on the PrintDocument.

Regarding the ability to enable an interaction mode without keyboard modifiers, there is not a direct way to do this. The advantage of the keyboard modifiers is that it allows you to have multiple modes enabled at the same time and a way to easily switch between them interactively, but the disadvantage is that there's not an easy way to toggle them via toolbars as you're trying to do. This is good feedback and I will file a suggestion to consider this for a future release.

There is a way to workaround this by synthesizing the keystrokes for the interaction keyboard modifiers, though. Below is a helper class called AutoInteractionMode that will work with either WaveformGraph or ScatterGraph. To use it in your project, create a class member variable for the AutoInteractionMode, then initialize it in your constructor after the InitializeComponent call, like this:

public class MyForm : Form
{
private AutoInteractionMode _autoInteraction;

// This could be a ScatterGraph as well.
private NationalInstruments.UI.WindowsForms.WaveformGraph waveformGraph1;
// ...

public MyForm()
{
InitializeComponent();
_autoInteraction = new AutoInteractionMode(waveformGraph1);
}
}

Once this is hooked up, you can set the InteractionMode property to correspond to the modes that you're toggling via the toolbars, and the AutoInteractionMode should do the right thing when the mouse enters the plot area without the use of the keyboard modifier. Hope this helps.

- Elton

class AutoInteractionMode
{
private bool _mouseInPlotArea;
private bool _enabled;
private XYGraph _graph;

private const GraphInteractionModes PanMask = GraphInteractionModes.PanX | GraphInteractionModes.PanY;
private const GraphInteractionModes ZoomMask = GraphInteractionModes.ZoomAroundPoint | GraphInteractionModes.ZoomX | GraphInteractionModes.ZoomY;

public AutoInteractionMode(XYGraph graph)
{
if (graph == null)
throw new ArgumentNullException("graph");

_mouseInPlotArea = false;
_enabled = false;
_graph = graph;

Enabled = true;
}

public bool Enabled
{
get
{
return _enabled;
}

set
{
if (value && !_enabled)
_graph.MouseMove += new MouseEventHandler(OnGraphMouseMove);
else if (!value && _enabled)
_graph.MouseMove -= new MouseEventHandler(OnGraphMouseMove);

_enabled = value;
}
}

[StructLayout(LayoutKind.Sequential)]
private struct MOUSEINPUT
{
public int dx;
public int dy;
public int mouseData;
public int dwFlags;
public int time;
public int dwExtraInfo;
}

[StructLayout(LayoutKind.Sequential)]
private struct KEYBDINPUT
{
public short wVk;
public short wScan;
public int dwFlags;
public int time;
public int dwExtraInfo;
}

[StructLayout(LayoutKind.Sequential)]
private struct HARDWAREINPUT
{
public int uMsg;
public short wParamL;
public short wParamH;
}

[StructLayout(LayoutKind.Explicit)]
private struct INPUT
{
[FieldOffset(0)] public int type;
[FieldOffset(4)] public MOUSEINPUT mi;
[FieldOffset(4)] public KEYBDINPUT ki;
[FieldOffset(4)] public HARDWAREINPUT hi;
}

private const int INPUT_KEYBOARD = 1;
private const int KEYEVENTF_EXTENDEDKEY = 0x0001;
private const int KEYEVENTF_KEYUP = 0x0002;
private const int KEYEVENTF_UNICODE = 0x0004;
private const int KEYEVENTF_SCANCODE = 0x0008;

[DllImport("user32.dll")]
private static extern uint MapVirtualKey(uint uCode, uint uMapType);

[DllImport("user32.dll")]
private static extern uint SendInput(uint nInputs, [In] INPUT[] pInputs, int cbSize);

private static void SendKeyUp(Keys key)
{
Send(key, true);
}

private static void SendKeyDown(Keys key)
{
Send(key, false);
}

private static void Send(Keys key, bool keyUp)
{
INPUT[] input = new INPUT[1];
input[0].type = INPUT_KEYBOARD;
input[0].ki.wVk = (short)key;
input[0].ki.wScan = ((short)MapVirtualKey((uint)key, 0));
input[0].ki.dwFlags = ((IsExtendedKey(key) ? KEYEVENTF_EXTENDEDKEY : 0) | (keyUp ? KEYEVENTF_KEYUP : 0));
input[0].ki.time = 0;
input[0].ki.dwExtraInfo = 0;

SendInput(1, input, Marshal.SizeOf(typeof(INPUT)));
}

private static bool IsExtendedKey(Keys key)
{
return (((key < Keys.Space) || (key > Keys.F15)) && ((key != Keys.Tab) && (key != Keys.Enter) && (key != Keys.LineFeed)));
}

private void OnGraphMouseMove(object sender, MouseEventArgs e)
{
Point pt = new Point(e.X, e.Y);
if (_graph.PlotAreaBounds.Contains(pt))
{
if (!_mouseInPlotArea)
{
_mouseInPlotArea = true;
if ((_graph.InteractionMode & ZoomMask) > 0)
SendKeyDown(Keys.ShiftKey);
else if ((_graph.InteractionMode & PanMask) > 0)
SendKeyDown(Keys.ControlKey);
}
}
else
{
if (_mouseInPlotArea)
{
_mouseInPlotArea = false;
if ((_graph.InteractionMode & ZoomMask) > 0)
SendKeyUp(Keys.ShiftKey);
else if ((_graph.InteractionMode & PanMask) > 0)
SendKeyUp(Keys.ControlKey);
}
}
}
}
0 Kudos
Message 2 of 5
(6,158 Views)
I used your AutoInteraction-Class, and it works fine, I can do what i want to do. But now, after running my app, after closing my application, the shift-key is (not always) still "down". I thought about saving the settings of the keyboard at the initialization of my app, and then write it back at the end. Is this possible, and how?
0 Kudos
Message 3 of 5
(6,158 Views)

I'm having the same problem.  I want to using zoom and pan on a scatter graph via my touchscreen.

Is there meanwhile on option (properties?) in the scatter graph that allows to zoom without pressing the CTRL key?

 

Kind regards

0 Kudos
Message 4 of 5
(5,367 Views)

Hi,

 

Why don't you just do it (I mean why NI don't do it ???) It is so simple that my 8 years son would take 5 minutes to implement that.

 

Just add a property: GraphDefaultInteractionMode.ZoomAndPanXY

And the few lines for checking...

 

PLEASE !!!!!!!!!!!!!!!!!!!!! It is so simple  !!!!!!Smiley Happy

 

Mainly for scatterGraph please !

 

Thanks in advance

0 Kudos
Message 5 of 5
(3,775 Views)