Board logo

标题: DOS的界面开发终结者 [打印本页]

作者: 郭恒     时间: 2004-11-24 00:00    标题: DOS的界面开发终结者

我个人开发出了一个“WINSail”  软件,其完全是免费的一套软件,完整的
“库文件”、“头文件”“说明书”和“源代码”可在"www.FirstSail.B2B.Cn中下载得到。
它基于DOS系统,用Borland C++3.1语言,在Large大模式下开发出来的软件开发包。虽然说完整的软件包大约只有450K左右,却能在DOS下生成的程序具有与WIN9x完全相同的界面,拥有Group、Label、Edit、ComboBox、Button、Radio、Check、ListBox、Grid、ScrollBar、Desktop、ToolsBar、StatusBar、Menu、PopuMenu、Window、Dialog、ICON、Bitmap、示波器等界面元素,支持鼠标,控件的操作99.9%与Windows兼容!可加载运行脚本对话框;支持Socket套接字编程;具有完整窗口图形界面的最小应用只有150K左右,可在只有1M的电子盘中运行;具有0.5uS微秒精确度的delay函数。可以说 DOS + WinSail >= Windows CE

“WinSail工业控制开发系统”目前支持:
(1)         “WinSail”的API与“C++ For DOS”函数库“共存”,特别是与C语言的图形函数BGI共存。
(2)       支持具有优先级的多任务,同时可达到50个任务。(注:可配置脚本文件来不需要多任务支持,使程序运行于单任务中) 。
(3)         支持数据库,生成的文件与Foxpro 2.6库兼容,可在微软Office的Excel中直接打开。
(4)         使用16*16的简体、繁体中文字库、8*16的英文字库,支持TrueType字库。
(5)       “对话框”能在Visual C++预先做好界面,然后通过转换软件,能使Windows的对话框界面变成“WinSail”系统的对话框的界面代码源文件或脚本文件,充分利用Visual的优越性,使DOS平台的应用程序界面开发“不再难”!!!!!
(6)         支持600*480*16、600*400*256、800*600*256、1024*768*256多种分辩率。
(7)         支持Group、Label、Edit、ComboBox、Button、Radio、Check、ListBox、Grid、ScrollBar、Desktop、ToolsBar、StatusBar、Menu、PopuMenu、Window、Dialog、ICON、Bitmap、MessageBox、示波器、多元纵坐标示波器等界面元素。
(8)       支持扩展内存--XMS、扩充内存EMS的内存访问。
(9)         支持文本注册表--INI文件的读写,在写键值时,可保证在键值后面的“注释内容”仍然还存在。
(10)      支持面向对象的I/O访问,屏蔽底层I/O口。
(11)      具有COMM口通讯接口,支持多种校验位,包括“没有校验位”、“奇校验位”、“偶校验位”、“校验位永为1”、“校验位永为0”。后两种校验方式多用在多机通讯中区别“地址”和“数据”。
(12)   支持条形码显示。包括EAN_8、UPC_A、UPC_E、EAN_13(商品码)、ISBN、ISSN、39、128、Codabar、交叉25码
(13)   窗口支持“用I/O口定义的虚拟键盘”、“窗口定时器”、“空闲时调用某函数”、“窗口刷新时调用某函数”等多种回调函数。
(14)   多种常用数学运算,包括“低通”、“高通”、“带通”、“带阻”滤波器系数的产生(可加矩形窗、三角形窗、汉宁窗、海明窗、布莱克窗、Sin(x)/x窗、余弦窗、凯塞窗),滤波、插值、拟合、微积分、相关分析、FFT、DFT等。
(15)      统计进程SPC和直方图、测量的可靠性和重复性GageR&R报表。
(16)      支持“Bitmap”、“ICON”图像文件的显示、“Wav”声音文件的播放。
(17)      支持“普通示波器”和“多纵坐标示波器”。
(18)      支持Socket 套接字编程。
作者: cn_archer     时间: 2004-11-24 00:00
哇!PFPF!这个GUI能做成一个完善的DOS Shell 吗?
作者: 郭恒     时间: 2004-11-25 00:00
    能够!    用它能够做出像WIN95似的桌面系统。在www.FirstSail.B2B.Cn网页中下载WinSail.Zip后,里面有一个工程“Sail3000”目录,运行“Sail2000.Exe”可执行文件或“A.Bat”批处理文件就可以看到。   可运行在    (1)纯“DOS”系统(支持所有私有分辨率)    (2)Win9X系统里面的“DOS”(支持所有私有分辨率)   (3)Windows2000 Professional(只支持私有的640*480*16色)“分辨率”更改在“附件”的“显示属性”中修改。在工程里面有完整的源代码,工程文件是“Sail2000.Prj”,开发环境是Bc31。
作者: autoit     时间: 2004-11-25 00:00
真的如此?DOwn来看看...[em02]
作者: 郭恒     时间: 2004-11-25 00:00
    MakeDlg是一个WINDOWS程序,它的作用是将VC++工程的对话框转换成DOS下的"WInSail"开发平台的对话框,它可以生成5种形式   (1)int main3(int argc, char** argv)的函数形式   (2)int main3(int argc, char** argv)的函数形式   (3)void far VccFuncton(CObject *)的函数形式   (3)void far VccFuncton()的函数形式   (5)脚本文件第1~4形式是CPP文件源代码,须在BC31中将其编译后,方能使用第5种形式由于是脚本文件,可以用内核的AfxLoadDialog(char* pFileName)函数加载运行,也可以在“WinSail.Zip”的范例工程“Sail3000”目录里面的"Sail2000.Exe"运行该程序,“密码”为空,在菜单“附件”有“加载对话框脚本”菜单项,由它加载运行。得用该工具,您能开发出非常多精美的“对话框”。
作者: boblhh9999     时间: 2004-11-25 00:00
真的这么厉害么
作者: jaywang     时间: 2004-11-25 00:00
看了一下,不错。厉害。向你学习。
作者: 郭恒     时间: 2004-11-27 00:00
    WinSail内核运行在“实模式”下,目前增强了对"多任务"的支持,内核启动时将“挂接”时钟中断-INT8,并修改定时器0的初始计数值为2048, 系统会每55/32 = 1.72mS调度一个任务,任务调度时若当前任务正在“DOS忙”,则系统不切换任务,故在多任务编程时,应该尽量调用没有使用INT21中断的函数,如果在WINDOWS下运行,需将Config.Sys脚本文件中[System]段的MultiMask键值置成"False",以便不修改INT8,而没有多任务的支持。详细可看说明书,可在Http://WWW.FirstSail.b2b.CN 中下载"WinSail"得到
作者: unknow     时间: 2004-12-7 00:00
真的有这么好吗?我荡一个看看
作者: zykdos     时间: 2004-12-7 00:00
给个MSN联系
作者: 郭恒     时间: 2004-12-11 00:00

    WinSail内核目前全面支持“TCP/IP”协议,支持SOCKET套接字编程,由于WinSail是在DOS“实模式”下运行,故设计“TCP/IP”协议时,所有的“接收数据包”和“发送数据包”都被内核放在“扩展内存XMS”中,不占用“常规内存”的空间,故整个协议代码不占用多大的“空间”。   “协议”设计时,所有的“数据结构”和“套接字”函数接口,尽量与微软的“WINDOWS”文档兼容。   “WinSail”的设计之初,是懂“WINDOWS”编程的人,不费吹灰之力,就能在DOS下编程!!!         Http://WWW.FirstSail.b2b.CN 中下载"WinSail"得到。(目前TCP/IP协议正在测试,载止到2004年12月11日,还不能下载到包含TCP/IP协议的WinSial。目前协议已经测试完成,但SOCKET套接字还正在测试...,可在2004年12月20日后,保证能下载到包括TCP/IP协议的“WinSail”。)    对于“楼上”说的MSN,将下载后的WinSail解压,里面有较简单的说明书,由于时间关系,详细说明书正在continue...,有问题,可发邮件到“szhello8@21cn.net”,或是“wave@public.guangzhou.gd.cn”
作者: cdl     时间: 2004-12-12 00:00
不错,好!!!真的是在实模式下运行吗?我们公司的网站是www.baby-pc.com,看看能否在移植到我们的产品上,现在很多用户需要这样的GUI。如果可能的话可以合作。
作者: jiaking     时间: 2004-12-18 00:00
很不错啊!技术文档很详细,是长期免费的吗?我很喜欢其中的界面开发和TCP/IP支持。研究研究。
作者: jiaking     时间: 2004-12-18 00:00
看了,真的很不错!!对了,那个SAIL2000.EXE的登陆密码是什么?学习学习。
作者: 郭恒     时间: 2004-12-18 00:00
回答jiaking
对于Sail3000示例工程来说---------用户名是:super(小写),密码是:空
在2004年12月18日早上10时上传了“最新版的WinSail”,最小图形应用是“171K”,完整图形应用是“220K”    “完整图形应用”比“最小图形应用”多了“示波器CGraph”、“多元示波器CTorqueGraph”、“桌面类CDesktop”、“对话框文件加载CDialog::LoadDailog()”、“登录框”、“权限修改”、“设备管理器”、“多任务管理器”的代码再过一个星期左右,含TCP/IP协议的、支持SOCKET套接字编程的内核将会上传,届时“最小图形应用”会增加30~50K左右的代码。
注“内核的TCP/IP协议是基于Packet Driver网卡驱动的”============================================================================WinSail的设计目的是用在工业上,     在电力系统应用中,本内核已完成其95%的工作,     在数控机床应用中,本内核已完成其75%的工作,     在智能仪器应用中,本内核已完成其80%的工作,
作者: jiaking     时间: 2004-12-19 00:00
我公司是从事数控机床的开发、生产的,能给我介绍介绍“在数控机床应用中,本内核已完成其75%的工作”具体是怎样的吗?具体有哪方面的应用、支持。谢谢!!我的邮箱是zhuhuijia@126.com
作者: profree     时间: 2004-12-20 00:00
楼主,你太厉害 了,我正在寻找这样一个开发包,真是激动人心啊,非常谢谢你,我下载试用看看,对了,我不懂Windows 编程,对DOS的BC31还懂一些,可以编一些小程序,请问我可以使用吗?
作者: profree     时间: 2004-12-20 00:00
话说终结者,当之无愧,佩服佩服,真呢是佩服,而且是免费的,让我们大家感谢楼主的无私奉献,
作者: tdj     时间: 2004-12-20 00:00
向郭恒兄致敬!!!![em17][em17][em17][em17]
作者: profree     时间: 2004-12-22 00:00
可以我下载了不知道怎么使用,不过怎么点关闭按钮没有反应呢?
作者: 郭恒     时间: 2004-12-23 00:00
特向广大喜欢这套软件的用户致歉:

    由于前段时间上传的“WinSail系统内核”是较早前的作品,目前已经上传了最新的“内核”,请重新在“http://www.FirstSail.b2b.Cn”的“产品列表/软件产品/WinSail/附件”中重新下载。

一、文件说明
    1:文件:WinSail工控开发系统.doc------WinSail系统简要使用说明书(老版本)
    2:文件:WinSail工控开发系统_界面类简介.doc------WinSail系统界面开发说明书(老版本)
    3:目录:WinToDos---------------------转换程序
    4:目录:include2---------------------系统“头文件”和“库文件”
    5:目录:Sail3000---------------------应用工程实例
    6:目录:Application------------------VC++程序,系统内核多个对话框是从中转换而来的。

二、include2目录里面的文件说明
    01:Barcode.h----------- 条形码显示/打印头文件,      类接口
    02:DownComm.h---------- COMM口通讯,                 类接口
    03:Foxpro.h------------ Foxpro2.6数据库,            类接口
    04:GageRR.h------------ 测量的可靠性和重重性报表,   类接口
    05:Graph.h------------- 示波器和多纵坐标示波器,     类接口
    06:HglgPrit.h---------- 文字、BITMAP图片、ICON图标的显示,WAV声音播放,API接口
    07:Kernal.h------------ 多任务,API接口
    08:Listing.h----------- 双向链表,类接口
    09:Memroy.h------------ XMS和EMS内存,类接口
    10:Mouse.h------------  鼠标,API接口
    11:MyFrame.h----------  控件和内核初始化,类和API接口
    12:NewMath.h----------  数学库,API接口
    13:Register.h---------  文本INI文件读写访问,类接口
    14:Relay.h------------  面向对象的I/O访问,API接口
    15:Spc.h--------------  进程统计控制SPC,类接口
    16:SVga_Dev.h---------  800*600*256,1024*768*256分辨率图形驱动,API接口
    17:Symbol.h-----------  符号定义
    18:EgavgaF.Obj--------  BC31远调用驱动程序
    19:Sail.Lib-----------  系统库文件
    20:Socket3.H----------- Socket套接字编程(支持Arp、Icmp、Udp、Tcp协议,链路层采用Packet Driver)

三、Sail3000目录里面的文件说明
    01:Config.Sys----------- 系统驱动配置文件
    02:Display.Fon---------- 8*16英文字库和16*16简体字库
    02:DisplayF.Fon--------- 8*16英文字库和16*16繁体字库
    03:Dwpword.Exe---------- 用户和密码观看文件(高级应用)
    04:Pass.Bin------------- 用户和密码数据库,二进制
    05:Mouse.Com------------ 鼠标驱动程序
    06:Sail2000.Cpp--------- 用户工程的源文件示例
    07:Sail2000.Prj--------- 用户工程的工程文件示例
    08:Sail2000.Exe--------- 用户工程的主程序
    09:a.bat---------------- 用户工程的批处理文件
    10:Sys\Destop.Sys------- 用户工程的桌面配置文件
    11:Sys\Manager.Sys------ 用户工程的桌面配置文件
    12:Sys\Relay.Sys-------- 用户工程的I/O配置文件
    13:Bmp\Computer.Bmp----- 内核使用的一幅图片
    14:Bmp\Desktop.Bmp------ 内核使用的一幅图片
    15:Bmp\Winnt.BMp-------- 密码框使用的一幅图片
    16:Bmp\Sail2000.Ico------ 窗口默认的标题栏图标
    17:Bmp\BookS??.Ico------ 菜单默认的图标
    18:Bmp\MsgBox??.Ico----- 信息框使用的图标
    19:Bmp\Display.Ico------ 内核使用的一幅图标
    20:Bmp\Net.Ico---------- 内核使和的一幅图标

四、WinToDos目录里面的文件说明
    对于VC工程中的文件,只有“工程.rc”和“Resource.h”文件有价值
    01:MakeDlg.Exe---------- 将VC中的资源对话框转成WinSail的对话框源程序或脚本文件
    02:RegisterDll.Dll------ 支持MakeDlg.Exe访问文本INI注册表的DLL文件

五:DOS起动文件配置说明
    假设Win的目录名称是“c:\Windows”,BC31的目录是“C:\Bc31”
    C:\Config.Sys请如下配置
Device = C:\Windows\Himem.Sys/TestMem:Off
Device = C:\Windows\Emm386.Exe  Ram  HighScan
DOS    = High,Umb
Stacks = 9,256
Files  = 25
    C:\Autoexec.Bat请如下配置
   path C:\Windows;C:\Windows\Command;C:\Bc31\Bin
          Lh   SmartDrv.Exe

六:对Main()主函数的要求
    1:需包含头文件"Symbol.h"和"MyFrame.h"
    2:先调用BOOL InitSystem(int argc, char** argv)内核初始化函数
    3:中间写自己的代码
    4:最后调用BOOL CloseSystem()内核退出函数.
    5:例:
       #include "Symbol.h"
       #include "Myframe.h"       extern unsigned _strlen = 60u * 1024u;
       //所有窗口默认虚拟键盘回调函数
       void far TransrateKey(CObject* pCurObj)
       {
           return(0);
       }       int main(int argc, char** argv)
       {
           //系统内核初始化
           if (!InitSystem(argc, argv))
           {
               ::CloseSystem() ;
               ::printf("\nInit System Error!") ;
               return(0);
           }           //用户代码开始
           
           //……           //用户代码结束           //退出系统内核
           ::CloseSystem();
           return(1);
       }
七:如何创建Sail2000工程并编码
    01:在C盘中安装BC31,最好目录为C:\Bc31
    02:用户在自已BC31的目录中,创建"Include2"目录
    03:将include2\*.*的所有文件拷贝C:\bc31的"include2"目录中。
    04:在BC31集成环境中,将"include包含"路径设成"c:\bc31\include2;c:\bc31\include"
    05:在BC31集成环境中,"Large"大模式;"Default for memory model"默认内存模式。
    06:在BC31集成环境中,Floating Point设置成"80287/387"和Instruion Set设置成"80386"
    07:在BC31集成环境中,创建一工程,假设工程名称为Sail2000.Prj
    08:在工程中加入C:\BC31\include2\Sail.Lib内核库文件
    09:在工程中加入C:\BC31\include2\Egavgaf.Obj图形库文件
    10:在工程中,须编写void far TransrateKey(CObject* pCurObj)的函数,一般如下所示
          void far TransrateKey(CObject* pCurObj)
          {
  return(0);
          }

