August 26, 2009

How To: Get the Content of Certain Environment Variable, ie: %ProgramFiles%

Code Snippet

#include <windows.h>
#include <string>

using namespace std;

wstring GetContentFromEnvironmentVariable(const wstring& wstrVariable)
{
  // Get the content of %ProgramFiles%

  wstring wstrRtn;
  DWORD dwSize = ::GetEnvironmentVariableW(wstrVariable.c_str(), NULL, NULL);
  if(dwSize > 0)
  {
    wchar_t* wszContent = new wchar_t [dwSize];
    dwSize = ::GetEnvironmentVariableW(wstrVariable.c_str(), wszContent, dwSize);

    wstrRtn = wszContent;

    delete [] wszContent;
    wszContent = NULL;
 }

 return wstrRtn;
}

Reference on MSDN
GetEnvironmentVariable Function

July 30, 2009

How To: Get the Installation Directory of Windows Media Player

Code Snippet

bool GetWMPInstallDirectory(wstring& wstrDirectory)
{
  bool bOK = false;
  HKEY hkResult = NULL;

  LONG lRet = ::RegOpenKeyExW(HKEY_LOCAL_MACHINE,
    L"SOFTWARE\\Microsoft\\MediaPlayer", NULL, NULL, &hkResult);

  if(lRet == ERROR_SUCCESS)
  {
    wchar_t wszRet[_MAX_PATH] = {0};
    DWORD type = REG_SZ;
    DWORD cbData = sizeof(wszRet);

    lRet = ::RegQueryValueExW(hkResult, L"Installation Directory",
      NULL, &type, (LPBYTE)wszRet, &cbData);

    if(lRet == ERROR_SUCCESS)
    {
      // We've got the installation directory of WMP
      wstrDirectory = wszRet;
      bOK = true;
    }

    ::RegCloseKey(hkResult);
    hkResult = NULL;
  }

  return bOK;
}

June 12, 2009

How To: Disable General Protection Fault Dialog for Your Program

Abstraction
Are you using any 3rd-party componet or ActiveX, which is not stable enough, in your program? You will get a GPF dialog if the componet in your program goes abnormal. That is not your problem totally, but actually your program crashed. There's a Windows API to prevent showing GPF dialog, you may adapt this solution if the crash can be ignored.

Code Snippet

UINT uPrevErrMode = SetErrorMode(SEM_NOGPFAULTERRORBOX);

Do you not know what GPF is?

Windows Calendar Crash

Reference on MSDN

June 06, 2009

Read/Write Windows Registry on Windows 64-Bits Platforms (C# Version)

Abstraction
How does a 32-bits(x64) program running on Windows 64-bits(x64) access the 64-bits registry? In C#, you can use P/Invoke to call RegOpenKeyEx function with KEY_WOW64_KEY to access the 64-bits registry.

Code Snippet

//
// This is a C# example to get the version of Windows Media Center on Windows 7 64-bits.
//

class RegQueryValueDemo
{
  [DllImport("advapi32.dll", CharSet = CharSet.Unicode, EntryPoint = "RegOpenKeyExW", SetLastError = true)]
  public static extern int RegOpenKeyEx(UIntPtr hKey, string subKey, uint options, int sam, out UIntPtr phkResult);
  public static UIntPtr HKEY_CURRENT_USER = (UIntPtr)0x80000001;
  public static UIntPtr HKEY_LOCAL_MACHINE = (UIntPtr)0x80000002;
  public static int KEY_QUERY_VALUE = 0x0001;
  public static int KEY_SET_VALUE = 0x0002;
  public static int KEY_CREATE_SUB_KEY = 0x0004;
  public static int KEY_ENUMERATE_SUB_KEYS = 0x0008;
  public static int KEY_WOW64_64KEY = 0x0100;
  public static int KEY_WOW64_32KEY = 0x0200;

  [DllImport("advapi32.dll", CharSet = CharSet.Unicode, EntryPoint = "RegQueryValueExW", SetLastError = true)]
  public static extern int RegQueryValueEx(UIntPtr hKey, string lpValueName, int lpReserved, out uint lpType,
    StringBuilder lpData, ref int lpcbData);

  public string GetMCEIdent()
  {
    UIntPtr regKeyHandle;
    if (RegOpenKeyEx(
    HKEY_LOCAL_MACHINE,
    "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Media Center",
    0, KEY_QUERY_VALUE | KEY_WOW64_64KEY, out regKeyHandle) == 0)
    {
      uint type;

      StringBuilder stringBuilder = new StringBuilder(2048);
      int cbData = stringBuilder.Capacity;
      if (RegQueryValueEx(regKeyHandle, "Ident", 0, out type, stringBuilder, ref cbData) == 0)
      {
        return stringBuilder.ToString();
      }
    }

    return string.Empty;
  }
}


Find a C++ version?
Read/Write Windows Registry on Windows 64-Bits Platforms

Reference on MSDN:
RegOpenKeyEx Function
32-bit and 64-bit Application Data in the Registry

May 24, 2009

How To: A Web Page Interacts with a Embedded Web Browser Control

If your application contains a web browser control to show certain web page, can the web page interact with your application by script language? Yes, it can.

There's a sample on MSDN, it's very short but clear, please refer to the following link:

Reference on MSDN

May 20, 2009

Windows Media ASF Viewer

Windows Media® ASF Viewer 9 Series is a tool for inspecting the contents of files (such as .asf. .wma, and .wmv file) to make sure they meet the requirements of the Advanced Systems Format (ASF) specification. -- Microsoft


Brief Introduction
This tool is very helpful for analyzing the contents of ASF files, it helps us to know the media structure and content easily. I was trying to encode WMV using Windows Media Format SDK, and this tool really helped me to verify the output content.

Download from Microsoft

May 14, 2009

How To: Extracting the embedded album art from a MP3 / WMA

I'm using Windows Media Sync Reader in Windows Media Format SDK to get the album art from id3 tag of a MP3, it can also get from a WMA.

Code Snippet:

#include <windows.h>
#include <wmsdk.h>
#include <atlbase.h>

#pragma comment(lib, "wmvcore.lib")

bool ExtractEmbeddedAlbumArt(LPCWSTR wszAudioFile)
{
  bool bOK = false;

  WM_PICTURE* pPicture = NULL;;

  do {

    CComPtr<IWMSyncReader> pIWMSyncReader;
    if(FAILED(WMCreateSyncReader(NULL, 0, &pIWMSyncReader))) break;

    if(FAILED(pIWMSyncReader->Open(wszAudioFile))) break;

    CComPtr<IWMHeaderInfo3> pIWMHeaderInfo3;
    if(FAILED(pIWMSyncReader->QueryInterface(&pIWMHeaderInfo3))) break;

    WMT_ATTR_DATATYPE wmtDataType = WMT_TYPE_BINARY;
    WORD wStreamNum = 0;
    WORD wLength = 0;
    if(FAILED(pIWMHeaderInfo3->GetAttributeByName(
      &wStreamNum, g_wszWMPicture, &wmtDataType, NULL, &wLength))) break;

    pPicture = (WM_PICTURE*)new BYTE[wLength];

    if(FAILED(pIWMHeaderInfo3->GetAttributeByName(
      &wStreamNum, g_wszWMPicture, &wmtDataType, (BYTE*)pPicture, &wLength))) break;

    bOK = true;

  } while(false);

  if(pPicture)
  {
    //
    // TODO: Save the picture or do something with it
    //

    delete [] (BYTE*)pPicture;
    pPicture = NULL;
  }

  return bOK;
}