The following code is intended to do the same as the method GetCaptionFont() from the Code Project article Dissecting the MessageBox:

Code:
// MessageBoxEx.cpp

#include "StdAfx.h"

#define WINVER 0x0502
#include <Windows.h>
#undef MessageBoxEx

#include "MessageBoxEx.h"

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

using namespace System::Runtime::InteropServices;
using namespace System::Diagnostics;

using namespace EriLib;

// ...

Drawing::Font ^MessageBoxEx::GetCaptionFont()
{
  NONCLIENTMETRICS ncm = {0};
  ncm.cbSize = sizeof(ncm);
  if (!SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(ncm), &ncm, 0)) {
    Trace::WriteLine(String::Format("SPI failed, code: {0}", GetLastError()));
    return nullptr;
  }
  array<Byte> ^abyTemp = gcnew array<Byte>(sizeof(LOGFONT));
  Marshal::Copy(IntPtr(&ncm.lfCaptionFont), abyTemp, 0, abyTemp->Length);
  return Drawing::Font::FromLogFont(abyTemp);
}
It actually does what it is supposed to, but isn't the way I use to pass ncm.lfCaptionFont to Font::FromLogFont() by marshaling it over the temporary array somewhat overcomplicated?

I expected that C++/CLI would free me from the need to replicate NONCLIENTMETRICS and LOGFONT as my own structures like the C# code from the article does, and that expectation was fulfilled. However, simply passing ncm.lfCaptionFont to Font::FromLogFont() did not work and resulted in an error C2665. Note quite that surprising since, as I understand it, LOGFONT, as a non-primitive native type, can't be implicitly boxed. But isn't there a simpler way than what I did above? I tried a bunch of other variants, mostly involving some sort of casting, all to no avail.

This seems to be a rarely discussed topic, BTW: MSDN search, CG forum search and Google, all for quite some time, did not yield any helpful result at all, not even a hint.