八:如何创建自己的控件,并挂接在窗口系统中。
   想定制一个属于自己的个性化控件,假设类名为“CCustomCtrl”,从CObject基类继承 不需要得到焦点的情况需要得到焦点的情况class  CCustomCtrl:public CObject{public:     void Show();//画控件public:     CCustomCtrl(CObject* pParent); //构造函数};//构造函数CCustomCtrl::CCustomCtrl(CObject* pParent):CLabel(pParent){    //…}//重画框件void CCustomCtrl::Show(){RECT rc this->GetScreenRect(&rc);//得到控件的屏幕位置//…}class  CCustomCtrl:public CObject{public:void Show();//画控件void SetFocus();//当控件得到焦点时void KillFocus();//当控件失去焦点时public:     CCustomCtrl(CObject* pParent); //构造函数};//构造函数CCustomCtrl::CCustomCtrl(CObject* pParent):CLabel(pParent){this->SetTab(TRUE);//将控件置成可接受焦点//…}//重画控件void CCustomCtrl::Show(){RECT rc this->GetScreenRect(&rc);//得到控件的屏幕位置//…}//当控件得到焦点时void CCustomCtrl::SetFocus(){    //…}//当控件失去焦点时void CCustomCtrl::KillFocus(){    //…}
作者: 郭恒     时间: 2004-12-23 00:00
由于上面文章不支持“表格”,关于定制自己的控件文章有一点“乱”,下面重新描述

八:如何创建自己的控件,并挂接在窗口系统中。
   想定制一个属于自己的个性化控件,假设类名为“CCustomCtrl”,从CObject基类继承//不需要得到焦点class  CCustomCtrl:public CObject{public:     void Show();//画控件public:     CCustomCtrl(CObject* pParent); //构造函数};//构造函数CCustomCtrl::CCustomCtrl(CObject* pParent):CObject(pParent){    //…}//重画框件void CCustomCtrl::Show(){RECT rc this->GetScreenRect(&rc);//得到控件的屏幕位置//…}//需要得到焦点 class  CCustomCtrl:public CObject{public:void Show();//画控件void SetFocus();//当控件得到焦点时void KillFocus();//当控件失去焦点时public:     CCustomCtrl(CObject* pParent); //构造函数};//构造函数CCustomCtrl::CCustomCtrl(CObject* pParent):CObject(pParent){this->SetTab(TRUE);//将控件置成可接受焦点//…}//重画控件void CCustomCtrl::Show(){RECT rc this->GetScreenRect(&rc);//得到控件的屏幕位置//…}//当控件得到焦点时void CCustomCtrl::SetFocus(){    //…}//当控件失去焦点时void CCustomCtrl::KillFocus(){    //…}
作者: profree     时间: 2005-1-1 00:00
还是不知道怎么使用
作者: 郭恒     时间: 2005-1-3 00:00
对于不明确“WinSail”怎么使用的朋友,请发邮件至    大邮箱:      szhello8@21cn.net或:    wave@public.guangzhou.gd.cn或致电:   电话:0755-27570111   传真:0755-27571747   联系人: 郭先生  下载地址:http://www.FirstSail.B2B.Cn中的"产品列表/软件产品/WinSail/附件/WinSail"
作者: 郭恒     时间: 2005-1-10 00:00
    目前“WinSail”支持“单色”显示和“虚拟”分辨率,可在下载地址:http://www.FirstSail.B2B.Cn中的"产品列表/软件产品/附件:WinSail编程库下载"下载地址:http://www.FirstSail.B2B.Cn中的"产品列表/软件产品/附件:Sail3000示例工程下载"
作者: yyz985     时间: 2005-1-11 00:00
好东西 顶
作者: boblhh9999     时间: 2005-1-18 00:00
又有新版本了,下来看看
作者: 笨的可以     时间: 2005-1-21 00:00
猛的一塌糊涂,牛!请问如果有新的网卡,如何处理呢?
作者: 郭恒     时间: 2005-1-21 00:00
回答“笨的可以”:
    目前的TCP/IP协议网络包是基于“Packet Driver”驱动。对于网卡来说:“Packet Driver”驱动程序在附带的网卡光盘上可以找到。您可在下面所列位置(1)(2)(3)处不定期下载,下载后的所有内容只供学习使用:(1) “http://www.firstsail.b2b.cn”的"产品列表/软件产品/WinSail编程库下载"
(2) “http://www.firstsail.b2b.cn”的"产品列表/软件产品/WinSail示例工程下载"
(3) “http://www.firstsail.b2b.cn”的"产品列表/软件产品/WinSail编程文档下载"   它是一个面向“工业控制”应用的开发平台,运行在“实模式”中,主要架构为:
作者: 笨的可以     时间: 2005-1-21 00:00
谢谢老大!努力学习先!
作者: crshen     时间: 2005-1-22 00:00
老大太强了,下载学习
作者: wzlong     时间: 2005-1-25 00:00
thanks
作者: jawbin     时间: 2005-1-30 00:00
高人啊,我要下载,我激动了!
作者: jawbin     时间: 2005-1-30 00:00
还没仔细看内容,看了点使用说明,如果内容都有的话,我只能说:“楼主你太狠心了,想把我感动死啊!”无话可说,银河系好男儿!
作者: jawbin     时间: 2005-1-30 00:00
好象没有源代码,只有接口和库,即使这样,你还是电,你还是光,你还是唯一的神话![em46]
作者: jawbin     时间: 2005-1-30 00:00
如果我说错了,请上帝不要处罚我,555[em27]
作者: jawbin     时间: 2005-1-30 00:00
我想知道为什么叫 kernal 而不是kernel
作者: stamp     时间: 2005-2-24 00:00
pf
作者: jawbin     时间: 2005-4-8 00:00
顶起
作者: ant.     时间: 2005-4-12 00:00

由于以下原因该页面禁止访问:

    (1) 用户服务已经到期,不过您的数据仍然将被我们完整保留100天。

如需继续服务,请您尽快进行空间续费或输入您购买的正式版注册码。

如有任何问题,请与商务网址客服部联系:0755-25840524。

对您带来的不便,深表歉意,商务网址软件感谢您的配合与支持!      *使用注册码续费商务网址软件管理中心
www.b2b.net.cn
作者: 郭恒     时间: 2005-4-14 00:00
原来的http://www.FirstSail.B2b.Cn网站,不能上传大图片,不能上传超过1M的附件.目前正在往http://www.FirstSail.Com.Cn迁移,网站正在建设中,请稍侯几天...
作者: dk7725     时间: 2005-4-15 00:00
还需等待多少天,期待中。。。。。。。。。
作者: dk7725     时间: 2005-4-15 00:00
[em08]急不可待,能否有劳郭兄将内容发至dukun_mail@163.com,万分感谢!!!!!!!
作者: 郭恒     时间: 2005-4-19 00:00
http://www.FirstSail.B2b.Cn网站已开通http://www.FirstSail.Com.Cn网站已开通
作者: dk7725     时间: 2005-4-20 00:00
好象没有源代码嘛!
作者: dk7725     时间: 2005-4-20 00:00
“WinSail的设计目的是用在工业上,     在电力系统应用中,本内核已完成其95%的工作,     在数控机床应用中,本内核已完成其75%的工作,     在智能仪器应用中,本内核已完成其80%的工作”请问郭兄上述应用内核包括哪 些具体内容,能否详细介绍一下!!!谢谢!!!!
作者: 郭恒     时间: 2005-4-21 00:00
1:对于界面而言,支持320*200*256,640*480*16,800*600*256,1024*768*256色分辨率的VGA形式,
支持320*240*2色分辨率的SED1335控制器的LCD屏幕形式,支持各种Windows界面因素。对话框可以VC++中
拉好界面,通过本系统提供的转换程序可转换成WinSail的源代码或脚本文件,开发界面不难了。2:提供的“示波器”控件,功能强大,特别是支持“多纵坐标”,可满足大多数的动态“波形”显示需要。3:电力系统是弱电控制强电,输出元件多,如继电器、电磁阀、指示灯、电机等等,WinSail的“面象对象
的I/O控制”接口功能强大,硬件可采用“I/O卡、PLC、网卡、COM通讯口”,但软件接口一致,区别是在配
置文件的不同.     例如:
         ExecuteRelay("K1, K2, ~K3, 300, SSR1, 20", pRegister, TRUE, TRUE);
     表示:
        合上K1, K2机械继电器,断开K3机械继电器,等待300mS, 再吸合SSR1固态继电器,等待20mS。
   
4:系统提供的数学仿真包,可以仿真“正弦波、方波、冲击波、三角波”等等,由这些波形的叠加可实现
大多数外部信号的实际情况,是仿真真实世界不可多得的工具。5:WinSail提供的离散信号FIR滤波功能---“低通滤波器、高通滤波器、带通滤波器、带阻滤波器”系数产
生和滤波程序,是所有“电气、电子、自动化、仪器仪表”等行业消除外界干扰的手段。如果您的产品上还
不具备这个功能,那么您的产品只是学生实验品而已。6:WinSail支持的TCP/IP协议,编程界面基本上与“Win9x”一样,如果您的产品支持网卡通讯,可想而知,
由此能给您增加多少的附加值!!!7:WinSail只是一个二次开发平台,其它的这里不想再多描述。
作者: 9zhmke     时间: 2005-5-12 00:00
太凶了!真高兴DOS现在还有这么强的生命力,还有这么多朋友一起完善它。
作者: gt2000     时间: 2005-7-17 04:13
源代码会公开吗,很难得的软件包,可以自由使用码,版权问题有吗
作者: faith22     时间: 2005-7-23 20:53
佩服 DOS下的界面开发 要钱的呀  怎么推广?
作者: bigboy2050     时间: 2005-7-27 13:29
WinSail确实很棒!多谢楼主大侠!请问这个WinSail和DJGPP有何不同?这个是用来开发16位dos程序,还是32位dos程序啊?谢谢
作者: firstsail     时间: 2005-7-28 15:23
DJGPP:只是IDE开发工具,与BC31/BC45的关系就象是VC++与Dephi的关系。
WinSail:编程库和应用开发工具,与BC31与BC45的关系好拟DLL、OCX与VC++的关系。


    目前WinSail已经发展到V2.0版本。包含以下几大类功能:
   
(1)仿Windows的GUI。

(2)显示模式包括VESA模式、TFT模式、LCD模式。

(3)多任务。

(4)TCP/IP协议栈,基于Packet Driver驱动,所有网络数据包在扩
展内存里,不占用常规内存。

(5)扩展内存支持“物理扩展内存”、“磁盘仿真扩展内存”、“扩充内存卡”。

(6)“文本注册表仿问”功能支持。

(7)扩展数学函数库。

(8)其它常用功能支持。
作者: guolvguolv     时间: 2005-8-4 09:15    标题: 不知道为什么,我编辑里面自再的sail2000的时候有问题

提示error graphics.h,gdi 有问题,请问老大怎么办?
作者: firstsail     时间: 2005-8-4 09:44    标题: 您可能是在Visual C++下编译吧?

Visual C++是不支持graphics.h的,即Visual C++只支持Windows下运行的程序。

WinSail V2.0是开发纯DOS程序的,您应该安装Borland C++3.1作为开发工具,或者安装Borland C++4.5作为开发工具。
作者: johnsonlam     时间: 2005-8-12 16:25


  Quote:
Originally posted by 郭恒 at 2004-11-24 12:00 AM:
        我个人开发出了一个“WINSail”  软件,其完全是免费的一套软件,完整的
“库文件”、“头文件”“说明书”和“源代码”可在"www.FirstSail ...

免 費 是 那 一 種 呢 ? GNU? Public Domain?

我 找 不 到 下 載 地 方 ...
作者: firstsail     时间: 2005-8-15 14:15    标题: WinSail V2.0的下载地址

网页:http://www.firstsail.b2b.cn
位置:主页左上角有“产品列表->软件产品->WinSail V2.0嵌入式系统->附件->WinSail编程库下载”
作者: firstsail     时间: 2005-8-15 14:40    标题: 如何做动态波形显示?

经常需要从AD转换卡采集到的数据做动态波形显示,用以下算法  

   (1)假设波形显示颜色为WHITE,背景色为BLACK,窗格为DARKGRAY颜色。
   (2)定义一个布尔变量BOOL bDisplay= FALSE
   (3)如果bDisplay = TRUE,已保存的采样数据用WHITE颜色异或画图,并置bDisplay = FALSE
   (4)从数据采样卡上采样数据
   (5)将采样数据用WHITE颜色异或画图,并置bDisplay = TRUE
   (6)保存采样数据
   (7)重复第(3)~(6)

采用以上的算法有以下缺点。
   (1)波形数据点数比作图宽度大的时候,需压缩显示。
   (2)压缩后,多个点在同一位置上异或画点,导致波形不够清晰
   (3)压缩后,多个点在同一位置上异或画点,导致波形的高频成份丢失。

目前采用以上的算法解决:
   (1)假设波形显示颜色为WHITE,背景色为BLACK,窗格为DARKGRAY颜色。
   (2)定义一个布尔变量BOOL bDisplay= FALSE
   (3)如果bDisplay = TRUE,已保存的采样数据用BLACK颜色直接画图,且用DARKGRAY颜色重画窗格,并置bDisplay = FALSE
   (4)采样数据
   (5)将采样数据用WHITE颜色直接画图,并置bDisplay = TRUE
   (6)保存采样数据
   (7)重复第(3)~(6)

各位DOS爱好者,有没有更好的解决方法???
作者: johnsonlam     时间: 2005-8-17 10:23


  Quote:
Originally posted by firstsail at 2005-8-15 02:15 PM:
网页:http://www.firstsail.b2b.cn
位置:主页左上角有“产品列表->软件产品->WinSail V2.0嵌入式系统->附件->WinSail编程库下载”

謝 謝 ! 下 載 了 , 真 是 厲 害 。

但 , 應 用 上 有 沒 有 限 制 呢 , 例 如 免 費 謹 限 於 個 人 使 用 , 商 用 要 不 要 付 款 買 許 可 ...

因 為 程 序 可 以 在 Windows 上 開 發 , 而 在 WinSail 執 行 , 真 的 省 時 省 力 ...
作者: firstsail     时间: 2005-8-23 15:46    标题: WinSail显示模式的详细说明!

序号  Device             Mode(宏)                Mode(值)    说明
1     VGA = 9            VGAHI        2                   640*480*16色

2     VESA = 11            VESA800_600_16           = 0           800*600*16色(暂不支持)
                    VESA640_400_256           = 1           640*400*256色
                    VESA640_480_256           = 2           640*480*16色(暂不支持)
                    VESA800_600_16_2           = 3           800*600*16色(暂不支持)
                    VESA800_600_256           = 4           800*600*256色
                    VESA1024_768_16           = 5           1024*768*16色(暂不支持)
                    VESA1024_768_256           = 6           1024*768*256色
                    VESA1280_1024_16           = 7           1280*1024*16色(暂不支持)
                    VESA1280_1024_256           = 8           1280*1024*256色
                    VESA320_200_256           = 9           320*200*256色
                    VESA320_240_256           = 10           320*240*256色

3  SED1335VGA = 13  SED1335VGA_320_240_1   = 0           320*240*1色
                    SED1335VGA_640_480_1   = 1           648*480*1色(暂不支持)
                    SED1335VGA_800_600_1   = 2           600*800*1色(暂不支持)
                    SED1335VGA_1024_768_1  = 3           1024*768*1色(暂不支持)

4  TFTVGA = 14      TFTVGA_320_240_256           = 0           320*240*256色(暂不支持)
                    TFTVGA_640_480_256           = 1           640*480*256色
                    TFTVGA_800_600_256           = 2           800*600*256色
                    TFTVGA_1024_768_256           = 3           1024*768*256色(暂不支持)
备注       

(1)其它仿真分辨率 * 256Color。须修改全局变量nAfxScreenWidth和
nAfxScreenHeight的值,只能改小,不能改大。
(2)Device的值配置在Config.Sys文件的[Display]段的"Device"键值,为整数类型!
(3)Mode的值配置在Config.Sys文件的[Display]段的"Mode"键值,为整数类型!
(4)单色仿真配置在Config.Sys文件的[Display]段的"Mono"键值,为布尔类型!
(5)使用PCM-3386嵌入式主板的用户,须将[Display]段的"Pcm3386"键值,设置为"TRUE"!
(6)使用PCM-3486嵌入式主板的用户,须将[Display]段的"Pcm3486"键值,设置为"TRUE"!

    配置文件为"Config.Sys",如下所示:
        [Display]
         Device = 9;设备号
         Mode = 2 ;模式号
         Mono = True ;单色/彩色显示控制
         Pcm3386 = False ;Pcm-3386嵌入式主板用户
         Pcm3486 = False ;Pcm-3486嵌入式主板用户
作者: maya0su     时间: 2005-10-31 16:57
下载不了,要“价格面议”我不打算买,所以我觉得楼主是骗子!做广告来了!
作者: firstsail     时间: 2005-11-1 11:19    标题: WinSail的下载地址

网址:http://www.firstsail.b2b.cn
位置:
   首页的左上角->[产品列表]->[软件产品]->[WinSail V2.0嵌入式系统]->[附件:WinSail编程库下载]

   免费下载的编程库是BC31编译器下使用的80386以上CPU、带浮点处理器的开发包!
作者: jpzsj     时间: 2005-11-2 19:30
这个编程库确实很好,可惜就是不支持真彩色,只支持256,如果能用djgpp+allegro编写,支持真彩色就好了
作者: Kinglion     时间: 2005-11-2 23:18
支持原创作品!
作者: firstsail     时间: 2005-11-3 12:42    标题: WinSail V2.0目前没有支持真彩色的计划!

目前的WinSail保存窗口背景的默认扩展内存空间为2M字节.
当然可以修改Config.Sys中配置的没有公开的“键值”来增加空间。

在16色(4位)下
   640 * 480 -> 154K字节,可同时开12个需保存窗口背景的全窗口
   800 * 600 -> 240K字节,可同时开8个需保存窗口背景的全窗口
  1024 * 768 -> 393K字节,可同时开4个需保存窗口背景的全窗口

在256色(8位)下
   640 * 480 -> 308K字节,可同时开6个需保存窗口背景的全窗口
   800 * 600 -> 480K字节,可同时开4个需保存窗口背景的全窗口
  1024 * 768 -> 786K字节,可同时开2个需保存窗口背景的全窗口

在65536色(16位)下:
   640 * 480 -> 615K字节,可同时开6个需保存窗口背景的全窗口
   800 * 600 -> 960K字节,可同时开4个需保存窗口背景的全窗口
  1024 * 768 -> 1572K字节,可同时开1个需保存窗口背景的全窗口

在真彩色(24位)下:
   640 * 480 -> 924K字节,可同时开1个需保存窗口背景的全窗口
   800 * 600 -> 1440K字节,可同时开1个需保存窗口背景的全窗口
  1024 * 768 -> 2304K字节,不能开需保存窗口背景的全窗口

    基于WinSail V2.0开发的目的是用于工业用途,许许多多的目标主板
的内存和硬盘空间有限,特别是在PC104主板中,故WinSail目前没有支持
真彩色的计划!
作者: jpzsj     时间: 2005-11-3 14:25
太可惜了, 如果做成通用的、 直接真彩色不是更好吗?
作者: bbsbot     时间: 2005-12-1 08:58
很好的dos开发工具包,免费的?
那个在线订购是怎么回事
作者: Neat     时间: 2005-12-1 20:27
带源码吗?
作者: zhgwbzhd     时间: 2005-12-4 23:29
支持一下
作者: kdlipm     时间: 2005-12-5 00:35
老大太强了,值得学习!·!·
作者: m168     时间: 2005-12-14 01:05
向老大致敬!!谢谢!
作者: zhgwbzhd     时间: 2005-12-20 11:44
俺怎么用不了呢?按照说明,把bc环境配置了一下。把include2拷贝过去。
建立一个工程,把那两个库增加进去。自己建立一个main.c
。按照说明把最简单的代码写进去。可是编译的时候报很多错??
作者: firstsail     时间: 2005-12-20 12:36    标题: 在include2目录中有一个Sail.Prj文件,用它做工程文件吧!

//在include2目录中有一个Sail.Prj文件,用它做工程文件吧!

//下面是例子
include <Symbol.h>
#include <MyFrame.h>


//Stack's Size
unsigned int _stklen = 50u * 1024u;//堆栈的尺寸

//Keyboard's Callback Function For All Default Window
int TransrateKey(CObject* pCurObj)//所有窗口默认虚拟键盘回调函数
{
        return(0);
}

void far VccFunction(CObject* pCurObj)
{
        //Create a Dialog On the Center of Desktop
        CDialog* pDialog = new CDialog;//分配实例
        pDialog->CreateWindow(0, 0, 447, 364, "单选按钮演示");//建立窗口
        pDialog->Center();//窗口对中

        //Register Callback Function for Window
        pDialog->SetTimeFc(NULL);//注册定时器回调函数
        pDialog->SetDrawFc(NULL);//注册画图回调函数
        pDialog->SetHelpFc(NULL);//注册帮助回调函数
        pDialog->SetKeyboardFc(NULL);//注册虚拟键盘回调函数

        //Create Close's Button Control
        CCloseButton* pCloseButton = new CCloseButton(pDialog);//分配和建立关闭按钮

        //Create a Button Control
        CButton* pButton1 = new CButton(pDialog);
        pButton1->CreateObject(225, 141, 192, 24, "确定(\x3\E\x3)");
        pButton1->SetShortcutKey(VK_ALT_E);
        pButton1->SetFc(ClickEnterButton);
        pButton1->SetID(BUTTONBASE + 1 - 1);

        //Create a Button Control
        CButton* pButton2 = new CButton(pDialog);
        pButton2->CreateObject(223, 183, 192, 24, "取消(\x3\C\x3)");
        pButton2->SetShortcutKey(VK_ALT_C);
        pButton2->SetFc(ClickCancelButton);
        pButton2->SetID(BUTTONBASE + 2 - 1);

        //Create Group Control
        CStatic* pGroup1 = new CStatic(pDialog);
        pGroup1->CreateObject(10, 32, 204, 94, "星期");
        pGroup1->SetID(GROUPBASE + 1 - 1);

        //Create Radio Control
        CRadio* pRadio1 = new CRadio(pDialog);
        pRadio1->CreateObject(22, 53, 73, 24, "星期一");
        pRadio1->SetStatic(TRUE);
        pRadio1->SetRadio(TRUE);
        pRadio1->SetID(RADIOBASE + 1 - 1);

        //Create Radio Control
        CRadio* pRadio2 = new CRadio(pDialog);
        pRadio2->CreateObject(22, 76, 73, 24, "星期二");
        pRadio2->SetID(RADIOBASE + 2 - 1);

        //Create Radio Control
        CRadio* pRadio3 = new CRadio(pDialog);
        pRadio3->CreateObject(22, 98, 73, 24, "星期三");
        pRadio3->SetID(RADIOBASE + 3 - 1);

        //Create Group Control
        CStatic* pGroup2 = new CStatic(pDialog);
        pGroup2->CreateObject(226, 32, 204, 94, "性别");
        pGroup2->SetID(GROUPBASE + 2 - 1);

        //Create Radio Control
        CRadio* pRadio4 = new CRadio(pDialog);
        pRadio4->CreateObject(240, 53, 57, 24, "男性");
        pRadio4->SetStatic(TRUE);
        pRadio4->SetRadio(TRUE);
        pRadio4->SetID(RADIOBASE + 4 - 1);

        //Create Radio Control
        CRadio* pRadio5 = new CRadio(pDialog);
        pRadio5->CreateObject(240, 83, 57, 24, "女性");
        pRadio5->SetID(RADIOBASE + 5 - 1);

        //Create Check Control
        CRadio* pCheck1 = new CRadio(pDialog);
        pCheck1->CreateObject(22, 154, 57, 24, "读书");
        pCheck1->SetBox(TRUE);
        pCheck1->SetID(CHECKBASE + 1 - 1);
        pCheck1->SetID(CHECKBASE + 1 - 1);

        //Create Check Control
        CRadio* pCheck2 = new CRadio(pDialog);
        pCheck2->CreateObject(22, 180, 57, 24, "跑步");
        pCheck2->SetBox(TRUE);
        pCheck2->SetID(CHECKBASE + 2 - 1);
        pCheck2->SetID(CHECKBASE + 2 - 1);

        //Create Check Control
        CRadio* pCheck3 = new CRadio(pDialog);
        pCheck3->CreateObject(22, 202, 73, 24, "打足球");
        pCheck3->SetBox(TRUE);
        pCheck3->SetID(CHECKBASE + 3 - 1);
        pCheck3->SetID(CHECKBASE + 3 - 1);

        //Create Group Control
        CStatic* pGroup3 = new CStatic(pDialog);
        pGroup3->CreateObject(10, 133, 204, 96, "星期");
        pGroup3->SetID(GROUPBASE + 3 - 1);

        //Create Edit Control
        CEdit* pEdit1 = new CEdit(pDialog);
        pEdit1->CreateObject(97, 153, 106, 21, NULL);
        pEdit1->SetID(EDITBASE + 1 - 1);

        //Create Edit Control
        CEdit* pEdit2 = new CEdit(pDialog);
        pEdit2->CreateObject(99, 180, 106, 21, NULL);
        pEdit2->SetID(EDITBASE + 2 - 1);


        //Show Window
        pDialog->ShowWindow();//显示窗口

        //go into Message Loop
        pDialog->DoModal();//进入窗口消息循环

        //Destroy Window
        delete pDialog;//删除对话框


        return;

}

int main(int argc, char** argv)
{

        //Initlize Sysem Kernel
        if (!::InitSystem(argc, argv))//初始化系统内核
        {
                ::CloseSystem();//关闭系统内核
                printf("\nInit System Error!");
                return(0);
        }


        //Callback Function
        ::VccFunction(NULL);


        //Close Sysem Kernel
        ::CloseSystem();//关闭系统内核

        return(1);

}
作者: zhgwbzhd     时间: 2005-12-20 14:49
报错呀!我用的是msdos7呀。
//下面是例子
include <Symbol.h>
#include <MyFrame.h>


//Stack's Size
unsigned int _stklen = 50u * 1024u;//堆栈的尺寸

//Keyboard's Callback Function For All Default Window
int TransrateKey(CObject* pCurObj)//所有窗口默认虚拟键盘回调函数
{
        return(0);
}
int main(int argc, char** argv)
{

        //Initlize Sysem Kernel
        if (!::InitSystem(argc, argv))//初始化系统内核
        {
                ::CloseSystem();//关闭系统内核
                printf("\nInit System Error!");
                return(0);
        }


        //
       printf("\nhahahahahahahahhahah\n");


        //Close Sysem Kernel
        ::CloseSystem();//关闭系统内核

        return(1);

}
作者: zhgwbzhd     时间: 2005-12-20 14:58
报错内容是:
上面是一些地址
下面让我[T]终止,可能要重新启动计算机,如果系统不能使用的话.....
作者: firstsail     时间: 2005-12-20 18:30
对于BC31来说,如果语法错误太多,BC31会崩溃!

include <Symbol.h>  //这里的语法是有错的,崩溃在这里
#include <MyFrame.h>
//-----------------------------------------

#include <Symbol.h> //应该这样
#include <MyFrame.h>


//==========================================
//下面是例子
#include <Symbol.h>
#include <MyFrame.h>


//Stack's Size
unsigned int _stklen = 50u * 1024u;//堆栈的尺寸

//Keyboard's Callback Function For All Default Window
int TransrateKey(CObject* pCurObj)//所有窗口默认虚拟键盘回调函数
{
        return(0);
}

void far VccFunction(CObject* pCurObj)
{
        //Create a Dialog On the Center of Desktop
        CDialog* pDialog = new CDialog;//分配实例
        pDialog->CreateWindow(0, 0, 447, 364, "单选按钮演示");//建立窗口
        pDialog->Center();//窗口对中

        //Register Callback Function for Window
        pDialog->SetTimeFc(NULL);//注册定时器回调函数
        pDialog->SetDrawFc(NULL);//注册画图回调函数
        pDialog->SetHelpFc(NULL);//注册帮助回调函数
        pDialog->SetKeyboardFc(NULL);//注册虚拟键盘回调函数

        //Create Close's Button Control
        CCloseButton* pCloseButton = new CCloseButton(pDialog);//分配和建立关闭按钮

        //Create a Button Control
        CButton* pButton1 = new CButton(pDialog);
        pButton1->CreateObject(225, 141, 192, 24, "确定(\x3\E\x3)");
        pButton1->SetShortcutKey(VK_ALT_E);
        pButton1->SetFc(ClickEnterButton);
        pButton1->SetID(BUTTONBASE + 1 - 1);

        //Create a Button Control
        CButton* pButton2 = new CButton(pDialog);
        pButton2->CreateObject(223, 183, 192, 24, "取消(\x3\C\x3)");
        pButton2->SetShortcutKey(VK_ALT_C);
        pButton2->SetFc(ClickCancelButton);
        pButton2->SetID(BUTTONBASE + 2 - 1);

        //Create Group Control
        CStatic* pGroup1 = new CStatic(pDialog);
        pGroup1->CreateObject(10, 32, 204, 94, "星期");
        pGroup1->SetID(GROUPBASE + 1 - 1);

        //Create Radio Control
        CRadio* pRadio1 = new CRadio(pDialog);
        pRadio1->CreateObject(22, 53, 73, 24, "星期一");
        pRadio1->SetStatic(TRUE);
        pRadio1->SetRadio(TRUE);
        pRadio1->SetID(RADIOBASE + 1 - 1);

        //Create Radio Control
        CRadio* pRadio2 = new CRadio(pDialog);
        pRadio2->CreateObject(22, 76, 73, 24, "星期二");
        pRadio2->SetID(RADIOBASE + 2 - 1);

        //Create Radio Control
        CRadio* pRadio3 = new CRadio(pDialog);
        pRadio3->CreateObject(22, 98, 73, 24, "星期三");
        pRadio3->SetID(RADIOBASE + 3 - 1);

        //Create Group Control
        CStatic* pGroup2 = new CStatic(pDialog);
        pGroup2->CreateObject(226, 32, 204, 94, "性别");
        pGroup2->SetID(GROUPBASE + 2 - 1);

        //Create Radio Control
        CRadio* pRadio4 = new CRadio(pDialog);
        pRadio4->CreateObject(240, 53, 57, 24, "男性");
        pRadio4->SetStatic(TRUE);
        pRadio4->SetRadio(TRUE);
        pRadio4->SetID(RADIOBASE + 4 - 1);

        //Create Radio Control
        CRadio* pRadio5 = new CRadio(pDialog);
        pRadio5->CreateObject(240, 83, 57, 24, "女性");
        pRadio5->SetID(RADIOBASE + 5 - 1);

        //Create Check Control
        CRadio* pCheck1 = new CRadio(pDialog);
        pCheck1->CreateObject(22, 154, 57, 24, "读书");
        pCheck1->SetBox(TRUE);
        pCheck1->SetID(CHECKBASE + 1 - 1);
        pCheck1->SetID(CHECKBASE + 1 - 1);

        //Create Check Control
        CRadio* pCheck2 = new CRadio(pDialog);
        pCheck2->CreateObject(22, 180, 57, 24, "跑步");
        pCheck2->SetBox(TRUE);
        pCheck2->SetID(CHECKBASE + 2 - 1);
        pCheck2->SetID(CHECKBASE + 2 - 1);

        //Create Check Control
        CRadio* pCheck3 = new CRadio(pDialog);
        pCheck3->CreateObject(22, 202, 73, 24, "打足球");
        pCheck3->SetBox(TRUE);
        pCheck3->SetID(CHECKBASE + 3 - 1);
        pCheck3->SetID(CHECKBASE + 3 - 1);

        //Create Group Control
        CStatic* pGroup3 = new CStatic(pDialog);
        pGroup3->CreateObject(10, 133, 204, 96, "星期");
        pGroup3->SetID(GROUPBASE + 3 - 1);

        //Create Edit Control
        CEdit* pEdit1 = new CEdit(pDialog);
        pEdit1->CreateObject(97, 153, 106, 21, NULL);
        pEdit1->SetID(EDITBASE + 1 - 1);

        //Create Edit Control
        CEdit* pEdit2 = new CEdit(pDialog);
        pEdit2->CreateObject(99, 180, 106, 21, NULL);
        pEdit2->SetID(EDITBASE + 2 - 1);


        //Show Window
        pDialog->ShowWindow();//显示窗口

        //go into Message Loop
        pDialog->DoModal();//进入窗口消息循环

        //Destroy Window
        delete pDialog;//删除对话框


        return;

}

int main(int argc, char** argv)
{

        //Initlize Sysem Kernel
        if (!::InitSystem(argc, argv))//初始化系统内核
        {
                ::CloseSystem();//关闭系统内核
                printf("\nInit System Error!");
                return(0);
        }


        //Callback Function
        ::VccFunction(NULL);


        //Close Sysem Kernel
        ::CloseSystem();//关闭系统内核

        return(1);

}
作者: zhgwbzhd     时间: 2005-12-20 19:50
还是报错。不过这次倒是没有崩溃。
还是谢谢郭恒。
作者: LiveOnLove     时间: 2005-12-20 22:40
学习ING...
作者: lyq     时间: 2006-1-9 10:19
郭大侠!你好好牛,美死我了!!!,我狠狠地KISS YOU
作者: GONGXP     时间: 2006-1-21 21:15    标题: winsail编译程序死机

winsail太伟大了,但是编译的程序在那里运行,不动鼠标键盘,久了死机。是不是一定要带:
//Register Callback Function for Window
        pDialog->SetTimeFc(NULL);//注册定时器回调函数
        pDialog->SetDrawFc(NULL);//注册画图回调函数
        pDialog->SetHelpFc(NULL);//注册帮助回调函数
        pDialog->SetKeyboardFc(NULL);//注册虚拟键盘回调函数
作者: coolboy163     时间: 2006-2-16 14:45
厉害,这个强,
不过,看不懂,嘿嘿
作者: firstsail     时间: 2006-4-17 11:10    标题: 使用XMS内存

#include <string.h>

#include <Symbol.h>
#include <Memory.h>


extern unsigned _stklen = 50L * 1024L;


int main()
{
    //建立一个默认页框为256字节
        CXmsMemory  mXmsMemory;

    //分配一新的内存块作为新页框。页框越大,访问XMS的速度越快
    BYTE* pNewBlock = new BYTE[2048];
    //用户的默认页框为256字节,改变页框为2048字节
    BYTE* pOldBlock = mXmsMemory.ChangeFrame(pNewBlock, 2048);
    //删除老的页框
    delete pOldBlock;

    //分配200K字节的XMS内存
    mXmsMemory.SetSize(200L, 1024L);

    //增加100K的XMS内存(300 = 200 + 100)
    mXmsMemory.SetSizeEx(300L, 1024L);


    //将字符串“My name is LiPing!”写入以字节为单位的索引“120030L”的位置
    char buf[100] = "My Name is LiPing!";
    mXmsMemory.SetByteData(120030L, (BYTE *)buf, _fstrlen(buf) + 1);

    //将字符串“My name is LiPing!”从以字节为单位的索引“120030L”的位置读出来
    _fmemset((BYTE *)buf, 0, 100);
    mXmsMemory.GetByteData(120030L, (BYTE *)buf, 100);
    printf("\n S = \"%s\"", buf);
    getch();

    //释放已经分配的XMS内存块
    mXmsMemory.FreeXms();

    return(0);
}
作者: jawbin     时间: 2006-4-24 09:57
在 pcm3486 上如何使用呢

作者: firstsail     时间: 2006-4-24 12:46
在XMS模块中,全程变量int nAfxXmsStyle是控制默认分配XMS内存模式的变量。
nAfxXmsStyle = XMSMEMORY_STYLE_MORAL (=0)表示默认XMS
作者: firstsail     时间: 2006-4-24 12:58    标题: 使用XMS内存

在XMS模块中,全程变量int nAfxXmsStyle是控制默认分配XMS内存模式的变量。
nAfxXmsStyle = 0    (=XMSMEMORY_STYLE_MORAL)表示默认XMS
nAfxXmsStyle = 1    (=XMSMEMORY_STYLE_DISK)表示磁盘XMS
nAfxXmsStyle = 2    (=XMSMEMORY_STYLE_EMSCARD)表示PCM3486的扩充内存卡

如果您调用了"InitSystem()"函数,则它会分析“Config.Sys”文件的"Boot"段的“XmsStyle”键。


其实,可以调用CXmsMemory::SetXmsStyle()来改变XMS性质,必须在下面函数之前调用:
CXmsMemory::SetSize()
CXmsMemory::SetSizeEx()
CXmsMemory::MallocXms()函数

//---------------------------------------------

#include <string.h>

#include <Symbol.h>
#include <Memory.h>


extern unsigned _stklen = 50L * 1024L;

extern int nAfxXmsStyle;
int main()
{
    nAfxXmsStyle = XMSMEMORY_STYLE_DISK; //用磁盘访真XMS内存


    //建立一个默认页框为256字节
    CXmsMemory  mXmsMemory;

    //分配一新的内存块作为新页框。页框越大,访问XMS的速度越快
    BYTE* pNewBlock = new BYTE[2048];
    //用户的默认页框为256字节,改变页框为2048字节
    BYTE* pOldBlock = mXmsMemory.ChangeFrame(pNewBlock, 2048);
    //删除老的页框
    delete pOldBlock;

    //分配200K字节的XMS内存
    mXmsMemory.SetSize(200L, 1024L);

    //增加100K的XMS内存(300 = 200 + 100)
    mXmsMemory.SetSizeEx(300L, 1024L);


    //将字符串“My name is LiPing1!”写入以字节为单位的索引“120030L”的位置
    char buf[100] = "My Name is LiPing1!";
    mXmsMemory.SetByteData(120030L, (BYTE *)buf, _fstrlen(buf) + 1);

    //将字符串“My name is LiPing1!”从以字节为单位的索引“120030L”的位置读出来
    _fmemset((BYTE *)buf, 0, 100);
    mXmsMemory.GetByteData(120030L, (BYTE *)buf, 100);
    printf("\n S = \"%s\"", buf);


    //如果在普通PC上运行的话,可以将内存改为XMS
    mXmsMemroy.FreeXms();
    mXmsMemory.SetXmsStyle(XMSMEMORY_STYLE_NORMAL);//如果是PCM3486改为XMSMEMORY_STYLE_EMSCARD
    mXmsMemory.SetSize(300L, 1024L);

   //将字符串“My name is LiPing2!”写入以字节为单位的索引“120030L”的位置
    _fmemcpy(buf, "My Name is LiPing2!");
    mXmsMemory.SetByteData(120030L, (BYTE *)buf, _fstrlen(buf) + 1);

    //将字符串“My name is LiPing2!”从以字节为单位的索引“120030L”的位置读出来
    _fmemset((BYTE *)buf, 0, 100);
    mXmsMemory.GetByteData(120030L, (BYTE *)buf, 100);
    printf("\n S = \"%s\"", buf);


    getch();

    //释放已经分配的XMS内存块
    mXmsMemory.FreeXms();

    return(0);
}
作者: LLing     时间: 2006-6-3 13:25
好东西呀!

踏破铁鞋无觅处,得来全不费功夫!

多谢楼主的无私奉献!
作者: firstsail     时间: 2006-7-17 18:33
请问版主,如何在贴子里面插入图片?
作者: profree     时间: 2006-7-17 22:08
to firstsail:强烈建议你搞一个集成开发环境,就比如boywindows和qbwin之类的一样,这样就更方便了,虽然用你的程序转vc++生成的代码,可我看应该说不错, 但并不是非常好,所以如果有时间的话,强烈的建议!!!!!
作者: johnsonlam     时间: 2006-7-22 11:49


  Quote:
Originally posted by profree at 2006-7-17 10:08 PM:
to firstsail:强烈建议你搞一个集成开发环境,就比如boywindows和qbwin之类的一样,这样就更方便了,虽然用你的程序转vc++生成的代码,可我看应该说不� ...

Firstsail 的 介 面 真 的 棒 , 但 愿 国 内 这 些 高 手 可 以 参 与 世 界 性 的 计 划 例 如 ReactOS ... 一 方 面 不 样 微 软 剥 削 , 二 来 又 为 中 国 人 民 争 光 !
作者: LLM545     时间: 2006-7-24 09:09    标题: 我怎么下载不下来?请问如何下载


作者: profree     时间: 2006-7-25 00:44
老大,怎么没有回贴啊
作者: ArmKing     时间: 2006-8-28 02:03    标题: 如何支持 LCD Touch Panel?

请问配备相关硬件情况下,软件如何支持 LCD Touch Panel?
作者: ArmKing     时间: 2006-8-28 02:06
WinSail 内的某些控件做的有些小问题, 请问如何修改啊? 内核源码, 控件源码会公开吗?
作者: firstsail     时间: 2006-8-28 11:26
关于鼠标触摸屏:

(1)在InitSystem()这前,向WinSail内核注册用户自己编写的鼠标功能调用函数
   ::AfxRegisterMouseFc(::MyMouse_Touch);

    其中MyMouse_Touch的原型为:
    void far MyMouse_Touch(unsigned int ax, unsigned int bx,
        unsigned int cx, unsigned int dx);


void far MyMouse_Touch(unsigned int ax, unsigned int bx,
    unsigned int cx, unsigned int dx)
{
    //Register AX = 0  --> Reset Mouse
    //Register AX = 1  --> Open  Mouse
    //Register AX = 2  --> Close Mouse
    //Register AX = 3  --> IsMouseDown
    //Register AX = 4  --> SetMouseLocation


    REGS regs;
    _fmemset(&regs, 0, sizeof(REGS));


    /*
        在这时编写您自己的代码,参考鼠标功能调用INT33,根据入口和出口格式化regs寄存器
          Register AX = 0  --> Reset Mouse ->复位鼠标
            Register AX = 1  --> Open  Mouse ->显示鼠标
            Register AX = 2  --> Close Mouse ->不显示鼠标
            Register AX = 3  --> IsMouseDown ->取按键信息
            Register AX = 4  --> SetMouseLocation ->设置鼠标位置      
    */   
    //.....
    //.....
    //....


    //这里根据regs返回值,格式化鼠标消息结构MOUSEMSG SystemMouse

        switch(ax)
        {
                case   0: //Reset Mouse
                {
                        if (regs.x.ax == (unsigned) - 1)
                        {
                                SystemMouse.exist = 1;
                        }
                        else
                        {
                                SystemMouse.exist = 0;
                        }
                        SystemMouse.visible = FALSE;

                        break;
                }
                case 1:   //Open  Mouse
                case 2:   //Close Mouse
                {
                    break;
                }
                case 3: //IsMouseDown
                {
                        SystemMouse.statue = regs.x.bx;
                        SystemMouse.point.x = regs.x.cx;
                        SystemMouse.point.y = regs.x.dx;
                        break;
                }
                case   4: //SetMouseLocation
                {
                        SystemMouse.statue  = 0;
                        SystemMouse.times   = 0;
                        SystemMouse.point.x = cx;
                        SystemMouse.point.y = dx;
                        break;
                }
       
                default:
                {
                         break;
                }
        }

        return;
}
作者: profree     时间: 2006-9-18 23:39
winsail里如何获得复选框和单选框的状态?
我用GetRadio()不能获取
作者: firstsail     时间: 2006-9-19 03:55
用CRadio::SetBox()函数来设置复选框还是单选框。
用CRadio::SetRadio()函数来设置复选框/单选框的状态。
用CRadio::GetRadio()函数来获得复选框/单选框的状态。
用CRadio::GetStatic()函数来设置单选框的组属性。
对于单选框来说:有一个“组”的问题,如同Windows中的VC按钮控件的WS_GROUP属性。在一组中,只有组中的第一个CRadio才能有WS_GROUP属性。

假设有3个单选按钮,其构成3选一的一组逻辑操作,分别是
CRadio* pRadio1 ---  单选按钮1,内容为“男性”
CRadio* pRadio2 ---  单选按钮2,内容为“女性”
CRadio* pRadio3 ---  单选按钮3,内容为“保密”

.........

CRadio* pRadio1 = new CRadio(pDialog);  //分配实例
CRadio* pRadio2 = new CRadio(pDialog);  //分配实例
CRadio* pRadio3 = new CRadio(pDialog);  //分配实例

pRadio1->CreateObject(10,30 + 18 * 0, 100, 16, "男性");
pRadio2->CreateObject(10,30 + 18 * 1, 100, 16, "女性");
pRadio3->CreateObject(10,30 + 18 * 2, 100, 16, "保密");

pRadio1->SetBoX(FALSE); //是单选按钮,不是复选按钮
pRadio2->SetBoX(FALSE); //是单选按钮,不是复选按钮
pRadio3->SetBoX(FALSE); //是单选按钮,不是复选按钮

pRadio1->SetStatic(TRUE); //Radio1控件是Radio1~3单选按钮一组的第一个。


................


为了获得该组中是哪一个被选中,只能遍历该组中的每一个成员。
if (pRadio1->GetRadio())
{
}
else if (pRadio2->GetRadio())
{
}
else if (pRadio3->GetRadio())
{
}

........

所以profree提出的问题,可能是指“单选按钮”吧!
作者: profree     时间: 2006-9-19 22:54
谢谢回复
如果是复选框又怎么获得哪些项被选中了呢?
我很是搞不明白,如果我的一个窗口中有多个单选框/复选框,是分为一个以上组的,怎么分清是属于哪个组,又要怎么设置才能分开呢?
比如:
性别 分为 男,女,
年龄分为:15-20,21-30,31-40,
学历:大专,本科,硕士,博士
以上三个组都是同一窗口中,怎么分开设置,我认为应该有一个“归属于哪个组”的概念就好办多了
另外,如果一个对话框要设计成上一步,下一步,具体该怎么做?难道是上一步,下一步都要分别调用另一个函数来“画”对话框吗?这样如果对话框“画”多了,程序会就自动退出(应该是内存不够吧)
作者: firstsail     时间: 2006-9-20 05:04
VC++生成对话框,MakeDlg转换成WinSail的源代码,阅读之,可以较好的了解。

关于单选按钮(适用于WinSail及微软的Windows)
(1)一个对话框中,可以有多“组”单选按钮
(2)一组单选按钮中,所有的单选按钮必须是连续分配的。
(3)一组单选按钮中的第一个单选按钮的属性是带有WS_GROUP窗口风格的
      如果是VC,在单选按钮的属性框中选中Static属性。
   如果是Winsail,调用CRadio::SetStatic(TRUE);
(4)假设有3组单选按钮
      第一组是性别 分为 男,女,
      第二组是年龄:15-20,21-30,31-40,
      第三组是学历:大专,本科,硕士,博士


//第一组
CRadio* pRadio1 = new CRadio(pDialog);  //分配实例
CRadio* pRadio2 = new CRadio(pDialog);  //分配实例

pRadio1->CreateObject(10,30 + 18 * 0, 100, 16, "男");
pRadio2->CreateObject(10,30 + 18 * 1, 100, 16, "女");

pRadio1->SetBox(FALSE); //是单选按钮,不是复选按钮
pRadio2->SetBox(FALSE); //是单选按钮,不是复选按钮

pRadio1->SetStatic(TRUE); //Radio1控件是Radio1-2的组带头人


//第二组
CRadio* pRadio3 = new CRadio(pDialog);  //分配实例
CRadio* pRadio4 = new CRadio(pDialog);  //分配实例
CRadio* pRadio5 = new CRadio(pDialog);  //分配实例

pRadio3->CreateObject(10,50 + 18 * 0, 100, 16, "15-20");
pRadio4->CreateObject(10,50 + 18 * 1, 100, 16, "21-30");
pRadio5->CreateObject(10,50 + 18 * 2, 100, 16, "31-40");

pRadio3->SetStatic(TRUE); //Radio3控件是Radio3-5的组带头人


//第三组
CRadio* pRadio6 = new CRadio(pDialog);  //分配实例
CRadio* pRadio7 = new CRadio(pDialog);  //分配实例
CRadio* pRadio8 = new CRadio(pDialog);  //分配实例
CRadio* pRadio9 = new CRadio(pDialog);  //分配实例

pRadio6->CreateObject(10,70 + 18 * 0, 100, 16, "大专");
pRadio7->CreateObject(10,70 + 18 * 1, 100, 16, "本科");
pRadio8->CreateObject(10,70 + 18 * 2, 100, 16, "硕士");
pRadio9->CreateObject(10,70 + 18 * 3, 100, 16, "博士");


pRadio6->SetStatic(TRUE); //Radio6控件是Radio6-9的组带头人


------------------------------------------------------------
WinSail V2.0的GUI有一些已经更新,可重新下载了!
作者: firstsail     时间: 2006-9-20 05:19
(1)WinSail V2.0的全局控件句柄只有120个。
    #define MAX_OBJECT_LIST_COUNT 120
(2)WinSail V2.0运行于实模式,受DOS的640K内存限制。
(3) 每一个窗口/对话框中的控件不限,受内存和全局控件句柄个数限制。
作者: profree     时间: 2006-9-21 00:20
我的窗口需要使用下一步,上一步来完成,我想按下一步或上一步时,删除本窗口,重新生成新的窗口,我定义一个全局变量,在执行下一步时,先删除上一窗口,再生成新的窗口,但不成功,不知是为什么
作者: firstsail     时间: 2006-9-21 21:28
不能在本窗口的“控件”函数里面删除其父窗口。
只能发出窗口退出消息,可通过
   void CloseWindow(CObject* pObj); -------- 窗口返回值为“IDCLOSE”
   void ClickCloseButton(CObject* pObj); --- 窗口返回值为“IDCLOSE”
   void ClickEnterButton(CObject* pObj); --- 窗口返回值为“IDOK”
   void ClickCancelButton(CObject* pObj); -- 窗口返回值为“IDCANCEL”
   void ClickYesButton(CObject* pObj); ----- 窗口返回值为“IDYES”
   void ClickNoButton(CObject* pObj); ------ 窗口返回值为“IDNO”
   void ClickRetryButton(CObject* pObj); --- 窗口返回值为“IDRETRY”

窗口消息循环函数为:  int CWindow::PurseMessage();
对话框消息循环函数为:int CDialog::DoModal();

int CDialog::DoModal()的函数源代码为
int CDialog::DoModal()
{
        return(CWindow::PurseMessage());
}


void ClickEnterButton(CObject* pObj)的函数源代码为
void ClickEnterButton(CObject* pObj)
{
   ::CloseWindow(pObj);

   extern int nAfxMessageFlags;
   nAfxMessageFlags = IDOK;
}

void ClickCancelButton(CObject* pObj)的函数源代码为
void ClickCancelButton(CObject* pObj)
{
   ::CloseWindow(pObj);

   extern int nAfxMessageFlags;
   nAfxMessageFlags = IDCANCEL;
}
作者: firstsail     时间: 2006-9-21 21:34
int CWindow::PurseMessage()的函数源代码为
int CWindow::PurseMessage()
{
    int nOldMessageFlags = nAfxMessageFlags; // 保护原值
    nAfxMessageFlags = IDNULL; //刷新窗口退出标志

    //......

    //窗口消息循环
    while (nAfxMessageFlags == IDNULL)
    {
        //....
    }


    //...

   
   int nResult = nAfxMessageFlags;
   nAfxMessageFlags = nOldMessageFlags; //恢复原值
   return (nResult);
}
作者: firstsail     时间: 2006-9-21 23:53    标题: 发给一个实用的“向导”类

/*
向导属性封装,由于WinSail受640K内存限制,可以这样来设计
(1)向“向导页”注册的页是函数,函数原型为
   int far page(CObject* pObj);
   对返回值要求
   IDNO ------ 表示单击了“上一步”按钮
   IDYES ----- 表示单击了“下一步”按钮
   IDCANCEL -- 表示单击了“退出”按钮
(2)最多支持MAX_WIZARD_COUNT ( =10)个页
*/

#include <Symbol.h>
#include <Myframe.h>


#define MAX_WIZARD_COUNT  10
class CWizard
{
private:
       int  m_nOrder;
       int  m_nCount;
       int far (*m_psFc[MAX_WIZARD_COUNT])(CObject *);
public:
       BOOL  AddDialog(int far (*pFc)(CObject*));
public:
       int   DoWizard();

public:

     CWizard();
     ~CWizard();
};


CWizard::CWizard()
{
    m_nOrder = 0;
    m_nCount = 0;
    for (int i = 0; i < MAX_WIZARD_COUNT; i++)
    {
        m_psFc[i] = NULL;
    }
}

CWizard::~CWizard()
{
}

BOOL  CWizard::AddDialog(int far (*pFc)(CObject *))
{
    if (pFc == NULL || m_nCount >= MAX_WIZARD_COUNT)
    {
        return (FALSE);
    }

    m_psFc[m_nCount++] = pFc;

    return (TRUE);
}

int   CWizard::DoWizard()
{
    //1 - IDNO   --  Prev
    //2 - IDYES  --  Next
    //3 - Cancel --  Cancel
    int far (*pFc)(CObject *) = NULL;

    int nResult = IDCLOSE;
    while (1)
    {
        pFc = m_psFc[m_nOrder];

        if (pFc == NULL)
        {
            break;
        }

        nResult = pFc(NULL);

        if (nResult == IDNO)
        {
            if (m_nOrder > 0)
            {
                m_nOrder--;
            }
            continue;
        }
        else if (nResult == IDYES)
        {
            if (m_nOrder + 1 < m_nCount)
            {
                m_nOrder++;
            }
            continue;
        }

        break;
    }

    return (nResult);
}
作者: firstsail     时间: 2006-9-21 23:58
将CWizard::AddDialog()函数改名为CWizard::AddPage()函数
现举例如下:

#include <Symbol.h>
#include <MyFrame.h>

int far Page1(CObject* pCurObj)
{
        //Create a Dialog On the Center of Desktop
        CDialog* pDialog = new CDialog;//分配实例
        pDialog->CreateWindow(0, 0, 321, 240, "第一页:1");//建立窗口
        pDialog->Center();//窗口对中


        //Create Close's Button Control
        CCloseButton* pCloseButton = new CCloseButton(pDialog);//分配和建立关闭按钮

        //Create a Button Control
        CButton* pButton1 = new CButton(pDialog);
        pButton1->CreateObject(10, 199, 93, 24, "上一步(\x3P\x3)");
        pButton1->SetShortcutKey(VK_ALT_P);
        pButton1->SetFc(ClickNoButton);

        //Create a Button Control
        CButton* pButton2 = new CButton(pDialog);
        pButton2->CreateObject(111, 199, 93, 24, "下一步(\x3N\x3)");
        pButton2->SetShortcutKey(VK_ALT_N);
        pButton2->SetFc(ClickYesButton);

        //Create a Button Control
        CButton* pButton3 = new CButton(pDialog);
        pButton3->CreateObject(211, 199, 93, 24, "退出(\x3\C\x3)");
        pButton3->SetShortcutKey(VK_ALT_C);
        pButton3->SetFc(ClickCancelButton);


        //Create Radio Control
        CRadio* pRadio1 = new CRadio(pDialog);
        pRadio1->CreateObject(28, 59, 57, 24, "男姓");
        pRadio1->SetStatic(TRUE);
        pRadio1->SetRadio(TRUE);
        pRadio1->SetID(RADIOBASE + 1 - 1);

        //Create Radio Control
        CRadio* pRadio2 = new CRadio(pDialog);
        pRadio2->CreateObject(100, 61, 57, 24, "女性");
        pRadio2->SetID(RADIOBASE + 2 - 1);

        //Create Radio Control
        CRadio* pRadio3 = new CRadio(pDialog);
        pRadio3->CreateObject(171, 61, 57, 24, "保密");
        pRadio3->SetID(RADIOBASE + 3 - 1);

        //Create Radio Control
        CRadio* pRadio4 = new CRadio(pDialog);
        pRadio4->CreateObject(28, 148, 57, 24, "大专");
        pRadio4->SetStatic(TRUE);
        pRadio4->SetRadio(TRUE);
        pRadio4->SetID(RADIOBASE + 4 - 1);

        //Create Radio Control
        CRadio* pRadio5 = new CRadio(pDialog);
        pRadio5->CreateObject(100, 148, 57, 24, "本科");
        pRadio5->SetID(RADIOBASE + 5 - 1);

        //Create Radio Control
        CRadio* pRadio6 = new CRadio(pDialog);
        pRadio6->CreateObject(169, 148, 57, 24, "硕士");
        pRadio6->SetID(RADIOBASE + 6 - 1);

        //Create Radio Control
        CRadio* pRadio7 = new CRadio(pDialog);
        pRadio7->CreateObject(229, 147, 57, 24, "博士");
        pRadio7->SetID(RADIOBASE + 7 - 1);

        //Create Group Control
        CStatic* pGroup1 = new CStatic(pDialog);
        pGroup1->CreateObject(10, 29, 285, 67, "性别");

        //Create Group Control
        CStatic* pGroup2 = new CStatic(pDialog);
        pGroup2->CreateObject(10, 118, 285, 66, "学位");

        //Show Window
        pDialog->ShowWindow();//显示窗口

        //go into Message Loop
        int nResult = pDialog->DoModal();//进入窗口消息循环

        //Destroy Window
        delete pDialog;//删除对话框


        return (nResult);

}

int far Page2(CObject* pCurObj)
{
        //Create a Dialog On the Center of Desktop
        CDialog* pDialog = new CDialog;//分配实例
        pDialog->CreateWindow(0, 0, 321, 240, "第二页:2");//建立窗口
        pDialog->Center();//窗口对中

        //Create Close's Button Control
        CCloseButton* pCloseButton = new CCloseButton(pDialog);//分配和建立关闭按钮

        //Create a Button Control
        CButton* pButton1 = new CButton(pDialog);
        pButton1->CreateObject(10, 199, 93, 24, "上一步(\x3P\x3)");
        pButton1->SetShortcutKey(VK_ALT_P);
        pButton1->SetFc(ClickNoButton);

        //Create a Button Control
        CButton* pButton2 = new CButton(pDialog);
        pButton2->CreateObject(111, 199, 93, 24, "下一步(\x3N\x3)");
        pButton2->SetShortcutKey(VK_ALT_N);
        pButton2->SetFc(ClickYesButton);

        //Create a Button Control
        CButton* pButton3 = new CButton(pDialog);
        pButton3->CreateObject(211, 199, 93, 24, "退出(\x3\C\x3)");
        pButton3->SetShortcutKey(VK_ALT_C);
        pButton3->SetFc(ClickCancelButton);

        //Create Radio Control
        CRadio* pRadio1 = new CRadio(pDialog);
        pRadio1->CreateObject(28, 64, 57, 24, "北京");
        pRadio1->SetStatic(TRUE);
        pRadio1->SetRadio(TRUE);
        pRadio1->SetID(RADIOBASE + 1 - 1);

        //Create Radio Control
        CRadio* pRadio2 = new CRadio(pDialog);
        pRadio2->CreateObject(100, 65, 57, 24, "上海");
        pRadio2->SetID(RADIOBASE + 2 - 1);

        //Create Radio Control
        CRadio* pRadio3 = new CRadio(pDialog);
        pRadio3->CreateObject(171, 65, 57, 24, "广州");
        pRadio3->SetID(RADIOBASE + 3 - 1);

        //Create Combo Control
        CComboBox* pComboBox1 = new CComboBox(pDialog);
        pComboBox1->CreateCombo(124, 122, 169, 24, NULL);
        pComboBox1->SetID(COMBOBASE + 1 - 1);


        //Create Group Control
        CStatic* pGroup1 = new CStatic(pDialog);
        pGroup1->CreateObject(10, 34, 285, 67, "籍贯");

        //Create a Label Control
        CLabel* pLabel1 = new CLabel(pDialog);
        pLabel1->CreateObject(13, 125, 67, 12, "选择年份(N)");


        //Show Window
        pDialog->ShowWindow();//显示窗口

        //go into Message Loop
        int nResult = pDialog->DoModal();//进入窗口消息循环

        //Destroy Window
        delete pDialog;//删除对话框


        return (nResult);

}

int far Page3(CObject* pCurObj)
{
        //Create a Dialog On the Center of Desktop
        CDialog* pDialog = new CDialog;//分配实例
        pDialog->CreateWindow(0, 0, 321, 240, "第三页:3");//建立窗口
        pDialog->Center();//窗口对中

        //Create Close's Button Control
        CCloseButton* pCloseButton = new CCloseButton(pDialog);//分配和建立关闭按钮

        //Create a Button Control
        CButton* pButton1 = new CButton(pDialog);
        pButton1->CreateObject(10, 199, 93, 24, "上一步(\x3P\x3)");
        pButton1->SetShortcutKey(VK_ALT_P);
        pButton1->SetFc(ClickNoButton);

        //Create a Button Control
        CButton* pButton2 = new CButton(pDialog);
        pButton2->CreateObject(111, 199, 93, 24, "下一步(\x3N\x3)");
        pButton2->SetShortcutKey(VK_ALT_N);
        pButton2->SetFc(ClickYesButton);

        //Create a Button Control
        CButton* pButton3 = new CButton(pDialog);
        pButton3->CreateObject(211, 199, 93, 24, "退出(\x3\C\x3)");
        pButton3->SetShortcutKey(VK_ALT_C);
        pButton3->SetFc(ClickCancelButton);

        //Create Slider Control
        CSliderCtrl* pSliderCtrl1 = new CSliderCtrl(pDialog);
        pSliderCtrl1->CreateObject(37, 153, 241, 24, NULL);
        pSliderCtrl1->SetID(SLIDERBASE + 1 - 1);
        pSliderCtrl1->SetHorz(TRUE);

        //Create Slider Control
        CSliderCtrl* pSliderCtrl2 = new CSliderCtrl(pDialog);
        pSliderCtrl2->CreateObject(138, 38, 30, 111, NULL);
        pSliderCtrl2->SetID(SLIDERBASE + 2 - 1);
        pSliderCtrl2->SetHorz(FALSE);


        //Show Window
        pDialog->ShowWindow();//显示窗口

        //go into Message Loop
        int nResult = pDialog->DoModal();//进入窗口消息循环

        //Destroy Window
        delete pDialog;//删除对话框


        return(nResult);

}

void DemoWizard()
{
    CWizard *pWizard = new CWizard;


    pWizard->AddPage (Page1);
    pWizard->AddPage (Page2);
    pWizard->AddPage (Page3);


    pWizard->DoWizard();

    DELETE(pWizard);
}
作者: profree     时间: 2006-9-23 00:09
非常感谢firstsail的热心帮助!
这几天一直在看winsail的资料,现有几个建议:
一、好像winsail没有驱动器列表,选项卡控件和数值增减控件,不知firstsail能否加入
二、本人以前也反映过firstsail的界面和控件的美观问题,firstsail能否再考虑
前久下载了chicago9的源代码(全部为源代码),里面有可执行文件,包括驱winsail没有动器列表控件,数值增减控件等控件,运行截图如下:








建议firstsail能取其长处,这个文件可以到网上下载,或需要的话我可以上传

[ Last edited by profree on 2006-9-23 at 02:32 ]
作者: firstsail     时间: 2006-9-23 06:04
WinSail V2.0内核已经重新上传。

     (1) 演示程序所在的目录是“Sail3000”
     (2)“向导”类已经被“WinSail”内核支持。
     (3)“向导”类的详细设计文档名为“界面非控件类_CWizard向导类详细设计.doc”
     (4)“向导”演示模块在“sail3000\Wizard2.cpp”文件
     (5) 可在Win98,Windows2000,WindowsXP运行Sail3000\sail2000.exe可执行文件。
     (6) 鼠标只能在“Win98”或“纯DOS”下显示。

     所有用WinSail V2.0开发出来的界面,只要按下“F3”功能键,就自动会将当前窗口的画
面以256色的“a.bmp”文件形式记录下来,方便写说明书。
作者: firstsail     时间: 2006-9-23 06:08    标题: 关于“chicago9”

这个“芝加哥”chicago9哪里可以下载?
我在“百度”和“google”里面都无法找到?请问它是“DOS”下运行的吗?
您可以通过邮件把“chicago9”发到我的信箱“szhello8@21cn.net”,多谢!
作者: profree     时间: 2006-9-23 06:58
哈哈,芝加哥?差不多哦。:)

