实用!超强VC/MFC 常见问答收集(上)

By | 04月15日
Advertisement


自编浏览器进入一个网页后,点一个链接后系统自动调用用IE打开网页而不是用自身浏览器打开网页。如何让窗口用我自己的浏览器打开?

http://www.csdn.net/develop/read_article.asp?id=21702
控制新的窗口
默认情况下,浏览器收到创建新窗口请求时,会在IE中打开新的窗口。你可以处理NewWindow2事件来在自己指定的窗口中打开请求的页面。

问:
如何枚举系统中视频捕获设备(摄像头)的设备名称
答:
以下代码来 自DirectX9 SDK中的AMCAP示例

// put all installed video and audio devices in the menus
//
void AddDevicesToMenu()
{
……
// enumerate all video capture devices
ICreateDevEnum *pCreateDevEnum=0;
hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
IID_ICreateDevEnum, (void **)&pCreateDevEnum);
if (hr != NOERROR)
{
ErrMsg(TEXT("Error Creating Device Enumerator" ));
return ;
}

IEnumMoniker *pEm=0;
hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEm, 0);
if (hr != NOERROR)
{
ErrMsg(TEXT("Sorry, you have no video capture hardware./r/n/r/n" )
TEXT("Video capture will not function properly." ));
goto EnumAudio;
}

pEm->Reset();
ULONG cFetched;
IMoniker *pM;

while (hr = pEm->Next(1, &pM, &cFetched), hr==S_OK)
{
IPropertyBag *pBag=0;

hr = pM->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pBag);
if (SUCCEEDED(hr))
{
VARIANT var;
var.vt = VT_BSTR;
hr = pBag->Read(L"FriendlyName" , &var, NULL);
if (hr == NOERROR)
{
AppendMenu(hMenuSub, MF_STRING, MENU_VDEVICE0 + uIndex,
W2T(var.bstrVal));

if (gcap.pmVideo != 0 && (S_OK == gcap.pmVideo->IsEqual(pM)))
bCheck = TRUE;

CheckMenuItem(hMenuSub, MENU_VDEVICE0 + uIndex,
(bCheck ? MF_CHECKED : MF_UNCHECKED));
EnableMenuItem(hMenuSub, MENU_VDEVICE0 + uIndex,
(gcap.fCapturing ? MF_DISABLED : MF_ENABLED));
bCheck = FALSE;

SysFreeString(var.bstrVal);

ASSERT(gcap.rgpmVideoMenu[uIndex] == 0);
gcap.rgpmVideoMenu[uIndex] = pM;
pM->AddRef();
}
pBag->Release();
}

pM->Release();
uIndex++;
}
pEm->Release();

问:
我目前使用 BCG 中的 CBCGPPropList 来实现某一个东西的属性,可是有一项数据特别大,大约500个字符,我希望能把这一项的高度调整可是不知道如何处理,不知道能单独调整其中一项吗

答:从CBCGPProp派生一个函数,重载OnEdit并在其中创建一个需要的大小的编辑框。最后Add自定义的prop类对象。具体实现可以参照CBCGPColorProp和CBCGPFontProp类的实现

问:我想实现一个功能,就是检测一个目录或文件,看它是否存在,如果不存在就创建这个目录或文件。
答:
可以用Win32文件查找来查找文件或者文件夹是否存在,也可以用PathFileExists来判断。GetFileAttributes和 PathIsDirectory可以用于判断文件是否是目录。创建文件可以用CreateDirectory或者 MakeSureDirectoryPathExists。

bool FileExists(CString FileName)
{
WIN32_FIND_DATA FindFileData;
HANDLE hFind;
bool FindFlag = false ;

hFind = FindFirstFile(FileName , &FindFileData);

if (hFind == INVALID_HANDLE_VALUE)
{
FindFlag = false ;
}
else
{
FindFlag = true ;
}
FindClose(hFind);
return FindFlag;
}
DWORD dwFlag = GetFileAttributes(pathname);
if ( 0xFFFFFFFF == dwFlag ) 不存在;
if ( FILE_ATTRIBUTE_DIRECTORY & dwFlag ) 是文件夹
else 是文件

