有关VC知识的一些介绍_evan

来源:百度文库 编辑:神马文学网 时间:2024/04/28 02:18:59
百度首页 |百度空间 |登录
evan
evan
主页博客相册|个人档案
查看文章
有关VC知识的一些介绍
2007-03-12 19:02
VC学习笔记1:一些调试的宏和函数
1.TRACE 宏的利用
TRACE 宏有点象我们以前在C语言中用的Printf函数,使程序在运行过程中输出一些调试信息,使我们能了解程序的一些状态。但有一点不同的是:TRACE 宏只有在调试状态下才有所输出,而以前用的Printf 函数在任何情况下都有输出。和Printf 函数一样,TRACE函数可以接受多个参数如:
int x = 1;
int y = 16;
float z = 32.0;
TRACE( "This is a TRACE statement\n" );
TRACE( "The value of x is %d\n", x );
TRACE( "x = %d and y = %d\n", x, y );
TRACE( "x = %d and y = %x and z = %f\n", x, y, z );
要注意的是TRACE宏只对Debug 版本的工程产生作用,在Release 版本的工程中,TRACE宏将被忽略。
2.ASSERT宏的利用
在开发过程中我们可以假设只要程序运行正确,某一条件肯定成立。如不成立 ,那么我们可以断言程序肯定出错。在这种情况下我们可以利用ASSERT来设定断言。ASSERT宏的参数是一个逻辑表达式,在程序运行过程中,若该逻辑表达式为真,则不会发生任何动作,若此表达式为假,系统将弹出一个对话框警告你,并停止程序的执行。同时要求你作出选择:Abort,Ignore,Retry。若你选择Abort,系统将停止程序的执行;若你选择Ignore 系统将忽略该错误,并继续执行程序;若你选择Retry ,系统将重新计算该表达式,并激活调试器。同TRACE宏一样,ASSERT宏只DEBUG版本中起作用,在RELEASE版本中ASSERT宏将被忽略。
3.ASSERT_VALID宏的利用以及类的AssertValid()成员函的重载
ASSERT_VALID宏用来在运行时检查一个对象的内部合法性,比如说现在 有一个学生对象,我们知道每个学生的年龄一定大于零,若年龄小于零,则该学生对象肯定有问题。事实上,ASSERT_VALID宏就是转化为对象的成员函数AssertValid()的调用,只是这种方法更安全。它的参数是一个对象指针,通过这个指针来调用它的AssertValid()成员函数。
与此相配套,每当我们创建从Cobject类继承而来的一个新的类时,我们可以重载该成员函数,以执行特定的合法性检查。
4.对象的DUMP函数的利用
Dump 函数用来按指定的格式输出一个对象的成员变量,来帮助你诊断一个对象的内部情况。与AssertValid成员函数一样,Dump也是Cobject 类的成员函数。Dump函数的参数是一个CdumpContext对象,你可以象利用流一样往向这个对象中输入数据。当你创建一个Cobject继承而来的 新类时,你可以按如下步骤重载你自己的Dump函数:
(1) 调用基类的Dump函数,以输出基类的内容;
(2) 向Cdumpcontest对象输出该类的数据.
例如,典型的Dump函数定义如下:
#ifdef _DEBUG
void CPerson::Dump( CDumpContext& dc ) const
{
// call base class function first
CObject::Dump( dc );
// now do the stuff for our specific class
dc << "last name: " << m_lastName << "\n"
<< "first name: " << m_firstName << "\n";
}
#endif
你可能已经注意到整个函数的定义都包含在#ifdef _DEBUG 和#endif中,这使得Dump成员函数只在DEBUG版本中发生作用,而对RELEASE版本不发生作用。
5.内存漏洞的检查
也许你已经知道,在C++和C语言中指针问题也就是内存申请与释放是一个令人头疼的事情,假如你申请了内存,但没有释放,并且你的程序需要长时间地运行,那么,系统的资源将逐渐减少,当系统的资源全部被用完时,系统将会崩溃。所以在开发程序的过程中一定要保证资源的完全释放。下面我们来介绍内存漏洞的检查。
也许你会问,系统是怎样支持内存漏洞的检查的?其实在你的Debug版本中所有的有关内存分配的函数都是被重载过的,具体过程是这样的,当你的程序申请内存时,它首先调用一般的内存分配函数分配一块稍大的内存块。在这一内存块中分为四个小块:Heap Information, buffer , User memory block, buffer。第一块为有关堆的信息,比如,申请该内存的地点(文件名,行号),此内存块的类型(如整型,浮点,或某一类的对象)等等。第二块是一个缓冲区,用于截获用户对其申请内存使用越界的情况。第三块是真正给用户的内存,返回的指针也是指向这儿。第四块也是一个缓冲区,作用同第二块。
当你申请的内存均被记录在案后,要检查内存漏洞就比较容易了,粗略地说,假如你要检查某一程序段是否有内存漏洞,你只需在这一程序 段的开始要求系统为你做一个内存使用情况的映象,记录下程序开始时的内存使用情况,然后在程序段的末尾再使系统为你做一次内存映象,比较两次映象,以检查是否有没释放的内存,假如有未释放的内存,根据这一块中有关分配情况的信息来告诉用户在那儿申请的内存没释放。
具体地讲检查内存漏洞需要以下几个步骤:
在你所检测的程序段的开始处建立一个CmemoryState对象,调用其成员函数Checkpoint,以取得当前内存使用情况的快照;
在你所检测的程序段的末尾处再建立一个CmemoryState 对象,调用其成员函数Checkpoint ,以取得当前内存使用情况的快照;
再建立第三个CmemoryState 对象,调用其成员函数Difference,把第一个CmemoryState对象和第二个CmemeoryState对象作为其参数.,如果两次内存快照不相同,则该函数返回非零,说明此程序 段中有内存漏洞。下面我们来看一个典型的例子:
// Declare the variables needed
#ifdef _DEBUG
CMemoryState oldMemState, newMemState, diffMemState;
OldMemState.Checkpoint();
#endif
// do your memory allocations and deallocations...
CString s = "This is a frame variable";
// the next object is a heap object
CPerson* p = new CPerson( "Smith", "Alan", "581_0215" );
#ifdef _DEBUG
newMemState.Checkpoint();
if( diffMemState.Difference( oldMemState, newMemState ) )
{
TRACE( "Memory leaked!\n" );
}
#endif
VC学习笔记2:利用MFC进行开发的通用方法介绍
以下是我在最初学习VC时所常用的开发思路和方法,希望能对初学VC的朋友有所帮助和启发。
1、开发需要读写文件的应用程序并且有简单的输入和输出可以利用单文档视结构。
2、开发注重交互的简单应用程序可以使用对话框为基础的窗口,如果文件读写简单这可利用CFile           进行。
3、开发注重交互并且文件读写复杂的的简单应用程序可以利用以CFormView为基础视的单文档视结         构。
4、利用对话框得到用户输入的数据,在等级提高后可使用就地输入。
5、在对多文档要求不强烈时尽量避免多文档视结构,可以利用分隔条产生单文档多视结构。
6、在要求在多个文档间传递数据时使用多文档视结构。
7、学会利用子窗口,并在自定义的子窗口包含多个控件达到封装功能的目的。
8、尽量避免使用多文档多视结构。
9、不要使用多重继承并尽量减少一个类中封装过多的功能。
VC学习笔记3:MFC中常用类,宏,函数介绍
常用类
CRect:用来表示矩形的类,拥有四个成员变量:top left bottom right。分别表是左上角和右                下角的坐标。可以通过以下的方法构造:
CRect( int l, int t, int r, int b ); 指明四个坐标
CRect( const RECT& srcRect ); 由RECT结构构造
CRect( LPCRECT lpSrcRect ); 由RECT结构构造
CRect( POINT point, SIZE size ); 有左上角坐标和尺寸构造
CRect( POINT topLeft, POINT bottomRight ); 有两点坐标构造
下面介绍几个成员函数:
int Width( ) const; 得到宽度
int Height( ) const; 得到高度
CSize Size( ) const; 得到尺寸
CPoint& TopLeft( ); 得到左上角坐标
CPoint& BottomRight( ); 得到右下角坐标
CPoint CenterPoint( ) const; 得当中心坐标
此外矩形可以和点(CPoint)相加进行位移,和另一个矩形相加得到“并”操作后的矩形。
CPoint:用来表示一个点的坐标,有两个成员变量:x y。 可以和另一个点相加。
CString:用来表示可变长度的字符串。使用CString可不指明内存大小,CString会根据需要自行分配。下面介绍几个成员函数:
GetLength 得到字符串长度
GetAt 得到指定位置处的字符
operator + 相当于strcat
void Format( LPCTSTR lpszFormat, ... ); 相当于sprintf
Find 查找指定字符,字符串
Compare 比较
CompareNoCase 不区分大小写比较
MakeUpper 改为小写
MakeLower 改为大写
CStringArray:用来表示可变长度的字符串数组。数组中每一个元素为CString对象的实例。下面介绍几个成员函数:
Add 增加CString
RemoveAt 删除指定位置CString对象
RemoveAll 删除数组中所有CString对象
GetAt 得到指定位置的CString对象
SetAt 修改指定位置的CString对象
InsertAt 在某一位置插入CString对象
常用宏
RGB
TRACE
ASSERT
VERIFY
常用函数
CWindApp* AfxGetApp();
HINSTANCE AfxGetInstanceHandle( );
HINSTANCE AfxGetResourceHandle( );
int AfxMessageBox( LPCTSTR lpszText, UINT nType = MB_OK, UINT nIDHelp = 0 );用于弹出一个         消息框
VC学习笔记4:文字的输出
输出文字一般使用CDC::BOOL TextOut( int x, int y, const CString& str )和CDC::int DrawText( const CString& str, LPRECT lpRect, UINT nFormat )两个函数,对TextOut来讲只能输出单行的文字,而DrawText可以指定在一个矩形中输出单行或多行文字,并且可以规定对齐方式和使用何种风格。nFormat可以是多种以下标记的组合(利用位或操作)以达到选择输出风格的目的。
在输出文字时如果希望改变文字的颜色,你可以利用CDC::SetTextColor( COLORREF crColor )进行设置,如果你希望改变背景色就利用CDC::SetBkColor( COLORREF crColor ),很多时候你可能需要透明的背景色你可以利用CDC::SetBkMode( int nBkMode )设置
VC笔记5: 文档 视图 框架窗口间的关系和消息传送规律
在MFC中M$引入了文档-视结构的概念,文档相当于数据容器,视相当于查看数据的窗口或是和数据发生交互的窗口。(这一结构在MFC中的OLE,ODBC开发时又得到更多的拓展)因此一个完整的应用一般由四个类组成:CWinApp应用类,CFrameWnd窗口框架类,CDocument文档类,CView视类。(VC6中支持创建不带文档-视的应用)
在程序运行时CWinApp将创建一个CFrameWnd框架窗口实例,而框架窗口将创建文档模板,然后有文档模板创建文档实例和视实例,并将两者关联。一般来讲我们只需对文档和视进行操作,框架的各种行为已经被MFC安排好了而不需人为干预,这也是M$设计文档-视结构的本意,让我们将注意力放在完成任务上而从界面编写中解放出来。
在应用中一个视对应一个文档,但一个文档可以包含多个视。一个应用中只用一个框架窗口,对多文档界面来讲可能有多个MDI子窗口。每一个视都是一个子窗口,在单文档界面中父窗口即是框架窗口,在多文档界面中父窗口为MDI子窗口。一个多文档应用中可以包含多个文档模板,一个模板定义了一个文档和一个或多个视之间的对应关系。同一个文档可以属于多个模板,但一个模板中只允许定义一个文档。同样一个视也可以属于多个文档模板。(不知道我说清楚没有)
接下来看看如何在程序中得到各种对象的指针:
全局函数AfxGetApp可以得到CWinApp应用类指针
AfxGetApp()->m_pMainWnd为框架窗口指针
在框架窗口中:CFrameWnd::GetActiveDocument得到当前活动文档指针
在框架窗口中:CFrameWnd::GetActiveView得到当前活动视指针
在视中:CView::GetDocument得到对应的文档指针
在文档中:CDocument::GetFirstViewPosition,CDocument::GetNextView用来遍历所有和文档关联的视。
在文档中:CDocument::GetDocTemplate得到文档模板指针
在多文档界面中:CMDIFrameWnd::MDIGetActive得到当前活动的MDI子窗口
一般来讲用户输入消息(如菜单选择,鼠标,键盘等)会先发往视,如果视未处理则会发往框架窗口。所以定义消息映射时定义在视中就可以了,如果一个应用同时拥有多个视而当前活动视没有对消息进行处理则消息会发往框架窗口
VC学习笔记6   文档,视,框架之间相互作用
一般来说用户的输入/输出基本都是通过视进行,但一些例外的情况下可能需要和框架直接发生作用,而在多视的情况下如何在视之间传递数据。
在使用菜单时大家会发现当一个菜单没有进行映射处理时为禁止状态,在多视的情况下菜单的状态和处理映射是和当前活动视相联系的,这样MFC可以保证视能正确的接收到各种消息,但有时候也会产生不便。有一个解决办法就是在框架中对消息进行处理,这样也可以保证当前文档可以通过框架得到当前消息。
在用户进行输入后如何使视的状态得到更新?这个问题在一个文档对应一个视图时是不存在的,但是现在有一个文档对应了两个视图,当在一个视上进行了输入时如何保证另一个视也得到通知呢?MFC的做法是利用文档来处理的,因为文档管理着当前和它联系的视,由它来通知各个视是最合适的。让我们同时看两个函数:
void CView::OnUpdate( CView* pSender, LPARAM lHint, CObject* pHint )
void CDocument::UpdateAllViews( CView* pSender, LPARAM lHint = 0L, CObject* pHint = NULL )
当文档的UpdateAllViews被调用时和此文档相关的所有视的OnUpdate都会被调用,而参数lHint和pHint都会被传递。这样一来发生改变视就可以通知其他的兄弟了。那么还有一个问题:如何在OnUpdate中知道是那个视图发生了改变呢,这就可以利用pHint参数,只要调用者将this指针赋值给参数就可以了,当然完全可以利用该参数传递更复杂的结构。
视的初始化,当一个文档被打开或是新建一个文档时视图的CView::OnInitialUpdate()会被调用,你可以通过重载该函数对视进行初始化,并在结束前调用父类的OnInitialUpdate,因为这样可以保证OnUpdate会被调用。
文档中内容的清除,当文档被关闭时(比如退出或是新建前上一个文档清除)void CDocument::DeleteContents ()会被调用,你可以通过重载该函数来进行清理工作。
在单文档结构中上面两点尤其重要,因为软件运行文档对象和视对象只会被产生并删除一次。所以应该将上面两点和C++对象构造和构析分清楚。
最后将一下文档模板(DocTemplate)的作用,文档模板分为两类单文档模板和多文档模板,分别由CSingleDocTemplate和CMultiDocTemplate表示,模板的作用在于记录文档,视,框架之间的对应关系。还有一点就是模板可以记录应用程序可以打开的文件的类型,当打开文件时会根据文档模板中的信息选择正确的文档和视。模板是一个比较抽想的概念,一般来说是不需要我们直接进行操作的。
当使用者通过视修改了数据时,应该调用GetDocument()->SetModifiedFlag(TRUE)通知文档数据已经被更新,这样在关闭文档时会自动询问用户是否保存数据。
VC学习笔记7:利用序列化进行文件读写
在很多应用中我们需要对数据进行保存,或是从介质上读取数据,这就涉及到文件的操作。我们可以利用各种文件存取方法完成这些工作,但MFC中也提供了一种读写文件的简单方法——“序列化”。序列化机制通过更高层次的接口功能向开发者提供了更利于使用和透明于字节流的文件操纵方法,举一个例来讲你可以将一个字串写入文件而不需要理会具体长度,读出时也是一样。你甚至可以对字符串数组进行操作。在MFC提供的可自动分配内存的类的支持下你可以更轻松的读/写数据。你也可以根据需要编写你自己的具有序列化功能的类。
序列化在最低的层次上应该被需要序列化的类支持,也就是说如果你需要对一个类进行序列化,那么这个类必须支持序列化。当通过序列化进行文件读写时你只需要该类的序列化函数就可以了。
怎样使类具有序列化功能呢?你需要以下的工作:
该类从CObject派生。
在类声明中包括DECLARE_SERIAL宏定义。
提供一个缺省的构造函数。
在类中实现Serialze函数
使用IMPLEMENT_SERIAL指明类名和版本号
VC学习笔记7:wParam and lParam
Each windows message may have up to two parameters, wParam and lParam. Originally wParam was 16 bit and lParam was 32 bit, but in Win32 they are both 32 bit. Not every message uses these parameters, and each message uses them differently. For example the WM_CLOSE message doesn‘t use either, and you should ignore them both. The WM_COMMAND message uses both, wParam contains two values, HIWORD(wParam) is the notification message (if applicable) and LOWORD(wParam) is the control or menu id that sent the message. lParam is the HWND (window handle) to the control which sent the message or NULL if the messages isn‘t from a control.
VC学习笔记8:CreateDialog(), DialogBox()
DialogBox() implements it‘s own message loop and does not return untill the dialog is closed, CreateDialog() acts more like a window created with CreateWindowEx() in that it returns immediately and depends on your message loop to pump the messages as it does for your main window. This is termed Modeless, whereas DialogBox() creates Modal dialogs
VC学习笔记9:CreateFont()和CreateFontIndirect()
您可以调用 CreateFont 和 CreateFontIndirect 来创建自己的字体,这两个函数的差别是前者要求 您传递一系列的参数,而后着只要传递一个指向 LOGFONT 结构的指针。这样就使得后者使用起来更方便,尤其当您需要频繁创建字体时。若只要创建一种字体,则用 CreateFont 就足够了。在调用该函数后会返回所创建的字体的句柄,然后把该句柄选进“设备环境”使其成为当前字体,随后所有的“绘制”文本串的函数在被调用时都要把该句柄作为一个参数传递
CreateFont 函数的详细介绍
CreateFont proto \
nHeight:DWORD,\
nWidth:DWORD,\
nEscapement:DWORD,\
nOrientation:DWORD,\
nWeight:DWORD,\
cItalic:DWORD,\
cUnderline:DWORD,\
cStrikeOut:DWORD,\
cCharSet:DWORD,\
cOutputPrecision:DWORD,\
cClipPrecision:DWORD,\
cQuality:DWORD,\
cPitchAndFamily:DWORD,\
lpFacename:DWORD
nHeight: 希望使用的字体的高度,0为缺省。
nWidth: 希望使用的字体的宽度,一般情况下最好用0, 这样 Windows 将会自动为您选择一个和高度匹配的值。因为在我们的例子中那样做的话会使得字符因太小而无法显示,所以 我 们设定它为16。
nEscapement: 每一个字符相对前一个字符的旋转角度,一般设成0。900代表转90度,1800转190度,2700转270度。
nOrientation: 字体的方向。
nWeight: 字体笔画的粗细。
我们得到了指向逻辑字体的句柄后必须调用 SelectObject 函数把它选择进“设备环境”,我们还可以调用该函数把诸如此类的像颜色、笔、画刷 等GDI对象选进“设备环境”。该函数会返回一个旧的“设备环境”的句柄。您必须保存该句柄,以便在完成“绘制”工作后再把它选回。在调用 SelectObject 函数后一切的绘制函数都是针对该“设备环境”的。
调用 TextOut 在客户区用我们前面选定的字体和颜色“绘制”文本串
VC学习笔记10:一些字符串转化函数
Afx全局函数及MFC常见数据类型
AfxBeginThread:开始一个新的线程
AfxEndThread:结束一个旧的线程
AfxFormatString1:类似printf一般地将字符串格式化
AfxFormatString2:类似printf一般地将字符串格式化
AfxMessageBox:类似Windows API 函数 MessageBox
AfxOuputDebugString:将字符串输往除错装置
AfxGetApp:获得application object (CwinApp派生对象)的指针
AfxGetMainWnd:获得程序主窗口的指针
AfxGetInstance:获得程序的instance handle
MFC数据类型
下面这些是和Win32程序共同使用的数据类型
BOOL:布尔值,取值为TRUE or FALSE
BSTR:32-bit 字符指针
BYTE:8-bit整数,未带正负号
COLORREF:32-bit数值,代表一个颜色值
DWORD:32-bit整数,未带正负号
LONG:32-bit整数,带正负号
LPARAM:32-bit整数,作为窗口函数或callback函数的一个参数
LPCSTR:32-bit指针,指向一个常数字符串
LPSTR:32-bit指针,指向一个字符串
LPCTSTR:32-bit指针,指向一个常数字符串,此字符串可以移植到Unicode和DBCS
LPTSTR:32-bit指针,指向一个字符串,此字符串可以移植到Unicode和DBCS
LPVOID:32-bit指针,指向一个未指定类型的数据
LPRESULT:32-bit数值,作为窗口函数或callback函数的返回值
UINT:在Win16中是一个16-bit 未带正负号整数,在Win32中是一个32-bit 未带 正负号整数,
WNDPROC:32-bit指针,指向一个窗口函数
WORD:16-bit 整数 ,未带正负号
WPARAM:窗口函数或callback函数的一个参数,在Win16中是16-bit,在Win32中是32-bit
下面这些是MFC独特的数据类型
POSITION:一个数值,代表collection对象(例如数组或链表)中的元素位置,常 用于MFC collection classes(即数据处理类,如CArray)
LPCRECT:32-bit指针,指向一个不变的RECT结构
有用的字符串转化函数
atof(将字符串转换成浮点型数)
atoi(将字符串转换成整型数)
atol(将字符串转换成长整型数)
gcvt(将浮点型数转换为字符串,取四舍五入)
strtod(将字符串转换成浮点数)
strtol(将字符串转换成长整型数)
strtoul(将字符串转换成无符号长整型数)
tolower(将大写字母转换成小写字母)
toupper(将小写字母转换成大写字母) 有点意思
toascii(将整型数转换成合法的ASCII 码字符)
VC学习笔记11: HWND,HANDLE,HINSTANCE之间的区别
HWND - 窗体句柄
HINSTANCE - 程序实例
HANDLE - 窗体或其它控件句柄
例如:
HWND = FormHandle(HANDLE)   //可以从句柄获得它的HWND
HWND GetSafeHwnd( )           //获取当前窗体句柄
HWND FindWindow()              //获取当前窗体句柄
HINSTANCE = AfxGetResourceHandle()   //获取资源实例
HINSTANCE AfxGetInstanceHandle( );   //获取实例句柄
HANDLE   GetHandle()
VC学习笔记12:消息发送函数SendMessage、PostMessage和SendDlgItemMessage的区别
SendMessage用于向窗口发送消息,该函数说明如下:
LRESULT SendMessage(
HWND hWnd, //消息要发往的窗口的句柄
UINT Msg, //要发送的消息
WPARAM wParam, //消息的第一个参数
LPARAM lParam //消息的第二个参数
);
其中,hWnd为接收消息窗口的句柄,参数Msg指定发送的消息,参数wParam和lParam依赖于消息Msg。该函数调用目标窗口的窗口函数,直到目标窗口处理完该消息才返回。
PostMessage函数同SendMessage类似,它把消息放在指定窗口创建的线程的消息队列中,然后不等消息处理完就返回,而不象SendMessage那样必须等到消息处理完毕才返回。目标窗口通过GetMessage或PeekMessage从消息队列中取出并处理。PostMessage函数说明如下:
BOOL PostMessage(
HWND hWnd, //消息发往的窗口
UINT Msg, //要发送的消息
WPARAM wParam, //消息的第一个参数
LPARAM lParam //消息的第二个参数
);
其中,参数hWnd为接收消息的窗口的句柄,参数Msg指定所发送的消息,参数wParam和lParam依赖于消息Msg。
SendDlgItemMessage函数用于向对话框的某个控制发送消息,函数声明如下:
LONG SendDlgItemMessage(
HWND hDlg, //对话框句柄
int nIDDlgItem, //对话框控件的ID
UINT Msg, //要发送的消息
WPARAM wParam, //消息的第一个参数
LPARAM lParam //消息的第二个参数
);
其中,hDlg为包含目标控制的对话框的窗口句柄,参数nIDDlgItem为接收消息的对话框控制的整数标识符,参数Msg指定了所发送的消息,参数wParam和lParam提供附加的特定消息的信息。
wParam指定ID
MFC将这三个函数封装为CWnd类的成员函数,隐藏了窗口句柄和对话框句柄。这三个成员函数用于向本窗口发送消息,函数的说明如下:
LRESULT SendMessage( UINT message, WPARAM wParam = 0, LPARAM lParam = 0 );
BOOL PostMessage( UINT message, WPARAM wParam = 0, LPARAM lParam = 0 );
LRESULT SendDlgItemMessage( int nID, UINT message, WPARAM wParam = 0, LPARAM lParam = 0 );
类别:技术文档 | 浏览(47)
网友评论:
发表评论:
姓 名: *姓名最长为50字节
网址或邮箱: (选填)
内 容:
验证码: 请输入下图中的四位验证码,字母不区分大小写。
看不清?

"); //-->
©2007 Baidu