是我一次在外国网站上下载的,现在再查找时好像真的不好找,幸好已经保存下来。
chicago9是运行于DOS下的,我用BC3.1编译通过,chicago9目录下有chicago.exe可执行文件。
压缩文件已经发到你的信箱,请查收

很高兴看到已经把向导类加入,:)
按照你的程序,头痛的向导搞定了

另外,多行文本框除了用loadfile以外,还有其它方法让它显示多行文本吗?用setlinetext没有效果。
谢谢

[ Last edited by profree on 2006-9-23 at 22:27 ]
作者: firstsail     时间: 2006-9-24 08:46
WinSail V2.0内核已经重新上传!

更新了:
        CKeyboardCtrl----虚拟键盘类
        CRadio-----------单选按钮/复选框类
        CGrid------------表格类
        CSliderCtrl------滑块类
        CComboBox--------组合框类
        CListBox---------列表框类
        CVScrollBar------垂直滑动条类
        CHScrollBar------水平滑动条类
        CWizard ---------向导类

        MakeDlg.exe -----VC对话框转WinSail的可执行程序

增加了:
        CSpinCtrl --------计数类,其文档名为:
            “界面控件类_CSpinCtrl计数控件详细设计.doc”

--------------------------------------------------------------------------------------
   WinSail V2.0的“计数”控件设计成与Visual C++的对
