#ifdef readme

This is a property sheet shell extension handler. The shell loads our dll, and calls the DllGetClassObject
function, passing a CLSID registered for current file class, and IID equal to IID_IClassFactory.
We save the CLSID for later usage, and return new()'ed class CClassFactory.

In CClassFactory, the shell calls CreateInstance passing IID equal to IShellExtInit, so we
create and return CShellExtInit newly created class. As next, the shell calls Initialize method
and passes an IDataObject interface with 'selected' file(s). Using DragQueryFile api we can load
all paths info CStringList.

Now the shell calls CShellExtInit::QueryInterface with IID equal to IID_ShellPropSheetExt, so we
return CShellPropSheetExt class (already created in CShellExtInit constructor).

As last, the shell calls CShellPropSheetExt::AddPages, where we can insert different pages, by
comparing the saved CLSID. One CLSID can be for .exe files to display one property page, another for other
file type...
If you need to display n property pages for one file type, register n different CLSID's
for that file type, as I did here:

HKCR\.dll
	(default) = dllfile // always check the default value before accesing hardcoded HKCR\dllfile
	                    // someone could change it (as I did: .acm, .ax, .des, .drv, .sys, .wcx (and more) = dllfile)

HKCR\dllfile\shellex\PropertySheetHandlers\Example
	(default) = {4D986938-7856-4F1C-881E-CA73ED1E96C6}  // string representation of _CLSID_EXAMPLE

HKCR\dllfile\shellex\PropertySheetHandlers\ExportsViewer
	(default) = {A4533B07-BC80-48F1-9DA4-2CD07F875066}  // string representation of _CLSID_EXPORTS

HKCR\dllfile\shellex\PropertySheetHandlers\ImportsViewer
	(default) = {8CD1BD38-B8AD-4FCE-A88E-D1F6DF5F0304}  // string representation of _CLSID_IMPORTS


-----------------
the basic entries for all dll servers:

HKCR\CLSID\{your_clsid}
	(default) = optional description

HKCR\CLSID\{your_clsid}\InprocServer32
	(default)      = full path to dll
	ThreadingModel = Apartment    // the value depends


also {your_clsid} should be replaced with {4D986938-7856-4F1C-881E-CA73ED1E96C6} and two other.

-----------------
required in windws XP, ignored in win98

HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Shell Extensions\Approved
	{your_clsid} = description



///////////////////////////////////////////////////////
page Example
	has a combobox, two buttons, and hidden read-only editbox
	The combobox holds all dll paths that were selected before you clicked 'Properties' from the shell context menu
	Button 'Register' will be enabled, if selected file in the combobox exports 'DllRegisterServer' function
	Button 'UnRegister' will be ... 'DllUnregisterServer' function

	When you click the 'Register' button, the dll will be loaded, and the 'DllRegisterServer' function will be called.
	The return value will be later displayed as error or success. Now the dll is unloaded.
	If the 'DllRegisterServer' function caused an exception, you will see a "Error 0xC..." message, and the dll will be not unloaded.
	It could be riskant to unload a dll with bugs.
	I prefer to load dll's using separate application, but unfortunelly rundll32 and regsvr32 are not returning the
	correct ExitCode. Rundll32 always returns 0, no matter if the api has returned an error or success.
	Regsvr32 returns always custom error codes.
	The editbox will display a baloon with error description, if your working on windows XP
	I've attached "dll with bug.dll" module so you can test the exceptions.

page ExportsViewer
	Has only a listview, where you'll see all exported by name functions

page ImportsViewer
	Has only a listview, with two columns. The first shows dll name,
	the second shows all imported functions (by name) from the dll from first column


so, nothing super extra cool to display here!


Resource file (pshext1.rc) was created with ResEd - http://www.radasm.com/resed/

#endif
