主窗体label.Text中的内容随时跟着子程序中变量的值改变

137867312 2015-11-13 03:39:37
项目中有一个主窗体,一个类库,主窗体调用类库中的方法实现网络连接,主窗体中的一个label随时体现网络连接的变化,当网络连接正常时label中的字体变成绿色,如果在运行过程中网络连接断开,label字体就变红色。我的做法是:类库中的网络连接状态给出一个静态标志位IsConnect,但是需要在主窗体中写一个死循环来随时检测IsConnect的状态,太耗资源了,有没有更好的方法?求各位大牛给出一个思路!
...全文
176 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
137867312 2015-11-13
  • 打赏
  • 举报
回复
学习了3、4楼,仿照4楼写了如下代码,不知道是否正确? 网络连接类库的委托
public class NetStateEvent
    {
        public delegate void IsConnectChange(object sender, EventArgs e);
        public event IsConnectChange OntempChange;
        bool IsConnect = false;     //网络连接是否成功的标志位,初始值false
        public bool isConnect
        {
            get { return IsConnection; }
            set
            {
                if (IsConnection == true)
                {
                    OntempChange(this, new EventArgs());
                }
                isConnect = value;
            }
        }
    }
主窗体的函数调用
 public  MainForm()
        {
            netStateEvent.OntempChange += new NetStateEvent.IsConnectChange(netStateEvent_OntempChange);//使用+=运算符将事件绑定给函数
            InitializeComponent();           
        }

private void netStateEvent_OntempChange(object sender, EventArgs e)
        {
            label1.Text = "网络已连接";
            label1.ForeColor = Color.Blue;
        }
exception92 2015-11-13
  • 打赏
  • 举报
回复
委托,子窗口:

 public delegate void DelegateSetText(string value);
        public event DelegateSetText SetTextEvent; // 定义事件
        /// <summary>
        /// 触发事件
        /// </summary>
        /// <param name="value"></param>
        private void RaiseEvent(string value)
        {
            if (SetTextEvent != null)
                SetTextEvent(value);
        }

        /// <summary>
        /// 发送
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button1_Click(object sender, EventArgs e)
        {
            // this.textBox1.Text
            RaiseEvent("点击了:" + (sender as Button).Text);
        }
父窗口:

TargetForm frm = new TargetForm();
            frm.SetTextEvent += new TargetForm.DelegateSetText(frm_SetTextEvent);
            frm.Show();


void frm_SetTextEvent(string value)
        {
            // 处理value 值
        }
crystal_lz 2015-11-13
  • 打赏
  • 举报
回复
引用 2 楼 crystal_lz 的回复:
事件通知。。。。

public class Test{//你的自定义类
    public delegate void StatusChangedEventHandler(object obj,StatusChangedEventArgs e);
    public event StatusChangedEventHandler StatusChanged;
    protected virtual void OnStatusChanged(StatusChangedEventArgs e){
        if (this.StatusChanged != null) this.StatusChanged(e);
    }
    
    public enum Status{ Close }
    
    //在你内里面 状态改变的时候 调用这个
    this.OnStatusChanged(new StatusChangedEventArgs("your log"));
    
    public class StatusChangedEventArgs : EventArgs{
        private Status _Status;
        public Status Status{
            get{ return _Status; }
        }
        
        public StatusChangedEventArgs(Status s){
            this._Status = s;
        }
    }
}
//====调用
Test t = new Test();
t.StatusChanged += new StatusChangedEventHandler(test_StatusChanged);

private void test_StatusChanged(object obj,StatusChangedEventArgs e){
    //这里事件会被触发自己YY吧
}
crystal_lz 2015-11-13
  • 打赏
  • 举报
回复
事件通知。。。。
runerback 2015-11-13
  • 打赏
  • 举报
