荔园在线

荔园之美,在春之萌芽,在夏之绽放,在秋之收获,在冬之沉淀

[回到开始] [上一篇][下一篇]


发信人: jek (好好学习天天向上), 信区: Program
标  题: 用C++ Builder3 制作NotePad(记事本)续篇
发信站: BBS 荔园晨风站 (Sat Mar 11 14:38:46 2000), 转信

用C++ Builder3 制作NotePad(记事本)续篇


上回说到“我的记事本”小功告成,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”删去),并在shortCut瞩性
中选择Ctrl+Z。这样,该项的快捷键就设完了。接着是编辑菜单里的各个项。首先是“撤
消(&U)Ctrl+Z”到“全部选定(&A)”六项(必须先将他们的Enabled属性都设为true),
C++ Builder3为这些功能提供了现成的方法(Method)。比如“撤消(&U)Ctral+Z”菜单,
可以使用Undo方法,即在该菜单的OnClick事件处理函数中输入“Memo1->Undo();”。同
理有:
    “剪切(&T)\tCtrl+X”项,输入:“Memo1->CutToClipboard();”
    “复制(&C)\tCtrl+C”项,输入:“Memo1->CopyToClipboard();”
    “粘贴(&P)\tCtrl+V”项,输入:“Memo1->PasteFromClipboard();”
    “用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的范例代码,你需要将这些代码插在程序的首部,即定义 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-szText + cchFind);
        if (!fNoScroll)
            SendMessage(MainForm - > Memo1 - > Handle,EM_SCROLLCARET, 0, 0L);
        fFound = TRUE;
 ace) {SendMessage(MainForm - > Memo1 - > Handle,
    EM_REPLACESEL, 0, (LPARAM) (LPSTR) szReplace);
    }
    VOID ReplaceAll(char * szFind, char * szReplace, BOOLfMatchCase, BOOL
 fWholeWord)
    { UINT ichStart;
      UINT ichEnd;
      GETSEL(ichStart, iar * 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用的,但我们只要稍加改动就能使用了,这也为我
们移植以前的代码提供了新思路,即一般只要将过去程序中的窗口或控制的句柄(HWND)
用C++Builder中表单或组件的Handle属性来代替,将过去程序中的程序事例句柄用
HInstance代替,就能方便的完成移植。回到程序中来,上面有5个函数和2个宏,其实我
们直接使用的只有FindReplace函数。先在表单上放上FindDialog和ReplaceDialog两个对
话框,随后写“查找(F)...”菜单项的处理代码:
FindDialog1->Execute();
   你可能会很奇怪,这么简单,那查找的过程在哪里呢?当用户按了查找对话框的[查找
下一个(F)]按钮后,会产生FindDialog的OnFind事件,在该事件的处理函数中进行查找工
作。如何编写组件的事件函数?
(1)在表单编辑区选中该组件(这里是FindDialog1);
(2)在对象观察器(如果没有显示,按F11调出)中选择Event(事件),系统将列出事
件;
(3)双击事件后面的编辑框(这里是OnFind),系统将切换入代码编辑区;
(4)输入事件处理代码rWholeWord));
同样的,“替换(&R)”菜单项处理代码是:
ReplaceDialog1 - > Execute();
ReplaceDialog1的onFind 事件的处理代码:
MainForm - > SetFocus();
if(ReplaceDialog1 - > Options.Contains(frFindNext))
FindReplace(ReplaceDialog1 - > FindText.c_str(),"", frtFeplaceDialog1的
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)”菜单处理,你可以用
WinHelp来显示一个帮助文件,用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++ Builder3制作的称得上“软件”的程序终于诞生了。

--
※ 来源:·BBS 荔园晨风站 bbs.szu.edu.cn·[FROM: 192.168.1.118]


[回到开始] [上一篇][下一篇]

荔园在线首页 友情链接:深圳大学 深大招生 荔园晨风BBS S-Term软件 网络书店