天天看點

實用!超強VC/MFC 常見問答收集

自編浏覽器進入一個網頁後,點一個連結後系統自動調用用IE打開網頁而不是用自身浏覽器打開網頁。如何讓視窗用我自己的浏覽器打開?

答:

控制新的視窗

預設情況下,浏覽器收到建立新視窗請求時,會在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);

}

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 , LPCTSTR p_lpszFormatString )

{

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;

}

問:如何在MDI環境下枚舉所有打開的視窗?

答:

In MFC, each CMDIChildWnd created by the framework is managed as a child window of the MDIClient window. This MDIClient window is a child of the mainframe window and fills its client area. For MDI applications, the mainframe window is encapsulated by the CMDIFrameWnd class. This class has a public embedded HWND member (m_hWndMDIClient), which is the handle to the MDIClient window. For MDI applications, AppWizard derives the CMainFrame class from CMDIFrameWnd.

The MDIClient maintains an internal list of child windows. In an MFC application, these child windows are either a CMDIChildWnd object or an internal window used to display the title of an iconized window. Note that this is an internal list controlled by Windows; don't make assumptions about the ordering of children in the list after an API function is called.

/

#define EXAMPLE_DIR "C:\\Newdir"

// Include Ifx.h for built-in InstallScript function prototypes.

#include "Ifx.h"

export prototype ExFn_DeleteDir(HWND);

function ExFn_DeleteDir(hMSI)

begin

// Create a directory.

if (CreateDir (EXAMPLE_DIR) != 0) then

// Report the error; then terminate.

MessageBox ("Unable to create directory.", SEVERE);

else

// Report success.

MessageBox (EXAMPLE_DIR + " was created.", INFORMATION);

// Delete the directory. If the directory is not

// empty, it is not deleted.

if (DeleteDir (EXAMPLE_DIR, ONLYDIR) = 0) then

// Report success.

MessageBox (EXAMPLE_DIR + " was deleted.", INFORMATION);

else

MessageBox ("Unable to delete directory.", SEVERE);

endif;

endif;

end;

問:怎樣動态顯示一個進度對話框呢? 我在主窗體裡面執行一個很耗時的計算過程,現在想啟動一個對話框,這個對話框中包含一個進度條,能夠動态顯示我的計算的進度,如何實作呢?

肯定是要用到多線程了?

答:

VC菜單“Project”->"Add components and controls"

有個進度條元件,基本上不要太大修改就可以,

問:怎樣把在ACCESS裡建立的報表在VC裡顯示出來

答:DAO對象不能直接通路Access報表和子產品,以及在查詢中使用這些對象。

在客戶機安裝了Access的情況下,可以自動化Access,然後把報表另存為HTML,之後用浏覽器控件或CHTMLView顯示

參見www.codeproject.com/database/access_reports_class.asp

http://codeguru.earthweb.com/Cpp/data/mfc_database/microsoftaccess/article.php/c1107/

問:為何我的ActiveX顯示位圖正常,但列印不正常。我開發了一個顯示位圖的控件,在插入到Word2000裡顯示圖形,顯示一切正常但列印時就巨小。我試着在OnDraw(CDC *pdc)裡在 if(pdc->IsPrinting()) 裡做放大處理,可是列印時pdc->IsPrinting() 傳回還是false,不起作用。我使用的是CPictureHolder顯示位圖。

答:不要用基于像素的映射模式,用基于實際尺寸的,列印機的像素大小和螢幕不一樣。看看你的邏輯坐标系的Y軸是不是反了

MM_HIMETRIC的Y軸方向和MM_TEXT不一樣的

問:

如何取得滑鼠位置的文字

比如滑鼠在記事本視窗上,并且在WORD的位置,我怎麼得到"word"

我知道可以得到NOTEPAD視窗的文字,但是如果打開的是10M的檔案,難道

我還要先複制到記憶體然後來找?

即使我知道了哪個緩沖區,又怎麼知道滑鼠指的是哪個字呢

DOS到好辦,WINDOWS下突然不知道咋辦了

________________________________

|無标題-1 |

--------------------------------

| how to get the word ... |

| $ |

| |

|______________________________|

答:Enabling Your Wish and the Needs of Others, Too

Dear Dr. GUI,

How can I grab the text that lies beneath the cursor, independent of the application that the text occurs in?

I am using Visual C++, and, ideally, I would like functionality similar to that found in VC's debugger: When the cursor is placed over a variable, information relevant to the variable is displayed in a box after a short delay, rather like a tool tip.