话框中的“计数”控件行为相同,需要有“EDIT”编辑框作
为伙伴控件供显示用。并且WinSail V2.0的“计数”控件支
持键盘光标键“UP”“DOWN”操作。

  “计数”类的演示程序模块是Sail3000目录下的“Wizard2.Cpp”文件的向导页的第三页。
可看桌面上的“向导”演示。
作者: firstsail     时间: 2006-9-24 09:26
假设想将以下“三行”内容写入多行编辑框,
   
   第一行:"《天龙八布》";
   第二行:"《新闻联播》";
   第三行:"《我爱我家》";

要以这样来:
------------------------------------------

void Demo_WriteEdit(CMultiEdit* pMultiEdit)
{

    DWORD dwLoc;
    int nLength;

    char* pStr1 = "《天龙八布》";
    char* pStr2 = "《新闻联播》";
    char* pStr3 = "《我爱我家》";

    //分配新的一行
    nLength =   _fstrlen(pStr1) + 1; //计算串长度
    dwLoc = pMultiEdit->m_XmsMemoryData.New (nLength, FALSE); //分配内存
   
    //将串写入内存
    if (dwLoc != 0L)
    {
        pMultiEdit->m_XmsMemoryData.SetText(dwLoc, pStr1, nLength);
    }
   
    //分配新的一行
    nLength =   _fstrlen(pStr2) + 1; //计算串长度
    dwLoc = pMultiEdit->m_XmsMemoryData.New (nLength, FALSE); //分配内存
   
    //将串写入内存
    if (dwLoc != 0L)
    {
        pMultiEdit->m_XmsMemoryData.SetText(dwLoc, pStr2, nLength);
    }

    //分配新的一行
    nLength =   _fstrlen(pStr3) + 1; //计算串长度
    dwLoc = pMultiEdit->m_XmsMemoryData.New (nLength, FALSE); //分配内存
   
    //将串写入内存
    if (dwLoc != 0L)
    {
        pMultiEdit->m_XmsMemoryData.SetText(dwLoc, pStr3, nLength);
    }

}
作者: ArmKing     时间: 2006-9-25 13:29
烦请也给我一分chicago9的源代码, 谢谢
Email: ArmKing88@163.com
作者: profree     时间: 2006-9-26 00:16


  Quote:
Originally posted by ArmKing at 2006-9-25 01:29 PM:
烦请也给我一分chicago9的源代码, 谢谢
Email: ArmKing88@163.com

已发
作者: profree     时间: 2006-9-26 00:18
to firstsail:
这样使用多行编辑框会不会麻烦了一些?希望能改进
作者: firstsail     时间: 2006-9-26 02:09
To Profree:

受了您的误导,其实CMultiEdit->SetWindowText()函数是可以设置多行内容的。

pMultiEdit1->SetWindowText("《天龙八布》\n《新闻联播》\n《我爱我家》");

如果您是在对话框的pDialog->ShowWindow()之后调用,您必须调用
pMultiEdit1->Paint()函数或pMultiEdit1->Show()函数才能更新显示。

WinSail的所有控件,改变内容后,都必须人工调用Paint或Show()函数方能重新显示。
作者: profree     时间: 2006-9-26 02:30
是你自己写的编程库,我能误导你吗?:)

当调用Show,返回上一步时会出现滞后现象

[ Last edited by profree on 2006-9-26 at 02:47 ]
作者: firstsail     时间: 2006-9-26 06:28
WinSail 已经重新上传!

  WinSail 的Bmp图片和ICON图标的显示已经作了“抖动”处理,对256色图片的显示具有较满意的显示效果!

怎么在贴子里面插入图片?
作者: profree     时间: 2006-9-26 07:04
FirstWail兄: 不会吧?

这就难倒英雄汉了?以附件的形式上传或者先上传到网站,在发贴的地方有提示:
“注意:强烈建议将文件或图片上传至中国DOS联盟文件上传系统,单个上传文件大小可达50MB。 ”


另外:发布更新winsail时,能在网站上注明最后更新时间更好,如:[下载:WinSail V2.0编程库](2006-9-25 19:1:38 Monday)
作者: profree     时间: 2006-9-26 07:13
再提几点建议:

1、多行编辑框内显示内容超过控件的大小时,自动触发滚动条
2、增加驱动器选择控件
3、完美文件选择控件

现在我认为winsail差不多实用化了,另外还有一点就是菜单项,现在没有分隔符,位置太紧
现在想到的就这些了
作者: firstsail     时间: 2006-9-28 05:45
WinSail (2006-09-27 15:30)已经重新上传!


(1)原来的VK_MOUSE_LEFT“宏”被取消,用到该“宏”的场合,请用VK_MOUSE_DOWN_LEFT“宏”代替!

(2)“弹出菜单”增加了“分隔符”的菜单项。
    函数名为----CBar:AddSeparator();
    等同于调用--CBar::AddItem(NULL, NULL, NULL, BAR_ATTRIB_SEPRATOR);
作者: firstsail     时间: 2006-9-28 05:47
写错单词,应是“BAR_ATTRIB_SEPARATOR”
作者: hh0118     时间: 2006-9-28 21:11    标题: dos编程开发

郭先生,看见你的帖子,很感兴趣,请问你在哪里?我有一个项目要做GUI的开发。是否能和我联系一下(hh_0118@hotmail.com)或留下你的联系方法我和你联系。谢了先!
作者: profree     时间: 2006-9-28 21:43
确实,现在显示的BMP图片好看多不了,不会变色了

1、增加设置默认项,也就是按回车时执行的默认项
2、修改现在的单选框/复选框 项-按热键为选中
3、显示BMP文件可改变大小,可有两种方式,剪辑或缩放
作者: firstsail     时间: 2006-9-29 03:15
WinSail V2.0 已重新上传 --- 2006-09-28 15:30

增加了按钮控件的“默认”属性,函数为
   CButton::SetDefaultFlags(BOOL bFlags);
作者: profree     时间: 2006-9-29 04:11
老大,太感谢你了

以前我都是把要默认的项放在最前面,现在方便多了

1、能否讲讲滚动条控件怎样使用,比如用在列表框控件或多行编辑框控件
2、滑动条控件、增值控件、和编辑控件三者“绑定”后,怎样才能保证三者的一致,
3、滑动条控件的默认值和“步长”怎么设置
4、进度条怎样设置等时间
5、进度条的表现上能否增加平滑一项,现在的是块状

[ Last edited by profree on 2006-9-29 at 04:15 ]
作者: firstsail     时间: 2006-9-29 06:37
问:(1)滑动条控件的默认值和“步长”怎么设置
答:
     //设置滑块的范围,相当于“步长”
     CSliderCtrl::SetRange(DWORD dwMin ,DOWRD dwMax)

     //获得滑块的范围
     CSliderCtrl::GetRange(DWORD* pdwMin ,DOWRD* pdwMax)

     //设置滑块的位置
     CSliderCtrl::SetPos(int nPos)

     //获得滑块的位置
     CSliderCtrl::GetPos()

问:(2)进度条怎样设置等时间
答:
     “进度条”没有所谓的时间间隔属性。

     //设置进度条的范围,相当于“步长”
     CSliderCtrl::SetRange(DWORD dwMin ,DOWRD dwMax)

     //获得进度条滑块的范围
     CSliderCtrl::GetRange(DWORD* pdwMin ,DOWRD* pdwMax)

     //设置进度条的位置
     CSliderCtrl::SetPos(int nPos)

     //获得进度条的位置
     CSliderCtrl::GetPos()

     进度条单词应是“CProgressCtrl”,这里有误,以后改正!
作者: firstsail     时间: 2006-9-29 06:39
上面贴子应该如下所示:

问:(1)滑动条控件的默认值和“步长”怎么设置
答:
     //设置滑块的范围,相当于“步长”
     CSliderCtrl::SetRange(DWORD dwMin ,DOWRD dwMax)

     //获得滑块的范围
     CSliderCtrl::GetRange(DWORD* pdwMin ,DOWRD* pdwMax)

     //设置滑块的位置
     CSliderCtrl::SetPos(int nPos)

     //获得滑块的位置
     CSliderCtrl::GetPos()

问:(2)进度条怎样设置等时间
答:
     “进度条”没有所谓的时间间隔属性。

     //设置进度条的范围,相当于“步长”
     CProcessCtrl::SetRange(DWORD dwMin ,DOWRD dwMax)

     //获得进度条滑块的范围
     CProcessCtrl::GetRange(DWORD* pdwMin ,DOWRD* pdwMax)

     //设置进度条的位置
     CProcessCtrl::SetPos(int nPos)

     //获得进度条的位置
     CProcessCtrl::GetPos()

     进度条单词应是“CProgressCtrl”,这里有误,以后改正!
作者: firstsail     时间: 2006-9-29 06:57    标题: 关于滚动条的使用

(1) 横向滚动条CHScrollBar的使用(),一般是
    <1>分配实例               
    <2>建立滚动条
    <3>设置滚动条的范围
    <4>设置滚动条的默认值
    <5>注册单击“滚动条左边按钮”事件
    <6>注册单击“滚动条拖动中间按钮”事件
    <7>注册拖动“滚动条左边按钮”事件
    <7>给滚动条分配一个不与其它控件冲突的ID号


    void far ClickScroll_Left(CHScrollBar* pScroll)
    {
        CDialog* pDialog = (CDialog *)pScroll->GetParent();
        //....
    }

    void far ClickScroll_Pos(CHScrollBar* pScroll)
    {
        CDialog* pDialog = (CDialog *)pScroll->GetParent();
        //....
    }

    void far ClickScroll_Right(CHScrollBar* pScroll)
    {
        CDialog* pDialog = (CDialog *)pScroll->GetParent();
        //....
    }

    //...


    CHScrollBar *pScrollBarH1 = new  CHScrollBar(pDialog); //分配实例
    pScrollBarH1->CreateScrollBar(100, 100, //建立滚动条
        180, SCROLL_BAR_WIDTH, NULL);
    pScrollBarH1->SetRange(0, 10); //设置范围
    pScrollBarH1->SetPos(5);  //设置默认值
    pScrollBarH1->SetScrollLeftRc(); //注册“单击左边按钮”事件
    pScrollBarH1->SetScrollPosRc();//注册“拖动中间按钮”事件
    pScrollBarH1->SetScrollRightRc();//注册“单击右边按钮”事件
    pScrollBarH1->SetID(HSCROLLBASE + 1 - 1); //设置ID号
作者: firstsail     时间: 2006-9-29 06:58
CHScrollBar *pScrollBarH1 = new  CHScrollBar(pDialog); //分配实例
    pScrollBarH1->CreateScrollBar(100, 100, //建立滚动条
        180, SCROLL_BAR_WIDTH, NULL);
    pScrollBarH1->SetRange(0, 10); //设置范围
    pScrollBarH1->SetPos(5);  //设置默认值
    pScrollBarH1->SetScrollLeftRc(::ClickScroll_Left); //注册“单击左边按钮”事件
    pScrollBarH1->SetScrollPosRc(::ClickScroll_Pos);//注册“拖动中间按钮”事件
    pScrollBarH1->SetScrollRightRc(::ClickScroll_Right);//注册“单击右边按钮”事件
    pScrollBarH1->SetID(HSCROLLBASE + 1 - 1); //设置ID号
作者: firstsail     时间: 2006-9-29 07:11
单击了横向滚动条“左按钮”时 , 滚动条会向上层控件返回“VK_SCROLL_LEFT”消息宏
拖动了横向滚动条“中间按钮”时,滚动条会向上层控件返回“VK_SCROLL_HORZ_POS”消息宏
单击了横向滚动条“左按钮”时,  滚动条会向上层控件返回“VK_SCROLL_RIGHT”消息宏

单击了竖向向滚动条“上按钮”时 , 滚动条会向上层控件返回“VK_SCROLL_UP”消息宏
拖动了竖向滚动条“中间按钮”时,滚动条会向上层控件返回“VK_SCROLL_VERT_POS”消息宏
单击了竖向滚动条“下按钮”时,  滚动条会向上层控件返回“VK_SCROLL_DOWN”消息宏
作者: firstsail     时间: 2006-9-29 07:15
(1)int CObject::SWapping()虚函数是所有控件的消息循环泵。
(2)窗口消息循环,就是不断地调用焦点控件的Swapping()函数。
作者: firstsail     时间: 2006-9-29 07:24    标题: 关于“控件基类的消息泵”

控件基类CObject的消息泵Swapping()函数源代码如下

int CObject::DefaultSwapping()
{
        int nKey = 0;
        int nX , nY;

        if (AfxKbhit())
        {
        nKey = ::bioskey(0);
        }

        if (nKey != 0)
        {
            return (nKey);
        }

        ::IsMouseDown(MOUSE_LEFT);
        nX = ::GetMouseX();
        nY = ::GetMouseY();

        if ((SystemMouse.statue & MOUSE_LEFT) == MOUSE_LEFT)
        {
            if (this->IsClientRect(nX, nY))
            {
                nKey = VK_MOUSE_DOWN_LEFT;
            }
            else if (this->IsScreenRect(nX, nY))
            {
                nKey = VK_MOUSE_CLIENT_OUT;
                if ((m_dwSort & WINDOW_SORT) != WINDOW_SORT)
                {
                    nKey = 0;
                }
            }
           else
          {
                nKey = VK_MOUSE_SCREEN_OUT;
          }
        }
        else if ((SystemMouse.statue & MOUSE_RIGHT) == MOUSE_RIGHT)
        {
            if (this->IsClientRect(nX, nY))
            {
                nKey = VK_MOUSE_DOWN_RIGHT;
            }
            else if (this->IsScreenRect(nX, nY))
            {
                nKey = VK_MOUSE_CLIENT_OUT;
                if ((m_dwSort & WINDOW_SORT) != WINDOW_SORT)
                {
                    nKey = 0;
                }
            }
            else
            {
                nKey = VK_MOUSE_SCREEN_OUT;
            }

        }

        if (nKey != 0)
        {
            return (nKey);
        }

        nKey = this->VirtualKeyboard();

        return(nKey);

}

int CObject::Swapping()
{
        return(this->DefaultSwapping());

}
作者: profree     时间: 2006-9-29 22:12
一、SetDefaultFlags函数有问题,当把某一项设为默认后,按Tab键把焦点移到另外一项,再按回车,执行的并不是焦点所在项,而是设置的默认项,在跟我们现在使用的Windows对话框的操作是不一致的

二、关于鼠标动作的响应问题,应该是鼠标按下直到释放才执行(应该是release吧,现在的是press),比如说在一个按钮上,应该是在按钮内按下鼠标左键,直到左键释放,当然范围也应是在按钮范围内,如果在按钮范围外释放,则操作无效
作者: firstsail     时间: 2006-9-30 01:20
WinSail 已经重新上传 2006-09-29 13:00

(1)SetDefaultFlags()已经重新“修正”

(2)“进度条”类的名称,已由“CProcessCtrl”更名为正确的“CProgressCtrl”
作者: profree     时间: 2006-9-30 04:25
随时和“官方”保持同步更新。

使用哪种字体在哪里设置?在config.sys文件里设置的显示属性起效,但设置的字体不起作用,我只能把字体改为默认的display.fon
作者: firstsail     时间: 2006-9-30 04:49
To Profree:

由于历史原因,Config.Sys文件的[Display]段的Font键是“布尔值”,需要升级为“字符串”类型才行,计划明天早上前更前WinSail
   比如说:
      
[Display]
Font = "Font\DisplayX.Fon"  ; 使用宋体



请告诉我
hzk16C、Hzk16F、HZK16H、HZK16K、HZK16L、HZK16S
HZK16V、HZK16X、HZK16Y的字库中文名称是什么
作者: profree     时间: 2006-9-30 05:14
我的理解是这样的:
Hzk16F--仿宋
HZK16H--黑体
HZK16K--楷体
HZK16L--隶书
HZK16S--宋体
HZK16X--细圆
HZK16Y--幼圆

字体是在这里下载的,也有说明:
http://www.cn-dos.net/forum/viewthread.php?tid=18934
作者: firstsail     时间: 2006-9-30 05:54
WinSail 已上传。2006-09-29 17:40
Config.Sys文件的[Display]段的Font键是已升级为“字符串”类型,

比如说:
      
[Display]
Font = "DisplayS.Fon"  ; 使用宋体
作者: firstsail     时间: 2006-9-30 06:28
一直用用论坛最下面的“快速回复 ”,导致无法插入图片也无法插入附件,今天才发现“左上角”有一个“发表回复”.......

不过,好象还是不能直接插入图片?



作者: firstsail     时间: 2006-9-30 06:29
太好了,图片插入成功了!
作者: yxzattraction     时间: 2006-9-30 11:19    标题: 我想要,谁有发我一份,感激不尽!yxzattraction@163.com

我想要,谁有发我一份,感激不尽!yxzattraction@163.com
作者: firstsail     时间: 2006-9-30 21:50
http://www.FirstSail.Com.Cn中下载!
作者: profree     时间: 2006-9-30 22:57


  Quote:
Originally posted by yxzattraction at 2006-9-30 11:19 AM:
我想要,谁有发我一份,感激不尽!yxzattraction@163.com

到官方主页下载

感谢firstsail为我们提供如此好用的开发库
作者: slion1980     时间: 2006-9-30 23:19
真的那么好吗?下一个来看看。。。。。。。
作者: firstsail     时间: 2006-10-1 00:35
WinSail V2.0已上传 2006-09-30 12:20

关于按钮的鼠标左键弹起触发的问题,已经修正!

WinSail V2.0的下载地址为http://www.firstsail.com.cn/Download/WinSail%20V2.0.rar
WinSail V2.0的字库下载地址为http://www.firstsail.com.cn/Download2/font.rar
作者: profree     时间: 2006-10-1 03:25
这样的提示框如何?

还有一个建议:
   根据使用Windows的经验,当焦点移动某一控件上时,按空格和回车的作用是一样的


对了,在对话框上按F3不能保存图片吗?

[ Last edited by profree on 2006-10-1 at 03:39 ]
附件 1: message.jpg (2006-10-1 03:25, 9.7 K, 下载附件所需积分 1点 ,下载次数: 3)



作者: firstsail     时间: 2006-10-1 04:40
to Profree:

WinSail V2.0已经重新上传:2006-09-30 16:20


  对于“滚动条”的使用,请参看sail3000工程的
Wizard2.Cpp模块的

   void far Page4(void* pUser) 函数


作者: firstsail     时间: 2006-10-1 04:43
对话框上按F3能保存图片,但必须保证“Bmp\Bmp256.Pal”文件的存在!该文件是固定的256色调色板。可在Sail3000\bmp下找到。
作者: firstsail     时间: 2006-10-1 04:50
“根据使用Windows的经验,当焦点移动某一控件上时,按空格和回车的作用是一样的”

   Windows里面即然是这样的.....,第一次听说这样情况,验证先。

  果然是这样!
  多谢Profree的提示!

作者: profree     时间: 2006-10-1 04:54
建议:
“不可用控件”的颜色增加深色,不可用控件是由至少2种颜色构成的

[ Last edited by profree on 2006-10-1 at 05:35 ]
作者: profree     时间: 2006-10-11 22:12
firstsail:
  还没有收假吗?很久没有更新winsail了
作者: firstsail     时间: 2006-10-14 01:50
WinSail V2.0已经重新上传[2006-10-13 13:05]!
作者: profree     时间: 2006-10-23 21:54


  Quote:
Originally posted by profree at 2006-10-11 10:12 PM:
firstsail:
  还没有收假吗?很久没有更新winsail了


作者: firstsail     时间: 2006-10-25 08:23
WinSail V2.0已经重新上传! [2006-10-24 08:00]

1:增加了对“数字键盘”控件的支持
   
   文档:界面控件类_CNumberKeyboard数字键盘控件详细设计.doc

   类名:CNumberKeyboard
   
   方法:CreateObject();----建立控件
         SetScale();    ----设置控件的放大倍数,默认1倍

   演示模块   
     (1)演示位置:sail3000工程的桌面有一“数字键盘演示”图标
     (2)程 序 名:Num_Demo.Cpp         





作者: firstsail     时间: 2006-10-27 02:30    标题: 增加中文输入法了!

WinSail V2.0已经更新 [2006-10-26 12:00]

1:增加了“中文拼音输入法”。

  (1)切换键 --- Ctrl + Space(空格) 组合键

  (2)对窗口的要求 --- 窗口控件的左上角坐标(left, top)
            left >= 0  并且 top >= 0

  (3)输入法码表文件为“Sail.Ime”,在sail3000目录中可以找到
        收录了1万多个汉字(包括多音字)。文件大小约28K字节。



作者: profree     时间: 2006-10-27 21:37
可以增加五笔输入法吗?
作者: profree     时间: 2006-10-27 21:45
刚才载测试winsail越来越漂亮了,:)
另外请教一个问题:
我想自己写登录对话框,用户名以下拉列表的方式显示,可以自定义自己的用户名和密码文件吗?
作者: firstsail     时间: 2006-10-28 04:14


  Quote:
Originally posted by profree at 2006-10-27 21:45:
另外请教一个问题:
我想自己写登录对话框,用户名以下拉列表的方式显示,可以自定义自己的用户名和密码栮..

完全可以!

用户和密码文件并不是WinSail V2.0的一部份,它只是基于WinSail V2.0的一个普通应用而已!!!

有一点须注意:Sail3000工程并不是WinSail,它只是基于WinSail V2.0的一个应用程序!


WinSail V2.0内部定义了以下三个变量:

extern BOOL bAfxManager; //系统管理员标志,默认为FALSE
extern char strAfxUserName[16]; //用户名称,不能超过15个字符,默认为“空”
extern char strAfxPassword[12]; //密码,不能超过11个字符,默认为“空”


强列建议用户定制的用户框登录后,将:

  (1)将用户名拷贝到strAfxUserName变量中
  (2)将密码拷贝到strAfxPassword变量中
  (3)将用户权限置位到bAfxManager变量中
作者: firstsail     时间: 2006-10-29 04:05    标题: 支持“五笔”输入了

1:为了使用WinSail V2.0的中文输入法,在main主程序中,须注册ime管理器!

  int main(int argc, char** argv)
  {
        ::AfxRegisterIme(::GlobalImeManager); //可放在任何地方,须在使用输入法前!

        ....
       

        return(0);
  }

   这样设计的目的是由于大多数“嵌入式应用”是不需要“中文输入”,这样可以节省大约4K字节的Exe文件尺寸。


2:输入法激活键 “Ctrl + Space(空格)” 组合键。
   输入法切换键 “Ctrl +  右Shift” 组合键”。

   目前只支持“单字”的输入,不支持“词组”和“联想”输入。

3:输入法描述在“Config.sys”文件的[Ime]字段。语法为

    [Ime]

    Ime1 = 文件名1  ;注:可含目录
    Ime2 = 文件名2  ;注:可含目录   
    ...


   比较特殊的是“区位输入法”,它不用描述,系统自动加载

4:在Sail3000目录中,已经支持三个输入法
   (1)全拼 --  输入法代码文件为“Ime\winqp.ime”
   (2)五笔 --  输入法代码文件为“Ime\winwb98.ime”
   (3)区位 --  不需要输入法代码文件,系统自动加载

5:码表文件结构分为四个部份

   第一部份:文件头, IME_HEAD
   第二部份:哈希表, IME_HALFTABLE,指示首字符在编码表中的位置索引。
   第三部份:编码表, 从小到大排列,指示每一种编码在代码表中位置、重根的符号个数。
   第四部份:代码表, 编码小的在前;相同的编码按顺序排列。