问:
请教一下,html中如果已知Activex的classid,有什么办法可以直接找到它? 通过id来查找比较慢,所以问一下可否通过这种方式?取得IOleObject之后,我需要如何做才可以调用Activex控件中的函数呢?
答:
由于控件所在容器是HTMLDocument对象,你可以用IOleContainer::EnumObjects枚举里面的OLE对象,包括控件和框架

IOleContainer* pContainer;

// Get the container
HRESULT hr = pHtmlDoc2->QueryInterface(IID_IOleContainer,
(void **)&pContainer);
lpDisp->Release();

if (FAILED(hr))
return hr;

IEnumUnknown* pEnumerator;

// Get an enumerator for the frames
hr = pContainer->EnumObjects(OLECONTF_EMBEDDINGS, &pEnumerator);
pContainer->Release();

if (FAILED(hr))
return hr;

IUnknown* pUnk;

ULONG uFetched;

// Enumerate and refresh all the frames
for (UINT i = 0; S_OK == pEnumerator->Next(1, &pUnk, &uFetched); i++)
{
// QI for IOleObject here to see if we have an embedded browser
IOleObject* pOleObject;

hr = pUnk->QueryInterface(IID_IOleObject, (void **)&pOleObject);
pUnk->Release();

if (SUCCEEDED(hr))
{
CLSID clsID;
pOleObject->GetUserClassID(&clsID);
}
}

pEnumerator->Release();

控件的IOleObject接口是用来查询控件的CLSID的。你应该查询控件的IDispatch接口,然后按照http://www.csdn.net/develop/read_article.asp?id=14752 里面的方法调用其属性和方法。

问:
已知PIDL怎么得到他对应的IShellFolder指针呢
答:用SHBindtoParent就可以了

IShellFolder *psfParent; //A pointer to the parent folder object's IShellFolder interface
LPITEMIDLIST pidlItem = NULL; //the item's PIDL
LPITEMIDLIST pidlRelative = NULL; //the item's PIDL relative to the parent folder
STRRET str; //the display name's STRRET structure
TCHAR szDisplayName[MAX_PATH]; //the display name's string

HRESULT hres = SHBindToParent(pidlItem, IID_IShellFolder, &psfParent, &pidlRelative);
if (SUCCEEDED(hres))
{
psfParent->GetDisplayNameOf(pidlRelative, SHGDN_NORMAL, &str);
psfParent->Release();
StrRetToBuf(&str, pidlItem, szDisplayName, ARRAYSIZE(szDisplayName));
}

问:如何handle IE的textsize changed event? 我想在用户改变text size 时做些处理,请问该如何handle,在哪个事件中做?谢谢指教。
答:sink HtmlDocument对象的IOleCommandTaget接口。

问: IStream *pStream; CString mString; 怎么样才能把pStream的内容赋给mString呢?
答:下面的代码把一个内存流读到字节数组。你可以根据字符串的类型把字节数组转化成字符串。

COleStreamFile osfRead;
osfRead.Attach(pStream);
long lLength=osfRead.GetLength();
CByteArray baBuf;
baBuf.SetSize(lLength);
osfRead.Read(baBuf.GetData(),lLength);

问:我Create了一个ListControl用来显示文件列表?怎么实现有图标的文件显示阿?
答:SHGetFileInfo可以返回系统图像列表,里面包含每一种文件类型的图标。参见http://www.csdn.net/develop/read_article.asp?id=22243
问题:如何编写无界面的HTML解析器?
答:walkall示例就是一个无界面的HTML解析器。
http://msdn.microsoft.com/downloads/samples/internet/browser/walkall/default.asp
问:用AfxBeginThread创建的线程除了调用AfxEndThread还可以用什么函数关闭?
答:
可以从外部用事件通知来优雅地结束线程
启动线程m_pThreadWrite=AfxBeginThread(ThreadProc,(LPVOID)this);
线程体。为了避免在静态函数中引用对象指针的麻烦,调用对象参数的线程体成员函数。

