精华内容
下载资源
问答
  • windows的控件

    2013-04-25 13:41:36
    该文档描述了在windows开发中常用到的控件的描述,包括,按钮,编辑框,列表框,单选框,组合框等等控件的详细描述,以及使用方法,该文档一共63页,通过举一翻三的方法,掌握windows的控件的使用方法。
  • Windows系统提供标准控件主要包括静态控件、按钮控件、编辑框控件、列表框控件、组合框控件等,如表所示。 Windows标准控件的类型 类别 MFC类 控件类型 静态控件 CStatic Static Text、Group Box 按钮控件 ...

    一、 Windows标准控件概述

    (一)Windows标准控件

    Windows系统提供的标准控件主要包括静态控件、按钮控件、编辑框控件、列表框控件、组合框控件等,如表所示。
    Windows标准控件的类型

    类别             MFC类                       控件类型
    静态控件     CStatic                       Static Text、Group Box
    按钮控件     CButton                      Button、Check Box、Radio Button
    编辑框控件 CEdit                          Edit Box
    组合框控件 CComboBox             Combo Box
    列表框控件 CListBox                    List Box

    控件操作的学习主要关注以下几个方面:
    1、控件的创建
    控件的创建分为静态创建动态创建两种方式。
    静态创建是指在对话框模板创建控件,并设置控件的属性,这样,在调用该对话框时,窗口系统会自动按预先的设置为对话框创建控件。程序员可以使用C1assWizard为该控件在对话框类中创建一个控件类的对象。
    动态创建是指在程序的运行中根据需要,定义一个控件类的对象,再通过窗口函数CreateWindow()或CreateWindowEx()创建控件、函数ShowWindow()显示控件,正如操作一个子窗口。

    2、控件的属性设置
    每个控件都有一个属性集,对于静态创建的控件,可以在对话框模板中,打开控件的属性对话框直接设置控件的初始属性。在程序设计过程中,可以通过控件类对象调用方法设置控件的属性。
    3、控件消息类别
    上表所列出的控件中,静态控件不发送消息,其他控件对于用户的操作都能发送消息,不同类的控件发送的消息类别是不相同的,可以使用C1assWizard为控件映射各种消息处理函数。
    4、控件对象的常用方法
    MFC控件类提供丰富的方法函数,帮助程序员操作控件对象。
    5、用户输入消息的获取和响应
    在前一章已经介绍了MFC支持应用程序与用户之间的通信的方法,为控件的显示值映射一个对话框类的成员变量,再通过对话框数据交换和校验机制在对话框打开和关闭的时候实现数据传递,在程序运行过程中,通过UpdateData()函数主动地控制数据在控件显示和成员变量之间交换。这是MFC应用程序获取用户输入消息的主要方法。
    同时MFC保留了Windows API函数,可直接通过控件ID操作控件,获取或设置控件的显示值。例如SetDlgItemText()和GetDIgItemText()函数可以用于设置或获取编辑框的显示文本串

    (二)控件的通用属性

    Windows标准控件的属性窗口通常由3个属性标签构成。
    1、General标签页
    General标签页中设置常规属性,通常包括:
    (1)ID
    程序通过控件ID来访问一个控件。所有的控件中,只有Static Box控件和GroupBox控件的ID是可以重复,一般使用默认设置IDC_STATIC。而其他类控件的ID在一个应用程序中应该是惟一的。
    (2)Visible
    设置对话框打开时控件是否可见。它的类型是布尔类型。默认为TRUE.即运行程序时显示控件。
    (3)Disabled
    设置当对话框在打开时该控件是否不可用,它的类型是布尔类型,默认为FALSE。
    (4)Group
    标记一组控件中的第一个控件。
    (5)Tap stop
    设置TAB键是否可以该控件上驻留,它的类型是布尔型,默认值为TRUE。
    (6) Help ID
    分配一个帮助ID给一个控件。这个帮助ID建立在资源ID基础上。它的类型是布尔型,默认为FALSE。
    2、Styles标签页
    可以通过Style标签页设置一些与控件风格有关的属性,不同的控件所设置的属性不相同,在本章的后续小节中将按不同的控件介绍。
    3、Extend Styles标签页
    Extent Styles标签页设置与控件显示风格有关的属性,通常包括:
    (1)Client edge
    围绕对话框建立一个有下凹风格的边框。它的类型是布尔型,默认值是FALSE.
    (2)Static edge
    围绕对话框建立一个边框。它的类型是布尔型,默认值是FALSE.
    (3)Modal frame
    该选项提供一个3D框架
    (4)Transparent
    使用这种风格的窗口在层叠状态下是透明的,它的类型是布尔型,默认值是FALSE.
    (5)Accept files
    这种风格的对话框可接受拖放文件操作。如果用户拖动一个文件到此对话框上,对话框将接收到一个WM_DROPFILES消息。该选项的类型是布尔型,默认值是FALSE.
    (6)Right aligned text
    指定在一个对话框中文本是右对齐的。它的类型是布尔型,默认值是FALSE.
    (7)Right-to-left reading order
    对话框的文本按从右到左的顺序编排,这是为了一些特殊语言的阅读方便而设置的(如阿拉伯语言)。它的类型是布尔型,默认值是FALSE.

    (三)常用控件窗口操作函数

    Windows应用程序对控件的操作实质上是对窗口的操作,对话框窗口中的控件被视为对话框窗口的子窗口,具有通用的窗口属性,所以控件的操作还可以通过一组窗口操作的函数来完成。常用的控件子窗口操作函数如下:
    1 、CreateWindow()或CreateWindowEx()
    在程序运行过程中,可以通过调用创建窗口的函数来动态地创建控件,创建窗口的函数是CreateWindow()或CreateWindowEx()。

    2、ShowWindow()
    使用函数ShowWindow()可以显示或隐藏控件。它的函数原型为:
    BOOL ShowWindow(int nCmdShow);
    参数nCmdShow表示窗口的显示特性,例如,取值SW_HIDE表示隐藏控件,取值SW_SHOW表示显示控件。
    3、EnableWindow()
    通过函数EnableWindow(可以激活控件或禁止控件接受用户输入。它的函数原型为
    BOOL EnableWindow(BOOL nEnable=true);
    参数nEnable决定控件的激活或禁止状态,当值为true时,允许控件接受用户输入,当其值为false时,不允许控件接受用户输入,其呈灰色显示。
    4、MoveWindow()
    通过函数MoveWindow()可以移动控件或改变控件的大小。函数的原型为
    BOOL MoveWindow(int x,int y,int nWidth,int nHeight,B00L bRepaint=TRUE);
    坐标x,y决定控件所在的位置,nWidth和nHeight决定控件的大小,bRepaint表明对话框窗口移动后,控件是否需要重画,以使其与对话框窗口的相对位置与大小保持不变。
    5、 DestroyWindow()
    通过该函数能够关闭一个控件,该函数的原型为
    void DestoyWindow();

    二、CStatic类控件的使用

    在程序中出现的文本根据作用的不同,可以分为两大类:静态文本和动态文本。静态文本在程序的执行中保持不变,主要用来表示控件的功能、下一步执行的操作等。动态文本在程序执行过程中是可以改变的,在Windows中可以通过编辑控件来实现。
    MFC中使用CStatic类来管理静态文本控件,包括StaticText控件和Group Box控件,StaticText控件通常用来标识一个控件,Group Box通常用来分割不同组别的控件
    一般情况下,静态控件不接受用户输入,也不发出消息。它的ID号默认为IDC_STATIC,只有CStatic类的控件的ID号是可以重复的。

    (一)Static Text控件

    用户能添加到对话框中的最简单控件是静态文本控件。静态文本控件不要求与对话框进行交互,需要显示的文本串只要在该控件属性对话框的General标签中的Caption属性中直接输入。
    对静态文本,可以在Styles标签页中设置文本的显示风格,属性设置的说明如下:
    1、Align text
    控制静态文本控件中文本的对齐方式。可能的取值有Right右对齐),Left〔左对齐),Center(居中),当No wrap选项选中时,这个选项设置为Left,它的默认值为Left。
    2 .Center vertically
    静态文本控件中文本在垂直方向上居中。它的类型是布尔型,默认值是FALSE.
    3. No prefix
    禁止文本中的“&”解释为它后面的字符有一个下划线,而直接将它作为文本的一部分进行显示。No prefix选项经常在显示包含“&”的文件名或字符串中用到。
    4. No wrap
    前提条件是文本必须是左对齐的。选中此选项时Tabs是可扩展的,但是不能保护单词的完整性。在行的末尾扩展处的部分将被剪切掉。它的类型是布尔型,默认值是FALSE。
    5. Simple
    此选项将禁用No wrap和Align text选项。在静态文本控件中的文本如果有此属性,就不保护单词的完整性,且不保证不被剪切。它的类型是布尔型,默认值是FALSE。
    6. Notify
    此选项表示当控件被选中或双击时,通知父窗口。此选项的类型是布尔型,默认值是FALSE。
    7. Sunken
    此选项表示围绕静态文本控件的文本,建立一个凹下的边框。它的类型是布尔型,默认值是FALSE。
    8. Border
    此选项表示围绕静态文本控件的文本,建立一个边框。它的类型是布尔型,默认值是FALSE。

    (二) Group Box控件

    Group Box的作用与Static Text类似,主要是用于标识控件的作用,它更多地用于成组控件的标识,例如,有一组单选按钮用于选择性别,一组复选框按钮用于表示兴趣爱好。
    Group Box的Styles标签页的属性设置更为简单,如下所示。

    1 .Horizontal alignment
    此选项用于设置Group Box中文本串显示的水平对齐位置,在下拉列表中提供了4个选项:Default, Right, Left, Center和默认选项Default,表示左对齐。
    2. Icon
    此选项表示使用图标作标识,代替文本串。
    3. Bitmap
    此选项表示使用位图作标识,代替文本串。
    4. Notify
    此选项表示当控件被选中或双击时,通知父窗口。此选项的类型是布尔型,默认值是FALSE。
    5. Flat
    此选项设置Group Box的线条显示风格。

    三、 CEdit类控件的使用

    编辑控件用于程序需要获取文本的时候,例如,在对话框内输入名字或数字时,由编辑控件获取此信息。编辑控件是用来存储用户输入的自由格式文本的窗口,分为单行编辑控件和多行编辑控件。单行编辑控件是用于输入单行文本的控件,多行文本编辑控件是用于输入多行文本的控件。在多行编辑控件中经常使用滚动条,从而能输入比显示区域更多的文本。事实上,Windows中的记事本(Notepad)应用程序就是一个带有控件菜单的编辑控件。
    每个编辑控件都提供了内置编辑能力,因此可以使用多行编辑控件来创建一个简单的文本编辑器。所有的编辑控件都支持特定的编辑功能,而不需要任何附加编程。在剪贴板中用到的粘贴命令在编辑控件中照常可以使用。

    编辑控件能够发送WM NOTIFY消息到对话框窗口,并告诉对话框窗口用户对编辑控件所做的操作,编辑控件能够处理的消息类别如下所示。
    消息类别                        发生事件
    EN_ CHANGE              输入框中的文本串被修改
    EN_ ERRSPACE         输入的文本串超过了输入框的显示范围
    EN_ HSCROLL             按下水平滚动条
    EN_KILLFOCUS           输入框失去焦点,也就是焦点转移到其他对象
    EN_ MAXTEXT             输入的文本串超过了设定的最大输入长度
    EN_ SETFOCUS          输入框获取焦点
    EN_ UPDATE                更新显示内容
    EN_ VSCROLL             按下垂直滚动条
    注:EN:Edit
    使用C1assWizard可以为一个编辑控件映射一个对话框的成员变量,通过对话框的数据交换机制,方便地获取用户输入的内容,或把应用程序的响应结果输出到编辑框。成员变量的数据类型可以设为CString, int, UINT, long, DWORD, float, double. BYTE, short,BOOL, COleDateTime, COleCurrency}方便程序员在不同应用情况下的数据处理。

    (一)属性设置

    通过Styles标签页的设置,可以得到不同类型的编辑框样式:多行编辑框、密码编辑框,只读编辑框,大小写转换编辑框、数字编辑框等等。
    1 .Align text
    控制编辑控件中的文本对齐方式。可能的取值有左对齐、居中和右对齐。
    2: Muttiline
    定义该编辑控件为多行文本编辑。通常情况下,该选项不被选中。
    3. Number
    限定用户输入的只能是数字。
    4. Horizontal scroll
    在多行编辑控件中提供一个水平滚动条。默认该选项不被选中。
    5. Auto HScroll
    当用户在编辑框的最右边输入字符时,文本自动进行滚动。该选项通常被选中。
    6. Vertical scroll
    在多行编辑控件中提供一个垂直滚动条。默认该选项不被选中。
    7. Auto VScroll
    在多行编辑控件中,当用户在最后一行按回车键时,文本自动向下滚动。默认该选项不被选中。
    8 .Password
    当用户在编辑控件中输入字符时,在编辑框中不显示输入的文本,而是相同个数的“*”字符。这一选项在多行编辑控件中不能使用。默认不被选中。
    9. No hide selection
    当编辑控件失去或重新获得焦点时,该项设置将改变文本的显示方式,使编辑框中选择的文本好像总是处于选中状态。默认该选项不被选中。
    10. OEM convert
    对用户输入内容进行从Windows字符集到OEM字符集的转化,这样可以使调用AnsiToOem时正常工作。默认不被选中。
    11.Want return
    应用于多行编辑控件。该选项允许在编辑控件中按Enter键换行,而不影响对话框的默认按钮。
    12. Border
    为控件创建边界,该选项默认被选中。
    13. Uppercase
    将所有的输入内容转化为大写字符,默认不被选中。

    14. Lowercase
    将所有的输入内容转化为小写字符,默认不被选中。
    15. Read-only
    禁止用户在编辑控件中输入或修改其内容,默认不被选中。与静态文本控件的扩展属性相比,编辑控件的扩展属性只增加了一项Left scroll bar,如果设置了垂直滚动条,这一项决定了滚动条在客户区的左边。它的类型是布尔型,默认情况下不选中。

    编程实例:Exam6_1编写一个用户登录的应用程序,应用程序维护着一张合法用户的用户名和密码的列表,至于合法用户才能通过登录程序.要求如下:

    (1)用户名输入后,转换为大写字母显示,最大长度不能超过10位。
    (2)密码以‘*’代替显示,密码只能是6位数字。
    (3)按“确定”按钮时,需要确认输入框不为空,且输入符合要求,否则返回输入框重新输入。
    (4)对合法用户显示欢迎对话框,对不合法用户显示警告对话框。

    相关参考函数代码:

    void CExam6_01Dlg::OnOK() 
    {
    	// TODO: Add extra validation here
    	UpdateData(true);
    	if(m_user.IsEmpty())
    	{
    		AfxMessageBox("用户名不能为空,请重新输入");
    		m_EditUser.SetFocus();
    	}
    	else if(m_pwd.IsEmpty())
    	{
    		AfxMessageBox("密码不能为空,请重新输入");
    		m_EditPwd.SetFocus();
    	}
    	else
    	{
    		int len=m_EditPwd.LineLength();
    		if(len!=6)
    		{
    			AfxMessageBox("密码必须为六位,请重新输入");
    			m_EditPwd.SetFocus();
    		}
    		else
    		{
    			for(int i=0;i<5;i++)
    				if((m_user==userlist[i][0])&&(m_pwd==userlist[i][1]))
    				{
    					MessageBox("You are welcome!");
    					break;
    				}
    				if(i==5)
    					MessageBox("Sorry,you are not permitted.");
    		}
    	}
    	CDialog::OnOK();
    }
     
     
    CExam6_01Dlg::CExam6_01Dlg(CWnd* pParent /*=NULL*/)
    : CDialog(CExam6_01Dlg::IDD, pParent)
    {
    	//{{AFX_DATA_INIT(CExam6_01Dlg)
    	m_user = _T("");
    	m_pwd = _T("");
    	//}}AFX_DATA_INIT
    	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
    	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
    	userlist[0][0]="MARY";
    	userlist[0][1]="123456";
    	userlist[1][0]="MARY";
    	userlist[1][1]="123456";
    	userlist[2][0]="MARY";
    	userlist[2][1]="123456";
    	userlist[3][0]="MARY";
    	userlist[3][1]="123456";
    	userlist[4][0]="MARY";
    	userlist[4][1]="123456";
    	userlist[5][0]="MARY";
    	userlist[5][1]="123456"; 
    }

    四、CButton类控件的使用

    (一)CButton类控件介绍

    按钮控件是Windows对话框中最常见的控件之一。按钮控件的类型比较丰富,其中主要有命令按钮、单选按钮、复选框按钮等。
    按钮控件能够处理的消息类别如下所示。

    消息类别                               发生事件
    BN_ CLICKED                     单击按钮
    BN_DOUBLECLICKED      双击按钮
    BN_ SETFOCUS                 按钮获取焦点
    BN_ KILLFOCUS                 按钮失去焦点
    注:BN:ButtoN
    CButton类提供的常用访问方法:

    GetBitmap( )获得用SetBitmap()设置的位图的句柄
    GetButtonStyle()获得有关按钮控件的样式信息
    GetCheck( )获得按钮控件的选中状态
    GetCursor()获得通过SetCursor()设置的光标图像的句柄
    Gedcon()获得由Setlcon()设置的图标句柄
    GetState()获得按钮控件的选中、选择和聚焦状态
    Sefitmap( )指定按钮上显示的位图
    SetBunonStyle()设置按钮样式
    SetCheck()设置按钮控件的选中状态
    Setclrsor( )指定按钮控件上的光标图像
    SetIcon()指定按钮上显示的图标
    SetState()设置按钮控件的选择状态

    (二)命令按钮

    MFC应用程序的对话框模板默认为每一个对话框配置两个按钮—“确认”和“取消”按钮,ID固定为IDOK和IDCANCEL,并在对话框基类中定义了BN_CLICKED消息处理函数OnOK()和OnCancel(),用于完成关闭对话框时所需要的工作。这两个函数是虚函数,可以在应用程序的对话框类中重载这两个函数。
    程序员可以自由地修改默认按钮和添加新的命令按钮。通常命令按钮上都有标题以表明此按钮的作用,命令按钮的Caption属性用于设置命令按钮的标题。例如,标题“确认”表示接受用户的选择等。
    在Styles标签页中主要设置按钮的显示,默认为Default button风格,Owner draw提供了另一种按钮边框风格.Icon和Bitmap属性允许创建一个显示图标或位图的按钮,Multiline属性允许按钮上显示多行文本。Horizontal alignment和Vertical alignment属性设置标题在按钮上显示的水平及垂直方向的对齐方式。

    (三)单选按钮

    使用单选按钮(Radio Button),只能从一组选项中选择惟一一个选项在组中选择一个上次未选中的选项时,其他选项自动变成未选中状态。用户可以在应用程序中添加单选按钮,并通过设置不同的属性满足自己的需要。
    属性对同一组单选按钮的设置非常重要,每一个按钮的Caption属性用于设置单选按钮的显示文本。一组中的第一个控件要选中Group属性,表示一组控件的开始,同组的其他控件则不能设置Group属性,并且同一组控件的Tab Order要求是连续的。
    打开C1assWizard的Member Variables标签页,可以发现对一组单选按钮,列表中只出现第一个控件ID,这意味着只能在对话框类中设置一个值类型的成员变量。该变量的值是int型,表示所选中的单选按钮在组中的序号,序号从0开始。例如,如果选择第2个单选按钮,则返回值为1。同样,一组单选按钮只能在对话框类设置一个单选按钮对象,也就是说一个单选按钮对象控制一组单选按钮。
    MFC除了提供值类型成员变量操作单选按钮,还支持Win32 API函数通过控件ID直接操作单选按钮,CheckRadioButton()用于设置单选按钮的选中状态,函数原型为
    CDialog::CheckRadioButton(int nIDFirstButton,int nIDLastButton,int nID_CheckButton);
    该函数包括3个参数,第一个参数是一组单选按钮中第一个按钮的ID,第二参数是一组单选按钮中最后一个按钮的ID,第三个参数是设置为选中的单选按钮的ID.函数IsDlgButtonChecked()用于检查一个按钮是否被选中,函数原型为
    CDialog::IsDlgButtonChecked(int nIDButton);
    该函数只包含一个参数,即所检查按钮的ID号,返回值为true或false.

    Radio按钮属性对话框的Style标签页:
    1 .Auto
    该项被选中时,控件状态将自动改变。该项通常被选中。
    2. Left text
    把控件的标题放在控件的左边。通常,控件的标题放在控件的右边。
    3. Push-like
    将控件设置成具有下压按钮的外观。则单击该按钮时,由原来的凸状态改变成下压状
    态。
    4. Multiline
    控件的标题可通过多行显示。若该项未被选中,则标题超过按钮的宽度时,自动截去
    后面部分
    5. Flat
    将控件左边的小圆圈显示为平放。默认为凹入。
    6. Icon
    将控件标题设置为图标。该项通常未选中。
    7. Bitmap
    将控件的标题用位图代替。Bitmap与Icon选项中,至多选中一个。该选项通常未选中。

    (四)复选按钮

    复选按钮与单选按钮一样,是Windows提供的另一种形式的按钮。使用复选按钮,可以从一组选项中选择一个选项或多个选项,各个选项之间的选中状态互不相关。

    使用C1assWizard可以为每一个复选框按钮在它所在的对话框类中添加一个值类型的成员变量用于传递数据,该变量的值是BOOL型,值为true时表示选中复选框,值为false时表示未选中复选框。

    MFC同样支持Win32 API函数对复选框控件的操作,函数CheckDlgButton()设置一个复选框的选中状态,函数原型为
    CDialog::CheckDlgButton(int nIDButton,UNIT nCheck);

    该函数包括二个参数,第一个参数是复选框按钮的ID,第二个参数设置按钮的选中状态,值为BST-CHECKED或1时表示选中,值为BST-UNCHECKED或0时表示按钮未选中。

    五、 CListBox类控件的使用

    (一) CListBox类控件介绍

    对于要从若干数据项中进行选择的场合,一个方便的方法是使用列表框。列表框是一个矩形窗口,在矩形窗口中包含一些列表字符串或其他的数据元素。列表框通常出现在对话框里,如用列表框选择文件名、目录等。列表框有一个预定义的键盘接口,用户可以用键盘上的箭头或PageUp及PageDown键在列表框中进行数据的选择,或通过适当的样式设置与Shift或Ctrl键组合使用。

    列表框包括两种样式—单选列表框和多选列表框。单选列表框只允许用户一次选择一个选项,而多选列表框则可以一次选择多个选项。列表框可以自带滚动条,数据项可按排序后的顺序显示,使用己排序的列表框时,用户很容易在大量选项中搜索并作出选择。

    列表框控件属性的Styles标签的具体属性设置如下:

    1.Selection
    设置列表框中选项的选中方式。有4个选项一Single,表示在给定的选项电至多有一个被选中:Multiple,表示可以有多个选项被选中,但忽略Shift键和Ctrl键;Extended,允许选择多个选项,在选择时,可以使用Shift和Ctrl键:None,不允许选择任何选项。
    2. Owner draw
    设置列表框将由列表框所有者来绘制,在大多数情况下,该选项设置为No.
    3. Sort
    设置列表框内容应按字母顺序排序,该选项通常被选中
    4. Multi-column
    创建一个多列列表框,该选项通常未选中。
    5. Use tapstops
    设置列表框中显示的文本选项可以包含标签页,该选项通常未选中。
    6. Want key input
    设置列表框有输入焦点,当按键时列表框所有者收到WM_VKEYTOITEM或WM_CHARTOITEM消息。该选项通常未选中。
    7. Disable no scroll
    即使不需要,也显示一个垂直滚动条。该选项通常未选中。
    CListBox类的通用方法用来获得和设置列表框数据的值和属性,所有的ClistBox控件都有这些方法,包括单选列表框、多选列表框和自绘列表框等。

    CListBox类通用方法包括:
    GetCount() 获得列表框中列表项数目
    Geforiwntafxtent( ) 获得列表框的水平滚动宽度(以像素为单位)
    GetItemData() 获得与某列表框项有关的32位值
    GetITermDataPtr() 获得指向列表框项的指针
    GetItemHeight( ) 获得列表框中项的高度
    GetItemRect() 获得列表框项边界矩形
    GetLocale() 获得列表框的位置标识(LCID)
    GetSel() 获得列表框项的选中状态
    GetText() 把列表框中字符串复制到缓冲区
    GetTextLen() 返回列表框字符串的长度(单位:字节)
    GetTopIndex() 获得列表框中第一个可见项的下标(由0开始)
    ItemFrompoint()确定和返回离某点最近的列表框项的下标
    SetColumnWidth()设置多列列表框的列宽度
    SetHotizontalExtent()设置列表框的水平滚动宽度(单位:像素)
    SetItemData()设置与一个列表框项有关的32位值
    SetDataPtr()设置一个列表框项的指针
    SetltemHeight()设置列表框中项的高度
    SetLocale( )设置列表框的位置标识(LCID )
    SetTabStops()设置列表框的制表位(Tab-Stop)位置
    SetTopIndex()设置列表框中第一个可见项的下标(由0开始)

    使用列表框之前,需要预先准各好列表框中的数据选择项,在对话框的运行过程中还允许对选择项执行增加和删除操作,CListBox类提供了操作字符串的一套方法,CListBox类用于操作列表框中字符串的方法如下:

    AddString( ) 在列表框中加入一个字符串
    DeleteString( ) 从列表框中删除一个字符串
    Dir() 从当前目录加文件名放入列表框
    FindString( ) 在列表框中搜索一个字符串
    FindSIringEacact() 在列表框中搜索第一个与指定字符串匹配的字符串
    InsertStting( ) 在列表框指定下标处插入一个字符串
    ResetContent() 清除列表框中的所有项
    SelectString() 在单选列表框中搜索并选择一个字符串

    CListBox类还声明了几个虚函数:

    CharToItem() 可以重载此方法来为自绘列表框(没有字符串)处理WM-CHAR消息
    CompareItem() 由MFC调用以得到排序后的自绘列表框中的新项的位置
    DeleteItem( ) 当用户从自绘列表框中删除一项时,MFC调用此方法
    DrawItem() 当确定自绘列表框项必须重绘时,MFC调用此方法
    MeasureItem( ) 创建自绘列表框时MFC调用此方法来决定列表框的维数
    VKeyToItem( ) 用户可重载此方法,来处理具有LBS_WANTKEYBOARDINPUT样式的列表框的WM_ KEYDOWN消息

    与列表框相关的消息
    LBN_ DBLCLK当双击某列表框选项时发送。
    LBN_ERRSPACE因为内存不够,一个操作不能执行时发送。
    LBN_ KILLFOCUS当列表框失去输入焦点时发送。
    LBN_ SELCANCEL当用户取消某列表框选择时发送。
    LBN_ SELCHANGE当列表框中的选择状态改变时发送
    LBN_ SETFOCUS当列表框得到输入焦点时发送。

    上面的消息都用LBN_作前缀(LBN:List ButtoN)。如果要发送这些消息,列表框必须在Properties对话框里选中Notify复选框。LBN_DBLCLK消息是最常用的消息,大多数用户希望双击列表框选项时执行某种默认的操作。例如,显示文件名列表时,希望双击某文件名可以打开该文件进行编辑。

    (二)单选列表框

    列表框的默认模式是单选项模式,在这种模式下,用户每次只能从列表框中选中一个选项。对列表框的操作围绕着选择项进行,包括选择项的装载、删除、设置选中状态及获得选中状态。
    列表框是按数组方式来组织选择项的,每一个选择项包含一个下标值和显示值。下标值从0开始:显示值是一个CString型的字符串。属性Sort的设置与对选择项的操作密切相关。
    CListBox类提供了两个函数装载选择项,即CListBox::AddString(LPCTSTR LpszItem)和CListBox::InsertString(int nlndex, LPCTSTR Lpszltem)。当选中Sort属性时,AddString按字符串排序顺序插入新的选择项,当未选中Sort属性时,AddString在选择项序列的最后插入一个新的选择项。InsertString操作不受Sort属性的影响,在指定下标位置插入新的选择项,其他选择项后移一位。

    当未选中Sort属性时,使用C1assWizard可在对话框类为列表框控件关联两种类型的值成员变量,CString类型的值成员变量表示选择项的显示值,int类型的值成员变量表示选择项的下标值。当选中Sort属性时,只能关联一个CString类型的值成员变量。所关联的值成员变量的数据类型不同,决定着在初始化时进行选中操作的方法也不同。

    当关联的是int型的值成员变量,可以使用CListBox::SetCurSel(int nSelect)来设置列表框的初始选中状态。如果关联的是CString型的值成员变量,就要使用CListBox::SelectString(intnStartAfter,LPCTSTR LpszItem)函数,从nStartAfter指定的下标位置起查找由LpszItem字符串指定的选择项,来设置列表框的初始选中状态。

    常用的操作还有:CListBox::DeleteString(int nIndex),删除指定下标的选择项,删除后其后的选择项向前移动一位;CListBox::GetCursel(),返回当前选中的选择项的下标值。

    (三)多选列表框

    多选列表框扩展了标准的单项选择列表框的能力,可以解决在一个列表框中选择多个选项带来的复杂性。

    对于多选列表框,同样可以关联CStting和int类型的值成员变量,但通过值成员变量传递回来的是最后一个选中的选项内容,要获得选中的多个选项,需要通过CListBox类提供的多选项操作方法。

    为多项选择列表框提供的CListBox类方法如下:

    GetAnchorlndex()获得多项选择列表框中当前定位项的下标
    GetCaretlndex()获得多项选择列表框中具有光标矩形的项的下标
    GetSelCount()获得多项选择列表框中当前所选的项的数目
    GetSelItems()将当前所有被选列表框项下标放入一整型数组缓冲区
    SelItemRange()切换多选择列表框项范围的选择状态
    SetAnchorIndex()在多项选择列表框中扩充选择设置开始(定位)项
    SetCaretlndex()在多项选择列表框中指定下标项设置光标矩形
    SetSel()在多项选择列表框中设置选项的选择状态

    六、 CComboBox类控件的使用

    组合框控件是把编辑框和列表框控件组合起来的一类控件。组合框使用户既能像使用编辑控件那样直接输入数据,也能像使用列表框那样从一些选项中选择某一选项来输入数据。
    当用户没有被限制必须选择列表框中选项时,组合框十分有用。组合框的列表框部分能用来显示最近的选择,同时给用户在编辑控件中输入新选择的自由。
    有如下三种类型的组合框控件:
    1.简单组合框(Simple)
    显示一个编辑控件和列表框。该列表框总是可见的。当列表框包含的选项太多,显示不下时,将使用一个滚动条在整个列表框中滚动。
    2.下拉式组合框(Dropdown)
    隐藏列表框,直到用户打开它。使用这种类型的组合框,在对话框中占用的空间比简
    单组合框要小得多。
    3.下拉式列表框(Drop List)
    与下拉式组合框相似,只有被用户打开时,才显示列表框。同时,编辑框只能显示选中的选项,而不允许用户输入。因此,用户只能从列表框中选择选项。

    (一)CComboBox类控件介绍

    MFC的CComboBox类封装了组合框。需要指出的是,虽然组合框是编辑框和列表框的组合,但是CComboBox类并不是Mit类和CListBox类的派生类,而是CWnd类的派生类。
    CComboBox类的成员函数较多。其中常用的函数可粗分为两类,分别针对编辑框组件和列表框组件。可以想象,这些函数与CEdit类和CListBox类的成员函数肯定有很多类似之处,但它们也会有一些不同的特点。如果我们能从“组合框是由编辑框和列表框组成”这一概念出发,就能够很快掌握CComboBox的主要成员函数。

    事实上,绝大部分CComboBox的成员函数都可以看成是Mit或CListBox成员函数的翻版。函数的功能、函数名、甚至函数的参数都是类似的。为了方便学习,下面列出的CComboBox类成员函数,采用了与对应的Mit或CListBox成员函数相比较的做法。在成员函数的列表中,分别列出了成员函数名、对应的Mit或CListBox成员函数,以及二者之间的不同之处。不同之处是指函数的功能、参数以及返回值的差别。
    针对编辑框组件的主要成员函数如表7-13所示。该表的前3个函数实际上是CWnd类的成员函数,可用来查询和设置编辑框组件。

    针对编辑框组件的CComboBox类成员函数:

    成员函数名对应的CEdit成员函数不同之处
    成员函数名                                          对应的CEdit成员函数                                                  不同之处
    CWnd::GetWindowText                      CWnd::GetWindowText                                                无
    CWnd::SetWindowText                      CWnd::SetWindowText                                                无
    CWnd::GetWindowTextLength          CWnd::GetWindowTextLength                                    无
    GetEditSel                                           GetSel                                                                           函数名不同
    SetEditSel                                           SetSel                                                                            函数名不同,且无bNoScroll参数
    Clear                                                    Clear                                                                              无
    Copy                                                    Copy                                                                               无
    Cut                                                       Cut                                                                                  无
    Paste                                                   Paste                                                                              无
    与CListBox的成员函数类似,针对列表框组件的CComboBox成员函数也可以分为3类。用于插入和删除列表项的成员函数、用于搜索、查询和设置列表框的成员函数,与列表项的选择有关的成员函数如下:

    另外,CComboBox的ShowDrouDown()成员函数专门负责显示或隐藏列表框组件,该函数的声明为
    void ShowDropDown(BOOL bShowIt=TRUE);

    成员函数名对应的CListBox成员函数区别:

    AddString  AddStting 无
    InsertString InsertStting无
    DeleteString DeleteString无
    ResetContent ResetContent无
    Dir  Dir 无
    GetCount GetCount无
    FindString FindString无
    GetLBText  GetText仅函数名不同
    GetLBTextLen GetTextLen 仅函数名不同
    GetItemData  GetltemData无
    SetItemData  SetItemData无
    GetTopIndex  GetTopIndex无
    SetToplndex  SetTopIndex无

    与列表项的选择有关的CComboBox成员函数

    成员函数名 对应的CListBox成员函数区别 
    GetCurSel  GetCurSel 无
    SetCurSel  SetCurSe1 新选中的列表项的内容会被复制到编辑框组件中
    SelectStting SelectString新选中的列表项的内容会被复制到编辑框组件中

    如果参数bShowlt的值为TRUE那么将显示列表框组件,否则将其隐藏。该函数对简单组合框没有作用。

    由于组合框中包含了编辑框和列表框,因此它有大量的属性。大多数编辑框和列表框
    样式有可用于组合框的相似属性,下面两个属性是组合框特有的。
    1 .Enter listbox items
    用于创建对话框时默认显示的列表项。在每次进入后按Ctrl+Enter键。
    2. Type
    用于指定组合框类。用户可以在Simple, Dropdown和Drop List之间选择。Dropdown是默认的选择。Simple类型是一个文本框与列表框相组合的风格,DropDown类型允许用户输入,DropList类型不允许用户输入。所以选择DropDown类型时,可以在对话框类中连接CString类型的值成员变量,选择DropList类型时,可以在对话框类中连接int型的值成员变量,对于两者的操作与列表框的操作完全相同。

    七、 CScroIIBar类控件的使用

    (一) CScrollBar类控件介绍

    滚动条是一种交互式的、高度可视化的控件,它对用户的输入有几种不同的响应。滚动条中包括一个滑块,这个滑块能够沿滚动条移动;在滚动条的两端还各有一组按钮。

    滚动条控件与属于窗口的滚动条是不一样的,属于窗口的滚动条由该窗口创建、管理和释放,而滚动条控件由用户创建、管理和释放。滚动条在窗口中可以设置为水平或垂直,单击滚动条两端的箭头按钮时,滚动条移动的距离称为滑块的滚动单位,滚动单位可以根据程序的需要进行设置。

    滚动条控件是Windows窗口操作中常用的工具。滚动条控件最直接的功能是当应用程序显示的内容超过窗口的范围时,用户可通过拖动滚动条遍历整个窗口内容。滚动条在功能上分为垂直与水平滚动条,分别实现窗口内容的纵向和横向滚动。

    此外,滚动条控件还可作为调节音量、颜色的工具。在应用程序开发中常见到类似的滚动条使用方法。

    滚动条类的主要方法及其含义如下所示:

    EnableScrollBar( )使滚动条的一个或两个箭头有效或无效
    GetScrollInfo( )获得滚动条的消息
    GetScrollLimit()获得滚动条的范围
    GetScrollPos()获得滚动条当前的位置
    GetscrollRange()获得制定滚动条的当前最大和最小滚动位置
    SetScmBlnfo()设置滚动条的消息
    SetSCrolIPOS()设置滚动块当前的位置
    SetScrollRange( )设置制定滚动条的最大和最小滚动位置
    ShowScrollBar()显示或隐藏滚动条
    滚动条可发出的消息如下:
    SB_ BOTTOM/ SB_ RIGHT滚动到底端(右端)
    SB_ TOP/SB_ LEFT滚动到顶端(左端)
    SB_ LINEDOWN/ SB_LINERIGHT向下(向右)滚动一行(列)
    SB_LINEUP/SB_ LINELEFC向上(向左)滚动一行(列)
    SB_ PAGEDOWN/SB_PAGERIGHT向下(向右)滚动一页
    SB_PAGEUP/SB_ PAGELEF向上〔向左)滚动一页
    SB_THUMBPOSITION滚动到指定位置
    SB THUMBTRACK 滚动框被拖动。用该消息可跟踪对滚动框的拖动
    SB_ENDSCROLL 滚动结束

    注:SB:Scroll Bar

    展开全文
  • 首先,需要向项目中reference添加两个dll,一个是.NET库中System.Windows.Forms,另外一个是WindowsFormsIntegration,它位置一般是在C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF 里。 添加完两个dll...
     

    首先,需要向项目中的reference添加两个dll,一个是.NET库中的System.Windows.Forms,另外一个是WindowsFormsIntegration,它的位置一般是在C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF 里。

    添加完两个dll以后,就可以在控件库中找到WindowsFormsHost这个控件了。这个控件是我们添加Windows Form控件的基础。跟别的其他的控件一样,它也是可控的,可以自定义它在窗口中的位置、控件大小颜色等属性。我一般是比较喜欢在Blend里面创建控件。可以在Blend中的Assets中找到这个控件。或者你也可以在vs中的设计模式下的toolbox中找到它。放置完以后在xmal代码中会自动生成相应代码:

    <WindowsFormsHost Height="196" HorizontalAlignment="Left" Margin="104,65,0,0" Name="windowsFormsHost1" VerticalAlignment="Top" Width="286"/>

    然后,需要在xmal的开始处添加两行代码

    xmlns:WinFormHost="clr-namespace:System.Windows.Forms.Integration;assembly=WindowsFormsIntegration"
    xmlns:WinFormControls="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"

    这样就可以在WindowsFormsHost下放置需要的Windows Form控件了,比如

    <WindowsFormsHost Height="196" HorizontalAlignment="Left" Margin="104,65,0,0" Name="windowsFormsHost1" VerticalAlignment="Top" Width="286">
    <WinFormControls:Button Text="WinformButton" Width="150"/>
    </WindowsFormsHost>

    这是最简单的情况,就是添加了一个button,运行以后会发现整个WindowsFormsHost上就放置了一个硕大的button……如果需要有布局的可以在WindowsFormsHost下放置Panel等布局控件。

    最后附上整个xmal代码

    复制代码
    <Window x:Class="WpfApplication2.MainWindow"
    xmlns
    ="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x
    ="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:WinFormHost
    ="clr-namespace:System.Windows.Forms.Integration;assembly=WindowsFormsIntegration"
    xmlns:WinFormControls
    ="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
    Title
    ="MainWindow" Height="350" Width="525">
    <Grid>
    <WindowsFormsHost Height="196" HorizontalAlignment="Left" Margin="104,65,0,0" Name="windowsFormsHost1" VerticalAlignment="Top" Width="286">
    <WinFormControls:Button Text="WinformButton" Width="150"/>
    </WindowsFormsHost>
    </Grid>
    </Window>
    复制代码

    附上一个有用的链接,如果想做响应的朋友可以参考一下

    http://www.dotblogs.com.tw/ouch1978/archive/2011/01/03/wpf_windowsformsintegration.aspx

    转载于:https://www.cnblogs.com/changbaishan/p/3305061.html

    展开全文
  • SynEdit是一种语法突出显示编辑控件,不基于Windows通用控件。 SynEdit与Delphi和C ++ Builder兼容。 这是TurboPack SynEdit仅源发行版。 它包括用于Delphi和C ++ Builder设计时和运行时软件包,并支持Win32...
  • 使用多线程提高 Windows 窗体应用程序性能时,必须注意以线程安全方式调用控件。 示例: 访问 Windows 窗体控件本质上不是线程安全。如果有两个或多个线程操作某一控件的状态,则可能会迫使该控件进入一...

    使用多线程提高 Windows 窗体应用程序的性能时,必须注意以线程安全方式调用控件。

    示例:
    访问 Windows 窗体控件本质上不是线程安全的。如果有两个或多个线程操作某一控件的状态,则可能会迫使该控件进入一种不一致的状态。还可能出现其他与线程相关的 bug,包括争用情况和死锁。确保以线程安全方式访问控件非常重要。

    .NET Framework 有助于在以非线程安全方式访问控件时检测到这一问题。在调试器中运行应用程序时,如果创建某控件的线程之外的其他线程试图调用该控件,则调试器会引发一个 InvalidOperationException,并显示以下消息:“从不是创建控件控件名称 的线程访问它。”

    此异常在调试期间和运行时的某些情况下可靠地发生。强烈建议您在显示此错误信息时修复此问题。在调试以 .NET Framework 2.0 版之前的 .NET Framework 编写的应用程序时,可能会出现此异常。

     说明:

      可以通过将 CheckForIllegalCrossThreadCalls 属性的值设置为 false 来禁用此异常。这会使控件以与在 Visual Studio 2003 下相同的方式运行。

    下面的代码示例演示如何从辅助线程以线程安全方式和非线程安全方式调用 Windows 窗体控件。它演示一种以非线程安全方式设置 TextBox 控件的 Text 属性的方法,还演示两种以线程安全方式设置 Text 属性的方法。
    using System;
    using System.ComponentModel;
    using System.Threading;
    using System.Windows.Forms;
    
    namespace CrossThreadDemo
    {
    	public class Form1 : Form
    	{
    		// This delegate enables asynchronous calls for setting
    		// the text property on a TextBox control.
    		delegate void SetTextCallback(string text);
    
    		// This thread is used to demonstrate both thread-safe and
    		// unsafe ways to call a Windows Forms control.
    		private Thread demoThread = null;
    
    		// This BackgroundWorker is used to demonstrate the 
    		// preferred way of performing asynchronous operations.
    		private BackgroundWorker backgroundWorker1;
    
    		private TextBox textBox1;
    		private Button setTextUnsafeBtn;
    		private Button setTextSafeBtn;
    		private Button setTextBackgroundWorkerBtn;
    
    		private System.ComponentModel.IContainer components = null;
    
    		public Form1()
    		{
    			InitializeComponent();
    		}
    
    		protected override void Dispose(bool disposing)
    		{
    			if (disposing && (components != null))
    			{
    				components.Dispose();
    			}
    			base.Dispose(disposing);
    		}
    
    		// This event handler creates a thread that calls a 
    		// Windows Forms control in an unsafe way.
    		private void setTextUnsafeBtn_Click(
    			object sender, 
    			EventArgs e)
    		{
    			this.demoThread = 
    				new Thread(new ThreadStart(this.ThreadProcUnsafe));
    
    			this.demoThread.Start();
    		}
    
    		// This method is executed on the worker thread and makes
    		// an unsafe call on the TextBox control.
    		private void ThreadProcUnsafe()
    		{
    			this.textBox1.Text = "This text was set unsafely.";
    		}
    
    		// This event handler creates a thread that calls a 
    		// Windows Forms control in a thread-safe way.
    		private void setTextSafeBtn_Click(
    			object sender, 
    			EventArgs e)
    		{
    			this.demoThread = 
    				new Thread(new ThreadStart(this.ThreadProcSafe));
    
    			this.demoThread.Start();
    		}
    
    		// This method is executed on the worker thread and makes
    		// a thread-safe call on the TextBox control.
    		private void ThreadProcSafe()
    		{
    			this.SetText("This text was set safely.");
    		}
    
    		// This method demonstrates a pattern for making thread-safe
    		// calls on a Windows Forms control. 
    		//
    		// If the calling thread is different from the thread that
    		// created the TextBox control, this method creates a
    		// SetTextCallback and calls itself asynchronously using the
    		// Invoke method.
    		//
    		// If the calling thread is the same as the thread that created
    		// the TextBox control, the Text property is set directly. 
    
    		private void SetText(string text)
    		{
    			// InvokeRequired required compares the thread ID of the
    			// calling thread to the thread ID of the creating thread.
    			// If these threads are different, it returns true.
    			if (this.textBox1.InvokeRequired)
    			{	
    				SetTextCallback d = new SetTextCallback(SetText);
    				this.Invoke(d, new object[] { text });
    			}
    			else
    			{
    				this.textBox1.Text = text;
    			}
    		}
    
    		// This event handler starts the form's 
    		// BackgroundWorker by calling RunWorkerAsync.
    		//
    		// The Text property of the TextBox control is set
    		// when the BackgroundWorker raises the RunWorkerCompleted
    		// event.
    		private void setTextBackgroundWorkerBtn_Click(
    			object sender, 
    			EventArgs e)
    		{
    			this.backgroundWorker1.RunWorkerAsync();
    		}
    		
    		// This event handler sets the Text property of the TextBox
    		// control. It is called on the thread that created the 
    		// TextBox control, so the call is thread-safe.
    		//
    		// BackgroundWorker is the preferred way to perform asynchronous
    		// operations.
    
    		private void backgroundWorker1_RunWorkerCompleted(
    			object sender, 
    			RunWorkerCompletedEventArgs e)
    		{
    			this.textBox1.Text = 
    				"This text was set safely by BackgroundWorker.";
    		}
    
    		#region Windows Form Designer generated code
    
    		private void InitializeComponent()
    		{
    			this.textBox1 = new System.Windows.Forms.TextBox();
    			this.setTextUnsafeBtn = new System.Windows.Forms.Button();
    			this.setTextSafeBtn = new System.Windows.Forms.Button();
    			this.setTextBackgroundWorkerBtn = new System.Windows.Forms.Button();
    			this.backgroundWorker1 = new System.ComponentModel.BackgroundWorker();
    			this.SuspendLayout();
    			// 
    			// textBox1
    			// 
    			this.textBox1.Location = new System.Drawing.Point(12, 12);
    			this.textBox1.Name = "textBox1";
    			this.textBox1.Size = new System.Drawing.Size(240, 20);
    			this.textBox1.TabIndex = 0;
    			// 
    			// setTextUnsafeBtn
    			// 
    			this.setTextUnsafeBtn.Location = new System.Drawing.Point(15, 55);
    			this.setTextUnsafeBtn.Name = "setTextUnsafeBtn";
    			this.setTextUnsafeBtn.TabIndex = 1;
    			this.setTextUnsafeBtn.Text = "Unsafe Call";
    			this.setTextUnsafeBtn.Click += new System.EventHandler(this.setTextUnsafeBtn_Click);
    			// 
    			// setTextSafeBtn
    			// 
    			this.setTextSafeBtn.Location = new System.Drawing.Point(96, 55);
    			this.setTextSafeBtn.Name = "setTextSafeBtn";
    			this.setTextSafeBtn.TabIndex = 2;
    			this.setTextSafeBtn.Text = "Safe Call";
    			this.setTextSafeBtn.Click += new System.EventHandler(this.setTextSafeBtn_Click);
    			// 
    			// setTextBackgroundWorkerBtn
    			// 
    			this.setTextBackgroundWorkerBtn.Location = new System.Drawing.Point(177, 55);
    			this.setTextBackgroundWorkerBtn.Name = "setTextBackgroundWorkerBtn";
    			this.setTextBackgroundWorkerBtn.TabIndex = 3;
    			this.setTextBackgroundWorkerBtn.Text = "Safe BW Call";
    			this.setTextBackgroundWorkerBtn.Click += new System.EventHandler(this.setTextBackgroundWorkerBtn_Click);
    			// 
    			// backgroundWorker1
    			// 
    			this.backgroundWorker1.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.backgroundWorker1_RunWorkerCompleted);
    			// 
    			// Form1
    			// 
    			this.ClientSize = new System.Drawing.Size(268, 96);
    			this.Controls.Add(this.setTextBackgroundWorkerBtn);
    			this.Controls.Add(this.setTextSafeBtn);
    			this.Controls.Add(this.setTextUnsafeBtn);
    			this.Controls.Add(this.textBox1);
    			this.Name = "Form1";
    			this.Text = "Form1";
    			this.ResumeLayout(false);
    			this.PerformLayout();
    
    		}
    
    		#endregion
    
    
    		[STAThread]
    		static void Main()
    		{
    			Application.EnableVisualStyles();
    			Application.Run(new Form1());
    		}
    
    	}
    }
    
    
    

    对 Windows 窗体控件的非线程安全调用

    对 Windows 窗体控件的非线程安全调用方式是从辅助线程直接调用。调用应用程序时,调试器会引发一个 InvalidOperationException,警告对控件的调用不是线程安全的。

    		// This event handler creates a thread that calls a 
    		// Windows Forms control in an unsafe way.
    		private void setTextUnsafeBtn_Click(
    			object sender, 
    			EventArgs e)
    		{
    			this.demoThread = 
    				new Thread(new ThreadStart(this.ThreadProcUnsafe));
    
    			this.demoThread.Start();
    		}
    
    		// This method is executed on the worker thread and makes
    		// an unsafe call on the TextBox control.
    		private void ThreadProcUnsafe()
    		{
    			this.textBox1.Text = "This text was set unsafely.";
    		}
    
    
    

    对 Windows 窗体控件进行线程安全调用

    1. 查询控件的 InvokeRequired 属性。

    2. 如果 InvokeRequired 返回 true,则使用实际调用控件的委托来调用 Invoke

    3. 如果 InvokeRequired 返回 false,则直接调用控件。

    在下面的代码示例中,此逻辑是在一个称为 SetText 的实用工具方法中实现的。名为 SetTextDelegate 的委托类型封装 SetText 方法。TextBox 控件的 InvokeRequired 返回 true 时,SetText 方法创建 SetTextDelegate 的一个实例,并调用窗体的 Invoke 方法。这使得 SetText 方法被创建 TextBox 控件的线程调用,而且在此线程上下文中将直接设置 Text 属性。

    		// This event handler creates a thread that calls a 
    		// Windows Forms control in a thread-safe way.
    		private void setTextSafeBtn_Click(
    			object sender, 
    			EventArgs e)
    		{
    			this.demoThread = 
    				new Thread(new ThreadStart(this.ThreadProcSafe));
    
    			this.demoThread.Start();
    		}
    
    		// This method is executed on the worker thread and makes
    		// a thread-safe call on the TextBox control.
    		private void ThreadProcSafe()
    		{
    			this.SetText("This text was set safely.");
    		}
    
    
    
    		// This method demonstrates a pattern for making thread-safe
    		// calls on a Windows Forms control. 
    		//
    		// If the calling thread is different from the thread that
    		// created the TextBox control, this method creates a
    		// SetTextCallback and calls itself asynchronously using the
    		// Invoke method.
    		//
    		// If the calling thread is the same as the thread that created
    		// the TextBox control, the Text property is set directly. 
    
    		private void SetText(string text)
    		{
    			// InvokeRequired required compares the thread ID of the
    			// calling thread to the thread ID of the creating thread.
    			// If these threads are different, it returns true.
    			if (this.textBox1.InvokeRequired)
    			{	
    				SetTextCallback d = new SetTextCallback(SetText);
    				this.Invoke(d, new object[] { text });
    			}
    			else
    			{
    				this.textBox1.Text = text;
    			}
    		}
    
    
    

    使用 BackgroundWorker 进行的线程安全调用

    在应用程序中实现多线程的首选方式是使用 BackgroundWorker 组件。BackgroundWorker 组件使用事件驱动模型实现多线程。辅助线程运行 DoWork 事件处理程序,创建控件的线程运行 ProgressChangedRunWorkerCompleted 事件处理程序。注意不要从 DoWork 事件处理程序调用您的任何控件。

    下面的代码示例不异步执行任何工作,因此没有 DoWork 事件处理程序的实现。TextBox 控件的 Text 属性在 RunWorkerCompleted 事件处理程序中直接设置。

    		// This event handler starts the form's 
    		// BackgroundWorker by calling RunWorkerAsync.
    		//
    		// The Text property of the TextBox control is set
    		// when the BackgroundWorker raises the RunWorkerCompleted
    		// event.
    		private void setTextBackgroundWorkerBtn_Click(
    			object sender, 
    			EventArgs e)
    		{
    			this.backgroundWorker1.RunWorkerAsync();
    		}
    		
    		// This event handler sets the Text property of the TextBox
    		// control. It is called on the thread that created the 
    		// TextBox control, so the call is thread-safe.
    		//
    		// BackgroundWorker is the preferred way to perform asynchronous
    		// operations.
    
    		private void backgroundWorker1_RunWorkerCompleted(
    			object sender, 
    			RunWorkerCompletedEventArgs e)
    		{
    			this.textBox1.Text = 
    				"This text was set safely by BackgroundWorker.";
    		}
    
    
    

    Windows 窗体上的 ActiveX 控件

    如果在窗体上使用 ActiveX 控件,则在调试器下运行时可能会收到线程间 InvalidOperationException。发生这种情况时,ActiveX 控件不支持多线程处理。有关使用 Windows 窗体的 ActiveX 控件的更多信息,请参见 Windows 窗体和非托管应用程序

    如果您使用的是 Visual Studio,则可以通过禁用 Visual Studio 宿主进程来防止此异常发生。

    转载于:https://www.cnblogs.com/fang8206/archive/2011/12/10/2283049.html

    展开全文
  • 访问 Windows 窗体控件本质上不是线程安全。如果有两个或多个线程操作某一控件的状态,则可能会迫使该控件进入一种不一致状态。还可能出现其他与线程相关 bug,包括争用情况和死锁。确保以线程安全方式访问...
  • 压缩包内为一个完整MFC程序,程序包括了静态控件、编辑框控件、复选框控件、单选控件、按钮控件的组合使用。同时对关键部分代码做了一定注释
  • 访问 Windows 窗体控件本质上不是线程安全。如果有两个或多个线程操作某一控件的状态,则可能会迫使该控件进入一种不一致状态。还可能出现其他与线程相关 bug,包括争用情况和死锁。确保以线程安全方式访问...

    访问 Windows 窗体控件本质上不是线程安全的。如果有两个或多个线程操作某一控件的状态,则可能会迫使该控件进入一种不一致的状态。还可能出现其他与线程相关的 bug,包括争用情况和死锁。确保以线程安全方式访问控件非常重要。
             .NET Framework 有助于在以非线程安全方式访问控件时检测到这一问题。在调试器中运行应用程序时,如果创建某控件的线程之外的其他线程试图调用该控件,则调试器会引发一个 InvalidOperationException,并提示消息:“从不是创建控件 control name 的线程访问它。”
             可以通过将 CheckForIllegalCrossThreadCalls 属性的值设置为 false 来禁用此异常。这会使控件以与在 Visual Studio 2003 下相同的方式运行。但是这样做会使程序出现预料之外的问题,如果程序的各线程之间没有互相争抢控件资源的情况,那么可以考虑采用这个办法。例如:
    public Form1()
             ...{
                 InitializeComponent();
                 CheckForIllegalCrossThreadCalls = false;
             }

    下面分别演示一下线程安全与非线程安全访问的实现
    这里演示了两种线程安全的控件调用方法:
    一种是利用delegate接口以及Invoke方法(黄色背景)
    一种是使用BackgroundWorker方法(绿色背景)
    目的都是通过调用创建该控件的线程,来对控件进行操作。
    namespace CrossThreadDemo
    ...{
         public class Form1 : Form
         ...{
             // 这个 delegate 用来实现对TextBox控件Text属性的异步操作
             delegate void SetTextCallback(string text);
             // 创建用来调用控件的线程对象
             private Thread demoThread = null;
             // 利用backgroundworker进行线程安全调用
             private BackgroundWorker backgroundWorker1;
             private TextBox textBox1;
             private Button setTextUnsafeBtn;
             private Button setTextSafeBtn;
             private Button setTextBackgroundWorkerBtn;
             private System.ComponentModel.IContainer components = null;
             // 按钮事件,创建非线程安全调用的线程
             private void setTextUnsafeBtn_Click(
                 object sender,
                 EventArgs e)
             ...{
                 this.demoThread =
                     new Thread(new ThreadStart(this.ThreadProcUnsafe));
                 this.demoThread.Start();
             }
             // 采用非线程安全调用
             private void ThreadProcUnsafe()
             ...{
                 this.textBox1.Text = "This text was set unsafely.";
             }
             // 按钮事件,创建线程安全调用的线程
             private void setTextSafeBtn_Click(
                 object sender,
                 EventArgs e)
             ...{
                 this.demoThread =
                     new Thread(new ThreadStart(this.ThreadProcSafe));
                 this.demoThread.Start();
             }
             // 调用worker线程,采用线程安全调用
             private void ThreadProcSafe()
             ...{
                 this.SetText("This text was set safely.");
             }
             // 使用线程安全方法对窗体控件进行操作
             // 首先查询控件的InvokeRequired属性,以此来判断是不是正在从创建这个控件的线程访问该控件
             // 如果不是正在从创建这个控件的线程访问该控件,该方法将创建 SetTextDelegate 的一个实例,
         // 并调用窗体的 Invoke 方法,这使得 SetText 方法被创建 TextBox 控件的线程调用,而且在此线程上下文中将直接设置 Text 属性
             //
             // 如果是从创建该控件的线程访问它,则直接对其进行操作
             private void SetText(string text)
             ...{
                 // InvokeRequired 比较线程ID以及创建控件的线程ID,不同则返回true
                 if (this.textBox1.InvokeRequired)
                 ...{   
                     SetTextCallback d = new SetTextCallback(SetText);
                     this.Invoke(d, new object[] ...{ text });
                 }
                 else
                 ...{
                     this.textBox1.Text = text;
                 }
             }
             // 该事件通过调用RunWorkerAsync方法启动BackgroundWorker
             // TextBox的Text属性将在 BackgroundWorker 发生 RunWorkerCompleted 事件之后设置好
             private void setTextBackgroundWorkerBtn_Click(
                 object sender,
                 EventArgs e)
             ...{
                 this.backgroundWorker1.RunWorkerAsync();
             }       
             // 通过调用创建控件的线程来更改控件属性,所以是线程安全的
             // BackgroundWorker 是首选的异步控件操作方法
             private void backgroundWorker1_RunWorkerCompleted(
                 object sender,
                 RunWorkerCompletedEventArgs e)
             ...{
                 this.textBox1.Text =
                     "This text was set safely by BackgroundWorker.";
             }
         }

    转载于:https://www.cnblogs.com/ChangTan/archive/2011/05/18/2050395.html

    展开全文
  • windows编程的控件应用,包括文本框,列表框,按钮,进度条等等
  • 控件包括:静态控件、按钮控件、编辑框控件、列表框控件、组合框控件,滚动条等如表所示。Windows标准控件类型StaticGroup BoxButtonCheck BoxRadio ButtonEditComboBoxListBox Windows通用控件,可执行代码都在...
  • VC++自定义CTRL控件包括按钮CList等代码实例,这些控件中包括了一些带图像动态按钮、带颜色ListBox、以及一些自定义菜单等,这些小控件对窗体美化来说比较有用,如果你是VC编程新手,这些例子是有必要学习...
  • 访问 Windows 窗体控件本质上不是线程安全。如果有两个或多个线程操作某一控件的状态,则可能会迫使该控件进入一种不一致状态。还可能出现其他与线程相关 bug,包括争用情况和死锁。确保以线程安全方式访问...
  • 这个控件可以让你拥有支持主题的Vista风格的控件包括普通的按钮、文本框、水平/垂直滚动条、Tab控件、菜单、上下文菜单、ComboBox下拉框、网格、树、进度条、状态条、工具条等等。需要的开发工具是Visual Studio ...
  • ScintillaNET是Windows Forms控件,包装程序和用于通用源代码编辑组件绑定。 “除了标准文本编辑组件中功能外,Scintilla还包括在编辑和调试源代码时特别有用功能。这些功能包括对语法样式,错误指示符,代码...
  • 设计了Windows基本控件的使用,本程序使用C语言写的,主要是为了帮助...里面的控件介绍包括TREEVIEW、Tab Control、Animation Control、Picture Control、Slider Control、List Control、ListView、Combo Box Control等
  • 如题,使用ToolStripControlHost。 先看MSDN上介绍: ToolStripControlHost 是 ToolStripComboBox、... ToolStripControlHost 可以通过两种方法承载其他控件包括自定义控件): •从派生自 Control
  • 本文讲解如何使用多线程安全地使用.NET 中的Windows窗体控件。  使用多线程提高 Windows 窗体应用程序性能时,必须注意以线程安全方式调用控件。  访问 Windows 窗体控件本质上不是线程安全。如果有两个...
  • 写这一篇还是顶着很大压力。相信又有不少人要瞧不过去了。...这些控件包括:Edit、ListBox、ComoBox。还有一些Win32控件,包括ListView、TreeView等等控件。所有这些,在VCL中定义为TWinControl,
  • 如何在EGE里面增加按钮以及弹出框之类的, EGE图形库并没有自带这些功能, 如何实现这些...目前版本的控件包括动态和静态截图功能等( jpg,bmp, avi 等多种格式), 又见:http://xege.org/ege_3rdparty_ui_lib.html

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,348
精华内容 939
关键字:

windows的控件包括