6:将“http://www.firstsail.com.cn/download/WinSail%20V2.0.rar”拷贝到地址栏,可下载WinSail V2.0。
   演示程序为Sail300目录,执行“a.bat”文件或“Sail2000.exe”文件。

[ Last edited by firstsail on 2006-10-29 at 11:52 PM ]
作者: pcwawa     时间: 2006-11-1 09:34
郭老师有开源的计划么?
作者: pcwawa     时间: 2006-11-1 09:51
如果不开源,以后成熟的版本会不会收费?
如果收费的话会提供什么样的技术支持呢?

一年多前第一次看到winsail的时候就有这个疑问,所以后来选择了"DJGPP+ALLEGRO+DZCOMM"。

对baby-pc的那款板子不知道有多少使用winsail的案例?偶也在考虑用他们的。
作者: firstsail     时间: 2006-11-7 08:21
WinSail V2.0已经更新 [2006-11-06 10:00]


加强了基于网卡的Socket套接字编程,特别是TCP/IP中的UDP协议!
作者: yoolu     时间: 2006-11-7 23:00
kankan
作者: firstsail     时间: 2006-11-11 05:05    标题: 我要感激DOS联盟!

我要感激DOS联盟!

今天在"http://zhenlove.com.cn/cndos/newdos/dosuse.htm"看到了如何配置c:\config.sys文件,采用以下配置,DOS的可用内存,可达700K!

device=c:\windows\himem.sys/testmem:off
device=c:\windows\emm386.exe noems novcpi
device=c:\windows\ifshlp.sys

dos=high,umb,auto
stacks=12,256
files=30


numlock=off
作者: Dill     时间: 2007-2-27 09:35
厉害哦,支持
作者: gne3     时间: 2007-2-27 10:49
ding
作者: hwzh     时间: 2007-3-5 23:56
好东西
作者: suailin     时间: 2007-3-6 00:29
老大,找不到啊
作者: firstsail     时间: 2007-3-14 01:45
在“http://www.firstsail.com.cn”中下载
作者: firstsail     时间: 2007-4-11 23:11    标题: 如何改动WinSail的默认字库?

字库可以在http://www.firstSail.com.cn/Download2/Font.rar中下载!

(1)WINDOWS下面生成的不同字体风格的HZK16

  宋  --DisplayS.Fon
  仿  --DisplayF.Fon
  黑  --DisplayH.Fon
  楷  --DisplayK.Fon(仿与楷字型相近而风格仍有差别)
  幼圆 --DisplayY.Fon
  隶  --DisplayL.Fon(效果较差)

(2)DOS下汉字系统的字库:
  粗  --DisplayC.Fon
  细  --DisplayX.Fon(类XZL字体)
  繁  --DisplayV.Fon


*********************************************
字库文件由WinSail的Config.Sys文件中的
“Display”段的“Font”键指定。如下所示

[Display]
Font = "Display.Fon";可指定目录
作者: m168     时间: 2007-4-18 11:29
老大,找不到,出现:

Sorry, this domain name is not in use.
   
   
   域名未被使用有以下几种情况:
您所访问的域名未注册。
您所访问的域名未设置地址解析。
作者: firstsail     时间: 2007-4-19 01:36
网页重在升级,2007--3-25后开通!
作者: xyq2001     时间: 2007-4-20 08:41
期待中......
作者: lsy9202     时间: 2007-4-21 02:05
高深
作者: firstsail     时间: 2007-4-30 08:25
网站“http://www.firstsail.com.cn”已经续费重新开通了....
作者: happybasic     时间: 2007-4-30 22:45
今年没更新了?
作者: henrya2     时间: 2007-4-30 23:30
听起来不错
作者: tzrzjj     时间: 2007-5-7 10:26    标题: 有软件项目要做,感兴趣联系我.13304514420

有软件项目要做,感兴趣联系我.13304514420
作者: yws     时间: 2007-5-9 12:24
PFPF,DOwn一个试试
作者: whowin     时间: 2007-5-30 17:45
真是难为你了,以我好多好多年玩DOS的经验看,似乎没有什么太大的意义。鼓励一下吧。
作者: firstsail     时间: 2007-6-3 19:22
(1)如果该“嵌入式系统”是X86架构的PC104电脑,CPU是8086、80186、80286、80386、80486,并且用上了LCD或VGA
(2)如果您现在是一名电子开发工程师或者嵌入式项目开发工程师
(3)如果您现在是一家企业的BOSS

----如果您选择采用“WinCE”或者是"Unix",那么在中国国内,以现在(2007年,深圳)的市场行情,您至少给出¥8000人民币来聘请软件工程师。

----如果CPU是8086、80186的情况下,您只能选择DOS,并且是唯一的选择。

----如里CPU是80386以上,如果不选择DOS的情况下,您只有选择Unix或WinCE了,请问一下,在中国,精通DOS开发的人多,还是精通UNIX或WinCE的人多呢?

    在嵌入式应用中,选择"DOS"系统,是最"节省成本"的方案,包括开发时间控制、成本控制等等.

    目前,嵌入式PC104一般选用16M(以上)的电子盘,或者16M(以上)的CF卡。在我的嵌入式应用上,我就将开发工具BC31都安装上了,以便于现场修改程序。

    没有什么东西是万能的,正由于嵌入式系统硬件的千变万化,所以DOS下的GUI才有发展的需要。老是拿DOS与WINDOWS、UNIX并列讨论,没有实际的意义。

    简而言之---- 萝卜白菜,各有所爱;DOS、UNIX、WinCE,各有千秋。并且在嵌入式应用中,往往是以企业本身的技术积累为基础,从而明智的作出选用何种操作系统。

    我见过不少“精通UNIX,没有不精通DOS编程的人”。
    我见过不少“精通DOS,而对UNIX的认识只局限于书面知识的人”。
    我见过不少“精通DOS,而对WinCE闻所未闻的人”。

[ Last edited by firstsail on 2007-6-3 at 07:40 PM ]
作者: lixun305     时间: 2007-6-8 12:51
厉害!厉害!
作者: yueluck     时间: 2007-6-14 17:15
微型嵌入式GUI http://www.ecurb2006.com/
也是个gui工具.也是自己开法的.
不知道你们有没有共同点.你的API详细吗?
谢谢.
作者: firstsail     时间: 2007-6-14 19:15
目前市场上大部分DOS下的GUI是C语言接口,并且是模仿Microsoft C for Windows;而WinSail的GUI是C++接口,主要模仿Visual C++6.0。

      下载地址是“http://www.firstsail.com.cn”。

[ Last edited by firstsail on 2007-6-14 at 10:38 PM ]
作者: firstsail     时间: 2007-6-27 18:25    标题: 关于TCP/IP协议

(1)目前WinSail V2.0的TCP协议还没有“超时”处理,只能用于“短时”连接!
(1)目前WinSail V2.0的UDP协议是非常完善的,应用例子在Sail3000目录中的“Remote_N.Cpp”文件。
作者: windowsvesta     时间: 2007-7-4 11:02
下载试一试!
作者: mnbvcxz1     时间: 2007-7-9 09:58
牛人啊 先下 再顶!!!!
作者: 59fei     时间: 2007-7-9 11:52
怎么没有找到下载地址啊
作者: firstsail     时间: 2007-7-9 12:54
"http://www.firstsail.com.cn/Download/WinSail%20V2.0.rar"拷贝到地址栏下载!
作者: haiou327     时间: 2007-7-12 00:47
技术文档很详细
作者: Jneny     时间: 2007-7-12 01:35
虽然我是菜鸟,但是也知道这玩意是高科技。 顶吧,还有啥好说的呢!!!
作者: firstsail     时间: 2007-7-26 14:59
WinSail 开发的目的是用于工业控制场合,它已经经过市场近十年的实际应用,安全、稳定、可靠,值得大家信赖!

界面一:


界面二:


界面三:


界面四:



界面五:


[ Last edited by firstsail on 2007-7-26 at 08:09 PM ]
作者: sichy     时间: 2007-7-26 15:56
windows向DOS转化怎么入门呢?
作者: firstsail     时间: 2007-7-26 20:02


  Quote:
Originally posted by sichy at 2007-7-26 15:56:
windows向DOS转化怎么入门呢?

"楼上"能否解释清楚一下?
作者: firstsail     时间: 2007-7-30 14:34



其实它是用MakeDlg.Exe程序将Visual C++的对话框转化成WinSail的对话框后,稍微增加一些代码而成,源代码如下

#include  <Symbol.h>
#include  <MyFrame.h>

extern BOOL     bAfxManager;
extern char far AfxString[][GROBAL_CHARACTER_MAX];
extern char     strAfxUserName[];
extern char     strAfxPrintPathName[MAXPATH];


void AboutDlg()
{
        char buf[250];

        CDialog* pDialog = new CDialog;
        pDialog->CreateWindow(0,0,455,287,"关于系统");
        pDialog->Center();

        new CCloseButton(pDialog);

        CLabel* pLabel1 = new CLabel(pDialog);
        pLabel1->CreateObject(0,19,123,285,NULL);
        pLabel1->SetBitmapFlags(TRUE);
        pLabel1->SetBackColorDisplay(TRUE);
        pLabel1->SetBitmapFile("Bmp\\DESKTOP.BMP");

        CLabel* pLabel2 = new CLabel(pDialog);
        pLabel2->CreateObject(127,40,273,64,
                        "    作者:先航公司\n"
                        "    联系电话:13560730316,0755-27570111\n"
                        "    本计算机程序受版权法和国际条约保护\n"
                        "如果未经授权而擅自复制或传播本程序(或\n"
                        "其中任何部分),将受到严厉的民事及刑事\n"
                        "制裁,并将在法律许可的范围内受到最大可\n"
                        "能的起诉!");

        CListBox* pListBox1 = new CListBox(pDialog);
        pListBox1->CreateList(127,160,320,120,NULL);

        pListBox1->SetLineCharacter(100);
        pListBox1->SetCount(6);
        //System
        sprintf(buf,"系统名称   %s",AfxString[0]);
        pListBox1->SetSel(0,buf);

        //User
        sprintf(buf,"用户名称   %s , %s",
                strAfxUserName,
                ((bAfxManager)?"系统管理员":"普通用户"));
        pListBox1->SetSel(1,buf);

        //Print
        sprintf(buf,"打印口地址 %s",strAfxPrintPathName);
        pListBox1->SetSel(2,buf);


        pDialog->ShowWindow();
        pDialog->DoModal();
        delete pDialog;

}
作者: firstsail     时间: 2007-7-31 20:59    标题: 获得TCP/IP支持

1:增加工作目录中的“Config.Sys”文件中的“NetCard”段

[NetCard]
NetCard = TRUE ;“真”表示需要网卡支持,“假”表示不需要网卡支持

HostName = OemComputer        ;本机的主机名
My_IP = 169.254.210.218       ;本机的主机IP地址

PeerName = NT_Server          ;服务器/上位机的主机名
You_IP = 169.254.210.218      ;服务器/上位机的主机IP地址

NetMask = 255.255.0.0         ;子网掩码
GateWay = 169.254.1.1         ;网关

3:在Main主函数中,向系统注册“TCP/IP”协议栈,须在调用“int InitSystem(int argc, char** argv)”函数之前注册。
#include <Symbol.h>
#include <MyFrame.h>

int main (int argc, char** argv)
{
    // 向WinSail V2.0注册TCP/IP协议
    // Register Tcpip Protoent stack!
            //        GlobalInitSocket -- Initlize Function For TCPIP!
            //        GlobalCloseSocket -- Close Function For TCPIP!
            //        EthernetEntry -- Message Loop For TCPIP!
    ::AfxRegisterNetcardEntry(::GlobalInitSocket,
                    ::GlobalCloseSocket, ::EthernetEntry);//注册WinSail-TCPIP栈

  //Initlize Sysem Kernel
  if (!::InitSystem(argc, argv))//初始化系统内核
  {
        ::CloseSystem();//关闭系统内核
      ::printf("\nInit System Error!");
         return(0);
    }


    //这里增加您的代码
    //……

    ::CloseSystem();//关闭WinSail 内核
    return (0);
}


4:TCP/IP协议包是基于“Packet Driver”驱动,固定使用“60H”中断。对于网卡来说:“Packet Driver”驱动程序在附带的网卡光盘上可以找到。在演示程序Sail3000目录中,有一个目录Internet,里面就有许多厂家的Packet驱动。其中“RTSPKT.Com”就是“8139”网卡的驱动。


5:目前TCP/IP的UDP协议是非常成熟的,而TCP协议表现还不是非常满意,因为该TCP协议目前还没有支持“超时处理”,没有支持“滑动窗口”。如果需要长时间使用TCP协议,推荐使用第三方的TCP/IP协议栈(例如:Wattcp)。


WinSail内部的TCP/IP协议目前不支持IP包的分片,不支持TCP包的重装配,TCP只是“数据包”不是“数据流”,使用时须注意它的局限性。

    WinSail V2.0主要用于“工业控制”场合,UDP协议基本能够满足实际现场需要,所以“协议栈”它的局限性有待将来升级,或者向WinSail注册第三方的TCP/IP协议栈(如:Wattcp)。由于WinSail的TCP/IP协议栈的代码已经达到70K之多,有些庸肿,将来有可能去除TCP协议,只保留UDP协议!

[ Last edited by firstsail on 2007-7-31 at 09:05 PM ]
作者: fcgboy     时间: 2007-8-21 09:40
为什么sail2000不能运行在dos下
program too big to fit in memory
作者: firstsail     时间: 2007-8-27 10:17
1:为了获得纯DOS,一般可以安装DOS6.22或DOS7.0.由于Win2000、WinXP、WinVesta不完全支持DOS,建议安装第二个操作系统----Win98系统来获得DOS7.0。

2:由于许许多多在WinXP下增加安装的纯DOS,基本上启动后,自动安装了中文系统,浪费了大量的常规内存,建议安装第二个操作系统----Win98系统来获得DOS7.0。

3:如果在Windows2000、WinXP下运行,请将Sail30000目录下的Config.Sys文件的“Boot”段的“XmsStyle”键盘配置为“1”,用磁盘仿真扩展内存。如果在纯DOS、Win9X下运行,可以将Sail30000目录下的Config.Sys文件的“Boot”段的“XmsStyle”键盘配置为“0”,直接使用扩展内存。

4:查看内存,请在DOS命令行下敲入“mem/c”命令查看。


  
C:\Config.Sys请如下配置(如果是DOS6.22,请将Windows改为DOS)

     Device=C:\Windows\Himem.Sys/TestMem:Off

     Device=C:\Windows\Emm386.Exe noems novcip

     DOS=High,Umb

     Stacks=9,256

     Files=30



    C:\Autoexec.Bat请如下配置(如果是DOS6.22,请将Windows改为DOS)

       path C:\Windows;C:\Windows\Command;C:\Bc31\Bin

       Lh   SmartDrv.Exe

[ Last edited by firstsail on 2007-8-27 at 10:21 AM ]
作者: langhuan1     时间: 2007-8-27 15:48
完整的
“库文件”、“头文件”“说明书”和“源代码”可在"www.FirstSail.B2B.Cn中下载得到

地址无效啊
作者: firstsail     时间: 2007-8-27 19:30
下载地址早就改为“http://www.firstsail.com.cn/software.html”了!
作者: fcgboy     时间: 2007-8-27 21:36    标题: firstsail在不在???

在的话留下联系方式呀
QQ或email什么的 好多东西需要请教
作者: firstsail     时间: 2007-9-9 17:56
(1)在某些386的PC104中,可能outtextxy函数无法显示8*8的字库,现WinSail修改了OutTextXY函数,让它能显示8*8字库。
(2)为配合(1)条,字库随着也增加了8*8的字模。

请到下面的地址下载:
http://www.firstsail.com.cn/software.html
作者: THREEKS     时间: 2007-9-9 19:09
已经不提供源码下载了吗?
作者: qunce     时间: 2007-9-9 22:48
很不错的东西,楼主是高手.DOS下运行的图形界面,连这种东西都自己开发!
不过你的网站设计的太差了,严重建议请我将你们的标志改一改.
作者: firstsail     时间: 2007-9-20 12:21
to qunce:
    多谢您的建议!
作者: zqlcch     时间: 2007-9-20 16:01
很早就用过了,确实是非常不错的GUI库,功能和方便性上比BBS中的另一个GUI库ECURB 2006强,

但发现一个BUG:按DELETE键是删除一整行的内容,而不是删除一个字符。

另外不算BUG吧:界面比较不好看,比QBWIN和ecurb差,所以一些小GUI程序还是选择了QBWIN。。。。。。不过这是仁者见仁,智者见智的事情了,每个人眼光不同。
作者: firstsail     时间: 2007-9-20 17:32
to Zqlcch

   (1)WinSail设计之初,按“Del”就是删除编辑框的所有字符,编辑框的数据全部重新输入有利于减少工业现场的误操作!
并且Windows操作系统的“Backspace”按键和“Del”按键在编辑框中的分工不是很明显,有浪费按键的嫌疑。

   (2)关于WinSail的GUI,图形主要是模访Win98,字库采用16X16的中文字库、8X8英文字库。在2006年9月份之前GUI界面
确实比较差强人意。但在那之后,WinSail做了比较大的界面控件的更新,用Windows附件中的“放大镜”程序将Windows控件
放大后,一点一线的模仿过来的,现在WinSail支持了中文输入法,这应该感谢“profree”会员发来的“芝加哥9”程序。


   (3)dos下的GUI主要是用“点阵”字库,Windows是用“矢量”或“TrueType”字库,所以界面要超越Windows可以说很难做到,
更大胆一点说,超越的可能性几乎不可能! 我们能做的就是尽量接近“微软”,超越“微软”不是我们这一代人的责任!


   (4)WinSail下载地址已经改为“http://www.firstsail.com.cn/software.html”了




在这里,应该好好感谢“Zqlcch”,因为您提出了不少实用性的建议。
作者: zh1234     时间: 2007-9-23 23:00
如何下载?
作者: firstsail     时间: 2007-9-24 18:38
to Zh1234
   
    登录"http://www.firstsail.com.cn/software.html"网页可下载WinSail V2.0
作者: huangxiaohao     时间: 2007-10-6 22:55
看着到是还不错啦
作者: windowsvesta     时间: 2007-10-17 16:26    标题: 发现一个严重的BUG!

发现一个严重的BUG!

      多行编辑框CMultiEdit类输入的内容在没有“回车换行”前,GetWindowText()函数返回的字符串恒为“空”,“回车换行”后,GetWindowText()函数才能返回正确的字符串!

[ Last edited by windowsvesta on 2007-10-17 at 04:27 PM ]
作者: firstsail     时间: 2007-11-15 13:51
已更新!
作者: cxjnet     时间: 2007-11-30 00:43
谢谢提供了

用这东西开发DOS程序就简单多了
作者: wuxianglin2000     时间: 2007-12-29 15:33
我怎么打不开你的网站啊,能否发一份给我,谢谢!
wuxianglin2000@sina.com
作者: wuxianglin2000     时间: 2007-12-29 15:37
幸好到前面翻了一下帖子,已经下载了,谢谢!
作者: kit100     时间: 2008-1-3 23:35
think!!!!!
作者: kit100     时间: 2008-1-3 23:44
我怎么打不开你的网站啊,能否发一份给我,谢谢!
honkit.wong@gmail.com
作者: firstsail     时间: 2008-1-5 17:37
在“http://www.firstsail.com.cn/software.html”下载
作者: firstsail     时间: 2008-2-19 19:31    标题: 如何加载第三方的TCP/IP和多任务模块

(1)对于第三方TCP/IP来说,注册三个函数,分别为“初始化服务函数”和“终止服务函数”以及“网络消息循环函数”
其中:
  注册“初始化服务函数”是为了InitSystem()中调用。
  注册“终止服务函数”是为了CloseSystem()中调用。
  注册“网络消息循环函数”是为了CWindow::OnIdle()函数中调用。


   (2)对于第三方多任务模块来说,注册三个函数,分别为“初始化服务函数”和“终止服务函数”以及“休息函数”
其中:
  注册“初始化服务函数”是为了InitSystem()中调用。
  注册“终止服务函数”是为了CloseSystem()中调用。
  注册“休息函数”是为了系统内部在调用KernelDelay()函数时,转换到实际的delay或sleep休息函数。




int main(int argc, char** argv)
{

//注册WinSail-TCPIP栈
// GlobalInitSocket -- TCP/IP初始化服务函数
// GlobalCloseSocket -- TCP/IP终止服务函数
// EthernetEntry -- TCP/IP网络消息循环函数
::AfxRegisterNetcardEntry(::GlobalInitSocket,
  ::GlobalCloseSocket, ::EthernetEntry);

////注册WinSail-多任务栈
// KernelInitProcess -- 多任务初始化服务函数
// KernelCloseProcess -- 多任务终止服务函数
// __MultiTaskDelay -- 多任务的休息函数
::AfxRegisterMultitaskEntry(::KernelInitProcess,
  ::KernelCloseProcess, ::__MultiTaskDelay);

//初始化系统内核
if (!::InitSystem(argc, argv))
{
  //关闭系统内核
  ::CloseSystem();
  printf("\nInit System Error!");
  return(0);
}


//用户程序
        //.......


//关闭系统内核
::CloseSystem();

return(1);

}
作者: godai     时间: 2008-2-20 18:59    标题: firstsail大大请进:关于winsail的问题

请问firstsail大大, 新下载了winwail的程序,发现了两个问题:

1。在有CMenu菜单的窗口里再加任一控件(例如加个工具条 CToolsBar)后, CMenu就不能用鼠标开启, 只能用键盘Alt+F开启后才能再用鼠标操作; 以前试用过大大的winsail早期版本反而没有问题?

2。 打开和存储文件夹好像不能支持软驱A盘?
作者: firstsail     时间: 2008-2-22 16:28


  Quote:
在有CMenu菜单的窗口里再加任一控件(例如加个工具条 CToolsBar)后, CMenu就不能用鼠标开启, 只能用键盘Alt+F开启后才能再用鼠标操作; 以前试用过大大的winsail早期版本反而没有问题?

答:已经发现确实有这一问题,因网站服务器正在刷新,需在下午5:30以后方能上传更改后的WinSail,届时请重新下载后,编译时用Bc31重新“Build All”.

  Quote:
打开和存储文件夹好像不能支持软驱A盘?

答:由于软盘很少使用,在新版本上将它取消了。我一般用“CF卡”+“CF转IDE转换器”代替软盘。
作者: kmlxk     时间: 2008-2-24 01:51
强~眼泪直流啊。。
作者: godai     时间: 2008-2-26 11:56    标题: 郭大大: 有否更新?

郭大大, 是在您的主页 http://www.firstsail.com.cn/Software.html 上更新了吗? 我刚刚下了好像还没有变, 还是[2008-01-15 20:48] 版本,  里面的sail.lib也还是07年12月25日的?

另: 打开和存储对话框函数的一个小问题: 比如我的D盘是USB-disk, 启动程序的时候有检测到U盘, 但打开对话框的时候如果没有插U盘就会造成系统死机。  

还有据我了解,在不少传统工业,由于更新缓慢,不少老的工业环境仍然在使用软盘。 如果从提高兼容性考虑,建议大大还是加入软盘读写功能,应该不用多加程序,因为读写与硬盘相同,都是DOS标准函数。

如果要解决上面两个问题, 建议在打开此对话框前先用absread或_bios_disk函数检测是否有此盘存在, 就可解决软盘或U盘没插入的问题。
作者: firstsail     时间: 2008-2-26 15:23


  Quote:
在您的主页 http://www.firstsail.com.cn/Software.html 上更新了吗? 我刚刚下了好像还没有变, 还是[2008-01-15 20:48] 版本,  里面的sail.lib也还是07年12月25日的?

因为网络刚刚修复,直至今日才更新WinSail [2008-02-26 14:05],已修正菜单的鼠标问题!

  Quote:
如果要解决上面两个问题, 建议在打开此对话框前先用absread或_bios_disk函数检测是否有此盘存在, 就可解决软盘或U盘没插入的问题。

过几天按您所提示加入absread或_bios_disk函数检测磁盘的存在,请关注更新!

[ Last edited by firstsail on 2008-2-26 at 03:27 PM ]
作者: fgckfl     时间: 2008-2-26 21:14    标题: 试用得几点意见

1。多exe程序合成时,主程序调用子程序时,屏幕上会显示“sail200 触”,如何屏蔽呢?
2。settimefc()函数可否设定定时时间,dos下“嘟”得时间太短。有时不希望定时器工作太快。
3。多行编辑框怎么设定最大字节数,或行最大字节数,或最大列数,这样在输入时不需回车就可自动换行。
4。能给个列表控件编辑和数据库相结合得例子吗?
作者: firstsail     时间: 2008-2-27 10:51


  Quote:
多exe程序合成时,主程序调用子程序时,屏幕上会显示“sail200 触”,如何屏蔽呢?

......

  Quote:
settimefc()函数可否设定定时时间,dos下“嘟”得时间太短。有时不希望定时器工作太快。

默认情况下是55mS,现将它设置为110mS
void far OnTime_MyDialog(CObject* pObj)
{

    CDialog* pDialog = (CDialog *)pObj;

    //引入静态变量作为计时次数
    static int nLoops = 0;
    if ((++nLoops) < 2)
    {
        return;
    }
    nLoops = 0;
   
    //这里加入您的代码

}

  Quote:
3。多行编辑框怎么设定最大字节数,或行最大字节数,或最大列数,这样在输入时不需回车就可自动换行。

//.....

  Quote:
4。能给个列表控件编辑和数据库相结合得例子吗?  

