VC炒股软件开发
文档说明:
此文档适合VC++的初学者,高手也可参考(希望能提出宝贵意见)。
开发前准备:
这是一个根据股票信息的数据绘的几个制界面,数据来源通信达软件的数据文件,通常在安装了通信达以后并下载数据到本地以后就有了。
1.数据文件的准备:
假如你安装通信达的目录是:D:\jcb_gx。那么对应的数据文件就在D:\jcb_gx\vipdoc\目录下,里面每一个目录下就是一类股票的数据,我们开发这个界面需要用到的是每个目录下的lday目录下的.lday后缀名的文件。每一个文件里面存放的是一支滚票的数据信息。我当时开发用到了两类股票的信息,分别对应的目录是:D:\jcb_gx\vipdoc\sh\lday和D:\jcb_gx\vipdoc\sz\lday。其实每类开发的方法完全一样,唯一不同就是读取不同的目录而已。
2.文件数据结构:
准备好数据以后,还有一点是必须知道的,不然也没有办法进行下去,就是文件里面的数据格式是怎样的。因为我用的是通信达的数据文件,所以只需要在www.g.cn查询通信达的数据格式就可以了,如下:
typedef struct
{ //共32字节
int date; //4字节 如20091229
int open; //开盘价
int high; //最高价
int low; //最低价
int close; //收盘价
float amount; //成交额
int vol; //成交量
int reservation; //保留值
} StockData;
详细开发过程(包括我的思路和具体实现):
1.实现如上图的界面,需要做如下事情
(1)读一个目录下的所有文件,并从文件名中提取出相应股票的代码
可行性分析:
首先我们打开的是一个目录,然后从这个目录中读出里面所有的文件名,目录存放的内容其实就是此目录下的文件名或目录名。用到两个函数,一个FindFirstFile查找到一个目录下的第一个文件名,另一个FindNextFile查找下一个文件名。这样就可以遍历一个目录下的所有文件名了。
具体实现:
BOOLCTongXinDaView::ReadFileData(LPCSTR path)
{
//path是这种形式的参数:D:\\jcb_gx\\vipdoc\\sh\\lday\\*
m_iCount = 0;
WIN32_FIND_DATA tFind = {0};
int i = 0;
CString strTemp;
HANDLE hSearch = ::FindFirstFile(path, &tFind);
if (hSearch == INVALID_HANDLE_VALUE)
{
return FALSE;
}
//过滤掉.和..文件
::FindNextFile(hSearch, &tFind);
while (::FindNextFile(hSearch, &tFind))
{
strTemp.Format("%s",tFind.cFileName);
m_File[i].Format("%s",path);
//去掉查询用到的*通配符
m_File[i] =m_File[i].Left(m_File[i].GetLength()-1);
m_File[i] +=strTemp;
//从文件名中提取股票代码
m_FileName[i] =strTemp.Mid(2, 6);
i++;
}
m_iPageCount = i / 31 + 1; //求出需要显示的总页面数
m_iLeave = i % 31; //最后一页显示的数据
m_CurrFile = m_File[m_iCount]; //保存选中的文件名
::FindClose(hSearch);
return TRUE;
}
注意事项:每一个目录下都有这两个目录文件:“.”和“..”。它们分别代表本目录和父目录(就是上层目录),必须过滤掉这两个目录文件。还好每次这两个目录文件总是最先被读出,所以前两次读出来的信息直接不管就可以了。
上面的函数被相应的每一个菜单项事件调用,就是针对不同的股票用一个菜单项打开。
(2)页面的显示:
可行性分析:
先说说我当时需要完成的现实任务,每页显示31行(具体可以变动,但是31 行效果比较好),显示3列,第一列索引号,也就是起个计数的作用,第二列就是刚才我们提取到的股票代码号,第三列随便填充4个汉字。还要求画一条线表示当前选中的股票,鼠标上下滚动和PageDown,PageUp按键实现上下翻页功能,鼠标点击选中点击最近的一支股票,按键上下键也可以移动股票选择。明白了需要实现的功能,我现在就一步一步来完成。这里需要用到文字输出函数DrawText。
具体实现:
void CTongXinDaView::DrawText(CDC *pDC, int page)
{
CRect rt;
GetClientRect(&rt);
int high = rt.Width() / 55;
int y = high;//控制每一行显示数据的增量
CString strLine;
int number = 1;
pDC->SetBkMode(TRANSPARENT);
pDC->SetTextColor(RGB(200, 200, 200));
strLine.Format(" 代码 名称 日期 开牌价 最高价 最低价 收盘价 多多 成交量 ");
pDC->TextOut(0, 0, strLine);
//控制最后一页只显示剩余的
if (page == m_iPageCount-1)
{
for (int i=page * SCREENHEIGHT; i<(page*SCREENHEIGHT + m_iLeave); i++)
{
if (i == m_iCount)
{
CPen pen(PS_SOLID, 1, RGB(255, 255, 0));
CPen *pOldPen = pDC->SelectObject(&pen);
pDC->MoveTo(50, y+high-5);
pDC->LineTo(rt.right, y+high-5);
pDC->SelectObject(pOldPen);
}
strLine.Format("%d", i+1);
pDC->DrawText(strLine, CRect(0, y, 40, y+high), DT_RIGHT);
pDC->DrawText(m_FileName[i], CRect(50, y, 100, y+hi