版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、VC(MFC)编写串口调试助手1.序确定基本功能:1自动寻找串口,并自动添加到下拉框中共选择;2.有波特率、数据位、停止位、校验位的选择设置;3串口打开控制按钮;4. 发送、清除按钮;5. 接收是自动实现的;6. 有定时自动发送功能;7. 有传送文件功能;8. 有状态栏显示,指示串口状态,设置参数和发送接收显示。下面就一步步实现,本人纯业余,只是记录下来这个学习过程,请勿拍砖。开发平台Visual C+6.0 英文版,电脑是i7-2670Q 四核8G内存1G独显的笔记本,装的win7 64位旗舰版,因此 VC6兼容不是太好,有些小毛病,不过不影响编写。2.创建MFC项目File - New -
2、 Projects 选择 MFC AppWizard(exe) ,项目名称 commassistFiles Prujerfs:Olhtfr Dacunients |ZiAIL CUM AppWizardl3 Cl lister Hesouce lype Wizard|Cugtpm ZippWIzardl宙 Didsilji 昭 e PtdJklI$ DcvStudio AdiHiiW;细(1 豐 ISAPI Extension Wizard Makefile 旅 MM ActiveX ControlWisard tMFC /ppWl23fd (dll|Prejject ns trie: cDB
3、imasslsiLacaiion:fFCV?miinijiYwisr-MFC:血ppWI/HW |艸此t| Utility Riijttcl3Win32 Application二Win32 Cofisolc ApplicationiWin32 Dynamic-Link Library0Win 32 Siitlc Library* Create new workspccc C Add to current workspace厂 DepEndeitcy nilPlatfqrms. lWiri3?OKCancel选择OKWhat type ot application would you like
4、to create? ingle documentMultiple ducumenls+ Dialog basedp Dacument/Vjew architecture support?What language would you like your resources in? 中丈|简体中 BflAPPWZCHDLLj -FinishCancel1选中 Dialog based ,点击 Next默认选项,点击 NextMFC AppWizard - Step 3 of 4Ue廿StudiioFik EdvtiBircrt DviH HlprTTirrnmWhat style of pro
5、ject would you like ?i* MFC StandardC Windows ExplorerWould you like to generate source file comments?fi Yes, please No, thank youHow would you like to use the MFC library?As a shared DLLAs a statically linked libraryFinishCancel接在没装VC的机器上运行。可以在项目中进行更改。MFC AppWizard - tep 4 of 4AppWizsrd creates the
6、 following classes for vou:CCommassistDICCommassistAppClass name;Header file:CCommassistDIgcommassistDlg.hBase class:Implementation file:CDialog|commassistDlg+cppFinishCancel选择第二个 CCommassistDIg ,点击 FinishAppWizard will ere ate a new skeleton project with ihe following tpecificatiant:Appllcallan typ
7、e of commassist;Dialog-Based Application targeting: Win32Classes tn be created:Application: CCommsf;itA卩卩 in cnmmassist.h and cnmmassist.rp卩Dialog: CCtrFmasGisiOlg in cQmmaGictDIg. and commaGsictDIgRcppFeaturest Ahfliit hox nn system msnu 3D Controls* Ues stiared DLL ImplememaTion (MFC4?hDLL)* Adive
8、X Controls tuppod enabled Localizable taxi in:中女ft作.中国Projed Directory:E VCcomm a ss islQ 崑Cancel_J conimaBsist resources *_ _l Dialog 上 _jlcan、_jSMng Tskk* ! VcrBiflii点击OK。项目创建完毕,进入项目。X ennwiaitsift Micr&wh ViijaI 亡中re IDD COMMAS.STST DCALOG 口血戲|S file .dil 蚩ier石 Irsert Erojezi 且uild Laymul loots Z
9、i!irduw 吐*p逍Q 0|Q|JEW 曾|mrrtfix亦二l| 事C Corn rtisESiS-Oy (Wl 虽曲# iticrntiEr&l* CCnrrimfl s IstUIg耳 *I r i i -I I H |i I i i i I i r lik fl Ac b n aH Im I ri。乂唇 Fmd in Fig 1 FiKd: m Filtis 2 Eteflults /:斗h口#扌? 41囹EBra T FHn删除界面上确定和取消按钮以及静态文字。M corriMsiK Micr&Mh1 Vitdili-Ct * -】DO上DfFXAMlS?匚DIALOG :N3
10、ile Edit Jtj ent Ir&eTt E rcj-rdt puild Layout lt?c 5 Mfiirduvr tlclpH,茹曲 * mmnxtdt-*|CCommvSGietIMy,|用1 iJM总甘 ifiunibcTSil TI 打4曲审8召曰石10ji_J icornmaE-sisI resources _l Dialog? _jkini+ _j Slrtnfl Table+ J Versian三割Ib r I F ii i b II | I 1 jiI N i XJCa. Ul*矗 nK 4Q國ffi 熨巴LI a团 亘E c曉 Cl&s.x.ftglRE-so.r
11、r血 vTJ詈営1 =才吉LL血w X尸j淹Eiiii口Fund g Fj-Iips:-i J -Ltx- n3. 创建界面保存后便可以开始创建界面了。参考界面二X釦卜呂 0匚区世 耳吃0JMFHAMET rtCCanwwi ssislDIgJ| |AII daa-s mmbET5| v | n_open iDIMAINGtAMI * 2j Strlftg Tabl# r _VrliiFh-_jresotrees+ _| Dialog_j IconIDI_ICON_CLOSFIDI ICON OPENj IOn MAINFRAME+ _j Siring Table + _VersinnDtvi
12、ue. |stanJiird (32x3|IDR MAINFRAME 原为 MFC提供的图标,这里我直接改成自己的,生成EXE后将会显示这个图标。下面将帮助页面图标也改为自绘图标。. &rmrnR-nifit rcndiumfiR DialogHJDjtfioirTBax3| IUD_COMMlfcSSlST_D 白il_IC(MM_ClOSE mLICQN.OktM _J MIR IAAIMF WAMiE ih _jSUin| fabke m 二j Versionpirlure Prcpc血 t Gttitia) Ihyka |JO: IDC STATICr Uugbhd厂血巾卯厂 Tubu
13、lvipI tie I* IDv T卿;1创耐吧:GdrrPicture,然后选中右键看在打开按钮旁边加入自绘的打开和关闭图标:先加入工具条中的 属性,并如图将 Image选为默认的IDI_ICON_CLOSE。如下图厂侶口 IF * *花兰狂技匚| r +-oti#寻 idd2commassist_di_j Icon IDIJCOHCLOSC IDI ICON OPEN-Q idLmaimi-f Class Wizard 选择 Add Class - New ,名字 MyButton ,基类选择在头文件MyButto n.h中加入以下变量和函数定义:private:intm_Style; /
14、按钮形状(0-正常,1-当前,2-按下,3-锁定)bool b_lnRect; /鼠标进入标志CStringm_strText; / 按钮文字COLORREFm_ForeColor; 文本颜色COLORREF m_MouseI nColor;/鼠标进入时文本颜色COLORREFm_BackColor; 背景颜色COLORREFm_LockForeColor; / 锁定按钮的文字颜色CRect m_ButRect; / 按钮尺寸CFont* p_Font; / 字体void DrawButton(CDC *pDC);/ 画正常按钮/接口函数public:MyButto n();void SetT
15、ext(CStri ng str); /设置文字void SetForeColor(COLORREF color); / 设置文本颜色/设置背景颜色void SetBkColor(COLORREF color);/设置字体void SetTextFont(int FontHight,LPCTSTR FontName);在MyButton.cpp的构造函数中初始化变量:m_Style = 1; m_Style = 0;/ 按钮形状风格b_lnRect = false; /鼠标进入标志m_strText = _T();/按钮文字(使用默认文字)m_ForeColor = RGB(0,0,0);/
16、文字颜色(黑色)m_Mousel nColor = RGB(0,0,255); /鼠标进入时文字颜色 (蓝色)m_BackColor = RGB(230,230,230);m_BackColor = RGB(243,243,243);/背景色(灰白色)m_LockForeColor = GetSysColor(COLOR_GRAYTEXT);/ 锁定按钮的文字颜色p_Font = NULL;/ 字体指针用ClassWizard 添加下列消息函数:PreSubclassWi ndow();Drawltem();on MouseMove();On LButto nDow n();On LButto
17、 nU p();在各函数内加入代码:void MyButto n:PreSubclassWi ndow() / TODO: Add your specialized code here an d/or call the base classModifyStyle( 0, BS_OWNERDRAW );/设置按钮属性为自画式/PreSubclassWi ndow()在按钮创建前自动执仃,所以我们可以在其中做一些初始工作。/这里只做了一项工作,就是为按钮设置属性为“自绘”式,这样,用户在添加按钮后,就不需设置Owner draw”属性了。CButto n:PreSubclassWi ndow();
18、 void MyButto n:Drawltem(LPDRAWITEMSTRUCT IpDrawltemStruct)/ TODO: Add your code to draw the specified itemCDC *pDC = CDC:FromHa ndle( lpDrawltemStruct-hDC );m_ButRect = lpDrawltemStruct-rcltem;/ 获取按钮尺寸if( m_strText .I sEmpty()GetWindowText( m_strText );/ 获取按钮文本int n SavedDC = pDC-SaveDC();VERIFY( p
19、DC );DrawButton( pDC );/ 绘制按钮pDC-RestoreDC( nSavedDC );Drawltem()函数是一个关键函数,按钮的绘制工作就在这里进行,它的作用相当于对话框中的On Pai nt()函数和视图中的 On Draw()函数。/这里我做了三项工作:获取按钮尺寸、获取按钮文本、绘制按钮。其中绘制工作在自定义函数DrawButton()中完成。以下就是绘制过程:void MyButt on:DrawButto n(CDC *pDC)/调整状态if( m_Style=3 ) m_Style = 0;if( GetStyle() & WS_DISABLED )m_
20、Style = 3;/禁止状态/根据状态调整边框颜色和文字颜色COLORREF bColor, fColor;/bColor 为边框颜色,fColor 为文字颜色switch( m_Style )case 0: bColor = RGB(192,192,192); fColor = m_ForeColor; break;/ 正常按钮/鼠标进入case 1: bColor = RGB(255,255,255); fColor = m_ForeColor; break;时按钮/按下/锁定的case 2: bColor = RGB(192,192,192); fColor = m_MouselnCo
21、lor; break;的按钮case 3: bColor = m_BackColor; fColor = m_LockForeColor; break;按钮/绘制按钮背景CBrush Brush;Brush.CreateSolidBrush( m_BackColor );/ 背景刷pDC-SelectObject( &Brush );CPen Pen;Pen .CreatePe n(PS_SOLID, 3, bColor );pDC-SelectObject( &Pen);pDC-RoundRect(&m_ButRect,CPoint(1O,1O);/ 画圆角矩形/绘制按钮按下时的边框if(
22、m_Style!=2 )CRect Rect;Rect.SetRect( m_ButRect.left+1,m_ButRect.top+1,i_ButRect.right,m_ButRect.bottom );/画边框pDC-DrawEdge( &Rect, BDR_RAISEDINNER, BF_RECT );/绘制按钮文字pDC-SetTextColor( fColor );/ 画文字pDC-SetBkMode( TRANSPARENT );pDC-DrawText( m_strText, &m _ButRect, DT_SINGLELINE | DT_CENTER| DT_VCENTER
23、 | DT_END_ELLIPSIS);/绘制拥有焦点按钮的虚线框if( GetFocus()=this)CRect Rect;Rect.SetRect( m_ButRect.left+3, m_ButRect.top+2, m_ButRect.right-3,m_ButRect.bottom-2 );pDC-DrawFocusRect( &Rect );/ 画拥有焦点的虚线框/变量m_Style表征当前按钮状态,它的取值为:0-正常,1-当前,2-按下,3-锁定。不同状态下按钮的边框颜色和文字颜色有所不同。/m_Style的值在鼠标响应函数中进行修改。/绘制工作主要利用CDC类的绘图函数完成
24、,主要注意在m_Style不同取值下表现出来的差别。void MyButton:0nLButtonDown(UINT nFlags, CPoint point)/ TODO: Add your message han dler code here an d/or call defaultm_Style = 2;/重绘按钮In validate。;CButto n:O nLButto nDow n(n Flags, poi nt);/On LButto nDow n()函数是单击鼠标左键时的消息函数。这里只是重新绘制按钮,具体的单击响应应该在拥有按钮的对话框或视图中进行。void MyButto
25、 n:O nM ouseMove(UINT nFlags, CPoi nt poi nt)/ TODO: Add your message han dler code here an d/or call default if( !b_InRect | GetCapture()!=this )/ 鼠标进入按钮b_ln Rect = true;/设置进入标志SetCapture();/捕获鼠标m_Style = 2;/m_Style = 1;/设置按钮状态In validate();/重绘按钮 else/鼠标离开按钮if ( !m_ButRect.Ptl nRect(poi nt)b_lnRect
26、 = false;II清除进入标志ReleaseCapture();II释放捕获的鼠标m_Style = 1;m_Style = 0;II 设置按钮状态Invalidate();II 重绘按钮CButt on :O nM ouseMove( nFlags, poi nt);onM ouseMove()函数是鼠标移动消息函数,用于判定当前鼠标指针是否在按钮上。b_lnRect是个标志,为true表示鼠标指针进入了按钮区域,II此时要捕获鼠标,让鼠标命令传送给按钮。当鼠标指针离开按钮时,要清除b_lnRect标志,并且释放捕获的鼠标,让其它窗口可以接收鼠标命令。IIIn validate()函数用
27、于更新按钮,它会自动调用 Drawltem()函数重新绘制按钮。II设置条件的目的是仅在鼠标指针进入按钮和离开按钮时更新按钮,这样可以防止鼠标在按钮上移动时发生闪烁。void MyButto n:O nLButto nU p(UINT nFlags, CPoi nt poi nt)II TODO: Add your message han dler code here an dIor call default m_Style = 1;In validate();II重绘按钮CButto n:O nLButto nU p( nFlags, poi nt);/On LButt on Up()函数是
28、单击鼠标左键后弹起时的消息函数。这里也只是重绘按钮,这样能使按钮在按下和弹起时有所不同,使按钮看上去有动态效果。/接口函数是用CMyButton 类 定义的按钮修改颜色、字体和按钮文字的接口,由以下函数组成:/设置按钮文本void MyButt on:SetText(CStri ng str)m_strText = _T();SetWi ndowText(str);/设置文本颜色void MyButt on:SetForeColor(COLORREF color)m_ForeColor = color;In validate();/设置背景颜色 void MyButt on:SetBkColo
29、r(COLORREF color) m_BackColor = color;In validate();/设置字体(字体高度、字体名)void MyButton:SetTextFont(int FontHight,LPCTSTR FontName)if ( p_Font )delete p_Font;/ 删除旧字体p_Font = new CFont;p_Font-CreatePointFont( FontHight, FontName );/ 创建新字体SetFont( p_Font );/ 设置字体的析构函数/由于新字体由 new生成,必须显式回收,这项工作可以在 CMyButton 类
30、中进行:/*CMyButt on:CMyButto n()if ( p_Font )delete p_Font;/ 删除字体*/这样一个可设置颜色、字体的按钮类就做好了。使用时,先在对话框中放置好按钮,再用ClassWizard为按钮添加控制变量,/并且将变量的类型设置为CMyButton 。之后,可以用该变量调用接口函数设置按钮颜色和字体。OK,自定义按钮完成。63实现过程及代码:现在可以对按钮,EDIT框等控件添加变量,文字描述麻烦,上图。Mrssayc MaiE McrnucrVariabksPni|r?d-Automaliorn ActiveX Evr nls |Class Infoc
31、ominas&iGt|Can)iinasHclDligEX-VmmassittDIgh EX-UommassIsiDIg.tppConlrol IDs:CHECK ITXEXGOQLm hcck hcxrxCHFCK_HFKTXROOlm_chenk_hsxtxCOMCONTROLMyButtanm camcvntrolCOM LI STCCombaBaxm comlitEDIT_ F1LEPATHCSlfingm_s1rf:ilcPathEDIT- RXEDIfSIAmCSlringmsIriitatuGrDlT_STATUECFditir_CrditStatu5FDIT TIME口CSir
32、lnyiiisIrTImeftoir rxCStringstatTc iconCStaticm drllccnIDCTyPeMevnberCCCCCCCCCC nIDIDIDIDlbDIDJDcomm.cpp 编写内容如下#i nclude stdafx.h#in elude commassist.h#include commassistDIg.h#in clude comm.h char Con vertHexChar(char ch);HANDLE hCom;/ 串 口句柄CString strcomname;/ 串口名,如COM1bool ComIsOK;/串口打开状态标识,为真表示已打
33、开,否则未打开/=自动 寻 找串口函数/函数功能:通过扫描注册表来找出当前所有物理串口II输入参数:无/返回类型:无II说 明:若搜索成功,则每搜到一个串口便发送消息通知主对话框,并将串口号以WPARAM传递void Fi ndComm() /枚举当前系统中的串口LONG result = 0;HKEY key = NULL;result = RegOpenKeyEx(HKEY_LOCAL_MACHINE,/ 需要打开的主键的名称HARDWAREWDEVICEMAPWSERIALCOMM,/ 需要打开的子键的名称,设备串口0,/保留,必须设置为0KEY_READ,/安全访问标记,也就是权限&
34、key);/得到的将要打开键的句柄,当不再需要句柄,/必须调用 RegCloseKey 关闭它if( result )AfxMessageBox(无法获取串口,请确认是否安装并连接串口return;TCHAR portname250;/ 串口名TCHAR data250;DWORD portnamelen = 0;/ 串口名长度DWORD datalen = 0;int in dex = 0;while(1)/找完COM后跳出port namele n = 255;datalen = 255;result = RegE num Value(key,定一个标准项名in dex+,值的索引编号为零
35、port name,的一个缓冲区&port namele n,区长度的一个变量。字符数量/Long ,个已打开项的句柄,或者指/Long ,欲获取值的索引。注意第一个 /String ,用于装载位于指定索引处值名/Lo ng ,用于装载 IpValueName 缓冲/ 一旦返回,它会设为实际载入缓冲区的/Lo ng,未用;设为零/Lo ng ,用于装载值的类型代码的变量用于装载值数据的一个缓冲区,用于装载lpData缓冲区长度的NULL,NULL,(LPBYTE)data, /Byte,&datale n);/Long一个变量。/ 一旦返回,它会设为实际载入缓冲区的字符数量 if( resul
36、t ) break;/发送消息,WM_USER+1 为自定义消息,即找到串口的,并将串口号COMx通过 WPARAM参数传送给主对话框窗口:AfxGetMai nWnd()-m_hWnd,获得主对话框句柄(WPARAM)(LPCTSTR)data,类型转换:Se ndMessage(:AfxGetMai nWnd()-m_hWnd,WM_FOUNDCOMM,(WPARAM) (LPCTSTR)data,O);RegCloseKey(key);/ 调用 RegCloseKey 关闭打开键的句 柄/=自动寻找串口函数结束 =/= 串口打开函数=/功能:打开串口,将已打开的串口句柄赋值给hCom,给
37、出串口打开状态 ComIsOK,完成串口状态设置/输入参数:波特率,数据位,停止位,校验位/返回类型:无void Open Comm(i nt n Baud, int n Data, int n Stop, int n Cal)/串口号hCom = CreateFile ( strco mn ame,/允许读或写GENERIC_READ | GENERIC_WRITE,0,/独占方式NULL,OPEN_EXISTING,/打开而不是创建FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,重叠方式,用于异步通信NULL );if(hCom = INVALID
38、_HANDLE_VALUE)AfxMessageBox( 打开COM 失败,串口不存在或已被占用);ComIsOK = false;return;ComIsOK = true;SetCommMask(hCom, EV_TXEMPTY | EV_RXCHAR );/ 设置事件掩码,暂时没用上SetupComm(hCom,1024,1024);/设置输入缓冲区和输出缓冲区的大小都是1024COMMTIMEOUTS TimeOuts;/设定读超时TimeOuts.Readl ntervalTimeout = MAXDWORD;TimeOuts.ReadTotalTimeoutC on sta nt
39、= 0;TimeOuts.ReadTotalTimeoutMultiplier = 0;/设定写超时TimeOuts.WriteTotalTimeoutCo nsta nt = 500;TimeOuts.WriteTotalTimeoutMultiplier = 100;if(SetCommTimeouts(hCom, &TimeOuts) = false)CloseHa ndle(hCom);ComIsOK = false;return;/串口属性配置DCB dcb;GetCommState(hCom, &dcb);dcb.BaudRate=nBaud;dcb.BaudRate=9600;
40、/波特率为 9600dcb.ByteSize=nData;dcb.ByteSize=8; /每个字节为 8 位dcb.StopBits=nStop; dcb.StopBits=ONESTOPBIT;/1 位停止位dcb.Parity=nCal; /dcb. Parity=NOPARITY; /无奇偶检验位SetCommState(hCom, &dcb);PurgeComm(hCom,PURGE_TXCLEAR|PURGE_RXCLEAR);CloseHa ndle(hCom);ComlsOK = false;return;return;/=串口打开函数结束=/=串口关闭控制函数=void Cl
41、oseComm()CloseHa ndle(hCom);hCom = NULL;ComIsOK = false;/=串口关闭控制函数结束/=串口监听线程函数=UINT ThreadFu nc(LPVOID pParam)/定义指针指向主对/ CCommassistDIg* pdlg = (CCommassistDlg*)pParam;话框COMSTAT ComStat;DWORD dwErrorFlags;while(ComlsOK)DWORD dwBytesRead = 100;ClearCommError(hCom, &dwErrorFlags,&ComStat);dwBytesRead
42、= min (dwBytesRead,(DWORD)ComStat.cbl nQue);if(!dwBytesRead)Sleep(10);/continue;使用continue 时,打开串口后 CPU占用率非常高else :Se ndMessage(:AfxGetMai nWnd()-m_hWnd,WM_READCOMM,1,O);/发送消息,已读到return 0;/=串口监听线程函数结束=/=字符串转16进制显示=/字符串转16进制显示的函数/传入参数Data为字符串Blank_allow为空格允许标志,为真则代表允许加入空格/函数返回为CString的结果sResultCStri ng DisplayCStri ng2Hex(CStri ng Data, bool Bla nk_allow)CStri ng sResult;CStri ng sTemp;int Data_Le ngth;Data_Le ngth = Data.GetLe ngth();if (Data_Le ngth = 0) return ;char *pchar = new charData_Length;/ 用了 new 分配内存空间,要记得释放strn cpy(pchar,Data,Data_Le ngth);for(i nt
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 辽宁省大连市西岗区重点中学2025-2026学年第二学期第一次阶段性考试初三语文试题含解析
- 项目研发高效承诺书范文9篇
- 能源使用与优化管理指南
- 企业售后服务流程标准化手册
- 履行岗位职责承诺责任书3篇范文
- 客户服务满意保证承诺书(3篇)
- 质量管理体系认证实施全面指导手册
- 企业团队建设活动策划实施模板
- 企业安全管理员安全防范与紧急处置指导书
- 供应商评价及合作策略管理工具
- 《中国痛风诊疗指南(2025版)》
- 安全生产四防内容是什么
- 2025江苏省江阴市中考数学带答案详解(综合卷)
- 智能建造讲解课件
- 高空作业安全技术交底范文
- 名师作文课堂:如何写正反对比类议论文
- 四川华电三江新区 100MW200MWh 电化学储能电站项目环评报告
- 农药执法课件
- 口腔科重点专科建设汇报
- (正式版)DB44∕T 2675-2025 《心肌梗死中医健康管理技术规范》
- 代码特征提取-洞察及研究
评论
0/150
提交评论