BOOL LoadDatabase(CListBox* pListbox)
{
        char buf[256];

        char* pStrFile = "MyBase.Dbf";
        //假设有一个数据库名称为“MyBase.Dbf”,其有三个字段
        //其中索引为 2的字段是字符串字段

        //打开数据库
        CFoxpro mFoxpro;
        if (!mFoxpro.Open (pStrFile))
        {
                ::sprintf (buf, "文件开打错误\n---%s", pStrFile);
                ::AfxMessageBox("错误", buf, MB_OK);
                return (FALSE);
        }

        //读索引为2的字段的属性
        FOXPRO_FIELDS mFoxproFields = *(mFoxpro.GetFoxproFields(2));

        //判断索引为2的字段是否为字符串字段
        if (mFoxproFields.byStyle != 'C' && mFoxproFields.byStyle != 'c')
        {
                ::sprintf (buf, "数据库非法\n---%s", pStrFile);
                ::AfxMessageBox("错误", buf, MB_OK);
                return (FALSE);
        }

        int nMaxCh = (int)(WORD)mFoxproFields.byLength;

        //得到数据库的总纪录数
        long lgCount = mFoxpro.GetRecordCount();

        //设置列表框每一行的最大字符数
        pListBox->SetLineCharacter((nMaxCh == 255) ? 255 : nMaxzCh + 1);
       
        //设置列表框的总项数为lgCount个
        pListBox->SetCount (lgCount);

        //循环读数据库的索引为2的字符串字段内容
        for (long i = 0L; i < lgCount; i++)
        {
                //定位数据库
                mFoxpro.Seek(i, SEEK_SET);

                //读索引为2的字符串字段的值
                mFoxpro.GetFieldString (2, buf);

                //将读出来的值写入列表框
                pListBox->SetSel(i, buf);
        }


        //关闭数据库
        mFoxpro.Close();

        return (TRUE);
}

[ Last edited by firstsail on 2008-2-27 at 11:27 AM ]
作者: liudongfu     时间: 2008-2-27 12:55
在那儿下呀,
作者: firstsail     时间: 2008-2-27 14:42
更新了文件打开/存贮框,要有bmp\key05.ico文件支持,该文件可在sail3000\bmp下找到。



下载地址“http://www.firstsail.com.cn/software.html

[ Last edited by firstsail on 2008-2-27 at 02:46 PM ]
作者: fgckfl     时间: 2008-3-1 11:58    标题: 用winsail开发的dos,win9x串口调试助手

作的一个小程序,用winsail开发dos程序方便多了,很奇怪
该程序竟然在xp的c:盘下也可以通信,我用的是直接端口
操作,xp不是工作在保护模式下吗?firstsail能解释一下吗?
作者: fgckfl     时间: 2008-3-1 12:13    标题: 开发中遇到的几个问题-1,请郭兄及高手指点!

1. “setsys.cpp” 文件中void far DisplayAttribSetting()函数中调用子程序::AddKeyboardString("SetSys 觞\xd");会在屏幕上显示“SetSys 觞”,如何屏蔽?
作者: fgckfl     时间: 2008-3-1 12:14    标题: 开发中遇到的几个问题-2,请郭兄及高手指点!

2.“demoser.cpp”文件中void  far OnTime_DemoCUartDialog(CObject* pCurObj)函数,原准备作为定时器回调函数,可是似乎是程序太大,屏幕总是黑屏,后来用void  OnTime_DemoCUartDialog1(CObject* pCurObj)为定时器回调函数,再调用void  far OnTime_DemoCUartDialog(CObject* pCurObj)解决了上述问题,是否dos小中断函数大小有限制呢? 因为现在买不到dos编程得书,很多dos底层得东西不明白.
作者: fgckfl     时间: 2008-3-1 12:14    标题: 开发中遇到的几个问题-3,请郭兄及高手指点!

3.        “demoser.cpp”文件中 ,在void  far OnTime_DemoCUartDialog(CObject* pCurObj)函数中,发现CMultiEdit编辑框有个很有意思现象.

Buf[]为串口接收的字符串, show_buf[]为格式化后显示的字符串, pEdit1为CMultiEdit*指针;
采用下面操作1:
      strcat(show_buf,buf);  
pEdit1->SetWindowText(show_buf);
pEdit1->Show();
将会在显示内容上自动换行

而采用如下操作2:
strcat(show_buf,"\n");
strcat(show_buf,buf);  
pEdit1->SetWindowText(show_buf);
pEdit1->Show();
将会在显示内容上换2行

如:新接收buf[]=”abc1”, 原来显示内容show_buf[]=”123”;
采用操作1:显示为:
abc1
123
采用操作2:显示为
abc1

123

而采用操作3:
pEdit1->SetLineText(当前行数,buf);       
pEdit1->Show();没反应
作者: fgckfl     时间: 2008-3-1 12:15    标题: 上传程序为什么那么慢呢?

上传程序太慢!!
作者: firstsail     时间: 2008-3-1 17:40


  Quote:
Originally posted by fgckfl at 2008-3-1 12:13:
1. “setsys.cpp” 文件中void far DisplayAttribSetting()函数中调用子程序::AddKeyboardString("SetSys 觞\xd");会在屏幕上显示“SetSys 觞”,如何屏蔽?

(1)如果在纯DOS或Win9x下运行,由于CPU运行速度快,人的眼睛是感觉不到的。
(2)如果在Win2000/WinXP下运行,由于命令行的解释器兼容问题,建议字符串加上"换行"标志。即::AddKeyboardString("SetSys 觞\xd\xa");

  Quote:
2.“demoser.cpp”文件中void  far OnTime_DemoCUartDialog(CObject* pCurObj)函数,原准备作为定时器回调函数,可是似乎是程序太大,屏幕总是黑屏,后来用void  OnTime_DemoCUartDialog1(CObject* pCurObj)为定时器回调函数,再调用void  far OnTime_DemoCUartDialog(CObject* pCurObj)解决了上述问题,是否dos小中断函数大小有限制呢? 因为现在买不到dos编程得书,很多dos底层得东西不明白.

这可能是您的代码有错,可能的话贴上代码看一下,注意这时候的函数参数CObject* pCurObj是窗口指针
如果窗口是CWindows,则一般CWindow* pWindow = (CWindow *)pCurObj;
如果窗口是CDialog,则一般CDialog* pDialog = (CDialog *)pCurObj;

[ Last edited by firstsail on 2008-3-1 at 05:44 PM ]
作者: firstsail     时间: 2008-3-1 17:50    标题: 贴上CMulitEdit::SetWindowText(const char* pStr)源代码

void CMultiEdit::SetWindowText(const char* pStr)
{

   
    char buf[EDIT_BUFFER_SIZE + 2];
    int nLength = _fstrlen(pStr);
   
   
    this->m_XmsMemoryData.InitListing(256);
   
    int nPoint = 0;
    for (int i = 0; i <= nLength; i++)
    {
        char ch = pStr;
        if (ch == '\xd')
        {
            continue;
        }
        if (ch != '\xa' && ch != '\x0')
        {
            buf[nPoint++] = ch;
            buf[nPoint] = '\x0';
            if (nPoint < EDIT_BUFFER_SIZE - 1)
            {
                continue;
            }
        }
        
        nPoint = this->ModifyEditBuffer(buf, EDIT_BUFFER_SIZE);
        
        DWORD dwLoc = this->m_XmsMemoryData.New(nPoint + 1, FALSE);
        if (dwLoc == NULL)
        {
            continue;
        }
        this->m_XmsMemoryData.SetText(dwLoc, buf, nPoint + 1);
        
        
        nPoint = 0;
        *buf = '\0';
    }
}

[ Last edited by firstsail on 2008-3-1 at 05:58 PM ]
作者: pingziru     时间: 2008-3-5 14:32    标题: Sail3000工程实例为何无法Debug单步跟踪?

Sail3000里面的例子在BC3.1下已编译通过,而且也能运行,可是想设断点或者单步跟踪一下,却无法跟进去,这是为何?
作者: godai     时间: 2008-3-5 15:59    标题: 菜单和“打开”对话框

郭兄, 新程序已下载试过了,Cmenu菜单已经可以了,感谢!:-)

除了Alt+F外,有没有方法可以用热键直接打开相应的菜单项? 如F1打开第一项一级菜单“文件”, F2打开第2项一级菜单“编辑”, F3打开第3项一级菜单“窗口”等类似这样的操作? 工业环境中有时用不到标准101/102键盘,太大; 这时就会考虑作模拟操作键盘,只模拟部分有用键。像“Alt+F” 这样的复合键就比较难以实现。

关于“打开”对话框,如果有接软驱,则读还是有问题: 插了A盘, 也还会出DOS提示符, 提示B盘没有准备好; 如果A盘里没插软盘,会直接产生DOS中断错误,从而退出程序。

另: 注意到了打开对话框加了“上一级目录”的按钮。另外的几个按钮可以控制吗?
如果选到相应的文件,可不可有消息通知当前选中高亮项的文件全路径名以便做操作,如预览类的处理?
作者: firstsail     时间: 2008-3-5 20:02
(1)菜单增加了 F1激活菜单的第一项,F2激活菜单的第二项,...,F10激活菜单的第十项
(2)关于接软驱的问题,由于我周围找不到一台计算机装有软驱,所以代码无法测试,不过增加了absread()判断,但在windows下运行时总是错,错误代码为“权限拒绝”。

(3)如果用"_bios_disk()"或"biosdisk()"函数在纯DOS下是可行的,但在WinXP下运行时总是提示"企图直接仿问硬盘端口"

(4)希望“godai兄”给以指点

[ Last edited by firstsail on 2008-3-6 at 09:10 AM ]
作者: godai     时间: 2008-3-6 15:29
郭兄,您好!

程序已试, 菜单功能非常好用了, 谢谢! :-)

关于判断软盘或U盘程序,把我以前用过的一段程序copy上来,希望能对郭兄有点帮助:

用absread函数判断U盘(“D:”)是否存在; (隐掉的部分是用_bios_disk判断的程序):

BOOL IfUsbExist()
{//判断软盘是否存在
  char buffer[512];
  char ch[MAXPATH], ch1[50];
  int Ifdrive = -1;
  UINT nRetry;
  char USBPATH[10];
  strcpy(USBPATH, "D:"); //D盘为U盘
  char cDrive=toupper(USBPATH[0])-'A';
  //struct diskinfo_t di;
  //di.drive = toupper(USBPATH[0])-'C'+0x80; //D驱USB
  //di.head = 0;
  //di.track = 0;
  //di.sector = 1;
  //di.nsectors = 1;
  //di.buffer = buffer;
  
  memset( buffer, 0, 512 );
  Ifdrive = absread(cDrive,1,2,buffer);//Re_bios_disk( _DISK_READ, &di );
  
  //no USB disk
  if( Ifdrive!=0 )  return FALSE;
  
  return TRUE;
}

BOOL IfFloppyExist()
{//判断软盘是否存在
  char buffer[512];
  struct diskinfo_t di;
  int Ifdrive = -1;
  char ch[MAXPATH], ch1[50];
  UINT nRetry;
  char FLOPPYPATH[10];
  strcpy(FLOPPYPATH, "A:"); //软盘为A盘
  
  memset( buffer, 0, 512 );
  strcpy(ch,FLOPPYPATH);
  di.drive = toupper(ch[0])-'A';
  di.head = 1;
  di.track = 1;
  di.sector = 1;
  di.nsectors = 1;
  di.buffer = buffer;
  
  Ifdrive = Re_bios_disk( _DISK_READ, &di );
  
  //no floppy disk
  if( Ifdrive != 0 )  return FALSE;
  
  return TRUE;
}


UINT Re_bios_disk( unsigned cmd, struct diskinfo_t _FAR *dinfo )
{//retry _bios_disk for 3 times for anti noise
  UINT ret;
  for(char i=0;i<3;i++)
  {
  ret = _bios_disk( cmd, dinfo ) & 0xff00;
  if(ret==0)
   break;
  }
  
  return ret;
}
作者: firstsail     时间: 2008-3-6 18:25
_bios_disk( cmd, dinfo )函数在以下操作系统中,

(1)纯DOS下正常运行
(2)Win9x下正常运行
(3)Win2000/WinXP下运行时总会弹出“不能直接仿问硬盘端口”的错误


初步分析是biosdisk或_bios_disk内部直接仿问了中断0x13,导致系统保护所致

“godai兄” 请明示!

[ Last edited by firstsail on 2008-3-6 at 06:30 PM ]
作者: godai     时间: 2008-3-6 19:21
是的,我也试过了, 在Win2000/WinXP下运行是有这样的警告, 因为Win2000/WinXP下禁止了用户对BIOS一级的操作.  在纯DOS下运行_bios_disk函数没有问题.  这个问题在BIOS一级的操作上可能无法绕过Win2000/WinXP. 我原先编程的时候也是利用宏定义__WINXP__对Win2000/WinXP下和纯DOS下分别编译的两个版本运行的, 还没想出什么好办法.  :-)

但是现在在纯DOS下的检测程序也有问题: 如果插上软盘,也会出现DOS提示符 "diskette B not ready",  如果没插软盘更会进入DOS错误中断INT25提示disk fail 之类的造成系统当机. 实用性还不如以前. 郭大大如果暂时也没有更好的办法还不如回到以前的版本不检测软盘,呵呵.
作者: firstsail     时间: 2008-3-6 20:32
暂时恢复不检测软盘,请重新下载更新!


    有一种思路是:读32位标志寄存器内容,如果“VM标志”即“虚拟8086状态标志”为“1”的话表示是在Windows下运行,不要用biosdisk函数判断软盘存在,如果标志为“0”,表示在纯DOS下运行,要用biosdisk函数判断软盘存在。

    但是用以下的代码读到的标志寄存器的“高16位”总是"00000000",即永远无法知道是在“DOS虚拟机”下运行,“godai兄” 有没有其它的方法?

BOOL Is8086VM()
{
    DWORD dwFlags;

    asm pushfd
    asm pop eax
    asm mov dwFlags, eax


    return ((0 == (dwFlags & (1L << 17))) ? TRUE : FALSE);
}

[ Last edited by firstsail on 2008-3-6 at 08:33 PM ]
作者: firstsail     时间: 2008-3-6 20:48
如果godai 兄对“文件打开框”感兴趣的话,可以将您的邮箱告诉我,我会将对应模块源代码发给您,您修改后可以代替“sail.lib”编程库文件里面的“filedlg.obj”模块
作者: godai     时间: 2008-3-7 01:45
那非常感谢! 我的邮箱是bingxizhao@tom.com
希望能进一步与您探讨sail软件的完备与应用!

关于windows与dos的问题兼容版本的问题, 我也还没想到更好的办法。 明天再到单位机器上试验一下看看。

另: 您写的这么好的dos下实用程序竟然没有诸如软驱类的设备吗? 真的不容易了! 呵呵。  如果需要的话我这里有,可以给您寄个过去做试验。
作者: firstsail     时间: 2008-3-7 13:35
邮件已发送到bingxizhao@tom.com
作者: firstsail     时间: 2008-3-7 19:47    标题: 找到一个判断“程序是否是在纯DOS下运行”的可行办法

找到一个判断“程序是否是在纯DOS下运行”的可行办法,基本思路如下:

    80386寄存器MSW可在实模式或任何特权级中读取到,而控制寄存器CR0只能在实模式或特权级0下才能读到,而CR0的低16位就是MSW,根据这个原理,如果它门的值相等,则认为在纯DOS下运行,否则是在Window下的DOS虚拟机运行。

BOOL IsWindowVM()
{
        DWORD dwCr0;
        WORD  wMsw;

        //读机器状态字MSW
        asm smsw ax;
        asm mov wMsw, ax

        //读控制寄存器cr0,在VM下可能引起异常
        asm mov eax, cr0
        asm mov dwCr0, eax

        //判断是否相等,相等时表示纯DOS,否则VM
        if (wMsw == (WORD)(dwCr0 & 0xFFFFlu))
        {
                return (FALSE);
        }

        return (TRUE);
}

虽然纯DOS加载了“Emm386.Exe”后,纯DOS将从“实模式”进入到“保护模式”,但此时纯DOS是在“特权级0”的保护模式下运行,代码不受影响!

由于上面的代码用到了32位指令,特修改16位代码为:
BOOL IsWindowVM()
{
        DWORD dwCr0;
        WORD  wMsw;

        //read MSW
        __emit__(0x0F, 0x01, 0xE0);//asm mov smsw ax
        asm mov wMsw, ax

        //Read cr0
        asm mov ax, wMsw
        asm inc ax
        __emit__(0x0F, 0x20, 0xC0); //asm mov eax, cr0

        //eax to dwCr0
        __emit__(0x66, 0x50); //asm push eax
        asm pop  ax
        asm pop  dx
        asm mov word ptr dwCr0 + 0, ax
        asm mov word ptr dwCr0 + 2, dx

        //judge
        return ((wMsw == (WORD)(dwCr0 & 0xFFFFlu)) ? FALSE : TRUE);

}

[ Last edited by firstsail on 2008-3-14 at 08:21 PM ]
作者: fgckfl     时间: 2008-3-7 21:07    标题: winsail 能支持usb读取吗?

winsail 能支持usb读取吗?
作者: godai     时间: 2008-3-8 00:55
文件已收到。 非常感谢郭兄!
作者: fgckfl     时间: 2008-3-14 12:38
顶一下
作者: firstsail     时间: 2008-3-14 20:17    标题: 文件打开框完善了对软驱的访问

文件打开框完善了对软驱的访问,在这里特别感谢“godai”兄寄来的软驱和软盘!
作者: fgckfl     时间: 2008-3-21 10:25    标题: 表格控件的问题

请问郭兄,如何处理能设置表格每单元格的背景色或字体颜色。
另加载doslen后,在bc下可以打开,保存长文件名文件,但是您的文件框不支持
长文件名显示,可以解决吗?
希望对完善和加强winsail有点意义。
作者: firstsail     时间: 2008-3-21 12:54    标题: 设置表格每单元格的背景色或字体颜色

控件的基类CObject里面有两个函数,一个是设置控件的背景色,一个是设置控件的前景色,
设置控件的背景色:CObject::SetBackColor(int nColor);
设置控件的前景色:CObject::SetForeColor(int nColor);

假设您的表格控件pGrid1,则这样
pGrid1->SetBackColor(YELLOW);//将表格背景设置为“黄色”
pGrid1->SetForeColor(RED);//将表格的文字前景色设置为“红色”

[ Last edited by firstsail on 2008-3-21 at 12:57 PM ]
作者: fgckfl     时间: 2008-3-21 13:14    标题: 设置表格每单元格的背景色或字体颜色

恐怕这样不行吧,您封装的函数无法单独控制每个单元格的显示设置。
提一点建议,在表格控件中,增加设置每个单元格前景色和背景色的属性,在内部显示函数中,每显示表格内容中,单独调用前景色背景色。
这样做是有实际意义的,因为有的时候工程中需要直观显示3维4维数据。颜色可以作为一维数据,我曾经做过这样的表格,不过我不会控制xms内存,所以数据量大不了。
您觉得这样怎么样?
或则能给我点资料,我来帮您完善表格控件?
作者: firstsail     时间: 2008-3-21 14:20
每一个单元格单独设置文字颜色和背景颜色占用的内存较大,实用性不大,不过对于每一列的颜色可单独设置我觉得意义较大。

如果需要编写非标准控件,建议从基类继承开发属于自己的新控件,例如电流表、旋钮、指示灯、温度表......




[ Last edited by firstsail on 2008-3-21 at 02:23 PM ]
作者: fgckfl     时间: 2008-3-23 17:16    标题: 自己写控件的问题

自己写控件内部消息如何处理呢?能给个控件代码的完整例子吗?
作者: fgckfl     时间: 2008-4-4 11:26
封装了新表格和列表控件,如何画一闪一闪的光标呢?
作者: stronger     时间: 2008-4-7 14:42
从那下载呢
作者: firstsail     时间: 2008-4-12 15:14


  Quote:
Originally posted by fgckfl at 2008-4-4 11:26:
封装了新表格和列表控件,如何画一闪一闪的光标呢?

(1)在Swapping函数里面,做一个时间标记,假设为1秒钟


if (abs(现在时间- 时间标记) >= 1)
{
    (1)假设已经显示则隐去闪烁光标,否则显示闪烁光标
   (2)更新时间标记为现在时间,即时间标记=现在时间
}

(2)由于Swapping函数是一直被调用的,在函数里面尽量不要有“new”、"delete"等C语言语句,因为频繁地分配和删除内存易造成内存碎片,从而引起程序的蹦匮。

(3)在最终程序的Release版本中,分配内存后,尽量不用验证分配内存的成功,

   CEdit* pEdit1 = new CEdit;
    if (pEdit1 == NULL)
    {
        ::AfxMessageBox("分配内存","分配内存失败!", MB_OK);
    }


    上面一段代码,则有两个方面的不利之处:
   <1>代码段增加了,由于DOS程序受640K内存限制,应尽量减少代码量!这是DOS下编程的注意点!
    <2>数据段增加了,由于C语言大模式只有一个64K的数据段,尽量做到错误信息用错误处理函数处理!

[ Last edited by firstsail on 2008-4-12 at 06:28 PM ]
作者: godai     时间: 2008-4-16 17:33
刚刚出差了一个月左右回来。 郭兄不用客气! :-)

关于DOS640K常规内存的问题,郭兄有没有考虑过用覆盖模式来编译代码?
作者: godai     时间: 2008-5-5 16:22
这么好的东西, 怎么能沉下去了?
发个贴, 顶上来! ^_^

另: 郭兄, 看看CComboBox中是否有个小BUG: 当CComboBox中只有一项可选的时候, 这时拉动下拉滚动条则有异常。 请查下。
作者: firstsail     时间: 2008-5-6 15:08    标题: 原因找到,请重新到网站下载

1:Bug找到,主要是由CScrollBar::SetRange()函数引起

void   CScrollBar::SetRange(DWORD dwMin,DWORD dwMax)
{
        if (dwMax > dwMin)
        {
                m_dwMax=dwMax;
                m_dwMin=dwMin;

        }
}

当项为1个时,则dwMin = 0, dwMax = 0,此时上面代码导致“值”没有更新


现修正代码如下:
void   CScrollBar::SetRange(DWORD dwMin,DWORD dwMax)
{
        if (dwMax >= dwMin)
        {
                m_dwMax=dwMax;
                m_dwMin=dwMin;

                if (m_dwLocation < m_dwMin)
                {
                        m_dwLocation = m_dwMin;
                }
                else if (m_dwLocation > m_dwMax)
                {
                        m_dwLocation = m_dwMax;
                }
        }
}
作者: firstsail     时间: 2008-5-6 19:13    标题: 大数据量的数组

由于C语言大模式只有一个64K的数据段,用户又需要大数据量的全局变量时,建议将该变量的数据类型设置成“far”类型的数据变量。

现有一个全局变量数组,占用16K字节。如果配置成

WORD  wsGobalArray[4][2048];

此时,可能导致64K断溢出。故正确应配置如下:

WORD far wsGobalArray[4][2048];

大数组一般用于“AD采样”!
作者: godai     时间: 2008-5-8 12:05
郭兄:CComboBox已测试正常。

在BC编译环境Large模式下,好像我理解的是编译器自动把所有的函数和指针变成far的。不知道理解的对不对。

BC下的说明如下:
“ Use Large model for very large applications only.
Far pointers are used for both codes and data, giving both a 1MB range. All function and data pointers are far by default. ”
作者: firstsail     时间: 2008-5-8 12:37
(1)对于指针和函数,在大模式下,全部都是far类型
(2)对于全局变量来说,没有far类型的变量是“DATA”数据段,而far类型的数据类型是“FAR_DATA”数据段

假设有如下的一个abc.Cpp文件,内容如下
#include <Symbol.h>

WORD wAfxData1;
WORD far wAfxData2;


void Abcd()
{
    wAfxData1 = 0;
    wAfxData2 = 0;
}

对于上面的abc.Cpp文件在large模式下编译,注意选中菜单
[Options]->[Compile]->Generate Assembler Source
此时编译后会在磁盘中留下“abc.asm”汇编文件,用notepad或edit程序打开并阅读它,可看到“DATA”和“FAR_DATA”数据段

<1>当仿问“DATA”数据段时,CPU自动用DS寄存器作为段寄存器,所以访问速度较快

<2>当仿问“FAR_DATA”数据段时,程序将FAR_DATA段的段地址加载到ES寄存器中,然后正确访问该变量,所以访问速度较慢

上面Abcd函数对应汇编语言如下
   ;        void Abcd()
   ;       
        assume        cs:ABC_TEXT
@Abcd$qv        proc        far
        push        bp
        mov        bp,sp
   ;       
   ;        {
   ;            wAfxData1 = 0;
   ;       
        mov        word ptr DGROUP:_wAfxData1,0
   ;       
   ;            wAfxData2 = 0;
   ;       
        mov        ax,seg _wAfxData2
        mov        es,ax
        mov        word ptr es:_wAfxData2,0
   ;       
   ;        }
   ;       
        pop        bp
        ret       
@Abcd$qv        endp

[ Last edited by firstsail on 2008-5-8 at 12:54 PM ]
作者: firstsail     时间: 2008-7-10 13:37    标题: 完善图片保存功能

由于WinSail老的版本,当窗口中按下“F3”功能键时,会将当前窗口以固定的文件名-----“A.Bmp”文件存贮,这样在工业现场往往很不方便。现改为:

  当窗口中按下“F3”功能键时,会弹出输入框让用户输入文件名,然后用输入的文件名来存贮图片。


下载地址:“http://www.firstsail.com.cn/software.html
作者: dama_01     时间: 2008-7-16 11:59    标题: 能支持中断吗?

工业PC104的板子,很多应用需要用到硬终端,比如IRQ10等,并在中断程序中做计算,IO操作等
用楼主的系统,能支持吗?
作者: godai     时间: 2008-7-17 12:00    标题: 鼠标 INT33H 问题

郭大大, 您的winsail程序在试用中出现一个现象: 就是在振动环境中有时候偶尔会发生PS2鼠标指针乱飞掉的情况。 初步判断是干扰引起的鼠标通讯错误。
您的鼠标驱动是用的加载标准驱动, 然后调用INT33h来驱动鼠标的吗?
有没有可能我自己能控制鼠标的调用?
比如发现数据错位引起的乱飞情况后重新调用鼠标初始化之类的操作。
作者: firstsail     时间: 2008-9-19 18:57    标题: WinSail 已经支持16位(64K)色了

1)WinSail 已经支持64K色了,即16位色。

    如果是640x680x16位色,Config.Sys设置如下:
        Device = 11
        Mode = 111

    如果是800x600x16位色,Config.Sys设置如下:
        Device = 11
        Mode = 114

   如果是1024x768x16位色,Config.Sys设置如下:
        Device = 11
        Mode = 117


(2)下载解压后,有一文件Sail3000\bmp3\Color1.Bmp可供测试,它是一幅24位真彩色图片



(3)测试程序可用下面的一段代码
void Demo_DisplayBmp()
{

        char bufFile[256];

        //调用打开文件框函数选择“BMP”文件
        while (::AfxOpenFileDialog(TRUE, bufFile, NULL))
        {
                       
                //保存鼠标状态               
                int nMouse = ::GetMouse();
                //画图前,须将鼠标关闭
                ::CloseMouse();

                //清除视窗
                ::ClearViewPort();

                //显示图片
                ::DisplayBmpFile(0, 0, bufFile);

                //恢复鼠标状态
                ::SetMouse(nMouse);
        }

        return;
}




WinSail的下载地址:http://www.firstsail.com.cn/Software.html

[ Last edited by firstsail on 2008-10-5 at 17:51 ]
作者: firstsail     时间: 2008-10-5 17:13    标题: WinSail增加动画控件了

WinSail增加了动画控件CAnimalCtrl,目前只能播放GIF文件.



(1)类定义在头文件"MyFrame.h"中,
(2)文档名是:“界面控件类_CAnimalCtrl动画控件详细设计.doc”。

(3)应用该控件非常简单,一般仅需要三行代码

//分配实例
CAnimalCtrl* pAnimalCtrl1 = new CAnimalCtrl(pDialog);
//建立控件
pAnimalCtrl1->CreateObject(100, 100, 50, 50, NULL);
//装入GIF文件
pAnimalCtrl1->LoadFile("Bmp\\Earth3.Gif");


下载WinSail解压后,运行sail3000里面的Sai2000程序,在桌面右上角可以看到有一个地球在转动
建议将WinSail调整到256色或“16位=64K色”,此时动画控件的颜色最逼真。


注意:使用动画控件CAnimalCtrl后,Exe文件增加7K左右的代码量。

7        举例
#include <bios.h>
#include <Stdio.h>
#include <Stdlib.h>
#include <conio.h>
#include <dos.h>
#include <String.h>
#include <math.h>

#include <Symbol.H>
#include <MyFrame.h>
#include <gif.h>
#include <Lzw.h>

int far TransrateKey(CObject *)

{

        return(0);

}

unsigned _stklen = 60u * 1024u;

//动画控件演示函数的一个按钮对应的回调函数
void far ClickButton1_DemoAnimalCtrl(CObject *pObj)
{
    //得到动画控件对应父窗口的指针
        CDialog* pDialog = (CDialog *)pObj->GetParent();
    //得到动画控件的指针
        CAnimalCtrl* pAnimalCtrl = (CAnimalCtrl *)
                pDialog->ObjectFromID(ANIMALBASE + 1 - 1);

    //选择新的一个GIF文件
        char bufFile[256];
        if (!AfxOpenFileDialog(TRUE, bufFile, NULL))
        {
                return;
        }

    //装入新的GIF文件
        pAnimalCtrl->LoadFile(bufFile);
    //由于每个动画的大小不同,所以必须重刷新窗口
        pDialog->ShowWindow();

        return;
}

//动画控件演示函数
void far Demo_AnimalCtrl()
{
    //分配对话框实例
        CDialog* pDialog = new CDialog;
//建立对话框
        pDialog->CreateWindow(0,0,640,480,"动画控件演示程序");
    //将窗口居中
        pDialog->Center();

    // 分配动画控件的实例
        CAnimalCtrl* pAnimalCtrl = new CAnimalCtrl(pDialog);
// 建立动画控件,该控件的宽度和高度的意义不大。
        pAnimalCtrl->CreateObject(5,30,40,100, NULL);
    //装入动画GIF文件
        pAnimalCtrl->LoadFile("Bmp\\Earth3.gif");
    //设置动画控件的ID号
        pAnimalCtrl->SetID(ANIMALBASE + 1 - 1);

        //分配按钮实例
CButton* pButton1 = new CButton(pDialog);
//建立按钮
        pButton1->CreateObject(500, 50, 80, 24, "Load");
    //设置控钮对应的回调函数
        pButton1->SetFc(ClickButton1_DemoAnimalCtrl);

    //显示对话框
        pDialog->ShowWindow();
    //进入对话框的消息循环
        pDialog->DoModal();

    //删除对话框实例
        delete pDialog;
    //函数返回
        return;
}

int main(int argc, char** argv)
{
    //初始化WinSail系统
        if (!::InitSystem(argc, argv))
        {
                ::CloseSystem();
                return(0);
        }

     //调用动画演示程序
         ::Demo_AnimalCtrl();

    //退出WinSail系统
        ::CloseSystem();
        return(1);
}

WinSail的下载地址:http://www.firstsail.com.cn/Software.html

[ Last edited by firstsail on 2008-10-5 at 17:53 ]
作者: firstsail     时间: 2008-10-5 17:31
为了增加动画控件,WinSail增加了系统全局定时器,目前暂时定为最多20个


(1)函数WinSail_SetTimer();
原    型:int  WinSail_SetTimer(DWORD dwParam, WORD wTime,
              void far(*pFc)(DWORD dwParam),DWORD dwWindow);
作    用:建立系统定时器
入口参数:DWORD dwParam ----------   定时器回调函数的入口指针
         WORD  wTime-------------   定时器的时间,以55mS(即1/18.2S)为单位
         void far(*pFc)(DWORD)---   定时器回调函数
         DWORD dwWindow----------   隶属窗口指针,没有隶实时为NULL
出口参数:无
返 回 值:成功返回定时器名柄0,1,2,....;失改返回"-1".


(2)函数WinSail_KillTimer()
原    型:void WinSail_KillTimer(int nTimer);
作    用:删除指定的定时器
入口参数:int nTimer -------------   定时器名柄
出口参数:无
返 回 值:无



注意:如果建立了有隶属窗口的定时器,在窗口销毁之前必定要先销毁该定时器!


WinSail的下载地址:http://www.firstsail.com.cn/Software.html

[ Last edited by firstsail on 2008-10-5 at 17:55 ]
作者: firstsail     时间: 2008-11-2 12:40    标题: WinSail已经支持JPG文件的显示了

WinSail支持JPG文件的显示,系统必须配置成64K色以上

[display]

device=11
mode = 117

;mode=111 是640*480*64K色
;mode=114 是800*600*64K色
;mode=117 是1024*768*64K色


目前解压“1024*768”且Y:Cb:Cr = 1:1:1分辨率的JPG文件,解压并显示的时间大约需要2秒左右,还不太满意。目前正在优化代码!





作者: firstsail     时间: 2008-11-20 11:15


  Quote:
Originally posted by dama_01 at 2008-7-16 11:59:
工业PC104的板子,很多应用需要用到硬终端,比如IRQ10等,并在中断程序中做计算,IO操作等
用楼主的系统,能支持吗?

WinSail是一个完全与BC31兼容的嵌入式开发系统,特别适用于电力、电子系统的PC104应用,您所提到的问题是完全支持的。

[ Last edited by firstsail on 2008-11-20 at 11:21 ]
作者: firstsail     时间: 2008-11-20 11:18


  Quote:
Originally posted by godai at 2008-7-17 12:00:
郭大大, 您的winsail程序在试用中出现一个现象: 就是在振动环境中有时候偶尔会发生PS2鼠标指针乱飞掉的情况。 初步判断是干扰引起的鼠标通讯错误 ...

关于鼠标在振动的工业环境中乱跳的情况可能是由于用了“光电鼠标”,建议在工业强振动环境用“机械式滚轮鼠标”试一试。
作者: windowsvesta     时间: 2009-3-5 00:45
好像好久没有更新了!
作者: andyond     时间: 2009-3-15 10:05
下来学习学习,
作者: firstsail     时间: 2009-4-2 23:36
窗口控件支持了“命令快捷键”函数
void CWindow::AddCommandKey(WORD wKey, void far (*pMyFc)(CObject *));

函数功能:增加键盘快捷键(无需控件宿主)

入口参数:wKey ------ 虚拟按键值。例如F1键是VK_F1,F1键是VK_F2,...,F10键是VK_F10
          pMyFc  ---- 回调函数。原型为
                void far MyFc(CObject* pObject)
                        {
                            CWindow* pWindow = (CWindow *)pObject;
                             //下面增加您自己的代码
                   //......
                        }
出口参数:无
返 回 值:无

[ Last edited by firstsail on 2009-4-2 at 23:39 ]
作者: firstsail     时间: 2009-5-6 08:12    标题: 发现数据库Flush函数的严重出错

    发现经过
有客户反映,程序未正常关机时,经常造成数据库文件的数据丢失,数据库文件非法!
    检查程序
自己的程序每写一次数据纪录,已经调用了“CFoxpro::Flush()”函数,其作用是将数据真正写入磁盘,如果有上面说过的情况,理应是该函数有问题。

BOOL CFoxpro::Flush()
{
                //检查文件指针的合法性
        if (NULL == m_pFile)
        {
                return(FALSE);
        }

                //刷新磁盘缓冲区
        ::fflush(m_pFile);

        return(TRUE);
}

初步怀疑C函数库提供的fflush()函数并不是将磁盘冲区数据全部写入磁盘,经过使用BC31的帮助文件,发现真不是这回事!正确应如下修改

    解决问题

将CFoxpro::Flush()修改为如下所示,已解决

BOOL CFoxpro::Flush()
{
                //检查文件指针的合法性
        if (NULL == m_pFile)
        {
                return(FALSE);
        }

                //刷新磁盘缓冲区
        ::fflush(m_pFile);

        int duphandle = ::dup(fileno(m_pFile));

        ::close(duphandle);

        return(TRUE);
}
作者: firstsail     时间: 2009-5-16 01:11    标题: WinSail的TCP/IP栈是如何工作的?

为了让大家对WINSAIL在单任务系统中如何调度TCP/IP的。下面作一些说明!

(1)在窗口的CWindow::OnIdle(CObject* pObj)函数中,调用了TCP/IP的循环处理入口函数指针pSocketLoopFc指向的套接字循环函数。




CWindow::OnIdle(CObject* pObj)的源代码如下


extern BOOL bAfxNetcard;   //是否在CONFIG.Sys文件中配置需要网卡标志
extern BOOL bAfxInitSocket; //是否套接字成功初始化标志
extern BOOL (*__pSocketInitFc)(); //套接字初始化函数指针
extern BOOL (*__pSocketCloseFc)();//套接字关闭函数指针
extern BOOL (*__pSocketLoopFc)(BOOL, BOOL, BOOL);//套接字循环函数指针

void    CWindow::OnIdle()
{
    //这里判断是否需要执行TCP/IP栈
    if (bAfxNetcard && bAfxInitSocket && __pSocketLoopFc != NULL)
    {
        __pSocketLoopFc(TRUE, TRUE, TRUE);
    }

    //这里执行void CWindow::SetIdleFc()函数注册的“空闲函数指针“
    if (m_pIdleFc != NULL)
    {
        m_pIdleFc((CObject*)this);
    }
}

(2)注册TCP/IP协议栈的函数AfxRegisterNetcardEntry()源代码如下

BOOL AfxRegisterNetcardEntry(BOOL (*pSocketInitFc)(),
        BOOL (*pSocketCloseFc)(), BOOL (*pSocketLoopFc)(BOOL, BOOL, BOOL))
{
        if (pSocketInitFc == NULL || pSocketCloseFc == NULL)
        {
                return(FALSE);
        }
        __pSocketInitFc = pSocketInitFc;
        __pSocketCloseFc = pSocketCloseFc;
        __pSocketLoopFc = pSocketLoopFc;
        return(TRUE);
}

(3)WinSail默认的
     套接字初始化函数:GlobalInitSocket()函数
     套接字关闭函数是:GlobalCloseSocket()函数
     套接字循环函数:EthernetEntry()函数

EthernetEntry只处理ARP、RARP、ICMP请求以及没有发送的数据包及时发送出去,对于其它的请求则被忽略。
所以用户应用还需要重新编写自己的“套接字循环函数”。


//下面是用户自己编写的“套接字循环函数”。这个可以参照Sail3000工程的Sail2000.Cpp文件和Remote_N.Cpp文件,它实现了“文件传输、键盘按键下发、鼠标按键下发、屏幕上传、QQ聊天”等功能。
BOOL User_EthernetEntry(BOOL bSingle, BOOL bSend, BOOL bIcmp)
{
    //运行默认的套接字循环函数
    ::EthernetEntry(bSingle, bSend, bIcmp);

    //下面编写自己的SOCKET查询、读、写等等
  //(略)

  
        return(TRUE);
}



(4)由于WINSAIL运行于单任务中,所以任何地方的长时间堵塞,都会造成TCP/IP的长期堵塞。为了减少这情况,在堵塞的循环中,须调用

    User_EthernetEnty(TRUE, TRUE, TRUE);


(5)如果用户注册第三方的TCP/IP栈(如Watcp等),初始化函数成功须返回TRUE,否则返回FALSE,WinSail自动对初始化函数的返回标志对bAfxInitSocket变量置位,同时别忘了配置config.Sys文件中的“Netcard”段的“netCard”键值置成  TRUE,方能与WinSail完美结合!

    在WINSAIL里面的InitSystem()函数是这样初始化TCP/IP协议栈的:



    bAfxInitSocket = FALSE;

    if (bAfxNetcard && __pSocketInitFc != NULL &&
        __pSocketCloseFc != NULL)
    {
        if (!__pSocketInitFc())
        {
            __pSocketCloseFc();
            bAfxInitSocket = FALSE;

            //AfxMessageBox("网络","无法加载网络!");
        }
        else
        {
            bAfxInitSocket = TRUE;
        }
}

[ Last edited by firstsail on 2009-5-16 at 02:25 ]
作者: zhiming420     时间: 2009-11-15 09:08
好东西哦
作者: firstsail     时间: 2010-7-5 14:17
网站因地址解析错误,导致网站几个月不能正常登录.现在终于可以登录了!
作者: houwenhui     时间: 2010-7-9 13:56
太神奇了 看不懂啊
作者: firstsail     时间: 2011-1-14 11:15    标题: WinSail的MakeDlg.Exe文件升级

WinSail的MakeDlg.Exe文件升级



增高了两个选项
  (1)将CLabel和CGroup控件解释成非控件
  (2)将CGroup坐标与Windows对齐

    <1>如果选中"CLabel和CGroup控件解释成非控件"选项, 则将所有的CLabel与CGroup控件的生成代码被注释,并且生成void FAR OnDraw_VccFunction(CObject *)函数,函数内部生成代码如下:

     其中CLabel控件解释成ChPrintf()函数
   其中CGroup控件解释成DrawBoxCaptionEx()函数

    这样设计的目的是为了节省宝贵的内存


   <2>如果选中"将CGroup坐标与Windows对齐"选项, 则WinSail的Group控件与Windows的Group控件的可视边框区域相同,强列推荐使用该选项.


下载地址:http://www.firstsail.com.cn/software.html

[ Last edited by firstsail on 2011-1-14 at 11:23 ]
作者: wuhengsi     时间: 2011-1-16 00:48
我用的联通网络,不知道为什么,我无法进入郭兄的网址“http://www.FirstSail.b2b.Cn

希望那个好心朋友能帮将郭兄的软件发到我的邮箱里面,感谢了
邮箱地址:  wuhengsi88@163.com
作者: firstsail     时间: 2011-1-19 10:16


  Quote:
Originally posted by wuhengsi at 2011-1-16 00:48:
我用的联通网络,不知道为什么,我无法进入郭兄的网址“http://www.FirstSail.b2b.Cn

希望那个好心朋友能帮将郭兄的软件发到我的邮箱里面,感谢了
邮箱地址:  wuhengsi88@163.com

网站地址是:http://www.firstsail.com.cn/softwafe.html
电子邮箱是:szhello8@21cn.net
作者: f371575950     时间: 2016-12-24 23:58
学习学习
作者: firstsail2     时间: 2018-7-13 20:16
好久没有回来了!
作者: firstsail     时间: 2018-7-14 12:08    标题: 如果定制可移值的Excel能识别的数据库

在单片机系统,或Linux系统中,经常要用到自定义的数据库,该数据库文件希望能被Windows下的Office Excel识别,怎么办呢?现在有一个方法,可以使用Foxpro2.6版本的数据库,文件结构是公开的,且可被Excel识别。
   
    在WinSail中,由Foxpro.h和Foxpro.Cpp文件组成,稍后会公开所有源代码上来,如果有需要的人士可以移值!
作者: firstsail     时间: 2018-7-14 12:10
//下面文件是Foxpro.h文件

#ifndef _FOXPRO_20110811_H_
#define _FOXPRO_20110811_H_

//数据库头
struct FOXPRO_HEAD
{
        BYTE        byFlags;
        BYTE    byYear;
        BYTE    byMonth;
        BYTE    byDay;

        DWORD   dwRecordCount;
        WORD    wRecordAddress;
        WORD    wRecordLength;
        DWORD   dwReserve1;
        DWORD   dwReserve2;
        DWORD   dwReserve3;
        DWORD   dwReserve4;
        DWORD   dwReserve5;
};

//数据库“域”属性
struct FOXPRO_FIELDS
{
        BYTE    strName[10];
        BYTE    byFill;
        BYTE    byStyle;
        DWORD   dwDataAddress;
        BYTE    byLength;
        BYTE    byDotCount;
        WORD    wReserve1;
        BYTE    byFlags;
        BYTE    wsReserve[11];

};

//数据库“类”定义
class CFoxpro
{
private:
        BOOL           m_bNew;
        long           m_lRecordPoint;
        char           m_strFile[256];
        FOXPRO_HEAD    m_FoxproHead;
        FOXPRO_FIELDS  m_FoxproFields;
        FILE*          m_pFile;
        BYTE*          m_pRecordBuf;
        FOXPRO_FIELDS* m_pFoxproFields;
public:
        //建立新的数据库
        BOOL  CreateFoxpro(const char*pStr);
        //打开已存在的数据库
        BOOL  OpenFoxpro(const char*pStr);
        //关闭数据库
        BOOL  CloseFoxpro();
        //增加一域
        BOOL  AddFields(const char* strName,BYTE byStyle,int nLength,int nDot);
        //获得指定列的“域”属性
        FOXPRO_FIELDS*  GetFoxproFields(int nIndex);
public:
        //获得列的数量
        int   GetFieldsCount() {return(m_FoxproHead.wRecordAddress-sizeof(FOXPRO_HEAD))/sizeof(FOXPRO_FIELDS);}
        //获得纪录总数
        long  GetRecordCount() {return(m_FoxproHead.dwRecordCount);}
        //获得纪录地址
        long  GetRecordAddress() {return((DWORD)m_FoxproHead.wRecordAddress);}
        //获得数据库的最后修改日期-“有”
        int   GetMonth()       {return((int)m_FoxproHead.byMonth);}
        //获得数据库的最后修改日期-“日”
        int   GetDay()         {return((int)m_FoxproHead.byDay);}
        //获得数据库的最后修改日期-“年”
        int   GetYear()        {return((int)1900+(DWORD)m_FoxproHead.byYear);}
        //获得纪录的长度
        int   GetRecordLength(){return((int)(DWORD)m_FoxproHead.wRecordLength);}
        //显示数据库调试信息
        void  Debug();
public:
        //修剪指定字符串的前导空格
        static char*  TrimLeft(char  *pStr);
        //修剪指定字符串的后导空格
        static char*  TrimRight(char *pStr);

public:
        //设置串类型“域”的字符串
        BOOL  SetFieldsString(int nIndex, const char* pStr);
        //设置数字类型“域”的数字值
        BOOL  SetFieldsNumber(int nIndex,float fValue);
        //设置日期类型“域”的日期值
        BOOL  SetFieldsDate(int nIndex,int nYear,int nMonth,int nDay);
        //设置逻辑类型“域”的逻辑值
        BOOL  SetFieldsLogic(int nIndex,BOOL bLogic);
        //设置备注类型“域”的备注值
        BOOL  SetFieldsMemo(int nIndex, const char* pStr);

        //获得串类型“域”的字符串
        BOOL  GetFieldsString(int nIndex,char* pStr);
        //获得数字类型“域”的数字值
        float GetFieldsNumber(int nIndex);
        //获得日期类型“域”的日期值
        BOOL  GetFieldsDate(int nIndex,int* pnYear,int* pnMonth,int* pnDay);
        //获得逻辑类型“域”的逻辑值
        BOOL  GetFieldsLogic(int nIndex);
        //获得备注类型“域”的备注值
        BOOL  GetFieldsMemo(int nIndex,char* pStr);

        //定位纪录
        BOOL  Seek(long nIndex,int nMode);       
        //判断数据库是否已经打开
        BOOL  IsOpen();
        //刷新数据库到磁盘
        BOOL  Flush();
        //增加一新纪录
        BOOL  AddNew();
        //准备修改当前纪录
        BOOL  Edit();
        //使当前的更改有效
        BOOL  Update();
        //在当前纪录中插入一条纪录
        BOOL  Insert();
        //删除当前纪录(带上删除标记)
        BOOL  Delete();
        //删除当前纪录
        BOOL  DeleteEx();
        //将带有删除标准的纪录删除
        BOOL  Zap();
public:
        void CoFoxpro();//构造函数调用
        //构造函数
        CFoxpro();
        //构造函数(打开指定的数据库)
        CFoxpro(char* strFile);
        //析构函数
        ~CFoxpro();
};



#endif
作者: firstsail     时间: 2018-7-14 12:13
//下面文件是Foxpro.Cpp文件
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <dos.h>
#include <bios.h>
#include <dir.h>
#include <conio.h>
#include <string.h>
#include <sys\\stat.h>
#include <io.h>

#include "symbol2.h"
#include "Foxpro.h"


//#include <Myframe.h>

void CFoxpro::CoFoxpro()
{
        m_bNew          = FALSE;
        m_lRecordPoint  = 0;
        m_pRecordBuf    = NULL;
        m_pFile         = NULL;
        m_pFoxproFields = NULL;
        _fmemset(&m_FoxproHead  ,0,sizeof(FOXPRO_HEAD));
        _fmemset(&m_FoxproFields,0,sizeof(FOXPRO_FIELDS));
        _fmemset(&m_strFile,0,256);
}

CFoxpro::CFoxpro()
{
        this->CoFoxpro();
}

CFoxpro::CFoxpro(char* strFile)
{

        this->CoFoxpro();
        this->OpenFoxpro(strFile);
}

CFoxpro::~CFoxpro()
{
        if (m_pFile != NULL)
        {
                fclose(m_pFile);
        }
        m_pFile = NULL;

        DELETE(m_pRecordBuf);
        DELETE(m_pFoxproFields);

}

void CFoxpro::Debug()
{
        char buf[512];
        if(!m_pRecordBuf) return;

        int nFields = this->GetFieldsCount();
        printf("\n-------------------------------------------------");
        for(int i=0;i<nFields;i++)
        {
                m_FoxproFields = *(this->GetFoxproFields(i));

                printf("\n%10s--",m_FoxproFields.strName);
                if(m_FoxproFields.byStyle=='C')
                {
                        this->GetFieldsString(i,buf);
                        this->TrimLeft(buf);
                        this->TrimRight(buf);
                        printf("%s",buf);
                }
                else if(m_FoxproFields.byStyle=='L')
                {
                        BOOL bLogic = this->GetFieldsLogic(i);
                        printf("%d",bLogic);
                }
                else if(m_FoxproFields.byStyle=='D')
                {
                        int nYear,nMonth,nDay;
                        this->GetFieldsDate(i,&nYear,&nMonth,&nDay);
                        printf("%04d-%02d-%02d",nYear,nMonth,nDay);
                }
                else if(m_FoxproFields.byStyle=='N')
                {
                        float fValue = this->GetFieldsNumber(i);
                        if(m_FoxproFields.byDotCount==0)      printf("%.0f",fValue);
                        else if(m_FoxproFields.byDotCount==1) printf("%.1f",fValue);
                        else if(m_FoxproFields.byDotCount==2) printf("%.2f",fValue);
                        else if(m_FoxproFields.byDotCount==3) printf("%.3f",fValue);
                        else if(m_FoxproFields.byDotCount==4) printf("%.4f",fValue);
                        else if(m_FoxproFields.byDotCount==5) printf("%.5f",fValue);
                        else                                  printf("%.6f",fValue);

                }
                else if(m_FoxproFields.byStyle=='M')
                {
                }
                if(i&& !(i%24))
                {
                        getch();
                }

        }
}

BOOL  CFoxpro::CreateFoxpro(const char *pStr)
{
        if(m_pFile) return(FALSE);

        m_pFile = NULL;

        CoFoxpro();

        int nFields = 0;

        date mDate;
        ::getdate(&mDate);

        m_FoxproHead.byFlags        = 0x03;
        m_FoxproHead.byDay          = (BYTE)mDate.da_day;
        m_FoxproHead.byMonth        = (BYTE)mDate.da_mon;
        m_FoxproHead.byYear         = (BYTE)(WORD)(mDate.da_year-1900);
        m_FoxproHead.dwRecordCount  = 0x00;
        m_FoxproHead.wRecordAddress = sizeof(FOXPRO_HEAD)+1;
        m_FoxproHead.wRecordLength  = 0x01;
        m_FoxproHead.dwReserve1     = 0x00;
        m_FoxproHead.dwReserve2     = 0x00;
        m_FoxproHead.dwReserve3     = 0x00;
        m_FoxproHead.dwReserve4     = 0x00;
        m_FoxproHead.dwReserve5     = 0x00;

        _fmemset(&m_FoxproFields.strName,0,10);
        m_FoxproFields.byFill        = 0;
        m_FoxproFields.byStyle       = (BYTE)'C';
        m_FoxproFields.dwDataAddress = 0;
        m_FoxproFields.byLength      = 0;
        m_FoxproFields.byDotCount    = 0;
        m_FoxproFields.wReserve1     = 0;
        m_FoxproFields.byFlags       = 0;
        _fmemset(&m_FoxproFields.wsReserve,0,11);

        if(!(m_pFile=fopen(pStr,"w+b")))
        {
                return(FALSE);
        }

        fwrite(&m_FoxproHead  ,sizeof(FOXPRO_HEAD)  ,1,m_pFile);
        fwrite(&m_FoxproFields,sizeof(FOXPRO_FIELDS),nFields,m_pFile);
        fwrite("\x0D",1,1,m_pFile);
        fwrite("\x1A",1,1,m_pFile);

        //File Name
        _fstrcpy(m_strFile,pStr);
        //Malloc RecordBuf
        m_pRecordBuf = new BYTE[this->GetRecordLength()+1024];
        _fmemset(m_pRecordBuf,0,this->GetRecordLength()+1024);
        //Malloc  Foxpro_Fields
        m_pFoxproFields = new FOXPRO_FIELDS[1+this->GetFieldsCount()];
        _fmemset(m_pFoxproFields,0,sizeof(FOXPRO_FIELDS)*(1+this->GetFieldsCount()));
        //Fill FoxproFields
        ::fseek(m_pFile,sizeof(FOXPRO_HEAD),SEEK_SET);
        nFields = this->GetFieldsCount();
        for(int i=0;i<nFields;i++)
        {
                ::fread(&m_pFoxproFields,sizeof(FOXPRO_FIELDS),1,m_pFile);
        }
        return(TRUE);
}


