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

启动C++ Builder3后,在File菜单中选New APPlication来建立一个新程序。这时,显示在屏幕中间的窗口的标题是Form1,这个窗口是程序的主表单(就是主窗口的意恩),它将在程序启动时自动显示。而以后再创建的表单(Form)一般需要用Show()方法(Method)来显示。和组件一样,系统为第一个表单起名为Form1,以后的表单起名为Form2、Form3等等,标题(Caption)也是如此。
   当然,你可以将它们改成你喜欢的名字。我们先来把Form1的名字(Name)属性设为MainForm,把MainForm的标题(Caption)属性设为“Untited.txt--我的记事本”。接着可以用鼠标拖动窗口的位置和改
变窗口的大小。以上的这些工作,几乎每个程序都需要如法炮制一番。
   随后,我们要开始NotePad的编程工作了。知己知彼,百战不殆,先来分析一下MicroSoft NotePad的结构。其实NotePad是附件里最简单的程序了,它的主窗口中只包含一个占据全部用户区域(Client Area)的多行的编辑控制(Edit)。由于编辑控制最多容纳64KB文字(Windows95),所以NotePad只能打开小于64KB的文件。好,我们来依样画葫芦,选择Standard中的多行编辑(Memo)组件(而不是单行编辑组件)。
   放入表单中,将多行编辑Memo1的Align属性设为alClient,这时Memo1撑满了整个窗口,Memo1中显示的是Memo1。选择Memo1的Lines属性,[TString]后面出现了一个按钮。
   单击该按钮,将出现一个设置Lines属性的对话框,其中第一行便是“Memo1”。多行编辑(Memo)组件的Lines属性在设计时(Design Time)设定的内容将在该窗口创建时自动显示。由于我们不需要显示什么,所以把“Memo1”擦掉,选OK退出。你一定想看看目前的效果,运行一下吧。编译……连接……启动程序……怎
么样,是不是和NotePad一模一样,能打字、删字、删行,还能使用右键菜单来复制(copy)和粘贴(paste)。
   本来就是嘛,用一样的编辑控制,不一样才怪呢。哎,不对,好像字体小了点,而且没有滚动条。没有关
系,关闭程序回到C++ Builder3中,先修改Memo1的字体(Font)属性,选择system字体(当然你爱选什么字
体都可以),然后设置滚动条(ScrollBars)属性,选择ssBoth(两根滚动条都要)。在这些改动之后,先别急着运行,windows的程序没菜单是不行的。在C++ Builder中,菜单也是组件之一。选择Standard中的主菜单(MainMenu)组件放入表单中。主菜单(MainMenu)组件显示为一个图标。顺便提一句菜单,对话框或系统功能之类组件属于非可视组件(nonvisual components),它们的工作基本不是用来满足视觉的,或者在程序运行时根本就看不见(相对于界面上可视组件来说),因此你可以将非可视组件放在表单中的任意位置。
   接下来的工作是制作菜单,双击主菜单MainMenu1的图表,会弹出菜单编辑窗口,开始时是一个空菜单。按右键会弹出一个菜单(不是我们要做的菜单),其中:
Insert(添加一个菜单项,按Insert键完成相同的功能)
Delete(删除一个菜单项,按Delete键完成相同的功能)
Create SubMenu(添加一个子菜单,按Ctrl + →键完成相同的功能)
Select Menu(选择一个菜单,用来关闭当前编辑的菜单并选择另一个菜单来编辑)
Save as Template(将当前菜单保存为模板,供以后使用)
Insert From Template(将已有的菜单模板加入当前菜单)
Delete Template(删除菜单模板)
Insert From Resource(从资源文件中取得菜单加入当前菜单)
   制作“我的记事本”的菜单有一种偷懒的方法,就是照抄Microsoft记事本的菜单。你可以用BC5.02的IDE打开Notepad.exe(先把打开文件对话框中的Viewer设为Edit Resource,再把文件类型设为Exe cutable(*.exe),这样才是以编辑资源的方式打开EXE文件,否则默认的打开方式是Debug调试程序),将里面的菜单导出以RC(资源脚本)方式存盘,然后用Insert From Resource导入该菜单;一共用不了2分钟。
   还有一种方法就是自己一项一项慢慢地做。当然,不管你用什么方法,最后都要做出菜单来才能继续下面的工作。下面附上从Windows NT4.0中Notepad导出的菜单的资源脚本menu.rc,把下面的文件以menu.rc存盘就能用C++ Builder3来导入了:
1 MENU
{ POPUP "文件(&F)"
  { MENUITEM "新建(&N)", 9
    MENUITEM "打开(&O)...", 10
    MENUITEM "保存(&S)", 1
    MENUITEM "另存为(&A)...", 2
    MENUITEM SEPARATOR
    MENUITEM "页面设置(&T)...", 32
    MENUITEM "打印(&P)", 14
    MENUITEM SEPARATOR
    MENUITEM "退出(&X)", 28
  }
  POPUP "编辑(&E)"
  { MENUITEM "撤消(&U)\tCtrl+Z", 25
    MENUITEM SEPARATOR
    MENUITEM "剪切(&T)\tCtrl+X", 768,GRAYED
    MENUITEM "复制(&C)\tCtrl+C", 769, GRAYED
    MENUITEM "粘贴(&P)\tCtrl+V", 770,GRAYED
    MENUITEM "删除(&L)\tDel",771, GRAYED
    MENUITEM SEPARATOR
    MENUITEM "全部选定(&A)", 7
    MENUITEM "时间/日期(&D)\tF5",12
    MENUITEM SEPARATOR
    MENUITEM "自动换行(&W)", 27
    MENUITEM "设置字体(&F)...", 37
  }
  POPUP "搜索(&S)"
  { MENUITEM "查找(&F)...", 3
    MENUITEM "查找下一个(&N)\tF3", 8
    MENUITEM "替换(&R)"', 40
  }
  POPUP "帮助(&H)"
  { MENUITEM "帮助主题(&H)", 5
    MENUITEM SEPARATOR
    MENUITEM "关于记事本(&A)...",11
  }
}
关于菜单,还有两点要提:
1.一般没有必要去改动菜单项的Name属性,使用系统给出的默认名就可以了。
2.以“-”为标题的菜单项即是菜单分割条,而菜单项的Break属性提供的分割则是一种很奇怪的样子--“垂直分害条”(群山笑:这个名词是我自已加上的)。
   OK,到此为止,界面部分的工作已经全部完成了,接下来便是代码部分的编写。首先要做的就是打开文件和存盘的工作。我们来建立一个char *UserFileName的全局变量来存放文件名。按工具条上的Toggle Form/Uint将工作窗口切换到代码编辑区。这个按钮用于表单编辑区和代码编辑区的相互切换,按F11显示对象观察器。在“TMainForm *MainForm;”下加语句:
char *UserFileName="untitled.txt";//默认文件名Untitled.txt
BOOL If_saved=TRUE;//表示文件存盘与否
char title_buf[256];//标题的内容
   接着,我们再切换回表单编辑区,从Dialogs组件条中选SaveDialog组件放入表单中。
   SaveDialog组件就是用来显示Save As对话框的,当然用Windows API也能实现此功能,这里将使用SaveDialog组件。将SaveDialog1的DefaultExt(默认的扩展名)属性设为.txt,这表示如果用户没有加扩展名,系统会自动加上“.txt”。按Filter属性后的[…]按钮,在弹出的对话框中输入“文本文件”“*.txt”“所有文件”“*.*”。另外再双击Options属性,将展开后其中的ofOverwritePrompt(文件覆盖提醒)属性设为true。接着在表单编辑区的菜单中选菜单项“另存为(A)...”,这时C++ Builder3会自动切换到代码编辑区,而光标停在一个函数的开头。在该例中菜单项“另存为(A)…”的名字属性是A1,所以这个函数的名字是A1Click(TObject * Sender),表示用户选择(Click)这个菜单项而执行的函数。我们所要做的是弹出Save As对话框来获得用户输入的文件名,并将这个文件存盘。所以在这个函数里加如下的语句:
if(!SaveDialog1->Execute()) return; //如果用户选择了取消,我们就return
UserFileName = SaveDialog1 -> FileName.c_str();
/ * FileName保存了用户输入的文件名,但是AnsiString类型的,用其中的c_str()方法可以将其转换成字符串*/
Memo1 ->Lines->SaveToFile(UserFlleName);
If_saved=TRUE; //已经存盘
sprintf(title_buf,"% s - 我的记事本”, UserFileName); /* 设置窗口的标题,记得要加上include <stdio.h> * /
Caption=title_buf;
/ * Memo中的Lines属性即是编辑控制中的内容,Lines属性是Strings类型的,用其中提供的SaveToFile方法可以方便地将编辑控制中的内容存盘 */
   类似地,我们再来处理打开文件的工作。首先,在表单中放置一个OpenDialog组件,DefaultExt和Filter
属性同SaveDialog1,将Options属性中的ofFileMustExist(文件必须存在)设为true。然后在表单编辑区中
的菜单中选菜单项“打开(O)...”,在代码编辑区中输入如下语句。
if(!if_saved)
if(Application ->MessageBox("文件还未保存,是否要保存?","我的记事本",
MB_OKCANCEL+MB_DEFBUTTON1+MB_ICONWARNING)==ID_OK) S1Click(NULL);
/ * 如果文件没有保存,我们得先征求用户是否要保存文件。s1Click()是“保存(s)”菜单项的处理函数(就是接下来处理的菜单项),“保存(S) ”菜单项的工作就是将文件存盘,所以我们没有必要写重复的代码,而只要直接调用该函数就可以了。注意,如果你的“保存(S)”菜单项的名字属性不是S1而是其他,那么这个函数的名字也会有所不同,但总是“名字”+Click() */
if(!OpenDialog1->Execute())return;
UserFileName=OpenDialog1->FileName.c_str();
Memo1->Lines->LoadFromFile(UserFileName);
sprintf(title_buf,"% s - 我的记事本", UserFileName);
Caption = title_buf;
(为节省篇幅,以下凡是重复的操作描述省略)
   处理“保存(S)”菜单项,输入:
Memo1->Lines->SaveToFile(UserFileName);
If_saved=TRUE;
sprintf(title_buf,"% s - 我的记事本", UserFileName)";
Caption = title_buf;
   处理“新建(N)”菜单项,输入如下语句:
lf(!If_saved)
if(Application ->MessageBox ("文件还未保存,是否要保存?","我的记事本",
MB_OKCANCEL+MB_DEFBUTTON1+MB_ICONWARNING)==ID_OK)S1Click(NULL);
sprintf(UserFileName,"Untitled.txt");
sprintf(title_buf, "% s - 我的记事本-未存盘",UserFileName);
Caption=title_buf;
Memo1->Lines->Clear(); //将编辑控制中的内容清空
   随后,我们要处理Memo1的OnChange事件(Events)。一旦编辑控制中的内容有改变,Memo1就将产生OnChange事件,这时需要将If_saved置为FALSE,表示文件已经改动过了,并在标题上显示“未存盘”。在对象观察器中选Memo1,再单击下面的Events,将列出许多事件,第一个就是OnChange,双击后面的编辑框,后面的操作和处理菜单项是一样的(其实前面处理的菜单项就是处理菜单的OnClick事件),输入:
If_saved=FALSE;
sprintf(title_buf,"% s -我的记事本-未存盘", UserFileName);
Caption=title_buf;
   随后处理MainForm的OnClose事件,输入:
//OnClose事件在关闭窗口时产生,需要做一些收尾工作
if(!If_saved)
if(application->MessageBox("文件还未保存,是否要保存?","我的记事本",
MB_OKCANCEL+MB_DEFBUTTON1+MB_ICONWARNING)==ID_OK)S1Click(NULL);
   最后,处理“退出(X)”菜单项,输入如下语句:
if(!If_saved)
if(application->MessageBox("文件还未保存,是否要保存?","我的记事本",
MB_OKCANCEL+MB_DEFBUTTON1+MB_ICONWARNING)==ID_OK)S1Click(NULL);
Application->Terminate(); //程序结束
   到此为止,终于小功告成了,快把项目保存下来吧。在File菜单中选Save Project As…,首先弹出的对
话框要求输入表单的文件名(不能和表单的名字属性相同),我们就输入Main。随后弹出的对话框才是要求输入项目(Project)的文件名,该文件名也就是exe文件的名字,我们输入NotePad。保存后再选Project菜单
里的Make NotePad,或按Ctrl+F9,就会产生一个NOtePad.exe,这就是我们自己做的记事本,目前它已经能打开文件、编辑并保存。你一定发现菜单中还有许多功能尚未实现,这就是我只说小功告成的原因,不过
下次我们会完成它。
   附件中除了记事本(NotePad),还有一个写字板(WordPad)。它们最大的区别在于前者使用的是编辑
控制(Edit),而后者使用的是Rich Edit控制(有些书翻译成丰富文本控制)。与编辑控制相比,Rich Edit除了能给文本加上各种修饰,还支持简单的对象链接和嵌入技术(Object Linking and Embedding)。
   此外,Microsoft Win32 SDK的文档中说Rich Edit控制能接受的文本大小将只受内存大小的限制,这比
编辑控制的64KB强多了。当然,效率又是另一个问题。我曾试图用写字板(WordPad)打开一个15MB的文件,硬盘读了10多分钟还没结果,只能按Reset重新启动了(我可有64MB内存哦)。自然使用Rich Edit控制也比编辑控制难的多。在以后讲到RichEdit组件时,详细讲述它的用法。

用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();”
    “删除(&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-szText + 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 - > Handle,
    EM_REPLACESEL, 0, (LPARAM) (LPSTR) szReplace);
    }
    VOID ReplaceAll(char * szFind, char * szReplace, BOOLfMatchCase, BOOL fWholeWord)
    { 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用的,但我们只要稍加改动就能使用了,这也为我们移植以前的代码提供了新思路,即一般只要将过去程序中的窗口或控制的句柄(HWND)用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)”菜单处理,你可以用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制作的称得上“软件”的程序终于诞生了。

用C++ Builder3 制作NotePad(记事本)相关推荐

  1. vue学习:基于本地应用制作的记事本

    基于本地应用制作的记事本 功能 1.新增 2.删除 3.统计 4.清空 5.隐藏 逻辑 新增 1.生成列表结构(v-for 数组):建立一个字符串数组用于统计用户输入内容,并且用于新增数据内容. 2. ...

  2. Android的Notepad记事本案例实战

    一.搭建记事本布局 效果图: (activity_notepad.xml) 1.去掉标题栏:在AndroidManifest.xml中的theme改成NoActionBar. 2.记事本主页布局: & ...

  3. notepad 记事本的问题

    首先这里再明确一下,所有的版本控制系统,其实只能跟踪文本文件的改动,比如TXT文件,网页,所有的程序代码等等,Git也不例外.版本控制系统可以告诉你每次的改动,比如在第5行加了一个单词"Li ...

  4. Windows系统下制作一个记事本以语音方式读出你输入的文字 以及放到开机启动项,开机自启动读出语音!

    右键新建一个记事本,输入下面代码: 代码: createobject("SAPI.spvoice").speak"123" 在speak里面输入你想让他读出来的 ...

  5. 用UltraEdit判断打开文件的编码类型 用UltraEdit或notepad记事本查看文件编码格式 用UltraEdit查看当前文件编码...

    用UltraEdit查看当前文件编码 想判断文件的编码类型? 用强大的UltraEdit-32软件: UltraEdit-32的状态栏可以显示文件的编码类型,详细情况如下: ANSI/ANSCI--- ...

  6. 用android制作一个记事本app_用扁平化呈现一个天气APP

    作为当下最火的设计风格之一,扁平化设计其实是一种简约的Ul 设计理念,现被广泛应用于图形用户界面上,在图形材料,例如海报,艺术作品,指导文档,各类出版物等方面尤为常用.  今天为大家带来了我最近的扁平 ...

  7. 微信小程序制作-----日历记事本

    因为某些原因吧,我接触到了微信小程序在这里将自己的一些理解和感悟写出来. 小程序介绍 小程序其实就是前端,后端你可以使用Java去完成,小程序的目录结构,页面可以当在一个pages的文件夹里面 然后注 ...

  8. 【Python黑科技】tkinter库实战制作一个记事本(保姆级图文+实现代码)

    目录 实现效果 实现思路 实现代码 总结 欢迎关注 『Python黑科技』 系列,持续更新中 欢迎关注 『Python黑科技』 系列,持续更新中 实现效果 实现思路 具有记事本的基本功能,可以另存为t ...

  9. Python制作简易记事本

    需要用到tkinter,pyautogui,sys这几个模块,pyautogui可以通过pip install pyautogui来下载. 废话不多说,上代码: import tkinter as t ...

最新文章

  1. linux学习笔记(5)
  2. 一文看清这些年自监督和无监督的进展
  3. raid操作相关命令笔记
  4. Linux文件系统之df
  5. Linux进阶之路————用户管理
  6. asp.net web开发框架_用Python开发一个Web框架
  7. iOS和android运存机制,再次确认苹果的1G运存相当于安卓的4G运行内存
  8. js基础-14-JS阻止事件冒泡和默认事件
  9. 《Apache Spark源码剖析》
  10. 茴字有几种写法?SQL排名问题之全局排名的四种解法
  11. 显示器知识:分辨率1080P、2K、4K、8K相关知识介绍,看完你就懂了!
  12. IPSec IKEV2
  13. 初识Cura3D打印开源项目
  14. Thinkphp6调用企业微信官方php版本接口方法
  15. “老K,怎样副业搞钱?”
  16. 威纶通,威纶通UI,WEINVIEW UI,HMI 模板,人机界面模板,WEINVIEW
  17. 理解Anchor、RPN真值与预测量、RPN卷积网络
  18. 做了一个网页版的串口调试助手
  19. while、do...while、for循环的使用
  20. 怎么写小说?做好这4步,你也能开始写小说 | Effie经验分享

热门文章

  1. win下修改mysql默认的字符集以防止乱码出现
  2. rocks自建存储流程
  3. windows 下Android的开发准备
  4. 面试(后台开发,转载)
  5. POJ 1061 青蛙的约会(扩展欧几里得)
  6. [转帖]linux下的X server:linux图形界面原理
  7. [洛谷P4430]小猴打架
  8. wc 统计文件的行数
  9. Windows Server Backup 裸机恢复
  10. ArcGIS AddIN开发:如何调用ArcMap中的选择工作空间的窗体