??xml version="1.0" encoding="utf-8" standalone="yes"?>
const char *filename, /* Database filename (UTF-8) */
sqlite3 **ppDb /* OUT: SQLite db handle */
);
功能:打开数据?如果不存在则自动创徏.
PARAM1(IN): 数据库文件名,UTF-8格式
PARAM2(OUT): q回的数据库句柄
q回?q回SQLITE_OK成功,反之p|(数据库句柄ppDb为空),p|D具体SQLITE_*定义.
=====================================================================================
int sqlite3_close(sqlite3 *);
功能:关闭数据?br />PARAM1(IN):打开的数据库句柄
q回?q回SQLITE_OK成功,反之p|.
=====================================================================================
int sqlite3_exec(
sqlite3*, /* An open database */
const char *sql, /* SQL to be executed */
sqlite3_callback, /* Callback function */
void *, /* 1st argument to callback function */
char **errmsg /* Error msg written here */
);
功能:执行SQL
PARAM1(IN):数据库句?br />PARAM2(IN):sql语句,以\0l尾.
PARAM3(IN):回调函数
PARAM4(IN):回调参数
PARAM5(OUT):输出错误信息
q回?SQLITE_OK成功,反之p|,p|后错误信息见PARAM5;
说明Q如果有多条SQL语句,中间用分?;)隔开.回调函数和回调参数通常在查询语句会(x)用到,
Ҏ(gu)条查询结果结果都?x)调用回调函C?
回调函数格式:
typedef int(*sqlite3_callback)(void *,int ,char **,char **);
参数1:sqlite3_exec中传入的参数
参数2:d?
参数3:列数?char*)
参数4:列名U?char*)
=====================================================================================
int sqlite3_get_table(
sqlite3*, /* An open database */
const char *sql, /* SQL to be executed */
char ***resultp, /* Result written to a char *[] that this points to */
int *nrow, /* Number of result rows written here */
int *ncolumn, /* Number of result columns written here */
char **errmsg /* Error msg written here */
);
功能:查询?br />PARAM1(IN):数据库句?br />PARAM2(IN):sql语句,以\0l尾.
PARAM3(OUT):查询l果
PARAM4(OUT):q回行数(多少条数?
PARAM5(OUT):q回列数(多少字段)
PARAM6(OUT):q回错误信息
q回?SQLITE_OK成功,房子p|见错误信?/p>
=====================================================================================
void sqlite3_free_table(char **result);
功能:释放通过sqlite3_get_table查询保存的结果数?br />PARAM1(IN):要释攄数据指针
=====================================================================================
int sqlite3_prepare(
sqlite3 *db, /* Database handle */
const char *zSql, /* SQL statement, UTF-8 encoded */
int nBytes, /* Length of zSql in bytes. */
sqlite3_stmt **ppStmt, /* OUT: Statement handle */
const char **pzTail /* OUT: Pointer to unused portion of zSql */
);
功能:构造查?br />PARAM1(IN):数据库句?br />PARAM2(IN):sql语句
PARAM3(IN):sql语句长度,讄?1则自动按字符串计sql语句长度
PARAM4(OUT):保存的查询结构体,
PARAM5(OUT):NULL卛_
q回?SQLITE_OK成功.
=====================================================================================
int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*));
功能:为查询结构体l定数据
PARAM1(IN):查询l构?br />PARAM2(IN):l定W几个数?sql语句中的W几个问??))
PARAM3(IN):二进制数据指?br />PARAM4(IN):二进制数据长?br />PARAM5(IN):析构回调函数,通常讄NULL,l束后自己释?br />q回?S_OK成功.
说明:l定函数必须要在sqlite3_step?sqlite3_prepare或者sqlite3_reset之后调用.
未绑定的参数~省为NULL,cM的绑定函数还有以?br />int sqlite3_bind_double(sqlite3_stmt*, int, double);
int sqlite3_bind_int(sqlite3_stmt*, int, int);
int sqlite3_bind_int64(sqlite3_stmt*, int, sqlite_int64);
int sqlite3_bind_null(sqlite3_stmt*, int);
int sqlite3_bind_text(sqlite3_stmt*, int, const char*, int n, void(*)(void*));
int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*));
int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*);
=====================================================================================
int sqlite3_reset(sqlite3_stmt *pStmt);
功能:重置所有绑定的?回到刚刚调用sqlite3_prepare后的状?/p>
=====================================================================================
int sqlite3_step(sqlite3_stmt*);
功能:执行查询
PARAM1:查询l构?br />q回?
SQLITE_BUSY:数据库被?可以{待释放后重新调用该函数
SQLITE_DONE:成功
SQLITE_ROW:成功q且有数据返?Ҏ(gu)查询C条数据都?x)返回该?
可以调用sqlite3_column_*函数获取数据后重新调用处理下一条数?br />SQLITE_ERROR:p|
SQLITE_MISUSE:错误的调?比如已经q回了SQLITE_DONE或者SQLITE_ERROR后还l箋调用该函?/p>
=====================================================================================
int sqlite3_finalize(sqlite3_stmt *pStmt);
功能:释放查询l构?/p>
=====================================================================================
int sqlite3_key(
sqlite3 *db, /* Database to be rekeyed */
const void *pKey, int nKey /* The key */
);
功能:为加密的数据库指定密?改函数在sqlite3_open之后调用
=====================================================================================
int sqlite3_rekey(
sqlite3 *db, /* Database to be rekeyed */
const void *pKey, int nKey /* The new key */
);
功能:重设数据库密?如果pKey = 0 或?nKey = 0,q数据库不加?/p>
=====================================================================================
const char *sqlite3_libversion(void);
int sqlite3_libversion_number(void);
功能:获取版本?/p>
sqlite_int64 sqlite3_last_insert_rowid(sqlite3*);
功能:获取最后插入的行标C?
int sqlite3_changes(sqlite3*);
功能:获取最q执行的sqlite3_exec影响的行?
int sqlite3_total_changes(sqlite3*);
功能:获取自从数据库打开后有改动的函?/p>
void sqlite3_interrupt(sqlite3*);
功能:打断或停止数据库当前操作.
int sqlite3_complete(const char *sql);
功能:判断语句是否以分?;)l尾
int sqlite3_busy_handler(sqlite3*, int(*)(void*,int), void*);
功能:讄查询忙碌时的回调处理
说明:~省的回调函Cؓ(f)I?如果回调函数为空,表锁定后sqlite3_exec()执行?x)直接返回SQLITE_BUSY
int sqlite3_busy_timeout(sqlite3*, int ms);
功能:讄查询时旉(毫秒)
char *sqlite3_mprintf(const char*,...);
char *sqlite3_vmprintf(const char*, va_list);
char *sqlite3_snprintf(int,char*,const char*, ...);
功能:格式化字W?需要用%q来代?s.(主要是不用对分号'q行转义)
void *sqlite3_malloc(int);
void *sqlite3_realloc(void*, int);
void sqlite3_free(void*);
功能:内存函数
int sqlite3_set_authorizer(
sqlite3*,
int (*xAuth)(void*,int,const char*,const char*,const char*,const char*),
void *pUserData
);
功能:讄数据库授?/p>
void *sqlite3_trace(sqlite3*, void(*xTrace)(void*,const char*), void*);
void *sqlite3_profile(sqlite3*,
void(*xProfile)(void*,const char*,sqlite_uint64), void*);
void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
功能:讄执行回调函数,sqlite3_exec(),sqlite3_step() ,sqlite3_get_table()时会(x)调用
void *sqlite3_commit_hook(sqlite3*, int(*)(void*), void*);
功能:讄事务回调函数
int sqlite3_errcode(sqlite3 *db);
const char *sqlite3_errmsg(sqlite3*);
功能:获取错误码和错误消息
int sqlite3_bind_parameter_count(sqlite3_stmt*);
功能:q回需要绑定的参数数目(sql语句中问?数量)
const char *sqlite3_bind_parameter_name(sqlite3_stmt*, int);
功能:获取l定参数名字,?参数q回NULL
int sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName);
功能:获取l定参数索引
int sqlite3_clear_bindings(sqlite3_stmt*);
功能:清除l定的参?/p>
int sqlite3_column_count(sqlite3_stmt *pStmt);
功能:获取列数
const char *sqlite3_column_name(sqlite3_stmt*,int);
功能:获取列名
const char *sqlite3_column_database_name(sqlite3_stmt*,int);
const void *sqlite3_column_database_name16(sqlite3_stmt*,int);
const char *sqlite3_column_table_name(sqlite3_stmt*,int);
const void *sqlite3_column_table_name16(sqlite3_stmt*,int);
const char *sqlite3_column_origin_name(sqlite3_stmt*,int);
const void *sqlite3_column_origin_name16(sqlite3_stmt*,int);
功能:q回列信?
const char *sqlite3_column_decltype(sqlite3_stmt *, int i);
功能:q回列数据类?/p>
int sqlite3_data_count(sqlite3_stmt *pStmt);
功能:q回数据数量(行数)
const void *sqlite3_column_blob(sqlite3_stmt*, int iCol);
int sqlite3_column_bytes(sqlite3_stmt*, int iCol);
int sqlite3_column_bytes16(sqlite3_stmt*, int iCol);
double sqlite3_column_double(sqlite3_stmt*, int iCol);
int sqlite3_column_int(sqlite3_stmt*, int iCol);
sqlite_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol);
const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol);
const void *sqlite3_column_text16(sqlite3_stmt*, int iCol);
int sqlite3_column_type(sqlite3_stmt*, int iCol);
int sqlite3_column_numeric_type(sqlite3_stmt*, int iCol);
sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol);
功能:获取列数?/p>
int sqlite3_create_function(
sqlite3 *,
const char *zFunctionName,
int nArg,
int eTextRep,
void*,
void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
void (*xStep)(sqlite3_context*,int,sqlite3_value**),
void (*xFinal)(sqlite3_context*)
);
功能:
const void *sqlite3_value_blob(sqlite3_value*);
int sqlite3_value_bytes(sqlite3_value*);
int sqlite3_value_bytes16(sqlite3_value*);
double sqlite3_value_double(sqlite3_value*);
int sqlite3_value_int(sqlite3_value*);
sqlite_int64 sqlite3_value_int64(sqlite3_value*);
const unsigned char *sqlite3_value_text(sqlite3_value*);
const void *sqlite3_value_text16(sqlite3_value*);
const void *sqlite3_value_text16le(sqlite3_value*);
const void *sqlite3_value_text16be(sqlite3_value*);
int sqlite3_value_type(sqlite3_value*);
int sqlite3_value_numeric_type(sqlite3_value*);
功能:cMsqlite3_column_*函数
本文?a >应有有-应有有|ؓ(f)(zhn)整理提?/p>
?span class="t_tag" href="tag.php?name=%CA%F4%D0%D4">属?/span>斚w
AfxDump
void AfxDump(const CObject* pOb); // 如果在调试器内调用,则{存对象的状?br />
参数Q?pOb 指向由CObjectl承的类的对象的指针?
说明Q?br />在调试器中调用这个函C在调试时转储对象的状态。AfxDump调用一个对象的Dump函数q且信息发送到afxDump变量指定的位|。AfxDump仅能在MFC的调试版本中使用?br />你的E序代码不应该调用AfxDumpQ而是应该调用适当对象的Dump成员函数?/p>
AfxDumpStack
void AFXAPI AfxDumpStack(DWORD dwTarget = AFX_STACK_DUMP_TARGET_DEFAULT); // 生成当前栈的一个映像,该函数通常被静态链?br />
参数Q?dwTarget 指出转储输出的目标。其取值可以用位或操作W(|Q组合v来,可能值如下:(x) · AFX_STACK_DUMP_TARGET_TRACE 通过TRACE宏输出。TRACE仅仅在调试版本中产生输出Q在发行版本中不产生输出。同ӞTRACE可以被重定向到调试器以外的目标?
· AFX_STACK_DUMP_TARGET_DEFAULT {储输出发送到~省目标。对于调试版本,输出发送给TRACE宏。在发行版本中,输出发送到剪脓(chung)ѝ?
· AFX_STACK_DUMP_TARGET_CLIPBOARD 输出仅发送到剪脓(chung)ѝ数据将按CF_TEXT格式以普通文本的形式攑֜剪脓(chung)板上?
· AFX_STACK_DUMP_TARGET_BOTH 同时输出发送到剪脓(chung)板和TRACE宏?
· AFX_STACK_DUMP_TARGET_ODS 通过Win32函数OutputDebugString()直接输出发送的调试器。如果连接了调试器,它在调试版本和发行版本中都会(x)产生调试器输出。AFX_STACK_DUMP_TARGET_ODS 通常到达调试器(如果q接了调试器Q,q且不能被重定向?
说明Q?br />
q个全局函数可以被用来生成当前栈的一个映象。下面的例子反映了MFC对话框应用程序中按钮处理函数调用AfxDumpStack所产生的单行调试输出:(x)
=== begin AfxDumpStack output ===
...
BFF928E0: WINDOWS\SYSTEM\KERNERL32.DLL! UTUnRegister + 2492 bytes
=== end AfxDumpStack() output ===
BFF928E0Q?最q一ơ函数调用的q回地址
WINDOWS\SYSTEM\KERNEL32.DLL! 包含函数调用的模块的完整路径?
UTUnRegister 调用的函数原?
+ 2492 bytes 以字节ؓ(f)单位的从函数原型地址Q这个例子中为UTUnregisterQ到q回地址Q这个例子中为BEF928E0Q的偏移
AfxDumpStack在MFC库的调试版本和非调试版本中都可以使用。但是,q个函数通常是静态连接的Q即使你的可执行文g以共享DLL的方式用MFC?br />
在共享库的实CQ可以在MFCS42.LIB库(以及(qing)它的变化形式Q中扑ֈq个函数?br />
Z成功C用这个函敎ͼ(x)
· 在你的\径中必须包含I(xin)MAGEHLP.DLL文g。如果你没有q个DLL文gQ这个函C(x)昄一条错误信息。IMAGEHLP.DLL是随Win32 SDK和W(xu)indows一起发售的可散发的DLL。在C:\[Windows]\system[32]下查扑֮。有关IMAGEHLP提供的函数集的介l可以参考“可UL的可执行文g的操作”一文?
· h栈框架的模块必须包含调试信息。如果它不包含调试信息,q个函数仍然?x)生成对栈的跟踪Q但是这U跟t是很简略的?/p>
AfxEnableMemoryTracking
BOOL AfxEnableMemoryTracking(BOOL bTrack); // 打开或关闭内存跟t?br />
q回|(x)以前的跟t允许状态设|?br />
参数Q?bTrack 这个D为TRUE时就打开了内存跟t特性。如果是FALSE则将其关闭?
说明Q?br />诊断内存跟踪通常在MFC的调试版本中有效。利用这个函数对你的代码中正分配内存的部分止跟踪?br />有关AfxEnableMemoryTracking的更多信息请参见《Visual C++E序员指南》中的“MFC调试支持”?br />注意Q这个函C在MFC的调试版本中起作用?/p>
AfxIsMemoryBlock
BOOL AfxIsMemoryBlock( const void* p, UINT nBytes, LONG* plRequestNumber = NULL ); // 验一个内存块是否被正的分配
q回|(x)
如果内存块是现在分配的,q且光度也是正的Q则q回非零倹{否则ؓ(f)0?br />
参数Q?p 指向被试的内存块?
nBytes 包含了以字节为单位的内存块长度?
plRequestNumber 指向一个长整数Q它?yu)被设?f)内存块的分配pdL(fng)。由plRequestNumber指向的这个变量只有当AfxIsMemoryBlockq回非零值时才会(x)被填充?
说明Q?br />一个内存地址Q确保它代表了一个由new的诊断版本分配的zd的内存块。它同时也检验指定的大小是否与最初分配的大小相符。如果这个函数返回非零|分配的系列号码将在plRequestNumber中返回。这个号码代表了q个内存块相对于其它所有内存分配的序?br />
CZQ?br />// AfxIsMemoryBlock的例?br />CAge* pcage = new CAge( 21 ); // CAge is derived from CObject.
ASSERT( AfxIsMemoryBlock( pcage, sizeof( CAge ) ) )
AfxIsValidString
BOOL AfxIsValidString( LPCSTR lpsz, int nLength = -1 ); // 验一个字W串指针是否有效
如果l定的指针指向一个给定大的字符串则q回非零|否则q回0?br />
参数Q?lpsz 要测试的指针?
nLength 指定要测试的字符串的长度Q以字节为单位。如果gؓ(f)Q?Q表C字W串是以nulll尾的?
说明Q?br />使用q个函数来确定指向字W串的指针是否有效?/p>
AfxSetAllocHook
AFX_ALLOC_HOOK AfxSetAllocHook( AFX_ALLOC_HOOK pfnAllocHook ); // 允许在每ơ进行内存分配事调用一个函?br />
如果你希望允许分配,则返回非零倹{否则返??br />
参数Q?pfnAllocHook 指定要调用的函数名。参考关于分配函数的原型的说明?
说明Q?br />q个函数讄一个钩子,使每ơ分配内存之前都?x)调用一个指定的函数。微软基cd中的调试内存分配函数能够调用一个用户定义的钩子函数Q用户能够监控内存分配q控制是否允许分配内存。内存分配的钩子函数的原型如下:(x)
BOOL AFXAPI AllocHook( size_t nSize, BOOL bObject, LONG lRequestNumber );
nSize 计划分配的内存大?
bObject 如果是要Z个CObjectzcd象分配内存则为TRUEQ否则ؓ(f)FALSE?
lRequestNumber 内存分配的系列号?br />注意QAFXAPI调用U定意味着调用者必M栈中清除参数?/p>
AfxDoForAllClasses
void AFXAPI AfxDoForAllClasses(
void (* pfn)(const CRuntimeClass* pClass, void* pContext),
void* pContext
); //Ҏ(gu)有从CObjectl承的支持运行时查的cL行一个特定的功能
参数Q?pfn 指向每个c都?x)调用的重复函数。这个参数是一个指向CRuntimeClass对象的指针以?qing)指向调用者提供给函数的附加数据的void指针?
pContext 指向调用者提供给重复函数的可选数据的指针。这个指针可以是NULL?
说明Q?br />在应用程序的内存I间中,为所有从CObjectl承的可串行化的c调用指定的重复函数。从CObjectl承的可串行化的cL以DECLARE_SERIAL宏承的。每ơ调用指定的重复函数Ӟ都会(x)在pContext中传递给AfxDoForAllClasses的指针传递给重复函数?br />注意Q这个函C在MFC的调试版本中起作用?/p>
AfxDoForAllObjects
void AfxDoForAllObjects(
void (* pfn)(CObject* pObject, void* pContext),
void* pContext
); // Ҏ(gu)有从CObjectl承的用new分配内存对象执行一个指定的功能
参数Qpfn 指向每个对象都执行的重复函数。函数的参数是一个指向CObject的指针以?qing)指向调用者提供给函数的附加数据的void指针?
pContext 指向调用者提供给函数的附加数据的指针。这个指针可以ؓ(f)NULL?
说明Q?br />Ҏ(gu)个用new分配的从CObjectl承的对象执行指定的重复函数。栈、全局变量或嵌入对象不包括在内。每ơ调用指定的重复函数Ӟ都会(x)在pContext中传递给AfxDoForAllObjects的指针传递给重复函数?br />注意Q这个函C在MFC的调试版本中起作用?br />
from:http://hi.baidu.com/ice_water/blog/item/7cef04f73475c42a720eec98.html
在需要在相应的对话框中加上InitInstanceQvoidQ函Cd
AfxInitRichEdit();
b.升默认的Riched版本(默认的有一些bug)Q如
可在InitInstance中添?br />LoadLibrary("RICHED20.DLL")
最后注?FreeLibrary
如果是CRichEditView基类的可?br />BOOL CXXXXXXView::PreCreateWindow(CREATESTRUCT& cs)
{
//装入rich edit version 2.0
if (LoadLibraryA("RICHED20.DLL") == NULL)
{
AfxMessageBox(_T("Fail to load \"riched20.dll\"."),MB_OK | MB_ICONERROR);
PostMessage(WM_QUIT,0,0);
return FALSE;
}
m_strClass = RICHEDIT_CLASSA;//for 2.0 class
return CRichEditView::PreCreateWindow(cs);
}
c.最后追加行
richeditctrl.SetSel(-1, -1);
richeditctrl.ReplaceSel( (LPCTSTR)str );
d.字数限制
CRichEditCtrl::LimitText(long nChars)
e.换行切换
CRichEditView的OnInitialUpdate()函数中加入下面两句:(x)
m_nWordWrap = WrapNone;
WrapChanged();
WrapChanged实际上也是调?br />ctrl.SetTargetDevice(NULL, 1); //m_nWordWrap == WrapNone
ctrl.SetTargetDevice(NULL, 0); //m_nWordWrap == WrapToWindow
q有不常用的 m_nWordWrap == WrapToTargetDevice
ctrl.SetTargetDevice(m_dcTarget, GetPrintWidth());
如果是在Dialog中,可用SetTargetDeviceQ注意在属性里面加上want return
f.有时候不希望带格式的数据_脓(chung)Q可通过PasteSpecial选择性粘?br />pmyRichEditCtrl->PasteSpecial(CF_TEXT);
g.随着输入随着自动滚动条滚动到最后一?br />int nFirstVisible = pmyRichEditCtrl->GetFirstVisibleLine();
if (nFirstVisible > 0)
{
pmyRichEditCtrl->LineScroll(-nFirstVisible, 0);
}
?br />m_cRichEdit.PostMessage(WM_VSCROLL, SB_BOTTOM,0);
h.讄UNDO的次?只能用在RICHED20以上Q即默认不支持,必须升)
SendMessage(EM_SETTEXTMODE,TM_MULTILEVELUNDO,0);
TM_MULTILEVELUNDO 支持多取?默认?.可通过EM_SETUNDOLIMIT讄最大次?
SendMessage(EM_SETUNDOLIMIT,100,0);
i.响应OnChange
EM_SETEVENTMASK 讄 ENM_CHANGE
long lMask = GetEventMask();
lMask |= ENM_CHANGE;
lMask &= ~ENM_PROTECTED;
SetEventMask(lMask);
j.讄只读
CRichEditCtrl::SetReadOnly( BOOL bReadOnly = TRUE );
通过讄PROTECTED实现选中的文本只读,参见
http://www.codeguru.com/Cpp/controls/richedit/article.php/c2401/
?函数应用
a.讄字体Q主要是通过SetSelectionCharFormatQ?br />CHARFORMAT cf;
rich.GetSelectionCharFormat(cf);
cf.dwMask|=CFM_BOLD;
cf.dwEffects|=CFE_BOLD;//讄_体Q取消用cf.dwEffects&=~CFE_BOLD;
cf.dwMask|=CFM_ITALIC;
cf.dwEffects|=CFE_ITALIC;//讄斜体Q取消用cf.dwEffects&=~CFE_ITALIC;
cf.dwMask|=CFM_UNDERLINE;
cf.dwEffects|=CFE_UNDERLINE;//讄斜体Q取消用cf.dwEffects&=~CFE_UNDERLINE;
cf.dwMask|=CFM_COLOR;
cf.crTextColor = RGB(255,0,0);//讄颜色
cf.dwMask|=CFM_SIZE;
cf.yHeight =200;//讄高度
cf.dwMask|=CFM_FACE;
strcpy(cf.szFaceName ,_T("隶书"));//讄字体
rich.SetSelectionCharFormat(cf);
b.讄字体的行间距
要用richedit2.0以上
试试
PARAFORMAT2 pf;
pf.cbSize = sizeof(PARAFORMAT2);
pf.dwMask = PFM_NUMBERING | PFM_OFFSET;
pf.wNumbering = PFN_BULLET;//注意PFM_NUMBERING
pf.dxOffset = 10;
VERIFY(SetParaFormat(pf));
常用的dwMask?br />PFM_NUMBERING 成员 wNumbering 才v作用Q项目符P默认用PFN_BULLET
2 使用阿拉伯数?(1, 2, 3, ...).
3 使用写字母 (a, b, c, ...).
4 使用大写字母 (A, B, C, ...).
5 使用写|马数字 (i, ii, iii, ...).
6 使用大写|马数字 (I, II, III, ...).
7 自定义,字符见成?wNumberingStart.
PFM_OFFSET 成员 dxOffset 才v作用Q羃q,单位twips
PFM_STARTINDENT 成员 dxStartIndent 才v作用Q首行羃q?br />PFM_SPACEAFTER 成员 dySpaceAfter 才v作用Q段间距
PFM_LINESPACING 成员 dyLineSpacing 才v作用Q行间距
c.讄CRichEditCtrl(2.0)背景透明
long style = ::GetWindowLong(GetSafeHwnd(), GWL_EXSTYLE);
style &= WS_EX_TRANSPARENT;
::SetWindowLong(GetSafeHwnd(), GWL_EXSTYLE, style);
?CreateExQ然后把WS_EX_TRANSPARENT样式加上
e.得到内容有三U?br />1)GetWindowText
2)使用EM_GETTEXTEX
GETTEXTEX gt;
gt.cb = 200;
gt.flags = GT_DEFAULT;
gt.codepage = CP_ACP ;
gt.lpDefaultChar = NULL;
gt.lpUsedDefChar = NULL;
SendMessage(EM_GETTEXTEX,(WPARAM)>,(LPARAM)text);
3)StreamOut(主要用于RTF{格式输?
static DWORD CALLBACK
MyStreamOutCallback(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
{
CFile* pFile = (CFile*) dwCookie;
pFile->Write(pbBuff, cb);
*pcb = cb;
return 0;
}
CFile cFile(TEXT("myfile.rtf"), CFile::modeCreate|CFile::modeWrite);
EDITSTREAM es;
es.dwCookie = (DWORD) &cFile;//讄用例参数,以便回调函数调用
es.pfnCallback = MyStreamOutCallback;
pmyRichEditCtrl->StreamOut(SF_RTF, es);
d可以此类推,SetWindowText,EM_SETTEXTEX,StreamIn
f.查找字符?br />FINDTEXTEX ft;
ft.chrg.cpMin = 0;
ft.chrg.cpMax = -1;
ft.lpstrText = "|";
long lPos = FindText(0, &ft);
如果要l查找,修改cpMin,?br />int nCount = 0;
do
{
long lPos = GetRichEditCtrl().FindText(0, &ft);
if( -1 == lPos) break;
ft.chrg.cpMin = lPos + strlen(ft.lpstrText);
++nCount;
}while(TRUE);
g.以Html格式保存
目前做法可先转ؓ(f)RTF格式Q再通过RTF-to-HTML Converter
http://www.codeguru.com/Cpp/controls/richedit/conversions/article.php/c5377/
h.重蝲OnProtected函数得到对应的消息,如粘贴等
void CMYichEditorView::OnProtected(NMHDR* pNMHDR, LRESULT* pResult)
{
ENPROTECTED* pEP = (ENPROTECTED*)pNMHDR;
switch (pEP->msg) {
case WM_KEYDOWN://按键Q判断pEP->wParam
case WM_PASTE://_脓(chung)
case WM_CUT://剪切
case EM_SETCHARFORMAT:
default:
break;
};
*pResult = FALSE;
}
?聊天常用
a.LINK 链接功能
1. LoadLibrary(_T("Riched20.dll"));
2. 创徏RichEdit2.0控g
CreateEx(0, _T("RichEdit20A"), NULL, WS_CHILD|WS_VISIBLE|WS_VSCROLL|WS_TABSTOP
|ES_READONLY|ES_WANTRETURN|ES_MULTILINE,
rect.left, rect.top, cx, cy,
pParentWnd->m_hWnd, (HMENU)nID, NULL);
3. 讑֮选中的文字ؓ(f)链接昄
CHARFORMAT2 cf2;
ZeroMemory(&cf2, sizeof(CHARFORMAT2));//
cf2.cbSize = sizeof(CHARFORMAT2);
cf2.dwMask = CFM_LINK;
cf2.dwEffects |= CFE_LINK;
m_cRichEdit.SendMessage(EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf2);
4.支持链接的点d?br />m_cRichEdit.SetEventMask(ENM_LINK);
5.响应链接的点击EN_LINK
BEGIN_MESSAGE_MAP(CMyRichEdit, CRichEditCtrl)
ON_NOTIFY_REFLECT(EN_LINK,OnURL)
END_MESSAGE_MAP()
......
void CMyRichEdit::OnURLClick(NMHDR *pNmhdr, LRESULT *pResult)
{
TCHAR LinkChar[512];
ENLINK *pLink = (ENLINK *)pNmhdr;
if (pLink->msg == WM_LBUTTONUP)
{
SetSel(penLink->chrg);//q是链接的文字范?br />long Res = GetSelText((char *)LinkChar);//q是链接文字
//后面是你的处理过E?br /> ......
}
}
b.插入位图
http://www.codeguru.com/Cpp/controls/richedit/article.php/c2417/
http://www.codeguru.com/Cpp/controls/richedit/article.php/c5383/
自定义在RichEdit中插入对象的图标
http://www.blogcn.com/user3/jiangsheng/blog/1319738.html
Ҏ(gu)基本同Knowledge Base文章Q220844 HOWTO: Insert a Bitmap Into an RTF Document Using the RichEdit Control
只是在最后插入之前调用一下IOleCache::SetData,用一个HGLOBAL作ؓ(f)参数QHGLOBAL里面的数据是一个METAFILEPICTl构Q包含自己提供的囄
使用CRichEditView::InsertFileAsObject可以插入图像。VC++带有一个例子WordPad?br />另外可以参考“Insert any HBITMAP (Bitmap) in your RichEdit Control?http://www.codeguru.com/richedit/richeditrc.html)?/p>
c.昄GIF动画
常用的是通过qq的imageole.dll(也有用Gif89.dll?
http://www.xiaozhou.net/cooldog/blogview.asp?logID=82
http://www.codeproject.com/richedit/AnimatedEmoticon.asp
在richedit控g中插入动态GIF (Native C++?
http://blog.joycode.com/jiangsheng/archive/2004/12/15/41209.aspx
d.IRichEditOleCallback的?br />http://61.186.252.131/Expert/topic/905/905844.xml?temp=.8379022
cM MSN 信息发送框的制??
http://www.vckbase.com/document/viewdoc/?id=1087
内容包含Q实现右键菜单,囄插入Q读?写入RTF格式字符?/p>
自定?CRichEditCtrl 控g
http://www.vckbase.com/document/viewdoc/?id=328
内容包含Q鼠标右键消息,消息映射Q字体变?/p>
PS.richedit控g升?.0后,先把字体设ؓ(f)楷体Q输入汉字没有问题,但输入字母时Q字母自动蟩转ؓ(f)Arial字体Q?.0却没有这个文题,仍然是用楷体昄字母
是一个专门的设计 Dual-font, Smart font apply, 参见 http://61.186.252.131/Expert/topic/913/913807.xml?temp=.3753778
不能昄囄{其他OLE对象
MFC提供的CRichEditCtrl没有提供直接昄囄{OLE对象的属性或Ҏ(gu)讄Q但是提供了一个接口SetOLECallback( IRichEditOleCallback* pCallback );
要让CRichEditCtrl昄囄Q就得在IRichEditOleCallback上下功夫?br />IRichEditOleCallback是windows中的接口Q它的定义如下:(x)
ContextSensitiveHelp:
通过该方法通知应用E序它将以上下文兌方式调度帮助?br />DeleteObject:
通过该方法发出通知Q一个对象即从RichEdit控g中删?br />GetClipboardData:
通过该方法允许RichEdit的客L(fng)Q调用程序)提供自己的粘贴对?br />GetContextMenu:
通过该方法向应用E序提出通过鼠标右键事g来获取上下文菜单的请?br />GetDragDropEffect:
通过该方法允许RichEdit的客L(fng)Q调用程序)讄拖动操作的效?br />GetInPlaceContext:
通过该方法提供了应用E序U和文档U接口,以及(qing)必要的支持In-placeȀzȝ信息
GetNewStrorage:
通过该方法存储从_脓(chung)板或文本流(RTF)中读取的新对?br />QueryAcceptData:
通过该方法决定在_脓(chung)操作或拖放操作中引入的数据是否可以被接受?br />QueryInsertObject:
通过该方法向应用E序询问某个对象是否可以被插?br />ShowContainerUI:
通过该方法告知应用程序是否显Cq操作界面
大致了解了IRichEditOleCallback接口后,应该清楚,要显C图片等ole对象Q至应该实现GetNewStorageҎ(gu)Q因Ҏ(gu)是存储ole对象的接口方法?/p>
以下是接口声明的代码Q?br /> interface IExRichEditOleCallback; // forward declaration (see below in this header file)
IExRichEditOleCallback* m_pIRichEditOleCallback;
BOOL m_bCallbackSet;
interface IExRichEditOleCallback : public IRichEditOleCallback
{
public:
IExRichEditOleCallback();
virtual ~IExRichEditOleCallback();
int m_iNumStorages;
IStorage* pStorage;
DWORD m_dwRef;
virtual HRESULT STDMETHODCALLTYPE GetNewStorage(LPSTORAGE* lplpstg);
virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void ** ppvObject);
virtual ULONG STDMETHODCALLTYPE AddRef();
virtual ULONG STDMETHODCALLTYPE Release();
virtual HRESULT STDMETHODCALLTYPE GetInPlaceContext(LPOLEINPLACEFRAME FAR *lplpFrame,
LPOLEINPLACEUIWINDOW FAR *lplpDoc, LPOLEINPLACEFRAMEINFO lpFrameInfo);
virtual HRESULT STDMETHODCALLTYPE ShowContainerUI(BOOL fShow);
virtual HRESULT STDMETHODCALLTYPE QueryInsertObject(LPCLSID lpclsid, LPSTORAGE lpstg, LONG cp);
virtual HRESULT STDMETHODCALLTYPE DeleteObject(LPOLEOBJECT lpoleobj);
virtual HRESULT STDMETHODCALLTYPE QueryAcceptData(LPDATAOBJECT lpdataobj, CLIPFORMAT FAR *lpcfFormat,
DWORD reco, BOOL fReally, HGLOBAL hMetaPict);
virtual HRESULT STDMETHODCALLTYPE ContextSensitiveHelp(BOOL fEnterMode);
virtual HRESULT STDMETHODCALLTYPE GetClipboardData(CHARRANGE FAR *lpchrg, DWORD reco, LPDATAOBJECT FAR *lplpdataobj);
virtual HRESULT STDMETHODCALLTYPE GetDragDropEffect(BOOL fDrag, DWORD grfKeyState, LPDWORD pdwEffect);
virtual HRESULT STDMETHODCALLTYPE GetContextMenu(WORD seltyp, LPOLEOBJECT lpoleobj, CHARRANGE FAR *lpchrg,
HMENU FAR *lphmenu);
};
-----------------------------------------------------------------------
注:(x)
m_edit1代表ID为IDC_EDIT1的CEdit控g的controlcd的变?br /> m_richedit1代表ID为IDC_RICHEDIT1的CRichEditCtrl控g的controlcd的变?/p>
--------------------------------------------------------------------------------
1.讄edit只读属?/p>
Ҏ(gu)一Q?br /> m_edit1.SetReadOnly(TRUE);
Ҏ(gu)二:(x)
::SendMessage(m_edit1.m_hWnd, EM_SETREADONLY, TRUE, 0);
--------------------------------------------------------------------------------
2.判断edit中光标状态ƈ得到选中内容(richedit同样适用)
int nStart, nEnd;
CString strTemp;
m_edit1.GetSel(nStart, nEnd);
if(nStart == nEnd)
{
strTemp.Format(_T("光标?d"), nStart);
AfxMessageBox(strTemp);
}
else
{
//得到edit选中的内容 ?
m_edit1.GetWindowText(strTemp);
strTemp = strTemp.Mid(nStart) - strTemp.Mid(nEnd);
AfxMessageBox(strTemp);
}
注:(x)GetSel后,如果nStart和nEndQ表明光标处于某个位|(直观来看是光标在闪动)Q?br /> 如果nStart和nEnd不相{,表明用户在edit中选中了一D内宏V?/p>
--------------------------------------------------------------------------------
3.在edit最后添加字W串
CString str;
m_edit1.SetSel(-1, -1);
m_edit1.ReplaceSel(str);
--------------------------------------------------------------------------------
4.随输入自动滚动到最后一?richedit同样适用)
Ҏ(gu)一Q(摘自msdnQ?br /> // The pointer to my edit.
extern CEdit* pmyEdit;
int nFirstVisible = pmyEdit->GetFirstVisibleLine();
// Scroll the edit control so that the first visible line
// is the first line of text.
if (nFirstVisible > 0)
{
pmyEdit->LineScroll(-nFirstVisible, 0);
}
Ҏ(gu)二:(x)
m_richedit.PostMessage(WM_VSCROLL, SB_BOTTOM, 0);
--------------------------------------------------------------------------------
5.如何限制edit输入指定字符
可以从CEditz一个类Q添加WM_CHAR消息映射。下面一个例子实C限定输入16q制字符的功能?/p>
void CMyHexEdit::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{
if ( (nChar >= '0' && nChar <= '9') ||
(nChar >= 'a' && nChar <= 'f') ||
(nChar >= 'A' && nChar <= 'F') ||
nChar == VK_BACK ||
nChar == VK_DELETE) //msdn的virtual key
{
CEdit::OnChar(nChar, nRepCnt, nFlags);
}
}
--------------------------------------------------------------------------------
6.如何使用richedit
dAfxInitRichEdit();
CxxxApp::InitInstance()
{
AfxInitRichEdit();
.............
}
AfxInitRichEdit()功能Q装?RichEdit 1.0 Control (RICHED32.DLL).
--------------------------------------------------------------------------------
7.如何使用richedit2.0 or richedit3.0
使用原因Q由于RichEdit2.0A自动为宽字符QWideCharQ,所以它可以解决中文q以及(qing)一些汉字问?/p>
Ҏ(gu)一Q(msdn上的做法Q适用于用VC.NET?qing)以后版本创建的工程Q?br /> To update rich edit controls in existing Visual C++ applications to version 2.0,
open the .RC file as text, change the class name of each rich edit control from "RICHEDIT" to "RichEdit20a".
Then replace the call to AfxInitRichEdit with AfxInitRichEdit2.
Ҏ(gu)二:(x)以对话框ZQ?br /> (1) 增加一全局变量 HMODULE hMod;
(2) 在CxxxApp::InitInstance()中添加一句hMod = LoadLibrary(_T("riched20.dll"));
在CxxxApp::ExitInstance()中添加一句FreeLibrary(hMod);
(3) 在对话框上放一个richeditQ文本方式打开.rc文g修改该richedit控g的类?RICHEDIT" to "RichEdit20a".
(4) 在对话框头文件添?CRichEditCtrl m_richedit;
在OnInitDialog中添?m_richedit.SubclassDlgItem(IDC_RICHEDIT1, this);
--------------------------------------------------------------------------------
8.改变richedit指定区域的颜色及(qing)字体
CHARFORMAT cf;
ZeroMemory(&cf, sizeof(CHARFORMAT));
cf.cbSize = sizeof(CHARFORMAT);
cf.dwMask = CFM_BOLD | CFM_COLOR | CFM_FACE |
CFM_ITALIC | CFM_SIZE | CFM_UNDERLINE;
cf.dwEffects = 0;
cf.yHeight = 12*12;//文字高度
cf.crTextColor = RGB(200, 100, 255); //文字颜色
strcpy(cf.szFaceName ,_T("隶书"));//讄字体
m_richedit1.SetSel(1, 5); //讄处理区域
m_richedit1.SetSelectionCharFormat(cf);
--------------------------------------------------------------------------------
9.讄行间距(只适用于richedit2.0Q?/p>
PARAFORMAT2 pf;
pf2.cbSize = sizeof(PARAFORMAT2);
pf2.dwMask = PFM_LINESPACING | PFM_SPACEAFTER;
pf2.dyLineSpacing = 200;
pf2.bLineSpacingRule = 4;
m_richedit.SetParaFormat(pf2);
--------------------------------------------------------------------------------
10.richedit插入位图
Q220844QHow to insert a bitmap into an RTF document using the RichEdit control in Visual C++ 6.0
http://support.microsoft.com/default.aspx?scid=kb;en-us;220844
http://www.codeguru.com/Cpp/controls/richedit/article.php/c2417/
http://www.codeguru.com/Cpp/controls/richedit/article.php/c5383/
--------------------------------------------------------------------------------
11.richedit插入gif动画
http://www.codeproject.com/richedit/AnimatedEmoticon.asp
--------------------------------------------------------------------------------
12.richedit嵌入ole对象
http://support.microsoft.com/kb/141549/en-us
--------------------------------------------------------------------------------
13.使richedit选中内容只读
http://www.codeguru.com/cpp/controls/richedit/article.php/c2401/
--------------------------------------------------------------------------------
14.打印richedit
http://www.protext.com/MFC/RichEdit3.htm
--------------------------------------------------------------------------------
15.richeidt用于聊天消息H口
http://www.vckbase.com/document/viewdoc/?id=1087
http://www.codeproject.com/richedit/chatrichedit.asp
http://www.codeguru.com/Cpp/controls/richedit/article.php/c2395/
--------------------------------------------------------------------------------
16.解决richedit的EN_SETFOCUS和EN_KILLFOCUS无响应的问题
http://support.microsoft.com/kb/181664/en-us
--------------------------------------------------------------------------------
17.richedit拼写?/p>
http://www.codeproject.com/com/AutoSpellCheck.asp
--------------------------------------------------------------------------------
18.改变edit背景?/p>
Q117778QHow to change the background color of an MFC edit control
http://support.microsoft.com/kb/117778/en-us
--------------------------------------------------------------------------------
19.当edit控g的父H口属性是带标题栏WS_CAPTION和子H口WS_CHILDӞ不能讄焦点SetFocus
Q230587QPRB: Can't Set Focus to an Edit Control When its Parent Is an Inactive Captioned Child Window
http://support.microsoft.com/kb/230587/en-us
--------------------------------------------------------------------------------
20. 在Edit中回车时Q会(x)退出对话框
选中Edit的风格Want Return?/p>
MSDN的解释如下:(x)
ES_WANTRETURN Specifies that a carriage return be inserted when the user presses the ENTER key while entering text into a multiple-line edit control in a dialog box. Without this style, pressing the ENTER key has the same effect as pressing the dialog box's default pushbutton. This style has no effect on a single-line edit control.
--------------------------------------------------------------------------------
21. 动态创建的edit没有Ҏ(gu)的问?/p>
m_edit.Create(....);
m_edit.ModifyStyleEx(0, WS_EX_CLIENTEDGE, SWP_DRAWFRAME);
--------------------------------------------------------------------------------
22. 一个能昄RTFQoleQ包括gifQ?wmvQexcel QpptQ的例子
http://www.codeproject.com/richedit/COleRichEditCtrl.asp
本文来自CSDN博客Q{载请标明出处Q?a >http://blog.csdn.net/qsycn/archive/2009/11/10/4793461.aspx
本文来自CSDN博客Q{载请标明出处Q?a >http://blog.csdn.net/abcpanpeng/archive/2010/04/21/5509680.aspx
1, d下面得函敎ͼ
#include <dbghelp.h>
#include <shellapi.h>
#include <shlobj.h>
LONG WINAPI GenerateDump(struct _EXCEPTION_POINTERS *pExceptionPointers)
{
LONG ret = EXCEPTION_EXECUTE_HANDLER;
BOOL bMiniDumpSuccessful;
TCHAR szPath[MAX_PATH];
TCHAR szFileName[MAX_PATH];
TCHAR* szAppName = TEXT(“AppName?;
TCHAR* szVersion = TEXT(“v1.0?;
DWORD dwBufferSize = MAX_PATH;
HANDLE hDumpFile;
SYSTEMTIME stLocalTime;
MINIDUMP_EXCEPTION_INFORMATION ExpParam;
GetLocalTime( &stLocalTime );
GetTempPath( dwBufferSize, szPath );
_stprintf( szFileName, TEXT(?s%s?, szPath, szAppName );
CreateDirectory( szFileName, NULL );
_stprintf( szFileName, TEXT(“c:\\aaaa.dmp?);
hDumpFile = CreateFile(szFileName, GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_WRITE|FILE_SHARE_READ, 0, CREATE_ALWAYS, 0, 0);
ExpParam.ThreadId = GetCurrentThreadId();
ExpParam.ExceptionPointers = pExceptionPointers;
ExpParam.ClientPointers = TRUE;
bMiniDumpSuccessful = MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(),
hDumpFile, MiniDumpWithDataSegs, &ExpParam, NULL, NULL);
int i = GetLastError();
HRESULT hr = HRESULT_FROM_WIN32(i);
return ret;
}
2Q在project setting中加入dbghelp.lib作ؓ(f)library的inputQ这是MiniDumpWriteDump需要的?strong>在Debug Information Format讄Program Database (/Zi)。设|?strong>Generate Debug Info?strong>Yes (/DEBUG)。在Optimization讄References?Eliminate Unreferenced Data (/OPT:REF)。设|?Enable COMDAT Folding?Remove Redundant COMDATs (/OPT:ICF)。后面两设|可以大大羃?yu)exe文g大小?/p>
3Q用如下:(x)
void SomeFunction()
{
int *pBadPtr = NULL;
*pBadPtr = 0;
}
void Ctest2Dlg::OnBnClickedButton1()
{
__try
{
SomeFunction();
}
__except(GenerateDump(GetExceptionInformation()))
{
}
}
4Q用windbg打开dmp文gQ就可以看到出错时的call stack了?/p>
几点要注意的Q?Q网上有文章介绍使用 SetUnhandledExceptionFilter讄异常qo(h)Q保证出现异常时能调用minidump函数Q但是这有些问题Q这个函C(x)Ddebugger失效Q而且好像跟drwatson有些冲突Q感觉用h比较危险。在E序的关键部分加入__try ?__exceptionQ这L(fng)?yu)捕捉范_(d)应该p够用了?Q必L用__try ?__exceptionq样的Ş式,才能保证GetExceptionInformation()能正怋用?QMiniDumpWithDataSegsq个参数我试着换成另外几个Q好像都不好用。返回值都?Q经q解析lasterror都是E_INVALIDARGQ奇怪?/p>
update: 关于使用windbg
windbg下蝲地址在这?a >http://www.microsoft.com/whdc/devtools/debugging/debugstart.mspx
下蝲安装最新版本即可,我没有搞清楚的一Ҏ(gu)必须要设|windows的symbol目录Q否则光有pdb是没法看到调用栈信息的?/p>
使用windbgq程如下Q安装。然后打开菜单file-> symbol file pathQ添加如?/p>
srv*c:\symbol_local*http://msdl.microsoft.com/download/symbols;c:\debug
其中srv*c:\symbol_local*http://msdl.microsoft.com/download/symbols;指明从网上下载操作系l用的symbol存放到c盘symbol_local目录Q另外程序的symbolQpdb文gQ可以放在c盘debug目录下?/p>
windbg?x)显CZD|间busy或者retrieving..Q然后就可以看到详细的dump信息?/p>
![]() |
SMTP命o(h) | 命o(h)说明 |
HELLO QdomainQ?QCRLFQ?/td> | 识别发送方到接收SMTP的一个HELLO命o(h) |
MAIL FROM:Qreverse-pathQ<CRLFQ? | Qreverse-pathQؓ(f)发送者地址。此命o(h)告诉接收方一个新邮g发送的开始,q对所有的状态和~冲行初始化。此命o(h)开始一个邮件传输处理,最l完成将邮g数据传送到一个或多个邮箱中?/td> |
RCPT TO:Qforward-pathQ<CRLFQ? | Qforward-pathQ标识各个邮件接收者的地址 |
DATA QCRLFQ? | 接收SMTP把其后的行为看作邮件数据去处理Q以QCRLFQ?QCRLFQ标识数据的l尾?/td> |
REST QCRLFQ?/td> | 退?复位当前的邮件传?/td> |
NOOP QCRLFQ?/td> | 要求接收SMTP仅做OK应答。(用于试Q?/td> |
QUIT QCRLFQ?/td> | 要求接收SMTPq回一个OK应答q关闭传输?/td> |
VRFY QstringQ?QCRLFQ? | 验证指定的邮是否存在,׃安全因素Q服务器多禁止此命o(h)?/td> |
EXPN QstringQ?QCRLFQ? | 验证l定的邮列表是否存在,扩充邮箱列表Q也常禁止用?/td> |
HELP QCRLFQ?/td> | 查询服务器支持什么命?/td> |
应答?/td> | 说明 |
501 | 参数格式错误 |
502 | 命o(h)不可实现 |
503 | 错误的命令序?/td> |
504 | 命o(h)参数不可实现 |
211 | pȝ状态或pȝ帮助响应 |
214 | 帮助信息 |
220 | QdomainQ服务就l?/td> |
221 | QdomainQ服务关?/td> |
421 | QdomainQ服务未qAQ关闭传输信?/td> |
250 | 要求的邮件操作完?/td> |
251 | 用户非本圎ͼ{发向Qforward-pathQ?/td> |
450 | 要求的邮件操作未完成Q邮׃可用 |
550 | 要求的邮件操作未完成Q邮׃可用 |
451 | 攑ּ要求的操作;处理q程中出?/td> |
551 | 用户非本圎ͼ请尝试<forward-pathQ? |
452 | pȝ存储不Q要求的操作未执?/td> |
552 | q量的存储分配,要求的操作未执行 |
553 | 邮箱名不可用Q要求的操作未执?/td> |
354 | 开始邮件输入,?."l束 |
554 | 操作p| |
R:220 sina.com Simple Mail Transfer Service Ready S:HELLO sohu.com R:250 sina.com S:MAIL FROM:Qlangrui@sohu.comQ?br />R:250 OK S:RCPT TO:Qrenping@sina.comQ?br />R:250 OK S:DATA R:354 Start mail input;end with "QCRLFQ?QCRLFQ? S:…?br />R:250 OK S:QUIT R:221 sina.com Service closing transmission channel |
//邮g头准?br />strTemp = _T( "From: " ) + m_strFrom; file://发g人地址 add_header_line( (LPCTSTR)strTemp ); strTemp = _T( "To: " ) + m_strTo; file://收g人地址 add_header_line( (LPCTSTR)strTemp ); m_tDateTime = m_tDateTime.GetCurrentTime();//发送时?br />strTemp = _T( "Data: " ); strTemp += m_tDateTime.Format( "%a, %d %b %y %H:%M:%S %Z" ); add_header_line( (LPCTSTR)strTemp ); strTemp = _T( "Subject: " ) + m_strSubject; file://主题 add_header_line( (LPCTSTR)strTemp ); file://邮g头结?br />m_strHeader += _T( "\r\n" ); file://邮g体准?br />if( m_strBody.Right( 2 ) != _T( "\r\n" ) ) file://认最后以回R换行l束 m_strBody += _T( "\r\n" ); |
BOOL CSMTP::get_response( UINT response_expected )//输入参数为希望的应答?br />{ …?br />// m_wsSMTPServer为CSocket的类对象Q调用Receive()应{码接收到缓?br />// response_buf?br />m_wsSMTPServer.Receive( response_buf, RESPONSE_BUFFER_SIZE ) sResponse = response_buf; sscanf( (LPCTSTR)sResponse.Left( 3 ), _T( "%d" ), &response ); pResp = &response_table[ response_expected ]; file://验收到的应答码是否是所希望得到?br />if( response != pResp-QnResponse ) { …?/不相{的话进行错误处?br />return FALSE; } return TRUE; } |
//格式化ƈ发送HELLO命o(h)Qƈ接收、验证服务器应答?br />gethostname( local_host, 80 ); sHello.Format( _T( "HELO %s\r\n" ), local_host ); m_wsSMTPServer.Send( (LPCTSTR)sHello, sHello.GetLength() ); if( !get_response( GENERIC_SUCCESS ) ) file://验应{码是否?50 { …?br />return FALSE; } file://格式化ƈ发送MAIL命o(h)Qƈ接收、验证服务器应答?br />sFrom.Format( _T( "MAIL From: Q?sQ\r\n" ), (LPCTSTR)msg-Qm_strFrom ); m_wsSMTPServer.Send( (LPCTSTR)sFrom, sFrom.GetLength() ); if( !get_response( GENERIC_SUCCESS ) ) file://验应{码是否?50 return FALSE; file://格式化ƈ发送RCPT命o(h)Qƈ接收、验证服务器应答?br />sEmail=(LPCTSTR)msg-Qm_strTo; sTo.Format( _T( "RCPT TO: Q?sQ\r\n" ), (LPCTSTR)sEmail ); m_wsSMTPServer.Send( (LPCTSTR)sTo, sTo.GetLength() ); if(!get_response( GENERIC_SUCCESS )) file://验应{码是否?50 return FALSE; file://格式化ƈ发送DATA命o(h)Qƈ接收、验证服务器应答?br />sTemp = _T( "DATA\r\n" ); m_wsSMTPServer.Send( (LPCTSTR)sTemp, sTemp.GetLength() ); if( !get_response( DATA_SUCCESS ) ) file://验应{码是否?54 return FALSE; file://发送根据RFC 822文档规定格式化过的邮件头 m_wsSMTPServer.Send( (LPCTSTR)msg-Qm_strHeader, msg-Qm_strHeader.GetLength() ); …?br />file://发送根据RFC 822文档规定格式化过的邮件体 sTemp = msg-Qm_strBody; if( sTemp.Left( 3 ) == _T( ".\r\n" ) ) sTemp = _T( "." ) + sTemp; while( (nPos = sTemp.Find( szBad )) Q?-1 ) { sCooked = sTemp.Mid( nStart, nPos ); sCooked += szGood; sTemp = sCooked + sTemp.Right( sTemp.GetLength() - (nPos + nBadLength) ); } m_wsSMTPServer.Send( (LPCTSTR)sTemp, sTemp.GetLength() ); file://发送内Ҏ(gu)据结束标?QCRLFQ?QCRLFQ?Qƈ验返回应{码 sTemp = _T( "\r\n.\r\n" ); m_wsSMTPServer.Send( (LPCTSTR)sTemp, sTemp.GetLength() ); if( !get_response( GENERIC_SUCCESS ) )// 验应{码是否?50 return FALSE; |