UINT CMyClass::ThreadProc(LPVOID lp)
{
CMicrophoneInput* pInput = (CMicrophoneInput*)lp;
return pInput->Run();
}
简单的循环检测退出标志
UINT CMyClass::Run()
{
HRESULT hr;
if (!InitInstance())
{
TRACE("InitInstance failed/r/n" ;
return ExitInstance();
}
while (!IsKilling())
{
//do something
}
return ExitInstance();
}
重设退出标志
BOOL CMyClass::InitInstance()
{
m_eventKill.ResetEvent();
m_eventDead.ResetEvent();
//do something
return TRUE
}
设已退出标志
UINT CMyClass::ExitInstance()
{
//do something
m_eventDead.SetEvent();
return 0;
}

检查退出标志

BOOL CMyClass::IsDead()
{
return WaitForSingleObject(m_eventDead, 0) == WAIT_OBJECT_0;
}
BOOL CMyClass::IsKilling()
{
return WaitForSingleObject(m_eventKill, 0) == WAIT_OBJECT_0;
}

在外部可以这样终止线程

//check if dead
if (!IsDead()&&m_pThreadWrite!=NULL){
m_eventKill.SetEvent();
WaitForSingleObject(m_eventDead,INFINITE);
m_pThreadWrite=NULL;
}

问:怎么实现IEnumString接口?
答:http://www.codeproject.com/wtl/customautocomplete_wtl.asp
IAutoComplete and custom IEnumString implementation for WTL dialogs
下面是我的基于数据库的IEnumString实现

if !defined(AFX_ENUMSTRING_H__4D5D61AD_CD0D_477C_880F_8E5EEB5B1E8F__INCLUDED_)
#define AFX_ENUMSTRING_H__4D5D61AD_CD0D_477C_880F_8E5EEB5B1E8F__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// EnumString.h : header file
//

//////////////////////////////////////////////////////////
// CEnumString command target
#include <shldisp.h>
#include "esuihelper.h"
class _ES_UI_EXPORT CEnumString : public IEnumString
{
public :
CEnumString(); // protected constructor used by dynamic creation
// Attributes
public :
ULONG m_nRefCount;
// Operations
public :
STDMETHODIMP_(ULONG ) AddRef();
STDMETHODIMP_(ULONG ) Release();
STDMETHODIMP QueryInterface(REFIID riid, void ** ppvObject);
STDMETHODIMP Next(ULONG celt, LPOLESTR* rgelt, ULONG * pceltFetched);
STDMETHODIMP Skip(ULONG celt);
STDMETHODIMP Reset(void );
STDMETHODIMP Clone(IEnumString** ppenum);
BOOL Bind(HWND p_hWndEdit, DWORD p_dwOptions = 0, LPCTSTR p_lpszFormatString = NULL);
VOID Unbind();
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CEnumString)
//}}AFX_VIRTUAL

// Implementation
protected :
virtual ~CEnumString();
CComPtr<IAutoComplete> m_pac;
BOOL m_fBound;
// Generated message map functions
//{{AFX_MSG(CEnumString)
// NOTE - the ClassWizard will add and remove member functions here.
//}}AFX_MSG

};

/////////////////////////////////////////////////////////////

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_ENUMSTRING_H__4D5D61AD_CD0D_477C_880F_8E5EEB5B1E8F__INCLUDED_)
// EnumString.cpp : implementation file
//

#include "stdafx.h"
#include "EnumString.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////
// CEnumString

CEnumString::CEnumString()
{
m_fBound = FALSE;
m_nRefCount = 0;

}

CEnumString::~CEnumString()
{

}
/////////////////////////////////////////////////////////////
// CEnumString message handlers
ULONG FAR EXPORT CEnumString::AddRef()
{
TRACE_LINE("CEnumString::AddRef/n" );
return ::InterlockedIncrement(reinterpret_cast <LONG *>(&m_nRefCount));
}

ULONG FAR EXPORT CEnumString::Release()
{
TRACE_LINE("CEnumString::Release/n" );
ULONG nCount = 0;
nCount = (ULONG ) ::InterlockedDecrement(reinterpret_cast <LONG *>(&m_nRefCount));

if (nCount == 0)
delete this ;

return nCount;

}

