📄 9920.txt
字号:
===========================================================
《编 程 技 术》
一份属于广大编程爱好者的电子杂志
这是一份完全关于探讨编程的免费电子杂志
您可以任意传播本刊,但必须保持它的完整
本刊承诺绝不向订户发送任何形式的垃圾邮件!
===========================================================
第20期 99/08/08 本期发送数: 2953
===========================================================
◆本期栏目◆
*刊首语*
*技术文档*
调用API函数设计ABOUT窗口
使用VB收发电子邮件
无标题窗口的移动
TDBGrid控件中对多个记录的处理
用MFC实现在字段中存储变长数组
BC++ Builder 3.0中各种资源的利用
在PB应用中收发电子邮件
VFP中怎样获取表单的返回值
*服务台*
三个编程相关的软件下载地址
*有问必答*
***********************************************************
***********************************************************
◆技术文档◆
调用API函数设计ABOUT窗口
江苏省镇江港务局 蔡可训
---- windows98 系 统 的 许 多 软 件 中 都 包 含 一 个windows 风 格 的
about 窗 口, 它 向 用 户 反 映 了 当 前 系 统 的 一 些 基 本 信 息,
其 中 显 示 有 关windows 及 其 应 用 软 件 的 版 本、 版 权 和 系 统
的 工 作 状 态 等 信 息。 笔 者 用VB 6.0 通 过 调 用API 函 数 设 计
应 用 系 统 的ABOUT 窗 口。
1 . 建 立 含 有 如 下 控 件 的 窗 体:
控 件 NAME CAPTION
窗 体 FORM1 用VB6.0 设 计ABOUT 窗 口
命 令 按 钮 COMMAND1 关 于 销 售 管 理 系 统
2 . 程 序 清 单:
Private Declare Function GetWindowWord Lib "user32"
(ByVal hwnd As Long, ByVal nIndex As Long) As Integer
Private Declare Function ShellAbout Lib
"shell32.dll" Alias "ShellAboutA" (ByVal hwnd As Long,
ByVal szApp As String, ByVal szOtherStuff As String,
ByVal hIcon As Long) As Long
Private Declare Function ExtractIcon Lib
"shell32.dll" Alias "ExtractIconA" (ByVal hinst As Long,
ByVal lpszExeFileName As String, ByVal nIconIndex As
Long) As Long Private Declare Function GetDiskFreeSpace
Lib "kernel32" Alias "GetDiskFreeSpaceA" (ByVal
lpRootPathName As String, lpSectorsPerCluster As Long,
lpBytesPerSector As Long, lpNumberOfFreeClusters As
Long, lpTotalNumberOfClusters As Long) As Long Private
Declare Function GetDriveType Lib "kernel32" Alias
"GetDriveTypeA" (ByVal nDrive As String) As Long
Private Declare Sub GetSystemInfo Lib "kernel32"
(lpSystemInfo As SYSTEM_INFO) Private Declare Function
GetSystemMetrics Lib "user32" (ByVal nIndex As Long) As
Long
Private Const GWL_EXSTYLE = (-20)
Private Const GWL_STYLE = (-16)
Private Const GWL_WNDPROC = (-4)
Private Const GWL_HINSTANCE = (-6)
Private Type SYSTEM_INFO
dwOemID As Long
dwPageSize As Long
lpMinimumApplicationAddress As Long
lpMaximumApplicationAddress As Long
dwActiveProcessorMask As Long
dwNumberOrfProcessors As Long
dwProcessorType As Long
dwAllocationGranularity As Long
dwReserved As Long
End Type
Private Const SM_CXSCREEN = 0
Private Const SM_CYSCREEN = 1
Private Sub Command1_Click()
Dim hinst As Long
Dim icons As Long
Dim abouts As Long
Dim dispx As String
Dim dispy As String
Dim cps As String
Dim space1 As String
Dim space2 As String
hinst = GetWindowWord(Me.hwnd, GWL_HINSTANCE)
icons = ExtractIcon(hinst, "d:\fpw26\foxprow.exe", 0)
Dim sysinfo As SYSTEM_INFO
Dim cls1 As Long
Dim cls2 As Long
Dim secs As Long
Dim bytes As Long
Dim buffs As String
buff = "C:\"
x = GetDriveType(buffs)
x = GetDiskFreeSpace(buffs, secs, bytes, cls1, cls2)
cls1 = cls1 * secs * bytes
cls2 = cls2 * secs * bytes
space1 = "C驱动器总共容量: " + Format$(cls2/1024, "#, #") + "千字节"
space2 = "C驱动器可用容量:
" + Format$(cls1/1024, "#, #") + "千字节"
x = GetSystemMetrics(SM_CXSCREEN)
dispx = "显示器分辨率:" + Str$(x)
x = GetSystemMetrics(SM_CYSCREEN)
dispy = Str$(x)
Call GetSystemInfo(sysinfo)
Select Case sysinfo.dwProcessorType
Case 386
cpus = "处理器类型:386"
Case 486
cpus = "处理器类型:486"
Case 586
cpus = "处理器类型:586"
End Select
abouts = ShellAbout(Me.hwnd, "演示程序",
"销售管理系统V2.0版权所有[C]1998-1999蔡可训"
& Chr$(13) & Chr$(10) & space1 & Chr$(13) & Chr$(10)
& space2 & Chr$(13) & Chr$(10) & cpus + " " + dispx +
"*" + dispy , icons)
End Sub
---- 以 上 程 序 在WINDOWS98,VISUAL BASIC 6.0 FOR WINDOWS 环 境 下 运
行 通 过. 用 户 可 以 将 其 加 入 应 用 系 统 的ABOUT 菜 单 项, 通
过 菜 单 项 调 用 它, 效 果 更 好。
***********************************************************
使用VB收发电子邮件
中国航空信息中心 吴斌
发送和接收电子邮件,对于某些执行特殊任务的应用程序而言,是一个十
分有用的功能。例如,一个监视网络服务器资源使用情况的工具软件,如果它
具有自动发送电子邮件的功能,那么当它发现服务器的资源使用已经接近事先
设定的临界状态时,便可以向系统管理员发送一封告警的电子邮件,从而使系
统管理员能够及时地采取措施,以避免重大事故的出现。在Visual Basic中,
应用程序可以通过调用微软公司的MAPI(Messaging Application Programming
Interface,消息应用程序编程接口),实现收发电子邮件的功能。笔者将在
本文中结合简单实例,向大家介绍在VB程序中实现电子邮件收发功能的编程方
法。
编制具有收发电子邮件功能的VB程序,必须使用Visual Basic 4.0以上的版本,
因为只有4.0以上的Visual Basic才带有两个实现电子邮件收发功能的核心控
件:MAPI会话控件和MAPI消息控件。MAPI会话控件用于建立和控制一个
Microsoft Mail会话,MAPI消息控件用于创建和收发邮件消息。此外,程序必
须运行在采用遵从MAPI的消息系统(如:Microsoft Exchange、Microsoft Mail、
Outlook等)的环境中。
在开始编程之前,首先需要将MAPI控件加入VB工具箱。具体操作是:在VB菜单
栏中选择Tools菜单项中的Custom Controls命令,调出"Custom Controls"对话
框,在其中的"Available Controls"列表框中选中"Microsoft MAPI Controls"
表项,然后按"OK"命令按钮退出该对话框。此后,工具箱中将新添两个图标,
这就是MAPI会话控件和MAPI消息控件的图标。
下面,笔者将以两个简单的VB程序为例,分别介绍发送邮件和接收邮件的程序
编制方法。
邮件发送程序
邮件发送程序的基本处理过程是:根据用户输入信息组成邮件,然后使用MAPI
消息控件的Send方法将邮件发出。编程步骤如下:
1、新建一个VB项目。
2、将缺省窗体Form1的Caption属性设置为"发送邮件"。
3、将MAPI控件加入VB工具框。
4、在Form1中加入一个MAPI会话控件MAPISession1和一个MAPI消息控件MAPIMessages1。
5、在Form1中加入三个文本框控件,将它们的Name属性分别设置为txtSendTo、
txtSubject、txtMessage,并将txtMessage的Multiline属性设置为True。这三
个文本框控件将分别用于填写邮件的收件人、主题和内容。
6、在Form1中加入三个标签控件,将它们的Caption属性分别设置为"收件人"、
"主题"和"内容",并将它们放在合适的位置用以标注相应的文本框控件。
7、在Form1中加入一个命令按钮控件,将其Caption属性和Name属性分别设置
为"发送"和"cmdSend"。
8、将下列代码加入Form1的Form_Load事件:
Private Sub Form_Load()
MAPISession1.SignOn
End Sub
9、将下列代码加入Form1的Form_Unload事件:
Private Sub Form_Unload(Cancel As Integer)
MAPISession1.SignOff
End Sub
10、将下列代码加入cmdSend的Click事件:
Private Sub cmdSend_Click()
With MAPIMessages1
.MsgIndex = -1
.RecipDisplayName = txtSendTo.Text
.MsgSubject = txtSubject.Text
.MsgNoteText = txtMessage.Text
.SessionID = MAPISession1.SessionID
.Send
End With
MsgBox "邮件发送完毕!", , "发送邮件"
End Sub
程序运行后如图3所示。在填写完邮件的收件人、主题和内容后,按"发送"命令
按钮,如果没有出现运行时错误提示,那么就表明邮件已经成功地发往目的地
了,否则,请检查填写的收件人地址是否准确无误以及系统中运行的消息系统
工作是否正常。
邮件接收程序
邮件接收程序比邮件发送程序稍微复杂一些。首先需要使用MAPI消息控件的
Fetch方法读取邮件,这个过程将把用户收件箱中所有未读邮件全部装入MAPI
消息控件中。然后,检查MAPI消息控件的MsgCount属性以确定通过Fetch方法
读取的邮件的总数。接着,可以通过设置MAPI消息控件的MsgIndex属性来指
定具体需要处理哪一封邮件。需要说明的是,MsgIndex属性值的计数是从0开
始的,也就是说,第一封邮件的索引号是0,第二封邮件的索引号是1,依次
类推。编程步骤如下:
1、新建一个VB项目。
2、将缺省窗体Form1的Caption属性设置为"接收邮件"。
3、将MAPI控件加入VB工具框。
4、在Form1中加入一个MAPI会话控件MAPISession1和一个MAPI消息控件MAPIMessages1。
5、在Form1中加入三个标签控件和一个文本框控件,将三个标签控件的Name属
性分别设置为lblMsgDateReceived、lblMsgOrigDisplayName、lblMsgSubject,
将文本框控件的Name属性设置为txtMsgNoteText,并将标签控件的Caption属性
和文本框控件的Text属性的内容清空。这四个控件将分别用于显示邮件的日期、
发件人、主题和内容。
6、将txtMsgNoteText控件的Locked属性和Multiline属性设置为True,ScrollBars
属性设置为2 - Vertical。
7、在Form1中再加入四个标签控件用于标注上述四个控件,将它们的Caption
属性分别设置为"日期"、"发件人"、"主题"、"内容"。
8、在Form1中加入一个标签控件,将其Name属性设置为lblMsgCount,Caption
属性设置为"第 0 封邮件,总计 0 封邮件"。该控件用于显示接收的邮件总数
以及当前正在处理第几封邮件。
9、在Form1中加入三个命令按钮控件,将它们的Name属性分别设置为cmdPrevious、
cmdNext、cmdClose,Caption属性分别设置为"上一封"、"下一封"、"关闭"。
10、编写一个窗体级子例程FetchNewMail:
Public Sub FetchNewMail()
MAPIMessages1.FetchUnreadOnly = True
MAPIMessages1.Fetch
End Sub
11、编写一个窗体级子例程DisplayMessage:
Public Sub DisplayMessage()
lblMsgCount.Caption = "第 " & _
LTrim(Str(MAPIMessages1.MsgIndex + 1)) & " 封邮件,总计 " & _
LTrim(Str(MAPIMessages1.MsgCount)) & " 封邮件"
lblMsgDateReceived.Caption = MAPIMessages1.MsgDateReceived
txtMsgNoteText.Text = MAPIMessages1.MsgNoteText
lblMsgOrigDisplayName.Caption = MAPIMessages1.MsgOrigDisplayName
lblMsgSubject.Caption = MAPIMessages1.MsgSubject
End Sub
12、将下列代码加入Form1的Form_Load事件:
Private Sub Form_Load()
MAPISession1.SignOn
MAPIMessages1.SessionID = MAPISession1.SessionID
FetchNewMail
DisplayMessage
End Sub
13、将下列代码加入cmdPrevious的Click事件:
Private Sub cmdPrevious_Click()
If MAPIMessages1.MsgIndex > 0 Then
MAPIMessages1.MsgIndex = MAPIMessages1.MsgIndex - 1
DisplayMessage
Else
Beep
End If
End Sub
14、将下列代码加入cmdNext的Click事件:
Private Sub cmdNext_Click()
If MAPIMessages1.MsgIndex < MAPIMessages1.MsgCount - 1 Then
MAPIMessages1.MsgIndex = MAPIMessages1.MsgIndex + 1
DisplayMessage
Else
Beep
End If
End Sub
15、将下列代码加入cmdClose的Click事件:
Private Sub cmdClose_Click()
Unload Me
End Sub
程序运行后如图4所示。在窗体加载过程中,窗体Load事件中的代码会读取新邮
件,如果有新邮件,就显示第一个新邮件。如果有多个新邮件,则可以使用"上
一封"和"下一封"命令按钮前后翻阅。
接收邮件
本例是读取用户收件箱中所有未读邮件,如果要读取收件箱中所有的邮件,那么
只需在执行Fetch方法之前,将MAPI消息控件的FetchUnreadOnly属性设置为False。
具体接收的邮件是否已经读过,可以通过MsgRead属性来判别。如果邮件的正文
或附件曾经被浏览过,那么该邮件就会自动标记为已读,不过只浏览邮件的主题
不会标记该邮件已读。
邮件附件
与处理邮件的方式一样,MAPI也为邮件的附件提供了一个计数器和一个索引。在
处理收到的邮件时,可以通过检查AttachmentCount属性来确定该邮件携带了多少
个附件,然后可以通过设置AttachmentIndex属性依次处理每一个附件。
AttachmentIndex的合法取值范围为0至AttachmentIndex-1。在设置了AttachmentIndex
属性值后,可以读取附件的下列属性:
AttachmentName:当附件是一个文件时,该属性用于指定文件的名称。当附件是
一个OLE对象时,该属性用于指定对象的类型。
AttachmentPath:该属性用于指定做为附件的文件的全路径名。
AttchmentPosition:该属性用于指定附件在邮件内容部分中的位置。当邮件收发
程序显示邮件内容时,将使用该属性提供的信息把附件的标志放在合适的位置。
AttachmentType:该属性用于指定附件的类型,其合法取值为三个整数型数值,
在VB中分别由下列常量表示:
·mapData-附件是一个数据文件
·mapEOLE-附件是一个嵌入式OLE对象
·mapSOLE-附件是一个静态OLE对象
发送邮件时,上述属性的使用方法与接收邮件时相同,只不过由读操作改为写操作
了。值得一提的是AttachmentIndex属性,发送邮件时可以将其设置为任意值。而
AttachmentCount属性则会自动设置为正确的值,无需人为设置。
小结
通过分析上述两个程序的代码,可以归纳出具有收发电子邮件功能的VB程序的基本
流程如下:
1、使用MAPI会话控件建立一个邮件会话。
2、使用MAPI消息控件进行邮件的处理工作。
3、再次使用MAPI会话控件释放邮件会话。
由于上述两个VB程序只是简单的示例,因而略去了一些与本文主题关系不大的细节,
如错误处理等。在编制实用程序时,为了保证程序的可靠性,应该考虑加入这些细
节部分。
***********************************************************
无标题窗口的移动
天津纺织工学院104# 姚佩云
---- 在Delphi 编 程 中 有 时 要 对 无 标 题 窗 体 进 行 移 动, 以 下
就 结 合 本 人 的 经 验 介 绍 几 种 对 无 标 题 窗 体 移 动 的 方 法。
---- 方 法 一:
---- 通 过 响 应“wm_NCHitTest” 消 息 来 移 动 窗 体。 Windows 发 送
“wM_NCHitTest” 消 息 来 确 定 鼠 标 操 作 是 否 发 生 在 窗 体 的
客 户 区, 或 边 框 的 特 殊 区 上( 非 客 户 区) 。 如 果Windows 发
现 用 户 单 击 了 窗 体 标 题, 系 统 将 移 动 窗 体, 单 击 了 窗 体
边 框, 则 系 统 将 开 始 改 变 窗 体 大 小。
---- 例 程 如 下:
.
.
private
{ Private declarations }
Procedure MoveForm(var M:TWMNCHITTEST);
Message WM_NCHITTEST;
//声明一自定义事件,拦截“WM_NCHITTEST”消息
public
.
.
{$R *.DFM}
Procedure TForm1.MoveForm (var M:TWMNCHITTEST);
begin
inHerited;//继承,窗体可以继续处理以后的事件
if (M.Result=HTCLIENT) //如果发生在客户区
and ((GetKeyState(vk_CONTROL) < 0)
//检测“Ctrl”键是否按下
then M.Result:=HTCAPTION;
//更改“.Result”域的值
end;
---- 方 法 二:
---- 通 过 为Application.OnMessage 创 建 一 个 处 理 程 序 获 得Windows
消 息, 可 以 调 整 应 用 程 序 对 不 同 消 息 的 响 应 或 为 不 能
正 常 识 别 的 消 息 提 供 服 务。 这 里 受 到 窗 体 客 户 区 的 鼠
标 按 下 的 消 息 后, 发 送 一 条 在 标 题 栏 内 按 下 的 消 息。
---- 例 程 如 下:
.
.
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
procedure AppMessage(var Msg:TMsg;var Handled:Boolean);
.
.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -