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


  自编浏览器进入一个网页后,点一个链接后系统自动调用用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;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值