January 19, 2009

More explanation of CoInitialize() and CoUninitialize()

In this article, I'll not talk about how it works about the COM's apartment model, but the coding practice.

CoInitializeEx() provides the same functionality as CoInitialize() except it provides a parameter to specify the thread's apartment model. So, MSDN recommands us to call CoInitializeEx() instead of CoInitialize().

For using CoInitializeEx(), we also need to follow the same rules as CoInitialize(), I mentioned in the previous article.

The following examples explain how to use CoInitializeEx() and CoUninitialize():

Example #1: CoInitializeEx() will return S_FALSE if the COM library was loaded.

void main()
{
  HRESULT hr = E_FAIL;

  // The first call
  hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); // hr = S_OK

  // The second call
  hr = CoInitialize(NULL); // hr = S_FALSE, CoInitialize(NULL) = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED)

  // ... skip ...

  // For the second call
  CoUninitialize();

  // For the first call
  CoUninitialize(); // COM library will be unloaded
}

Example #2: CoInitializeEx() will return RPC_E_CHANGED_MODE if a previous call to CoInitializeEx() specified a different apartment model

void main()
{
  HRESULT hr = E_FAIL;

  // The first call
  hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); // hr = S_OK

  // The second call
  hr = CoInitializeEx(NULL, COINIT_MULTITHREADED); // hr = RPC_E_CHANGED_MODE, the thread's apartment model is still the single thread apartment.

  // ... skip ...

  // NOTE: We do not need to call CoUninitialize() if the corresponding call made by CoInitializeEx() returns error.

  // For the first call
  CoUninitialize(); // COM library will be unloaded
}

January 18, 2009

A clear explanation of CoInitialize() and CoUninitialize()

As you know, when you are using DirectShow or the other COM-based components, the first thing you have to do is calling CoInitialize() to initialize the COM library.

Furthermore, there are several rules you should follow. Now, I will give you a clear explanation here.

Rule #1: For each thread, you have to call CoInitialize() before you call any of the COM library funtions except CoGetMalloc() and the memory allocation functions.

Rule #2: For each successful call made by CoInitialize(), you have to call CoUninitialize() to free the COM library.

Rule #3: Do not call CoInitialize() or CoUninitialize() from the DllMain() function.

Rule #4: The first thread in the application that calls CoInitialize() must be the last thread to call CoUninitialize().


Reference in MSDN:
CoInitialize

January 15, 2009

fatal error RC1015: cannot open include file 'activex.ver'.

Error Message:

fatal error RC1015: cannot open include file 'activex.ver'.

When compile the DirectShow filter sample in DXSDK, you may get the above error message.

Root Cause:

The resource file(.rc) includes <activex.ver> and <activex.rcv>, but compiler cannot find them.

Solution:

activex.ver and activex.rcv are in %DXSDK%\Samples\C++\DirectShow\BaseClasses
(%DXSDK% is your dx sdk installed directory.)

Add the above path to "VC++ Directories" of your VC++ setting,
or add it to "Additional Include Directories" of your project setting.

January 10, 2009

How to correctly call HttpOpenRequest() with specified accept types?

Windows API: (Wininet)

HINTERNET HttpOpenRequest(
  __in  HINTERNET hConnect,
  __in  LPCTSTR lpszVerb,
  __in  LPCTSTR lpszObjectName,
  __in  LPCTSTR lpszVersion,
  __in  LPCTSTR lpszReferer,
  __in  LPCTSTR *lplpszAcceptTypes,
  __in  DWORD dwFlags,
  __in  DWORD_PTR dwContext
);

Tips:
lplpszAcceptTypes is not a pointer to a null-terminated string, it is a pointer to a null-terminated array of strings. 

Sample Code:

// A null-terminated array of null-terminated strings
const char* lplpszAcceptTypes[] = {"text/*", NULL}; // Accept only text documents

HINTERNET  hHttpFile = HttpOpenRequestA(
  hConnect,
  "GET",
  "/TextDocument",
  HTTP_VERSION,
  NULL,
  lplpszAcceptTypes,
  INTERNET_FLAG_DONT_CACHE, 1);

Reference in MSDN:

January 01, 2009

How to get the last modified date of a file in C++?

On Win32 platform, you can get the attribute information of a file easily by just calling GetFileAttributesEx().
The information you got includes creation time, last access time, and last write time (last modified date).

Windows API:

BOOL WINAPI GetFileAttributesEx(
  __in   LPCTSTR lpFileName,
  __in   GET_FILEEX_INFO_LEVELS fInfoLevelId,
  __out  LPVOID lpFileInformation
);

Sample Code:

WIN32_FILE_ATTRIBUTE_DATA fileAttrData = {0};
GetFileAttributesExW(L"C:\\abc.txt, GetFileExInfoStandard, &fileAttrData);
// GetFileAttributesExA for non-unicode

FILETIME ftLastModifiedDate = fileAttrData.ftLastWriteTime;

Reference in This Site:

Reference in MSDN: