VB中动态创建控件

C++游戏开发实战:从零构建局域网联机对战系统(附完整代码解析) 本文详细介绍了如何使用C++开发局域网联机对战游戏系统,涵盖从环境搭建到实战代码解析的全过程。重点讲解了Winsock库的应用、Socket通信原理、服务端与客户端开发技巧,以及性能优化和安全防护方案,帮助开发者快速掌握C++游戏开发的核心技术。 阅读详情
VB中动态创建控件
作者:未知

创建数据驱动窗体

所谓数据驱动窗体就是根据所请求的数据的不同生成相应的窗体。举例来讲,假设你现在有一个数据库,其中有些字段必须根据登录者的身份加以显示,授权级别高的用户可以浏览并修改这些字段的内容;授权级别一般的用户只能浏览这些字段中的数据;授权级别低的用户则不能浏览这些字段中的内容。要做到这一点就得利用VB动态添加控件的功能。

动态创建控件

无论你想要创建何种类型的数据驱动窗体,你必须知道如何在运行时动态地创建控件。你可以通过控件数组做到这一点,但VB6的Controls集合所提供的Add方法,功能更强大,灵活性更高。使用该方法,你不需要在设计时将控件的实例放在窗体上。实际上,用Add方法你甚至可以创建程序在编译时根本不存在的控件。这种方法的用法也很简单:

' 声明一个窗体级的变量
Dim WithEvents txtTotal As TextBox

Sub CreateTextbox()
   ' 创建新的Textbox控件
   Set txtTotal = Controls.Add("VB.TextBox", "txtTotal")
   ' 将控件移动到你所需要的地方
   txtTotal.Move 1000, 800, 1200, 300
   ' 创建时,所有的控件都是不可见的
   txtTotal.Visible = True
End Sub
请注意Add方法的第二个参数:分配给控件的名称。从代码可读性出发,这个名称一般都与变量名相同。你可以用这个名称从Controls集合中获取相应的控件或移除该控件。例如:

Controls.Remove "txtTotal"

在变量声明时加上WithEvents关键字,即使在设计时窗体不存在该控件,你也可以为该控件的事件编写代码。

上面所讲的方法只适合解决VB内置的控件。例如,当你要添加一个TreeView控件时,VB会要求你证明你已经得到了合法的授权来创建该控件的实例。换句话说,VB要证明这个控件是买来的,而不是从其它附有该控件的程序中借来的。

要证明你经过了合法的授权有下面几种方法:

在窗体上放置一个控件。这也是最简单的方法。你完全没有必要将这个窗体显示出来。
将相关的控件添加到工具箱中,然后在“工程属性”对话框的“生成”标签页中取消选择“删除有关未使用的ActiveX控件的信息”这一项。
向Licenses集合添加一个元素。例如:Debug.Print Licenses.Add("MSMask.MaskedEdBox")
仅仅创建了控件并不足够

要创建一个数据驱动窗体,仅仅知道动态创建控件还不够。例如:现在你要创建一个能根据数据库中表的不同字段自动生成控件的窗体。该窗体可能会创建单行文本框,其长度随字段长度不同而不同;也可能会创建单选按钮或复选按钮以显示布尔型字段;甚至可能创建一个多行文本框显示备注型字段。

你需要解决的第一个问题是:文本框控件的Multiline属性在运行时是只读的,只在设计时可用。幸好,微软的Microsoft Windowless Controls 6.0可以解决这个问题。这组控件集包括了轻量级的TextBox,ComboBox,ListBox,CheckBox,OptionButton,CommandButton和两个scrollbar控件。这些控件与VB内置的相应的控件最大的区别在于:这些控件的所有属性在运行时是可读写的。在VB的安装光盘中的Common/Tools/VB/WinLess文件夹中可以找到这个控件组。用下面的代码可以创建一个多行文本框:

Dim WithEvents txtEditor As  MSWLess.WLText

Private Sub CreateEditor()
   Set txtEditor = Controls.Add( "MSWLess.WLText", "txtEditor")
   txtEditor.Move 0, 0, 4000, 4000
   txtEditor.MultiLine = True
   txtEditor.ScrollBars = wlBoth
   txtEditor.Visible = True
End Sub
另外一个问题比较复杂:在事先不知道要创建多少个控件的情况下,如何给每个对新创建的控件的引用分配唯一的带WithEvents关键字的变量。换句话说就是要对新创建的控件的事件进行编程,前提是你在设计时不知道程序会创建多少个控件。使用对象数组显然不行,因为不能用WithEvents关键字声明一个对象数组;更坏的情况是,资一个变量定义为As Control或As Object也不行,因为还是不能用WithEvents。

问题源自于我们无法在运行时捕获一个对象数组事件。所以我们只能采取曲线救国的办法。所要的编写的代码可能比你想象的多,不过这个解决方法很有趣,值得我们这样去做。

我们需要两个辅助类模块来捕获事件,分别取名为ControlItems和ControlItem。ControlItems是一个集合类,其中保存了ControlItem对象及其数量。该数量等于你所要对之编程的控件的数量。ControlItem类的每一份实例捕获控件产生的事件,然后调用在其所属的ControlItems集合类中的过程,最后由ControlItems在窗体中触发事件并执行事件中的代码。整个过程如下图所示:



捕获多个控件的事件

为简单起见,假设你要捕获来自所有的动态添加到窗体上去的控件的Validate事件。为完成这个工作,ControlItems集合类必须向父窗体展示该事件,并随时准备接收来自其子ControlItem类的通知以触发事件。代码如下:

Event Validate(CtrlItem As ControlItem, Cancel As Boolean)
Private m_ControlItems As New Collection

' 向集合中添加一个新的ControlItem项目
Function Add(ctrl As Control) As ControlItem
   Dim newItem As New ControlItem
   newItem.Init ctrl, Me
   ' 添加到私有类
   m_ControlItems.Add newItem
   ' 返回新项目给调用者
   Set Add = newItem
End Function

Friend Sub Notify_Validate(Item As ControlItem, Cancel As Boolean)
   RaiseEvent Validate(Item, Cancel)
End Sub
ControlItem类必须捕获来自动态添加到窗体中的控件的事件,并通知其所属的ControlItems集合类。很显然,ControlItem类必须有一个用WithEvents关键字定义的变量来引用真正的控件。这意味着你不能将变量声明为As Control或As Object。如果你决定在窗体中所动态添加的控件不使用VB内置的控件的话,这个问题的解决办法相当的简单。你只需要将变量声明为VBControlExtender类型就行了。对于创建数据驱动窗体来讲,不使用VB内置的控件并不是一件大不了的事。

将变量声明为VBControlExtender,并加上WithEvents关键字,你就能直接捕获Validate,GotFocus,LostFocus,DragDrop和DragOver这几个事件了。如果要捕获其它更多的事件,你可以使用ObjectEvent。下面是ControlItem类模块中的代码:

Public WithEvents Ctrl As VBControlExtender
' 所属的ControlItems对象
Dim m_Parent As ControlItems

Sub Init(ctl As Object, parnt As ControlItems)
   Set Ctrl = ctl
   Set m_Parent = parnt
End Sub

Private Sub Ctrl_Validate(Cancel As Boolean)
   ' 通知所属的ControlItems类
   m_Parent.Notify_Validate Me, Cancel
End Sub
将下面的代码放入窗体中,就可以捕获动态添加的控件所产生的事件了:

Dim WithEvents CtrlItems As New ControlItems

Private Sub cmdCreateControls_Click()
   Dim ctrl As Control
   ' 创建两个文本框并将它们添加到ControlItems集合?   Set ctrl = Controls.Add("MSWLess.WLText", "One")
   ctrl.Move 100, 200, 1000, 300
   ctrl.Visible = True
   CtrlItems.Add ctrl
   ' 注意你可以使用同一个变量
   Set ctrl = Controls.Add("MSWLess.WLText", "Two")
   ctrl.Move 100, 800, 1000, 300
   ctrl.Visible = True
   CtrlItems.Add ctrl