I have seen translation software give an immediate translation of the word under the cursor, irrespective of the application in which the word resides. How are they doing it? Is it done by using Optical Character Recognition (OCR)? Or is there a more elegant method using the Win32 API?

Thanks in advance,

Henry Brighton

Dr. GUI replies:

Wow, Henry. This turns out to be really interesting because currently there is no single Microsoft Win32&reg; API to get the text underneath the cursor for all Windows-based applications. However, you can get this information for most Windows applications by using the Microsoft Active Accessibility Software Development Kit (SDK).

This technology has been developed by Microsoft for people who have accessibility problems that affect their ability to utilize the standard computer. There are now accessibility aids such as screen review utilities, on-screen keyboard utilities, and so forth. Is this cool or what?

Active Accessibility is based on the Component Object Model (COM) and can be used to obtain or provide information about the system-provided UI elements of Windows applications and the operating system. Currently, it is fully supported on Windows 95, Windows 98, and Windows 2000, and partly supported on Windows NT 4.0 Service Pack 4 and later. The supported UI elements include:

Predefined controls (controls defined in User32.dll), such as list boxes.

Common controls (controls defined in Comctl32.dll), such as toolbars.

Window elements, such as title bars and menus.

Although the UI elements in applications such as Microsoft Office and Visual C++ are supported by this SDK, the Office document content is not.

To obtain more information about the Active Accessibility SDK and where to download its latest version, go to http://www.microsoft.com/enable/msaa/.

問:為什麼用CWnd::CreateControl在視圖中建立的控件子窗體不能顯示?

我的程式是這樣的:

void CCreateButtonView::OnRButtonDown(UINT nFlags, CPoint point)

{

CWnd m_ax;

LPCTSTR pszName = "MSDBGrid.DBGrid";

//控件的ProgID ,這裡我用的是DBGrid32.ocx

m_ax.CreateControl (pszName,NULL, WS_VISIBLE | WS_CHILD,

CRect(100,100,200,200), this, AFX_IDW_PANE_FIRST);

m_ax.ShowWindow(SW_SHOW);

CView::OnRButtonDown(nFlags, point);

}

想要實作的功能是:在View中右鍵單擊動态建立DBGrid.ocx控件的子窗體,通過調試發現沒有問題,建立成功,但就是不能将建立的控件顯示出來。

最奇怪的是,如果我在m_ax.ShowWindow(SW_SHOW);之後加上一句 AfxMessageBox("hehe");建立的子窗體居然能顯示出來了,請高手指點,這到底是怎麼回事啊?應該怎麼解決?多謝

答:CWnd::~CWnd會調用DestroyWindow。将CWnd m_ax;不定義為局部變量就ok了!

問:在ACTIVEX中開線程,是用_beginthreadEx還是用Afxbeginthread

我線上程中用到了不少c runtime 的函數,如strlen等等。按照道理似乎應該使用beginthreadEx,但是我的activex是用MFC開發的,這樣按照道理,似乎又應該使用Afxbeginthread。還有,如果我在項目設定裡選擇不使用mfc,整個程式正常運作。請問我到底該使用哪個函數。

beginthreadEx啟動的線程中不使用MFC就沒問題。否則還是用MFC的Afxbeginthread吧。MFC裡面大把的函數引用線程局部存儲的。

問:如何對基于對話框的MFC應用程式加入Accelerator,我已經添加了Accelerator資源,卻沒有作用

答:Q222829 HOWTO: Using Accelerator Keys Within a Modal Dialog Box

http://support.microsoft.com?kbid=222829

問:如何在檔案夾浏覽對話框中隻顯示映射檔案夾

答:SHGetSpecialFolderLocation/CSIDL_DRIVES

Custom Filtering

Under Microsoft&reg; Windows&reg; XP, SHBrowseForFolder supports custom filtering on the contents of the dialog box. To create a custom filter, follow these steps:

Set the BIF_NEWDIALOGSTYLE flag in the ulFlags member of the BROWSEINFO parameter structure.

Specify a callback function in the lpfn member of the BROWSEINFO parameter structure.

The callback function will receive BFFM_INITIALIZED and BFFM_IUNKNOWN messages. On receipt of the BFFM_IUNKNOWN message, the callback function's LPARAM parameter will contain a pointer to an instance of IUnknown. Call QueryInterface on that IUnknown to obtain a pointer to an IFolderFilterSite interface.

Create an object that implements IFolderFilter.

Call IFolderFilterSite::SetFilter, passing it a pointer to IFolderFilter. IFolderFilter methods can then be used to include and exclude items from the tree.

Once the filter is created, the IFolderFilterSite interface is no longer needed. Call IFolderFilterSite::Release if you have no further use for it.

see also

http://www.codeproject.com/dialog/cfolderdialog.asp

http://msdn.microsoft.com/msdnmag/issues/0800/c/default.aspx

http://msdn.microsoft.com/msdnmag/issues/02/01/c/default.aspx

http://msdn.microsoft.com/msdnmag/issues/0400/c/

http://msdn.microsoft.com/msdnmag/issues/04/03/CQA/default.aspx

問:現在有一個浮動的DialogBar工具條,如保去除其上的系統控制鈕,即狀态欄上的關閉按鈕

答:http://www.codeproject.com/docking/disabletoolbarclose.asp

問:用mfc建立了一個dll,dll裡有個對話框,但話框上的工具條沒有tooltip功能,該怎麼做?

答:代碼是在DLL還是在EXE并不是這個問題的關鍵。你需要從CFrameWnd中複制工具提示相關代碼。當然,如果對話框是非模态的,那麼你還需要用Hook來確定擷取滑鼠和鍵盤消息。

參考文檔

微軟知識庫文章Q233263 PRB: Modeless Dialog Box in a DLL Does Not Process TAB Key

問:為什麼我使用SAFEARRAY通過VB向VC程式傳遞字元串數組時總是不能成功啊?

答:Q207931 HOWTO: Pass Arrays Between Visual Basic and C

問:如何在我的程式中自動化Office?

答:Q196776 Office Automation Using Visual C++

參考文檔:

Q216388 FILE: B2CSE.exe Converts Visual Basic Automation Code to Visual C++

Q222101 HOWTO: Find and Use Office Object Model Documentation

Q185125 HOWTO: Invoke a Stored Procedure w/ADO Query using VBA/C++/Java

Q207931 HOWTO: Pass Arrays Between Visual Basic and C

Q238972 INFO: Using Visual C++ to Automate Office

問:如何使CTreeCtrl的節點即使沒有子節點也顯示+号? 像資料總管那樣?這樣就可以在Expand的時候加載其子節點

答:http://www.microsoft.com/msj/archive/S563.aspx

問:在CListCtrl中如何将LVS_EX_CHECKBOXES系統指定的風格換成自己的圖示。

即可以辨別為選中、未選中及目前指針位置所在項目

答:LVS_EX_CHECKBOXES的作用是添加一個包含兩個圖像的State Image List以及在滑鼠點選和盤操作的時候自動修改ItemState。

自定義方法是重設State Image List或者用Custom Draw自己畫State

問:dll中的對話框内ocx控件不能顯示,如何解決?

我試圖寫一個Share MFC DLL,在dll中包含一個屬性對話框,屬性對話框中的其中一個屬性頁包含一個vsflexgrid 7.0的控件,在運作時,當我選擇含有vsflexgri控件的屬性頁時,該頁立即消失,且屬性對話框中對應的tab也不見了。

答:DLL中需要的OLE的初始化最好在放在調用DLL的主應用程式中,而不要放在DLL中。參見Q154320 BUG: AfxOleInit Returns TRUE Without Initializing OLE in a DLL

問: 如何在VC中使用ADO将資料高效地從一個ACCESS資料庫移動到另一個ACCESS資料庫

答:Select Into/Insert into到連結表就可以了

Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1615185

[ 收藏到我的網摘] moon發表于 2007年05月18日 15:31:00 <link href="http://blog.csdn.net/xiaops2005/Services/Pingback.aspx" target="_blank" rel="external nofollow" rel="pingback"> <!--<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"xmlns:dc="http://purl.org/dc/elements/1.1/"xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/"><rdf:Descriptionrdf:about="http://blog.csdn.net/xiaops2005/archive/2007/05/18/1615185.aspx"dc:identifier="http://blog.csdn.net/xiaops2005/archive/2007/05/18/1615185.aspx"dc:title="實用!超強VC/MFC 常見問答收集"trackback:ping="http://tb.blog.csdn.net/TrackBack.aspx?PostId=1615185" /></rdf:RDF>-->function hide(){showComment();}

相關文章:

  • 在應用程式中內建自動完成功能 2003-09-10 jiangsheng
  • Win32 & .Net Q&A 200509 2005-09-13 jiangsheng
  • Jiangsheng的CSDN Digest (Dec 2005) 2005-12-24 jiangsheng
  • [翻譯]WTL開發者指南 第2章 Win32 SDK windowing 2005-05-30 uoyevoli
  • WINDOWS核心程式設計筆記(16-21) 2005-12-10 byxdaz