发信人: lofe ()感激生活(), 信区: BorlandDev
标 题: 用C++ Builder3 制作NotePad(记事本)续篇
发信站: 哈工大紫丁香 (Sun Sep 3 07:51:36 2000), 转信
上回说到“我的记事本”小功告成,copy给朋友一份,咦,不能用,说是缺文件?噢,
像VB的VBRUN???
.dll一样,C++ Builder3编译的程序也需要运行库的支持的。找到并打开它看看我们还
有些什么没有做?首先是关于菜单的快捷键问题。如果你是使用我上次所给的资源脚本
导人的菜单,你会发现带有快捷键的菜单项的文字都像“撒消(U)\tCtrl+Z”一样。以前
用BC的资源编辑器做过菜单的朋友都知道,“\t”表示右对齐,而在C++ Builder3中也
作为菜单的文字了。另外C++ Builder3中的快捷键的建立也简单的多,快捷键已经作为
菜单的ShortCut属性了。这里,仅改动“编辑(E)”中的“撒消(U)Ctrl+Z”项来示众,
其余皆可依样而画葫芦之。
先双击MainMenu1菜单组件,进入菜单编辑器,选中“编辑(E)”中的“撤消(U)Ctrl
+Z”项。接着将Caption属性改为“撤消(U)”(即把“\tCtrl+Z”删去),并在shortC
ut瞩性中选择Ctrl+Z。这样,该项的快捷键就设完了。接着是编辑菜单里的各个项。首
先是“撤消(&U)Ctrl+Z”到“全部选定(&A)”六项(必须先将他们的Enabled属性都设为
true),C++ Builder3为这些功能提供了现成的方法(Method)。比如“撤消(&U)Ctral
+Z”菜单,可以使用Undo方法,即在该菜单的OnClick事件处理函数中输入“Memo1->Un
do();”。同理有:
“剪切(&T)\tCtrl+X”项,输入:“Memo1->CutToClipboard();”
“复制(&C)\tCtrl+C”项,输入:“Memo1->CopyToClipboard();”
“粘贴(&P)\tCtrl+V”项,输入:“Memo1->PasteFromClipboard();”
“删除(&L)\tDel”项,输入:“Memo1->ClearSelection();”
“全部选定(&A)”项,输入:“Memo1->SelectAll();”
下面是“时间/日期(&D)F5”项,我们必须先取得当前的日期和时间。有两种方法,
一种是用getdate和
gettime函数,一种是用C++ Builder3中的TDateTime类。这里选择后一种,但有时使用
getdate和gettime函数会更简便。下面给出该菜单项的处理代码:
TDateTime * Current_DateTime =newTDateTime; //生成TDateTime对象
* Current_DateTime=Current_DateTime->CurrentDateTime(); //获取当前日期和时间
Memo1->SetselTextBuf(Current_DateTime->DateTimeString().c_str());//将当前日期
和时间转换成字符串,并用SetSelTextBuf方法插入当前光标位置
接着是处理‘自动换行(&W)”的代码:
//W1是“自动换行(&W)”菜单项的名字(Name)属性,如果你不是W1,请做相应的改动
if(W1->Checked) //该菜单已经检取(Checked)
{W1->Checked=false; //取消检取
Memo1->ScrollBars=ssBoth; //Memo1两根滚动条都要
} else
{ W1->Checked=true; //设置检取
Memo1->ScrollBars = ssVertical; //Memo1只设垂直滚动条,效果就是自动换行
}
接下来处理“设置字体(&F)...”菜单,我们首先需要一个设置字体的公用对话框。
从Dialogs组件条中选FontDialog组件放入表单中。下面是处理“设置字体(&F)...”的
代码:
if(FontDialog1->Execute())Memo1->Font=FontDialog1->Font;
至此,“编辑(E)”菜单的功能都处理完了,下面将是处理“搜索(S)”菜单的工作。
其中,我们又将用到两个公用对话框。C++ Builder3只提供了用来获取用户欲查我的字
符串的对话框,并未提供具体查找的函数,所以我们得自己写处理函数。下面我给出修
改的Win32 SDK的范例代码,你需要将这些代码插在程序的首部,即定义全局变量的地方
。
typedef enum {
frtFind
frtReplace,
frtRepAll
} FRT
#define GETSEL(ichS,ichE) \ SendMessage(MainForm - > Memo1 - > Handle,
EM_GETSEL,(WPARAM) & ichs, (LPARAM) & ichE)
#define SETSEL(ichS,ichE) \SendMessage(MainForm - > Memo1 - > Handle,
EM_SETSEL, (WPARAM) ichS, (LPARAAM) ichE)
BOOL FWholeWord(char * sz, char * szStart, char * szEnd,
int cch) {
if ( sz! = szStart & &
* (sz - 1 ) ! = ' ' & &
* (sz - 1 ) ! = '\t' & &
* (sz - 1 ) ! = ',' & &
* (sz - 1 ) ! = '.' & &
* (sz - 1 ) ! = '\r'
) { return FALSE;
}
if ( sz + cch! = szEnd & &
* (sz + cch) ! = ' ' & &
* (sz +cch) ! = '\t' & &
* (sz + cch) ! = ',' & &
* (sz + cch) ! = '.' & &
* (sz + cch) ! = '\r'
) { return FALSE;
}
return TRUE;
}
BOOL Find(char * szFind, BOOL fDown, BOOL fMatchCase, BOOL fWholeWord, BOOL
fNoScroll)
{ char * szText;
UINT ichStart;
UINT ichEnd;
UINT cch;
int dch;
int dchComp;
char * szTerm;
char * sz;
UINT cchFind;
BOOL fFound = FALSE;
int dcbOnFind;
szText = MainForm - > Memo1 - > Lines - > GetText();
cchFind = strlen (szFind);
GETSEL(ichStart, ichEnd);
cch = strlen(szText);
if (
ichEnd - ichStart = = cchFind & &
!strnicmp(szText + ichStart, szFind, cchFind)
)
dchOnFind = 1;
else
dchOnFind = 0;
if (fDown)
{ dch = 1;
dchComp = 0;
sz = szText + ichStart + dchOnFind;
szTerm = szText + cch;
}
else
{ dch = -1;
dchComp = 1;
sz = szText + ichStart - dchOnFind;
szTerm = szText;
}
for (; sz + dchComp! = szTerm; sz + = dch)
{
if (
tolower(* sz) = = tolower( * szFind) & &
(fMatchCase ?
!strncmp(sz, szFind, cchFind) :
!strnicmp (sz, szFind, cchFind)
) & &
( !fWholeWord || FWholeWord(sz, szText, szTerm,cchFind)))
{ SendMessage(MainForm -> Memo1 -> Handle,EM_SETSEL, sz-szText, sz-s
zText + cchFind);
if (!fNoScroll)
SendMessage(MainForm - > Memo1 - > Handle,EM_SCROLLCARET, 0, 0L)
;
fFound = TRUE;
break;
}
}
if ( !fNoScroll & & !fFound)
MessageBox(NULL, szFind, "字 符 串 没 有 找 到",MB_OK);
return fFound;
}
VOID Replace(char * szReplace) {SendMessage(MainForm - > Memo1 - > Handl
e,
EM_REPLACESEL, 0, (LPARAM) (LPSTR) szReplace);
}
VOID ReplaceAll(char * szFind, char * szReplace, BOOLfMatchCase, BOOL fW
holeWord)
{ UINT ichStart;
UINT ichEnd;
GETSEL(ichStart, ichEnd);
SETSEL(0, 0);
while(Find(szFind, TRUE, fMatchCase, fWholeWord,TRUE)) {
Replace (szReplace);
}
SETSEL(ichStart, ichEnd);
}
VOID FindReplace(
char * szFind, char * szReplace,
FRT frt,
BOOL fDown, BOOL fMatchCase, BOOL fWholeWord)
{ switch (frt)
{ case frtFind:
Find(szFind, fDown, fMatchCase, fWholeWord,FALSE);
break;
case frtReplace:
Find(szFind, fDown, fMatchCase, fWholeWord,FALSE);
Replace (szReplace);
break;
case frtRepAll:
ReplaceAll(szFind, szReplace, fMatchCase, fWholeWord);
}
}
这些代码本来并不是给C++ Builder用的,但我们只要稍加改动就能使用了,这也为
我们移植以前的代码提供了新思路,即一般只要将过去程序中的窗口或控制的句柄(HW
ND)用C++Builder中表单或组件的Handle属性来代替,将过去程序中的程序事例句柄用
HInstance代替,就能方便的完成移植。回到程序中来,上面有5个函数和2个宏,其实我
们直接使用的只有FindReplace函数。先在表单上放上FindDialog和ReplaceDialog两个
对话框,随后写“查找(F)...”菜单项的处理代码:
FindDialog1->Execute();
你可能会很奇怪,这么简单,那查找的过程在哪里呢?当用户按了查找对话框的[查
找下一个(F)]按钮后,会产生FindDialog的OnFind事件,在该事件的处理函数中进行查
找工作。如何编写组件的事件函数?
(1)在表单编辑区选中该组件(这里是FindDialog1);
(2)在对象观察器(如果没有显示,按F11调出)中选择Event(事件),系统将列出事
件;
(3)双击事件后面的编辑框(这里是OnFind),系统将切换入代码编辑区;
(4)输入事件处理代码。
下面给出OnFind的处理代码:
MainForm - > SerFocus();
FindReplace(FindDialog1 - > FindText.c_str(), "", frtFind,
FindDialog1 - > Options. Contains(frDown),
FindDiaiog1 - > Options.Contains(frMatchCase),
FindDialog1 - > Options.Contains(frWholeWord));
同样的,“替换(&R)”菜单项处理代码是:
ReplaceDialog1 - > Execute();
ReplaceDialog1的onFind 事件的处理代码:
MainForm - > SetFocus();
if(ReplaceDialog1 - > Options.Contains(frFindNext))
FindReplace(ReplaceDialog1 - > FindText.c_str(),"", frtFind,
ReplaceDialog1 - > Options. Contains(frDown),
ReplaceDialog1 - > Options. Contains(frMatchCase),
ReplaceDialog1 - > Options. Contains(frWholeWord));
ReplaceDialog1的onReplace 事件(用户按了[替换(R)]按钮)的处理代码:
MainForm - > SetFocus ();
if(ReplaceDialog1 - > Options. Contains (frReplace))
FindReplace(ReplaceDialog1 - > FindText. c_str(),
ReplaceDiaiog1 - > ReplaceText. c_str(), frtReplace,
ReplaceDialog1 - > Options. Contains(frDown),
ReplaceDialog1 - > Options. Contains(frMatchCase),
ReplaceDialog1 - > Options. Contains(frWholeWord));
else if(ReplaceDialog1 - > Options. Contains (frReplaceAll))//全部替换
FindReplace(ReplaceDialog1 - > FindText.c_str(),
ReplaceDialog1 - > ReplaceText, c_str(), frtRepAll,
ReplaceDialog1 - > Options. Contains(frDown),
ReplaceDialog1 - > Options. Contains(frMatchCase),
ReplaceDialog1 - > Options. Contains(frWholeWord));
当然,还有“查找下一个(N)”菜单项,处理的方法几乎和OnFind一样:
FindReplace(FindDialog1 - > FindText. c_str(),"", frtFind,
FindDialog1 - > Options. Contains (frDown),
FindDialog1 - > Options. Contains (frMatchCase),
FindDialog1 - > Options. Contains(frWholeWord));
至此为止,终于真的“大”功告成了。至于“帮助(H)”菜单处理,你可以用WinHe
lp来显示一个帮助文
件,用MessageBox来显示“关于XXX”的对话框,这些都不怎么和C++ Builder有关,我
就不赘述了。
最后还有些收尾工作,选择Project菜单Options,将显示一个程序设置的对话框。
1.选择Application页面,这里Title是程序在任务栏上的标题,默认的是程序文件
名。我们将它设为
“我的记事本V1.00”。接着,单击[Load Icon...]按钮来为你的软件选择一个图标。
2.选择Compiler页面,单击[Release]按钮,这样就不会向程序中插入调试代码而
加快执行速度。
3.选择Linker页面,取消对Use Dynamic RTL的选择,不使用动态链接库。
4.选择Packages页面,取消对Build with runtime packages的选择,不使用运行
时包。
按OK退出后,选Project菜单中的Build NotePad来编译一下,你的第一个用C++ Bu
ilder3制作的称得上“软件”的程序终于诞生了。
--
※ 修改:.haojs 于 Sep 3 07:49:12 修改本文.[FROM: bbs.hit.edu.cn]
--
※ 转寄:.武汉白云黄鹤站 bbs.whnet.edu.cn.[FROM: bbs.hit.edu.cn]
--
☆ 来源:.哈工大紫丁香 bbs.hit.edu.cn.[FROM: haojs.bbs@bbs.whnet.]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:2.546毫秒