不瞒您说,我那朋友是刚应聘到金牛公司的,急于想出成绩。
谢谢指点:
1、我是让分析家分析实时接受的数据呀,为什么要写通视卡的虚拟驱动程序?
2、能提供一些分析家存取数据的资料吗?
3、写vxd之类的东西是没问题的,但我实在不知道如何写这样一个东东,最好有详细的思路。
急盼回音。

解决方案 »

  1.   

    到www.tongshi.com.cn上下载一个接口规范,
      

  2.   

    我不是那个意思,我说的虚拟驱动程序不是VXD,是DLL。
    为什么要写通视卡的虚拟驱动程序?因为分析家的接口与通视卡的基本相同。
    我可以给你发分析家的接口的,给我你的EMAIL。
      

  3.   

    金牛是无线接收的,卡有串口和ISA两种,你肯定要知道一些硬件参数才也能写VXD
      

  4.   

    to  lgl
    是的,我非常需要分析家的接口,也就是说分析家是怎样读写数据的。我的地址是:[email protected],再次谢过。to Tasehouny(阿甘) 
    我已经有金牛的接口程序,谢谢指点。
    to alwaysakid()
    我马上到www.tongshi.com.cn去看看。
    to yoci(阿呸) 
    为朋友乃份内之事。再次感谢各位的指点。
      

  5.   


    /****************************************************************************************
    * 分析家证券投资分析系统行情接口规范V2.0
    * (适用于单向数据传输方式)
    ****************************************************************************************/
    ****************************************************************************************/
    * 驱动程序安装后,应该在系统注册库中注册以下信息,分析软件通过该注册信息启动动态库 *
    * HKEY_LOCAL_MACHINE/SOFTWARE/StockDrv 下 * 
    * Driver  = "驱动DLL全路径" *
    ****************************************************************************************/#ifndef __STOCKDRV_H__
    #define __STOCKDRV_H__// 工作方式类型定义
    #define RCV_WORK_MEMSHARE 2 // 内存共享直接引用//==================================== 数据结构 =================================================
    /*
    指数代号-名称
    1A0001  上证综合指数 1A0002  上证A股指数 1A0003  上证B股指数
    1B0001  上证工业指数 1B0002  上证商业指数 1B0004  上证地产指数
    1B0005  上证公用事业 1B0006  上证综合 1B0007  上证30指数2A01 深证成分指数 2A02 深证成分A 2A03 深证成分B
    2B01 深证工业     2B02 深证商业 2B03 深证金融
    2B04 深证地产 2B05 深证公共事业 2B06 深证综合
    2B07 深证基金 2C01 深证指数 2C02 深证A股
    2C03 深证B股
    */// 证券市场
    #define SH_MARKET_EX 'HS' // 上海
    #define SZ_MARKET_EX 'ZS' // 深圳
    #define HK_MARKET_EX 'KH' // 香港// 文件数据类型
    // 结构数组形式的文件数据
    #define FILE_HISTORY_EX 2 // 补日线数据
    #define FILE_MINUTE_EX 4 // 补分钟线数据
    #define FILE_POWER_EX 6 // 补充除权数据
    #define FILE_BASE_EX 0x1000 // 钱龙兼容基本资料文件,m_szFileName仅包含文件名
    #define FILE_NEWS_EX 0x1002 // 新闻类,其类型由m_szFileName中子目录名来定
    #define FILE_HTML_EX 0x1004 // HTML文件,m_szFileName为URL
    #define FILE_SOFTWARE_EX 0x2000 // 升级软件
    #define FILE_TYPE_RES -1 // 保留//Definition For nInfo of Function GetStockDrvInfo(int nInfo,void * pBuf);
    #define RI_IDSTRING 1 // 厂商名称,返回(LPCSTR)厂商名
    #define RI_IDCODE 2 // 卡号
    #define RI_VERSION 3 // 驱动程序版本#define STKLABEL_LEN 10 // 股号数据长度,国内市场股号编码兼容钱龙
    #define STKNAME_LEN 32 // 股名长度
    //////////////////////////////////////////////////////////////////////////////////
    //行情数据
    typedef struct tagRCV_REPORT_STRUCTEx
    {
    WORD m_wMarket; // 股票市场类型
    char m_szLabel[STKLABEL_LEN]; // 股票代码,以'\0'结尾
    char m_szName[STKNAME_LEN]; // 股票名称,以'\0'结尾

    float m_fLastClose; // 昨收
    float m_fOpen; // 今开
    float m_fHigh; // 最高
    float m_fLow; // 最低
    float m_fNewPrice; // 最新
    float m_fVolume; // 成交量
    float m_fAmount; // 成交额 float m_fBuyPrice[3]; // 申买价1,2,3
    float m_fBuyVolume[3]; // 申买量1,2,3
    float m_fSellPrice[3]; // 申卖价1,2,3
    float m_fSellVolume[3]; // 申卖量1,2,3
    } RCV_REPORT_STRUCTEx;//////////////////////////////////////////////////////////////////////////////////
    //补充数据头
    //数据补充头用于标识自动补充分时线、日线和除权资料时的股票代码
    //补充上述数据时,接收系统传给分析软件一个结构数组,数组可以是RCV_HISTORY_STRUCTEx,
    //RCV_MINUTE_STRUCTEx等结构,数量由RCV_DATA::m_nPacketNum决定。这些数组都是补充数据和
    //RCV_EKE_HEADEx结构的联合,若RCV_EKE_HEADEx::m_dwHeadTag==EKE_HEAD_TAG,则表示该结构是
    //RCV_EKE_HEADEx结构,用于指示其后的数据都是该股票的数据,直到下一个RCV_EKE_HEADEx结构
    //出现为止#define EKE_HEAD_TAG 0xfffffffftypedef struct tagRCV_EKE_HEADEx
    {
    DWORD m_dwHeadTag; // = EKE_HEAD_TAG
    WORD m_wMarket; // 市场类型
    char m_szLabel[STKLABEL_LEN]; // 股票代码
    }RCV_EKE_HEADEx;//补充日线数据
    typedef union tagRCV_HISTORY_STRUCTEx
    {
    struct
    {
    time_t m_time; //UCT
    float m_fOpen; //开盘
    float m_fHigh; //最高
    float m_fLow; //最低
    float m_fClose; //收盘
    float m_fVolume; //量
    float m_fAmount; //额
    WORD m_wAdvance; //涨数,仅大盘有效
    WORD m_wDecline; //跌数,仅大盘有效
    };
    RCV_EKE_HEADEx m_head;
    }RCV_HISTORY_STRUCTEx;//补充分时线数据
    typedef union tagRCV_MINUTE_STRUCTEx
    {
    struct{
    time_t m_time; // UCT
    float m_fPrice;
    float m_fVolume;
    float m_fAmount;
    };
    RCV_EKE_HEADEx m_head; 
    }RCV_MINUTE_STRUCTEx;//补充除权数据
    typedef union tagRCV_POWER_STRUCTEx
    {
    struct
    {
    time_t m_time; // UCT
    float m_fGive; // 每股送
    float m_fPei; // 每股配
    float m_fPeiPrice; // 配股价,仅当 m_fPei!=0.0f 时有效
    float m_fProfit; // 每股红利
    };
    RCV_EKE_HEADEx m_head;
    }RCV_POWER_STRUCTEx;//////////////////////////////////////////////////////////////////////////////////
    // 文件类型数据包头
    //  注一:
    // m_wDataType == FILE_BASE_EX
    // m_dwAttrib = 股票证券市场,m_szFileName仅包含文件名
    // m_FileTime = 基本面资料文件创建日期
    //  m_wDataType == FILE_NEWS_EX
    // m_dwAttrib = 消息来源,m_szFileName 包含目录的文件名,目录名为消息来源
    // m_dwSerialNo = 序列号
    // 如:  "上交所消息\\0501Z012.TXT","新兰德\\XLD0001.TXT"
    //  m_wDataType == FILE_HTML_EX
    // m_dwAttrib 保留, m_szFileName为URL
    // m_wDataType == FILE_SOFTWARE_EX
    // m_dwAttrib 分析软件类型, 用于初步判断
    // m_szFileName 分析软件 ID 特征字符串 + '\\' + 文件名
    // 如 "huitianqi\\SuperStk\\SuperStk.EXE",
    // ID 特征字符串为 "huitianqi", "SuperStk\\SuperStk.EXE" 为文件名
    // 特征字符串 和 文件名及其含义由分析软件商定义
    //  注二:
    // 数据文件循环播出,每个文件有唯一的序列号,以避免重复接收
    typedef struct tagRCV_FILE_HEADEx
    {
    DWORD m_dwAttrib; // 文件子类型
    DWORD m_dwLen; // 文件长度
    union
    {
    DWORD m_dwSerialNo; // 序列号,对股评
    time_t m_FileTime; // 文件创建时间
    };
    char m_szFileName[MAX_PATH]; // 文件名 or URL
    } RCV_FILE_HEADEx;//////////////////////////////////////////////////////////////////////////////////
    //  数据通知消息
    // wParam = RCV_WPARAM;
    //  lParam 指向 RCV_DATA结构;
    // 返回 1 已经处理, 0 未处理或不能处理#define RCV_REPORT 0x3f001234
    #define RCV_FILEDATA 0x3f001235// 注一:
    //   记录数表示行情数据和补充数据(包括 Header)的数据包数,对文件类型数据, = 1
    // 注二:
    //   若 m_bDISK = FALSE, m_pData 为数据缓冲区指针
    //  ******** 数据共享,不能修改数据 **********
    //  m_bDISK = TRUE,  m_pData 为该文件的存盘文件名,
    typedef struct tagRCV_DATA
    {
    int m_wDataType; // 文件类型
    int m_nPacketNum; // 记录数,参见注一
    RCV_FILE_HEADEx m_File; // 文件接口
    BOOL m_bDISK; // 文件是否已存盘的文件
    union
    {
    RCV_REPORT_STRUCTEx  * m_pReport;
    RCV_HISTORY_STRUCTEx * m_pDay;
    RCV_MINUTE_STRUCTEx  * m_pMinute;
    RCV_POWER_STRUCTEx  * m_pPower;
    void  * m_pData; // 参见注二
    };
    } RCV_DATA;/* 消息处理程序 DEMO
    LONG OnStkDataOK(UINT wParam,LONG lParam)
    {
    union tagSrcStock DOS_StkBuf;
    RCV_REPORT_STRUCTEx NEW_StkBuf;
    PBYTE pDataBuf;
    RCV_DATA Header;
    RCV_DATA * pHeader;
    STOCK * pStock = NULL;
    DWORD dwFileLen;
    int ok,i;
    pHeader = (RCV_DATA *)lParam;
    switch( wParam )
    {
    case RCV_REPORT: // 股票行情
    for(i=0; i<pHeader->m_nPacketNum; i++)
    {
    pHeader->m_pReport[i] ...
    // 数据处理
    }
    break; case RCV_FILEDATA: // 文件
    switch(pHeader->m_wDataType)
    {
    case FILE_HISTORY_EX: // 补日线数据
    for(i=0;i<pHeader->m_nPacketNum;i++)
    {
    if(pHeader->m_pDay[i].m_head.m_dwHeadTag==EKE_HEAD_TAG)
    {
    pStock = FindStock(pHeader->m_pDay[i].m_head.m_wMarket,
       pHeader->m_pDay[i].m_head.m_szLabel); //由股号查股票
    }
    else if(pStock)
    {
    AppendDayData(pStock,&pHeader->m_pDay[i]); //补充日线数据
    }
    }
    break;
    case FILE_MINUTE_EX: // 补分钟线数据
    ...
    break;
    case FILE_POWER_EX: // 补充除权数据
    ...
    break;
    case FILE_BASE_EX: // 钱龙兼容基本资料文件,m_szFileName仅包含文件名
    ...
    break;
    case FILE_NEWS_EX: // 新闻类,其类型由m_szFileName中子目录名来定
    ...
    break;
    case FILE_HTML_EX: // HTML文件,m_szFileName为URL
    ...
    break;
    case FILE_SOFTWARE_EX: // 升级软件
    ...
    break;
    }
    break;
    default:
    return 0; // unknown data
    }
    return 1;
    }
    */
    //////////////////////////////////////////////////////////////////////////////////
    //APIs
    #ifdef __cplusplus
    extern "C"{
    #endif//////////////////////////////////////////////////////////////////////////////////
    // 注册函数// 股票初始化
    // 入口参数:
    // hWnd 处理消息的窗口句柄
    // Msg 用户自定义消息
    // nWorkMode 接口工作方式,设为:RCV_WORK_MEMSHARE
    // 返回参数:
    //  1 成功
    // -1 失败
    // 注:
    // 注册后,驱动程序会向处理窗口发送消息
    int WINAPI Stock_Init(HWND hWnd,UINT Msg,int nWorkMode);// 退出,停止发送消息
    // 入口参数:
    // hWnd 处理消息的窗口句柄,同 Stock_Init 的调用入口参数
    // 返回参数:
    //  1 成功
    // -1 失败
    int WINAPI  Stock_Quit(HWND hWnd);
    // 激活接收程序,进行设置
    // 入口参数:
    // bSetup TRUE 显示窗口,进行设置
    // FALSE 隐含窗口
    // 返回参数:
    //  1 成功
    // -1 失败
    int WINAPI  SetupReceiver(BOOL bSetup);// 取得股票驱动信息
    // 入口参数:
    // nInfo 索引
    // pBuf 缓冲区
    // 出口参数:
    // nInfo == RI_IDSTRING, 返回特征字符串长度, pBuf 为特征字符串
    // 如: "TongShi_StockDrv_1.00"
    // nInfo == RI_IDCODE, 返回信息卡 ID 号, pBuf 为字符串形式的 ID 号
    // 如: 0x78001234   "78001234"
    // nInfo == RI_VERSION, 返回信息卡版本号, pBuf 为字符串版本
    // 如:  1.00   "1.00"
    DWORD WINAPI  GetStockDrvInfo(int nInfo,void * pBuf);//为接收专业文件指定路径(包括公告新闻、股评等,若是ZIP,ARJ文件还解压缩该文件,并将压缩文件删除)
    //对于直接将股评、新闻等文件接收到内存中传给分析软件的接收系统,该函数可以不要,
    //若接收系统要直接将文件写到磁盘上,则应将接收到的文件写到lpszNewsPath指定的路径
    //对于能够对新闻进行分类(如:上交所新闻,深交所新闻,股评等)的驱动程序来说,可在该路径下建立子目录,
    //目录名成为相应类型的汉字名,如lpszNewsPath\上交所新闻,然后将该分类的文件拷贝到相应目录下.
    // 入口参数:
    // lpszNewsPath 公告新闻文件路径
    // 返回参数:
    // 无
    void WINAPI SetNewsPath(LPCTSTR lpszNewsPath);#ifdef __cplusplus
    }
    #endif#endif // __STOCKDRV_H__
      

  6.   

    lgl:我还是没有做出来,请谈一下做这个程序的思路,最好详细一点。分数是没问题的,我还有3000多分等着给呢。
      

  7.   

    如果你安装发通视卡的话,将会找到StockDrv.DLL,这是其它软件与卡打交道的桥,也就是说分析家接收行情是用通视公司的StockDrv.DLL提供的函数的,现在你不用通视卡是吗?那写一个接口与通视公司的StockDrv.DLL一样的程序不就完了?分析家可不管那StockDrv.DLL是通视公司的或是你的或是我的,现在它会把你写的StockDrv.DLL加载上了,那行情来源么?你不是有其它卡吗?
    关键是:你的StockDrv.DLL与通视公司的StockDrv.DLL接口一致。
      

  8.   

    lgl:
    好了一个stockdrv.dll,好象能够接受数据,但是一与分析家连接起来,就出错。怎么办呢,还有什么需要注意的问题吗?
    再次表示感谢。
      

  9.   

    分析家能找到你的stockdrv.dll吗?注意:“驱动程序安装后,应该在系统注册库中注册以下信息,分析软件通过该注册信息启动动态库KEY_LOCAL_MACHINE/SOFTWARE/StockDrv Driver= "驱动DLL全路径"”。
    你所提供的接口都能正常使用吗?
    如果以上都是肯定的话,那可能是你数据不大好,也就是说你发送消息时所包含的地址内的数据不大对。
    你在哪?如果方便我与你一起做好了。
      

  10.   

    我分析了一下其它卡的fxjdrv.dll发现,他们输出的函数为:
    GetStockDrvInfo
    SetNewsPath
    SetupReceiver
    Stock_Init
    Stock_Quit
    而金牛卡所提供的jndll.dll 的输出函数为:
    _GetChannelName@8
    _GetStockByCodeEx@12
    _GetStockByNoEx@8
    _GetStockDrvInfo@8
    _GetTotalChannelNum@0
    _GetTotalNumber@0
    _Stock_Init@12
    _Stock_Quit@4
    所以我所写的stockdrv.dll调用了jndll.dll的
    _Stock_Init@12
    _Stock_Quit@4
    _GetStockDrvInfo@8而
    SetNewsPath
    SetupReceiver
    这两个函数只好调用其它卡的了。
    我对照了一下金牛的数据结构和分析家的数据结果,基本上是一样的。我不知道这样做的思路对不对。我在上海,如果能与您一起做,我就太荣幸了。我可以把我现在所写的东西发给您,并有适当的报酬。
      

  11.   

    是分析家调用你写的Stock_Init出错还是你调用金牛的出错?是什么错?是异常吗?
    按我的理解,要错也就会在行情接收过程出错,Stock_Init怎么可能出错呢?
      

  12.   

    是分析家调用我写的Stock_Init出错
      

  13.   

    那就是你写的Stock_Init有问题。其实,在你写的Stock_Init中要完成三件事,一是调用金牛的Stock_Init;二是建立发送数据消息的通道;另一个是返回(对分析家来说是)正确的信息。怎么会出错呢?
      

  14.   

    int WINAPI    Stock_Init(HWND hWnd,UINT Msg,int nWorkMode);
    在你的程序中记住HWND hWnd与UINT Msg(以后当有数据时按分析家要求的方式组织好并向hWnd发送Msg),同时调用金牛卡的相关初始函数完成后返回1.
    nWorkMode是固定的不必多说。
      

  15.   

    LGL()
    你是搞什么的?这么专业。
    我也作过,能不能交流一下!
    1395994
      

  16.   

    ajiva(赛跑老鼠):
      以前是靠这个吃饭,但现在这也靠不住了,我已下岗。有空看看http://www.csdn.net/expert/Topic/196/196530.shtm