MFC富文本编辑框richedit插入图片ole对象问题
MFC富文本编辑框richedit插入图片ole对象问题
学习了三四天的一点成果,如果有不对的地方还请指出。
目前发现有两种方法来向richedit中插入ole对象:
1.直接粘贴,然后使用回调函数来控制即将插入的ole对象。
2.自己构造一个ole对象然后调用richedit的方法来插入。
MFC应该对richedit插入ole对象做了封装,只留了一个接口设置回调函数,然后在回调函数中对即将插入的ole对象进行处理。这种方法的广度还是很大的,可以直接获得ole对象中的所有数据,然后想怎么改就怎么改。但是问题是,这方面的文档实在是有点少,找来找去只找到了一个能用的例子,而且是简单的返回,没有做更多的操作。回调函数中的很多方法和结构体完全不知道怎么使用,于是尝试第二种方法。
大致思路是:先截图,然后从剪切板中读取位图数据,转换成CImage类型的图片,然后对图片进行缩放,构造ole对象,将其中的hBitmap替换成缩放图的hBitmap,最后插入richedit。我的做法只是能实现功能而已,很多地方并不规范,实现功能简单。如果有做过截图和ole的大佬,也希望能够指点一下。
大致源码如下:
CChatRichEditCtrl.h
class CChatRichEditCtrl : public CRichEditCtrl
{
CDisplayPicture* m_pDisplayPic = nullptr;//图片显示器类
bool m_bPastePic = false;//粘贴的是位图则屏蔽系统的ctrl+v
DWORD m_oleCnt = 0;
map<DWORD, CString> m_olePathMap;//粘贴到聊天框中的ole与原图的映射
public:
CChatRichEditCtrl() {/* AfxInitRichEdit(); AfxInitRichEdit2(); AfxOleInit(); /}
~CChatRichEditCtrl(){}
DECLARE_MESSAGE_MAP()
afx_msg void OnPaste();
afx_msg void OnPasteUpdateUI(CCmdUI pCmdUI);
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
virtual BOOL PreTranslateMessage(MSG* pMsg);
protected:
static DWORD CALLBACK readFunction(DWORD dwCookie,
LPBYTE lpBuf, // the buffer to fill
LONG nCount, // number of bytes to read
LONG* nRead); // number of bytes actually read
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);
};
IRichEditOle* m_pRichEditOle;
virtual void PreSubclassWindow();
public:
afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point);
};
CChatRichEditCtrl.cpp
#define ID_RICH_PASTE 104
BEGIN_MESSAGE_MAP(CChatRichEditCtrl, CRichEditCtrl)
ON_COMMAND(ID_RICH_PASTE, OnPaste)
ON_UPDATE_COMMAND_UI(ID_RICH_PASTE, OnPasteUpdateUI)
ON_WM_CREATE()
ON_WM_LBUTTONDBLCLK()
END_MESSAGE_MAP()
int CChatRichEditCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CRichEditCtrl::OnCreate(lpCreateStruct) == -1)
return -1;
ASSERT(m_pIRichEditOleCallback != NULL);
if (!m_bCallbackSet)SetOLECallback(m_pIRichEditOleCallback);AFX_MANAGE_STATE(AfxGetStaticModuleState());m_pDisplayPic = new CDisplayPicture;m_pDisplayPic->Create(IDD_DIALOG_DISPLAYPIC, this/*AfxGetMainWnd()*/);m_pDisplayPic->ShowWindow(SW_HIDE);
return 0;
}
BOOL CChatRichEditCtrl::PreTranslateMessage(MSG* pMsg)
{
// TODO: 在此添加专用代码和/或调用基类
if (pMsg->message == WM_KEYDOWN)
{
if(pMsg->wParam == 0x56 && GetAsyncKeyState(VK_CONTROL))
//0x56是’v’键,但是不知道为什么,直接写pMsg->wParam == 'v’不好使
{
m_bPastePic = false;
OnPaste();
if (m_bPastePic)
return TRUE;//屏蔽ctrl+v
}
}
return CRichEditCtrl::PreTranslateMessage(pMsg);
}
void CChatRichEditCtrl::OnPaste()
{
//对于图片,粘贴前需要进行处理
if (IsClipboardFormatAvailable(CF_DIB))
{
GLOBALHANDLE hGMem;
LPBITMAPINFO lpBI;
void* pDIBBits;
if (OpenClipboard())
{
hGMem = GetClipboardData(CF_DIB);
lpBI = (LPBITMAPINFO)GlobalLock(hGMem);
// point to DIB bits after BITMAPINFO object
pDIBBits = (void*)(lpBI + 1);
int width = 100 * lpBI->bmiHeader.biWidth / lpBI->bmiHeader.biHeight;
//缩略图高固定100,按比例计算缩略图宽,最大200
if (width > 200)
width = 200;
CRect abbpic(0,0, width,100);
CImage image, image1, image2;
if (m_pTeamWorkOpr)
{
CString path = L"C:\Users\Administrator\Desktop\新建文件夹";
image1.Load(path + L"system\\screenshot.bmp");//样图,提供格式,否则下面的GetBPP()函数错误,无法生成图片image.Create(abbpic.Width(), abbpic.Height(), image1.GetBPP());image2.Create(lpBI->bmiHeader.biWidth, lpBI->bmiHeader.biHeight, image1.GetBPP());::StretchDIBits(image2.GetDC(), 0, 0,lpBI->bmiHeader.biWidth,lpBI->bmiHeader.biHeight,0, 0, lpBI->bmiHeader.biWidth,lpBI->bmiHeader.biHeight,pDIBBits, lpBI, DIB_RGB_COLORS, SRCCOPY);//保存原图image2.Save(path + L"system\\oriscreenshot.png");string pathStr = StringWideToAnsi((path + L"system\\oriscreenshot.png").GetBuffer());//生成md5作为文件名另存文件,用于之后ole对象和图片的关联//生成md5用的第三方库,可以生成GUID代替md5做文件名string md5 = CalcFileMd5(pathStr);CString md5Name;md5Name = StringAnsiToWide(md5).c_str();CString md5Path;md5Path = path + L"system\\OriScreenShot\\" + md5Name + L".png";image2.Save(md5Path);HBITMAP bitmap2 = image2.Detach();image2.ReleaseDC();::StretchDIBits(image.GetDC(),abbpic.left, abbpic.top,abbpic.Width(), abbpic.Height(),0, 0, lpBI->bmiHeader.biWidth,lpBI->bmiHeader.biHeight,pDIBBits, lpBI, DIB_RGB_COLORS, SRCCOPY);//保存缩略图GlobalUnlock(hGMem);image.Save(path + L"system\\abbscreenshot.png");HBITMAP bitmap = image.Detach();image.ReleaseDC();CloseClipboard();STGMEDIUM stgm;stgm.tymed = TYMED_GDI;stgm.hBitmap = bitmap;//在这里将图片hBitmap换成缩略图的stgm.pUnkForRelease = NULL;FORMATETC fm;fm.cfFormat = CF_BITMAP;fm.ptd = NULL;fm.dwAspect = DVASPECT_CONTENT;fm.lindex = -1;fm.tymed = TYMED_GDI;IStorage* pStorage;LPLOCKBYTES lpLockBytes = NULL;SCODE sc = ::CreateILockBytesOnHGlobal(NULL, TRUE, &lpLockBytes);if (sc != S_OK) AfxThrowOleException(sc);ASSERT(lpLockBytes != NULL);sc = ::StgCreateDocfileOnILockBytes(lpLockBytes, STGM_SHARE_EXCLUSIVE | STGM_CREATE | STGM_READWRITE, 0, &pStorage);if (sc != S_OK){VERIFY(lpLockBytes->Release() == 0);lpLockBytes = NULL;AfxThrowOleException(sc);}ASSERT(pStorage != NULL);COleDataSource* pDataSource = new COleDataSource;pDataSource->CacheData(CF_BITMAP, &stgm);LPDATAOBJECT lpDataObject = (LPDATAOBJECT)pDataSource->GetInterface(&IID_IDataObject);LPOLECLIENTSITE lpClientSite;GetIRichEditOle()->GetClientSite(&lpClientSite);//创建OLE对象IOleObject* pOleObject;sc = OleCreateStaticFromData(lpDataObject, IID_IOleObject, OLERENDER_FORMAT,&fm, lpClientSite, pStorage, (void**)&pOleObject);if (sc != S_OK) AfxThrowOleException(sc);//插入OLE对象REOBJECT reobject;ZeroMemory(&reobject, sizeof(REOBJECT));reobject.cbStruct = sizeof(REOBJECT);CLSID clsid;sc = pOleObject->GetUserClassID(&clsid);if (sc != S_OK)AfxThrowOleException(sc);reobject.clsid = clsid;reobject.cp = REO_CP_SELECTION;reobject.dvaspect = DVASPECT_CONTENT;reobject.poleobj = pOleObject;reobject.polesite = lpClientSite;reobject.pstg = pStorage;reobject.dwUser = m_oleCnt++;//每次插入ole对象的索引,删除不做处理//REOBJECT obj;//obj.cbStruct = sizeof(obj);// if (GetPic(&obj))// {// long lStart, lEnd;// pTextIn1->GetSel(lStart, lEnd);// pTextIn1->SetSel(obj.cp, obj.cp + 1);// pTextIn1->Clear();// // pTextIn1->GetIRichEditOle()->InsertObject(&reobject);// // pTextIn1->SetSel(lStart, lEnd);// // }// else// {GetIRichEditOle()->InsertObject(&reobject);// }delete pDataSource;SendMessage(EM_SCROLLCARET, (WPARAM)0, (LPARAM)0);SetFocus();m_olePathMap.insert(make_pair(reobject.dwUser, md5Path));//关联ole和原图m_bPastePic = true;}}
}
}
void CChatRichEditCtrl::OnPasteUpdateUI(CCmdUI* pCmdUI)
{
pCmdUI->Enable(CanPaste());
}
DWORD CALLBACK CChatRichEditCtrl::readFunction(DWORD dwCookie,
LPBYTE lpBuf, // the buffer to fill
LONG nCount, // number of bytes to read
LONG* nRead) // number of bytes actually read
{
CFile* fp = (CFile*)dwCookie;
*nRead = fp->Read(lpBuf, nCount);
return 0;
}
CChatRichEditCtrl::IExRichEditOleCallback::IExRichEditOleCallback()
{
pStorage = NULL;
m_iNumStorages = 0;
m_dwRef = 0;
// set up OLE storageHRESULT hResult = ::StgCreateDocfile(NULL,STGM_TRANSACTED | STGM_READWRITE | STGM_SHARE_EXCLUSIVE /*| STGM_DELETEONRELEASE */ | STGM_CREATE,0, &pStorage);if (pStorage == NULL ||hResult != S_OK)
{AfxThrowOleException(hResult);
}
}
CChatRichEditCtrl::IExRichEditOleCallback::~IExRichEditOleCallback()
{
}
HRESULT STDMETHODCALLTYPE
CChatRichEditCtrl::IExRichEditOleCallback::GetNewStorage(LPSTORAGE* lplpstg)
{
m_iNumStorages++;
WCHAR tName[50];
swprintf_s(tName, L"REOLEStorage%d", m_iNumStorages);
HRESULT hResult = pStorage->CreateStorage(tName,STGM_TRANSACTED | STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE,0, 0, lplpstg);if (hResult != S_OK)
{::AfxThrowOleException(hResult);
}return hResult;
}
HRESULT STDMETHODCALLTYPE
CChatRichEditCtrl::IExRichEditOleCallback::QueryInterface(REFIID iid, void** ppvObject)
{
HRESULT hr = S_OK;
*ppvObject = NULL;if (iid == IID_IUnknown ||iid == IID_IRichEditOleCallback)
{*ppvObject = this;AddRef();hr = NOERROR;
}
else
{hr = E_NOINTERFACE;
}return hr;
}
ULONG STDMETHODCALLTYPE
CChatRichEditCtrl::IExRichEditOleCallback::AddRef()
{
return ++m_dwRef;
}
ULONG STDMETHODCALLTYPE
CChatRichEditCtrl::IExRichEditOleCallback::Release()
{
if (–m_dwRef == 0)
{
delete this;
return 0;
}
return m_dwRef;
}
HRESULT STDMETHODCALLTYPE
CChatRichEditCtrl::IExRichEditOleCallback::GetInPlaceContext(LPOLEINPLACEFRAME FAR* lplpFrame,
LPOLEINPLACEUIWINDOW FAR* lplpDoc, LPOLEINPLACEFRAMEINFO lpFrameInfo)
{
return S_OK;
}
HRESULT STDMETHODCALLTYPE
CChatRichEditCtrl::IExRichEditOleCallback::ShowContainerUI(BOOL fShow)
{
return S_OK;
}
HRESULT STDMETHODCALLTYPE
CChatRichEditCtrl::IExRichEditOleCallback::QueryInsertObject(LPCLSID lpclsid, LPSTORAGE lpstg, LONG cp)
{
//return E_NOTIMPL;
return S_OK;
}
HRESULT STDMETHODCALLTYPE
CChatRichEditCtrl::IExRichEditOleCallback::DeleteObject(LPOLEOBJECT lpoleobj)
{
return S_OK;
}
HRESULT STDMETHODCALLTYPE
CChatRichEditCtrl::IExRichEditOleCallback::QueryAcceptData(LPDATAOBJECT lpdataobj, CLIPFORMAT FAR* lpcfFormat,
DWORD reco, BOOL fReally, HGLOBAL hMetaPict)
{
return S_OK;
}
HRESULT STDMETHODCALLTYPE
CChatRichEditCtrl::IExRichEditOleCallback::ContextSensitiveHelp(BOOL fEnterMode)
{
return S_OK;
}
HRESULT STDMETHODCALLTYPE
CChatRichEditCtrl::IExRichEditOleCallback::GetClipboardData(CHARRANGE FAR* lpchrg, DWORD reco, LPDATAOBJECT FAR* lplpdataobj)
{
return E_NOTIMPL;//这里如果返回S_OK,则剪切板数据被拦截
}
HRESULT STDMETHODCALLTYPE
CChatRichEditCtrl::IExRichEditOleCallback::GetDragDropEffect(BOOL fDrag, DWORD grfKeyState, LPDWORD pdwEffect)
{
return S_OK;
}
HRESULT STDMETHODCALLTYPE
CChatRichEditCtrl::IExRichEditOleCallback::GetContextMenu(WORD seltyp, LPOLEOBJECT lpoleobj, CHARRANGE FAR* lpchrg,
HMENU FAR* lphmenu)
{
return S_OK;
}
void CChatRichEditCtrl::OnLButtonDblClk(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
LONG cnt = GetIRichEditOle()->GetObjectCount();
for (LONG i=0;i<cnt;i++)//判断双击中哪个ole对象
{
REOBJECT reobject;
ZeroMemory(&reobject, sizeof(REOBJECT));
reobject.cbStruct = sizeof(REOBJECT);
GetIRichEditOle()->GetObjectW(i, &reobject, REO_GETOBJ_NO_INTERFACES);
if (reobject.dwFlags &= REO_SELECTED)
//这里我只知道如果选中ole对象则会有REO_SELECTED标志,但我感觉选中ole对象和对ole对象的操作不是这么做的
{
if (m_pDisplayPic)
{
if (m_olePathMap.count(reobject.dwUser))
{
CString path = m_olePathMap[reobject.dwUser];
m_pDisplayPic->DisplayPic(path);
}
}
}
}
CRichEditCtrl::OnLButtonDblClk(nFlags, point);
}
CDisplayPicture.h
class CDisplayPicture : public CDialogEx
{
DECLARE_DYNAMIC(CDisplayPicture)
public:
CDisplayPicture(CWnd* pParent = nullptr); // 标准构造函数
virtual ~CDisplayPicture();
// 对话框数据
enum { IDD = IDD_DIALOG_DISPLAYPIC };
void DisplayPic(CString path);
bool m_bInit = false;
bool m_bDealCut = false;
int m_delX;
int m_delY;
CRect m_initStaticPicRect;
int m_initDlgWidth;
int m_initDlgHeight;
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
DECLARE_MESSAGE_MAP()
public:
CStatic m_picDisplayPic;
virtual BOOL OnInitDialog();
afx_msg void OnSize(UINT nType, int cx, int cy);
};
CDisplayPiture.cpp
IMPLEMENT_DYNAMIC(CDisplayPicture, CDialogEx)
- CDisplayPicture::CDisplayPicture(CWnd* pParent /=nullptr/)
-
CDialogEx(IDD_DIALOG_DISPLAYPIC, pParent)
{
}
CDisplayPicture::~CDisplayPicture()
{
}
void CDisplayPicture::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Control(pDX, IDC_STATIC_DISPLAYPIC, m_picDisplayPic);
}
BEGIN_MESSAGE_MAP(CDisplayPicture, CDialogEx)
ON_WM_SIZE()
END_MESSAGE_MAP()
// CDisplayPicture 消息处理程序
void CDisplayPicture::DisplayPic(CString path)
{
CRect rect;
m_picDisplayPic.GetClientRect(&rect);
CImage image;
image.Load(path);
HBITMAP hbitmap = image.Detach();
if (image.GetWidth()>rect.Width()||image.GetHeight()>rect.Height())
{
CImage image1;
image1.Create(rect.Width(), rect.Height(), image.GetBPP());
SetStretchBltMode(image1.GetDC(), COLORONCOLOR);
StretchBlt(image1.GetDC(), 0, 0, rect.Width(), rect.Height(), image.GetDC(), 0, 0, image.GetWidth(), image.GetHeight(), SRCCOPY);
hbitmap = image1.Detach();
image1.ReleaseDC();
image1.Destroy();
}
m_picDisplayPic.SetBitmap(hbitmap);
image.ReleaseDC();
image.Destroy();
ShowWindow(SW_SHOW);
}
BOOL CDisplayPicture::OnInitDialog()
{
CDialogEx::OnInitDialog();
// TODO: 在此添加额外的初始化
m_bInit = true;
CRect rect, crect;
m_picDisplayPic.GetClientRect(rect);
GetClientRect(crect);
m_initStaticPicRect = rect;
m_initDlgHeight = crect.Height();
m_initDlgWidth = crect.Width();
SendMessage(WM_SYSCOMMAND, SC_MAXIMIZE, 0);return TRUE; // return TRUE unless you set the focus to a control// 异常: OCX 属性页应返回 FALSE
}
void CDisplayPicture::OnSize(UINT nType, int cx, int cy)
{
CDialogEx::OnSize(nType, cx, cy);
// TODO: 在此处添加消息处理程序代码
if (m_bInit)
{CRect currect;GetClientRect(currect);int curheight = currect.Height();int curwidth = currect.Width();CRect rect;rect.top = m_initStaticPicRect.top;rect.bottom = m_initStaticPicRect.bottom * curheight / m_initDlgHeight;rect.left = m_initStaticPicRect.left * curwidth / m_initDlgWidth;rect.right = m_initStaticPicRect.right * curwidth / m_initDlgWidth;m_picDisplayPic.MoveWindow(rect);RedrawWindow();
}
}
希望能对第一次做richedit的人有帮助
MFC富文本编辑框richedit插入图片ole对象问题相关推荐
- 【学习记录贴】Vue+Element-UI富文本编辑框及插入图片
本贴会涉及以下几个技术点: Vue+Element-UI实现富文本编辑框,以及文本编辑框中事件拦截.插入图片 Element-UI限制上传图片后,隐藏上传按钮:官网上是没有这个方法的,可以通过上传到指 ...
- vue 封装调用 wangeditor v4.0富文本编辑框组件 v-model
背景 本机的环境使用的vue的脚手架,用到了富文本编辑框,所以选择将wangeditor封装为组件调用 wangeditor官网:https://www.wangeditor.com/ 在vue的项目 ...
- element-ui vue-quill-editor 富文本编辑器 解决插入图片不采用base64 从服务器传图片在显示返回url
vue-quill-editor默认的图片插入方式,是直接将图片转成base64编码,这样的结果是整个富文本的html片段十分冗余.我们的服务器端接收的post的数据大小都是有限制的,这样的话导致提交 ...
- tinymce富文本编辑框使用
引用 <link rel="stylesheet" href="./tinymce/skins/ui/oxide/skin.min.css" />& ...
- wangeditor 请求头_富文本编辑框wangEditor
由于项目需要,在网上找了个富文本编辑框wangEditor,抱着试一试的态度用了一下,原以为这款个人开发维护的插件会有不少bug,使用之后经过我们测试人员全方位的测试检验,基本符合需求,并且较之前使用 ...
- 解决sharepoint2010的多行文本框的插入图片—【从sharepoint】的disabled问题
大家发现sharepoint2010的多行文本框的插入图片有个-[从sharepoint]插入图片的功能,但是看到的disabled.如下图: 怎么办呢?通过查找资料才知道原来可以这样解决 在这里我们 ...
- qtabwidget设置tab高度_VC|富文本编辑框CRichEditCtrl的字体与段落设置
将富文本编辑框设置为2.0,关联一个control变量m_textblock: 1 字体设置 富文本编辑框关于字体设置的成员函数: BOOL CRichEditCtrl::SetSelectionCh ...
- JAVAFX如何在文本框内插入图片
JAVAFX如何在"文本框"内插入图片 TextBox.java TestUI.java TestUI运行展示 文本框默认样式 设置后的样式 思路:将图片(ImageView)及文 ...
- html5文本框里插图片文字,word应用教程:在文本框内插入图片
在使用word编辑电子文档时,可以通过插入功能插入图片,那么怎样才能在wps文字文档从插入可以任意移动的图片呢,那么下面就由学习啦小编给大家分享下word在文本框内插入图片的技巧,希望能帮助到您. w ...
最新文章
- 图像去噪的深度学习最新综述论文,36页pdf,Deep Learning on Image Denoising
- django 数据库迁移注意事项
- LYVC揭秘硅谷核心基金圈投资游戏规则
- MFC模块的动态链接库DLL以及静态链接库LIB编译后的调用
- PHP大文件上传问题
- 全站 HTTPS 就一定安全了吗?
- 计算机应用基础怎么教作业,北京语言大学网络教育2017春计算机应用基础作业(1)及答案...
- Linux指令not found
- android 谷歌邮箱,Android 使用 SMTP 发送邮件 (Gmail)
- Python实现二叉树
- Vmware esxi忘记密码重置方法
- mos 多路模拟电子开关_软开关设计 || 软开关硬件三极管、MOS管典型电路分析
- 怎么就没发现华为Mate20 pro有这么多神奇功能!这波黑科技盘它!
- uva 1339 题解
- 风变编程,帮助你从零开始学习编程
- SQL笔记(约束、外键、casewhen)
- 性别为什么不适合建立索引-值重复率高的字段不适合建索引
- 1072 开学寄语 (20 分)
- selenium实现163邮箱登录
- DW与JavaScript