回复
DataBinding
      课程设计题目    学生成绩管理系统 课程设计的目的   理解面向对象的软件设计基本理论,学习VB软件设计的基本方法,熟悉一般软件项目开发的基本步骤,培养运用VB解决实际问题的能力和技巧。 课程设计的内容和要求(包括原始数据、技术参数、设计要求、工作量要求等) 四、工作进度安排 2011-2012学年第19周。 五、要参考文献 Visual Basic程序设计教程 审核批准意见                                           系任(签字)    年  月  日     指导教师评语及成绩 指 导 教 师 评 语                           成 绩                                    导师签字: 年 月 日                    设计思路及其创建过程    一、任务概述     简易学生成绩管理系统要完成学生成绩的管理,包括:    1)、添加信息模块:要完成学生记录、课程记录、学生成绩和用户记录的添加工作。    2)、删除信息模块:要完成学生记录、课程记录、学生成绩和用户记录的删除工作。    3)、修改成绩模块:要完成学生成绩的修改工作。    4)、查询模块:要完成学生成绩的查询工作。    1.进行数据库设计     要编写一个实用的数据库程序,必须系统地学习过数据库原理的知识,并首先设计出符合用户业务需求的数据库系,然后才能利用某种语言,开发出针对这个数据库的交互程序:数据库应用程序。    2. 程序的要功能    利用SQL语句完成对学生成绩表的插入、修改、删除和查询操作。比如:    (1)插入记录:    Insert Into 学生成绩表(学号,课程号,成绩)    Values(‘001’,’001’,85)    (2)删除记录    Delete From 学生成绩表    Where 学号=‘001’ And 课程号=‘001’    (3)修改记录    Update 学生成绩表 set 成绩 =90    Where 学号=‘001’ And 课程号=‘001’    (4)按学号查询    Select * From 学生成绩表 Where 学号=‘001’    二、界面设计    1.创建工程    新建一“标准EXE”工程.工程名为“成绩查询”.    2.创建(frmMain)-MDI    设计菜单:    增加 删除 修改 查询 退出    增加学生记录 删除学生记录 修改成绩    增加课程记录 删除课程记录    增加成绩 删除成绩记录    增加用户 删除用户 3.创建新增学生记录(frmAddStudent)-MDI子 4、建新增课程记录(frmAddCourse)-MDI子 5.创建新增成绩记录(frmAddGrade)-MDI子 6.创建新增用户记录(frmAddUser)-MDI子 7. 创建修改记录( frmUpdate )-MDI子 8.创建删除学生记录(frmDeleteStudent)-MDI子 9.创建删除课程记录(frmDeleteCourse)-MDI子 10.创建删除成绩记录(frmDeleteGrade)-MDI子 11.创建删除用户(frmDelete)-MDI子 12.创建查询记录(frmQuery)-MDI子 13.创建身份验证-MDI子 1.3 代码设计 1. 连接数据库代码 步骤: (1)通过“工程—引用”菜单添加对象库: Microsoft Activex Data Objects 2.7 Library (Ado数据对象)。 (2)通过工程菜单添加一个标准模块(Module),并设计代码。 (3) 通过“工程—工程1属性”菜单,将(frmMain)MDIform1设置为启动对象。 添加标准模块代码: '声明全局对象变量ABOcn,用于创建于数据库的连接 Public ADOcn As New ADODB.Connection 添加初始化过程代码: Private Sub MDIForm_Initialize() ADOcn.ConnectionString = "Provider=SQLOLEDB.1;Password=;User ID=sa;Initial Catalog=成绩;Data Source= localhost;" If ADOcn.State = adStateClosed Then ADOcn.Open '打开到数据库的连接 End Sub 完成本项工作后,就创建了一个全局变量ADOcn,但它是一个特殊的变量,其数据类型是数据连接对象(Connection对象)。可以把ADDcn理解成是一个虚拟的数据库。或者称为VB程序的逻辑数据库,通过它可以非常方便地访问其的数据。换句话说,ADOcn是VB程序的后台数据库交互的通道。 2.设置间的调用关系 2.设置间的调用关系 ’调用增加课程 Private Sub AddCourse_Click(Index As Integer) frmAddCourse.Show End Sub ’调用增加成绩 Private Sub AddGrade_Click(Index As Integer) FrmAdd.Show End Sub ’调用增加学生 Private Sub AddStudent_Click(Index As Integer) FrmAddStudent.Show End Sub ’调用增加用户 Private Sub AddUser_Click() FrmAddUser.Show End Sub ’调用删除课程 Private Sub DeleteCourse_Click() frmDeleteCourse.Show End Sub ’调用删除成绩 Private Sub DeleteGrade_Click() frmDelete.Show End Sub ’调用删除学生 Private Sub DeleteStudent_Click() frmDeleteStudent.Show End Sub ’调用删除用户 Private Sub DeleteUser_Click() frmDeleteUser.Show End Sub ’调用学生基本信息查询 Private Sub Querystudent_Click() frmQuerystudent.Show End Sub ’调用学生成绩查询 Private Sub QueryGrade_Click() frmQueryGrade.Show End Sub’调用修改成绩 Private Sub Update_Click() FrmUpdate.Show End Sub 调用退出程序 Private Sub Exit_Click() End End Sub 3.frmAddStudent (增加学生)的代码设计: Private Sub Command1_Click() Dim ADOrs As New Recordset '声明一个记录集对象 Dim strSQL As String ADOrs.ActiveConnection = ADOcn '与ADOcn连接对象关联 If Text1.Text = "" Then MsgBox "未输入学号,请重新输入数据!", vbCritical + vbOKOnly Text1.SetFocus '定位光标 Exit Sub End If If Text2.Text = "" Then MsgBox "未输入姓名,请重新输入数据!", vbCritical + vbOKOnly Text2.SetFocus '定位光标 Exit Sub End If '首先查询表是否存在关键字相同的记录 strSQL = "select * from 学生情况表" strSQL = strSQL & " Where 学号='" + Text1.Text + " '" strSQL = strSQL & " and 姓名='" + Text2.Text + "'" ADOrs.Open strSQL '如果关键字重复,则退出 If Not ADOrs.EOF Then MsgBox "该记录已经存在,不能继续增加", vbCritical + vbOKOnly Exit Sub End If '拼写Insert插入语句 strSQL = "Insert Into 学生情况表(学号,姓名)" strSQL = strSQL + " Values('" + Text1.Text + "'," strSQL = strSQL + "'" + Text2.Text + "'" + ")" ADOcn.Execute strSQL '执行Insert语句 Text1.Text = "“ '初始化文本框控件 Text2.Text = "" Text1.SetFocus '定位光标 MsgBox "已成功添加新记录", vbQuestion + vbOKOnly ADOrs.Close '关闭记录集 Set ADOrs = Nothing End Sub Private Sub Command2_Click() Unload Me End Sub 4.frmAddCourse (增加课程)的代码设计: (1)在Load事件,进行初始化工作,代码如下: Private Sub Form_Load() '初始化文本框控件 Text1.Text = "" Text2.Text = "" End Sub (2)’Command1_Click()(”确定”按钮)事件代码 Private Sub Command1_Click() Dim ADOrs As New Recordset '声明一个记录集对象 Dim strSQL As String '与ADOcn连接对象关联 ADOrs.ActiveConnection = ADOcn If Text1.Text = "" Then MsgBox "未输入课程号,请重新输入数据!", vbCritical + vbOKOnly Text1.SetFocus '定位光标 Exit Sub End If If Text2.Text = "" Then MsgBox "未输入课程名,请重新输入数据!", vbCritical + vbOKOnly Text2.SetFocus '定位光标 Exit Sub End If ’Command1_Click()(”确定”按钮)事件代码 '首先查询表是否存在关键字相同的记录 strSQL = "select * from 课程情况表" strSQL = strSQL & " Where 课程号='" + Text1.Text + " '" strSQL = strSQL & " and 课程名='" + Text2.Text + "'" ADOrs.Open strSQL '如果关键字重复,则退出 If Not ADOrs.EOF Then MsgBox "该记录已经存在,不能继续增加", vbCritical + vbOKOnly Exit Sub End If ’Command1_Click()(”确定”按钮)事件代码 '拼写Insert插入语句 strSQL = "Insert Into 学生情况表(学号,姓名)" strSQL = strSQL + " Values('" + Text1.Text + "'," strSQL = strSQL + "'" + Text2.Text + "'" + ")" ADOcn.Execute strSQL '执行Insert语句 Text1.Text = "“ '初始化文本框控件 Text2.Text = "" Text1.SetFocus '定位光标 MsgBox "已成功添加新记录", vbQuestion + vbOKOnly ADOrs.Close '关闭记录集 Set ADOrs = Nothing End Sub (3)’Command2_Click()(”返回”按钮)事件代码 Private Sub Command2_Click() Unload Me End Sub 5.frmAddGrade(增加成绩)的代码设计: (1)在Load事件,进行初始化工作,代码如下: Private Sub Form_Load() Dim ADOrs As New Recordset '声明记录集对象 ADOrs.ActiveConnection = ADOcn '与ADOcn连接对象关联 '对Combo1组合框进行初始化 ADOrs.Open "Select 学号 From 学生情况表 Order By 学号" Combo1.Clear Do While Not ADOrs.EOF Combo1.AddItem Trim(ADOrs.Fields("学号")) '添加"学号"字段 ADOrs.MoveNext '取下一条记录 Loop ADOrs.Close '关闭记录集 (1)Load事件代码 '对Combo2组合框进行初始化 ADOrs.Open "select 课程号 from 课程情况表 Order By 课程号" Combo2.Clear Do While Not ADOrs.EOF Combo2.AddItem Trim(ADOrs.Fields("课程号")) '添加"课程号"字段 ADOrs.MoveNext '取下一条记录 Loop ADOrs.Close '关闭记录集 '初始化文本框控件 Text1.Text = "" Text2.Text = "" Text3.Text = "0" End Sub (2) Combo1_Click 事件代码 Private Sub Combo1_Click() Dim ADOrs As New Recordset '声明一个记录集对象 ADOrs.ActiveConnection = ADOcn '与ADOcn连接对象关联 '如果输入了学号,则把姓名显示在Text1.Text strSQL = "select * from 学生情况表" strSQL = strSQL + " Where 学号='" + Combo1.Text + " '" ADOrs.Open strSQL Text1.Text = ADOrs.Fields("姓名") ADOrs.Close '关闭记录集 Set ADOrs = Nothing End Sub (3) Combo2_Click 事件代码 Private Sub Combo2_Click() Dim ADOrs As New Recordset '声明一个记录集对象 ADOrs.ActiveConnection = ADOcn '与ADOcn连接对象关联 '如果输入了课程号,则把课程名显示在Text2.text strSQL = "select * from 课程情况表" strSQL = strSQL + " Where 课程号='" + Combo2.Text + " '" ADOrs.Open strSQL Text2.Text = ADOrs.Fields("课程名") ADOrs.Close '关闭记录集 Set ADOrs = Nothing End Sub (4) Command1_Click(确认) 事件代码 Private Sub Command1_Click() Dim strSQL As String Dim ADOrs As New Recordset '声明一个记录集对象 ADOrs.ActiveConnection = ADOcn '与ADOcn连接对象关联 '检查学号与课程号是否输入 If Combo1.Text = "" Or Combo2.Text = "" Then MsgBox "输入数据不全,请重新输入数据!", vbCritical + vbOKOnly Exit Sub End If '首先查询表是否存在关键字相同的记录 strSQL = "select * from 学生成绩表" strSQL = strSQL & " Where 学号='" + Combo1.Text + " '" strSQL = strSQL & " and 课程号='" + Combo2.Text + "'" ADOrs.Open strSQL '如果关键字重复,则退出 If Not ADOrs.EOF Then MsgBox "该记录已经存在,不能继续增加", vbCritical + vbOKOnly Exit Sub End If (4) Command1_Click(确认) 事件代码 '拼写Insert插入语句 strSQL = "Insert Into 学生成绩表(学号,课程号,成绩)" strSQL = strSQL + "Values('" + Combo1.Text + "','" strSQL = strSQL + Combo2.Text + "'," + Str(Val(Text3.Text)) + ")" ADOcn.Execute strSQL '执行Insert语句 MsgBox "已成功添加新记录", vbQuestion + vbOKOnly '初始化文本框控件 Text1.Text = "" Text2.Text = "" Text3.Text = "0" ADOrs.Close '关闭记录集 Set ADOrs = Nothing End Sub (5) Command2_Click(返回) 事件代码 Private Sub Command2_Click() Unload Me End Sub 6.frmAddUser(增加用户)代码设计 (1)在Load事件,进行初始化工作,代码如下: Private Sub Form_Load() '初始化文本框控件 Text1.Text = "" Text2.Text = "" Text3.Text = "" End Sub (2) Command1_Click(确认) 事件代码 Private Sub Command1_Click() Dim strSQL As String Dim ADOrs As New Recordset '声明一个记录集对象 ADOrs.ActiveConnection = ADOcn '与ADOcn连接对象关联 '记录已输入的用户信息 UserName = Text1.Text PaasWord = Text2.Text PaasWord1 = Text3.Text '若 Text1.TextText2.TextText3.Text为空则提示用户重新输入 If Text1.Text = "" Or Text2.Text = "" Or Text3.Text = "" Then MsgBox "未输入用户名、密码或密码确认,请重新输入!", vbCritical + vbOKOnly Exit Sub End If '若 两此输入密码不一致则提示用户重新输入 If PaasWord PaasWord1 Then MsgBox "两次输入的密码不一致,请重新输入!", vbCritical + vbOKOnly Text2.Text = "" Text3.Text = "" Text2.SetFocus Exit Sub End If '首先查询用户是否存在相同的记录 strSQL = "Select * From 用户" strSQL = strSQL + " Where 用户名='" + UserName + "'" ADOrs.Open strSQL If Not ADOrs.EOF Then '如果关键字重复,则退出 MsgBox "该用户已经存在,请重新注册", vbCritical + vbOKOnly Exit Sub End If '拼写Insert插入语句 strSQL = "Insert Into 用户(用户名,密码)" strSQL = strSQL + " Values('" + UserName + "','" + PaasWord + "')" ADOcn.Execute strSQL '执行Insert语句 MsgBox "已成功添加新记录", vbQuestion + vbOKOnly ADOrs.Close '关闭记录集 Set ADOrs = Nothing End Sub (3) Command2_Click(返回) 事件代码 Private Sub Command2_Click() Unload Me End Sub 7.frmUpdata (修改成绩)代码设计 (1)、在Load事件,进行初始化工作,代码如下: Private Sub Form_Load() Dim ADOrs As New Recordset '声明记录集对象 ADOrs.ActiveConnection = ADOcn '与ADOcn连接对象关联 '对Combo1组合框进行初始化 ADOrs.Open "Select 学号 From 学生情况表 Order By 学号" Combo1.Clear Do While Not ADOrs.EOF Combo1.AddItem Trim(ADOrs.Fields("学号")) '添加"学号"字段 ADOrs.MoveNext '取下一条记录 Loop ADOrs.Close '关闭记录集 (1)、Form_Load()事件代码 '对Combo2组合框进行初始化 ADOrs.Open "select 课程号 from 课程情况表 Order By 课程号" Combo2.Clear Do While Not ADOrs.EOF Combo2.AddItem Trim(ADOrs.Fields("课程号")) '添加"课程号"字段 ADOrs.MoveNext '取下一条记录 Loop ADOrs.Close '关闭记录集 '初始化文本框控件 Text1.Text = "" Text2.Text = "" Text3.Text = "0" End Sub (2) Combo1_Click 事件代码 Private Sub Combo1_Click() Dim ADOrs As New Recordset '声明一个记录集对象 ADOrs.ActiveConnection = ADOcn '与ADOcn连接对象关联 '如果输入了学号,则把姓名显示在Text1.Text strSQL = "select * from 学生情况表" strSQL = strSQL + " Where 学号='" + Combo1.Text + " '" ADOrs.Open strSQL Text1.Text = ADOrs.Fields("姓名") ADOrs.Close '关闭记录集 (2) Combo1_Click 事件代码 If Combo2 "" Then '输入完毕则显示成绩信息 '查询学生成绩表是否有指定指定学号与课程号的记录 strSQL = "select * from 学生成绩表" strSQL = strSQL & " Where 学号='" + Combo1.Text + " '" strSQL = strSQL & " and 课程号='" + Combo2.Text + "'" ADOrs.Open strSQL If ADOrs.EOF Then MsgBox "学生成绩表在不存在学号为" + Combo1.Text + "课程号为" + Combo2.Text + "的记录,请重新输入!", vbCritical + vbOKOnly Text1.Text = "" Text3.Text = "" Exit Sub Else Text3.Text = ADOrs.Fields("成绩") End If End If If ADOrs.State = adStateOpen Then ADOrs.Close '关闭记录集 Set ADOrs = Nothing End Sub (3) Combo2_Click 事件代码 Private Sub Combo2_Click() Dim ADOrs As New Recordset '声明一个记录集对象 ADOrs.ActiveConnection = ADOcn '与ADOcn连接对象关联 '如果输入了课程号,则把课程名显示在Text2.text strSQL = "select * from 课程情况表" strSQL = strSQL + " Where 课程号='" + Combo2.Text + " '" ADOrs.Open strSQL Text2.Text = ADOrs.Fields("课程名") ADOrs.Close '关闭记录集 (3) Combo2_Click 事件代码 If Combo1 "" Then '输入完毕则显示成绩信息 '查询学生成绩表是否有指定指定学号与课程号的记录 strSQL = "select * from 学生成绩表" strSQL = strSQL & " Where 学号='" + Combo1.Text + " '" strSQL = strSQL & " and 课程号='" + Combo2.Text + "'" ADOrs.Open strSQL If ADOrs.EOF Then MsgBox "学生成绩表在不存在学号为" + Combo1.Text + "课程号为" + Combo2.Text + "的记录,请重新输入!", vbCritical + vbOKOnly Text2.Text = "" Text3.Text = "" Exit Sub Else Text3.Text = ADOrs.Fields("成绩") End If End If If ADOrs.State = adStateOpen Then ADOrs.Close '关闭记录集 Set ADOrs = Nothing End Sub (4)、 Command1_Click()(修改/确认按钮)事件代码 Private Sub Command1_Click() Dim strSQL As String Dim ADOrs As New Recordset '声明一个记录集对象 ADOrs.ActiveConnection = ADOcn '与ADOcn连接对象关联 '检查学号与课程号是否输入 If Combo1.Text = "" Or Combo2.Text = "" Then MsgBox "输入数据不全,请重新输入数据!", vbCritical + vbOKOnly Exit Sub End If (4)、 Command1_Click()(修改/确认按钮)事件代码 '根据当前按钮文字的不同进行相关处理 If Command1.Caption = "修改" Then Command1.Caption = "确认" Command2.Caption = "放弃" Else Command1.Caption = "修改" Command2.Caption = "返回" '拼写Update语句,以便进行修改 strSQL = "Update 学生成绩表" strSQL = strSQL + " Set 成绩=" + Text3.Text strSQL = strSQL + " Where 学号='" + Combo1.Text + "'" strSQL = strSQL + " And 课程号='" + Combo2.Text + " '" ADOcn.Execute strSQL '执行Updata语句 MsgBox "修改成功!", vbQuestion + vbOKOnly End If If ADOrs.State = adStateOpen Then ADOrs.Close '关闭记录集 Set ADOrs = Nothing End Sub (5) Command2_Click(返回/放弃) 事件代码 Private Sub Command2_Click() If Command2.Caption = "返回" Then Unload Me Else Command2.Caption = "返回" Command1.Caption = "修改" End If End Sub 8.frmDeleteStudent (删除学生)的代码设计 (1)、Form_Load()事件代码 Private Sub Form_Load() Dim ADOrs As New Recordset '声明记录集对象 ADOrs.ActiveConnection = ADOcn '与ADOcn连接对象关联 '对Combo1组合框进行初始化 ADOrs.Open "select 学号 from 学生情况表 Order By 学号" Combo1.Clear Do While Not ADOrs.EOF Combo1.AddItem Trim(ADOrs.Fields("学号")) '添加"学号"字段 ADOrs.MoveNext '取下一条记录 Loop ADOrs.Close '关闭记录集 '对Combo2组合框进行初始化 ADOrs.Open "select 姓名 from 学生情况表 Order By 学号" Combo2.Clear Do While Not ADOrs.EOF Combo2.AddItem Trim(ADOrs.Fields("姓名")) '添加"姓名"字段 ADOrs.MoveNext '取下一条记录 Loop ADOrs.Close '关闭记录集 End Sub (2) Combo1_Click 事件代码 Private Sub Combo1_Click() Dim ADOrs As New Recordset '声明一个记录集对象 ADOrs.ActiveConnection = ADOcn '与ADOcn连接对象关联 '若选择了学号则将姓名自动填写到Combo2.Text ADOrs.Open "Select 姓名 From 学生情况表 Where 学号 ='" + Combo1.Text + "'" If ADOrs.EOF Then MsgBox "学生情况表没有学号为" + Combo1.Text + "的记录,请重新输入!", vbQuestion + vbOKOnly Combo1.Text = "" Exit Sub Else Combo2.Text = ADOrs.Fields("姓名") End If ADOrs.Close '关闭记录集 End Sub (3) Combo2_Click 事件代码 Private Sub Combo2_Click() Dim ADOrs As New Recordset '声明一个记录集对象 ADOrs.ActiveConnection = ADOcn '与ADOcn连接对象关联 '若选择了姓名则将学号自动填写到Combo1.Text ADOrs.Open "Select 学号 From 学生情况表 Where 姓名 ='" + Combo2.Text + "'" If ADOrs.EOF Then MsgBox "学生情况表没有姓名为" + Combo2.Text + "的记录,请重新输入!", vbQuestion + vbOKOnly Combo1.Text = "" Exit Sub Else Combo1.Text = ADOrs.Fields("学号") End If ADOrs.Close '关闭记录集 End Sub (4)、 Command1_Click()(确定按钮)事件代码 Private Sub Command1_Click() Dim ADOrs As New Recordset '声明记录集对象 Dim ADOrs1 As New Recordset '声明记录集对象 ADOrs.ActiveConnection = ADOcn '与ADOcn连接对象关联 ADOrs1.ActiveConnection = ADOcn '与ADOcn连接对象关联 '若学号和姓名同时为空则提示用户重新输入 If Combo1.Text = "" And Combo2.Text = "" Then MsgBox "学号和姓名不能同时为空,请重新输入!", vbQuestion + vbOKOnly Exit Sub End If (4)、 Command1_Click()(确定按钮)事件代码 '若输入了学号则将姓名自动填写到Combo2.Text If Combo1.Text "" And Combo2.Text = "" Then ADOrs.Open "Select 姓名 From 学生情况表 Where 学号 ='" + Combo1.Text + "'" If ADOrs.EOF Then MsgBox "学生情况表没有学号为" + Combo1.Text + "的记录,请重新输入!", vbQuestion + vbOKOnly Combo1.Text = "" Exit Sub Else Combo2.Text = ADOrs.Fields("姓名") End If If ADOrs.State = adStateOpen Then ADOrs.Close '关闭记录集 End If (4)、 Command1_Click()(确定按钮)事件代码 '若输入了号姓名则将学号自动填写到Combo1.Text If Combo2.Text "" And Combo1.Text = "" Then ADOrs1.Open "Select 学号 From 学生情况表 Where 姓名='" + Combo2.Text + "'" If ADOrs1.EOF Then MsgBox "学生情况表没有姓名为" + Combo2.Text + "的记录,请重新输入!", vbQuestion + vbOKOnly Combo2.Text = "" Exit Sub Else Combo1.Text = ADOrs1.Fields("学号") End If If ADOrs1.State = adStateOpen Then ADOrs1.Close '关闭记录集 End If '查询学生情况表是否有指定学号和指定姓名的记录 If Combo1.Text "" And Combo2.Text "" Then ADOrs.Open "Select * From 学生情况表 Where 学号='" + Combo1.Text + "'" + " And 姓名='" + Combo2.Text + "'" If ADOrs.EOF Then MsgBox "学生情况表没有学号为" + Combo1.Text + "且姓名为" + Combo2.Text + "的记录,请重新输入!", vbQuestion + vbOKOnly Combo1.Text = "" Combo2.Text = "" Exit Sub Else Combo1.Text = ADOrs.Fields("学号") Combo2.Text = ADOrs.Fields("姓名") End If If ADOrs.State = adStateOpen Then ADOrs.Close '关闭记录集 End If End Sub (5)、 Command2_Click()(确认按钮)事件代码 Private Sub Command2_Click() Dim xm As String Dim xh As String Dim strSQL As String Dim ADOrs As New Recordset '声明记录集对象 ADOrs.ActiveConnection = ADOcn '与ADOcn连接对象关联 '如果学号与姓名同时为空则提示重新输入/选择 If Combo1.Text = "" Or Combo2.Text = "" Then MsgBox "学号和姓名不能为空,请重新输入!", vbQuestion + vbOKOnly Else xh = Combo1.Text xm = Combo2.Text If MsgBox("删除学号为" + xh + "姓名为" + xm + "的学生记录,该学生在学生成绩表的全部记录也将一起删除,是否继续?", vbQuestion + vbYesNo) = vbYes Then '拼写Delete学生成绩表指定记录语句 strSQL = "Delete From 学生成绩表" strSQL = strSQL + " Where 学号='" + Combo1.Text + "'" ADOcn.Execute strSQL '执行Delete语句 '拼写Delete学生情况表指定记录语句 strSQL = "Delete From 学生情况表" strSQL = strSQL + " Where 学号='" + Combo1.Text + "'" ADOcn.Execute strSQL '执行Delete语句 MsgBox "删除成功!", vbQuestion + vbOKOnly Combo1.Text = "" Combo2.Text = "" End If End If If ADOrs.State = adStateOpen Then ADOrs.Close '关闭记录集 End Sub (6)、 Command3_Click()(返回按钮)事件代码 Private Sub Command3_Click() Unload Me End Sub 9. frmDeleteCourse(删除课程)代码设计 (1)、Form_Load()事件代码 Private Sub Form_Load() Dim ADOrs As New Recordset '声明记录集对象 ADOrs.ActiveConnection = ADOcn '与ADOcn连接对象关联 '对Combo1组合框进行初始化 ADOrs.Open "select 课程号 from 课程情况表 Order By 课程号" Combo1.Clear Do While Not ADOrs.EOF Combo1.AddItem Trim(ADOrs.Fields("课程号")) '添加"课程号"字段 ADOrs.MoveNext '取下一条记录 Loop ADOrs.Close '关闭记录集 '对Combo2组合框进行初始化 ADOrs.Open "select 课程名 from 课程情况表 Order By 课程号" Combo2.Clear Do While Not ADOrs.EOF Combo2.AddItem Trim(ADOrs.Fields("课程名")) '添加"课程名"字段 ADOrs.MoveNext '取下一条记录 Loop ADOrs.Close '关闭记录集 End Sub (2) Combo1_Click 事件代码 Private Sub Combo1_Click() Dim ADOrs As New Recordset '声明一个记录集对象 ADOrs.ActiveConnection = ADOcn '与ADOcn连接对象关联 '若选择了课程号则将课程名自动填写到Combo2.Text ADOrs.Open "Select 课程名 From 课程情况表 Where 课程号 ='" + Combo1.Text + "'" If ADOrs.EOF Then MsgBox "课程情况表没有课程号为" + Combo1.Text + "的记录,请重新输入!", vbQuestion + vbOKOnly Combo1.Text = "" Exit Sub Else Combo2.Text = ADOrs.Fields("课程名") End If ADOrs.Close '关闭记录集 End Sub (3) Combo2_Click 事件代码 Private Sub Combo2_Click() Dim ADOrs As New Recordset '声明一个记录集对象 ADOrs.ActiveConnection = ADOcn '与ADOcn连接对象关联 '若选择了课程名则将课程号自动填写到Combo1.Text ADOrs.Open "Select 课程号 From 课程情况表 Where 课程名 ='" + Combo2.Text + "'" If ADOrs.EOF Then MsgBox "课程情况表没有课程名为" + Combo2.Text + "的记录,请重新输入!", vbQuestion + vbOKOnly Combo1.Text = "" Exit Sub Else Combo1.Text = ADOrs.Fields("课程号") End If ADOrs.Close '关闭记录集 End Sub (4)、 Command1_Click()(确定按钮)事件代码 Private Sub Command1_Click() Dim ADOrs As New Recordset '声明记录集对象 Dim ADOrs1 As New Recordset '声明记录集对象 ADOrs.ActiveConnection = ADOcn '与ADOcn连接对象关联 ADOrs1.ActiveConnection = ADOcn '与ADOcn连接对象关联 '若课程号和课程名同时为空则提示用户重新输入 If Combo1.Text = "" And Combo2.Text = "" Then MsgBox "课程号和课程名不能同时为空,请重新输入!", vbQuestion + vbOKOnly Exit Sub End If (4)、 Command1_Click()(确定按钮)事件代码 '若输入了课程号则将课程名自动填写到Combo2.Text If Combo1.Text "" And Combo2.Text = "" Then ADOrs.Open "Select 课程名 From 课程情况表 Where 课程号 ='" + Combo1.Text + "'" If ADOrs.EOF Then MsgBox "课程情况表没有课程号为" + Combo1.Text + "的记录,请重新输入!", vbQuestion + vbOKOnly Combo1.Text = "" Exit Sub Else Combo2.Text = ADOrs.Fields("课程名") End If If ADOrs.State = adStateOpen Then ADOrs.Close '关闭记录集 End If (4)、 Command1_Click()(确定按钮)事件代码 '若输入了课程名则将课程号自动填写到Combo1.Text If Combo2.Text "" And Combo1.Text = "" Then ADOrs1.Open "Select 课程号 From 课程情况表 Where 课程名='" + Combo2.Text + "'" If ADOrs1.EOF Then MsgBox "课程情况表没有课程名为" + Combo2.Text + "的记录,请重新输入!", vbQuestion + vbOKOnly Combo2.Text = "" Exit Sub Else Combo1.Text = ADOrs1.Fields("课程号") End If If ADOrs1.State = adStateOpen Then ADOrs1.Close '关闭记录集 End If (4)、 Command1_Click()(确定按钮)事件代码 '查询课程情况表是否有指定课程号和指定课程名的记录 If Combo1.Text "" And Combo2.Text "" Then ADOrs.Open "Select * From 课程情况表 Where 课程号='" + Combo1.Text + "'" + " And 课程名='" + Combo2.Text + "'" If ADOrs.EOF Then MsgBox "课程情况表没有课程号为" + Combo1.Text + "且课程名为" + Combo2.Text + "的记录,请重新输入!", vbQuestion + vbOKOnly Combo1.Text = "" Combo2.Text = "" Exit Sub Else Combo1.Text = ADOrs.Fields("课程号") Combo2.Text = ADOrs.Fields("课程名") End If If ADOrs.State = adStateOpen Then ADOrs.Close '关闭记录集 End If End Sub (5)、 Command2_Click()(确认按钮)事件代码 Private Sub Command2_Click() Dim xm As String Dim xh As String Dim strSQL As String Dim ADOrs As New Recordset '声明记录集对象 ADOrs.ActiveConnection = ADOcn '与ADOcn连接对象关联 '如果课程号与课程名同时为空则提示重新输入/选择 If Combo1.Text = "" Or Combo2.Text = "" Then MsgBox "课程号和课程名不能为空,请重新输入!", vbQuestion + vbOKOnly Else xh = Combo1.Text xm = Combo2.Text If MsgBox("删除课程号为" + xh + "课程名为" + xm + "的课程记录,该课程在学生成绩表的全部记录也将一起删除,是否继续?", vbQuestion + vbYesNo) = vbYes Then (5)、 Command2_Click()(确认按钮)事件代码 '拼写Delete学生成绩表指定记录语句 strSQL = "Delete From 学生成绩表" strSQL = strSQL + " Where 课程号='" + Combo1.Text + "'" ADOcn.Execute strSQL '执行Delete语句 '拼写Delete课程情况表指定记录语句 strSQL = "Delete From 课程情况表" strSQL = strSQL + " Where 课程号='" + Combo1.Text + "'" ADOcn.Execute strSQL '执行Delete语句 MsgBox "删除成功!", vbQuestion + vbOKOnly Combo1.Text = "" Combo2.Text = "" End If End If If ADOrs.State = adStateOpen Then ADOrs.Close '关闭记录集 End Sub (6)、 Command3_Click()(返回按钮)事件代码 Private Sub Command3_Click() Unload Me End Sub 10. frmDeleteGrade (删除成绩)代码设计 (1)、Form_Load()事件代码 Private Sub Form_Load() Dim ADOrs As New Recordset '声明记录集对象 ADOrs.ActiveConnection = ADOcn '与ADOcn连接对象关联 '对Combo1组合框进行初始化 ADOrs.Open "Select 学号 From 学生情况表 Order By 学号" Combo1.Clear Do While Not ADOrs.EOF Combo1.AddItem Trim(ADOrs.Fields("学号")) '添加"学号"字段 ADOrs.MoveNext '取下一条记录 Loop ADOrs.Close '关闭记录集 '对Combo2组合框进行初始化 ADOrs.Open "select 课程号 from 课程情况表 Order By 课程号" Combo2.Clear Do While Not ADOrs.EOF Combo2.AddItem Trim(ADOrs.Fields("课程号")) '添加"课程号"字段 ADOrs.MoveNext '取下一条记录 Loop ADOrs.Close '关闭记录集 'End Sub (2) Combo1_Click 事件代码 Private Sub Combo1_Click() Dim ADOrs As New Recordset '声明一个记录集对象 ADOrs.ActiveConnection = ADOcn '与ADOcn连接对象关联 '如果输入了学号,则把姓名显示在Text1.Text strSQL = "select * from 学生情况表" strSQL = strSQL + " Where 学号='" + Combo1.Text + " '" ADOrs.Open strSQL Text1.Text = ADOrs.Fields("姓名") ADOrs.Close '关闭记录集 (2) Combo1_Click 事件代码(续) If Combo2 "" Then '输入完毕则显示成绩信息 '查询学生成绩表是否有指定指定学号与课程号的记录 strSQL = "select * from 学生成绩表" strSQL = strSQL & " Where 学号='" + Combo1.Text + " '" strSQL = strSQL & " and 课程号='" + Combo2.Text + "'" ADOrs.Open strSQL If ADOrs.EOF Then MsgBox "学生成绩表在不存在学号为" + Combo1.Text + "课程号为" + Combo2.Text + "的记录,请重新输入!", vbCritical + vbOKOnly Text1.Text = "" Text3.Text = "" Exit Sub Else Text3.Text = ADOrs.Fields("成绩") End If End If If ADOrs.State = adStateOpen Then ADOrs.Close '关闭记录集 Set ADOrs = Nothing End Sub (3) Combo2_Click 事件代码 Private Sub Combo2_Click() Dim ADOrs As New Recordset '声明一个记录集对象 ADOrs.ActiveConnection = ADOcn '与ADOcn连接对象关联 '如果输入了课程号,则把课程名显示在Text2.text strSQL = "select * from 课程情况表" strSQL = strSQL + " Where 课程号='" + Combo2.Text + " '" ADOrs.Open strSQL Text2.Text = ADOrs.Fields("课程名") ADOrs.Close '关闭记录集 (3) Combo2_Click 事件代码(续) If Combo1 "" Then '输入完毕则显示成绩信息 '查询学生成绩表是否有指定指定学号与课程号的记录 strSQL = "select * from 学生成绩表" strSQL = strSQL & " Where 学号='" + Combo1.Text + " '" strSQL = strSQL & " and 课程号='" + Combo2.Text + "'" ADOrs.Open strSQL If ADOrs.EOF Then MsgBox "学生成绩表在不存在学号为" + Combo1.Text + "课程号为" + Combo2.Text + "的记录,请重新输入!", vbCritical + vbOKOnly Text2.Text = "" Text3.Text = "" Exit Sub Else Text3.Text = ADOrs.Fields("成绩") End If End If If ADOrs.State = adStateOpen Then ADOrs.Close '关闭记录集 Set ADOrs = Nothing End Sub (4)、 Command1_Click()(确定按钮)事件代码 Private Sub Command1_Click() Dim strSQL As String Dim ADOrs As New Recordset '声明一个记录集对象 ADOrs.ActiveConnection = ADOcn '与ADOcn连接对象关联 Dim ADOrs1 As New Recordset '声明一个记录集对象 ADOrs1.ActiveConnection = ADOcn '与ADOcn连接对象关联 Dim ADOrs2 As New Recordset '声明一个记录集对象 ADOrs2.ActiveConnection = ADOcn '与ADOcn连接对象关联 ‘如果学号为空则提示用户重新输入 If Combo1.Text = "" Then MsgBox "学号不能为空,请重新输入!", vbQuestion + vbOKOnly Combo1.Text = "" Text1.Text = "" Exit Sub End If (4)、 Command1_Click()(确定按钮)事件代码---续 '如果课程号为空则提示拥护重新输入 If Combo2.Text = "" Then MsgBox "课程号不能为空,请重新输入!", vbQuestion + vbOKOnly Combo2.Text = "" Text2.Text = "" Exit Sub End If '查询学生情况表是否有指定学号的记录 If Combo1.Text "" Then ADOrs1.Open "Select 姓名 From 学生情况表 Where 学号='" + Combo1.Text + "'" If ADOrs1.EOF Then MsgBox “学生情况表没有学号为” + Combo1.Text + “的记录,请重新输入!”, vbQuestion + vbOKOnly Combo1.Text = "" Text1.Text = "" Exit Sub Else '若有指定学号的学生记录,则将姓名字段填写到text1 Text1.Text = ADOrs1.Fields("姓名") End If End If '查询课程情况表是否有指定课程号的记录 If Combo2.Text "" Then ADOrs2.Open "Select 课程名 From 课程情况表 Where 课程号='" + Combo2.Text + "'" If ADOrs2.EOF Then MsgBox "课程情况表没有课程号为" + Combo2.Text + "的记录,请重新输入!", vbQuestion + vbOKOnly Combo2.Text = "" Text2.Text = "" Exit Sub Else '若有指定课程号的课程记录,则将课程名字段填写到text2 Text2.Text = ADOrs2.Fields("课程名") End If End If '查询学生表是否有指定学号与课程号的记录 If Combo1 "" And Combo1 "" Then strSQL = "select * from 学生成绩表" strSQL = strSQL & " Where 学号='" + Combo1.Text + " '" strSQL = strSQL & " and 课程号='" + Combo2.Text + "'" ADOrs.Open strSQL If ADOrs.EOF Then MsgBox "学生成绩表在不存在学号为" + Combo1.Text + "课程号为" + Combo2.Text + "的记录,请重新输入!", vbCritical + vbOKOnly Combo1.Text = "" Combo2.Text = "" Text1.Text = "" Text2.Text = "" Text3.Text = "" Exit Sub Else Text3.Text = Val(ADOrs.Fields("成绩")) End If End If End Sub 5)、 Command2_Click()(确认按钮)事件代码 Private Sub Command2_Click() If MsgBox("是否要删除学号为" + Combo1.Text + "课程号为" + Combo2.Text + "的成绩记录?", vbQuestion + vbYesNo) = vbYes Then '拼写Delete语句 strSQL = "Delete From 学生成绩表" strSQL = strSQL + " Where 学号='" + Combo1.Text + "'" strSQL = strSQL + " And 课程号='" + Combo2.Text + "'" ADOcn.Execute strSQL '执行Delete语句 Combo1.Text = "" Combo2.Text = "" Text1.Text = "" Text2.Text = "" Text3.Text = "" MsgBox "删除成功!", vbQuestion + vbOKOnly End If End Sub (6)、 Command3_Click()(返回按钮)事件代码 Private Sub Command3_Click() Unload Me End Sub 11. frmDeleteUser(删除用户)代码设计 (1)、 Command1_Click()(确定按钮)事件代码 Private Sub Command1_Click() '定义变量,建立与数据库的连接 Dim strSQL As String Dim ADOrs2 As New Recordset ADOrs2.ActiveConnection = ADOcn If Trim(Text1.Text) = "" Then MsgBox "请输入用户名!", , "删除用户" Text1.SetFocus Exit Sub End If If Trim(Text2.Text) = "" Then MsgBox "请输入用户密码!", , "删除用户" Text2.SetFocus Exit Sub End If '查询是否有指定用户名和密码的记录 ADOrs2.Open "Select * From 用户 Where 用户名='" + Text1.Text + "'" + " And 密码='" + Text2.Text + "'" If ADOrs2.EOF Then MsgBox "用户没有名为:" + Text1.Text + " 密码为:" + Text2.Text + "的记录,请重新输入!", vbQuestion + vbOKOnly Text1.Text = "" Text2.Text = "" Text1.SetFocus Else If MsgBox("是否删除用户名为“" + Text1.Text + "”密码为“" + Text2.Text + "”的用户记录?", vbQuestion + vbYesNo) = vbYes Then '拼写Delete用户指定记录语句 strSQL = "Delete From 用户 Where 用户名='" + Text1.Text + "'" + " And 密码='" + Text2.Text + "'" ADOcn.Execute strSQL '执行Delete语句 MsgBox "删除成功!", vbQuestion + vbOKOnly Text1.Text = "" Text2.Text = "" Text1.SetFocus End If End If End Sub (2)、 Command2_Click()(返回按钮)事件代码 Private Sub Command2_Click() Unload Me End Sub 12. frmQuerystudent(学生基本信息查询)代码设计 使用ado数据控件与DataGrid数据绑定控件实现 (1)、Form_Load()事件代码 Private Sub Form_Load() Combo1.Text = "全部学生" '默认查询全部学生 Label2.Caption = "全部学生数据浏览表格:" Label1.Visible = False Text1.Visible = False End Sub 说明:这里使用ado数据控件adodc1与DataGrid数据绑定控件DataGrid1,并已设置好adodc属性---查询数据库的表格(学生情况表)。 (2) Combo1_Click 事件代码 Private Sub Combo1_Click() Select Case Combo1.ListIndex '根据选择的组合框项进行处理 Case 0 '选择“全部学生”时隐藏提示信息 strSQL = "select * from 学生情况表" Adodc1.CommandType = adCmdText Adodc1.RecordSource = strSQL Adodc1.Refresh Label2.Caption = "全部学生数据浏览表格:“ DataGrid1.Visible = True Label1.Visible = False Text1.Visible = False Case 1 '选择“按学号查询”时给出提示并定位光标 Label1.Visible = True Text1.Visible = True Text1.SetFocus Label1.Caption = "请输入学号并按回车键确认:" Case 2 '选择“按姓名查询”时给出提示并定位光标 Label1.Visible = True Text1.Visible = True Text1.SetFocus Label1.Caption = "请输入姓名并按回车键确认:" End Select End Sub (3) Text1_KeyPress 事件代码 Private Sub Text1_KeyPress(KeyAscii As Integer) Dim atrsql As String If KeyAscii = 13 Then Select Case Combo1.ListIndex '根据选择的组合框项进行处理 Case 1 '选择“按学号查询”时 strSQL = "select * from 学生情况表 where 学号='" & Trim(Text1.Text) & "'" Adodc1.CommandType = adCmdText Adodc1.RecordSource = strSQL Adodc1.Refresh If Adodc1.Recordset.EOF Then '没有找到时 Label2.Caption = "" DataGrid1.Visible = False MsgBox "没有该生记录信息,请检查你输入的学号是否正确!" Else '找到时 Label2.Caption = "学号为" & Text1.Text & "的学生数据浏览表格:" DataGrid1.Visible = True End If Text1.Text = "" Case 2 '选择“按姓名查询”时 strSQL = "select * from 学生情况表 where 姓名='" & Trim(Text1.Text) & "'" Adodc1.CommandType = adCmdText Adodc1.RecordSource = strSQL Adodc1.Refresh If Adodc1.Recordset.EOF Then '没有找到时 Label2.Caption = "" DataGrid1.Visible = False MsgBox "没有该生记录信息,请检查你输入的姓名是否正确!" Else '找到时 Label2.Caption = "姓名为" & Text1.Text & "的学生数据浏览表格:" DataGrid1.Visible = True End If Text1.Text = "" End Select End If End Sub (4) Command1_Click(返回按钮)事件代码 Private Sub Command1_Click() Unload Me End Sub 13. frmQueryGrade(学生成绩查询)代码设计 使用MSFlexGrid1控件(编程模型)实现 (1)、Form_Load()事件代码 Private Sub Form_Load() Dim ADOrs As New Recordset '声明一个记录集对象 ADOrs.ActiveConnection = ADOcn '与ADOcn连接对象关联 MSFlexGrid1.Visible = False '隐藏MSFlexGrid1控件 '对Combo1组合框进行初始化 ADOrs.Open "select 学号 from 学生情况表 Order By 学号" Combo1.Clear Do While Not ADOrs.EOF Combo1.AddItem Trim(ADOrs.Fields("学号")) '添加"学号"字段 ADOrs.MoveNext '取下一条记录 Loop ADOrs.Close '关闭记录集对象 Text1.Text = "" End Sub (2) Combo1_Click 事件代码 Private Sub Combo1_Click() Dim ADOrs As New Recordset '声明一个记录集对象 ADOrs.ActiveConnection = ADOcn '与ADOcn连接对象关联 '若选择了学号则将姓名自动填写到text1 ADOrs.Open "Select 姓名 From 学生情况表 Where 学号 ='" & Combo1.Text & "'" If ADOrs.EOF Then MsgBox "学生情况表没有学号为" & Combo1.Text & "的记录,请重新输入!", vbQuestion & vbOKOnly Text1.Text = "" Else Text1.Text = ADOrs.Fields("姓名") End If ADOrs.Close '关闭记录集 End Sub (3) Command1_Click(确定按钮)事件代码 Private Sub Command1_Click() Dim strSQL As String, strSQL2 As String Dim strRecord As String Dim ADOrs As New Recordset '声明记录集对象 Dim ADOrs2 As New Recordset ADOrs.ActiveConnection = ADOcn '与ADOcn连接对象关联 ADOrs2.ActiveConnection = ADOcn strSQL = "select * from 学生情况表 Where 学号='" & Combo1.Text & " '" ADOrs.Open strSQL If ADOrs.EOF Then MsgBox ("数据库找不到学号为" & Combo1.Text & "的记录,请重新输入!") Combo1.Text = "" Text1.Text = "" Else Text1.Text = ADOrs.Fields("姓名") End If '拼写Select语句 strSQL2 = "Select 学生成绩表.学号,学生成绩表.课程号,学生成绩表.成绩," strSQL2 = strSQL2 & "学生情况表.姓名,课程情况表.课程名" strSQL2 = strSQL2 & " From 学生成绩表,学生情况表,课程情况表" strSQL2 = strSQL2 & " Where 学生成绩表.学号=学生情况表.学号" strSQL2 = strSQL2 & " And 学生成绩表.课程号=课程情况表.课程号" strSQL2 = strSQL2 & " And 学生成绩表.学号= '" & Combo1.Text & "'" ADOrs2.Open strSQL2 '执行Select语句 If ADOrs2.EOF = True Then MSFlexGrid1.Visible = False '隐藏MSFlexGrid1控件 MsgBox "没有该生成绩!" Else '初始化MSFlexGrid表格 MSFlexGrid1.Rows = 0 '行数 MSFlexGrid1.Cols = 5 '列数 MSFlexGrid1.ColWidth(3) = 1500 '调节第4列宽度 MSFlexGrid1.Visible = True '显示MSFlexGrid1控件 '设置表格标题栏 strRecord = "学号" & vbTab & "姓名" & vbTab & "课程号" strRecord = strRecord & vbTab & "课程名" & vbTab & "成绩" MSFlexGrid1.AddItem strRecord '从第一条记录开始循环,直至表尾,填写表格内容 Do While Not ADOrs2.EOF '拼写表格内容 strRecord = Trim(ADOrs2.Fields("学号")) & vbTab & Trim(ADOrs2.Fields("姓名")) & vbTab strRecord = strRecord & Trim(ADOrs2.Fields("课程号")) & vbTab & Trim(ADOrs2.Fields("课程名")) strRecord = strRecord & vbTab & Trim(Str(ADOrs2.Fields("成绩"))) MSFlexGrid1.AddItem strRecord '向表格内添加行 ADOrs2.MoveNext '取下一条记录 Loop End If ADOrs.Close '关闭记录集对象 ADOrs2.Close '释放记录集对象 Set ADOrs = Nothing Set ADOrs2 = Nothing End Sub (4) Command2_Click(返回按钮)事件代码 Private Sub Command2_Click() Unload Me End Sub 14.身份验证(frmlogin)代码设计 1)、Form_Initialize()事件代码 Private Sub Form_Initialize() ADOcn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=成绩.MDB" If ADOcn.State = adStateClosed Then ADOcn.Open '打开到数据库的连接 End Sub 2)、Command1_Click()事件代码—登录按钮 Private Sub Command1_Click() Dim ADOrs As New Recordset '声明记录集对象 Dim strSQL As String ADOrs.ActiveConnection = ADOcn '与连接对象adocn关联 If Trim(Text1.Text) = "" Or Trim(Text2.Text) = "" Then '检验用户名与密码为空否 MsgBox "帐号和密码不能为空,请重新填写", vbOKOnly + vbInformation Exit Sub End If strSQL = "select * from 用户 where 用户名='" + Trim(Text1.Text) + "'" ADOrs.Open strSQL '按用户名查询 If ADOrs.EOF Then '找不到该用户 MsgBox "用户不存在", vbCritical + vbOKOnly Text1.Text = "" Text1.SetFocus Exit Sub ElseIf Trim(Text2.Text) ADOrs.Fields(“密码”) Then ‘找到用户后检验密码 MsgBox "密码不正确", vbOKOnly + vbInformation Text2.Text = "" Text2.SetFocus Exit Sub End If '用户登录成功,记录用户类型参数 usertype = ADOrs.Fields("用户类型") Unload Me MDIForm1.Show '登录成功,打开MDI ADOrs.Close Set ADOrs = Nothing End Sub 3)、Command2_Click()事件代码—退出按钮 Private Sub Command2_Click() ADOcn.Close Set ADOcn = Nothing Unload Me End Sub 4)、登录成功并打开MDI后,应根据人员类型设置菜单权限 Private Sub MDIForm_Load() '根据人员类型设置菜单权限 Select Case usertype 'Case "管理员" Case "查询人员" addmenu.Enabled = False deletemenu.Enabled = False Updata.Enabled = False End Select End Sub 1.4 其他 一、用户自定义函数的使用 1、初始化大小及显示座标函数 Public Sub init(frmname As Object, X As Integer, Y As Integer) frmname.Width = X frmname.Height = Y frmname.Left = (MDIForm1.Width - frmname.Width) / 2 frmname.Top = (MDIForm1.Height - frmname.Height) / 2 End Sub 2、校验输入的文本框字符是否为数字或backspace回格键函数 ,’如果是则返回true,否则返回false Public Function in_int(KeyAscii As Integer) As Boolean Dim Accept_int(10) As String '可接受的字符数组 Accept_int(0) = "0" Accept_int(1) = "1" Accept_int(2) = "2" Accept_int(3) = "3" Accept_int(4) = "4" Accept_int(5) = "5" Accept_int(6) = "6" Accept_int(7) = "7" Accept_int(8) = "8" Accept_int(9) = "9" Accept_int(10) = Chr(8) 'Chr(8)是backspace键对应的字符 in_int = False For i = 1 To 10 '检查输入的字符是否在数组 If Chr(KeyAscii) = Accept_int(i) Then in_int = True End If Next i End Function
没法下载,到这里折腾一把试试。 本文由abc2253130贡献 doc文档可能在WAP端浏览验不佳。建议您优先选择TXT,或下载源文件到本机查看。 C#(WINFORM)学习 一、 C#基础 基础 类型和变量 类型和变量 类型 C# 支持两种类型:“类型”和“引用类型”。类型包括简单类型(如 char、int 和 float 等)、枚举类型和结构类型。引用类型包括类 (Class)类 型、接口类型、委托类型和数组类型。 变量的类型声明 变量的类型声明 每个变量必须预先声明其类型。如 int a; int b = 100; float j = 4.5; string s1; 用 object 可以表示所有的类型。 预定义类型 下表列出了预定义类型,并说明如何使用。 类型 object 说明 所有其他类型的最终 基类型 字符串类型; 字符串是 Unicode 字符序列 8 位有符号整型 16 位有符号整型 32 位有符号整型 64 位有符号整型 示例 object o = null; 范围 string sbyte short int long string s = "hello"; sbyte val = 12; short val = 12; int val = 12; long val1 = 12; -128 到 127 -32,768 到 32,767 -2,147,483,648 2,147,483,647 -9,223,372,036,854,775,808 到 第1页 C#(WINFORM)学习 long val2 = 34L; 到 9,223,372,036,854,775,807 byte ushort 8 位无符号整型 16 位无符号整型 byte val1 = 12; ushort val1 = 12; uint val1 = 12; uint 32 位无符号整型 uint val2 = 34U; ulong val1 = 12; ulong val2 = 34U; ulong 64 位无符号整型 ulong val3 = 56L; ulong val4 = 78UL; float 单精度浮点型 float val = 1.23F;7 位 double val1 = 1.23; double 双精度浮点型 double val2 = ±5.0 × 10?324 ±1.7 × 10 308 0 到 255 0 到 65,535 0 到 4,294,967,295 0 到 18,446,744,073,709,551,615 ±1.5 × 10?45 ±3.4 × 10 38 到 到 4.56D;15-16 布尔型;bool 或为 真或为假 字符类型;char 是 一个 Unicode 字符 精确的小数类型, 具有 28 个有效数字 bool val1 = true; bool val2 = false; char val = 'h'; decimal val = bool char decimal DateTime ±1.0 × 10?28 ±7.9 × 10 28 到 1.23M;28-29 变量转换 简单转换: float f = 100.1234f; 可以用括号转换: short s = (short)f 也可以利用 Convert 方法来转换: string s1; s1=Convert.ToString(a); MessageBox.Show(s1); 常用 Convert 方法有: 第2页 C#(WINFORM)学习 C# Convert.ToBoolean Convert.ToByte Convert.ToChar Convert.ToDateTime Convert.ToDecimal Convert.ToDouble Convert.ToInt16 Convert.ToInt32 Convert.ToInt64 Convert.ToSByte Convert.ToSingle Convert.ToString Convert.ToUInt16 Convert.ToUInt32 Convert.ToUInt64 备注 Math 类 常用科学计算方法: C# Math.Abs Math.Sqrt Math.Ro
要改协议,,高手帮下忙。。在线等。
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Messaging;
using System.Net.Sockets;
using System.Text;
using System.Runtime.InteropServices;
using System.IO;
using System.Threading ;
using System.Net;

namespace GprsServer
{
///
/// Form1 的摘要说明。
///

public class GprsServer : System.Windows.Forms.Form
{
///
/// 必需的设计器变量
///


[DllImport("User32.dll",EntryPoint="SendMessage")]
private static extern int
SendMessage(
int hWnd, // handle to destination window
int Msg, // message
int wParam, // first message parameter
string lParam // second message parameter
);
[DllImport("User32.dll",EntryPoint="FindWindow")]
private static extern int FindWindow(string lpClassName,string lpWindowName);

[DllImport("kernel32.dll")]
public static extern int GetPrivateProfileString ( string section ,string key , string def , StringBuilder retVal ,int size , string filePath ) ;
[DllImport("kernel32")]
public static extern long WritePrivateProfileString ( string section,string key,string val,string filePath ) ;

private System.ComponentModel.IContainer components;

public static int LocaPort;//本地端口
public static string RemoteIp;
public static int RemotePort;//远程端口
public static string sCompanyName;//公司名称

private Icon m_Icon1;
private Icon m_Icon2;
private Icon m_Icon3;

private NotifyIcon notifyIcon;

MenuItem menuItem1;
MenuItem menuItem2;

private Hashtable CarID_RemoteIP_Hash;

private Thread thGprs ;
private Thread thTcpMsg ;
private Socket socket;
private Socket TcpSocket;

private System.Windows.Forms.Timer TimerIcon;
private System.Windows.Forms.Label lblInfo;
private System.Windows.Forms.Timer TimerConn;
private byte[] TempBuff;
private System.Windows.Forms.CheckBox checkBox1;
private System.Windows.Forms.ImageList imgList;// = new byte[1024];
private byte[] TcpBuff;
private System.Windows.Forms.ListView lvwMsg;
private System.Windows.Forms.ColumnHeader sId;
private System.Windows.Forms.ColumnHeader sNote;
private System.Windows.Forms.Button cmdExit;
private System.Windows.Forms.Button cmdSet;// = new byte[2048];

private bool bTsFlag=false;
public GprsServer()
{

InitializeComponent();
//检测配置文件目录是否存在
GetSysPra();

TempBuff= new byte[1];
TcpBuff=new byte[1];

m_Icon1 = new Icon("SysFile\\Icon1.ico");
m_Icon2 = new Icon("SysFile\\Icon2.ico");
m_Icon3 = new Icon("SysFile\\Icon3.ico");

notifyIcon = new NotifyIcon();
notifyIcon.Icon = m_Icon1;
notifyIcon.Text = sCompanyName;
notifyIcon.Visible = true;

menuItem1=new MenuItem("设置");
menuItem2=new MenuItem("退出");

menuItem1.Click+=new EventHandler(this.menuItem1_Click);
menuItem2.Click+=new EventHandler(this.menuItem2_Click);

notifyIcon.ContextMenu=new ContextMenu(new MenuItem[]{menuItem1,menuItem2});
notifyIcon.DoubleClick+=new System.EventHandler(this.notifyIcon_DBClick);

CarID_RemoteIP_Hash=new Hashtable();

thGprs = new Thread(new ThreadStart(ReadUdp)) ;
//启动线程
thGprs.IsBackground =true;//将线程作为后台线程处理,用途,当线程关闭,子线程随着关闭
thGprs.Start( );

try
{
IPHostEntry IPHost = Dns.Resolve(RemoteIp);
string []aliases = IPHost.Aliases;
IPAddress []addr = IPHost.AddressList;
EndPoint ep = new IPEndPoint(addr[0],RemotePort);
TcpSocket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
TcpSocket.Connect(ep);

thTcpMsg = new Thread (new ThreadStart(ReadTcpMsg)) ;
//启动线程
thTcpMsg.IsBackground =true;
thTcpMsg.Start( ) ;
lblInfo.Text ="系统运行正常,正在转GPRS数据...";
}
catch
{}
}

private void GetSysPra()
{
StringBuilder temp = new StringBuilder(255);
if (Directory.Exists("SysIni"))
{
if (File.Exists("SysIni\\SysIni.ini"))
{
int i;
i= GetPrivateProfileString("PortIni","UdpPort","",temp,255,"SysIni\\SysIni.ini");
if (i==0)
{
LocaPort=8888;
WritePrivateProfileString("PortIni","UdpPort","8888","SysIni\\SysIni.ini");
}
else
{
LocaPort=int.Parse(temp.ToString( ));
}
i = GetPrivateProfileString("Company","Name","",temp,255,"SysIni\\SysIni.ini");
if (i==0)
{
sCompanyName="龙翰科技";
WritePrivateProfileString("Company","Name","龙翰科技","SysIni\\SysIni.ini");
}
else
{
sCompanyName=temp.ToString( );
}
i = GetPrivateProfileString("PortIni","TcpAddress","",temp,255,"SysIni\\SysIni.ini");
if (i==0)
{
RemoteIp="127.0.0.1";
WritePrivateProfileString("PortIni","TcpAddress","127.0.0.1","SysIni\\SysIni.ini");
}
else
{
RemoteIp=temp.ToString( );
}
i = GetPrivateProfileString("PortIni","TcpPort","",temp,255,"SysIni\\SysIni.ini");
if (i==0)
{
RemotePort=6666;
WritePrivateProfileString("PortIni","TcpPort","6666","SysIni\\SysIni.ini");
}
else
{
RemotePort=int.Parse(temp.ToString( ));
}
}
else
{
//File.Create("SysIni\\SysIni.ini",255);
LocaPort=8888;
WritePrivateProfileString("PortIni","UdpPort","8888","SysIni\\SysIni.ini");
sCompanyName="龙翰科技";
WritePrivateProfileString("Company","Name","龙翰科技","SysIni\\SysIni.ini");
RemoteIp="127.0.0.1";
WritePrivateProfileString("PortIni","TcpAddress","127.0.0.1","SysIni\\SysIni.ini");
RemotePort=6666;
WritePrivateProfileString("PortIni","TcpPort","6666","SysIni\\SysIni.ini");
}
}
else
{
Directory.CreateDirectory("SysIni");
//File.Create("SysIni\\SysIni.ini",255);
LocaPort=8888;
WritePrivateProfileString("PortIni","UdpPort","8888","SysIni\\SysIni.ini");
sCompanyName="龙翰科技";
WritePrivateProfileString("Company","Name","龙翰科技","SysIni\\SysIni.ini");
RemoteIp="127.0.0.1";
WritePrivateProfileString("PortIni","TcpAddress","127.0.0.1","SysIni\\SysIni.ini");
RemotePort=6666;
WritePrivateProfileString("PortIni","TcpPort","6666","SysIni\\SysIni.ini");
}
}
///
/// 清理所有正在使用的资源。
///


private void menuItem1_Click(object sender,System.EventArgs e)
{
//
}
private void menuItem2_Click(object sender,System.EventArgs e)
{
this.Close();
Application.Exit();
}
private void notifyIcon_DBClick(object sender, System.EventArgs e)
{
//
}

protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
notifyIcon.Visible =false;;
notifyIcon.Icon=null;
notifyIcon.Dispose();
m_Icon1.Dispose();
m_Icon2.Dispose();
m_Icon3.Dispose();
}
base.Dispose( disposing );
}

#region Windows 设计器生成的代码
///
/// 设计器支持所需的方法 - 不要使用代码编辑器修改
/// 此方法的内容
///

private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
System.Resources.ResourceManager resources = new System.Resources.ResourceManager(typeof(GprsServer));
this.TimerIcon = new System.Windows.Forms.Timer(this.components);
this.lblInfo = new System.Windows.Forms.Label();
this.TimerConn = new System.Windows.Forms.Timer(this.components);
this.lvwMsg = new System.Windows.Forms.ListView();
this.sId = new System.Windows.Forms.ColumnHeader();
this.sNote = new System.Windows.Forms.ColumnHeader();
this.imgList = new System.Windows.Forms.ImageList(this.components);
this.checkBox1 = new System.Windows.Forms.CheckBox();
this.cmdExit = new System.Windows.Forms.Button();
this.cmdSet = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// TimerIcon
//
this.TimerIcon.Enabled = true;
this.TimerIcon.Interval = 1000;
this.TimerIcon.Tick += new System.EventHandler(this.TimerIcon_Tick);
//
// lblInfo
//
this.lblInfo.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
this.lblInfo.Location = new System.Drawing.Point(4, 298);
this.lblInfo.Name = "lblInfo";
this.lblInfo.Size = new System.Drawing.Size(310, 23);
this.lblInfo.TabIndex = 0;
this.lblInfo.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// TimerConn
//
this.TimerConn.Enabled = true;
this.TimerConn.Interval = 6000;
this.TimerConn.Tick += new System.EventHandler(this.TimerConn_Tick);
//
// lvwMsg
//
this.lvwMsg.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
this.sId,
this.sNote});
this.lvwMsg.FullRowSelect = true;
this.lvwMsg.Location = new System.Drawing.Point(2, 2);
this.lvwMsg.Name = "lvwMsg";
this.lvwMsg.Size = new System.Drawing.Size(564, 292);
this.lvwMsg.SmallImageList = this.imgList;
this.lvwMsg.TabIndex = 1;
this.lvwMsg.View = System.Windows.Forms.View.Details;
//
// sId
//
this.sId.Text = "";
this.sId.Width = 21;
//
// sNote
//
this.sNote.Text = "消息内容";
this.sNote.Width = 522;
//
// imgList
//
this.imgList.ColorDepth = System.Windows.Forms.ColorDepth.Depth16Bit;
this.imgList.ImageSize = new System.Drawing.Size(16, 16);
this.imgList.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("imgList.ImageStream")));
this.imgList.TransparentColor = System.Drawing.Color.Transparent;
//
// checkBox1
//
this.checkBox1.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
this.checkBox1.Location = new System.Drawing.Point(332, 300);
this.checkBox1.Name = "checkBox1";
this.checkBox1.Size = new System.Drawing.Size(104, 19);
this.checkBox1.TabIndex = 2;
this.checkBox1.Text = "显示调试数据";
this.checkBox1.CheckedChanged += new System.EventHandler(this.checkBox1_CheckedChanged);
//
// cmdExit
//
this.cmdExit.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
this.cmdExit.Location = new System.Drawing.Point(504, 298);
this.cmdExit.Name = "cmdExit";
this.cmdExit.Size = new System.Drawing.Size(60, 22);
this.cmdExit.TabIndex = 3;
this.cmdExit.Text = "退出(&E)";
this.cmdExit.Click += new System.EventHandler(this.cmdExit_Click);
//
// cmdSet
//
this.cmdSet.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
this.cmdSet.Location = new System.Drawing.Point(432, 298);
this.cmdSet.Name = "cmdSet";
this.cmdSet.Size = new System.Drawing.Size(60, 22);
this.cmdSet.TabIndex = 4;
this.cmdSet.Text = "设置(&S)";
this.cmdSet.Click += new System.EventHandler(this.cmdSet_Click);
//
// GprsServer
//
this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
this.ClientSize = new System.Drawing.Size(566, 323);
this.Controls.Add(this.cmdSet);
this.Controls.Add(this.cmdExit);
this.Controls.Add(this.checkBox1);
this.Controls.Add(this.lvwMsg);
this.Controls.Add(this.lblInfo);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
this.MaximizeBox = false;
this.Name = "GprsServer";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "继服务器";
this.Load += new System.EventHandler(this.GprsServer_Load);
this.ResumeLayout(false);

}
#endregion

///
/// 应用程序的入口点。
///

[STAThread]
static void Main()
{
Application.Run(new GprsServer());
}

private byte Get_CheckXor(ref byte[] temp,int len)
{
byte A=0;
for(int i=0;i {
A^=temp[i];
}
return A;
}

private void ReadTcpMsg() //读取用户发送的指令数据
{
byte[] buff= new byte[2048];
string CartIpAddress="";//车辆的IP地址
EndPoint TempRemote = null;

int recv = 0;
byte[] Tbuff;
byte[] AllBuff;
int iLenght=0;
int iIndex=0;
int iLen=0;
int iXorValue=0;

while(true)
{
try
{
recv=TcpSocket.Receive(buff,0,TcpSocket.Available,SocketFlags.None);//读取数据内容
if (recv==0)
{
recv=TcpSocket.Receive(buff,0,TcpSocket.Available,SocketFlags.None);//读取数据内容
if (recv==0)
{
TcpSocket.Close();
break;
}
}

}
catch
{
break;
}

AllBuff=new byte[recv +TcpBuff.Length];
for (iIndex = 1; iIndex <=TcpBuff.Length; iIndex++)
{
AllBuff[iIndex-1]=TcpBuff[iIndex-1];
}

for (iIndex = 1; iIndex <=recv; iIndex++)
{
AllBuff[TcpBuff.Length+iIndex-1]=buff[iIndex-1];
}

for (iIndex = 1; iIndex <=AllBuff.Length; iIndex++)
{
iLenght=AllBuff.Length-iIndex+1;
if (iLenght<6)//检测数据包长度
{
//不完整,则将指令保存
if (iLenght>0)
{
TcpBuff=new byte[iLenght];
for (iLen = 1; iLen <=iLenght; iLen++)
{
TcpBuff[iLen-1]=AllBuff[iLen+iIndex-2];
}
}
break;
}
else
{
//检测当前指令是否是完整的指令,查找数据包头
if (AllBuff[iIndex-1]==0x29 & AllBuff[iIndex]==0x29)
{
if ((AllBuff.Length -iIndex)>=(AllBuff[iIndex+2]*256+ AllBuff[iIndex+3]+4))
{
//检测当前指令是否是完整的指令
if ((AllBuff[AllBuff[iIndex+2]*256+ AllBuff[iIndex+3]+iIndex+3])==0x0D)
{
//在接收的数据获取单条完整的指令数据
Tbuff=new byte[AllBuff[iIndex+2]*256+ AllBuff[iIndex+3]+5];
for (iLen = 1; iLen <=Tbuff.Length; iLen++)
{
Tbuff[iLen-1]=AllBuff[iLen+iIndex-2];
}
iXorValue=Get_CheckXor(ref Tbuff,Tbuff.Length-2);
if(iXorValue!=Tbuff[Tbuff.Length-2])
{
//校验不合格,继续查找合法指令数据
continue;
}
else
{
if (bTsFlag)
{
string BuffToStr="";
for(int i=0;i {
BuffToStr+=Tbuff[i].ToString("X2")+" ";
}
ShowSysMsg(BuffToStr,2);
}
//获取车载终端手机号
CartIpAddress=Tbuff[5]+"." +Tbuff[6] +"."+Tbuff[7] +"."+Tbuff[8];
TempRemote=(EndPoint)CarID_RemoteIP_Hash[CartIpAddress];
if( TempRemote==null)
{
if (bTsFlag)
{
ShowSysMsg("无法查找到接收数据的远程终节点!",3);
}
}
else
{
try
{
socket.SendTo(Tbuff,TempRemote);
if (bTsFlag)
{
ShowSysMsg("数据成功转发到车载终端!",1);
}
}
catch
{
if (bTsFlag)
{
ShowSysMsg("数据转发到车载终端失败!",3);
}
}
}
iIndex=iIndex+Tbuff.Length-1;
TcpBuff=new byte[1];
}
}
else
{
continue;
}
}
else
{
if ((AllBuff[iIndex+2]*256+ AllBuff[iIndex+3]+4)>1024)
{
continue;
}
else
{
//不完整,则将指令保存
if (iLenght>0)
{
TcpBuff=new byte[iLenght];
for (iLen = 1; iLen <=iLenght; iLen++)
{
TcpBuff[iLen-1]=AllBuff[iLen+iIndex-2];
}
break;
}
else
{
TcpBuff=new byte[1];
break;
}

}
}
}
else
{
continue;
}
}//检测数据包长度
}
}
}

public void ShowSysMsg(string sNote,int iIcon)
{
//显示系统消息
try
{
lvwMsg.BeginUpdate();
if (lvwMsg.Items.Count >100)
lvwMsg.Items.Clear();
ListViewItem li = new ListViewItem();
//li.SubItems[0].Text =sNote ;
li.SubItems.Add (sNote);
li.ImageIndex=iIcon;
lvwMsg.Items.Add(li);
lvwMsg.EndUpdate();
}
catch
{}
}

private void ReadUdp() //从UDP数据端口读取GPRS数据
{
byte[] buff = new byte[1024];
int recv = 0;
byte[] Tbuff;
byte[] AllBuff;
int iLenght=0;
int iIndex=0;
int iLen=0;
int iXorValue=0;
string CarIpAddress="";
byte[] RecvAffirmBuff=new byte[]{0x29,0x29,0x21,0x00,0x05,0,0,0,0,0x0D};//回应终端数组

IPEndPoint ipep = new IPEndPoint(IPAddress.Any ,LocaPort);
//socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
try
{
socket.Bind(ipep);
ShowSysMsg("系统成功在"+LocaPort + "端口侦听!",6);
}
catch
{
ShowSysMsg("端口"+LocaPort+"已被占用,系统侦听失败!",5);
return;
}
IPEndPoint sender = new IPEndPoint(IPAddress.Any , 0);//指远程终端(终节点)Ip地址对象 IPAddress.Any表示任何地址 0 表示任何端口
EndPoint remote = (EndPoint)(sender); //指远程终端(终节点)

while(true)
{
try
{
recv = socket.ReceiveFrom(buff , ref remote);
}
catch
{
ShowSysMsg("接收车载终端数据错误!",3);
}
//---------------------you2004-12-31 begin------------------------------//
AllBuff=new byte[recv +TempBuff.Length];
for (iIndex = 1; iIndex <=TempBuff.Length; iIndex++)
{
AllBuff[iIndex-1]=TempBuff[iIndex-1];
}

for (iIndex = 1; iIndex <=recv; iIndex++)
{
AllBuff[TempBuff.Length+iIndex-1]=buff[iIndex-1];
}

for (iIndex = 1; iIndex <=AllBuff.Length; iIndex++)
{
iLenght=AllBuff.Length-iIndex+1;
if (iLenght<6)//检测数据包长度
{
//不完整,则将指令保存
if (iLenght>0)
{
TempBuff=new byte[iLenght];
for (iLen = 1; iLen <=iLenght; iLen++)
{
TempBuff[iLen-1]=AllBuff[iLen+iIndex-2];
}
}
break;
}
else
{
//检测当前指令是否是完整的指令,查找数据包头
if (AllBuff[iIndex-1]==0x29 & AllBuff[iIndex]==0x29)
{
if ((AllBuff.Length -iIndex)>=(AllBuff[iIndex+2]*256+ AllBuff[iIndex+3]+4))
{
//检测当前指令是否是完整的指令
if ((AllBuff[AllBuff[iIndex+2]*256+ AllBuff[iIndex+3]+iIndex+3])==0x0D)
{
//在接收的数据获取单条完整的指令数据
Tbuff=new byte[AllBuff[iIndex+2]*256+ AllBuff[iIndex+3]+5];
for (iLen = 1; iLen <=Tbuff.Length; iLen++)
{
Tbuff[iLen-1]=AllBuff[iLen+iIndex-2];
}
iXorValue=Get_CheckXor(ref Tbuff,Tbuff.Length-2);
if(iXorValue!=Tbuff[Tbuff.Length-2])
{
//校验不合格,继续查找合法指令数据
continue;
}
else
{
if (bTsFlag)
{
string BuffToStr="";
for(int i=0;i {
BuffToStr+=Tbuff[i].ToString("X2")+" ";
}
ShowSysMsg(BuffToStr,0);
}

//获取车载终端手机号
CarIpAddress=Tbuff[5]+"." +Tbuff[6] +"."+Tbuff[7] +"."+Tbuff[8];

//-----------------检测系统哈希表是否包含此终端数据---------------------\\
if(CarID_RemoteIP_Hash.ContainsKey(CarIpAddress))
{
CarID_RemoteIP_Hash[CarIpAddress]=remote;//有更新
}
else
{
CarID_RemoteIP_Hash.Add(CarIpAddress,remote);//没有添加
}

//--------------------将数据转发到心处理程序-----------------\\
if (TcpSocket.Connected)
{
try
{
TcpSocket.Send(Tbuff,0,Tbuff.Length,SocketFlags.None);
if (bTsFlag)
{
ShowSysMsg("数据成功转发到网络心处理程序!",1);
}
}
catch
{
if (bTsFlag)
{
ShowSysMsg("数据转发到网络心处理程序失败!",3);
}
}
}
//-------------------向终端发出0x21的接收确认-------------------\\
RecvAffirmBuff[5]=Tbuff[Tbuff.Length-2];
RecvAffirmBuff[6]=Tbuff[2];
RecvAffirmBuff[7]=Tbuff[9];
RecvAffirmBuff[8]=Get_CheckXor(ref RecvAffirmBuff,8);
socket.SendTo(RecvAffirmBuff,remote);
iIndex=iIndex+Tbuff.Length-1;
TempBuff=new byte[1];
}
}
else
{
continue;
}
}
else
{
if ((AllBuff[iIndex+2]*256+ AllBuff[iIndex+3]+4)>1024)
{
continue;
}
else
{
//不完整,则将指令保存
if (iLenght>0)
{
TempBuff=new byte[iLenght];
for (iLen = 1; iLen <=iLenght; iLen++)
{
TempBuff[iLen-1]=AllBuff[iLen+iIndex-2];
}
break;
}
else
{
TempBuff=new byte[1];
break;
}

}
}
}
else
{
continue;
}
}//检测数据包长度

}
//---------------------you2004-12-31 end------------------------------//
}

}

private void GprsServer_Load(object sender, System.EventArgs e)
{
//
}

int I=0;
private void TimerIcon_Tick(object sender, System.EventArgs e)
{
if(thGprs!=null)
{
if(thGprs.IsAlive)
notifyIcon.Icon=notifyIcon.Icon==m_Icon1?m_Icon2:m_Icon1;
else
notifyIcon.Icon=notifyIcon.Icon==m_Icon1?m_Icon3:m_Icon1;
}
I++;
if(I>5)
{
I=FindWindow(null,@sCompanyName);
if( I!= 0)
{
SendMessage(I,0x501,1002,"");
}
I=0;
}
}

private void TimerConn_Tick(object sender, System.EventArgs e)
{
if (!TcpSocket.Connected)
{
try
{
lblInfo.Text ="与心数据处理程序断开,正在进行二次连接...";
IPHostEntry IPHost = Dns.Resolve(RemoteIp);
string []aliases = IPHost.Aliases;
IPAddress []addr = IPHost.AddressList;
EndPoint ep = new IPEndPoint(addr[0],RemotePort);
TcpSocket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
TcpSocket.Connect(ep);

thTcpMsg = new Thread ( new ThreadStart(ReadTcpMsg)) ;
//启动线程
thTcpMsg.IsBackground =true;
thTcpMsg.Start( ) ;
lblInfo.Text ="系统运行正常,正在转GPRS数据...";
}
catch
{
return;
}
}
}

private void checkBox1_CheckedChanged(object sender, System.EventArgs e)
{
bTsFlag=checkBox1.Checked;
}

private void cmdExit_Click(object sender, System.EventArgs e)
{
if(MessageBox.Show("确定关闭继服务器?", "提示",MessageBoxButtons.YesNo,MessageBoxIcon.Information) == DialogResult.Yes)
{
Application.Exit ();
}
}

private void cmdSet_Click(object sender, System.EventArgs e)
{
frmUdpSet frmudpset=new frmUdpSet();
frmudpset.Show();
}

protected override void OnClosing(CancelEventArgs e)
{
e.Cancel =true;
this.WindowState =FormWindowState.Minimized;
}
}
}
一、Qt Creator 的安装和hello world 程序的编写(原创) 1.首先到Qt 的官方网站上下载Qt Creator,这里我们下载windows 版的。 下载地址:http://qt.nokia.com/downloads 如下图我们下载:Download Qt SDK for Windows* (178Mb) 下载完成后,直接安装即可,安装过程按默认设置即可。 2.运行Qt Creator,首先弹出的是欢迎界面,这里可以打开其自带的各种演示 程序。 3.我们用File->New 菜单来新建工程。 4.这里我们选择Qt4 Gui Application。 5.下面输入工程名和要保存到的文件夹路径。我们这里的工程名为helloworld。 6.这时软件自动添加基本的头文件,因为这个程序我们不需要其他的功能,所以 直接点击Next。 7.我们将base class 选为QDialog 对话框类。然后点击Next。 8.点击Finish,完成工程的建立。 9.我们可以看见工程的所有文件都出现在列表了。我们可以直接按下下面的 绿色的run 按钮或者按下Ctrl+R 快捷键运行程序。 10.程序运行会出现空白的对话框,如下图。 11.我们双击文件列表的dialog.ui 文件,便出现了下面所示的图形界面编辑界 面。 12.我们在右边的器件栏里找到Label 标签器件 13.按着鼠标左键将其拖到设计口上,如下图。 14.我们双击它,并将其内容改为helloworld。 15.我们在右下角的属性栏里将字大小由9 改为15。 16.我们拖动标签一角的蓝点,将全部文字显示出来。 17.再次按下运行按钮,便会出现helloworld。 到这里helloworld 程序便完成了。 Qt Creator 编译的程序,在其工程文件夹下会有一个debug 文件夹,其有程序的.exe 可执行文件。但Qt Creator 默认是用动态链接的, 就是可执行程序在运行时需要相应的.dll 文件。我们点击生成的.exe 文件,首 先可能显示“没有找到mingwm10.dll,因此这个应用程序未能启动。重新安装 应用程序可能会修复此问题。”表示缺少mingwm10.dll 文件。 解决这个问题我们可以将相应的.dll 文件放到系统 。在Qt Creator 的安装目录的qt 文件下的bin 文件夹下(我安装在了D 盘, 所以路径是D:\Qt\2009.04\qt\bin),可以找到所有的相关.dll 文件。在这里 找到mingwm10.dll 文件,将其复制到C:\WINDOWS\system 文件夹下,即可。下 面再提示缺少什么dll 文件,都像这样解决就可以了。 二、Qt Creator 编写多口程序(原创) 实现功能: 程序开始出现一个对话框,按下按钮后便能进入口,如果直 接关闭这个对话框,便不能进入口,整个程序也将退出。当进入口后, 我们按下按钮,会弹出一个对话框,无论如何关闭这个对话框,都会回到口。 实现原理: 程序里我们先建立一个工程,作为界面,然后再建立一个对 话框类,将其加入工程,然后在程序调用自己新建的对话框类来实现多口。 实现过程: 1.首先新建Qt4 Gui Application 工程,工程名为nGui,Base class 选为QWidget。 建立好后工程文件列表如下图。 2.新建对话框类,如下图,在新建,选择Qt Designer Form Class。 3.选择Dialog without Buttons。 4.类名设为myDlg。 5.点击Finish 完成。注意这里已经默认将其加入到了我们刚建的工程了。 6.如下图,在mydlg.ui 拖入一个Push Button,将其上的文本改为“进入 口”,在其属性将其objectName 改为enterBtn,在下面的Signals and slots editor 进行信号和槽的关联,其,Sender 设为enterBtn,Signal 设为clicked(),Receive 设为myDlg,Slot 设为accept()。这样就实现了单击 这个按钮使这个对话框关闭并发出Accepted 信号的功能。下面我们将利用这个 信号。 7.修改函数main.cpp,如下: #include #include "widget.h" #include "mydlg.h" //加入头文件 int main(int argc, char *argv[]) { QApplication a(argc, argv); Widget w; myDlg my1; //建立自己新建的类的对象my1 if(my1.exec()==QDialog::Accepted) //利用Accepted 信号判 断enterBtn 是否被按下 { w.show(); //如果被按下,显示口 return a.exec(); //程序一直执行,直到口 关闭 } else return 0; //如果没被按下,则不会进入口,整个程 序结束运行 } 函数必须这么写,才能完成所要的功能。 如果函数写成下面这样: #include #include "widget.h" #include "mydlg.h" int main(int argc, char *argv[]) { QApplication a(argc, argv); myDlg my1; if(my1.exec()==QDialog::Accepted) { Widget w; w.show(); } return a.exec(); } 这样,因为w 是在if 语句里定义的,所以当if 语句执行完后它就无效了。这样 导致的后果就是,按下enterBtn 后,界面口一闪就没了。如果此时对程序 改动了,再次点击运行时,就会出现error: collect2: ld returned 1 exit status 的错误。这是因为虽然口没有显示,但它只是隐藏了,程序并没有 结束,而是在后台运行。所以这时改动程序,再运行时便会出错。你可以按下调 试栏上面的红色Stop 停止按钮来停止程序运行。你也可以在windows 任务管理 器的进程将该进程结束,而后再次运行就没问题了,当然先关闭Qt Creator, 而后再重新打开,这样也能解决问题。 如果把程序改为这样: #include #include "widget.h" #include "mydlg.h" int main(int argc, char *argv[]) { QApplication a(argc, argv); myDlg my1; Widget w; if(my1.exec()==QDialog::Accepted) { w.show(); } return a.exec(); } 这样虽然解决了上面口一闪而过的问题,但是,如果在my1 对话框出现的时 候不点enterBtn,而是直接关闭对话框,那么此时整个程序应该结束执行,但 是事实是这样的吗?如果你此时对程序进行了改动,再次按下run 按钮,你会发 现又出现了error: collect2: ld returned 1 exit status 的错误,这说明程 序并没有结束,我们可以打开windows 任务管理器,可以看到我们的程序仍在执 行。 因为return a.exec();一句表示只要口界面不退出,那么程 序就会一直执行。所以只有用第一种方法,将该语句也放到if 语句,而在else 语句用else return 0; ,这样如果enterBtn 没有被按下,那么程序就会结 束执行了。 到这里,我们就实现了一个界面结束执行,然后弹出另一个 界面的程序。下面我们在口上加一个按钮,按下该按钮,弹出一个对话框, 但这个对话框关闭,不会使口关闭。 8.如下图,在口加入按钮,显示文本为“弹出一个对话框”,在其上点击鼠 标右键,在弹出的菜单选择go to slot。 9.我们选择单击事件clicked()。 10.我们在弹出的槽函数添加一句: my2.show(); my2 为我们新建对话框类的另一个对象,但是my2 我们还没有定义,所以 在widget.h 文件添加相应代码,如下,先加入头文件,再加入my2 的定义语 句,这里我们将其放到private 里,因为一般的函数都放在public 里,而变量 都放在private 里。 #ifndef WIDGET_H #define WIDGET_H #include #include "mydlg.h" //包含头文件 namespace Ui { class Widget; } class Widget : public QWidget { Q_OBJECT public: Widget(QWidget *parent = 0); ~Widget(); private: Ui::Widget *ui; myDlg my2; //对my2 进行定义 private slots: void on_pushButton_clicked(); }; #endif // WIDGET_H 到这里,再运行程序,便能完成我们实验要求的功能了。整个程序里,我们用两 种方法实现了信号和槽函数的关联,第一个按钮我们直接在设计器实现其关 联;第二个按钮我们自己写了槽函数语句,其实图形的设计与直接写代码效果是 一样的。 这个程序里我们实现了两类口打开的方式,一个是自身消失而 后打开另一个口,一个是打开另一个口而自身不消失。可以看到他们实现的 方法是不同的。 三、Qt Creator 登录对话框(原创) 实现功能: 在弹出对话框填写用户名和密码,按下登录按钮,如果用户名和密码均正确则 进入口,如果有错则弹出警告对话框。 实现原理: 通过上节的多口原理实现由登录对话框进入口,而用户名和密码可以用 if 语句进行判断。 实现过程: 1.先新建Qt4 Gui Application 工程,工程名为mainWidget,选用QWidget 作 为Base class,这样便建立了口。文件列表如下: 2.然后新建一个Qt Designer Form Class 类,类名为loginDlg,选用Dialog without Buttons,将其加入上面的工程。文件列表如下: 3.在logindlg.ui 设计下面的界面:行输入框为Line Edit。其用户名后面 的输入框在属性设置其object Name 为usrLineEdit,密码后面的输入框为 pwdLineEdit,登录按钮为loginBtn,退出按钮为exitBtn。 4.将exitBtn 的单击后效果设为退出程序,关联如下: 5.右击登录按钮选择go to slot,再选择clicked(),然后进入其单击事件的槽 函数,写入一句 void loginDlg::on_loginBtn_clicked() { accept(); } 6.改写main.cpp: #include #include "widget.h" #include "logindlg.h" int main(int argc, char *argv[]) { QApplication a(argc, argv); Widget w; loginDlg login; if(login.exec()==QDialog::Accepted) { w.show(); return a.exec(); } else return 0; } 7.这时执行程序,可实现按下登录按钮进入口,按下退出按钮退出程序。 8.添加用户名密码判断功能。将登陆按钮的槽函数改为: void loginDlg::on_loginBtn_clicked() { if(m_ui->usrLineEdit->text()==tr("qt")&&m_ui->pwdLineEdit->text()==tr ("123456")) //判断用户名和密码是否正确 accept(); else{ QMessageBox::warning(this,tr("Warning"),tr("user name or password error!"),QMessageBox::Yes); //如果不正确,弹出警告对话框 } } 并在logindlg.cpp 加入#include 的头文件。如果不加这个头文件, QMessageBox 类不可用。 9.这时再执行程序,输入用户名为qt,密码为123456,按登录按钮便能进入 口了,如果输入错了,就会弹出警告对话框。 如果输入错误,便会弹出警告提示框: 10.在logindlg.cpp 的loginDlg 类构造函数里,添上初始化语句,使密码显示 为小黑点。 loginDlg::loginDlg(QWidget *parent) : QDialog(parent), m_ui(new Ui::loginDlg) { m_ui->setupUi(this); m_ui->pwdLineEdit->setEchoMode(QLineEdit::Password); } 效果如下: 11.如果输入如下图的用户名,在用户名前不小心加上了一些空格,结果程序 按错误的用户名对待了。 我们可以更改if 判断语句,使这样的输入也算正确。 void loginDlg::on_loginBtn_clicked() { if(m_ui->usrLineEdit->text().trimmed()==tr("qt")&&m_ui->pwdLineEdit-> text()==tr("123456")) accept(); else{ QMessageBox::warning(this,tr("Warning"),tr("user name or password error!"),QMessageBox::Yes); } } 加入的这个函数的作用就是移除字符串开头和结尾的空白字符。 12.最后,如果输入错误了,重新回到登录对话框时,我们希望可以使用户名和 密码框清空并且光标自动跳转到用户名输入框,最终的登录按钮的单击事件的槽 函数如下: void loginDlg::on_loginBtn_clicked() { if(m_ui->usrLineEdit->text().trimmed()==tr("qt")&&m_ui->pwdLineEdit-> text()==tr("123456")) //判断用户名和密码是否正确 accept(); else{ QMessageBox::warning(this,tr("Warning"),tr("user name or password error!"),QMessageBox::Yes); //如果不正确,弹出警告对话框 m_ui->usrLineEdit->clear();//清空用户名输入框 m_ui->pwdLineEdit->clear();//清空密码输入框 m_ui->usrLineEdit->setFocus();//将光标转到用户名输入框 } } 四、Qt Creator 添加菜单图标(原创) 在下面的几节,我们讲述Qt 的MainWindow 口部件。这一节只讲述怎样在其 上的菜单栏里添加菜单和图标。 1.新建Qt4 Gui Application 工程,将工程命名为MainWindow,其他选项默认 即可。 生成的口界面如下图。其最上面的为菜单栏。 2.我们在Type Here 那里双击,并输入“文件(&F)”,这样便可将其文件菜单的 快捷键设为Alt+F。(注意括号最好用英文半角输入,这样看着美观) 3.输入完按下Enter 键确认即可,然后在子菜单加入“新建(&N)”,确定后, 效果如下图。 4.我们在下面的动作编辑口可以看到新加的“新建”菜单。 5.双击这一条,可打开它的编辑对话框。我们看到Icon 项,这里可以更改“新 建”菜单的图标。 6.我们点击后面的...号,进入资源选择器,但现在这里面是空的。所以下面我 们需要给该工程添加外部资源。 7.添加资源有两种方法。一种是直接添加系统提供的资源文件,然后选择所需图 标。另一种是自己写资源文件。我们要介绍第一种。新建Qt Resources file, 将它命名为menu。其他默认。 8.添加完后如下图。可以看到添加的文件为menu.qrc。 9.我们最好先在工程文件夹里新建一个文件夹,如images,然后将需要的图标 文件放到其。 10.在Qt Creator 的menu.qrc 文件,我们点击Add 下拉框,选择Add Prefix。 我们可以将生成的/new/prefix 前缀改为其他名字,如/File。 11.然后再选择Add 下拉框,选择Add Files。再弹出的对话框,我们到新建 的images 文件夹下,将里面的图标文件全部添加过来。 12.添加完成后,我们在Qt Creator 的File 菜单里选择Save All 选项,保存所 做的更改。 13.这时再打开资源选择器,可以看到我们的图标都在这里了。(注意:如果不显 示,可以按一下上面的Reload 按钮) 14.我们将new.png 作为“新建”菜单的图标,然后点击Shortcut,并按下 Crtl+N,便能将Crtl+N 作为“新建”菜单的快捷键。 15.这时打开文件菜单,可以看到“新建”菜单已经有图标了。 运行程序后效果如下。 16.我们在工程文件夹下查看建立的menu.qrc 文件,可以用写字板将它打开。 其具内容如下。 附:第二种添加资源文件的方法。 1.首先右击工程文件夹,在弹出的菜单选择Add New,添加新文件。也可以用 File 的添加新文件。 2.我们选择文本文件。 3.将文件名设置为menu.qrc。 4.添加好文件后将其内容修改如下。可以看到就是用第一种方法生成的 menu.qrc 文件的内容。 5.保存文件后,在资源管理器可以看到添加的图标文件。 五、Qt Creator 布局管理器的使用(原创) 上篇讲解了如何在Qt Creator 添加资源文件,并且为菜单添加了图标。这次 我们先对那个界面进行一些完善,然后讲解一些布局管理器的知识。 首先对菜单进行完善。 1.我们在上一次的基础上再加入一些常用菜单。 “文件”的子菜单如下图。间的分割线可以点击Add Separator 添加。 “编辑”子菜单的内容如下。 “帮助”子菜单的内容如下。 2.我们在动作编辑器对各个菜单的属性进行设置。 如下图。 3.我们拖动“新建”菜单的图标,将其放到工具栏里。 拖动“新建”菜单的图标。 将其放到菜单栏下面的工具栏里。 4.我们再添加其他几个图标。使用Append Separator 可以添加分割线。 5.最终效果如下。如果需要删除图标,可以在图标上点击右键选择Remove action 即可。 下面简述一下布局管理器。 (这里要以垂直布局管理器进行讲解,其他类型管理器用法与之相同,其效 果可自己验证。) 1.在左边的器件栏里拖入三个PushButton 和一个Vertical Layout(垂直布局 管理器)到心面板。如下图。 2.将这三个按钮放入垂直布局管理器,效果如下。可以看到按钮垂直方向排列, 并且宽度可以改变,但高度没有改变。 3.我们将布局管理器整,按下上面工具栏的Break Layout 按钮,便可取 消布局管理器。(我们当然也可以先将按钮移出,再按下Delete 键将布局管理 器删除。) 4.下面我们改用分裂器部件(QSplitter)。 先将三个按钮同时选,再按下上面工具栏的Lay Out Vertically in Splitter (垂直分裂器)。 效果如下图。可以看到按钮的大小可以随之改动。这也就是分裂器和布局管理器 的分别。 5.其实布局管理器不但能控制器件的布局,还有个很重要的用途是,它能使器件 的大小随着口大小的改变改变。 我们先在口的心拖入一个文本编辑器Text Edit。 这时直接运行程序,效果如下。可以看到它的大小和位置不会随着改变。 下面我们选口部件,然后在空白处点击鼠标右键,选择Layout->Lay Out in a Grid,使整个口的心区处于网格布局管理器。 可以看到,这时文本编辑器已经占据了整个口的心区。 运行一下程序,可以看到无论怎样拉伸口,文本编辑框的大小都会随之改变。 我们在这里一共讲述了三种使用布局管理器的方法,一种是去器件栏添加,一 种是用工具栏的快捷图标,还有一种是使用鼠标右键的选项。 程序用到的图标是我从Ubuntu 复制的,可以到 http://www.qtcn.org/bbs/read.php?tid=23252&page=1&toread=1 下载到。 六、Qt Creator 实现文本编辑(原创) 前面已经将界面做好了,这里我们为其添加代码,实现文本编辑的功能。 首先实现新建文件,文件保存,和文件另存为的功能。 (我们先将上次的工程文件夹进行备份,然后再对其进行修改。在写较大的程序 时,经常对源文件进行备份,是个很好的习惯。) 在开始正式写程序之前,我们先要考虑一下整个流程。因为我们要写记事本一 样的软件,所以最好先打开windows 的记事本,进行一些简单的操作,然后 考虑怎样去实现这些功能。再者,再强大的软件,它的功能也是一个一个加上 去的,不要设想一下子写出所有的功能。我们这里先实现新建文件,保存文件, 和文件另存为三个功能,是因为它们联系很紧,而且这三个功能总的代码量也 不是很大。 因为三个功能之间的关系并不复杂,所以我们这里便不再画流程图,而只是简 单描述一下。 新建文件,那么如果有正在编辑的文件,是否需要保存呢? 如果需要进行保存,那这个文件以前保存过吗?如果没有保存过,就应该先将其 另存为。 下面开始按这些关系写程序。 1.打开Qt Creator,在File 菜单选择Open,然后在工程文件夹打开 MainWindow.pro 工程文件。 先在main.cpp 文件加入以下语句,让程序可以使用文。 在其加入#include TextCodec> 头文件包含,再在函数加入下面一行: QTextCodec::setCodecForTr(QTextCodec::codecForLocale()); 这样在程序使用文,便能在运行时显示出来了。更改后文件如下图。 2.在mainwindow.h 文件的private 下加入以下语句。 bool isSaved; //为true 时标志文件已经保存,为false 时标志文件尚未保存 QString curFile; //保存当前文件的文件名 void do_file_New(); //新建文件 void do_file_SaveOrNot(); //修改过的文件是否保存 void do_file_Save(); //保存文件 void do_file_SaveAs(); //文件另存为 bool saveFile(const QString& fileName); //存储文件 这些是变量和函数的声明。其isSaved 变量起到标志的作用,用它来标志文件 是否被保存过。然后我们再在相应的源文件里进行这些函数的定义。 3.在mainwindow.cpp 先加入头文件#include ,然后在构造函数里添 加以下几行代码。 isSaved = false; //初始化文件为未保存过状态 curFile = tr("未命名.txt"); //初始化文件名为“未命名.txt” setWindowTitle(curFile); //初始化口的标题 这是对口进行初始化。效果如下。 4.然后添加“新建”操作的函数定义。 void MainWindow::do_file_New() //实现新建文件的功能 { do_file_SaveOrNot(); isSaved = false; curFile = tr("未命名.txt"); setWindowTitle(curFile); ui->textEdit->clear(); //清空文本编辑器 ui->textEdit->setVisible(true); //文本编辑器可见 } 新建文件,先要判断正在编辑的文件是否需要保存。然后将新建的文件标志为未 保存过状态。 5.再添加do_file_SaveOrNot 函数的定义。 void MainWindow::do_file_SaveOrNot() //弹出是否保存文件对话框 { if(ui->textEdit->document()->isModified()) //如果文件被更改过,弹出保 存对话框 { QMessageBox box; box.setWindowTitle(tr("警告")); box.setIcon(QMessageBox::Warning); box.setText(curFile + tr(" 尚未保存,是否保存?")); box.setStandardButtons(QMessageBox::Yes | QMessageBox::No); if(box.exec() == QMessageBox::Yes) //如果选择保存文件,则执行保存操作 do_file_Save(); } } 这个函数实现弹出一个对话框,询问是否保存正在编辑的文件。 6.再添加“保存”操作的函数定义。 void MainWindow::do_file_Save() //保存文件 { if(isSaved){ //如果文件已经被保存过,直接保存文件 saveFile(curFile); } else{ do_file_SaveAs(); //如果文件是第一次保存,那么调用另存为 } } 对文件进行保存时,先判断其是否已经被保存过,如果没有被保存过,就要先对 其进行另存为操作。 7.下面是“另存为”操作的函数定义。 void MainWindow::do_file_SaveAs() //文件另存为 { QString fileName = QFileDialog::getSaveFileName(this,tr("另存为 "),curFile); //获得文件名 if(!fileName.isEmpty()) //如果文件名不为空,则保存文件内容 { saveFile(fileName); } } 这里弹出一个文件对话框,显示文件另存为的路径。 8.下面是实际文件存储操作的函数定义。 bool MainWindow::saveFile(const QString& fileName) //保存文件内容,因为可能保存失败,所以具有返回,来表明是否保存成功 { QFile file(fileName); if(!file.open(QFile::WriteOnly | QFile::Text)) //以只写方式打开文件,如果打开失败则弹出提示框并返回 { QMessageBox::warning(this,tr("保存文件"), tr("无法保存文件 %1:\n %2").arg(fileName) .arg(file.errorString())); return false; } //%1,%2 表示后面的两个arg 参数的 QTextStream out(&file); //新建流对象,指向选定的文件 out << ui->textEdit->toPlainText(); //将文本编辑器里的内容以纯文本 的形式输出到流对象 isSaved = true; curFile = QFileInfo(fileName).canonicalFilePath(); //获得文件的标准路 径 setWindowTitle(curFile); //将口名称改为现在口的路径 return true; } 这个函数实现将文本文件进行存储。下面我们对其的一些代码进行讲解。 QFile file(fileName);一句,定义了一个QFile 类的对象file,其filename 表明这个文件就是我们保存的的文件。然后我们就可以用file 代替这个文件, 来进行一些操作。Qt 文件的操作和C,C++很相似。对于QFile 类对象怎么使 用,我们可以查看帮助。 点击Qt Creator 最左侧的Help,在其输入QFile, 在搜索到的列表选择QFile 即可。这时在右侧会显示出QFile 类所有相关信 息以及他们的用法和说明。 // 我们往下拉,会发现下面有关于怎么读取文件的示例代码。 // // 再往下便能看到用QTextStream 类对象,进行字符串输入的例子。下面也提到了 QFileInfo 和QDir 等相关的类,我们可以点击它们去看一下具的使用说明。 // 上面只是做了一个简单的说明。以后我们对自己不明白的类都可以去帮助里进行 查找,这也许是我们以后要做的最多的一件事了。对于其的英文解释,我们最 好想办法弄明白它的大意,其实网上也有一些文的翻译,但最好还是从一开始 就尝试着看英文原版的帮助,这样以后才不会对文翻译产生依赖。 我们这次只是很简单的说明了一下怎样使用帮助文件,这不表明 它不重要,而是因为这里不可能将每个类的帮助都解释一遍,没有那么多时间, 也没有那么大的篇幅。而更重要的是因为,我们这个教程只是引你入门,所以很 多东西需要自己去尝试。 在以后的教程里,如果不是特殊情况,就不会再对其的类进行 详细解释,文章的重点是对整个程序的描述,其不明白的类,自己查看帮助。 9.双击mainwindow.ui 文件,在图形界面口下面的Action Editor 动作编辑 器里,我们右击“新建”菜单一条,选择Go to slot,然后选择triggered(), 进入其触发事件槽函数。 同理,进入其他两个菜单的槽函数,将相应的操作的函数写入槽函数。如下。 void MainWindow::on_action_New_triggered() //信号和槽的关联 { do_file_New(); } void MainWindow::on_action_Save_triggered() { do_file_Save(); } void MainWindow::on_action_SaveAs_triggered() { do_file_SaveAs(); } 这时点击运行,就能够实现新建文件,保存文件,文件另存为的功能了。 然后实现打开,关闭,退出,撤销,复制,剪切,粘贴的功能。 先备份上次的工程文件,然后再将其打开。 1.先在mainwindow.h 文件加入函数的声明。 void do_file_Open(); //打开文件 bool do_file_Load(const QString& fileName); //读取文件 2.再在mainwindow.cpp 文件写函数的功能实现。 void MainWindow::do_file_Open()//打开文件 { do_file_SaveOrNot();//是否需要保存现有文件 QString fileName = QFileDialog::getOpenFileName(this); //获得要打开的文件的名字 if(!fileName.isEmpty())//如果文件名不为空 { do_file_Load(fileName); } ui->textEdit->setVisible(true);//文本编辑器可见 } bool MainWindow::do_file_Load(const QString& fileName) //读取文件 { QFile file(fileName); if(!file.open(QFile::ReadOnly | QFile::Text)) { QMessageBox::warning(this,tr("读取文件"),tr("无法读取文件 %1:\n%2.").arg(fileName).arg(file.errorString())); return false; //如果打开文件失败,弹出对话框,并返回 } QTextStream in(&file); ui->textEdit->setText(in.readAll()); //将文件的所有内容都 写到文本编辑器 curFile = QFileInfo(fileName).canonicalFilePath(); setWindowTitle(curFile); return true; } 上面的打开文件函数与文件另存为函数相似,读取文件的函数与文件存储函数相 似。 3.然后按顺序加入更菜单的关联函数,如下。 void MainWindow::on_action_Open_triggered() //打开操作 { do_file_Open(); } // void MainWindow::on_action_Close_triggered() //关闭操作 { do_file_SaveOrNot(); ui->textEdit->setVisible(false); } // void MainWindow::on_action_Quit_triggered() //退出操作 { on_action_Close_triggered(); //先执行关闭操作 qApp->quit(); //再退出系统,qApp 是指向应用程序的全局指针 } // void MainWindow::on_action_Undo_triggered() //撤销操作 { ui->textEdit->undo(); } // void MainWindow::on_action_Cut_triggered() //剪切操作 { ui->textEdit->cut(); } // void MainWindow::on_action_Copy_triggered() //复制操作 { ui->textEdit->copy(); } // void MainWindow::on_action_Past_triggered() //粘贴操作 { ui->textEdit->paste(); } 因为复制,撤销,全选,粘贴,剪切等功能,是TextEdit 默认就有的,所以我 们只需调用一下相应函数就行。 到这里,除了查找和帮助两个菜单的功能没有加上以外,其他功能都已经实现了。 七、Qt Creator 实现文本查找(原创) 现在加上查找菜单的功能。因为这里要涉及关于Qt Creator 的很多实用功能, 所以单独用一篇文章来介绍。 以前都用设计器设计界面,而这次我们用代码实现一个简单的查找对话框。对于 怎么实现查找功能的,我们详细地分步说明了怎么进行类方法的查找和使用。 其也将Qt Creator 智能化的代码补全功能和程序函数的声明位置和定义位 置间的快速切换进行了介绍。 1.首先还是保存以前的工程,然后再将其打开。 我们发现Qt Creator 默认的字有点小,可以按下Ctrl 键的同时按两下+键, 来放大字。也可以选择Edit->Advanced->Increase Font Size。 2.在mainwindow.h 加入#include 的头文件包含,在private 添加 QLineEdit *find_textLineEdit; //声明一个行编辑器,用于输入要查找的内容 在private slots 添加 void show_findText(); 在该函数实现查找字符串的功能。 3.我们进入查找菜单的触发事件槽函数,更改如下。 void MainWindow::on_action_Find_triggered() { QDialog *findDlg = new QDialog(this); //新建一个对话框,用于查找操作,this 表明它的父口是MainWindow。 findDlg->setWindowTitle(tr("查找")); //设置对话框的标题 find_textLineEdit = new QLineEdit(findDlg); //将行编辑器加入到新建的查找对话框 QPushButton *find_Btn = new QPushButton(tr("查找下一个"),findDlg); //加入一个“查找下一个”的按钮 QVBoxLayout* layout = new QVBoxLayout(findDlg); layout->addWidget(find_textLineEdit); layout->addWidget(find_Btn); //新建一个垂直布局管理器,并将行编辑器和按钮加入其 findDlg ->show(); //显示对话框 connect(find_Btn,SIGNAL(clicked()),this,SLOT(show_findText())); //设置“查找下一个”按钮的单击事件和其槽函数的关联 } 这里我们直接用代码生成了一个对话框,其一个行编辑器可以输入要查找的字 符,一个按钮可以进行查找操作。我们将这两个部件放到了一个垂直布局管理器 。然后显示这个对话框。并设置了那个按钮单击事件与show_findText()函数 的关联。 5.下面我们开始写实现查找功能的show_findText()函数。 void MainWindow::show_findText()//“查找下一个”按钮的槽函数 { QString findText = find_textLineEdit->text(); //获取行编辑器内容 } 先用一个QString 类的对象获得要查找的字符。然后我们一步一步写查找操作的 语句。 6.在下一行写下ui,然后直接按下键盘上的“<.”键,这时系统会根据是否是 指针对象而自动生成“->”或“.”,因为ui 是指针对象,所以自动生成“->” 号,而且弹出了ui 的所有部件名称的列表。如下图。 7.我们用向下的方向键选列表textEdit。或者我们可以先输入text,这 时能缩减列表的内容。 8.如上图我们将鼠标放到textEdit 上,这时便出现了textEdit 的类名信息, 且后面出现一个F1 按键。我们按下键盘上的F1,便能出现textEdit 的帮助。 9.我们在帮助向下拉,会发现这里有一个find 函数。 10.我们点击find,查看其详细说明。 11.可以看到find 函数可以实现文本编辑器字符串的查找。其有一个 FindFlags 的参数,我们点击它查看其说明。 12.可以看到它是一个枚举变量(enum),有三个选项,第一项是向后查找(即 查找光标以前的内容,这里的前后是相对的说法,比如第一行已经用完了,光 标在第二行时,把第一行叫做向后。),第二项是区分大小写查找,第三项是 查找全部。 13.我们选用第一项,然后写出下面的语句。 ui->textEdit->find(findText,QTextDocument::FindBackward); //将行编辑器内容在文本编辑器进行查找 当我们刚打出“f”时,就能自动弹出textEdit 类的相关属性和方法。 可以看到,当写完函数名和第一个“(”后,系统会自动显示出该函数的函数原 型,这样可以使我们减少出错。 14.这时已经能实现查找的功能了。但是我们刚才看到find 的返回类型是bool 型,而且,我们也应该为查找不到字符串作出提示。 if(!ui->textEdit->find(findText,QTextDocument::FindBackward)) { QMessageBox::warning(this,tr("查找"),tr("找不到 %1") .arg(findText); } 因为查找失败返回是false,所以if 条件加了“!”号。在找不到时弹出警 告对话框。 15.到这里,查找功能就基本上写完了。show_findText()函数的内容如下。 我们会发现随着程序功能的增强,其的函数也会越来越多,我们都会为查找 某个函数的定义位置感到头疼。而在Qt Creator 有几种快速定位函数的方法, 我们这里讲解三种。 第一,在函数声明的地方直接跳转到函数定义的地方。 如在do_file_Load 上点击鼠标右键,在弹出的菜单选择Follow Symbol under Cursor 或者下面的Switch between Method Declaration/Definition。 这时系统就会自动跳转到函数定义的位置。如下图。 第二,快速查找一个文件里的所有函数。 我们可以点击口最上面的下拉框,这里会显示本文件所有函数的列表。 第三,利用查找功能。 1.我们先将鼠标定位到一个函数名上。 2.然后选择Edit->Find/Replace->Find Dialog。 3.这时会出现一个查找对话框,可以看到要查找的函数名已经写在里面了。 4.当我们按下Search 按钮后,会在查找结果口显示查找到的结果。 5.我们点击第二个文件。会发现在这个文件有两处关键字是高亮显示。 6.我们双击第二项,就会自动跳转到函数的定义处。 文章讲到这里,我们已经很详细地说明了怎样去使用一个类里面没有用过的方法 函数;也说明了Qt Creator 的一些便捷操作。可以看到,Qt Creator 开发环 境,有很多很人性化的设计,我们应该熟练应用它们。 在以后的文章,我们不会再很详细地去用帮助来说明一个函数是 怎么来的,该怎么用,这些应该自己试着去查找。 八、Qt Creator 实现状态栏显示(原创) 在程序口Mainwindow ,有菜单栏,工具栏,心部件和状态栏。前面几 个已经讲过了,这次讲解状态栏的使用。 程序有哪些不明白的类或函数,请自己查看帮助。 1.我们在mainwindow.h 做一下更改。 加入头文件包含: #include Label> 加入私有变量和函数: QLabel* first_statusLabel; //声明两个标签对象,用于显示状态信息 QLabel* second_statusLabel; void init_statusBar(); //初始化状态栏 加入一个槽函数声明:void do_cursorChanged(); //获取光标位置信息 2.在mainwindow.cpp 加入状态栏初始化函数的定义。 void MainWindow::init_statusBar() { QStatusBar* bar = ui->statusBar; //获取状态栏 first_statusLabel = new QLabel; //新建标签 first_statusLabel->setMinimumSize(150,20); //设置标签最小尺寸 first_statusLabel->setFrameShape(QFrame::WinPanel); //设置标签形状 first_statusLabel->setFrameShadow(QFrame::Sunken); //设置标签阴影 second_statusLabel = new QLabel; second_statusLabel->setMinimumSize(150,20); second_statusLabel->setFrameShape(QFrame::WinPanel); second_statusLabel->setFrameShadow(QFrame::Sunken); bar->addWidget(first_statusLabel); bar->addWidget(second_statusLabel); first_statusLabel->setText(tr("欢迎使用文本编辑器")); //初始化内容 second_statusLabel->setText(tr("yafeilinux 制作!")); } 这里将两个标签对象加入到了口的状态栏里,并设置了他们的外观和初。 3.在构造函数里调用状态栏初始化函数。 init_statusBar(); 这时运行程序,效果如下。 4.在mainwindow.cpp 加入获取光标位置的函数的定义。 void MainWindow::do_cursorChanged() { int rowNum = ui->textEdit->document()->blockCount(); //获取光标所在行的行号 const QTextCursor cursor = ui->textEdit->textCursor(); int colNum = cursor.columnNumber(); //获取光标所在列的列号 first_statusLabel->setText(tr("%1 行 %2 列").arg(rowNum).arg(colNum)); //在状态栏显示光标位置 } 这个函数可获取文本编辑框光标的位置,并显示在状态栏。 5.在构造函数添加光标位置改变信号的关联。 connect(ui->textEdit,SIGNAL(cursorPositionChanged()),this,SLOT(do_cur sorChanged())); 这时运行程序。效果如下。 6.在do_file_Load 函数的最后添加下面语句。 second_statusLabel->setText(tr("打开文件成功")); 7.在saveFile 函数的最后添加以下语句。 second_statusLabel->setText(tr("保存文件成功")); 8.在on_action_Find_triggered 函数的后面添加如下语句。 second_statusLabel->setText(tr("正在进行查找")); 9.在on_action_Close_triggered 函数最后添加如下语句。 first_statusLabel->setText(tr("文本编辑器已关闭")); second_statusLabel->setText(tr("yafeilinux 制作!")); 到这里整个文本编辑器的程序就算写完了。我们这里没有写帮助菜单的功能实 现,大家可以自己添加。而且程序也有很多漏洞和不完善的地方,如果有兴 趣,大家也可以自己修改。因为时间和篇幅的原因,我们这里就不再过多的讲 述。 九、Qt Creator 鼠标键盘事件的处理实现自定义鼠标指针(原创) 我们前面一直在说信号,比方说用鼠标按了一下按钮,这样就会产生一个按钮的 单击信号,然后我们可以在相应的槽函数里进行相应功能的设置。其实在按下鼠 标后,程序要先接收到鼠标按下的事件,然后将这个事件按默认的设置传给按钮。 可以看出,事件和信号并不是一回事,事件比信号更底层。而我们以前把单击按 钮也叫做事件,这是不确切的,不过大家都知道是什么意思,所以当时也没有细 分。 Qt 的事件可以在QEvent 查看。下面我们只是找两个例子来进行简单的演示。 1.还是先建立一个Qt4 Gui Application 工程,我这里起名为event。 2.添加代码,让程序可以使用文。 即在main.cpp 文件加入#include TextCodec>的头文件包含。 再在下面的函数里添加 QTextCodec::setCodecForTr(QTextCodec::codecForLocale()); 3.在mainwindow.h 文件做一下更改。 添加#include 头文件。因为这样就包含了QtGui 所有的子文件。 在public 添加两个函数的声明 void mouseMoveEvent(QMouseEvent *); void keyPressEvent(QKeyEvent *); 4.我们在mainwindow.ui 添加一个Label 和一个PushButton,将他们拉长点, 因为一会要在上面显示标语。 5.在mainwindow.cpp 的构造函数里添加两个部件的显示文本。 ui->label->setText(tr("按下键盘上的A 键试试!")); ui->pushButton->setText(tr("按下鼠标的一个键,然后移动鼠标试试")); 6.然后在下面进行两个函数的定义。 /*以下是鼠标移动事件*/ void MainWindow::mouseMoveEvent(QMouseEvent *m) {//这里的函数名和参数不能更改 QCursor my(QPixmap("E:/Qt/Qt-Creator-Example/event/time.png")); //为鼠标指针选择图片,注意这里要用绝对路径,且要用“/”,而不能用“\” QApplication::setOverrideCursor(my); //将鼠标指针更改为自己设置的图片 int x = m->pos().x(); int y = m->pos().y(); //获取鼠标现在的位置坐标 ui->pushButton->setText(tr("鼠标现在的坐标是(%1,%2), 哈哈好玩吧 ").arg(x).arg(y)); //将鼠标的位置坐标显示在按钮上 ui->pushButton->move(m->pos()); //让按钮跟随鼠标移动 } /*以下是键盘按下事件*/ void MainWindow::keyPressEvent(QKeyEvent *k) { if(k->key() == Qt::Key_A) //判断是否是A 键按下 { ui->label->setPixmap(QPixmap("E:/Qt/Qt-Creator-Example/event/linux.jp g")); ui->label->resize(100,100); //更改标签图片和大小 } } 注意:这两个函数不是自己新建的,而是对已有函数的重定义,所有函数名和参 数都不能改。第一个函数对鼠标移动事件进行了重写。其实现了鼠标指针的更 改,和按钮跟随鼠标移动的功能。 第二个函数对键盘的A 键按下实现了新的功能。 效果如下。 按下鼠标的一个键,并移动鼠标。 按下键盘上的A 键。 十、Qt Creator 实现定时器和产生随机数(原创) 有两种方法实现定时器。 第一种。自己建立关联。 1.新建Gui 工程,工程名可以设置为timer。并在界面上添加一个标签label, 并设置其显示内容为“0000-00-00 00:00:00 星期日”。 2.在mainwindow.h 添加槽函数声明。 private slots: void timerUpDate(); 3.在mainwindow.cpp 添加代码。 添加#include 的头文件包含,这样就包含了QtCore 下的所有文件。 构造函数里添加代码: QTimer *timer = new QTimer(this); //新建定时器 connect(timer,SIGNAL(timeout()),this,SLOT(timerUpDate())); //关联定时器计满信号和相应的槽函数 timer->start(1000); //定时器开始计时,其1000 表示1000ms 即1 秒 4.然后实现更新函数。 void MainWindow::timerUpDate() { QDateTime time = QDateTime::currentDateTime(); //获取系统现在的时间 QString str = time.toString("yyyy-MM-dd hh:mm:ss dddd"); //设置系统时间显示格式 ui->label->setText(str); //在标签上显示时间 } 5.运行程序,效果如下。 第二种。使用事件。(有点像单片机的定时器啊) 1.新建工程。在口上添加两个标签。 2.在main.cpp 添加代码,实现文显示。 #include TextCodec> QTextCodec::setCodecForTr(QTextCodec::codecForLocale()); 3.在mainwindow.h 添加代码。 void timerEvent(QTimerEvent *); 4.在mainwindow.cpp 添加代码。 添加头文件#include 在构造函数里添加以下代码。 startTimer(1000); //其返回为1,即其timerId 为1 startTimer(5000);//其返回为2,即其timerId 为2 startTimer(10000); //其返回为3,即其timerId 为3 添加了三个定时器,它们的timerId 分别为1,2,3。注意,第几个定时器的返 回就为几。所以要注意定时器顺序。 在下面添加函数实现。 void MainWindow::timerEvent(QTimerEvent *t) //定时器事件 { switch(t->timerId()) //判断定时器的句柄 { case 1 : ui->label->setText(tr("每秒产生一个随机数: %1").arg(qrand()%10));break; case 2 : ui->label_2->setText(tr("5 秒后软件将关闭"));break; case 3 : qApp->quit();break; //退出系统 } } 这里添加了三个定时器,并都在定时器事件判断它们,然后执行相应的功能。 这样就不用每个定时器都写一个关联函数和槽函数了。 随机数的实现: 上面程序的qrand(),可以产生随机数,qrand()%10 可以产生0-9 之间的随机 数。要想产生100 以内的随机数就%100。以此类推。 但这样每次启动程序后,都按同一种顺序产生随机数。为了实现每次启动程序产 生不同的初始。我们可以使用qsrand(time(0));实现设置随机数的初,而 程序每次启动时time(0)返回的都不同,这样就实现了产生不同初始的功 能。 我们将qsrand(time(0));一句加入构造函数里。 程序最终运行效果如下。 十一、Qt 2D 绘图(一)绘制简单图形(原创) 声明:本文原创于yafeilinux 的百度博客,http://hi.baidu.com/yafeilinux 转载请注明出处。 说明:以后使用的环境为基于Qt 4.6 的Qt Creator 1.3.0 windows 版本 本文介绍在口上绘制最简单的图形的方法。 1.新建Qt4 Gui Application 工程,我这里使用的工程名为painter01,选用 QDialog 作为Base class 2.在dialog.h 文件声明重绘事件函数void paintEvent(QPaintEvent *); 3.在dialog.cpp 添加绘图类QPainter 的头文件包含#include 4.在下面进行该函数的重定义。 void Dialog::paintEvent(QPaintEvent *) { QPainter painter(this); painter.drawLine(0,0,100,100); } 其创建了QPainter 类对象,它是用来进行绘制图形的,我们这里画了一条线 Line,其的参数为线的起点(0,0),和终点(100,100)。这里的数指的 是像素,详细的坐标设置我们以后再讲,这里知道(0,0)点指的是口的左上 角即可。运行效果如下: 5.在qt 的帮助里可以查看所有的绘制函数,而且下面还给出了相关的例子。 6.我们下面将几个知识点说明一下,帮助大家更快入门。 将函数改为如下: void Dialog::paintEvent(QPaintEvent *) { QPainter painter(this); QPen pen; //画笔 pen.setColor(QColor(255,0,0)); QBrush brush(QColor(0,255,0,125)); //画刷 painter.setPen(pen); //添加画笔 painter.setBrush(brush); //添加画刷 painter.drawRect(100,100,200,200); //绘制矩形 } 这里的pen 用来绘制边框,brush 用来进行封闭区域的填充,QColor 类用来提供 颜色,我们这里使用了rgb 方法来生成颜色,即(red,green,blue),它们取 分别是0-255,例如(255,0,0)表示红色,而全0 表示黑色,全255 表示 白色。后面的(0,255,0,125),其的125 是透明度(alpha)设置,其 也是从0 到255,0 表示全透明。最后将画笔和画刷添加到painter 绘制设备, 画出图形。这里的Rect 是长方形,其的参数为(100,100)表示起始坐标, 200,200 表示长和宽。效果如下: 7.其实画笔和画刷也有很多设置,大家可以查看帮助。 QPainter painter(this); QPen pen(Qt::DotLine); QBrush brush(Qt::blue); brush.setStyle(Qt::HorPattern); painter.setPen(pen); painter.setBrush(brush); painter.drawRect(100,100,200,200); 这里我们设置了画笔的风格为点线,画刷的风格为并行横线,效果如下: 在帮助里可以看到所有的风格。 我们这里用了Qt::blue,Qt 自定义的几个颜色如下: 8.画弧线,这是帮助里的一个例子。 QRectF rectangle(10.0, 20.0, 80.0, 60.0); //矩形 int startAngle = 30 * 16; //起始角度 int spanAngle = 120 * 16; //跨越度数 QPainter painter(this); painter.drawArc(rectangle, startAngle, spanAngle); 这里要说明的是,画弧线时,角度被分成了十六分之一,就是说,要想为30 度, 就得是30*16。它有起始角度和跨度,还有位置矩形,要想画出自己想要的弧线, 就要有一定的几何知识了。这里就不再祥述。 十二、Qt 2D 绘图(二)渐变填充(原创) 声明:本文原创于yafeilinux 的百度博客,http://hi.baidu.com/yafeilinux 转载请注明出处。 在qt 提供了三种渐变方式,分别是线性渐变,圆形渐变和圆锥渐变。如果能 熟练应用它们,就能设计出炫目的填充效果。 线性渐变: 1.更改函数如下: void Dialog::paintEvent(QPaintEvent *) { QPainter painter(this); QLinearGradient linearGradient(100,150,300,150); //从点(100,150)开始到点(300,150)结束,确定一条直线 linearGradient.setColorAt(0,Qt::red); linearGradient.setColorAt(0.2,Qt::black); linearGradient.setColorAt(0.4,Qt::yellow); linearGradient.setColorAt(0.6,Qt::white); linearGradient.setColorAt(0.8,Qt::green); linearGradient.setColorAt(1,Qt::blue); //将直线开始点设为0,终点设为1,然后分段设置颜色 painter.setBrush(linearGradient); painter.drawRect(100,100,200,100); //绘制矩形,线性渐变线正好在矩形的水平心线上 } 效果如下: 圆形渐变: 1.更改函数内容如下: QRadialGradient radialGradient(200,100,100,200,100); //其参数分别为圆形渐变的圆心(200,100),半径100,和焦点(200, 100) //这里让焦点和圆心重合,从而形成从圆心向外渐变的效果 radialGradient.setColorAt(0,Qt::black); radialGradient.setColorAt(1,Qt::yellow); //渐变从焦点向整个圆进行,焦点为起始点0,圆的边界为1 QPainter painter(this); painter.setBrush(radialGradient); painter.drawEllipse(100,0,200,200); //绘制圆,让它正好和上面的圆形渐变的圆重合 效果如下: 2.要想改变填充的效果,只需要改变焦点的位置和渐变的颜色位置即可。 改变焦点位置:QRadialGradient radialGradient(200,100,100,100,100); 效果如下: 锥形渐变: 1.更改函数内容如下: //圆锥渐变 QConicalGradient conicalGradient(50,50,0); //圆心为(50,50),开始角度为0 conicalGradient.setColorAt(0,Qt::green); conicalGradient.setColorAt(1,Qt::white); //从圆心的0 度角开始逆时针填充 QPainter painter(this); painter.setBrush(conicalGradient); painter.drawEllipse(0,0,100,100); 效果如下: 2.可以更改开始角度,来改变填充效果 QConicalGradient conicalGradient(50,50,30); 开始角度设置为30 度,效果如下: 其实三种渐变的设置都在于焦点和渐变颜色的位置,如果想设计出漂亮的渐变 效果,还要有美术功底啊! 十二、Qt 2D 绘图(三)绘制文字(原创) 声明:本文原创于yafeilinux 的百度博客,http://hi.baidu.com/yafeilinux 转载请注明出处。 接着上一次的教程,这次我们学习在上绘制文字。 1.绘制最简单的文字。 我们更改重绘函数如下: void Dialog::paintEvent(QPaintEvent *) { QPainter painter(this); painter.drawText(100,100,"yafeilinux"); } 我们在(100,100)的位置显示了一行文字,效果如下。 2.为了更好的控制字的位置。我们使用另一个构造函数。在帮助里查看 drawText,如下。 这里我们看到了构造函数的原型和例子。其的flags 参数可以控制字在矩形 的位置。我们更改函数内容如下。 void Dialog::paintEvent(QPaintEvent *) { QPainter painter(this); QRectF ff(100,100,300,200); //设置一个矩形 painter.drawRect(ff); //为了更直观地看到字的位置,我们绘制出这个矩形 painter.setPen(QColor(Qt::red)); //设置画笔颜色为红色 painter.drawText(ff,Qt::AlignHCenter,"yafeilinux"); //我们这里先让字水平居 } 效果如下。 可以看到字符串是在最上面水平居的。如果想让其在矩形正间,我们可以使 用Qt::AlignCenter。 这里我们也可以使用两个枚举变量进行按位与操作,例如可以使用 Qt::AlignBottom|Qt::AlignHCenter 实现让文字显示在矩形下面的正间。效 果如下。 对于较长的字符串,我们也可以利用“\n”进行换行,例如"yafei\nlinux"。效 果如下。 3.如果要使文字更美观,我们就需要使用QFont 类来改变。先在帮助查 看一下这个类。 可以看到它有好几个枚举变量来设置字。下面的例子我们对要的几个选项进 行演示。 更改函数如下。 void Dialog::paintEvent(QPaintEvent *) { QFont font("Arial",20,QFont::Bold,true); //设置字的类型,大小,加粗,斜 font.setUnderline(true); //设置下划线 font.setOverline(true); //设置上划线 font.setCapitalization(QFont::SmallCaps); //设置大小写 font.setLetterSpacing(QFont::AbsoluteSpacing,5); //设置间距 QPainter painter(this); painter.setFont(font); //添加字 QRectF ff(100,100,300,200); painter.drawRect(ff); painter.setPen(QColor(Qt::red)); painter.drawText(ff,Qt::AlignCenter,"yafeilinux"); } 效果如下。 这里的所有字我们可以在设计器进行查看。如下。 基于Qt 4.6 的Qt Creator 1.3.0 环境变量设置(原创) 如果你以前安装过visual studio 2005 之类的软件,那么装上Qt Creator 1.3.0 后,编译运行其自带的演示程序时就可能出现如下图的,105 个错误,几十个警 告的问题。 我们查看输出口,如下图。会发现它居然显示VC98 之类的东西,就是说它并 没有去自己的include 文件夹 查找文件。我们可以怀疑是系统环境变量的问题了。 点击Qt Creator 界面左侧的projects 图标,查看工程信息。这里我们要查看 编辑环境Buid Environment,点击其右侧的show Details。 可以看到其的include 和lib 均指向了virtual studio 文件夹,我们需要 将其改正。 将他们都改为自己Qt Creator 安装目录下的相关路径,如下图。(要换成你的 安装路径) 改完后会发现新的设置已经显示出来了。 我们查看下面的Run Environment,发现它已经自己改过来了。 回到编辑界面,右击工程文件,在弹出的菜单上选择Clean project,清空以前 的编译信息。 然后运行Run qmake,生成Makefile 文件。 最后,点击run 或者build 都可,这时程序已经能正常编译运行了。 基于Qt 4.6 的Qt Creator 1.3.0 写helloworld 程序注意事项(原创) 注意:下面指的是在windows 下,linux 下的情况可进行相应改变 昨天Qt 4.6 和Qt Creator 1.3.0 正式版发布了,但是如果以前用过旧版本,就 可能出一些问题。 1.用debug 方式 如果你以前用了Qt 4.5 的Qt Creator,并且将QtCored4.dll,QtGuid4.dll, mingwm10.dll 等文件放到了C 盘的system 文件夹下。那么请先将它们删除,不 然编译不会通过。 编译完helloworld 程序后,如果要直接执行exe 文件,需要将安装目录(新版 Qt)下的qt/bin 目录下的QtCored4.dll,QtGuid4.dll,mingwm10.dll,和 libgcc_s_dw2-1.dll(这个是新增的)文件放在exe 文件夹。或者将它们放到 系统的system 文件夹下。 2.选择release 方式 编译程序后生成exe 文件 1.需要Qt 安装目录下的qt/bin 目录的QtGui4.dll ,Qt Core4.dll, libgcc_s_dw2-1.dll 以及mingwm10.dll 四个文件的支持,将它们拷贝到exe 文 件目录下。 2.程序默认只支持png 图片,如果使用了gif,jpg 等格式的文件是显示不出 来的。需要将Qt 安装目录下的qt/plugins/目录的imageformats 文件夹拷贝 到exe 文件目录下(注意是整个文件夹)。而imageformats 文件夹只需要保 留你需要的文件,例如你只需要支持gif 文件,就只保留qgif4.dll 即可。 ‘Qt Creator 发布release 软件相关注意事项(原创) 注意:环境是windows 选择release 编译程序后生成exe 文件 1.需要Qt 安装目录下的qt/bin 目录的QtGui4.dll 和 Qt Core4.dll 以及 mingwm10.dll 三个文件的支持,将它们拷贝到exe 文件目录下。 2.程序默认只支持png 图片,如果使用了gif,jpg 等格式的文件是显示不出 来的。需要将Qt 安装目录下的qt/plugins/目录的imageformats 文件夹拷贝 到exe 文件目录下(注意是整个文件夹)。而imageformats 文件夹只需要保 留你需要的文件,例如你只需要支持gif 文件,就只保留qgif4.dll 即可。 Qt Creator 的 error: collect2: ld returned 1 exit status 问题 利用Qt Creator 1.2.1( Built on Sep 30 2009 at 05:21:42)编译 程序经常会出现error: collect2: ld returned 1 exit status 的错误,但是 自己的程序没有一点问题,怎么回事呢? 如果这时退出软件,再重新进入,打开刚才的工程,重新编译, 就不会出现刚才的错误了。这应该是Qt Creator 软件的问题吧! 后来发现是因为上次执行的程序还在运行,你打开windows 的任 务管理器的进程可以看见你刚才运行的程序还在执行,我们看不见,是因为它 在后台执行着。出现这个现象,是因为你写的代码的问题,比如在main 函数里 用了w.show();语句,就可能出现界面一闪而过,但它并没有关闭,而是在后台 运行,所以再次运行时就会出错。我们可以在资源管理器将该进程关闭,或者 像上面那样直接关闭Qt Creator。 示例: #include #include "widget.h" #include "logindlg.h" int main(int argc, char *argv[]) { QApplication a(argc, argv); loginDlg m; if(m.exec()==QDialog::Accepted) { Widget w; w.show(); } return a.exec(); } 执行后就会在后台运行。这时如果修改了代码再次运行程序,就会出现上面的错 误。 在任务管理器可以看见自己的程序: 将该进程结束,然后在重新运行,就不会出错了。 正确的代码应该这样写: int main(int argc, char *argv[]) { QApplication a(argc, argv); loginDlg m; Widget w; if(m.exec()==QDialog::Accepted) { w.show(); return a.exec(); } else return 0; //关闭整个程序 } 这样新建的对象w 就不是局部变量了,这样运行程序w 表示的口不会一闪而过, 会一直显示。程序也不会再出现上面的错误了。 QT 常用问题解答(转) 本文是我前几天一个网友告诉我的,当时看了感觉好,就保存下来。今天再次查 看,感觉有必要把文章分享给各位学习QT 的朋友,因为网上好用的QT 资源真的 好少。 1、如果在关闭前自行判断是否可关闭 答:重新实现这个的closeEvent()函数,加入判断操作 Quote: void MainWindow::closeEvent(QCloseEvent *event) { if (maybeSave()) { writeSettings(); event->accept(); } else { event->ignore(); } } 2、如何用打开和保存文件对话 答:使用QFileDialog Quote: QString fileName = QFileDialog::getOpenFileName(this); if (!fileName.isEmpty()) { loadFile(fileName); } Quote: QString fileName = QFileDialog::getSaveFileName(this); if (fileName.isEmpty()) { return false; } 3、如果创建Actions(可在菜单和工具栏里使用这些Action) 答: Quote: newAct = new QAction(QIcon(":/images/new.png"), tr("&New"), this); newAct->setShortcut(tr("Ctrl+N")); newAct->setStatusTip(tr("Create a new file")); connect(newAct, SIGNAL(triggered()), this, SLOT(newFile())); openAct = new QAction(QIcon(":/images/open.png"), tr("&Open..."), this); openAct->setShortcut(tr("Ctrl+O")); openAct->setStatusTip(tr("Open an existing file")); connect(openAct, SIGNAL(triggered()), this, SLOT(open())); saveAct = new QAction(QIcon(":/images/save.png"), tr("&Save"), this); saveAct->setShortcut(tr("Ctrl+S")); saveAct->setStatusTip(tr("Save the document to disk")); connect(saveAct, SIGNAL(triggered()), this, SLOT(save())); saveAsAct = new QAction(tr("Save &As..."), this); saveAsAct->setStatusTip(tr("Save the document under a new name")); connect(saveAsAct, SIGNAL(triggered()), this, SLOT(saveAs())); exitAct = new QAction(tr("E&xit"), this); exitAct->setShortcut(tr("Ctrl+Q")); exitAct->setStatusTip(tr("Exit the application")); connect(exitAct, SIGNAL(triggered()), this, SLOT(close())); cutAct = new QAction(QIcon(":/images/cut.png"), tr("Cu&t"), this); cutAct->setShortcut(tr("Ctrl+X")); cutAct->setStatusTip(tr("Cut the current selection's contents to the " "clipboard")); connect(cutAct, SIGNAL(triggered()), textEdit, SLOT(cut())); copyAct = new QAction(QIcon(":/images/copy.png"), tr("&Copy"), this); copyAct->setShortcut(tr("Ctrl+C")); copyAct->setStatusTip(tr("Copy the current selection's contents to the " "clipboard")); connect(copyAct, SIGNAL(triggered()), textEdit, SLOT(copy())); pasteAct = new QAction(QIcon(":/images/paste.png"), tr("&Paste"), this); pasteAct->setShortcut(tr("Ctrl+V")); pasteAct->setStatusTip(tr("Paste the clipboard's contents into the current " "selection")); connect(pasteAct, SIGNAL(triggered()), textEdit, SLOT(paste())); aboutAct = new QAction(tr("&About"), this); aboutAct->setStatusTip(tr("Show the application's About box")); connect(aboutAct, SIGNAL(triggered()), this, SLOT(about())); aboutQtAct = new QAction(tr("About &Qt"), this); aboutQtAct->setStatusTip(tr("Show the Qt library's About box")); connect(aboutQtAct, SIGNAL(triggered()), qApp, SLOT(aboutQt())); 4、如果创建菜单 答:采用上面的QAction 的帮助,创建菜单 Quote: fileMenu = menuBar()->addMenu(tr("&File")); fileMenu->addAction(newAct); fileMenu->addAction(openAct); fileMenu->addAction(saveAct); fileMenu->addAction(saveAsAct); fileMenu->addSeparator(); fileMenu->addAction(exitAct); editMenu = menuBar()->addMenu(tr("&Edit")); editMenu->addAction(cutAct); editMenu->addAction(copyAct); editMenu->addAction(pasteAct); menuBar()->addSeparator(); helpMenu = menuBar()->addMenu(tr("&Help")); helpMenu->addAction(aboutAct); helpMenu->addAction(aboutQtAct); 5、如果创建工具栏 答:采用上面的QAction 的帮助,创建工具栏 Quote: fileToolBar = addToolBar(tr("File")); fileToolBar->addAction(newAct); fileToolBar->addAction(openAct); fileToolBar->addAction(saveAct); editToolBar = addToolBar(tr("Edit")); editToolBar->addAction(cutAct); editToolBar->addAction(copyAct); editToolBar->addAction(pasteAct); 6、如何使用配置文件保存配置 答:使用QSettings 类 Quote: QSettings settings("Trolltech", "Application Example"); QPoint pos = settings.value("pos", QPoint(200, 200)).toPoint(); QSize size = settings.value("size", QSize(400, 400)).toSize(); Quote: QSettings settings("Trolltech", "Application Example"); settings.setValue("pos", pos()); settings.setValue("size", size()); 7、如何使用警告、信息等对话框 答:使用QMessageBox 类的静态方法 Quote: int ret = QMessageBox::warning(this, tr("Application"), tr("The document has been modified.\n" "Do you want to save your changes?"), QMessageBox::Yes | QMessageBox::Default, QMessageBox::No, QMessageBox::Cancel | QMessageBox::Escape); if (ret == QMessageBox::Yes) return save(); else if (ret == QMessageBox::Cancel) return false; 8、如何使通用对话框文化 答:对话框的文化 比 如说,QColorDialog 的与文字相关的部分,要在qcolordialog.cpp 文件 ,我们可以从qcolordialog.cpp 用 lupdate 生成一个ts 文件,然后用自定 义这个ts 文件的翻译,再用lrelease 生成一个.qm 文件,当然了,程序就要 改变要支持多国语言了, 使用这个.qm 文件就可以了。 另外,还有一个更快的方法,在源代码解开后有一个目录translations,下面 有一些.ts, .qm 文件,我们拷贝一个: Quote: cp src/translations/qt_untranslated.ts ./qt_zh_CN.ts 然 后,我们就用Linguist 打开这个qt_zh_CN.ts,进行翻译了,翻译完成后, 保存后,再用lrelease 命令生成qt_zh_CN.qm, 这样,我们把它加入到我们的 qt project ,那些系统的对话框,菜单等等其它的默认是英文的东西就能显 示成文了。 9、在Windows 下Qt 里为什么没有终端输出? 答:把下面的配置项加入到.pro 文件 Quote: win32:CONFIG += console 10、Qt 4 for X11 OpenSource 版如何静态链接? 答:编译安装的时候加上-static 选项 Quote: ./configure -static //一定要加static 选项 gmake gmake install 然后,在Makefile 文件加 static 选项或者在.pro 文件加上QMAKE_LFLAGS += -static,就可以连接静态库了。 11、想在源代码直接使用文,而不使用tr()函数进行转换,怎么办? 答:在main 函数加入下面三条语句,但并不提倡 Quote: QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8")); QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8")); QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8")); 或者 Quote: QTextCodec::setCodecForLocale(QTextCodec::codecForName("GBK")); QTextCodec::setCodecForCStrings(QTextCodec::codecForName("GBK")); QTextCodec::setCodecForTr(QTextCodec::codecForName("GBK")); 使用GBK 还是使用UTF-8,依源文件汉字使用的内码而定 这样,就可在源文件直接使用文,比如: Quote: QMessageBox::information(NULL, "信息", "关于本软件的演示信息", QMessageBox::Ok, QMessageBox::NoButtons); 12、为什么将开发的使用数据库的程序发布到其它机器就连接不上数据库? 答:这是由于程序找不到数据库插件而致,可照如下解决方法: 在main 函数加入下面语句: Quote: QApplication::addLibraryPath(strPluginsPath"); strPluginsPath 是插件所在目录,比如此目录为/myapplication/plugins 则将需要的sql 驱动,比如qsqlmysql.dll, qsqlodbc.dll 或对应的.so 文件放 到 /myapplication/plugins/sqldrivers/ 目录下面就行了 这是一种解决方法,还有一种通用的解决方法,即在可执行文件目录下写 qt.conf 文件,把系统相关的一些目录配置写到qt.conf 文件里,详细情况情参 考Qt Document Reference 里的qt.conf 部分 13、如何创建QT 使用的DLL(.so)以及如何使用此DLL(.so) 答:创建DLL 时其工程使用lib 模板 Quote: TEMPLATE=lib 而源文件则和使用普通的源文件一样,注意把头文件和源文件分开,因为在其它 程序使用此DLL 时需要此头文件 在使用此DLL 时,则在此工程源文件引入DLL 头文件,并在.pro 文件加入 下面配置项: Quote: LIBS += -Lyourdlllibpath -lyourdlllibname Windows 下和Linux 下同样(Windows 下生成的DLL 文件名为yourdlllibname.dll 而在Linux 下生成的为libyourdlllibname.so。注意,关于DLL 程序的写法, 遵从各平台级编译器所定的规则。 14、如何启动一个外部程序 答:1、使用QProcess::startDetached()方法,启动外部程序后立即返回; 2、使用QProcess::execute(),不过使用此方法时程序会最阻塞直到此方法执 行的程序结束后返回
《C#全能速查宝典》共分为8章,分别介绍了C#语言基础、Windows及常用控件、Windows高级控件、控件公共属性、方法及事件、数据库开发、文件、数据流与注册表、GDI+绘图技术和C#高级编程,共包含562个C#编程常用的属性、方法、类和各种技术,每一个知识点都配有具的示例,便于读者理解。 《C#全能速查宝典》所讲的知识点按照功能和字母进行排序,读者既可以按照功能顺序查找,又可以按照字母顺序学习。 《C#全能速查宝典》不仅适合C#程序设计初学者,也可作为、高级程序开发人员的参考手册。 ============================================================ 图书目录 第1章 C#语言基础 1 1.1 常用概念、关键字及基础类 1 1.1.1 abstract关键字——抽象 1 1.1.2 as操作符——引用类型转换 3 1.1.3 base关键字——从派生类访问基类的成员 3 1.1.4 变量——存储特定类型的数据 4 1.1.5 Console类——控制台的输入流、输出流和错误流 6 1.1.6 Convert类——类型转换 8 1.1.7 常量——改变的量 9 1.1.8 Dispose方法——释放资源 10 1.1.9 迭代器——相同类型的的有序序列的一段代码 10 1.1.10 泛型——处理算法和数据结构 11 1.1.11 分部类——将一个类分成几部分 12 1.1.12 is操作符——检查变量是否为指定的类型 14 1.1.13 lock关键字——锁定 15 1.1.14 namespace关键字——定义命名空间 15 1.1.15 new运算符——创建一个新的类型实例 16 1.1.16 Object类型——所有类型的基类 17 1.1.17 OOP技术——面向对象编程技术 18 1.1.18 ReadLine方法——从当前流读取一行字符 20 1.1.19 typeof运算符——获得系统原型对象的类型 21 1.1.20 using关键字——引入命名空间 22 1.1.21 WriteLine方法——写入流 23 1.2 数学方法类——Math 25 1.2.1 Abs方法——返回指定数字的绝对 25 1.2.2 Acos方法——返回余弦为指定数字的角度 26 1.2.3 Asin方法——返回正弦为指定数字的角度 26 1.2.4 Atan方法——返回正切为指定数字的角度 27 1.2.5 Pow方法——返回指定数字的指定次幂 27 1.2.6 Round方法——将小数舍入到指定的精度 28 1.3 流程控制语句 29 1.3.1 break语句——跳出循环 29 1.3.2 case语句——比较表达式以确定结果 30 1.3.3 continue语句——继续执行下一个循环 31 1.3.4 do…while语句——循环语句 31 1.3.5 for语句——循环语句 32 1.3.6 foreach语句——枚举一个集合的元素 33 1.3.7 goto语句——跳转到标签 34 1.3.8 if…else语句——条件判断语句 36 1.3.9 return语句——返回 38 1.3.10 switch case语句——条件判断语句 39 1.3.11 throw语句——显式引发异常 40 1.3.12 try…catch…finally语句——捕捉异常 42 1.3.13 while语句——循环语句 43 1.4 字符串处理 44 1.4.1 AddDays方法——添加天数 44 1.4.2 AddString方法——添加文本字符串 45 1.4.3 Compare方法——比较两个字符串 46 1.4.4 CompareTo方法——比较两个字符串对象 47 1.4.5 DATEADD函数——在指定日期上加一段时间 48 1.4.6 DateDiff方法——获取日期时间的间隔数 48 1.4.7 DateTime结构——表示时间上的一刻 50 1.4.8 DAY函数——返回日期部分的整数 51 1.4.9 DayOfWeek属性——获取星期几 52 1.4.10 Equals方法——比较两个字符串对象 53 1.4.11 First函数——返回查询结果的第一个记录 55 1.4.12 FirstDayOfWeek属性——获取或设置一周的第一天 56 1.4.13 Format方法——格式化字符串 56 1.4.14 GETDATE函数——返回当前系统日期和时间 58 1.4.15 GetDayOfMonth方法——返回几号 59 1.4.16 GetDayOfWeek方法——返回星期几 59 1.4.17 GetDayOfYear方法——返回第几天 60 1.4.18 GetDaysInMonth方法——返回指定月份的天数 60 1.4.19 GetDaysInYear方法——返回指定年份的天数 61 1.4.20 GetMonth方法——返回指定日期的月份 61 1.4.21 GetMonthsInYear方法——返回指定年份的月数 62 1.4.22 GetText方法——检索文本数据 63 1.4.23 GetYear方法——返回指定日期的年份 64 1.4.24 IndexOf方法——确定指定字符在字符串的索引 65 1.4.25 IsLeapYear方法——判断年份是否为闰年 67 1.4.26 IsMatch方法——搜索正则表达式匹配项 67 1.4.27 IsUpper方法——判断是否大写 68 1.4.28 Join方法——串联字符串 69 1.4.29 LastIndexOf方法——确定字符在字符串最后索引 70 1.4.30 Matches方法——检查字符串是否有重复的词出现 71 1.4.31 MONTH函数——返回指定日期月部分的整数 73 1.4.32 PadLeft方法——在左边用空格填充 73 1.4.33 PadRight方法——在右边用空格填充 74 1.4.34 Random类——伪随机数生成器 75 1.4.35 Regex类——正则表达式 76 1.4.36 Split方法——分割字符串 78 1.4.37 String类——字符串 79 1.4.38 StringBuilder类——可变字符串 82 1.4.39 Substring方法——截取字符串 83 1.4.40 TimeSpan对象——表示时间间隔或持续时间 84 1.4.41 ToInt32方法——转换为32位有符号整数 85 1.4.42 ToLongDateString 方法——转换为长日期字符串 86 1.4.43 ToLongTimeString 方法——转换为长时间字符串 87 1.4.44 ToLower方法——转换为小写 87 1.4.45 ToShortDateString方法——转换为短日期字符串 88 1.4.46 ToShortTimeString方法——转换为短时间字符串 88 1.4.47 ToString方法——转换为字符串 89 1.4.48 ToUpper方法——转换为大写 90 1.4.49 Trim方法——移除所有空白字符 91 1.4.50 TrimEnd方法——从尾部移除匹配项 92 1.4.51 TrimStart方法——从开始移除匹配项 92 1.4.52 YEAR函数——返回指定日期的年份的整数 93 1.5 数组与集合 93 1.5.1 Add方法——添加项 93 1.5.2 ArrayList类——集合 95 1.5.3 AsEnumerable方法——转换为IEnumerable类型 97 1.5.4 Clear方法——清空内容 98 1.5.5 Contains方法——确定是否包含某项 99 1.5.6 ContainsKey方法——确定哈希表是否包含特定键 100 1.5.7 ContainsText方法——确定剪贴板是否存在数据 101 1.5.8 ContainsValue方法——确定哈希表是否包含特定 101 1.5.9 Count属性——获取数目 102 1.5.10 GetEnumerator方法——循环访问对象 103 1.5.11 GetEnvironmentVariables方法——检索环境变量 104 1.5.12 Hashtable类——哈希表 106 1.5.13 Insert方法——插入项 110 1.5.14 Item属性——获取或设置指定索引处的元素 111 1.5.15 Length属性——获取长度 112 1.5.16 Next方法——返回一个指定范围内的随机数 113 1.5.17 Queue类——队列 115 1.5.18 Remove方法——移除指定项 116 1.5.19 RemoveAt方法——移除指定索引处的项 118 1.5.20 Replace方法——替换文件或字符串 119 1.5.21 Reverse方法——反转数组元素 120 1.5.22 Sort方法——数组排序 121 1.5.23 Stack类——堆栈 123 第2章 Windows及常用控件 126 2.1 Form 126 2.1.1 AcceptButton属性——设置接受按钮 126 2.1.2 Activate事件——当激活时发生 126 2.1.3 Appllication类——提供管理应用程序的静态方法 126 2.1.4 CancelButton属性——设置取消按钮 128 2.1.5 Computer类——提供操作计算机组件的属性 129 2.1.6 ComputerInfo类——获取计算机信息 130 2.1.7 Control类——定义控件基类 131 2.1.8 Environment类——提供当前环境和平台的信息 134 2.1.9 Form——可视化界面 136 2.1.10 FormClosed事件——关闭后事件 139 2.1.11 FormClosing事件——关闭前事件 139 2.1.12 Icon属性——设置图标 139 2.1.13 IsMdiContainer属性——设置父 140 2.1.14 LayoutMdi方法——排列子 141 2.1.15 Load事件——加载事件 141 2.1.16 MaximizeBox属性——是否显示最大化按钮 142 2.1.17 Maximum属性——设置数字显示框的最大 142 2.1.18 MDI——多文档界面 143 2.1.19 MdiChildren属性——获取子的数组 146 2.1.20 MdiParent属性——设置父 147 2.1.21 MinimizeBox属性——是否显示最小化按钮 147 2.1.22 Minimum属性——数字显示框的最小 148 2.1.23 Opacity属性——设置的透明度级别 148 2.1.24 Owner属性——设置所有者 149 2.1.25 StartPosition属性——设置起始位置 150 2.1.26 StartupPath 属性——获取可执行文件路径 150 2.1.27 TopMost属性——是否应显示为最顶层 151 2.1.28 WindowState属性——口状态 151 2.2 文本类控件 152 2.2.1 AllowEdit属性——是否可以编辑列表项 152 2.2.2 AppendText方法——追加文本 152 2.2.3 BeginEdit方法——将单元格置于编辑模式下 153 2.2.4 Button控件——按钮控件 153 2.2.5 CancelEdit属性——取消更改 155 2.2.6 CanPaste方法——是否可以粘贴数据 155 2.2.7 CanRedo属性——是否有可以重新应用的操作 156 2.2.8 CanSelect属性——是否可以选控件 157 2.2.9 CanUndo属性——能否撤销上一个操作 157 2.2.10 Cut方法——将选定内容移动到“剪贴板” 158 2.2.11 Find方法——搜索指定的项目 158 2.2.12 FindString方法——搜索文本 160 2.2.13 Label控件——标签控件 161 2.2.14 LabelEdit属性——允许用户编辑控件数据 163 2.2.15 LinkLabel控件——以超链接形式显示文本 164 2.2.16 MaskedTextBox控件——使用掩码区分用户输入 166 2.2.17 Multiline属性——是否为多行输入数据 169 2.2.18 PasswordChar属性——取代用户输入而显示的字符 170 2.2.19 Redo方法——重新应用控件上次撤销的操作 171 2.2.20 RichTextBox控件——有格式文本控件 171 2.2.21 Select方法——激活控件 173 2.2.22 SelectAll方法——选定所有文本 176 2.2.23 Selected属性——是否选定 176 2.2.24 SelectedCells属性——用户选定的单元格集合 177 2.2.25 SelectedColumns属性——用户选定的列集合 178 2.2.26 SelectedRows属性——用户选定的行集合 179 2.2.27 SelectionBackColor属性——文本在选时的颜色 180 2.2.28 SelectionColor属性——插入点的文本颜色 180 2.2.29 SelectionEnd属性——设置选定日期范围的结束日期 181 2.2.30 SelectionFont属性——选定文本或插入点的字 182 2.2.31 SelectionIndent属性——所选内容开始行的缩进距离 183 2.2.32 SelectionLength属性——控件选定的字符数 184 2.2.33 SelectionRange 属性——设置选定的日期范围 185 2.2.34 SelectionStart属性——选择的起始位置的字符索引 185 2.2.35 TextBox控件——输入或显示文本 186 2.2.36 TextChanged事件——Text属性更改时发生 187 2.3 选择类控件 188 2.3.1 CheckBox控件——复选框控件 188 2.3.2 CheckBoxes属性——是否显示复选框 190 2.3.3 Checked属性——复选框是否处于选状态 190 2.3.4 CheckedChanged事件——Checked属性更改时发生 191 2.3.5 CheckedListBox控件——复选框列表控件 191 2.3.6 CheckState属性——设置CheckBox控件的状态 193 2.3.7 ComboBox控件——下拉组合框控件 194 2.3.8 DomainUpDown控件——上下选择控件 195 2.3.9 DropDownStyle属性——指定组合框样式的 197 2.3.10 GetItemCheckState方法——当前项的复选状态的 198 2.3.11 GetItemText方法——指定项的文本表示形式 199 2.3.12 Index属性——从零开始的索引 200 2.3.13 Items属性——数组列表对象的项的集合 200 2.3.14 ListBox控件——列表控件 201 2.3.15 ListView控件——显示带图标的项列表 205 2.3.16 NumericUpDown控件——数选择控件 208 2.3.17 RadioButton控件——单选按钮 210 2.3.18 SelectedIndex属性——获取选择项的索引 212 2.3.19 SelectedIndices属性——表示当前选的项 213 2.3.20 SelectedItem属性——当前选的项 214 2.3.21 SelectedItems属性——选定项的集合 215 2.3.22 SelectedText属性——选定文本 216 2.4 容器类控件 217 2.4.1 FlatStyle属性——设置控件的平面样式外观 217 2.4.2 FlowDirection属性——指示FlowLayoutPanel控件的流向 217 2.4.3 FlowLayoutPanel控件——水平或垂直排列内容 218 2.4.4 GroupBox控件——分组控件 219 2.4.5 Panel控件——容器控件 220 2.4.6 TabControl控件——选项卡控件 222 2.4.7 TabIndex属性——控件的Tab键顺序 224 2.4.8 TabPages属性——选项卡页的集合 224 第3章 Windows高级控件 226 3.1 日期时间类控件 226 3.1.1 CalendarFont属性——日历的字样式 226 3.1.2 CalendarForeColor属性——日历的前景色 226 3.1.3 DateTimePicker控件——日期和日历的组合 226 3.1.4 MaxDate属性——最大日期和时间 228 3.1.5 MinDate属性——最小日期和时间 228 3.1.6 MonthCalendar控件——以网格形式显示日历 229 3.1.7 SetDate方法——将日期设置为当前选定的日期 231 3.1.8 ShowToday属性——是否显示当前日期 232 3.2 对话框、菜单、工具栏及状态栏控件 232 3.2.1 ColorDialog控件——颜色对话框 232 3.2.2 ContextMenuStrip控件——右键快捷菜单 233 3.2.3 ExpandAll方法——展开所有树节点 233 3.2.4 Filter属性——设置筛选器字符串 234 3.2.5 FolderBrowserDialog控件——浏览文件夹对话框 234 3.2.6 Font属性——设置字 235 3.2.7 FontDialog控件——字对话框 235 3.2.8 InitialDirectory属性——文件对话框显示的初始目录 237 3.2.9 MenuStrip控件——菜单控件 238 3.2.10 Nodes属性——树节点集合 241 3.2.11 OpenFileDialog控件——打开文件对话框 241 3.2.12 RestoreDirectory属性——是否还原当前目录 244 3.2.13 RootFolder属性——设置浏览的根文件夹 245 3.2.14 SaveFileDialog组件——保存文件对话框 246 3.2.15 SelectedNode属性——获取选定的树节点 248 3.2.16 SelectedPath属性——用户选定的路径 249 3.2.17 ShowDialog方法——打开模式对话框 249 3.2.18 ToolStrip控件——工具栏控件 251 3.2.19 TreeNode类——树节点 252 3.2.20 TreeView控件——树控件 254 3.3 数据绑定类控件 256 3.3.1 BindingNavigator控件——导航和操作数据 256 3.3.2 Cell对象——表示Word文档的单元格 258 3.3.3 CellClick事件——单元格的任何部分被单击时发生 259 3.3.4 CellEnter事件——控件接收到输入焦点时发生 260 3.3.5 CellMouseClick事件——鼠标单击单元格时发生 261 3.3.6 CellLeave事件——单元格失去输入焦点时发生 261 3.3.7 Cells属性——Bookmark控件的表单元格 261 3.3.8 ColumnCount属性——DataGridView控件显示的列数 262 3.3.9 Columns属性——控件所有列的集合 262 3.3.10 ColumnWidth属性——ListBox列的宽度 263 3.3.11 CurrentCell属性——设置当前处于活动状态的单元格 263 3.3.12 CurrentRow属性——包含当前单元格的行 263 3.3.13 DataGridView控件——数据控件 264 3.3.14 FullRowSelect属性——是否选择其所有子项 268 3.3.15 GetCellCount方法——获取满足筛选器的单元格数目 269 3.3.16 GetColumn方法——指定子控件的列位置 270 3.3.17 NewRow方法——添加一条新记录 270 3.3.18 RowCount方法——DataGridView显示的行数 271 3.3.19 Rows属性——DataGridView控件的所有行 272 3.4 打印类控件 273 3.4.1 CrystalReportViewer控件——水晶报表查看控件 273 3.4.2 Document属性——设置要预览的文档 280 3.4.3 PageSetupDialog组件——配置页面的对话框 281 3.4.4 Print方法——打印当前页面 283 3.4.5 PrintDialog组件——打印对话框 283 3.4.6 PrintDocument组件——设置打印的文档 286 3.4.7 PrinterSettings属性——打印机设置 291 3.4.8 PrintPage事件——当需要为当前页打印的输出时发生 292 3.4.9 PrintPreviewControl组件——按文档打印时的外观显示Print Document组件 292 3.4.10 PrintPreviewDialog组件——显示PrintDocument组件在打印时的外观 295 3.4.11 PrinterSettings类——用来指定有关文档打印方式的信息 297 3.4.12 Zoom属性——指示页面的显示大小 300 3.5 其他常用组件 300 3.5.1 BackgroundWorker组件——在线程的另一线程上异步执行耗时的操作 300 3.5.2 ErrorProvider控件——检查并显示错误信息 302 3.5.3 EventLog组件——连接本地和远程计算机的事件日志 303 3.5.4 HelpProvider组件——将帮助文件与Windows应用程序相关联 306 3.5.5 HScrollBar控件——一个标准Windows水平滚动条 309 3.5.6 Image属性——显示在控件上的图像 311 3.5.7 ImageAlign属性——在控件显示的图像的对齐方式 312 3.5.8 ImageFormat类——指定图像的格式 312 3.5.9 ImageList组件——用于存储图像 314 3.5.10 ImageList属性——在控件显示的图像的ImageList 316 3.5.11 Interval属性——设置Timer控件执行的间隔 317 3.5.12 NotifyIcon控件——设置程序的系统托盘图标 317 3.5.13 PerformStep方法——按照Step属性的数量增加进度栏的当前位置 319 3.5.14 PictrueBox控件——用于显示指定的图像 320 3.5.15 Play方法——播放.wav文件 323 3.5.16 ProgressBar控件——进度条 323 3.5.17 SetError方法——设置错误信息 326 3.5.18 SetShowHelp方法——是否显示帮助信息 327 3.5.19 SetToolTip方法——设置提示文本 328 3.5.20 Step属性——增加进度条的当前位置时所根据的数量 328 3.5.21 Stop方法——停止加载网页 329 3.5.22 Tick事件——计时器处于启用状态时发生 330 3.5.23 Timer组件——定期引发事件的组件 330 3.5.24 ToolTip控件——显示提示信息 332 3.5.25 ToolTipIcon属性——提示文本旁显示的图标类型 333 3.5.26 ToolTipText属性——ToolTip显示的文本 334 3.5.27 ToolTipTitle属性——工具提示口的标题 334 3.5.28 TrackBar控件——标准的Windows跟踪条 335 3.5.29 Url属性——引用服务说明的URL 337 3.5.30 VscrollBar控件——标准的Windows垂直滚动条 337 3.5.31 WebBrowser控件——在显示网页 339 3.5.32 Windows Media Player控件——播放常见的音频文件 343 第4章 控件公共属性、方法及事件 347 4.1 控件公共属性 347 4.1.1 BackColor属性——设置控件的背景色 347 4.1.2 BackgroudColor属性——设置控件背景色 347 4.1.3 BackgroudImage属性——设置控件背景图像 347 4.1.4 Border属性——控件边框 348 4.1.5 BorderStyle属性——控件的边框样式 349 4.1.6 Bottom属性——控件下边缘与其容器的工作区上边缘之间的距离 349 4.1.7 CanFocus属性——控件是否可以接收焦点 350 4.1.8 Capture属性——控件是否已捕获鼠标 350 4.1.9 Color属性——设置用户选定的颜色 350 4.1.10 Dock属性——控件在的布局样式 351 4.1.11 Enabled属性——控件是否可用 352 4.1.12 ForeColor属性——设置控件的前景色 352 4.1.13 Handle属性——获取控件绑定到的口句柄 352 4.1.14 Height属性——设置控件的高度 353 4.1.15 KeyChar属性——设置与按下的键对应的字符 354 4.1.16 KeyValue属性——获取KeyDown或KeyUp事件的键盘 355 4.1.17 Lines属性——设置多行配置的文本行 355 4.1.18 Location属性——控件的左上角相对于其容器的左上角的坐标 356 4.1.19 Name属性——控件或实例的名称 356 4.1.20 Parent属性——设置控件的父容器或获取指定子目录的父目录 357 4.1.21 Position属性——设置坐标 358 4.1.22 ReadOnly属性——是否只读 359 4.1.23 Right属性——控件右边缘与其容器的工作区左边缘之间的距离 359 4.1.24 RightToLeft属性——控件的文本从右向左读取 360 4.1.25 ScrollBars属性——滚动条的可见性和位置 360 4.1.26 SizeMode属性——指示如何显示图像 361 4.1.27 Tag属性——或控件的标识 362 4.1.28 Text属性——与控件关联的文本 362 4.1.29 TextAlign 属性——控件上文本的对齐方式 363 4.1.30 Top属性——控件上边缘与其容器的工作区上边缘之间的距离 364 4.1.31 Value属性——辅助性对象的 364 4.1.32 View属性——项在控件的显示方式 365 4.1.33 Visible属性——控件是否可见 366 4.1.34 Width属性——控件的宽度 366 4.2 控件公共方法 367 4.2.1 BringToFront方法——将控件带到Z顺序的前面 367 4.2.2 Focus方法——为控件设置输入焦点 367 4.2.3 GetClipboardContent方法——检索选定单元格内容的格式化 368 4.2.4 GetParent方法——检索指定路径的父目录 368 4.2.5 Hide方法——隐藏 369 4.2.6 Load方法——加载XML文档 369 4.2.7 LoadFile方法——将文件加载到RichTextBox控件 371 4.2.8 Navigate方法——打开指定的URL地址 372 4.2.9 Refresh方法——重新加载当前的网页 373 4.2.10 SaveAs方法——用新名称或新格式保存文档 373 4.2.11 SaveFile方法——将内容保存到文件 374 4.2.12 Show方法——显示光标或者打开新 375 4.2.13 UpButton方法——按照指定数递增 376 4.3 控件公共事件 377 4.3.1 Click事件——单击控件时触发该事件 377 4.3.2 Enter事件——光标进入控件时发生 378 4.3.3 KeyDown事件——控件有焦点按下键时发生 378 4.3.4 KeyPress事件——控件有焦点按下键时发生 380 4.3.5 KeyUp事件——控件有焦点释放键时发生 381 4.3.6 Leave事件——输入焦点离开控件时发生 381 4.3.7 MouseClick事件——用户单击控件时发生 382 4.3.8 Navigated事件——加载新文档时发生 383 4.3.9 Paint事件——重绘或更新控件时发生 383 第5章 数据库开发 385 5.1 SQL语言基础 385 5.1.1 AVG聚合函数——返回组的平均 385 5.1.2 CAST函数——数据类型显式转换 385 5.1.3 COUNT函数——返回组的项的数量 386 5.1.4 Last函数——返回查询结果的最后一个记录 386 5.1.5 MAX函数——返回表达式的最大 388 5.1.6 MIN函数——返回表达式的最小 388 5.1.7 newid函数——创建uniqueidentifier类型的惟一 389 5.1.8 SUM函数——返回表达式所有的和 389 5.1.9 UPDATE语句——更改表的现有数据 390 5.2 ADO.NET技术 392 5.2.1 Command对象——对数据源执行增、删、改、查操作 392 5.2.2 CommandText属性——获取设置SQL语句或存储过程 393 5.2.3 CommandTimeout属性——获取或设置错误等待时间 393 5.2.4 CommandType属性——获取或设置如何解释CommandText属性 394 5.2.5 Connection对象——数据库连接对象 394 5.2.6 ConnectionState枚举——数据库连接状态 395 5.2.7 DataAdapter类——数据库桥接器 396 5.2.8 DataMember属性——获取或设置数据源列表或表名称 398 5.2.9 DataReader类——只读数据集 398 5.2.10 DataSet类——数据集 400 5.2.11 DataSource属性——获取或设置数据源 402 5.2.12 ExecuteNonQuery方法——执行SQL语句并返回受影响的行数 402 5.2.13 ExecuteReader方法——执行SQL语句并返回DataReader对象 403 5.2.14 ExecuteScalar方法——执行SQL语句并返回结果集第1行的第1列 404 5.2.15 Fill方法——填充数据集 405 5.2.16 Merge方法——合并数据集 407 5.2.17 Parameters属性——获取SqlParameterCollection 409 5.2.18 ReadXml方法——将XML架构和数据读入数据集 410 5.2.19 SelectCommand属性——获取或设置选择记录命令 411 5.2.20 SQL注入式攻击——利用设计上的漏洞攻击SQL 412 5.2.21 SqlCommand类——SQL执行命令 413 5.2.22 SqlConnection类——SQL数据库连接对象 415 5.2.23 SqlDataAdapter类——SQL数据库桥接器 416 5.2.24 SqlDataReader类——SQL只读数据集 418 5.2.25 Tables属性——获取包含在数据集的表的集合 421 5.2.26 Update方法——使控件重绘工作区内的无效区域 422 5.2.27 UpdateCommand属性——获取或设置更新记录命令 423 5.2.28 WriteXml方法——将数据集数据写入到XML 423 5.3 LINQ技术 424 5.3.1 Lambda表达式——匿名函数 424 5.3.2 LINQ技术——语言集成查询 426 5.3.3 LinqToDataSet技术——LINQ操作数据集 427 5.3.4 LinqToObjects技术——LINQ操作数组和集合 429 5.3.5 LinqToSql技术——LINQ操作SQL数据库 431 5.3.6 LinqToXml技术——LINQ操作XML文件 436 5.3.7 var关键字——根据初始化语句推断变量类型 439 第6章 文件、数据流与注册表 441 6.1 文件与I/O数据流 441 6.1.1 ASCII码——键盘的一种表示方式 441 6.1.2 ASCIIEncoding类——ASCII字符编码的操作类 442 6.1.3 Attributes属性——获取和设置文件的属性 443 6.1.4 BinaryReader类——将特定的数据读作二进制 445 6.1.5 BinaryWriter类——将二进制写入到流 447 6.1.6 CanRead属性——判断当前流是否支持读写 448 6.1.7 Close方法——释放所有关联的资源 449 6.1.8 Copy方法——文件的复制 450 6.1.9 CopyFile方法——将文件复制到新的位置 451 6.1.10 CopyTo方法——将指定的字符串复制到字符数组 452 6.1.11 Create方法——创建文件 455 6.1.12 CreateDirectory方法——创建指定路径的所有目录 456 6.1.13 CreateText方法——创建或打开文本文件 456 6.1.14 CreationTime属性——获取或设置文件的创建时间 457 6.1.15 CryptoStream类——将数据流连接到加密转换的流 457 6.1.16 Delete方法——删除文件 461 6.1.17 Directory类——对文件夹进行操作的类 463 6.1.18 DirectoryEntry类——封装节点或对象 464 6.1.19 DirectoryInfo类——对文件夹进行操作的类 466 6.1.20 DirectoryName属性——获取路径 468 6.1.21 DirectorySearcher组件——执行查找 468 6.1.22 DriveInfo类——驱动器的信息访问 469 6.1.23 Encoding属性——获取编码方式 470 6.1.24 Exists方法——判断文件是否存在 471 6.1.25 Exists属性——判断文件是否存在 472 6.1.26 Extension属性——获取文件扩展名 473 6.1.27 File类——对文件进行操作的类 473 6.1.28 FileAttributes枚举——提供文件和目录的属性 475 6.1.29 FileInfo类——文件的操作类 476 6.1.30 FileName属性——获取或设置文件的名称 478 6.1.31 FileStream类——对文件流操作的类 478 6.1.32 Flush方法——清除流的缓冲区 480 6.1.33 GetBytes方法——将字符串编码设为字节序列 481 6.1.34 GetDirectories方法——获取子目录的名称 482 6.1.35 GetExtension方法——获取路径字符串的扩展名 485 6.1.36 GetFiles方法——获取目录的文件名称 486 6.1.37 GetFileSystemEntries方法——获取目录的所有名称 487 6.1.38 GetFileSystemInfos方法——获取所有文件的信息 489 6.1.39 GetStream方法——返回用于发送和接收的数据 491 6.1.40 GetString方法——将字节解码成字符串 491 6.1.41 HasRows属性——指示 OleDbDataReader是否有数据 493 6.1.42 MD5CryptoServiceProvider类——操作MD5的类 493 6.1.43 MemoryStream类——创建其支持存储区为内存的流 495 6.1.44 Move方法——文件的移动 497 6.1.45 MoveNext方法——移动到下一个字符 497 6.1.46 MoveTo方法——文件的移动 498 6.1.47 NetworkStream类——网络访问的基础数据流 500 6.1.48 Open方法——打开文件 502 6.1.49 OpenFile方法——以只读方式打开文件 503 6.1.50 OpenText方法——打开UTF-8编码文本文件 504 6.1.51 Path属性——监视的目录的路径 505 6.1.52 Peek方法——返回下一个可用的字符 506 6.1.53 Read方法——读取数据流 507 6.1.54 ReadBytes方法——将指定的字节读入字节数组 508 6.1.55 ReadToEnd方法——从流的当前位置读到末尾 509 6.1.56 Stream类——对数据流进行操作的类 510 6.1.57 StreamReader类——数据流的读取类 512 6.1.58 StreamWriter类——数据流的写入类 513 6.1.59 TextReader类——读取连续字符的读取器 515 6.1.60 TextWriter类——编写一个有序字符系列的编写器 516 6.1.61 Write方法——将流写入到文件 517 6.2 注册表技术 521 6.2.1 CreateSubKey方法——创建或打开子项 521 6.2.2 GetValue方法——获取注册表项 522 6.2.3 GetValueNames方法——所有名称的字符串数组 523 6.2.4 GetSubKeyNames方法——所有子项名称字符串数组 525 6.2.5 OpenSubKey方法——以只读方式检索子项 525 6.2.6 Registry类——注册表操作类 528 6.2.7 RegistryKey类——表示Windows注册表的项级节点 529 6.2.8 SetValue方法——设置注册表项的指定名称/对 531 第7章 GDI+绘图技术 532 7.1 GDI+绘图基础 532 7.1.1 Bitmap类——图像对象 532 7.1.2 Cursor类——绘制光标指针图像 533 7.1.3 GDI+——图形图像的绘制 535 7.1.4 Graphics类——绘图类 536 7.1.5 GraphicsPath类——一系列相互连接的直线和曲线 540 7.1.6 Icon类——图标的操作类 542 7.1.7 Image类——图像的操作类 543 7.1.8 LinearGradientBrush类——线性渐变封装Brush 545 7.1.9 Region类——由矩形和路径构成的图形形状的内部 547 7.1.10 SolidBrush类——定义单色画笔 548 7.2 常用绘图方法 549 7.2.1 Draw方法——绘制光标 549 7.2.2 DrawArc方法——绘制圆弧 550 7.2.3 DrawBezier方法——绘制贝塞尔样条 551 7.2.4 DrawEllipse方法——绘制椭圆 553 7.2.5 DrawImage方法——绘制Image图像 555 7.2.6 DrawLine方法——绘制直线 556 7.2.7 DrawPath方法——绘制GraphicsPath图形路径 558 7.2.8 DrawPie方法——绘制扇形 558 7.2.9 DrawPolygon方法——绘制多边形 560 7.2.10 DrawRectangle方法——绘制矩形 561 7.2.11 DrawString方法——绘制文本字符串 562 7.3 常用填充图像方法 565 7.3.1 FillEllipse方法——填充椭圆 565 7.3.2 FillPath方法——填充GraphicsPath的内部 566 7.3.3 FillPie方法——填充扇形 567 7.3.4 FillPolygon方法——填充多边形 568 7.3.5 FillRectangle方法——填充矩形框 570 7.3.6 FillRegion方法——填充一个区域 572 7.4 其他常用方法 572 7.4.1 Clone方法——创建Bitmap对象的某个部分的副本 572 7.4.2 CreateGraphics方法——创建Graphics对象 574 7.4.3 FromArgb方法——从ARGB创建Color结构 574 7.4.4 FromFile方法——从指定的文件创建Image 577 7.4.5 FromImage方法——从Image创建新的Graphics对象 578 7.4.6 FromStream方法——数据流创建Image 578 7.4.7 GetPixel方法——获取图像的像素颜色 580 7.4.8 GetThumbnailImage方法——Image的缩略图 581 7.4.9 Save方法——将图片以文件的形式进行复制 583 7.4.10 SetPixel方法——设置图像的像素颜色 583 7.4.11 Transform方法——对路径的数据点进行变换 584 第8章 C#高级编程 586 8.1 网络编程技术 586 8.1.1 Accept方法——为新建连接创建新的Socket对象 586 8.1.2 AcceptSocket方法——接收挂起的连接请求 586 8.1.3 BeginConnect方法——开始远程机连接的异步请求 587 8.1.4 Dns类——从Internet域名系统检索特定机的信息 588 8.1.5 GetHostAddresses方法——返回机的IP地址 589 8.1.6 GetHostByAddress方法——创建IPHostEntry实例 590 8.1.7 GetHostByName方法——获取指定DNS机名的信息 591 8.1.8 GetHostName方法——获取本地计算机的机名 592 8.1.9 IPEndPoint类——将网络端点表示为IP地址和端口号 592 8.1.10 IPHostEntry类——为机地址信息提供容器类 594 8.1.11 Listen方法——将Socket置于侦听状态 596 8.1.12 MachineName属性——读取或写入事件的计算机名称 596 8.1.13 MailMessage类——邮件的操作类 597 8.1.14 Net send命令——用net send命令进行发送 598 8.1.15 Net use命令——实现映射网络驱动器 599 8.1.16 Ping类——网络访问远程计算机的操作类 601 8.1.17 POP3协议——POP邮件的操作类 603 8.1.18 Receive方法——由远程机发送的UDP数据报 608 8.1.19 Send方法——将数据发送到连接的Socket 609 8.1.20 SerialPort类——控制串行端口文件资源 610 8.1.21 SMTP协议——进行邮件的传输 612 8.1.22 SmtpClient类——将电子邮件发送到SMTP服务器 614 8.1.23 Socket类——网络通信的操作类 616 8.1.24 TcpClient类——为TCP网络服务提供客户端连接 618 8.1.25 TcpListener类——从TCP网络客户端侦听连接 619 8.1.26 UdpClient类——用户数据报(UDP)网络服务 620 8.1.27 WebClient类——URI标识的资源发送和接收 623 8.1.28 WebRequest类——访问Internet数据 625 8.1.29 WebResponse类——协议特定的响应类 629 8.2 多线程编程 630 8.2.1 Abort方法——终止线程 630 8.2.2 BeginInvoke方法——线程上异步执行委托 631 8.2.3 EndInvoke方法——异步操作的返回 632 8.2.4 Join方法——确保线程已终止 633 8.2.5 Kill方法——强制关闭进程 633 8.2.6 Process类——对正在计算机上运行的进程的访问 635 8.2.7 Sleep方法——线程挂起 640 8.2.8 Start方法——启动进程 640 8.2.9 Thread类——创建并控制线程的类 642 8.2.10 ThreadState属性——获取当前线程的状态 645 8.3 WMI技术——系统管理 646 8.3.1 MainWindowTitle属性——获取进程的口标题 646 8.3.2 ManagementClass类——公共信息模型管理类 647 8.3.3 ManagementObject类——表示WMI实例 648 8.3.4 ManagementObjectSearcher类——查询检索管理对象 650 8.3.5 ManagementScope类——管理操作的范围 651 8.3.6 Microsoft.Win32命名空间——操作注册表类 652 8.3.7 WndProc方法——处理Windows消息 654 8.4 其他高级技术 655 8.4.1 Children属性——获取节点的子项 655 8.4.2 COM+服务——为类的实例提供服务 655 8.4.3 DirectShow技术——流媒处理的一个开发包 656 8.4.4 DLL组件——动态链接库 663 8.4.5 MVC开发模式——模型视图控制器 664 8.4.6 VFW技术——视频应用程序提供的软件工具包 666 8.4.7 XML——定义其他标识语言的元标识语言 668 8.4.8 XmlReader类——XML读取器 670 8.4.9 XmlWriter类——XML编写器 673 附录——字母索引 676

110,567

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