HRESULT FAR EXPORT CEnumString::QueryInterface(
REFIID riid, void FAR* FAR* ppvObject )
{
HRESULT hr = E_NOINTERFACE;

if (ppvObject != NULL)
{
*ppvObject = NULL;

if (IID_IUnknown == riid)
*ppvObject = static_cast <IUnknown*>(this );

if (IID_IEnumString == riid)
*ppvObject = static_cast <IEnumString*>(this );

if (*ppvObject != NULL)
{
hr = S_OK;
((LPUNKNOWN)*ppvObject)->AddRef();
}

}
else
{
hr = E_POINTER;
}

return hr;
}

STDMETHODIMP CEnumString::Next(ULONG celt, LPOLESTR* rgelt, ULONG * pceltFetched)
{
return E_NOTIMPL;
}

STDMETHODIMP CEnumString::Skip(ULONG celt)
{
return E_NOTIMPL;
}

STDMETHODIMP CEnumString::Reset(void )
{
return E_NOTIMPL;
}
STDMETHODIMP CEnumString::Clone(IEnumString** ppenum)
{
if (!ppenum)
return E_POINTER;

CEnumString* pnew = new CEnumString;
pnew->AddRef();
*ppenum = pnew;
return S_OK;
}
BOOL CEnumString::Bind(HWND p_hWndEdit, DWORD p_dwOptions /*= 0-*/ , LPCTSTR p_lpszFormatString /*= NULL*/ )
{
if ((m_fBound) || (m_pac))
return FALSE;
HRESULT hr = S_OK;

hr = m_pac.CoCreateInstance(CLSID_AutoComplete);
if (SUCCEEDED(hr))
{

if (p_dwOptions)
{
CComQIPtr<IAutoComplete2> pAC2(m_pac);

ATLASSERT(pAC2);
hr = pAC2->SetOptions(p_dwOptions); // This never fails?
pAC2.Release();

}

hr = m_pac->Init(p_hWndEdit, this , NULL, (LPOLESTR)p_lpszFormatString);
if (SUCCEEDED(hr))
{
m_fBound = TRUE;
return TRUE;
}
}
return FALSE;
}
VOID CEnumString::Unbind()
{

if (!m_fBound)
return ;

ATLASSERT(m_pac);

if (m_pac)
{
m_pac.Release();
m_fBound = FALSE;

}
}
#include "../esuihelper/EnumString.h"
#include "DataType.h"
class CDataType;
class _ES_DATATYPE_EXPORT CEnumDataType : public CEnumString
{
public :
CEnumDataType(LPCTSTR lpszDataType);
virtual ~CEnumDataType();
CDataType* m_pDataType;
protected :
CString m_strDataType;
STDMETHODIMP Next(ULONG celt, LPOLESTR* rgelt, ULONG * pceltFetched);
STDMETHODIMP Skip(ULONG celt);
STDMETHODIMP Reset(void );
STDMETHODIMP Clone(IEnumString** ppenum);
ado20::_RecordsetPtr m_pRecordset;
};
CEnumDataType::CEnumDataType(LPCTSTR lpszDataType)
: m_strDataType(lpszDataType)

{
m_pDataType = g_pDataTypeManager->GetDataType(m_strDataType);
ASSERT(m_pDataType);
m_pRecordset.CreateInstance("ADODB.Recordset" );
try
{
if (m_pRecordset != NULL)
{
if ( m_pRecordset->State&adStateOpen)
{
return ;
}
}
ESRecordsetOpen((LPCTSTR )m_pDataType->m_strSQLAutoComplete, _variant_t((IDispatch *)g_connection, true ),
m_pRecordset, adOpenDynamic, adLockOptimistic, adCmdUnspecified);

m_pRecordset->Requery(adCmdUnknown);
if (m_pRecordset->BOF == VARIANT_FALSE)
m_pRecordset->MoveFirst();
}
catch (_com_error &e)
{
ESErrPrintProviderError(g_connection);
ESErrPrintComError(e);
}
}

CEnumDataType::~CEnumDataType()
{
try
{
if (m_pRecordset != NULL)
{
if ( m_pRecordset->State&adStateOpen)
{
m_pRecordset->Close();
}
}
}
catch (_com_error &e)
{
ESErrPrintProviderError(g_connection);
ESErrPrintComError(e);
}
}
STDMETHODIMP CEnumDataType::Next(ULONG celt, LPOLESTR* rgelt, ULONG * pceltFetched)
{
if (m_pRecordset == NULL) return OLE_E_BLANK;

HRESULT hr = S_FALSE;
ZeroMemory(rgelt, sizeof (OLECHAR*) * celt);
try
{
if (!celt) celt = 1;
for (ULONG i = 0; i < celt; i++)
{
if (m_pRecordset->EndOfFile == VARIANT_TRUE)
break ;
_bstr_t bstrText =
(LPCTSTR )g_GetValueString(
m_pRecordset->Fields->Item[(LPCTSTR )m_pDataType->m_strAutoCompleteField]->Value);
if (bstrText.length() > 0)
{
rgelt[i] = OLESTRDUP(bstrText);
if (pceltFetched)
*pceltFetched++;
}
m_pRecordset->MoveNext();
}
if (i == celt)
hr = S_OK;
}
catch (_com_error &e)
{
ESErrPrintProviderError(g_connection);
ESErrPrintComError(e);
return e.Error();
}
return hr;
}
STDMETHODIMP CEnumDataType::Skip(ULONG celt)
{
if (m_pRecordset == NULL) return OLE_E_BLANK;
try
{
m_pRecordset->Move(celt, (long )adBookmarkCurrent);
}
catch (_com_error &e)
{
ESErrPrintProviderError(g_connection);
ESErrPrintComError(e);
return e.Error();
}
return S_OK;
}
STDMETHODIMP CEnumDataType::Reset(void )
{
if (m_pRecordset == NULL) return OLE_E_BLANK;
try
{
m_pRecordset->Requery(adCmdUnknown);
if (m_pRecordset->BOF == VARIANT_FALSE)
m_pRecordset->MoveFirst();
}
catch (_com_error &e)

{
ESErrPrintProviderError(g_connection);
ESErrPrintComError(e);
return e.Error();
}
return S_OK;
}
STDMETHODIMP CEnumDataType::Clone(IEnumString** ppenum)
{
if (!ppenum)
return E_POINTER;

CEnumDataType* pnew = new CEnumDataType(m_strDataType);
pnew->AddRef();
*ppenum = pnew;
return S_OK;
}

