2003/09/19 05:26:47
[org.ibex.core.git] / src / org / xwt / plat / Win32.cc
index ef8d70f..06c5195 100644 (file)
@@ -1,7 +1,8 @@
 // Copyright 2002 Adam Megacz, see the COPYING file for licensing [LGPL]
+#include "GCJ.cc"
 
-// kinda ugly; we use -DCOMPILE_DLL to combine two .cc files into one
-#ifndef COMPILE_DLL
+// we have to do this because the jpeg libraries use the symbol 'INT32'
+#define INT32 WIN32_INT32
 
 // this has to precede the others so we don't get collisions on min/max
 #include <org/xwt/Box.h>
@@ -23,7 +24,7 @@
 #include <java/util/Hashtable.h>
 #include <org/xwt/Box.h>
 #include <org/xwt/Surface.h>
-#include <org/xwt/DoubleBuffer.h>
+#include <org/xwt/PixelBuffer.h>
 #include <org/xwt/Picture.h>
 #include <org/xwt/ByteStream.h>
 #include <org/xwt/Platform.h>
@@ -31,7 +32,7 @@
 #include <org/xwt/plat/Win32.h>
 #include <org/xwt/plat/Win32$Win32Font.h>
 #include <org/xwt/plat/Win32$Win32Surface.h>
-#include <org/xwt/plat/Win32$Win32DoubleBuffer.h>
+#include <org/xwt/plat/Win32$Win32PixelBuffer.h>
 #include <org/xwt/plat/Win32$Win32Picture.h>
 #include <org/xwt/util/Log.h>
 #include <org/xwt/util/Semaphore.h>
@@ -239,6 +240,17 @@ void org::xwt::plat::Win32::natInit() {
 
 // Platform Methods ///////////////////////////////////////////////////////////////////
 
+jstring org::xwt::plat::Win32::_getEnv(jstring key) {
+    int len = JvGetStringUTFLength(key);
+    char buf[len + 1];
+    JvGetStringUTFRegion(key, 0, len, buf);
+    buf[len] = '\0';
+    char buf2[1024];
+    DWORD ret = GetEnvironmentVariable(buf, buf2, 1024);
+    if (ret > 0 && ret < 1024) return JvNewStringLatin1(buf2);
+    return NULL;
+}
+
 jstring org::xwt::plat::Win32::_fileDialog(jstring suggestedFileName, jboolean write) {
 
     char buf[1024];
@@ -325,7 +337,7 @@ void org::xwt::plat::Win32::_criticalAbort(jstring message) {
     char buf[JvGetStringUTFLength(message) + 1];
     buf[JvGetStringUTFLength(message)] = '\0';
     JvGetStringUTFRegion(message, 0, JvGetStringUTFLength(message), buf);
-    MessageBox (NULL, buf, "XWT Critical Abort", MB_OK | MB_ICONSTOP | MB_TASKMODAL | MB_SETFOREGROUND);
+    MessageBox (NULL, buf, "XWT Cannot Continue", MB_OK | MB_ICONSTOP | MB_TASKMODAL | MB_SETFOREGROUND);
     java::lang::System::exit(-1);
 }
 
@@ -404,7 +416,7 @@ jboolean org::xwt::plat::Win32::_newBrowserWindow_(jstring url) {
 }
 
 
-// Win32DoubleBuffer /////////////////////////////////////////////////////////////////////////
+// Win32PixelBuffer /////////////////////////////////////////////////////////////////////////
 
 // This is a scratch area; when blitting a translucent image, we copy the underlying data here first.
 // Since all drawing operations are single-threaded, it's safe to use a global here.
@@ -420,10 +432,9 @@ static jint scratch_h = 0;
     else                                                                                             \
         StretchBlt(dest, dx1, dy1, dx2 - dx1, dy2 - dy1, src, sx1, sy1, sx2 - sx1, sy2 - sy1, op);
         
-void org::xwt::plat::Win32$Win32DoubleBuffer::drawPicture(org::xwt::Picture* source0,
+void org::xwt::plat::Win32$Win32PixelBuffer::drawPicture(org::xwt::Picture* source0,
                                                           jint dx1, jint dy1, jint dx2, jint dy2,
                                                           jint sx1, jint sy1, jint sx2, jint sy2) {
-
     org::xwt::plat::Win32$Win32Picture* source = (org::xwt::plat::Win32$Win32Picture*)source0;
 
     if (source->hasalpha) {
@@ -483,7 +494,7 @@ void org::xwt::plat::Win32$Win32DoubleBuffer::drawPicture(org::xwt::Picture* sou
 
 }
 
-void org::xwt::plat::Win32$Win32DoubleBuffer::drawString(jstring font, jstring text, jint x, jint y, jint color) {
+void org::xwt::plat::Win32$Win32PixelBuffer::drawString(jstring font, jstring text, jint x, jint y, jint color) {
 
     org::xwt::plat::Win32$Win32Font* wf = org::xwt::plat::Win32::getFont(font);
     SelectObject((HDC)hdc, (HFONT)(wf->hfont));
@@ -500,7 +511,7 @@ void org::xwt::plat::Win32$Win32DoubleBuffer::drawString(jstring font, jstring t
     TextOut((HDC)hdc, x, y, buf, len);
 }
 
-void org::xwt::plat::Win32$Win32DoubleBuffer::fillRect(jint x, jint y, jint x2, jint y2, jint color) {
+void org::xwt::plat::Win32$Win32PixelBuffer::fillRect(jint x, jint y, jint x2, jint y2, jint color) {
     jint w = x2 - x;
     jint h = y2 - y;
 
@@ -512,25 +523,27 @@ void org::xwt::plat::Win32$Win32DoubleBuffer::fillRect(jint x, jint y, jint x2,
     DeleteObject(brush);
 }
 
-void org::xwt::plat::Win32$Win32Surface::blit(org::xwt::DoubleBuffer* s, jint sx, jint sy, jint dx, jint dy, jint dx2, jint dy2) {
-    BitBlt((HDC)hdc, dx, dy, dx2 - dx, dy2 - dy, (HDC)(((org::xwt::plat::Win32$Win32DoubleBuffer*)s)->hdc), sx, sy, SRCCOPY);
+void org::xwt::plat::Win32$Win32Surface::blit(org::xwt::PixelBuffer* s, jint sx, jint sy, jint dx, jint dy, jint dx2, jint dy2) {
+    // we create the DC lazily to get around some strange race condition in WinXP
+    if (hdc == 0) hdc = (jint)GetDC((HWND)hwnd);
+    BitBlt((HDC)hdc, dx, dy, dx2 - dx, dy2 - dy, (HDC)(((org::xwt::plat::Win32$Win32PixelBuffer*)s)->hdc), sx, sy, SRCCOPY);
 }
 
-void org::xwt::plat::Win32$Win32DoubleBuffer::natInit() {
+void org::xwt::plat::Win32$Win32PixelBuffer::natInit() {
     hbitmap = (jint)CreateCompatibleBitmap((HDC)org::xwt::plat::Win32::desktop_dc, w, h);
     hdc = (jint)CreateCompatibleDC((HDC)org::xwt::plat::Win32::desktop_dc);
     SetBkMode((HDC)hdc, TRANSPARENT);
     SelectObject((HDC)hdc, (HBITMAP)hbitmap);
 }
 
-void org::xwt::plat::Win32$Win32DoubleBuffer::setClip(jint x, jint y, jint x2, jint y2) {
+void org::xwt::plat::Win32$Win32PixelBuffer::setClip(jint x, jint y, jint x2, jint y2) {
     clipx1 = x; clipx2 = x2; clipy1 = y; clipy2 = y2;
     HRGN hrgn = CreateRectRgn(x, y, x2, y2);
     SelectClipRgn((HDC)hdc, hrgn);
     DeleteObject(hrgn);
 }
 
-void org::xwt::plat::Win32$Win32DoubleBuffer::finalize() {
+void org::xwt::plat::Win32$Win32PixelBuffer::finalize() {
     DeleteObject((void*)hdc);
     DeleteObject((void*)hbitmap);
 }
@@ -602,7 +615,6 @@ void org::xwt::plat::Win32$Win32Surface::natInit(jboolean framed) {
     // GC_enable_incremental();
 
     ShowWindow ((HWND)hwnd, SW_SHOWDEFAULT);
-    hdc = (jint)GetDC((HWND)hwnd);
 }
 
 void org::xwt::plat::Win32$Win32Surface::finalize() { /* DeleteObject((void*)hwnd); */ }
@@ -628,9 +640,9 @@ void org::xwt::plat::Win32$Win32Surface::setSize(jint w, jint h) {
     RECT client_rect, window_rect;
     GetClientRect((HWND)hwnd, &client_rect);
     GetWindowRect((HWND)hwnd, &window_rect);
-    int addwidth = (window_rect.right - window_rect.left) - (client_rect.right - client_rect.left);
-    int addheight = (window_rect.bottom - window_rect.top) - (client_rect.bottom - client_rect.top);
-    SetWindowPos((HWND)hwnd, NULL, 0, 0, w + addwidth, h + addheight, SWP_NOZORDER | SWP_NOMOVE);
+    int width = (window_rect.right - window_rect.left) - (client_rect.right - client_rect.left) + w;
+    int height = (window_rect.bottom - window_rect.top) - (client_rect.bottom - client_rect.top) + h;
+    SetWindowPos((HWND)hwnd, NULL, 0, 0, width, height, SWP_NOZORDER | SWP_NOMOVE);
 }
 
 void org::xwt::plat::Win32$Win32Surface::setTitleBarText(java::lang::String* title) {
@@ -647,6 +659,9 @@ void org::xwt::plat::Win32$Win32Surface::setIcon(org::xwt::Picture* p0) {
     int icon_width = GetSystemMetrics(SM_CXSMICON);
     int icon_height = GetSystemMetrics(SM_CYSMICON);
 
+    // we create the DC lazily to get around some strange race condition in WinXP
+    if (hdc == 0) hdc = (jint)GetDC((HWND)hwnd);
+
     // create the bitmap
     HBITMAP bit = CreateCompatibleBitmap((HDC)hdc, icon_width, icon_height);
     HDC memdc = CreateCompatibleDC((HDC)hdc);
@@ -687,9 +702,11 @@ jint org::xwt::plat::Win32$Win32Surface::WndProc(jint _hwnd, jint _iMsg, jint _w
     POINT point;
     HWND hwnd2;
     RECT rect, rect2;
+    RECT client_rect, window_rect;
     jboolean newinside;
     int16_t mouse_x;
     int16_t mouse_y;
+    int addwidth, addheight;
 
     switch(iMsg) {
     case WM_DEVMODECHANGE: break;    // FEATURE: color depth changed
@@ -796,11 +813,15 @@ jint org::xwt::plat::Win32$Win32Surface::WndProc(jint _hwnd, jint _iMsg, jint _w
         return 0;
 
     case WM_GETMINMAXINFO:
+        GetClientRect((HWND)hwnd, &client_rect);
+        GetWindowRect((HWND)hwnd, &window_rect);
+        addwidth = (window_rect.right - window_rect.left) - (client_rect.right - client_rect.left);
+        addheight = (window_rect.bottom - window_rect.top) - (client_rect.bottom - client_rect.top);
         mmi = (MINMAXINFO*)lParam;
-        mmi->ptMinTrackSize.x = root->dmin(0);
-        mmi->ptMinTrackSize.y = root->dmin(1);
-        mmi->ptMaxTrackSize.x = root->dmax(0);
-        mmi->ptMaxTrackSize.y = root->dmax(1);
+        mmi->ptMinTrackSize.x = ((uint32_t)root->minwidth) + addwidth;
+        mmi->ptMinTrackSize.y = ((uint32_t)root->minheight) + addheight;
+        mmi->ptMaxTrackSize.x = min(org::xwt::plat::Win32::getScreenWidth(), ((uint32_t)root->maxwidth) + addwidth);
+        mmi->ptMaxTrackSize.y = min(org::xwt::plat::Win32::getScreenHeight(), ((uint32_t)root->maxheight) + addheight);
         return 0;
         
     case WM_PAINT: 
@@ -885,317 +906,3 @@ static jstring keyToString(WPARAM wParam) {
     }
     return NULL;
 }
-
-
-
-
-///////////////////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////////////
-
-#else /* COMPILE_DLL */
-
-
-//
-// A simple DLL to invoke xwt.exe and pass it any arguments found in the <object/> tag
-//
-
-#include <windows.h>
-#include <initguid.h>
-#include <objbase.h>
-#include <oaidl.h>
-#include <oleauto.h>
-#include <olectl.h>
-
-
-// Globals ////////////////////////////////////////////////////////////////////////
-
-using namespace std;
-
-#define CLSID_STRING_SIZE 39
-
-const char XWT_friendlyName[] = "XWT ActiveX Control (build " BUILDID ")";
-const char XWT_versionIndependantProgramID[] = "XWT.ActiveX";
-const char XWT_programID[] = "XWT.ActiveX (build " BUILDID ")";
-extern "C" const CLSID XWT_clsid = CLSID_STRUCT;
-static HMODULE g_hModule = NULL;    //DLL handle
-
-
-
-
-// Superclasses ////////////////////////////////////////////////////////////////////////
-
-// Option bit definitions for IObjectSafety:
-#define INTERFACESAFE_FOR_UNTRUSTED_CALLER  0x00000001  // Caller of interface may be untrusted
-#define INTERFACESAFE_FOR_UNTRUSTED_DATA    0x00000002  // Data passed into interface may be untrusted
-
-// {CB5BDC81-93C1-11cf-8F20-00805F2CD064}
-DEFINE_GUID(IID_IObjectSafety, 0xcb5bdc81, 0x93c1, 0x11cf, 0x8f, 0x20, 0x0, 0x80, 0x5f, 0x2c, 0xd0, 0x64);
-
-interface IObjectSafety : public IUnknown {
- public:
-    virtual HRESULT __stdcall GetInterfaceSafetyOptions(REFIID riid, DWORD __RPC_FAR *pdwSupportedOptions, DWORD __RPC_FAR *pdwEnabledOptions) = 0;
-    virtual HRESULT __stdcall SetInterfaceSafetyOptions(REFIID riid, DWORD dwOptionSetMask, DWORD dwEnabledOptions) = 0;
-};
-
-interface IShoeHorn : IPersistPropertyBag, IObjectSafety { };
-
-
-
-// Entry Points ////////////////////////////////////////////////////////////////////////
-
-// to get mingw to stop nagging me
-int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) { }
-
-// determines whether or not the DLL can be unloaded; always allow this since we don't do too much
-STDAPI __declspec(dllexport) DllCanUnloadNow(void) { return S_OK; }
-
-extern "C" __declspec(dllexport) BOOL WINAPI DllMain(HINSTANCE hModule, DWORD dwReason, LPVOID /*lpReserved*/) {
-    if (dwReason == DLL_PROCESS_ATTACH) g_hModule = (HINSTANCE)hModule;
-    return TRUE;
-}
-
-
-
-// Other ///////////////////////////////////////////////////////////////////////////////////
-
-// simple assert() replacement that pops open a message box if there are errors
-void check(int val, char* message) {
-    if (!val) {
-        MessageBox (NULL, message, "XWT Critical Abort", MB_OK | MB_ICONSTOP | MB_TASKMODAL | MB_SETFOREGROUND);
-        exit(-1);
-    }
-}
-
-void clsidToString(const CLSID& clsid, char* str, int length) {
-    check(length >= CLSID_STRING_SIZE, "clsidToString(): string too short");
-       LPOLESTR wide_str = NULL;
-       HRESULT hr = StringFromCLSID(clsid, &wide_str);
-       check(SUCCEEDED(hr), "StringFromCLSID() failed in clsidToString()");
-       wcstombs(str, wide_str, length);
-       CoTaskMemFree(wide_str);
-}
-
-void setRegistryKey(const char* key, const char* subkey, const char* value) {
-       HKEY hKey;
-       char keyBuf[1024];
-       strcpy(keyBuf, key);
-       if (subkey != NULL) {
-               strcat(keyBuf, "\\");
-               strcat(keyBuf, subkey );
-       }
-       long lResult = RegCreateKeyEx(HKEY_CLASSES_ROOT, keyBuf, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, NULL);
-       if (value != NULL)
-        check(RegSetValueEx(hKey, NULL, 0, REG_SZ, (BYTE *)value, strlen(value) + 1) == ERROR_SUCCESS,
-              "RegSetValueEx() failed in setRegistryKey()");
-       RegCloseKey(hKey);
-}
-
-void deleteRegistryKey(HKEY parent, const char* target) {
-       HKEY hKeyChild;
-       RegOpenKeyEx(parent, target, 0, KEY_ALL_ACCESS, &hKeyChild);
-
-       // Iterate over children, deleting them
-       FILETIME time;
-       char szBuffer[256];
-       DWORD dwSize = 256;
-       while (RegEnumKeyEx(hKeyChild, 0, szBuffer, &dwSize, NULL, NULL, NULL, &time) == S_OK) {
-               deleteRegistryKey(hKeyChild, szBuffer);
-               dwSize = 256;
-       }
-
-       RegCloseKey(hKeyChild);
-       RegDeleteKey(parent, target);
-}
-
-STDAPI __declspec(dllexport) DllRegisterServer(void) {
-       char moduleName[512];
-    HRESULT result = GetModuleFileName(g_hModule, moduleName, sizeof(moduleName)/sizeof(char));
-       check(result, "GetModuleFileName() failed in RegisterServer()");
-
-       char clsidString[CLSID_STRING_SIZE];
-       clsidToString(XWT_clsid, clsidString, sizeof(clsidString));
-
-       // build the key
-       char key[64];
-       strcpy(key, "CLSID\\");
-       strcat(key, clsidString);
-  
-       setRegistryKey(key, NULL, XWT_friendlyName);
-       setRegistryKey(key, "InprocServer32", moduleName);
-       setRegistryKey(key, "ProgID", XWT_programID);
-       setRegistryKey(key, "VersionIndependentProgID", XWT_versionIndependantProgramID);
-       setRegistryKey(XWT_versionIndependantProgramID, NULL, XWT_friendlyName); 
-       setRegistryKey(XWT_versionIndependantProgramID, "CLSID", clsidString);
-       setRegistryKey(XWT_versionIndependantProgramID, "CurVer", XWT_programID);
-       setRegistryKey(XWT_programID, NULL, XWT_friendlyName); 
-       setRegistryKey(XWT_programID, "CLSID", clsidString);
-       return S_OK;
-}
-
-STDAPI __declspec(dllexport) DllUnregisterServer(void) {
-       char clsidString[CLSID_STRING_SIZE];
-       clsidToString(XWT_clsid, clsidString, sizeof(clsidString));
-
-       // build the key
-       char key[64];
-       strcpy(key, "CLSID\\");
-       strcat(key, clsidString);
-
-       deleteRegistryKey(HKEY_CLASSES_ROOT, key);
-       deleteRegistryKey(HKEY_CLASSES_ROOT, XWT_versionIndependantProgramID);
-       deleteRegistryKey(HKEY_CLASSES_ROOT, XWT_programID);
-       return S_OK;
-}
-
-
-
-// ShoeHorn //////////////////////////////////////////////////////////////////////////////////
-
-class ShoeHorn : public IShoeHorn {
-    public:
-    virtual HRESULT __stdcall QueryInterface(const IID& iid, void** ppv) {
-        if(iid == IID_IUnknown) *ppv = static_cast<IShoeHorn*>(this);
-        else if(iid == XWT_clsid) *ppv = static_cast<IShoeHorn*>(this);
-        else if(iid == IID_IPersistPropertyBag) *ppv = static_cast<IPersistPropertyBag*>(this);
-        else if(iid == IID_IObjectSafety) *ppv = static_cast<IObjectSafety*>(this);
-        else { *ppv = NULL; return E_NOINTERFACE; }
-        reinterpret_cast<IUnknown*>(*ppv)->AddRef();
-        return S_OK;
-    }
-    virtual ULONG __stdcall AddRef() { return InterlockedIncrement(&m_cRef); }
-    virtual ULONG __stdcall Release() {
-        if(InterlockedDecrement(&m_cRef) == 0) { delete this; return 0; }
-        return m_cRef;
-    }
-    virtual HRESULT __stdcall GetClassID(CLSID*) { return S_OK; }
-    virtual HRESULT __stdcall InitNew() { return S_OK; }
-    virtual HRESULT __stdcall Save(IPropertyBag*, int, int) { return S_OK; }
-    virtual HRESULT __stdcall SetInterfaceSafetyOptions(REFIID riid, DWORD pdwSupportedOptions, DWORD pdwEnabledOptions) { return S_OK; }
-    virtual HRESULT __stdcall GetInterfaceSafetyOptions(REFIID riid, DWORD* pdwSupportedOptions, DWORD* pdwEnabledOptions) {
-        if (pdwSupportedOptions != NULL) *pdwSupportedOptions |= INTERFACESAFE_FOR_UNTRUSTED_DATA;
-        if (pdwEnabledOptions != NULL) *pdwSupportedOptions |= INTERFACESAFE_FOR_UNTRUSTED_DATA;
-        return S_OK;
-    }
-
-    virtual HRESULT __stdcall Load(IPropertyBag* pPropBag, IErrorLog* pErrorLog) {
-        VARIANT v;
-        v.vt = VT_BSTR;
-        HRESULT hrRead;
-        
-        WCHAR wc[100];
-        char url[100];
-        
-        MultiByteToWideChar(CP_ACP, 0, "initial-xwar-url", -1, wc, 100);
-        pPropBag->Read(wc, &v, pErrorLog);
-        check(WideCharToMultiByte(CP_ACP, 0, v.bstrVal, -1, url, 100, NULL, NULL),
-              "WideCharToMultiByte() failed in ShoeHorn::Load()");
-        
-        HKEY hkey;
-        LONG result = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\ActiveX Cache", &hkey);
-        check(result == ERROR_SUCCESS, "RegOpenKey() failed in ShoeHorn::Load()");
-        
-        // iterate over all the activex cache locations until we find ourselves
-        for(int i=0; i<9; i++) {
-            DWORD buflen = 999;
-            char buf[1000];
-            VALENT valents[20];
-            DWORD type;
-            char which[2];
-
-            which[0] = '0' + i;
-            which[1] = '\0';
-            result = RegQueryValueEx(hkey, which, NULL, &type, (BYTE*)buf, &buflen);
-            if (result != ERROR_SUCCESS)
-                if (i == 0) {
-                    check(0, "RegQueryValueEx() failed in ShoeHorn::Load()");
-                } else {
-                    break;
-                }
-            buf[buflen] = '\0';
-            
-            char cmdline[200];
-            for(int i=0; i<200; i++) cmdline[i] = '\0';
-            strncpy(cmdline, buf, 200);
-            strncpy(cmdline + strlen(cmdline), "\\xwt-" BUILDID ".exe", 200 - strlen(cmdline));
-            strncpy(cmdline + strlen(cmdline), " ", 200 - strlen(cmdline));
-            strncpy(cmdline + strlen(cmdline), url, 200 - strlen(cmdline));
-            
-            PROCESS_INFORMATION pInfo;
-            STARTUPINFO sInfo;
-            sInfo.cb = sizeof(STARTUPINFO);
-            sInfo.lpReserved = NULL;
-            sInfo.lpReserved2 = NULL;
-            sInfo.cbReserved2 = 0;
-            sInfo.lpDesktop = NULL;
-            sInfo.lpTitle = NULL;
-            sInfo.dwFlags = 0;
-            sInfo.dwX = 0;
-            sInfo.dwY = 0;
-            sInfo.dwFillAttribute = 0;
-            sInfo.wShowWindow = SW_SHOW;
-            BOOL b = CreateProcess(NULL, cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &sInfo, &pInfo);
-            if (b) return S_OK;
-        }
-
-        check(0, "unable to locate xwt-" BUILDID ".exe in ActiveX cache folders");
-    }
-
-    ShoeHorn() : m_cRef(1) { };
-    ~ShoeHorn() { };
-    private: long m_cRef;
-};
-
-
-
-
-// ClassFactory //////////////////////////////////////////////////////////////////////////
-
-class ClassFactory : public IClassFactory {
-    public:
-    virtual HRESULT __stdcall QueryInterface(const IID& iid, void** ppv) {
-        if(iid == IID_IUnknown) *ppv = static_cast<IClassFactory*>(this);
-        else if(iid == IID_IClassFactory) *ppv = static_cast<IClassFactory*>(this);
-        else {
-            *ppv = NULL;
-            return E_NOINTERFACE;
-        }
-        reinterpret_cast<IUnknown*>(*ppv)->AddRef();
-        return S_OK;
-    }
-
-    ClassFactory() : m_cRef(1) { }
-    ~ClassFactory() { }
-    virtual HRESULT __stdcall LockServer(BOOL bLock) { return S_OK; }
-    virtual ULONG __stdcall AddRef() { return InterlockedIncrement(&m_cRef); }
-    virtual ULONG __stdcall Release() {
-        if(InterlockedDecrement(&m_cRef) == 0) {
-            delete this;
-            return 0;
-        }
-        return m_cRef;
-    }
-
-    virtual HRESULT __stdcall CreateInstance(IUnknown* pUnknownOuter, const IID& iid, void** ppv) {
-        if(pUnknownOuter != NULL) return CLASS_E_NOAGGREGATION;
-        ShoeHorn* s = new ShoeHorn;
-        if(s == NULL) return E_OUTOFMEMORY;
-        HRESULT hr = s->QueryInterface(iid, ppv);
-        s->Release();
-        return hr;
-    }
-    
-    private: long m_cRef;
-};
-
-
-extern "C" __stdcall HRESULT DllGetClassObject(const CLSID& clsid, const IID& iid, void** ppv) {
-    if(clsid != XWT_clsid) return CLASS_E_CLASSNOTAVAILABLE;
-    ClassFactory* pFactory = new ClassFactory; 
-    if(pFactory == NULL) return E_OUTOFMEMORY;
-    HRESULT hr = pFactory->QueryInterface(iid, ppv);
-    pFactory->Release();
-    return hr;
-}
-
-#endif