BOOL  CFoxpro::OpenFoxpro(const char* pStr)
{
        if (m_pFile != NULL)
    {
        return(FALSE);
    }

        CoFoxpro();

        if (!(m_pFile = fopen(pStr,"r+b")))
    {
        return(FALSE);
    }

        long  lFileLength = filelength(fileno(m_pFile));
        if(lFileLength<1L*sizeof(FOXPRO_HEAD)+2)
        {
                ::fclose(m_pFile);
                m_pFile=NULL;
                return(FALSE);
        }

        rewind(m_pFile);
        fread(&m_FoxproHead  ,sizeof(FOXPRO_HEAD)  ,1,m_pFile);
        //Flags
        if(m_FoxproHead.byFlags!=0x03 && m_FoxproHead.byFlags!=0xF5)
        {
                ::fclose(m_pFile);
                m_pFile=NULL;
                return(FALSE);
        }

        BYTE nCh=0;
        fseek(m_pFile,-1,SEEK_END);
        fread(&nCh,1,1,m_pFile);
        // End Is 0x1A?
        if(nCh!=0x1A)
        {
                fclose(m_pFile);
                m_pFile=NULL;
                return(FALSE);
        }
        //---------------------------
        //File Name
        _fstrcpy(m_strFile,pStr);
        //Malloc Record Buffer
        m_pRecordBuf = new BYTE[this->GetRecordLength()+1024];
    if (m_pRecordBuf == NULL)
    {
                fclose(m_pFile);
                m_pFile=NULL;

        return (FALSE);
    }
        _fmemset(m_pRecordBuf,0,this->GetRecordLength()+1024);
        //Malloc  Foxpro_Fields
        m_pFoxproFields = new FOXPRO_FIELDS[1+this->GetFieldsCount()];
    if (m_pFoxproFields == NULL)
    {
        delete m_pRecordBuf;
        m_pRecordBuf = NULL;

                fclose(m_pFile);
                m_pFile=NULL;

        return (FALSE);
    }

        _fmemset(m_pFoxproFields,0,sizeof(FOXPRO_FIELDS)*(1+this->GetFieldsCount()));
        //Fill FoxproFields
        ::fseek(m_pFile,sizeof(FOXPRO_HEAD),SEEK_SET);
        int nFields = this->GetFieldsCount();
        for(int i=0;i<nFields;i++)
        {
                ::fread(&m_pFoxproFields,sizeof(FOXPRO_FIELDS),1,m_pFile);
        }
        return(TRUE);
}

BOOL  CFoxpro::CloseFoxpro()
{
        if (NULL != m_pFile)
        {
                fclose(m_pFile);
    }
        m_pFile = NULL;

        DELETE(m_pRecordBuf);
        DELETE(m_pFoxproFields);

        return(TRUE);
}

BOOL  CFoxpro::AddFields(const char* strName,BYTE byStyle,int nLength,int nDot)
{
        if(!m_pFile) return(FALSE);

        if(byStyle=='C')      {nDot = 0;}
        else if(byStyle=='N') {}
        else if(byStyle=='D') {nLength = 8;nDot    = 0;}
        else if(byStyle=='L') {nLength=1;nDot   =0;}
        else if(byStyle=='M') {nLength = 10;nDot    = 0;}
        else {return(0);}

        _fmemset(&m_FoxproFields,0,sizeof(FOXPRO_FIELDS));
        //----------------------------------------------------
        if(byStyle=='M')
        {
                m_FoxproHead.byFlags=0xF5;
                fseek(m_pFile,0,SEEK_SET);
                fwrite(&m_FoxproHead  ,sizeof(FOXPRO_HEAD)  ,1,m_pFile);
        }
        //Calc Fields
        int nFields=(m_FoxproHead.wRecordAddress-sizeof(FOXPRO_HEAD))/sizeof(FOXPRO_FIELDS);
        //Modify Head
        date mDate;
        ::getdate(&mDate);
        m_FoxproHead.byDay          = (BYTE)mDate.da_day;
        m_FoxproHead.byMonth        = (BYTE)mDate.da_mon;
        m_FoxproHead.byYear         = (BYTE)(WORD)(mDate.da_year-1900);
        m_FoxproHead.wRecordAddress+= sizeof(FOXPRO_FIELDS);
        m_FoxproHead.wRecordLength += (WORD)nLength;
        //Write Head Again
        fseek(m_pFile,0,SEEK_SET);
        fwrite(&m_FoxproHead,sizeof(FOXPRO_HEAD),1,m_pFile);
        //
        int nFieldsAddress = 1;
        fseek(m_pFile,sizeof(FOXPRO_HEAD),SEEK_SET);
        for(int i=0;i<nFields;i++)
        {
                ::fread(&m_FoxproFields,sizeof(FOXPRO_FIELDS),1,m_pFile);
                nFieldsAddress+=m_FoxproFields.byLength;
        }
        //Fill in Field
        if (::_fstrlen(strName) < 10)
        {
                ::_fstrcpy((char*)&m_FoxproFields.strName,(char*)strName);
        }
        else
        {
                ::_fmemcpy((BYTE*)&m_FoxproFields.strName, (char*)strName, 10);
        }

        m_FoxproFields.byStyle       = (BYTE)byStyle;
        m_FoxproFields.dwDataAddress = nFieldsAddress;
        m_FoxproFields.byLength      = (BYTE)nLength;
        m_FoxproFields.byDotCount    = nDot;
       //Write Field
        ::fseek(m_pFile,sizeof(FOXPRO_HEAD)+nFields*sizeof(FOXPRO_FIELDS),SEEK_SET);
        ::fwrite(&m_FoxproFields,sizeof(FOXPRO_FIELDS),1,m_pFile);
        //Write End
        fwrite("\x0D",1,1,m_pFile);
        fwrite("\x1A",1,1,m_pFile);

        //Malloc Record BUf
        DELETE(m_pRecordBuf);
        m_pRecordBuf = new BYTE[this->GetRecordLength()+1024];
        _fmemset(m_pRecordBuf,' ',this->GetRecordLength()+1024);
        m_pRecordBuf[GetRecordLength()]='\0';
        //Reset Record Point
        m_lRecordPoint=0;
        //Malloc Foxpro Fields
        DELETE(m_pFoxproFields);
        m_pFoxproFields = new FOXPRO_FIELDS[1+this->GetFieldsCount()];
        _fmemset(m_pFoxproFields,0,sizeof(FOXPRO_FIELDS)*(1+this->GetFieldsCount()));
        //Fill FoxproFields
        ::fseek(m_pFile,sizeof(FOXPRO_HEAD),SEEK_SET);
        nFields = this->GetFieldsCount();
        for(i=0;i<nFields;i++)
        {
                ::fread(&m_pFoxproFields,sizeof(FOXPRO_FIELDS),1,m_pFile);
        }

        return(TRUE);
}

char*  CFoxpro::TrimLeft(char  *pStr)
{
        //if(_fstrlen(pStr)>=256) return(pStr);
        while(pStr[0]==' '||pStr[0]=='\x9')
        {
                int nLength=_fstrlen(pStr);
                if(!nLength) break;
                if(nLength) _fmemcpy(&pStr[0],&pStr[1],nLength);
        }
        return(pStr);
}

char*  CFoxpro::TrimRight(char *pStr)
{
        //if(_fstrlen(pStr)>=256) return(pStr);
        int nLength=_fstrlen(pStr);
        if(!nLength) return(pStr);
        for(int i=nLength-1;i>=0;i--)
        {
                if(pStr!=' '&&pStr!='\x9') break;
                pStr='\0';
        }

        return(pStr);
}

FOXPRO_FIELDS*  CFoxpro::GetFoxproFields(int nIndex)
{
        ::_fmemset(&m_FoxproFields,0,sizeof(FOXPRO_FIELDS));
        //----------------------------------------------------
        //Calc Fields
        int nFields=this->GetFieldsCount();
        if(nIndex>=nFields||nFields<0) return(&m_FoxproFields);
        return(&m_pFoxproFields[nIndex]);
}

BOOL  CFoxpro::GetFieldsString(int nIndex,char* pStr)
{
        int nFields=this->GetFieldsCount();
        if(nIndex<0||nIndex>=nFields||nFields<0) return(FALSE);

        m_FoxproFields = *(this->GetFoxproFields(nIndex));
        if(m_FoxproFields.byStyle!='C') return(FALSE);
        if(!m_pRecordBuf) return(FALSE);

        int nAddress = (WORD)m_FoxproFields.dwDataAddress;
        _fmemcpy(pStr,&m_pRecordBuf[nAddress],m_FoxproFields.byLength);
        if(m_FoxproFields.byLength)
        {
                pStr[m_FoxproFields.byLength] = '\0';
        }
        this->TrimRight(pStr);

        return(TRUE);
}

float  CFoxpro::GetFieldsNumber(int nIndex)
{
        char buf[120];
        int nFields=this->GetFieldsCount();
        if(nIndex<0||nIndex>=nFields||nFields<0) return(FALSE);

        m_FoxproFields = *(this->GetFoxproFields(nIndex));

        if(m_FoxproFields.byStyle!='N') return(FALSE);
        if(!m_pRecordBuf) return(FALSE);

        int nAddress = (WORD)m_FoxproFields.dwDataAddress;
        _fmemcpy(buf,&m_pRecordBuf[nAddress],m_FoxproFields.byLength);
        buf[m_FoxproFields.byLength] = '\0';
        return(atof(buf));
}

BOOL  CFoxpro::GetFieldsDate(int nIndex,int* pnYear,int* pnMonth,int* pnDay)
{
        char buf1[20],buf2[20];
        int nFields=this->GetFieldsCount();
        if(nIndex<0||nIndex>=nFields||nFields<0) return(FALSE);

        m_FoxproFields = *(this->GetFoxproFields(nIndex));

        if(m_FoxproFields.byStyle!='D') return(FALSE);
        if(!m_pRecordBuf) return(FALSE);

        int nAddress = (WORD)m_FoxproFields.dwDataAddress;
        _fmemcpy(buf1,&m_pRecordBuf[nAddress],m_FoxproFields.byLength);
        buf1[m_FoxproFields.byLength] = '\0';

        buf2[0]=buf1[0];
        buf2[1]=buf1[1];
        buf2[2]=buf1[2];
        buf2[3]=buf1[3];
        buf2[4]='\0';
        *pnYear =(int)(atof(buf2)+0.5f);

        buf2[0]=buf1[4];
        buf2[1]=buf1[5];
        buf2[2]='\0';
        *pnMonth =(int)(atof(buf2)+0.5f);

        buf2[0]=buf1[6];
        buf2[1]=buf1[7];
        buf2[2]='\0';
        *pnDay =(int)(atof(buf2)+0.5f);

        return(TRUE);
}

BOOL  CFoxpro::GetFieldsLogic(int nIndex)
{
        char buf[10];
        int nFields=this->GetFieldsCount();
        if(nIndex<0||nIndex>=nFields||nFields<0) return(FALSE);

        m_FoxproFields = *(this->GetFoxproFields(nIndex));

        if(m_FoxproFields.byStyle!='L') return(FALSE);
        if(!m_pRecordBuf) return(FALSE);

        int nAddress = (WORD)m_FoxproFields.dwDataAddress;
        _fmemcpy(buf,&m_pRecordBuf[nAddress],m_FoxproFields.byLength);
        buf[m_FoxproFields.byLength] = '\0';
        if(buf[0]=='T')  return(TRUE);
        return(FALSE);
}

BOOL  CFoxpro::GetFieldsMemo(int /*nIndex*/,char* /*pStr*/)
{
        return(TRUE);
}

BOOL  CFoxpro::SetFieldsString(int nIndex, const char* pStr)
{
        int nFields=this->GetFieldsCount();
        if(nIndex<0||nIndex>=nFields||nFields<0) return(FALSE);

        m_FoxproFields = *(this->GetFoxproFields(nIndex));

        if(m_FoxproFields.byStyle!='C') return(FALSE);
        if(!m_pRecordBuf) return(FALSE);

        int nAddress = (WORD)m_FoxproFields.dwDataAddress;
        int nLength1 = _fstrlen(pStr);
        int nLength2 = (WORD)m_FoxproFields.byLength;
        for(int i=0;i<nLength2;i++)
        {
                if(i>=nLength1)
                {
                        m_pRecordBuf[nAddress+i]=' ';
                }
                else
                {
                        m_pRecordBuf[nAddress+i]=*(pStr+i);
                }
        }


        //::fseek(m_pFile,this->GetRecordAddress(),SEEK_SET);
        //::fseek(m_pFile,m_lRecordPoint*GetRecordLength(),SEEK_CUR);
        //::fseek(m_pFile,nAddress,SEEK_CUR);
        return(TRUE);
}
BOOL  CFoxpro::SetFieldsNumber(int nIndex,float fValue)
{
        char buf[100];
        int nFields=this->GetFieldsCount();
        if(nIndex<0||nIndex>=nFields||nFields<0) return(FALSE);

        m_FoxproFields = *(this->GetFoxproFields(nIndex));

        if(m_FoxproFields.byStyle!='N') return(FALSE);
        if(!m_pRecordBuf) return(FALSE);


        if(m_FoxproFields.byDotCount==0) sprintf(buf,"%.0f",fValue);
        else if(m_FoxproFields.byDotCount==1) sprintf(buf,"%.1f",fValue);
        else if(m_FoxproFields.byDotCount==2) sprintf(buf,"%.2f",fValue);
        else if(m_FoxproFields.byDotCount==3) sprintf(buf,"%.3f",fValue);
        else if(m_FoxproFields.byDotCount==4) sprintf(buf,"%.4f",fValue);
        else if(m_FoxproFields.byDotCount==5) sprintf(buf,"%.5f",fValue);
        else  sprintf(buf,"%.6f",fValue);

        int nAddress = (WORD)m_FoxproFields.dwDataAddress;
        int nLength1 = _fstrlen(buf);
        int nLength2 = (WORD)m_FoxproFields.byLength;
        for(int i=0;i<nLength2;i++)
        {
                if(i>=nLength1)
                {
                        m_pRecordBuf[nAddress+i]=' ';
                }
                else
                {
                        m_pRecordBuf[nAddress+i]=buf;
                }
        }

        return(TRUE);
}
BOOL  CFoxpro::SetFieldsDate(int nIndex,int nYear,int nMonth,int nDay)
{
        int nFields=this->GetFieldsCount();
        if(nIndex<0||nIndex>=nFields||nFields<0) return(FALSE);

        m_FoxproFields = *(this->GetFoxproFields(nIndex));

        if(m_FoxproFields.byStyle!='D') return(FALSE);
        if(!m_pRecordBuf) return(FALSE);

        int nAddress = (WORD)m_FoxproFields.dwDataAddress;
        //sprintf((char *)&m_pRecordBuf[nAddress],"%4d%2d%2d%",nYear,nMonth,nDay);
        //m_pRecordBuf[nAddress+8]=' ';
        char buf[40];
        sprintf(buf,"%4d%2d%2d",nYear,nMonth,nDay);
        for(int i=0;i<8;i++)
        {       
                m_pRecordBuf[nAddress+i] = buf;
        }


        return(TRUE);
}
BOOL  CFoxpro::SetFieldsLogic(int nIndex,BOOL bLogic)
{
        int nFields=this->GetFieldsCount();
        if(nIndex<0||nIndex>=nFields||nFields<0) return(FALSE);

        m_FoxproFields = *(this->GetFoxproFields(nIndex));

        if(m_FoxproFields.byStyle!='L') return(FALSE);
        if(!m_pRecordBuf) return(FALSE);

        int nAddress = (WORD)m_FoxproFields.dwDataAddress;
        if(bLogic) m_pRecordBuf[nAddress]='T';
        else m_pRecordBuf[nAddress]='F';

        return(TRUE);
}
BOOL  CFoxpro::SetFieldsMemo(int nIndex, const char* /*pStr*/)
{
        int nFields=this->GetFieldsCount();
        if(nIndex<0||nIndex>=nFields||nFields<0) return(FALSE);

        m_FoxproFields = *(this->GetFoxproFields(nIndex));

        if(m_FoxproFields.byStyle!='M') return(FALSE);
        if(!m_pRecordBuf) return(FALSE);

        //int nAddress = (WORD)m_FoxproFields.dwDataAddress;
        //((DWORD *)&m_pRecordBuf[nAddress])=(BYTE)chLogic;

        return(TRUE);
}

BOOL  CFoxpro::Seek(long nIndex,int nMode)
{
        if(!m_pFile) return(FALSE);

        if(nMode==SEEK_SET)      m_lRecordPoint = nIndex;
        else if(nMode==SEEK_CUR) m_lRecordPoint+= nIndex;
        else if(nMode==SEEK_END)
        {
                m_lRecordPoint = GetRecordCount();
                m_lRecordPoint+= nIndex;
        }
        ::fseek(m_pFile,this->GetRecordAddress(),SEEK_SET);
        ::fseek(m_pFile,m_lRecordPoint*GetRecordLength(),SEEK_CUR);

        if(m_lRecordPoint<this->GetRecordCount())
        {
                ::fread(m_pRecordBuf,this->GetRecordLength(),1,m_pFile);
                m_pRecordBuf[GetRecordLength()]='\0';
                ::fseek(m_pFile,0L-GetRecordLength(),SEEK_CUR);
        }

        return(TRUE);
}

BOOL  CFoxpro::Delete()
{
        if(!m_pFile) return(FALSE);
        if(!m_pRecordBuf) return(FALSE);

        if(m_lRecordPoint>=this->GetRecordCount()) return(FALSE);

        this->Edit();
        m_pRecordBuf[0]='*';
        this->Update();

        return(TRUE);
}

BOOL  CFoxpro::Zap()
{
        if(!m_pFile) return(FALSE);
        if(!this->GetRecordCount()) return(TRUE);


        long lRecordCount  = this->GetRecordCount();
        long lRecordLength = this->GetRecordLength();

        long lLocation=0;
        for(long i=0;i<lRecordCount;i++)
        {
                ::fseek(m_pFile,this->GetRecordAddress(),SEEK_SET);
                ::fseek(m_pFile,i*lRecordLength,SEEK_CUR);

                ::fread(m_pRecordBuf,lRecordLength,1,m_pFile);
                if(m_pRecordBuf[0] != '*')
                {
                        ::fseek(m_pFile,this->GetRecordAddress(),SEEK_SET);
                        ::fseek(m_pFile,lLocation*lRecordLength,SEEK_CUR);
                        ::fwrite(m_pRecordBuf,lRecordLength,1,m_pFile);
                        lLocation++;
                }
        }
        this->m_FoxproHead.dwRecordCount=lLocation;

        ::fseek(m_pFile,0,SEEK_SET);
        ::fwrite(&m_FoxproHead,sizeof(FOXPRO_HEAD),1,m_pFile);

        long lFileLength = sizeof(FOXPRO_HEAD)+
                1L*sizeof(FOXPRO_FIELDS)*this->GetFieldsCount()+
                1L+
                1L*this->m_FoxproHead.dwRecordCount*lRecordLength;


        ::chsize(fileno(m_pFile),lFileLength);
        ::fseek(m_pFile,0,SEEK_END);
        ::fwrite("\x1A",1,1,m_pFile);

        m_lRecordPoint=0L;

        this->Seek(m_lRecordPoint,SEEK_SET);
        this->Edit();
        return(TRUE);
}

BOOL  CFoxpro::DeleteEx()
{
        if(!m_pFile) return(FALSE);

        if(m_lRecordPoint>=this->GetRecordCount()) return(FALSE);


        long lRecordCount  = this->GetRecordCount();
        long lRecordLength = this->GetRecordLength();

        for(long i=m_lRecordPoint+1;i<lRecordCount;i++)
        {
                ::fseek(m_pFile,this->GetRecordAddress(),SEEK_SET);
                ::fseek(m_pFile,i*lRecordLength,SEEK_CUR);

                ::fread(m_pRecordBuf,lRecordLength,1,m_pFile);

                ::fseek(m_pFile,-2L*lRecordLength,SEEK_CUR);
                ::fwrite(m_pRecordBuf,lRecordLength,1,m_pFile);
        }

        this->m_FoxproHead.dwRecordCount-=1;
        ::fseek(m_pFile,0,SEEK_SET);
        ::fwrite(&m_FoxproHead,sizeof(FOXPRO_HEAD),1,m_pFile);
        long lFileLength = sizeof(FOXPRO_HEAD)+
                1L*sizeof(FOXPRO_FIELDS)*this->GetFieldsCount()+
                1L+
                1L*this->m_FoxproHead.dwRecordCount*lRecordLength;


        ::chsize(fileno(m_pFile),lFileLength);
        ::fseek(m_pFile,0,SEEK_END);
        ::fwrite("\x1A",1,1,m_pFile);

        if(m_lRecordPoint && m_lRecordPoint==this->GetRecordCount())
        {
                m_lRecordPoint-=1;
        }
        //------------------------------------------------------------
        this->Seek(m_lRecordPoint,SEEK_SET);
        this->Edit();
        return(TRUE);
}

BOOL  CFoxpro::Insert()
{
        return(TRUE);
}

BOOL  CFoxpro::AddNew()
{
        if (NULL == m_pFile)
        {
                return(FALSE);
        }
        m_lRecordPoint = this->GetRecordCount();
        _fmemset(m_pRecordBuf,' ',this->GetRecordLength()+1024);
        this->Seek(0,SEEK_END);
        m_bNew = TRUE;

        return(TRUE);
}

BOOL  CFoxpro::Edit()
{
        if(NULL == m_pFile)
        {
                return(FALSE);
        }
        if (m_bNew)
        {
                return(TRUE);
        }

        this->Seek(m_lRecordPoint,SEEK_SET);
        ::fread(m_pRecordBuf,this->GetRecordLength(),1,m_pFile);
        m_pRecordBuf[GetRecordLength()]='\0';

        return(TRUE);
}
BOOL  CFoxpro::Update()
{
        if (NULL == m_pFile) return(FALSE);

        if(m_bNew)
        {
                m_lRecordPoint = this->GetRecordCount();
        }

        ::fseek(m_pFile,this->GetRecordAddress(),SEEK_SET);
        ::fseek(m_pFile,m_lRecordPoint*GetRecordLength(),SEEK_CUR);
        ::fwrite(m_pRecordBuf,this->GetRecordLength(),1,m_pFile);

        if (m_bNew)
        {
                //::fseek(m_pFile, 0, SEEK_END);
                fwrite("\x1A",1,1,m_pFile);

                rewind(m_pFile);
                m_FoxproHead.dwRecordCount += 1;
                ::fwrite(&m_FoxproHead,sizeof(FOXPRO_HEAD),1,m_pFile);
        }
        m_bNew = FALSE;
        return(TRUE);
}

BOOL  CFoxpro::IsOpen()
{
        return(((m_pFile)?TRUE:FALSE));
}

BOOL CFoxpro::Flush()
{
        if (NULL == m_pFile)
        {
                return(FALSE);
        }
        ::fflush(m_pFile);

        int duphandle = ::dup(fileno(m_pFile));

        ::close(duphandle);

        return(TRUE);
}

[ Last edited by firstsail on 2018-7-14 at 12:38 ]
作者: firstsail     时间: 2018-7-14 12:15
//下面是Symbol2.h文件



#ifndef  _SYMBOL2_H_
#define  _SYMBOL2_H_

#ifndef                TRUE
#define                TRUE        1
#endif
#ifndef                FALSE
#define                FALSE        0
#endif
#ifndef         NULL
#define         NULL 0
#endif



        #define _fmemcpy memcpy
        #define _fstrcpy strcpy
        #define _fstricmp stricmp
        #define _fstrcmp  strcmp
        #define _fstrlen  strlen
        #define _fmemset  memset

        #define farmalloc malloc
        #define farfree   free

#define  pi 3.1415926
#define CONST_SINGLE_T    3.14159f
#define CONST_DOUBLE_T    3.14159265359

typedef     char*   LPCTSTR;
typedef     void*   LPVOID;
typedef                int                COLOR;
typedef                int                HANDLE;
typedef                unsigned int        WORD;
typedef                unsigned char        BYTE;
typedef                int                BOOL;
typedef     unsigned long        DWORD;
typedef         DWORD           SORT;
typedef         int                 BOOL;
typedef         unsigned int    BOOLEN;
typedef           int                HWND;
typedef                DWORD                WPARAM;
typedef DWORD                LPARAM;
typedef long                LONG;
typedef long*       LPLONG;
typedef void        VOID;
typedef        DWORD        ULONG;
typedef         float                FLOAT;
typedef         int                INT;
typedef signed   short  SHORT;
typedef unsigned short  USHORT;
typedef unsigned short  WCHAR;



#define DELETE(a) {if ((a) != NULL) delete (a); (a) = NULL;}



#define  MAX(a,b)  ((a>b)?a:b)
#define  MIN(a,b)  ((a<b)?a:b)

#define SHIFT8(a)   ((a)<<8)
#define SHIFT16(a)  ((a)<<16)
#define LOBYTE(a)   ((BYTE)((a)&0xFF))
#define HIBYTE(a)   ((((DWORD)(a))>>8)&0xFF)
#define LOWORD(a)   ((WORD)((WORD)(((DWORD)(a))&0xFFFFL)))
#define HIWORD(a)   ((WORD)((((DWORD)(a))>>16)&0xFFFFL))


#endif

[ Last edited by firstsail on 2018-7-14 at 12:37 ]
作者: firstsail     时间: 2019-5-24 11:57
近期美国政府打压并插手谷歌、高通公司与华为及大僵等科技公司的合作事件,在嵌入式场合的中国企业,突然被外国企业和外国政府掐住了脖子,国人这才逐渐意识到:掌握中国人自主研发的嵌入式系统有多么的重要和紧迫。

现在的WinSail实时嵌入式系统,目前是一款免费可供下载的软件系统,可在http://www.firstsail.com.cn/Software.html网页中下载,其于2004年推向市场,至今已经过15年的市场考验,成功运用到各种嵌入式领域中,并被各行各业广泛大量的下载使用。
作者: firstsail     时间: 2019-12-13 09:13
谢天谢地,自己忘了密码后,多谢论坛坛主wengierwu先生,帮我把和密码恢复回来了。老用户忘了密码,可找wengierwu@hotmail.com请求恢复

[ Last edited by firstsail on 2019-12-13 at 09:15 ]
作者: firstsail     时间: 2020-2-17 12:02
7年后,更新了下载版本

http://www.firstsail.com.cn/Software.html