Similar Posts:

  • [VC/MFC]给对话框贴上背景图片

    给对话框贴上背景图,一般的方法就是在对话框的OnPaint中加载位图(bmp),下面给出一个实例: CPaintDC dc(this); // device context for painting CRect rect; GetClientRect(&rect);//得到窗体的大小 CDC dcMem; dcMem.CreateCompatibleDC(&dc); CBitmap bmpBackground; bmpBackground.LoadBitmap(IDB_BK);//加载背景

  • Debian上配置vsftpd常见问答集锦

    vsftpd用户配置 添加用户ftpuser,用户目录指定为/var/www/ftpuser,且此用户不能登陆系统. #mkdir /var/www/ftpuser #useradd -s /sbin/nologin -d /var/www/ftpuser ftpuser #passwd ftpuser #chown -R ftpuser:ftpuser /var/www/ftpuser vsftpd与/bin/false./sbin/nologin 使用debian做ftp服务器 http:/

  • Fedora和Red Hat Enterprise Linux实用指南(第6版)(上、下册)( 入行必读的Linux圣经)

    Fedora和Red Hat Enterprise Linux实用指南(第6版)(上.下册)( 入行必读的Linux圣经) (美)苏贝尔(SobellL,M.G.)著 李洋等译 ISBN 978-7-121-19333-0 2013年1月出版 定价:198.00元 1308页 16开 编辑推荐 首屈一指的Fedora和RHEL的参考资源:学习和工作的最佳参考 全面掌握Linux管理和安全:采用基于GUI的图形化工具.命令行以及Perl脚本语言 搭建重要的Internet服务器:一步一步第搭建示例

  • VC/MFC的HDC,CDC,CWindowDC,CClientDC,CPaintDC详解:

    VC/MFC的HDC,CDC,CWindowDC,CClientDC,CPaintDC详解: 首先说一下什么是DC(设备描述表) 解:Windows应用程序通过为指定设备(屏幕,打印机等)创建一个设备描述表(Device Context, DC)在DC表示的逻辑意义的"画布"上进行图形的绘制.DC是一种包含设备信息的数据结构,它包含了物理设备所需的各种状态信息.Win32程序在绘制 图形之前需要获取DC的句柄HDC,并在不继续使用时释放掉. 在c++ 编程中常会见到HDC,CDC,CC

  • VC++/MFC 源码下载

    首页 > 程序资料 > VC++/MFC 源码下载 GUI界面处理源码: 列表框(ListBox)控制 » 2007-02-26 Drag and Drop Listbox Items Without OLE - 不使用 OLE 直接拖放 ListBox Items » 2000-06-12 Property Listbox 属性列表框 » 2000-02-11 A Dual ListBox Selection Manager - 双列表选择管理器 GUI界面处理源码: 列表视(ListVie

  • VC++MFC 窗口最大化、最小化的实现!

    VC++MFC 窗口最大化.最小化的实现! 当利用AppWizard生成运用程序框架时,VC++已经为我们在标题条上做好了最大化,最小化及恢复按钮. 但有时我们也想在其它地方使用这些功能.这就可采用下面的办法. 在指定的消息处理函效中加入下列语句,则程序在收到该条消息后即执行窗口最小化. WINDOWPLACEMENT lwndpl; WINDOWPLACEMENT * lpwndpl; lpwndpl = &lwndpl; GetWindowPlacement(lpwndpl); lpwndp

  • 关于对于VC/MFC/ATL的评论问题 (转)

    关于对于VC/MFC/ATL的评论问题 (转)[@[email protected]]关于对于VC/MFC/ATL的评论问题,其实我很早就想写一篇文章来阐述自己的观点,不过又觉得这种容易引发论战的文章实际上是在空耗大家的时间, 不如做点实际工作. 但是现在中国程序员群体的思想走向已经到了一种非常危险的一边倒的地步,上几期电脑报上登出了几名14岁的小孩子, 刚刚学会写几个程序, 就把VC列为自己的梦想. 我去年找工作的时候,连续被几个公司问会不会VC,得到我的答复之后,他们怎么也不能相信一个学了四年C,两年多C++,还利

  • VC/MFC保证系统只有一个实例在运

    VC/MFC项目开发--保证系统只有一个实例在运行 在项目开发中,为了保证系统一致性或者安全性,经常要求系统在一个时刻在同一台机器上只能运行一个实例.可以通过以下方式实现(示例代码): 1)在InitInstance()函数中添加如下代码: CString m_pszName(_T("OnlyOne")); HANDLE m_hMutex = ::CreateMutex(NULL,TRUE,m_pszName); if (GetLastError() = = ERROR_ALREADY

  • VC/MFC之ListCtrl控件使用经验总结(一)(

    VC/MFC之ListCtrl控件使用经验总结(一)(2009-04-16 15:40:44) 标签:vc/mfc listctrl clistctrl 控件 使用 经验 总结 it 分类:软件开发 VC/MFC之ListCtrl控件使用经验总结 作者:lixiaosan 时间:04/06/2006 以下未经说明,listctrl默认view 风格为report 相关类及处理函数 MFC:CListCtrl类 SDK:以 "ListView_"开头的一些宏.如 ListView_Ins

  • (他山之石)MFC学习之路(一)VC MFC程序,在About对话框中获取并显示程序的版本号

    VC MFC程序,在About对话框中获取并显示程序的版本号 ================================================= 本文为HeYuanHui原作 转载必须确保本文完整并完整保留原作者信息及本文原始链接! NN: khler E-mail: [email protected] QQ: 23381103 MSN: [email protected] ================================================= 用VC++

Tags: