📄 lc_bcb_36.txt
字号:
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制作的称得上“软件”的程序终于诞生了。 ?
返回