Chinaunix首页 | 论坛 | 博客
  • 博客访问: 5381721
  • 博文数量: 671
  • 博客积分: 10010
  • 博客等级: 上将
  • 技术积分: 7310
  • 用 户 组: 普通用户
  • 注册时间: 2006-07-14 09:56
文章分类

全部博文(671)

文章存档

2011年(1)

2010年(2)

2009年(24)

2008年(271)

2007年(319)

2006年(54)

我的朋友

分类: C/C++

2008-09-14 20:17:47

Sample Image

Introduction

Recently I was working in a project in which I had to draw data from a radio (or a spectrum analyzer). I reviewed all charting controls in CodeProject but none seemed to be useful for me. So, I managed to code it myself. In addition to simple charting, this controls also supports Zoom In/Out and scrolling. One can also discriminate higher data by another color as is seen in the picture.

Using the code

First of all, place a Picture control on your dialog. Change its ID to IDC_SPECTRUM_STATIC and its type from Frame to Rectangle. Change control's width and height to make it fit. This control will be created at run-time. Add #Include "SpectrumAnalyzer.h"; to your dialog's header file. Add a member variable to dialog for this control:

public:
    CSpectrumAnalyzer m_SpectrumAnalyzer_Ctrl;

Now, place this piece of code wherever you want to create the control:

DWORD m_iStartFreq = 100000000, 
    m_iStopFreq = 150000000;  

CPoint ptRangeX(m_iStartFreq, m_iStopFreq),  // Freq. Range : 100-150 MHz 
    ptRangeY(0, 120);  // Signal Strength Range: 0-120 units

CRect rect; 
// Get the rectangular coordinates of the rectangle we already placed on dialog
GetDlgItem(IDC_SPECTRUM_STATIC)->GetWindowRect(rect);

// Convert to the client coordinates
ScreenToClient(rect);

// remember to destroy it if it was created before
if (m_SpectrumAnalyzer_Ctrl)
    m_SpectrumAnalyzer_Ctrl.Destroy();

// Create and place the spectrum control on screen
m_SpectrumAnalyzer_Ctrl.Create(rect, this, IDC_SPECTRUM_STATIC, ptRangeX, ptRangeY);

The control is simply created by the above statements. ptRangeX defines horizontal bounds and ptRangeY defines vertical bounds.

Features

These are the public member functions and their descriptions:

// Add a new point
void AddPoint(CPoint CurPos);

// Draw all viewable data
void DrawLine();

// Write(draw) some text on the control
void DrawText(CPoint Pos, CString szStr);

// Clear all the drawing in the control
void Clear();

// re-draw grids, re-write labels
void UpdateLabels();

// clear list of data 
void ClearList();

// return number of points in the control
int GetPointCount() { return m_pList->GetCount();}

Deep Inside

Using a doubly-linked list to maintain data, the control determines which data points should be drawn (considering scroll position) and draws them.

The control defines three different scales: Actual data (point), Axis and View. Any data you provide is in the scales provided by ptRangeX and ptRangeY. The size of the control you place on dialog determines Axis scale. But, as is seen in the picture, user can define margins for top, bottom, left and right for the grids in the control. This defines View scale. So, any data you add to the list, should pass two stages to get drawn: conversion from Point to Axis (by MapPointToAxis() function), and conversion from Axis to View scale (by MapAxisToView() function).

In addition, you can change the color of background, grid, text, drawing pen and high-region pen by changing these variables in the constructor: m_crBackGround, m_crGrids, m_crText, m_crDrawPen and m_crIndicatorPen.

Advanced Features

Because this control was mainly written to be used as a receiver software, there are some extra features in it. You can highlight above-threshold data by using SetVHighIndicator() function.

Control can also send callback messages to parent dialog. Control sends WM_USER_SET_TO_FREQ message whenever user wants to set the radio to a new frequency by left-clicking the mouse while CTRL key is held. WM_USER_SHOW_CURRENT_FREQ message is sent when user moves the mouse over the control. You may want to use this message to show frequency at the pointer.

Use these functions to set callback functions to those messages:

// Set the Callback message that control sends when
// user clicks the control to set to a frequency
m_SpectrumAnalyzer_Ctrl.SetCallbackSetToFreq(m_hWnd, WM_USER_SET_TO_FREQ); 

// Set the Callback message that control sends when user moves the mouse over control 
m_SpectrumAnalyzer_Ctrl.SetCallbackShowFreq(m_hWnd, WM_USER_SHOW_CURRENT_FREQ);

where m_hWnd is the handle to the window that gets the messages.

How to improve?

One can revise the drawing section to improve speed. I think scrolling section is not wise, because it simply re-draws all the content in the window. One can use some API functions that "move" that portion of the image that is not changed by scrolling. Also, some function is needed for vertical scrolling. I have not written it here.

History

  • First version: 10/May/2004.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found

阅读(834) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~