📄 9910.txt
字号:
=====================================================
《编 程 技 术》
一份属于广大编程爱好者的电子杂志
这是一份完全关于探讨编程的免费电子杂志
您可以任意传播本刊,但必须保持它的完整
本刊承诺绝不向订户发送任何形式的垃圾邮件!
第10期 99/05/30
=====================================================
<本期栏目>
*刊首语*
*雕虫小技*
Visual C++编程技巧8则
*技术文档*
Foxpro Windows 制作影视汉字字幕特技
在Delphi程序中维护DBF数据库
在Access数据库中实现密码管理的另一种方式
给AutoCAD 增加超级编辑命令
Delphi应用程序中中国式报表的制作
*疑难杂症*
*本周主页更新*
*****************************************************
<刊首语>
从本期开始,今后本杂志全部由博大邮件列表系统发送,
假入您在收取杂志时遇到什么问题,请与我联系。
鉴于目前日益严重的垃圾邮件问题,本人承诺绝不向订户
发送任何形式的垃圾邮件,也不会将您的邮件地址提供给任何
人。假如您受到垃圾邮件的骚扰的话,决非本人所为,请明察。
*****************************************************
*****************************************************
<雕虫小技>
Visual C++编程技巧8则
1. 如何获取应用程序的实例句柄?
应用程序的 实例句柄保存在CWinAppIm_hInstance 中,可以这么调用
AfxGetInstancdHandle获得句柄.
Example: HANDLE hInstance=AfxGetInstanceHandle();
2. 如何通过代码获得应用程序主窗口的指针?
主窗口的 指针保存在CWinThread::m_pMainWnd中,调用 AfxGetMainWnd实现。
AfxGetMainWnd() ->ShowWindow(SW_SHOWMAXMIZED); //使程序最大化.
3.如何在程序中获得其他程序的 图标?
两种方法:
(1) SDK函数 SHGetFileInfo 或使用 ExtractIcon获得图标资源的 handle,
(2) SDK函数 SHGetFileInfo获得有关文件的 很多信息,如大小图标,属性,类型等.
Example(1): 在程序窗口左上角显示 NotePad图标.
void CSampleView: OnDraw(CDC * pDC)
{
if( :: SHGetFileInfo(_T("c:\\pwin95\\notepad.exe"),0,
&stFileInfo,sizeof(stFileInfo),SHGFI_ICON))
{
pDC ->DrawIcon(10,10,stFileInfo.hIcon);
}
}
Example(2):同样功能,Use ExtractIcon Function
void CSampleView:: OnDraw(CDC *pDC)
{
HICON hIcon=:: ExtractIcon(AfxGetInstanceHandle(),_T
("NotePad.exe"),0);
if (hIcon &&hIcon!=(HICON)-1)
pDC->DrawIcon(10,10,hIcon);
}
说明: 获得notepad.exe的路径正规上来说用GetWindowsDirectory 函数得到,如
果是调用 win95下的画笔,应该用访问注册表的方法获得其路径,要作成一个比
较考究的程序,考虑应该全面点.
4.如何编程结束应用程序?如何编程控制windows的重新引导?
第一问,向窗口发送 WM_CLOSE消息,调用 CWnd::OnClose成员函数.允许对用户提示
是否保存修改过的数据.
Example: AfxGetMainWindow()->SendMessage(WM_CLOSE);
还可以创建一个自定义的函数 Terminate Window
void Terminate Window(LPCSTR pCaption)
{
CWnd *pWnd=Cwnd::FindWindow(NULL,pCaption);
if (pWnd)
pWnd ->SendMessage(WM_CLOSE);
}
说明: FindWindow函数不是提倡的做法,因为它无法处理标题栏自动改变,比如我
们要检测 Notepad是不是已运行而事先不知道Notepad的标题栏,这时 FindWindow
就无能为力了,可以通过枚举 windows任务列表的办法来实现。 在 机械出版社
"Windows 95 API开发人员指南"一书有比较详细的介绍,这里就不再多说乐。
第二问,Use ExitWindowsEx Function函数控制系统是重新引导,还是重启 windows.
前面已经有人讲过乐,就不再提了。
5.怎样加栽其他的应用程序?
三个SDK函数 winexec, shellexecute,createprocess可以使用。
WinExec最简单,两个参数,前一个指定路径,后一个指定显示方式.后一个参数值
得说一下,比如泥用 SW_SHOWMAXMIZED方式去加栽一个无最大化按钮的程序,就是
Neterm,calc等等,就不会出现正常的窗体,但是已经被加到任务列表里了。
ShellExecute较 WinExex灵活一点,可以指定工作目录,下面的 Example就是直接
打开 c:\temp\1.txt,而不用加栽与 txt文件关联的应用程序,很多安装程序完成后
都会打开一个窗口,来显示Readme or Faq,偶猜就是这么作的啦.
ShellExecute(NULL,NULL,_T("1.txt"),NULL,_T("c:\\temp"),SW_SHOWMAXMIZED);
CreateProcess最复杂,一共有十个参数,不过大部分都可以用NULL代替,它可以指
定进程的安全属性,继承信息,类的优先级等等.来看个很简单的 Example:
STARTUPINFO stinfo; //启动窗口的信息
PROCESSINFO procinfo; //进程的信息
CreateProcess(NULL,_T("notepad.exe"),NULL,NULL.FALSE, NORMAL_PRIORITY_
CLASS,NULL,NULL, &stinfo,&procinfo);
6. 确定应用程序的路径
Use GetModuleFileName 获得应用程序的路径,然后去掉可执行文件名。
Example:
TCHAR exeFullPath[MAX_PATH]; // MAX_PATH在API中定义了吧,好象是128
GetModuleFileName(NULL,exeFullPath,MAX_PATH)
7. 获得各种目录信息
Windows目录: Use "GetWindowsDirectory“
Windows下的system目录: Use "GetSystemDirectory"
temp目录: Use "GetTempPath "
当前目录: Use "GetCurrentDirectory"
请注意前两个函数的第一个参数为 目录变量名,后一个为缓冲区; 后两个相反.
8. 如何自定义消息
(1) 手工定义消息,可以这么写 #define WM_MY_MESSAGE(WM_USER+100),
MS 推荐的至少是 WM_USER+100;
(2)写消息处理函数,用 WPARAM,LPARAM返回LRESULT.
LRESULT CMainFrame::OnMyMessage(WPARAM wparam,LPARAM lParam)
{
//加入你的处理函数
}
(3) 在类的 AFX_MSG处进行声明,也就是常说的"宏映射"
*****************************************************
*****************************************************
<技术文档>
Foxpro Windows 制作影视汉字字幕特技
制作字幕三维电视动画特技,可使用3DS与高级字幕机制作动态图像,这要求有较高
的软硬件资源,一般用户不可能有这种条件,其实用Foxpro Windows就可制作出高质量
汉字电视字幕特技。字幕特技在管理软件启动中使用,新颖别致,赏心悦目。其制作方
法如下:
一、用屏幕生成器制作电视汉字字幕显示屏
汉字字幕在屏中翻滚,而字幕屏设计成无名None窗口在底屏中移动。启动屏幕生成
器,根据需要设置屏幕颜色,边上画左上黑线,右、下白线组成立体效果的边框。使用
输入字符按钮工具在框内写入要显示的汉字“烟叶库存管理”。再使用复制的方法复制
汉字“烟叶库存管理”。把二个汉字字符串分别设置成红色和黑色,红色表示汉字彩色,
黑色表示影印。将字符串移动到恰当位置,这样,带影印的立体汉字字幕屏就制作成功
了。按ALT+PrSc键,将屏幕拷贝进Windows的剪贴板上(Clipboard)。
二、用Windows画笔制作动态字幕
按Ctrl+Esc键,启动程序管理器,再启动画笔,按Edit/Paste菜单,再对画笔中产
生刚拷贝进粘贴板图形进行编辑,使用剪接、翻转、缩小或放大等操作,易于得到边框
内一组动态图像名即正像、较扁正像、较扁倒像、倒像、较扁倒像、较扁正像,分别取
名为move00.bmp、move01.bmp、move02.bmp、move03.bmp、move04.bmp、move05.bmp。
三、用Foxpro编制字幕特技.prg程序
按Alt+Esc使窗口从画笔切换到Foxpro Windows状态,编制下面prg程序,其中
Novell.bmp为屏幕底图。运行此程序可见到立体汉字字幕从屏外翻滚进屏内,直观、动
感,强烈地改变用户视觉。
源程序如下:
SET DEFAULT TO D:\BOOK && 环境设置
SET TALK OFF
SET ESCAPE OFF
set console off
@ 0,0 SAY ″c:\windows\novell.bmp″BITMAP STYLE ″T″ && 字幕动画背景
bchar=″movep00.bmp″
DEFINE WINDOW move AT 0.000,0.000 SIZE 9,100.000 FONT;
″MS Sans Serif″,8 NOFLOAT NOCLOSE NOMINIMIZE NONE;
FILL FILE ″movep00.bmp″ &&窗口设置
ACTIVATE WINDOW move SAME
k=6 &&帧动画幅数
for i=7.4 to 47.4 step 1 &&字幕动画显示循环
move window move to i*0.09,i*0.25 &&窗口向右下移动
ii=mod(i-7,k)
if ii<10
bchar=″movep0″+str(ii,1)+″.bmp″ && 定义0-9幅图像文件名
else
bchar=″movep″+str(ii,2)+″.bmp″ &&定义10以上图像文件名
endif
clear
@ 0.0,0.0 SAY bchar BITMAP;
SIZE 9,100;
STYLE ″T″ && 字幕动画显示
do delay && 延迟时间
endfor
proc delay
for ii=0 to 300
de=1
endfor
return
*****************************************************
在Delphi 程 序 中 维 护DBF 数 据 库
王 发 军
---- 由 于Delphi 开 发 的 易 用 性 和 快 速 性, 很 多 原 来 使 用Foxpro 和Visual Foxpro
编 程 的 程 序 员 转 向 了Delphi . 但 由 于 工 作 上 或 其 它 的 原 因, 原 来 的 应 用
系 统 尤 其 是 应 用 数 据, 不 可 能 被 一 下 丢 弃, 因 而 需 要 用Delphi 来 维 护xBase
数 据 库 的 应 用 系 统 . 本 文 总 结 了 在 工 作 和 学 习 中 的 经 验, 与 广 大Delphi
程 序 员 和 爱 好 者 共 享 .
---- 在 下 面 讨 论 中, 主 要 应 用 了BDE 的 函 数 .Delphi1.0 没 有 提 供BDE 函 数 的
帮 助 文 件, 请 参 见 Delphi\Doc 中 的DbiTypes.int、DbiProcs.int 和DbiErrs.int 三 个 文
件; 在Delphi3.0/4.0 中 可 参 见BDE 帮 助 文 件 . 本 文 讨 论 的DBF 数 据 库 操 作 主
要 有: 真 正 删 除 记 录、 显 示 被 删 除 记 录、 获 取 当 前 记 录 号、 设 置 查 询 匹
配 方 式、 恢 复 被 删 除 记 录 .
一 . 真 正 删 除 记 录
---- 在Delphi 程 序 中, 用TTable 或TQuery 构 件 的 方 法Delete 执 行 删 除 记 录 的 操
作 时, 执 行 的 是 软 删 除, 即 相 当 于Foxpro 中 的"Set Delete Off" 的 效 果, 仅 将
记 录 用 星 号"*" 标 记 为 删 除, 实 际 并 没 有 数 据 库 中 进 行 物 理 上 的 删 除 .
要 进 行 真 正 的 删 除, 需 要 进 行Pack Table 的 操 作 .
---- 在Delphi 程 序 中 真 正 删 除 记 录, 需 要 调 用BDE 函 数, 函 数 名 为DbiPackTable,
函 数 原 型 为:
function DbiPackTable ( hDb : hDBIDb;hCursor :
hDBICur; pszTableName : PChar;
pszDriverType : PChar; bRegenIdxs : Bool ): DBIResult;
---- 其 中,hDb 为 数 据 库TDatabse 的 句 柄,hCursor 为 数 据 表TTable 的 句 柄,pszTableName
为 要 删 除 记 录 的 数 据 表 的 名 称,pszDriverType 为 要 删 除 记 录 的 数 据 表 的 类 型,
bRegenIdxs 表 示 是 否 在 删 除 记 录 后 自 动 更 新 索 引 文 件 .
---- 在 上 面 前 四 个 参 数 中,hDb 不 能 为NULL .hCursor、pszTableName、pszDriverType
可 以 为 NULL, 但 必 须 提 供 足 够 的 信 息 来 标 识 数 据 表 的 文 件 名 称 和 类 型,
当hCursor 不 为 空 时, pszTableName 和pszDriverType 可 以 为NULL; 当pszTableName 为 数
据 表 的 路 径 和 文 件 名 时,hCursor 和pszDriverType 可 以 为NULL .
---- 值 得 注 意 的 是, 在 删 除 记 录 时, 如 果 用Table 来 实 现, 则Table 必 须 以
Exclusive=True 的 方 式 打 开 . 下 面 就 是 一 个 典 型 的 例 子 .
首先,应在uses语句加上DbiTypes,DbiProcs,DbiErrs.
{ Pack一个DBF数据表,DbfTable包含了数据表的信息 }
function PackDbfTable( DbfTable : TTable ) : boolean;
var
errResult : DBIResult;
begin
if not DbfTable.Exclusive then
{如果不是以独占方式,操作失败 }
begin
result := false;
exit;
end;
{进行删除操作 }
errResult := DbiPackTable( DbfTable.dbHandle,
DbfTable.handle, NIL, NIL, true );
{根据返回结果,返回成功与否的标志 }
if errResult = DBIERR_NONE then
{没有错误,操作成功 }
result := true
else{没有错误,操作失败 }
result := false;
end;
二 . 显 示 或 不 显 示 被 软 删 除 记 录
---- 当DBF 数 据 库 中 的 记 录 被 软 删 除 后, 缺 省 情 况 下 在TDBGrid 等 数 据 库 构
件 中 是 看 不 见 这 些 记 录 的 . 我 们 可 以 用BDE 函 数 来 控 制 是 否 显 示DBF 数
据 库 中 被 软 删 除 的 记 录, 就 象 在Foxpro 中 利 用 语 句 Set Delete ON/OFF 那 样 .
---- 要 用 到 的 函 数 名 为DbiSetProp, 函 数 原 型 为
function DbiSetProp ( hObj : hDBIObj; iProp
: Longint; iPropValue : Longint): DBIResult;
---- 该 函 数 用 来 设 置DBI 对 象 中 某 个 属 性 的 值. 其 中,hObj 为DBI 对 象 名 称,
我 们 这 里 为 数 据 表TTable 的 句 柄;iProp 为 属 性 名 称, 我 们 用 的 是 软 删 除
属 性curSOFTDELETEON;iPropValue 为 属 性 值, 我 们 用True 或False 表 示 是 否 使 软 删
除 的 记 录 被 显 示 .
---- 下 面 就 是 一 个 典 型 的 例 子 .
---- 同 样, 应 在uses 语 句 加 上DbiTypes,DbiProcs,DbiErrs.
{显示DBF数据表中的软删除记录,
DbfTable包含了数据表的信息,DeleteOn
表示是否显示,True表示显示 }
function SetDbfDelete( DbfTable :
TTable ; DeleteOn : boolean ) : boolean;
var
errResult : DBIResult;
begin
result := false; {操作失败时,返回False }
{如果数据表没有打开,则操作失败 }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -