Archive for September, 2008

Published by Roman on 06 Sep 2008

ATL Registration Script

Since ATL version 3, and actually it probably existed even since even earlier time, I have seen Microsoft Visual Studio (and its predecessor Visual C++) generating .RGS registration script with hardcoded CLSID value, ProgID values and other strings entered through IDE wizard. While it seems to work nice at the moment of generation, it still gives the problem to lose sync between identifiers if code is copied between projects or a different way. It might be an oversight originally, but was not it the obvious thing to do later to avoid possible typos of inaccurate user? Microsoft Visua Studio 2008 still generates the same code.

Previous versions of development environment offered attributed code option which in fact took care of this problem very well. Although there has been a lot of negative feedback written about C++ attributes, this was a kind of problem attributes left no chances to break: CLSID was specified once only in C++ COM class attribute and the rest of the deal was generated automatically, including IDL and registration sequence.

It is especially unclear why it was left this way because internal ATL classes already have all necessary capabilities to process wildcards. For example, default .RGS script contains an entry for COM class type library, HKCR\CLSID\{…} key, “TypeLib” value. Why would hardcode it if it can be specified through a replacement:

HKCR
{
	NoRemove CLSID
	{
		ForceRemove %CLSID% = s '...'
		{
			'TypeLib' = s '%LIBID%'

And the replacement is so easily added overriding CAtlModule’s virtual AddCommonRGSReplacements:

class CFooModule :
	public CAtlDllModuleT<CFooModule>
{
...
// CAtlModule
	HRESULT AddCommonRGSReplacements(IRegistrarBase* pRegistrar) throw()
	{
		_ATLTRY
		{
			ATLENSURE_SUCCEEDED(__super::AddCommonRGSReplacements(pRegistrar));
			ATLASSERT(!IsEqualGUID(m_libid, GUID_NULL));
			ATLENSURE_SUCCEEDED(pRegistrar->AddReplacement(L"LIBID", StringFromIdentifier(m_libid)));
		}
		_ATLCATCH(Exception)
		{
			return Exception;
		}
		return S_OK;
	}

I thought it would be implemented natively in ATL long ago, along with per-coclass replacements like %CLSID%.

This is how I like my registration script:

HKCR
{
	%PROGID% = s '%DESCRIPTION%'
	{
		CLSID = s '%CLSID%'
	}
	%VIPROGID% = s '%DESCRIPTION%'
	{
		CLSID = s '%CLSID%'
		CurVer = s '%PROGID%'
	}
	NoRemove CLSID
	{
		ForceRemove %CLSID% = s '%DESCRIPTION%'
		{
			ProgID = s '%PROGID%'
			VersionIndependentProgID = s '%VIPROGID%'
			ForceRemove 'Programmable'
			InprocServer32 = s '%MODULE%'
			{
				val ThreadingModel = s 'Both'
			}
			TypeLib = s '%LIBID%'
		}
	}
}

Published by Roman on 03 Sep 2008

Customer Quotes

Customer quotes about our product:

By the way, wanted to tell you.  I work in the NVR industry, I’m a sales engineer for S* http://www.s*.com.  I use your DVR for my 3 home cameras that I’ve recently put up due to some break ins lately in my community.   I’ve worked with many commercial DVR/NVR systems in my years working in the surveillance industry, you product is awesome.  Now that I have remote monitoring and sequencing configured it’s working great.  Your support has been rock solid and quick to respond and your server/DVR software is rock solid, it runs 100% of the time.  I’m a fan! Just wanted to say Thanks!
R*

Published by Roman on 02 Sep 2008

Network Cameras and Video Servers

An example to give an idea of how robust and reliable network cameras and video servers today are. Fl***h made video encoder hardware.

The request is http://***.***.***.***/cgi-bin/***.cgi?***, it informs on capabilities of the device.

...
SupportDigitalOutputCount=4
SupportDigitalIutputCount=4
...

« Prev