End Sub

Private Sub CtrlItems_Validate( CtrlItem As ControlItem, Cancel As Boolean)
   ' 拒绝空字符串 - 注意如何引用控件的属?   If CtrlItem.Ctrl.Text = ""
   Then Cancel=True
End Sub

现在解决了最困难的部分,要创建一个数据驱动窗体就变得简单了

**************************************************************
****************************************************************
动态添加控件

VB6有一个新功能,可以动态添加控件,不用控件数组:

object.Add (ProgID, name, container)
参数说明  



Object 必需的。一个对象表达式,其值是“应用于”列表中的一个对象。
ProgID 必需的。一个标识控件的字符串。大多数控件的 ProgID 都可通过查看对象浏览器来决定。控件的 ProgID 是由控件的库和类组成的。
     例如,CommandButton 控件的 ProgID 是 VB.CommandButton。在ProgID 与对象浏览器中所显示的不一样的情况下,Visual Basic
将显示一个包括正确 ProgId 的错误信息。
name 必要的。一个字符串,用来标识集合的成员。
container 可选的。一个对象引用,它指定控件的容器。如果没有指定或为NULL,缺省值为 Controls 集合所属的容器。通过指定该参数,可以把一个控件放置在任何现存的容器控件(如 Frame 控件)中。用户控件或 ActiveX 文档也可以作为一个容器。
 


举例: //在picture1上面添加一个commandbutton
Private Sub Form_Load()
    Form1.Controls.Add "VB.CommandButton", "cmdOk", Picture1
    With Form1!cmdOk
       .Visible = True
       .Width = 500
       .Caption = "确认(&Y)"
    End With
End Sub

 


  重点:当您添加一个未引用的需要许可证的控件到一个现存的(已部署好的)应用程序时,在使用 Add 方法之前您必须也添加这个控件的许可证关键字。

在运行时添加未引用的控件:
  您也可以利用 Add 方法来动态添加一个在工程中没有被引用的控件。(“未引用的”控件是不出现在 Toolbox 中的控件)。为此,您必须也把控件的License 关键字添加到 Licenses 集合中。下面的示例中在添加控件本身之前添加了控件的许可证关键字:

Option Explicit
Private WithEvents extCtl As VBControlExtender

Private Sub Form_Load()
    Licenses.Add "prjWeeks.WeeksCtl", "xydsfasfjewfe"
    Set extCtl = Form1.Controls.Add("prjWeeks.WeeksCtl", "ctl1")
    extCtl.Visible = True ' The control is invisible by default.
End Sub

  但是,为了编程这样一个未引用控件的事件,您必须使用 WithEvents 关键字声明一个对象变量为VBControlExtender 对象(如上),并且设置该对象变量到Add 方法返回的引用上。然后,利用VBControlExtender 对象的 ObjectEvent事件来编程该控件的事件。下面是一个简单的例子。

Option Explicit
Dim WithEvents objExt As VBControlExtender '声明 Extender 变量

Private Sub LoadControl()
    Licenses.Add "Project1.Control1", "xydsfasfjewfe"
    Set objExt = Controls.Add("Project1.Control1", "myCtl")
    objExt.Visible = True
End Sub

Private Sub extObj_ObjectEvent(Info As EventInfo)
    '使用 Select Case 编程控件的事件。
    Select Case Info.Name
    Case "Click"
       '这里处理 Click 事件。
    '现在显示其他的 case
    Case Else '未知事件
       '这里处理未知事件。
    End Select
End Sub

Note: 不能把一个固有的控件指定给这个 VBControlExtender 变量; 任何这种试图将引起类型不匹配错误。

  但是,您也可以通过使用 WithEvents 关键字声明一个对象变量,并且设置该方法返回的引用为该变量,从而编程一个动态添加控件的事件,如下所示。

Option Explicit
'声明对象变量为 CommandButton 。
Private WithEvents cmdObject As CommandButton

Private Sub Form_Load()
    Set cmdObject = Form1.Controls.Add("VB.CommandButton", "cmdOne")
    cmdObject.Visible = True
    cmdObject.Caption = "Dynamic CommandButton"
End Sub

Private Sub cmdObject_Click()
     Print "This is a dynamically added control"
End Sub
  如果希望添加一个用户控件或任何 ActiveX 控件到您的窗体,必须或者把这个控件添加到“工具箱”,或者把控件的 License 关键字添加到 Licenses集合中。有关详细信息请参阅“增加方法 (Licenses 集合)”。

  注意:如果您添加一个 ActiveX 或用户控件到您的工程,但是没有在窗体中使用它,您也必须不要选定“工程属性”对话框的“生成” 选项卡上的“删除有关未使用的 ActiveX 控件”选项。如果您的应用程序试图添加该控件,那么该 Add 方法将失败,因为必需的信息已经被丢弃。
ubuntu虚拟机搭建OP-TEE 在网上找了一些搭建OP-TEE的过程,模仿着进行搭建,结果有好多报错,为了方便自己以后重新搭建,所以将整个过程记录下来。 阅读详情

相关推荐

SFF-8654接口引脚定义全解析:从SAS到U.2的高速硬件连接核心

在高速数据存储与传输领域,接口标准是连接主机与存储设备、确保信号完整性与协议互通性的物理基础。其核心原理在于通过精确定义的物理引脚和电气特性,承载不同的高速串行通信协议,如SAS和PCIe。这类高密度连接器的技术价值在于以紧凑的形态支持多协议兼容与高速率传输,满足了企业级存储、高性能计算对带宽和可靠性的苛刻要求。典型的应用场景包括服务器硬盘背板连接、NVMe U.2固态硬盘直连以及外部存储扩展。本文聚焦于SFF-8654(亦称Mini SAS HD)这一关键接口,深入剖析其引脚定义、信号分区(如高速数据通道

weixin_29188043的博客 713

IPOS EXCEL 导入 报错 run-time error ‘91‘ object variable or with block variable not set”,怎么处理

【问】:用IPOS系统excel表格导入的时候,弹出错误提示:“run-time error '91' object variable or with block variable not set”,怎么处理? 【答】:这个是因为你安装office2007版,默认打开了一些插件开关,而安装文件没有自带这些插件程序。所以导致打开错误。其实这些插件开关,你都用不到,都关闭就可以了。 关闭方法: 打开你的excel2007,随便打开1个。 点击左上角的“文件” ↓ 找到“选项” ↓.

yuyin555的专栏 1万+

群晖Web Station实战:从零搭建个人静态导航站

本文详细介绍了如何利用群晖NAS自带的Web Station套件,从零开始搭建个人静态导航站。通过安装Web Station、上传静态网站源码、配置网页服务与网络门户等步骤,无需代码基础即可实现内网访问。文章还分享了文件权限设置、个性化定制及常见问题排查等实用技巧,帮助用户高效管理个人常用网址,充分挖掘NAS的服务器潜能。

tea88的博客 1330

20100910 学习记录:VB6.0 Error: run-time error '91' object variable or with block variable not set...

vb6.0对我来说就是噩梦..... (┬_┬)经理不知又从哪里弄出来的vb程序,让我修改... 我这个头晕....完全没有信心的研究了一下,最后居然真地搞定了.... (┬_┬) 内牛~事实证明,很多时候,没什么是做不到的,只是你想不想做,肯不肯去做的问题。 回过头说一下这个问题。网上查找了一下,一般说这个问题的产生是没有声明对象没有new我检查了一下,我的是有声明的,但是debug就一直说...

weixin_34293911的博客 773

Sentence-BERT 语义相似度双塔模型

论文介绍 发表:2019,EMNLP 论文题目:《Sentence-BERT:sentence embeddings using siaese BERT-networks》 论文地址:https://arxiv.org/abs/1908.10084 Github:https://github.com/UKPLab/sentence-transformers 适用领域: 句向量生成 语义相似度计算 语义搜索 无监督任务(聚类) 1 概述 在20年之前的各种预训练模型中,比如bert,XLNet,Alb

weiyaner的博客 9194

BCIC IV 2a数据集实战:从MATLAB导入到EEG信号分析全流程

本文提供了BCIC IV 2a数据集从MATLAB导入到EEG信号分析的完整实战流程。详细解析了数据集结构,区分了EEG与EOG信号,并演示了信号可视化、基础预处理(滤波、分段、基线校正)等关键步骤,帮助脑机接口研究者快速上手处理这一经典运动想象数据集。

weixin_29047919的博客 470

LabVIEW使用Excel 2007时错误

用程序打开Excel时,报错信息如下: Run-time error 91“”: Object variable or with block variable not set 原因是在打开Excel时,加载了2003版本的样式。 去除方法: 打开Microsoft Office 2007 建议设置, 去掉使用Office03样式经典菜单,

学习笔记 3372

太速科技-基于DSP TMS320C6678+FPGA XC7V690T的6U VPX信号处理卡

当多块盘并行工作时,存储阵列读写带宽成指数增长,2块盘则≥4GB/s,4块盘则≥8GB/s,以此类推。存储阵列的存储容量由单盘配置决定,目前单块NVME存储盘存储容量可选择512GB、1TB、2TB、4TB、8TB、16TB。硬盘管理通过文件系统,FPGA的PCIeX4与 6U VPX主板互联,操作系统直接映射管理硬盘,也可以通过前面板QSFP+ 光纤导出给其他服务器设备。本方案优势就是集中的进行采集,存储,计算一体化,降低硬件成本、功耗,减小设备体积、重量。信号处理,无线电通信领域。

Orihard_的博客 678

在VB中动态添加可响应消息的控件

在VB中动态添加可响应消息的控件    在VB编程中,经常要根据不同的情况在运行时向窗口中添加或者删除控件,而各个控件还要响应各种事件。在一般的情况下是首先在设计时将控件加入到窗口中,在它们的各个事件中写入代码,然后将它们的Visible属性设置为False。在运行时再使控件显示出来,但是这样既不方便同时也因为在设计时在窗口中加入太多的控件而使得程序的运行速度变慢。下面我向大家介绍

行者的专栏 1359

MFC C++ 中实现跨平台(WindowsLinux)的远程桌面控制

**输入捕获**:在显示窗口中捕获鼠标/键盘事件(重写 `OnLButtonDown`、`OnMouseMove`、`OnKeyDown` 等),将事件坐标/键值通过网络发送到服务端。- **显示窗口**:使用 `CStatic` 或自定义 `CWnd` 派生类显示远程桌面图像(通过 `StretchDIBits` 绘制解压后的像素数据)。// 转换为相对坐标。- **Wayland 支持**:需使用 `libweston` 或 `xdg-desktop-portal`,较复杂,建议优先支持 X11。

寒寒豆豆软件公司的博客 155

【以太网硬件一】802.3xx标准怎么这么多?它们有什么关系?

IEEE 802.3标准发展历史简介

highman110的博客 5017

VB窗体动态创建控件及控件事件

VB窗体动态创建较少,今天,试着弄一个,专为解答之用。 首先创建一个空白窗体,调整大小,修改名称,双击窗体进入代码编辑界面: Public Class VB解答专用窗体 Dim 数据列表 As DataGridView Dim 输入框 As TextBox Private Sub VB解答专用窗体_Load(sender As Object, e As EventAr...

浤济的专栏 4829

Python数据分析全流程指南:从数据采集到可视化呈现的实战解析

在数字化转型浪潮中,数据分析已成为企业决策的核心驱动力。Python凭借其丰富的生态库和简洁的语法,成为数据分析师的首选工具。本文将以实战案例为脉络,拆解数据分析全流程的关键环节,通过具体代码和场景说明如何用Python完成从数据采集到可视化呈现的完整链路。

这家伙很懒,什么都没有留下 1681

vb动态创建控件

vb动态创建控件 2009-05-17 15:52 创建数据驱动窗体         所谓数据驱动窗体就是根据所请求的数据的不同生成相应的窗体。举例来讲,假设你现在有一个数据库,其中有些字段必须根据登录者的身份加以显示,授权级别高的用户可以浏览并修改这些字段的内容;授权级别一般的用户只能浏览这些字段中的数据;授权级别低的用户则不能浏览这些字段中的内容。要做到这一点就得利用

whchensir的专栏 5270

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

vb.net 教程 3-13 动态创建控件2

版权声明:本文为博主原创文章,转载请在显著位置标明本文出处以及作者网名,未经作者允许不得用于商业目的。 上一节讲了设计时创建控件,实际设计时候可以很方便地选择创建控件的事件代码, 本节讲一下不使用withevents,如何在运行时创建一个带有事件的控件。 主要用到 AddHandler 语句: AddHandler event, AddressOf eventhandler event :要处理的事件的名称。 eventhandler :将处理事件的过程的名称。 这里需要强调一下,event

chinaherolts2008的博客 633

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

vb.net 教程 3-13 动态创建控件3

版权声明:本文为博主原创文章,转载请在显著位置标明本文出处以及作者网名,未经作者允许不得用于商业目的。 在vb6的时候,很方便在设计的时候创建控件数组。 例如两个按钮控件(CommandButton),当修改其中一个控件名称与另外一个控件名称一样时,vb6编辑器会提示: 按下“是”就会创建控件数组了,两个按钮区别在于Index属性不同: 在实际代码中可以看到,事件参数中多了 Index as Integer,也就是通过Index指明了是哪个具体的按钮: 那么在vb.net中,如果输入了相同的名称:

chinaherolts2008的博客 775

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

动态创建和删除VB控件

摘要:介绍在Visual Basic环境中利用动态创建和删除控件的方法,比较了两者异同,阐述了在实际应用中,Active X控件在程序运行时动态加载和删除的方法。关键词:Visual Basic 6.0;控件;控件集合;控件数组;属性;Active X1.概述在使用Visual Basic 进行程序设计的过程中,如果能在运行时刻动态地创建和删除控件,可以极大地丰富界面的处理和变化。

QQ348191658的专栏 1535

VB6 动态创建用户控件

<br />VB6有一个新功能,可以动态添加控件,不用控件数组:<br /><br />object.Add (ProgID, name, container)<br />====================================<br />参数说明:<br />Object 必需的。一个对象表达式,其值是“应用于”列表中的一个对象。 <br />ProgID 必需的。一个标识控件的字符串。大多数控件的 ProgID 都可通过查看对象浏览器来决定。控件的 ProgID 是由控件的库和类组成的。

lbuskeep的专栏 7215

VB 动态创建ActiveX控件详解

熟悉VB的朋友对使用ActiveX控件一定不会陌生,众多控件极大地方便了编程,但唯一的缺陷是不能动态加载控件,必须在设计时通过引用,将控件放置在窗体上。VB6.0已能够解决该问题,只是帮助中没有明确说明,并且没有描述到一些关键功能,由于以前的版本中可以动态创建进程外服务:如果对象是外部可创建的,可在 Set 语句中用 New 关键字、CreateObject 或 GetObject 从部件外面将对

xcntime的专栏 5247

VB动态创建控件

Dim WithEvents MyBtn As CommandButton Set MyBtn = Controls.Add("VB.CommandButton", "Button1") With MyBtn .Caption = "我可以响应事件!" .Width = 1800 .Left = 100 .Top = 700 .Visible

鞠勇鸿的技术专栏 1870
上一篇: 如何通过UDF实现查询汉字拼音的首字母?
下一篇: VB用API实现各种对话框(总结)
beta
博客等级 码龄27年 1粉丝 5原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值