Click here to Skip to main content
15,896,541 members
Articles / Desktop Programming / Win32

Stopwatch

Rate me:
Please Sign up or sign in to vote.
4.97/5 (29 votes)
3 Jan 2015CPOL6 min read 66.4K   1.5K   43  
Benchmark C++ std::vector vs raw arrays, move assignable/constructable & copy assignable/constructable
#include "stdafx.h"

#include "hwinhandle.h"
#include "hwinexception.h"
#include "hwincontrol.h"
#include "hwincom.h"
#include "hwinimaging.h"

#pragma comment(lib,"Windowscodecs")


namespace harlinn
{
    namespace windows
    {


        // ----------------------------------------------------------------------
        // SystemHandle
        // ----------------------------------------------------------------------
        HWIN_EXPORT SystemHandle::~SystemHandle()
        {
            if( OwnsHandle() && (Value() != INVALID_HANDLE_VALUE) )
            {
                CloseHandle(HANDLE(Value()));
            }
        }


        // ----------------------------------------------------------------------
        // ModuleHandle
        // ----------------------------------------------------------------------
        HWIN_EXPORT ModuleHandle::ModuleHandle(HMODULE hModule, bool closeHandle)
            : Base( hModule, closeHandle)
        {
             
        }

        HWIN_EXPORT ModuleHandle::ModuleHandle(const wchar_t* theModuleName, DWORD flags)
        {
            CheckPointerNotNull(theModuleName);
            HMODULE hModule = LoadLibraryEx(theModuleName, nullptr,flags);
            if(!hModule)
            {
                ThrowLastOSError();
            }
            SetValue(hModule);
        }
        HWIN_EXPORT ModuleHandle::ModuleHandle(const String& theModuleName, DWORD flags)
        {
            HMODULE hModule = LoadLibraryEx(theModuleName.c_str(), nullptr,flags);
            if(!hModule)
            {
                ThrowLastOSError();
            }
            SetValue(hModule);
        }
        HWIN_EXPORT ModuleHandle::ModuleHandle(std::shared_ptr<String> theModuleName, DWORD flags)
        {
            CheckPointerNotNull(theModuleName);
            HMODULE hModule = LoadLibraryEx(theModuleName->c_str(), nullptr,flags);
            if(!hModule)
            {
                ThrowLastOSError();
            }
            SetValue(hModule);
        }

        HWIN_EXPORT ModuleHandle::~ModuleHandle()
        {
            if(OwnsHandle() && Value())
            {
                FreeLibrary(static_cast<HMODULE>( Value() ));
            }
        }

        HWIN_EXPORT std::shared_ptr<ModuleHandle> ModuleHandle::Current()
        {
            HMODULE hModule = GetModuleHandle(nullptr);
            if(!hModule)
            {
                ThrowLastOSError();
            }
            std::shared_ptr<ModuleHandle> result = std::make_shared<ModuleHandle>(hModule,false);
            return result;
        }

        HWIN_EXPORT String ModuleHandle::GetModuleFileName() const
        {
            if(GetHMODULE())
            {
                wchar_t buffer[512];
                String::size_type length = ::GetModuleFileNameW((HMODULE)Value(),buffer,512);
                if(length == 0)
                {
                    ThrowLastOSError();
                }
                String result(buffer,length);
                return result;
            }
            return String();
        }


        // ----------------------------------------------------------------------
        // GraphicsDeviceObjectHandle
        // ----------------------------------------------------------------------
        HWIN_EXPORT GraphicsDeviceObjectHandle::GraphicsDeviceObjectHandle(HGDIOBJ theHandle, bool closeHandle)
            : Base(theHandle, closeHandle)
        {
        }

        // ----------------------------------------------------------------------
        // BitmapHandle
        // ----------------------------------------------------------------------
        BitmapHandle::map_t BitmapHandle::map;
        HWIN_EXPORT void BitmapHandle::AddHandleToMap(HBITMAP hElement,BitmapHandle* theHandle)
        {
            auto it = map.find(hElement);
            if(it ==  map.end())
            {
                map.insert( map_t::value_type(hElement,theHandle));
            }
        }
        HWIN_EXPORT BitmapHandle* BitmapHandle::GetHandleFromMap(HBITMAP hElement)
        {
            auto it = map.find(hElement);
            if(it !=  map.end())
            {
                auto result = (*it).second;
                return result;
            }
            return nullptr;
        }

        HWIN_EXPORT void BitmapHandle::RemoveHandleFromMap(HBITMAP hElement)
        {
            map.erase(hElement);
        }


        HWIN_EXPORT BitmapHandle::BitmapHandle(HBITMAP theHandle, bool ownsHandle)
            : Base(theHandle, ownsHandle)
        {
        }

        HWIN_EXPORT BitmapHandle::BitmapHandle(int resourceId, int width, int height,DWORD flags)
        {
            HANDLE hBitmap = LoadImage(0,MAKEINTRESOURCE(resourceId),IMAGE_ICON,width,height,flags);
            if(!hBitmap)
            {
                ThrowLastOSError();
            }
            SetValue(hBitmap, flags & LR_SHARED? false:true);
            AddHandleToMap(GetHBITMAP(),this);
        }

        HWIN_EXPORT BitmapHandle::BitmapHandle(const wchar_t* theBitmapName, int width, int height,DWORD flags)
        {
            CheckPointerNotNull(theBitmapName);
            HANDLE hBitmap = LoadImage(0,theBitmapName,IMAGE_ICON,width,height,flags);
            if(!hBitmap)
            {
                ThrowLastOSError();
            }
            SetValue(hBitmap, flags & LR_SHARED? false:true);
            AddHandleToMap(GetHBITMAP(),this);
        }

        

        HWIN_EXPORT BitmapHandle::BitmapHandle(const String& theBitmapName, int width, int height,DWORD flags)
        {
            HANDLE hBitmap = LoadImage(0,theBitmapName.c_str(),IMAGE_ICON,width,height,flags);
            if(!hBitmap)
            {
                ThrowLastOSError();
            }
            SetValue(hBitmap, flags & LR_SHARED? false:true);
            AddHandleToMap(GetHBITMAP(),this);
        }
        HWIN_EXPORT BitmapHandle::BitmapHandle(std::shared_ptr<String> theBitmapName, int width, int height,DWORD flags)
        {
            CheckPointerNotNull(theBitmapName);
            HANDLE hBitmap = LoadImage(0,theBitmapName->c_str(),IMAGE_ICON,width,height,flags);
            if(!hBitmap)
            {
                ThrowLastOSError();
            }
            SetValue(hBitmap, flags & LR_SHARED? false:true);
            AddHandleToMap(GetHBITMAP(),this);
        }


        HWIN_EXPORT BitmapHandle::BitmapHandle(std::shared_ptr<ModuleHandle> theModule, int resourceId, int width, int height,DWORD flags)
        {
            HINSTANCE hInstance = 0;
            if(theModule)
            {
                hInstance = static_cast<HINSTANCE>( theModule->Value() );
            }
            HANDLE hBitmap = LoadImage(hInstance,MAKEINTRESOURCE(resourceId),IMAGE_ICON,width,height,flags);
            if(!hBitmap)
            {
                ThrowLastOSError();
            }
            SetValue(hBitmap, flags & LR_SHARED? false:true);
            AddHandleToMap(GetHBITMAP(),this);
        }

        HWIN_EXPORT BitmapHandle::BitmapHandle(std::shared_ptr<ModuleHandle> theModule, const wchar_t* theBitmapName, int width, int height,DWORD flags)
        {
            HINSTANCE hInstance = 0;
            if(theModule)
            {
                hInstance = static_cast<HINSTANCE>( theModule->Value() );
            }
            CheckPointerNotNull(theBitmapName);
            HANDLE hBitmap = LoadImage(hInstance,theBitmapName,IMAGE_ICON,width,height,flags);
            if(!hBitmap)
            {
                ThrowLastOSError();
            }
            SetValue(hBitmap, flags & LR_SHARED? false:true);
            AddHandleToMap(GetHBITMAP(),this);
        }
        HWIN_EXPORT BitmapHandle::BitmapHandle(std::shared_ptr<ModuleHandle> theModule, const String& theBitmapName, int width, int height,DWORD flags)
        {
            HINSTANCE hInstance = 0;
            if(theModule)
            {
                hInstance = static_cast<HINSTANCE>( theModule->Value() );
            }
            HANDLE hBitmap = LoadImage(hInstance,theBitmapName.c_str(),IMAGE_ICON,width,height,flags);
            if(!hBitmap)
            {
                ThrowLastOSError();
            }
            SetValue(hBitmap, flags & LR_SHARED? false:true);
            AddHandleToMap(GetHBITMAP(),this);
        }
        HWIN_EXPORT BitmapHandle::BitmapHandle(std::shared_ptr<ModuleHandle> theModule, std::shared_ptr<String> theBitmapName, int width, int height,DWORD flags)
        {
            HINSTANCE hInstance = 0;
            if(theModule)
            {
                hInstance = static_cast<HINSTANCE>( theModule->Value() );
            }
            CheckPointerNotNull(theBitmapName);
            HANDLE hBitmap = LoadImage(hInstance,theBitmapName->c_str(),IMAGE_ICON,width,height,flags);
            if(!hBitmap)
            {
                ThrowLastOSError();
            }
            SetValue(hBitmap, flags & LR_SHARED? false:true);
            AddHandleToMap(GetHBITMAP(),this);
        }

        HWIN_EXPORT BitmapHandle::~BitmapHandle()
        {
            RemoveHandleFromMap(GetHBITMAP());
            if(OwnsHandle() && Value())
            {
                DeleteObject(static_cast<HBITMAP>( Value() ));
            }
        }


        HWIN_EXPORT std::shared_ptr<BitmapHandle> BitmapHandle::FromHandle(HBITMAP theHandle, bool ownsHandle)
        {
            BitmapHandle* existingBitmapHandle = GetHandleFromMap(theHandle);
            if(existingBitmapHandle)
            {
                return existingBitmapHandle->As<BitmapHandle>();
            }
            else
            {
                return std::make_shared<BitmapHandle>(theHandle, ownsHandle);
            }
        }


        HWIN_EXPORT SIZE BitmapHandle::Size() const
        {
            SIZE result = {0,};
            HBITMAP hBitmap = GetHBITMAP();
            if(hBitmap)
            {
                if(GetBitmapDimensionEx(hBitmap,&result) == FALSE)
                {
                    ThrowLastOSError();
                }
            }
            return result;
        }


        HWIN_EXPORT std::shared_ptr<BitmapHandle> BitmapHandle::LoadFromFile(const String& theFileMame)
        {
            using namespace harlinn::windows::imaging;

            auto factory = ImagingFactory::Create();
            auto decoder = factory.CreateDecoderFromFilename(theFileMame);
            auto frame = decoder.GetFrame(0);
            auto result = frame.AsBitmapHandle();
            return result;

        /*
            IWICImagingFactory *pIWICFactory = nullptr;
            IWICBitmapDecoder *pDecoder = nullptr;
            IWICBitmapFrameDecode *pFrame = nullptr;
            IWICBitmapSource *pBitmapSource = nullptr;
            IWICBitmapSource *pConvertedBitmapSource = nullptr;
            IWICFormatConverter *pConverter = nullptr;
            HRESULT hr = CoCreateInstance(CLSID_WICImagingFactory,NULL,CLSCTX_INPROC_SERVER,IID_PPV_ARGS(&pIWICFactory));
            CheckHRESULT(hr);
            UnknownPtr<IWICImagingFactory> imagingFactory(pIWICFactory);

            hr = imagingFactory->CreateDecoderFromFilename(theFileMame.c_str(),NULL,GENERIC_READ,WICDecodeMetadataCacheOnDemand,&pDecoder);
            CheckHRESULT(hr);
            UnknownPtr<IWICBitmapDecoder> decoder(pDecoder);
            
            hr = decoder->GetFrame(0,&pFrame);
            CheckHRESULT(hr);
            UnknownPtr<IWICBitmapFrameDecode> frame(pFrame);

            hr = pFrame->QueryInterface(IID_IWICBitmapSource, reinterpret_cast<void **>(&pBitmapSource));
            CheckHRESULT(hr);
            UnknownPtr<IWICBitmapSource> bitmapSource(pBitmapSource);
            
            hr = imagingFactory->CreateFormatConverter(&pConverter);
            CheckHRESULT(hr);
            UnknownPtr<IWICFormatConverter> converter(pConverter);
            
            hr = converter->Initialize(pBitmapSource,GUID_WICPixelFormat32bppBGR,WICBitmapDitherTypeNone,NULL,0.f,WICBitmapPaletteTypeCustom);
            CheckHRESULT(hr);

            hr = converter->QueryInterface(IID_PPV_ARGS(&pConvertedBitmapSource));
            CheckHRESULT(hr);
            UnknownPtr<IWICBitmapSource> convertedBitmapSource(pConvertedBitmapSource);

            UINT width = 0;
            UINT height = 0;
            hr = convertedBitmapSource->GetSize(&width, &height);
            CheckHRESULT(hr);

            BITMAPINFO bminfo;
            memset(&bminfo, 0,sizeof(bminfo));
            bminfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
            bminfo.bmiHeader.biWidth = width;
            bminfo.bmiHeader.biHeight = -(LONG)height; //top-down DIB with origin in the upper-left corner
            bminfo.bmiHeader.biPlanes = 1;
            bminfo.bmiHeader.biBitCount = 32;
            bminfo.bmiHeader.biCompression  = BI_RGB;

            HDC hdcScreen = GetDC(NULL);
            if(!hdcScreen)
            {
                ThrowLastOSError();
            }

            BYTE *imageBits = NULL;

            HBITMAP hBitmap = CreateDIBSection(hdcScreen, &bminfo, DIB_RGB_COLORS,(void**)&imageBits, NULL, 0);
            ReleaseDC(NULL, hdcScreen);
            if(!hBitmap)
            {
                ThrowLastOSError();
            }

            UINT strideSize = width * 4;
            UINT imageByteCount = strideSize*height;
            hr = convertedBitmapSource->CopyPixels(NULL,strideSize,imageByteCount, imageBits);
            
            if (FAILED(hr))
            {
                DeleteObject(hBitmap);
                CheckHRESULT(hr);
            }

            auto result = std::make_shared<BitmapHandle>(hBitmap,true);
            return result;
            */

        }



        // ----------------------------------------------------------------------
        // IconHandle
        // ----------------------------------------------------------------------
        HWIN_EXPORT std::shared_ptr<IconHandle> IconHandle::Question = std::make_shared<IconHandle>(OIC_QUES);
        HWIN_EXPORT std::shared_ptr<IconHandle> IconHandle::WinLogo = std::make_shared<IconHandle>(OIC_WINLOGO);
        HWIN_EXPORT std::shared_ptr<IconHandle> IconHandle::Warning = std::make_shared<IconHandle>(OIC_WARNING);
        HWIN_EXPORT std::shared_ptr<IconHandle> IconHandle::Error = std::make_shared<IconHandle>(OIC_ERROR);
        HWIN_EXPORT std::shared_ptr<IconHandle> IconHandle::Information = std::make_shared<IconHandle>(OIC_INFORMATION);
        HWIN_EXPORT std::shared_ptr<IconHandle> IconHandle::Shield = std::make_shared<IconHandle>(OIC_SHIELD);

        HWIN_EXPORT std::shared_ptr<IconHandle> IconHandle::Question16x16 = std::make_shared<IconHandle>(OIC_QUES,16,16);
        HWIN_EXPORT std::shared_ptr<IconHandle> IconHandle::WinLogo16x16 = std::make_shared<IconHandle>(OIC_WINLOGO,16,16);
        HWIN_EXPORT std::shared_ptr<IconHandle> IconHandle::Warning16x16 = std::make_shared<IconHandle>(OIC_WARNING,16,16);
        HWIN_EXPORT std::shared_ptr<IconHandle> IconHandle::Error16x16 = std::make_shared<IconHandle>(OIC_ERROR,16,16);
        HWIN_EXPORT std::shared_ptr<IconHandle> IconHandle::Information16x16 = std::make_shared<IconHandle>(OIC_INFORMATION,16,16);
        HWIN_EXPORT std::shared_ptr<IconHandle> IconHandle::Shield16x16 = std::make_shared<IconHandle>(OIC_SHIELD,16,16);

        HWIN_EXPORT std::shared_ptr<IconHandle> IconHandle::Question24x24 = std::make_shared<IconHandle>(OIC_QUES,24,24);
        HWIN_EXPORT std::shared_ptr<IconHandle> IconHandle::WinLogo24x24 = std::make_shared<IconHandle>(OIC_WINLOGO,24,24);
        HWIN_EXPORT std::shared_ptr<IconHandle> IconHandle::Warning24x24 = std::make_shared<IconHandle>(OIC_WARNING,24,24);
        HWIN_EXPORT std::shared_ptr<IconHandle> IconHandle::Error24x24 = std::make_shared<IconHandle>(OIC_ERROR,24,24);
        HWIN_EXPORT std::shared_ptr<IconHandle> IconHandle::Information24x24 = std::make_shared<IconHandle>(OIC_INFORMATION,24,24);
        HWIN_EXPORT std::shared_ptr<IconHandle> IconHandle::Shield24x24 = std::make_shared<IconHandle>(OIC_SHIELD,24,24);

        HWIN_EXPORT std::shared_ptr<IconHandle> IconHandle::Question32x32 = std::make_shared<IconHandle>(OIC_QUES,32,32);
        HWIN_EXPORT std::shared_ptr<IconHandle> IconHandle::WinLogo32x32 = std::make_shared<IconHandle>(OIC_WINLOGO,32,32);
        HWIN_EXPORT std::shared_ptr<IconHandle> IconHandle::Warning32x32 = std::make_shared<IconHandle>(OIC_WARNING,32,32);
        HWIN_EXPORT std::shared_ptr<IconHandle> IconHandle::Error32x32 = std::make_shared<IconHandle>(OIC_ERROR,32,32);
        HWIN_EXPORT std::shared_ptr<IconHandle> IconHandle::Information32x32 = std::make_shared<IconHandle>(OIC_INFORMATION,32,32);
        HWIN_EXPORT std::shared_ptr<IconHandle> IconHandle::Shield32x32 = std::make_shared<IconHandle>(OIC_SHIELD,32,32);


        HWIN_EXPORT IconHandle::IconHandle(HICON hIcon, bool closeHandle)
            : Base(hIcon, closeHandle)
        {
        }


        HWIN_EXPORT IconHandle::IconHandle(int resourceId, int width, int height,DWORD flags)
        {
            HANDLE hIcon = LoadImage(0,MAKEINTRESOURCE(resourceId),IMAGE_ICON,width,height,flags);
            if(!hIcon)
            {
                ThrowLastOSError();
            }
            SetValue(hIcon, flags & LR_SHARED? false:true);
            
        }

        HWIN_EXPORT IconHandle::IconHandle(const wchar_t* theIconName, int width, int height,DWORD flags)
        {
            CheckPointerNotNull(theIconName);
            HANDLE hIcon = LoadImage(0,theIconName,IMAGE_ICON,width,height,flags);
            if(!hIcon)
            {
                ThrowLastOSError();
            }
            SetValue(hIcon, flags & LR_SHARED? false:true);
        }

        

        HWIN_EXPORT IconHandle::IconHandle(const String& theIconName, int width, int height,DWORD flags)
        {
            HANDLE hIcon = LoadImage(0,theIconName.c_str(),IMAGE_ICON,width,height,flags);
            if(!hIcon)
            {
                ThrowLastOSError();
            }
            SetValue(hIcon, flags & LR_SHARED? false:true);
        }
        HWIN_EXPORT IconHandle::IconHandle(std::shared_ptr<String> theIconName, int width, int height,DWORD flags)
        {
            CheckPointerNotNull(theIconName);
            HANDLE hIcon = LoadImage(0,theIconName->c_str(),IMAGE_ICON,width,height,flags);
            if(!hIcon)
            {
                ThrowLastOSError();
            }
            SetValue(hIcon, flags & LR_SHARED? false:true);
        }


        HWIN_EXPORT IconHandle::IconHandle(std::shared_ptr<ModuleHandle> theModule, int resourceId, int width, int height,DWORD flags)
        {
            HINSTANCE hInstance = 0;
            if(theModule)
            {
                hInstance = static_cast<HINSTANCE>( theModule->Value() );
            }
            HANDLE hIcon = LoadImage(hInstance,MAKEINTRESOURCE(resourceId),IMAGE_ICON,width,height,flags);
            if(!hIcon)
            {
                ThrowLastOSError();
            }
            SetValue(hIcon, flags & LR_SHARED? false:true);
        }

        HWIN_EXPORT IconHandle::IconHandle(std::shared_ptr<ModuleHandle> theModule, const wchar_t* theIconName, int width, int height,DWORD flags)
        {
            HINSTANCE hInstance = 0;
            if(theModule)
            {
                hInstance = static_cast<HINSTANCE>( theModule->Value() );
            }
            CheckPointerNotNull(theIconName);
            HANDLE hIcon = LoadImage(hInstance,theIconName,IMAGE_ICON,width,height,flags);
            if(!hIcon)
            {
                ThrowLastOSError();
            }
            SetValue(hIcon, flags & LR_SHARED? false:true);
        }
        HWIN_EXPORT IconHandle::IconHandle(std::shared_ptr<ModuleHandle> theModule, const String& theIconName, int width, int height,DWORD flags)
        {
            HINSTANCE hInstance = 0;
            if(theModule)
            {
                hInstance = static_cast<HINSTANCE>( theModule->Value() );
            }
            HANDLE hIcon = LoadImage(hInstance,theIconName.c_str(),IMAGE_ICON,width,height,flags);
            if(!hIcon)
            {
                ThrowLastOSError();
            }
            SetValue(hIcon, flags & LR_SHARED? false:true);
        }
        HWIN_EXPORT IconHandle::IconHandle(std::shared_ptr<ModuleHandle> theModule, std::shared_ptr<String> theIconName, int width, int height,DWORD flags)
        {
            HINSTANCE hInstance = 0;
            if(theModule)
            {
                hInstance = static_cast<HINSTANCE>( theModule->Value() );
            }
            CheckPointerNotNull(theIconName);
            HANDLE hIcon = LoadImage(hInstance,theIconName->c_str(),IMAGE_ICON,width,height,flags);
            if(!hIcon)
            {
                ThrowLastOSError();
            }
            SetValue(hIcon, flags & LR_SHARED? false:true);
        }

        HWIN_EXPORT IconHandle::~IconHandle()
        {
            if(OwnsHandle() && Value())
            {
                DestroyIcon(static_cast<HICON>( Value() ));
            }
        }

        // ----------------------------------------------------------------------
        // CursorHandle
        // ----------------------------------------------------------------------
        HWIN_EXPORT std::shared_ptr<CursorHandle> CursorHandle::Normal = std::make_shared<CursorHandle>(OCR_NORMAL);
        HWIN_EXPORT std::shared_ptr<CursorHandle> CursorHandle::IBeam = std::make_shared<CursorHandle>(OCR_IBEAM);
        HWIN_EXPORT std::shared_ptr<CursorHandle> CursorHandle::Wait = std::make_shared<CursorHandle>(OCR_WAIT);
        HWIN_EXPORT std::shared_ptr<CursorHandle> CursorHandle::Cross = std::make_shared<CursorHandle>(OCR_CROSS);
        HWIN_EXPORT std::shared_ptr<CursorHandle> CursorHandle::Up = std::make_shared<CursorHandle>(OCR_UP);
        HWIN_EXPORT std::shared_ptr<CursorHandle> CursorHandle::Size = std::make_shared<CursorHandle>(OCR_SIZEALL);
        HWIN_EXPORT std::shared_ptr<CursorHandle> CursorHandle::SizeNWSE = std::make_shared<CursorHandle>(OCR_SIZENWSE);
        HWIN_EXPORT std::shared_ptr<CursorHandle> CursorHandle::SizeNESW = std::make_shared<CursorHandle>(OCR_SIZENESW);
        HWIN_EXPORT std::shared_ptr<CursorHandle> CursorHandle::SizeWE = std::make_shared<CursorHandle>(OCR_SIZEWE);
        HWIN_EXPORT std::shared_ptr<CursorHandle> CursorHandle::SizeNS = std::make_shared<CursorHandle>(OCR_SIZENS);
        HWIN_EXPORT std::shared_ptr<CursorHandle> CursorHandle::No = std::make_shared<CursorHandle>(OCR_NO);
        HWIN_EXPORT std::shared_ptr<CursorHandle> CursorHandle::Hand = std::make_shared<CursorHandle>(OCR_HAND);
        HWIN_EXPORT std::shared_ptr<CursorHandle> CursorHandle::AppStarting = std::make_shared<CursorHandle>(OCR_APPSTARTING);


        HWIN_EXPORT CursorHandle::CursorHandle(int resourceId, int width, int height,DWORD flags)
        {
            HANDLE hCursor = LoadImage(0,MAKEINTRESOURCE(resourceId),IMAGE_CURSOR,width,height,flags);
            if(!hCursor)
            {
                ThrowLastOSError();
            }
            SetValue(hCursor, flags & LR_SHARED? false:true);
            
        }

        HWIN_EXPORT CursorHandle::CursorHandle(const wchar_t* theCursorName, int width, int height,DWORD flags)
        {
            CheckPointerNotNull(theCursorName);
            HANDLE hCursor = LoadImage(0,theCursorName,IMAGE_CURSOR,width,height,flags);
            if(!hCursor)
            {
                ThrowLastOSError();
            }
            SetValue(hCursor, flags & LR_SHARED? false:true);
        }

        

        HWIN_EXPORT CursorHandle::CursorHandle(const String& theCursorName, int width, int height,DWORD flags)
        {
            HANDLE hCursor = LoadImage(0,theCursorName.c_str(),IMAGE_CURSOR,width,height,flags);
            if(!hCursor)
            {
                ThrowLastOSError();
            }
            SetValue(hCursor, flags & LR_SHARED? false:true);
        }
        HWIN_EXPORT CursorHandle::CursorHandle(std::shared_ptr<String> theCursorName, int width, int height,DWORD flags)
        {
            CheckPointerNotNull(theCursorName);
            HANDLE hCursor = LoadImage(0,theCursorName->c_str(),IMAGE_CURSOR,width,height,flags);
            if(!hCursor)
            {
                ThrowLastOSError();
            }
            SetValue(hCursor, flags & LR_SHARED? false:true);
        }


        HWIN_EXPORT CursorHandle::CursorHandle(std::shared_ptr<ModuleHandle> theModule, int resourceId, int width, int height,DWORD flags)
        {
            HINSTANCE hInstance = 0;
            if(theModule)
            {
                hInstance = static_cast<HINSTANCE>( theModule->Value() );
            }
            HANDLE hCursor = LoadImage(hInstance,MAKEINTRESOURCE(resourceId),IMAGE_CURSOR,width,height,flags);
            if(!hCursor)
            {
                ThrowLastOSError();
            }
            SetValue(hCursor, flags & LR_SHARED? false:true);
        }

        HWIN_EXPORT CursorHandle::CursorHandle(std::shared_ptr<ModuleHandle> theModule, const wchar_t* theCursorName, int width, int height,DWORD flags)
        {
            HINSTANCE hInstance = 0;
            if(theModule)
            {
                hInstance = static_cast<HINSTANCE>( theModule->Value() );
            }
            CheckPointerNotNull(theCursorName);
            HANDLE hCursor = LoadImage(hInstance,theCursorName,IMAGE_CURSOR,width,height,flags);
            if(!hCursor)
            {
                ThrowLastOSError();
            }
            SetValue(hCursor, flags & LR_SHARED? false:true);
        }
        HWIN_EXPORT CursorHandle::CursorHandle(std::shared_ptr<ModuleHandle> theModule, const String& theCursorName, int width, int height,DWORD flags)
        {
            HINSTANCE hInstance = 0;
            if(theModule)
            {
                hInstance = static_cast<HINSTANCE>( theModule->Value() );
            }
            HANDLE hCursor = LoadImage(hInstance,theCursorName.c_str(),IMAGE_CURSOR,width,height,flags);
            if(!hCursor)
            {
                ThrowLastOSError();
            }
            SetValue(hCursor, flags & LR_SHARED? false:true);
        }
        HWIN_EXPORT CursorHandle::CursorHandle(std::shared_ptr<ModuleHandle> theModule, std::shared_ptr<String> theCursorName, int width, int height,DWORD flags)
        {
            HINSTANCE hInstance = 0;
            if(theModule)
            {
                hInstance = static_cast<HINSTANCE>( theModule->Value() );
            }
            CheckPointerNotNull(theCursorName);
            HANDLE hCursor = LoadImage(hInstance,theCursorName->c_str(),IMAGE_CURSOR,width,height,flags);
            if(!hCursor)
            {
                ThrowLastOSError();
            }
            SetValue(hCursor, flags & LR_SHARED? false:true);
        }

        HWIN_EXPORT CursorHandle::~CursorHandle()
        {
            if(OwnsHandle() && Value())
            {
                DestroyCursor(static_cast<HICON>( Value() ));
            }
        }


        // ----------------------------------------------------------------------
        // Menu
        // ----------------------------------------------------------------------

        HWIN_EXPORT MenuHandle::MenuHandle(HMENU hMenu, bool ownsHandle)
            : Base(hMenu,ownsHandle)
        {
        }

        HWIN_EXPORT MenuHandle::~MenuHandle( )
        {
            HMENU hMenu = GetHMENU();
            if(OwnsHandle() && hMenu)
            {
                DestroyMenu(hMenu);
            }
        }


        HWIN_EXPORT MenuHandle& MenuHandle::AddStyle(DWORD style)
        {
            MENUINFO menuinfo = {sizeof(menuinfo),0};
            menuinfo.fMask = MIM_STYLE;
            GetMenuInfo(menuinfo);
            menuinfo.dwStyle |= style;
            SetMenuInfo(menuinfo);

            return *this;
        }




        HWIN_EXPORT MenuHandle& MenuHandle::AppendMenu(UINT uFlags,UINT_PTR uIDNewItem,const wchar_t* newItem)
        {
            if(::AppendMenu(GetHMENU(),uFlags,uIDNewItem,newItem) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }
        HWIN_EXPORT MenuHandle& MenuHandle::CheckMenuRadioItem(UINT idFirst,UINT idLast,UINT idCheck,UINT uFlags)
        {
            if(::CheckMenuRadioItem(GetHMENU(),idFirst,idLast,idCheck,uFlags) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }
        HWIN_EXPORT MenuHandle& MenuHandle::DeleteMenu(UINT position,UINT uFlags)
        {
            if(::DeleteMenu(GetHMENU(),position,uFlags) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }
        HWIN_EXPORT MenuHandle& MenuHandle::EnableMenuItem(UINT idOfItem, UINT enableFlags)
        {
            if(::EnableMenuItem(GetHMENU(),idOfItem, enableFlags) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }
        HWIN_EXPORT void MenuHandle::EndMenu( )
        {
            if(::EndMenu( ) == FALSE)
            {
                ThrowLastOSError();
            }
        }

        HWIN_EXPORT long MenuHandle::GetCheckMarkDimensions()
        {
            return ::GetMenuCheckMarkDimensions();
        }

        HWIN_EXPORT UINT MenuHandle::GetMenuDefaultItem(bool byPosition, UINT flags)
        {
            UINT result = ::GetMenuDefaultItem(GetHMENU(),byPosition, flags);
            if( result == -1)
            {
                ThrowLastOSError();
            }
            return result;
        }


        HWIN_EXPORT const MenuHandle& MenuHandle::GetMenuInfo(LPMENUINFO lpcmi) const
        {
            if(::GetMenuInfo(GetHMENU(),lpcmi) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }

        HWIN_EXPORT const MenuHandle& MenuHandle::GetMenuInfo(MENUINFO& lpcmi) const
        {
            if(::GetMenuInfo(GetHMENU(),&lpcmi) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }
        HWIN_EXPORT std::shared_ptr<MENUINFO> MenuHandle::GetMenuInfo( ) const
        {
            MENUINFO menuinfo = {sizeof(MENUINFO),0,};
            if(::GetMenuInfo(GetHMENU(),&menuinfo) == FALSE)
            {
                ThrowLastOSError();
            }
            return std::make_shared<MENUINFO>(menuinfo);
        }


        HWIN_EXPORT int MenuHandle::GetMenuItemCount( ) const
        {
            int result = ::GetMenuItemCount( GetHMENU() );
            if(result == -1)
            {
                ThrowLastOSError();
            }
            return result;
        }

        HWIN_EXPORT UINT MenuHandle::GetMenuItemID(int menuItemPosition) const
        {
            UINT result = ::GetMenuItemID( GetHMENU(), menuItemPosition);
            if(result == -1)
            {
                ThrowLastOSError();
            }
            return result;
        }


        HWIN_EXPORT const MenuHandle& MenuHandle::GetMenuItemInfo(UINT utemIdOrPosition, bool byPosition,LPMENUITEMINFO lpmii) const
        {
            if(::GetMenuItemInfo(GetHMENU(),utemIdOrPosition,byPosition,lpmii) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }
        HWIN_EXPORT const MenuHandle& MenuHandle::GetMenuItemInfo(UINT utemIdOrPosition, bool byPosition,MENUITEMINFO& lpmii) const
        {
            if(::GetMenuItemInfo(GetHMENU(),utemIdOrPosition,byPosition,&lpmii) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }
        HWIN_EXPORT std::shared_ptr<MENUITEMINFO> MenuHandle::GetMenuItemInfo(UINT utemIdOrPosition, bool byPosition) const
        {
            MENUITEMINFO menuiteminfo = {sizeof(MENUITEMINFO),0};
            if(::GetMenuItemInfo(GetHMENU(),utemIdOrPosition,byPosition,&menuiteminfo) == FALSE)
            {
                ThrowLastOSError();
            }
            return std::make_shared<MENUITEMINFO>(menuiteminfo);
        }

        HWIN_EXPORT UINT MenuHandle::GetMenuState(UINT itemIdOrPosition,bool byPosition) const
        {
            UINT result = ::GetMenuState( GetHMENU(), itemIdOrPosition,byPosition?MF_BYPOSITION:MF_BYCOMMAND);
            if(result == -1)
            {
                ThrowLastOSError();
            }
            return result;
        }

        HWIN_EXPORT int MenuHandle::GetMenuStringLength(UINT itemIdOrPosition,bool byPosition) const
        {
            int result = ::GetMenuString( GetHMENU(), itemIdOrPosition,nullptr,0,byPosition?MF_BYPOSITION:MF_BYCOMMAND);
            return result;
        }
        HWIN_EXPORT int MenuHandle::GetMenuString(UINT itemIdOrPosition,LPTSTR lpString,int nMaxCount,bool byPosition) const
        {
            int result = ::GetMenuString( GetHMENU(), itemIdOrPosition,lpString,nMaxCount,byPosition?MF_BYPOSITION:MF_BYCOMMAND);
            return result;
        }
        HWIN_EXPORT std::shared_ptr<String> MenuHandle::GetMenuString(UINT itemIdOrPosition,bool byPosition) const
        {
            int length = GetMenuStringLength(itemIdOrPosition,byPosition);
            if(length)
            {
                std::shared_ptr<String> result = std::make_shared<String>(size_t(length),'\x0');
                ::GetMenuString( GetHMENU(), itemIdOrPosition,const_cast<wchar_t*>(result->c_str()),length,byPosition?MF_BYPOSITION:MF_BYCOMMAND);
                return result;
            }
            return std::shared_ptr<String>();
        }

        HWIN_EXPORT HMENU MenuHandle::GetSubMenu(int position) const
        {
            HMENU result = ::GetSubMenu( GetHMENU(), position);
            
            return result;
        }


        HWIN_EXPORT MenuHandle& MenuHandle::InsertMenu(UINT uPosition,UINT uFlags, UINT_PTR itemIdOrPosition,LPCTSTR lpNewItem)
        {
            if(::InsertMenu(GetHMENU(),uPosition,uFlags, itemIdOrPosition,lpNewItem) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }

        HWIN_EXPORT MenuHandle& MenuHandle::InsertMenuItem(UINT itemIdOrPosition,bool byPosition,LPCMENUITEMINFO lpmii)
        {
            if(::InsertMenuItem(GetHMENU(),itemIdOrPosition,byPosition,lpmii) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }
        HWIN_EXPORT MenuHandle& MenuHandle::InsertMenuItem(UINT itemIdOrPosition,bool byPosition,const MENUITEMINFO& lpmii)
        {
            if(::InsertMenuItem(GetHMENU(),itemIdOrPosition,byPosition,&lpmii) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }


        HWIN_EXPORT bool MenuHandle::IsMenu() const
        {
            return ::IsMenu(GetHMENU()) != FALSE;
        }

        HWIN_EXPORT std::shared_ptr<MenuHandle> MenuHandle::LoadMenu(LPCTSTR lpMenuName)
        {
            return LoadMenu(ModuleHandle::Current(),lpMenuName);
        }
        HWIN_EXPORT std::shared_ptr<MenuHandle> MenuHandle::LoadMenu(std::shared_ptr<ModuleHandle> module,LPCTSTR lpMenuName)
        {
            HINSTANCE hInstance = module->GetHMODULE();
            return LoadMenu(hInstance,lpMenuName);
        }
        HWIN_EXPORT std::shared_ptr<MenuHandle> MenuHandle::LoadMenu(HINSTANCE module,LPCTSTR lpMenuName)
        {
            HMENU hMenu = ::LoadMenu(module,lpMenuName);
            if(!hMenu)
            {
                ThrowLastOSError();
            }
            std::shared_ptr<MenuHandle> result = std::make_shared<MenuHandle>(hMenu,false);
            return result;
        }


        HWIN_EXPORT MenuHandle& MenuHandle::ModifyMenu(UINT uPosition,UINT uFlags,UINT_PTR uIDNewItem,LPCTSTR lpNewItem)
        {
            if(::ModifyMenu(GetHMENU(),uPosition,uFlags,uIDNewItem,lpNewItem) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }

        HWIN_EXPORT MenuHandle& MenuHandle::RemoveMenu(UINT uPosition,UINT uFlags)
        {
            if(::RemoveMenu(GetHMENU(),uPosition,uFlags) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }

        HWIN_EXPORT MenuHandle& MenuHandle::SetMenuDefaultItem(UINT itemIdOrPosition,bool byPosition)
        {
            if(::SetMenuDefaultItem(GetHMENU(),itemIdOrPosition,byPosition) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }


        HWIN_EXPORT MenuHandle& MenuHandle::SetMenuItemInfo(UINT uItem, BOOL fByPosition, LPMENUITEMINFO lpmii)
        {
            if(::SetMenuItemInfo(GetHMENU(),uItem, fByPosition, lpmii) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }
        HWIN_EXPORT MenuHandle& MenuHandle::SetMenuInfo(LPCMENUINFO lpcmi)
        {
            if(::SetMenuInfo(GetHMENU(),lpcmi) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }

        HWIN_EXPORT MenuHandle& MenuHandle::SetMenuInfo(const MENUINFO& lpcmi)
        {
            if(::SetMenuInfo(GetHMENU(),&lpcmi) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }

        HWIN_EXPORT MenuHandle& MenuHandle::SetMenuItemBitmaps(UINT itemIdOrPosition,bool byPosition,HBITMAP hBitmapUnchecked,HBITMAP hBitmapChecked)
        {
            if(::SetMenuItemBitmaps(GetHMENU(),itemIdOrPosition,byPosition,hBitmapUnchecked,hBitmapChecked) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }

        // ----------------------------------------------------------------------
        // BrushHandle
        // ----------------------------------------------------------------------
        BrushHandle::map_t BrushHandle::map;
        HWIN_EXPORT void BrushHandle::AddHandleToMap(HBRUSH hElement,BrushHandle* theHandle)
        {
            auto it = map.find(hElement);
            if(it ==  map.end())
            {
                map.insert( map_t::value_type(hElement,theHandle));
            }
        }
        HWIN_EXPORT BrushHandle* BrushHandle::GetHandleFromMap(HBRUSH hElement)
        {
            auto it = map.find(hElement);
            if(it !=  map.end())
            {
                auto result = (*it).second;
                return result;
            }
            return nullptr;
        }

        HWIN_EXPORT void BrushHandle::RemoveHandleFromMap(HBRUSH hElement)
        {
            map.erase(hElement);
        }

        HWIN_EXPORT BrushHandle::BrushHandle(HBRUSH theHandle, bool ownsHandle )
            : Base(theHandle, ownsHandle)
        {
            if(theHandle)
            {
                AddHandleToMap(theHandle,this);
            }
        }

        HWIN_EXPORT BrushHandle::BrushHandle(const LOGBRUSH& theLogBrush)
            : Base(CreateBrushIndirect(&theLogBrush),true)
        {
            if(!GetHBRUSH())
            {
                ThrowLastOSError();
            }
            AddHandleToMap(GetHBRUSH(),this);
        }
        HWIN_EXPORT BrushHandle::BrushHandle(std::shared_ptr<const LOGBRUSH> theLogBrush)
            : Base(CreateBrushIndirect(theLogBrush.get()),true)
        {
            if(!GetHBRUSH())
            {
                ThrowLastOSError();
            }
            AddHandleToMap(GetHBRUSH(),this);
        }
        HWIN_EXPORT BrushHandle::BrushHandle(COLORREF color)
            : Base(CreateSolidBrush(color),true)
        {
            if(!GetHBRUSH())
            {
                ThrowLastOSError();
            }
            AddHandleToMap(GetHBRUSH(),this);
        }

        HWIN_EXPORT BrushHandle::BrushHandle(SysColor sysColor)
            : Base(GetSysColorBrush( int(sysColor)),false)
        {
            if(!GetHBRUSH())
            {
                ThrowLastOSError();
            }
            AddHandleToMap(GetHBRUSH(),this); // <-- This probably doesn't work as well as intended
        }


        HWIN_EXPORT BrushHandle::~BrushHandle( )
        {
            HBRUSH theHandle = GetHBRUSH();
            if(theHandle)
            {
                RemoveHandleFromMap(theHandle);
            }
            if(OwnsHandle() && theHandle)
            {
                DeleteObject(theHandle);
            }
        }


        // ----------------------------------------------------------------------
        // PenHandle
        // ----------------------------------------------------------------------
        PenHandle::map_t PenHandle::map;
        HWIN_EXPORT void PenHandle::AddHandleToMap(HPEN hElement,PenHandle* theHandle)
        {
            auto it = map.find(hElement);
            if(it ==  map.end())
            {
                map.insert( map_t::value_type(hElement,theHandle));
            }
        }
        HWIN_EXPORT PenHandle* PenHandle::GetHandleFromMap(HPEN hElement)
        {
            auto it = map.find(hElement);
            if(it !=  map.end())
            {
                auto result = (*it).second;
                return result;
            }
            return nullptr;
        }

        HWIN_EXPORT void PenHandle::RemoveHandleFromMap(HPEN hElement)
        {
            map.erase(hElement);
        }

        HWIN_EXPORT PenHandle::PenHandle(HPEN theHandle, bool ownsHandle )
            : Base(theHandle, ownsHandle)
        {
            if(theHandle)
            {
                AddHandleToMap(theHandle,this);
            }
        }

        HWIN_EXPORT PenHandle::~PenHandle( )
        {
            HPEN theHandle = GetHPEN();
            if(theHandle)
            {
                RemoveHandleFromMap(theHandle);
            }
            if(OwnsHandle() && theHandle)
            {
                DeleteObject(theHandle);
            }
        }


        // ----------------------------------------------------------------------
        // FontHandle
        // ----------------------------------------------------------------------
        FontHandle::map_t FontHandle::map;
        HWIN_EXPORT void FontHandle::AddHandleToMap(HFONT hElement,FontHandle* theHandle)
        {
            auto it = map.find(hElement);
            if(it ==  map.end())
            {
                map.insert( map_t::value_type(hElement,theHandle));
            }
        }
        HWIN_EXPORT FontHandle* FontHandle::GetHandleFromMap(HFONT hElement)
        {
            auto it = map.find(hElement);
            if(it !=  map.end())
            {
                auto result = (*it).second;
                return result;
            }
            return nullptr;
        }

        HWIN_EXPORT void FontHandle::RemoveHandleFromMap(HFONT hElement)
        {
            map.erase(hElement);
        }

        HWIN_EXPORT FontHandle::FontHandle(HFONT theHandle, bool ownsHandle )
            : Base(theHandle, ownsHandle)
        {
            if(theHandle)
            {
                AddHandleToMap(theHandle,this);
            }
        }

        HWIN_EXPORT FontHandle::~FontHandle( )
        {
            HFONT theHandle = GetHFONT();
            if(theHandle)
            {
                RemoveHandleFromMap(theHandle);
            }
            if(OwnsHandle() && theHandle)
            {
                DeleteObject(theHandle);
            }
        }


        // ----------------------------------------------------------------------
        // RegionHandle
        // ----------------------------------------------------------------------
        RegionHandle::map_t RegionHandle::map;
        HWIN_EXPORT void RegionHandle::AddHandleToMap(HRGN hElement,RegionHandle* theHandle)
        {
            auto it = map.find(hElement);
            if(it ==  map.end())
            {
                map.insert( map_t::value_type(hElement,theHandle));
            }
        }
        HWIN_EXPORT RegionHandle* RegionHandle::GetHandleFromMap(HRGN hElement)
        {
            auto it = map.find(hElement);
            if(it !=  map.end())
            {
                auto result = (*it).second;
                return result;
            }
            return nullptr;
        }

        HWIN_EXPORT void RegionHandle::RemoveHandleFromMap(HRGN hElement)
        {
            map.erase(hElement);
        }

        HWIN_EXPORT RegionHandle::RegionHandle(HRGN theHandle, bool ownsHandle )
            : Base(theHandle, ownsHandle)
        {
            if(theHandle)
            {
                AddHandleToMap(theHandle,this);
            }
        }

        HWIN_EXPORT RegionHandle::~RegionHandle( )
        {
            HRGN theHandle = GetHRGN();
            if(theHandle)
            {
                RemoveHandleFromMap(theHandle);
            }
            if(OwnsHandle() && theHandle)
            {
                DeleteObject(theHandle);
            }
        }


        // ----------------------------------------------------------------------
        // PaletteHandle
        // ----------------------------------------------------------------------
        PaletteHandle::map_t PaletteHandle::map;
        HWIN_EXPORT void PaletteHandle::AddHandleToMap(HPALETTE hElement,PaletteHandle* theHandle)
        {
            auto it = map.find(hElement);
            if(it ==  map.end())
            {
                map.insert( map_t::value_type(hElement,theHandle));
            }
        }
        HWIN_EXPORT PaletteHandle* PaletteHandle::GetHandleFromMap(HPALETTE hElement)
        {
            auto it = map.find(hElement);
            if(it !=  map.end())
            {
                auto result = (*it).second;
                return result;
            }
            return nullptr;
        }

        HWIN_EXPORT void PaletteHandle::RemoveHandleFromMap(HPALETTE hElement)
        {
            map.erase(hElement);
        }

        HWIN_EXPORT PaletteHandle::PaletteHandle(HPALETTE theHandle, bool ownsHandle )
            : Base(theHandle, ownsHandle)
        {
            if(theHandle)
            {
                AddHandleToMap(theHandle,this);
            }
        }

        HWIN_EXPORT PaletteHandle::~PaletteHandle( )
        {
            HPALETTE theHandle = GetHPALETTE();
            if(theHandle)
            {
                RemoveHandleFromMap(theHandle);
            }
            if(OwnsHandle() && theHandle)
            {
                DeleteObject(theHandle);
            }
        }


        // ----------------------------------------------------------------------
        // DeviceContextHandle
        // ----------------------------------------------------------------------
        HWIN_EXPORT DeviceContextHandle::DeviceContextHandle( )
            : Base(),originalPen(0),originalBrush(0),originalBitmap(0),originalFont(0)
        {
            
        }

        HWIN_EXPORT DeviceContextHandle::DeviceContextHandle(HDC theHandle, bool ownsHandle)
            : Base(theHandle, ownsHandle),originalPen(0),originalBrush(0),originalBitmap(0),originalFont(0)
        {}

        HWIN_EXPORT DeviceContextHandle::~DeviceContextHandle( )
        {
        }

        HWIN_EXPORT void DeviceContextHandle::SaveDefaultObjects()
        {
            HDC hDC = GetHDC();
            if(hDC)
            {
                originalPen = (HPEN)GetCurrentObject(GetHDC(),OBJ_PEN);
                originalBrush = (HBRUSH)GetCurrentObject(GetHDC(),OBJ_BRUSH);
                originalBitmap = (HBITMAP)GetCurrentObject(GetHDC(),OBJ_BITMAP);
                originalFont = (HFONT)GetCurrentObject(GetHDC(),OBJ_FONT);
            }
        }
        HWIN_EXPORT void DeviceContextHandle::RestoreDefaultObjects()
        {
            HDC hDC = GetHDC();
            if(hDC)
            {
                SelectObject(hDC,originalPen);
                SelectObject(hDC,originalBrush);
                SelectObject(hDC,originalBitmap);
                SelectObject(hDC,originalFont);
            }
        }

        HWIN_EXPORT std::shared_ptr<PenHandle> DeviceContextHandle::Pen() const
        {
            auto hObject = GetCurrentObject(GetHDC(),OBJ_PEN);
            if(!hObject)
            {
                ThrowLastOSError();
            }
            auto ptr = PenHandle::GetHandleFromMap((HPEN)hObject);
            if(ptr)
            {
                return ptr->As<PenHandle>();
            }
            return std::make_shared<PenHandle>((HPEN)hObject,false);
        }
        HWIN_EXPORT std::shared_ptr<PenHandle> DeviceContextHandle::SetPen(const std::shared_ptr<PenHandle>& newPen)
        {
            auto hObject = SelectObject(GetHDC(),newPen->GetHPEN());
            if(!hObject)
            {
                ThrowLastOSError();
            }
            auto ptr = PenHandle::GetHandleFromMap((HPEN)hObject);
            if(ptr)
            {
                return ptr->As<PenHandle>();
            }
            return std::make_shared<PenHandle>((HPEN)hObject,false);
        }

        HWIN_EXPORT std::shared_ptr<BrushHandle> DeviceContextHandle::Brush() const
        {
            auto hObject = GetCurrentObject(GetHDC(),OBJ_BRUSH);
            if(!hObject)
            {
                ThrowLastOSError();
            }
            auto ptr = BrushHandle::GetHandleFromMap((HBRUSH)hObject);
            if(ptr)
            {
                return ptr->As<BrushHandle>();
            }
            return std::make_shared<BrushHandle>((HBRUSH)hObject,false);
        }
        HWIN_EXPORT std::shared_ptr<BrushHandle> DeviceContextHandle::SetBrush(const std::shared_ptr<BrushHandle>& newBrush)
        {
            auto hObject = SelectObject(GetHDC(),newBrush->GetHBRUSH());
            if(!hObject)
            {
                ThrowLastOSError();
            }
            auto ptr = BrushHandle::GetHandleFromMap((HBRUSH)hObject);
            if(ptr)
            {
                return ptr->As<BrushHandle>();
            }
            return std::make_shared<BrushHandle>((HBRUSH)hObject,false);
        }

        HWIN_EXPORT std::shared_ptr<BitmapHandle> DeviceContextHandle::Bitmap() const
        {
            auto hObject = GetCurrentObject(GetHDC(),OBJ_BITMAP);
            if(!hObject)
            {
                ThrowLastOSError();
            }
            auto ptr = BitmapHandle::GetHandleFromMap((HBITMAP)hObject);
            if(ptr)
            {
                return ptr->As<BitmapHandle>();
            }
            return std::make_shared<BitmapHandle>((HBITMAP)hObject,false);
        }
        HWIN_EXPORT std::shared_ptr<BitmapHandle> DeviceContextHandle::SetBitmap(const std::shared_ptr<BitmapHandle>& newBitmap)
        {
            auto hObject = SelectObject(GetHDC(),newBitmap->GetHBITMAP());
            if(!hObject)
            {
                ThrowLastOSError();
            }
            auto ptr = BitmapHandle::GetHandleFromMap((HBITMAP)hObject);
            if(ptr)
            {
                return ptr->As<BitmapHandle>();
            }
            return std::make_shared<BitmapHandle>((HBITMAP)hObject,false);
        }

        HWIN_EXPORT std::shared_ptr<FontHandle> DeviceContextHandle::Font() const
        {
            auto hObject = GetCurrentObject(GetHDC(),OBJ_FONT);
            if(!hObject)
            {
                ThrowLastOSError();
            }
            auto ptr = FontHandle::GetHandleFromMap((HFONT)hObject);
            if(ptr)
            {
                return ptr->As<FontHandle>();
            }
            return std::make_shared<FontHandle>((HFONT)hObject,false);
        }
        HWIN_EXPORT std::shared_ptr<FontHandle> DeviceContextHandle::SetFont(const std::shared_ptr<FontHandle>& newFont)
        {
            auto hObject = SelectObject(GetHDC(),newFont->GetHFONT());
            if(!hObject)
            {
                ThrowLastOSError();
            }
            auto ptr = FontHandle::GetHandleFromMap((HFONT)hObject);
            if(ptr)
            {
                return ptr->As<FontHandle>();
            }
            return std::make_shared<FontHandle>((HFONT)hObject,false);
        }

        


        HWIN_EXPORT DeviceContextHandle& DeviceContextHandle::DrawCaption(std::shared_ptr<Control> control, const RECT& boundingRectangle, DrawCaptionOptions options)
        {
            CheckPointerNotNull(control);
            if(::DrawCaption(control->GetSafeHandle() ,GetHDC(),&boundingRectangle, UINT(options)) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }


        HWIN_EXPORT DeviceContextHandle& DeviceContextHandle::DrawEdge(RECT& boundingRectangle, BorderStyle borderStyle, BorderFlags borderFlags )
        {
            if(::DrawEdge(GetHDC(),&boundingRectangle, UINT(borderStyle), UINT(borderFlags) ) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }


        HWIN_EXPORT DeviceContextHandle& DeviceContextHandle::DrawFocusRect(RECT& boundingRectangle )
        {
            if(::DrawFocusRect(GetHDC(),&boundingRectangle ) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }


        HWIN_EXPORT DeviceContextHandle& DeviceContextHandle::DrawCaptionFrameControl(DrawFrameControlCaptionPart part, RECT& boundingRectangle, DrawFrameControlOptions options)
        {
            UINT state = UINT(part) | UINT(options);
            if(::DrawFrameControl(GetHDC(),&boundingRectangle,UINT(DrawFrameControlType::Caption),state ) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }

        HWIN_EXPORT DeviceContextHandle& DeviceContextHandle::DrawMenuBarFrameControl(DrawFrameControlMenuBarPart part, RECT& boundingRectangle, DrawFrameControlOptions options)
        {
            UINT state = UINT(part) | UINT(options);
            if(::DrawFrameControl(GetHDC(),&boundingRectangle,UINT(DrawFrameControlType::MenuBar),state ) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }

        HWIN_EXPORT DeviceContextHandle& DeviceContextHandle::DrawScrollBarFrameControl(DrawFrameControlScrollBarPart part, RECT& boundingRectangle, DrawFrameControlOptions options)
        {
            UINT state = UINT(part) | UINT(options);
            if(::DrawFrameControl(GetHDC(),&boundingRectangle,UINT(DrawFrameControlType::ScrollBar),state ) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }

        HWIN_EXPORT DeviceContextHandle& DeviceContextHandle::DrawButtonFrameControl(DrawFrameControlButtonOptions buttonOptions, RECT& boundingRectangle, DrawFrameControlOptions options)
        {
            UINT state = UINT(buttonOptions) | UINT(options);
            if(::DrawFrameControl(GetHDC(),&boundingRectangle,UINT(DrawFrameControlType::Button),state ) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }

        HWIN_EXPORT DeviceContextHandle& DeviceContextHandle::DrawPopupMenuFrameControl(DrawFrameControlPopupMenuPart part, RECT& boundingRectangle, DrawFrameControlOptions options)
        {
            UINT state = UINT(part) | UINT(options);
            if(::DrawFrameControl(GetHDC(),&boundingRectangle,UINT(DrawFrameControlType::PopupMenu),state ) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }


        HWIN_EXPORT DeviceContextHandle& DeviceContextHandle::DrawState(const String& theText, int x,int y,int cx,int cy,DrawStateFlags flags)
        {
            UINT uiFlags = UINT(flags);

            if((uiFlags & DSS_PREFIXONLY) != 0)
            {
                uiFlags &= ~DSS_HIDEPREFIX;
            }
            if((uiFlags & (DSS_HIDEPREFIX | DSS_PREFIXONLY)) != 0)
            {
                uiFlags |= DST_PREFIXTEXT;
            }
            if((uiFlags & DST_PREFIXTEXT) == 0)
            {
                uiFlags |= DST_TEXT;
            }

            if(::DrawState(GetHDC(),nullptr,nullptr,LPARAM(theText.c_str()),WPARAM(theText.length()), x,y,cx,cy, uiFlags) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }

        HWIN_EXPORT DeviceContextHandle& DeviceContextHandle::DrawState(const String& theText, int x,int y,DrawStateFlags flags)
        {
            UINT uiFlags = UINT(flags);

            if((uiFlags & DSS_PREFIXONLY) != 0)
            {
                uiFlags &= ~DSS_HIDEPREFIX;
            }
            if((uiFlags & (DSS_HIDEPREFIX | DSS_PREFIXONLY)) != 0)
            {
                uiFlags |= DST_PREFIXTEXT;
            }
            if((uiFlags & DST_PREFIXTEXT) == 0)
            {
                uiFlags |= DST_TEXT;
            }

            if(::DrawState(GetHDC(),nullptr,nullptr,LPARAM(theText.c_str()),WPARAM(theText.length()), x,y,0,0, uiFlags) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }


        HWIN_EXPORT DeviceContextHandle& DeviceContextHandle::DrawState(std::shared_ptr<BrushHandle> brush, const String& theText, int x,int y,int cx,int cy,DrawStateFlags flags)
        {
            UINT uiFlags = UINT(flags);

            if((uiFlags & DSS_PREFIXONLY) != 0)
            {
                uiFlags &= ~DSS_HIDEPREFIX;
            }
            if((uiFlags & (DSS_HIDEPREFIX | DSS_PREFIXONLY)) != 0)
            {
                uiFlags |= DST_PREFIXTEXT;
            }
            if((uiFlags & DST_PREFIXTEXT) == 0)
            {
                uiFlags |= DST_TEXT;
            }

            HBRUSH hBrush = nullptr;
            if(brush)
            {
                hBrush = brush->GetHBRUSH();
            }

            if(::DrawState(GetHDC(),hBrush,nullptr,LPARAM(theText.c_str()),WPARAM(theText.length()), x,y,cx,cy, uiFlags) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }

        HWIN_EXPORT DeviceContextHandle& DeviceContextHandle:: DrawState(std::shared_ptr<BrushHandle> brush, const String& theText, int x,int y,DrawStateFlags flags)
        {
            UINT uiFlags = UINT(flags);

            if((uiFlags & DSS_PREFIXONLY) != 0)
            {
                uiFlags &= ~DSS_HIDEPREFIX;
            }
            if((uiFlags & (DSS_HIDEPREFIX | DSS_PREFIXONLY)) != 0)
            {
                uiFlags |= DST_PREFIXTEXT;
            }
            if((uiFlags & DST_PREFIXTEXT) == 0)
            {
                uiFlags |= DST_TEXT;
            }
            HBRUSH hBrush = nullptr;
            if(brush)
            {
                hBrush = brush->GetHBRUSH();
            }

            if(::DrawState(GetHDC(),hBrush,nullptr,LPARAM(theText.c_str()),WPARAM(theText.length()), x,y,0,0, uiFlags) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }

        HWIN_EXPORT DeviceContextHandle& DeviceContextHandle::DrawState(std::shared_ptr<BitmapHandle> bitmap, int x,int y,int cx,int cy,DrawStateFlags flags)
        {
            CheckPointerNotNull(bitmap);
            UINT uiFlags = UINT(flags);

            uiFlags |= DST_BITMAP;

            if(::DrawState(GetHDC(),nullptr,nullptr,LPARAM(bitmap->GetHBITMAP()),0, x,y,cx,cy, uiFlags) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }

        HWIN_EXPORT DeviceContextHandle& DeviceContextHandle::DrawState(std::shared_ptr<BitmapHandle> bitmap, int x,int y,DrawStateFlags flags)
        {
            CheckPointerNotNull(bitmap);
            UINT uiFlags = UINT(flags);

            uiFlags |= DST_BITMAP;

            if(::DrawState(GetHDC(),nullptr,nullptr,LPARAM(bitmap->GetHBITMAP()),0, x,y,0,0, uiFlags) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }

        HWIN_EXPORT DeviceContextHandle& DeviceContextHandle::DrawState(std::shared_ptr<IconHandle> icon, int x,int y,int cx,int cy,DrawStateFlags flags)
        {
            CheckPointerNotNull(icon);
            UINT uiFlags = UINT(flags);

            uiFlags |= DST_ICON;

            if(::DrawState(GetHDC(),nullptr,nullptr,LPARAM(icon->GetHICON()),0, x,y,cx,cy, uiFlags) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }

        HWIN_EXPORT DeviceContextHandle& DeviceContextHandle::DrawState(std::shared_ptr<IconHandle> icon, int x,int y,DrawStateFlags flags)
        {
            CheckPointerNotNull(icon);
            UINT uiFlags = UINT(flags);

            uiFlags |= DST_ICON;

            if(::DrawState(GetHDC(),nullptr,nullptr,LPARAM(icon->GetHICON()),0, x,y,0,0, uiFlags) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }

        HWIN_EXPORT RegionType DeviceContextHandle::ExcludeUpdateRgn(std::shared_ptr<Control> control)
        {
            CheckPointerNotNull(control);
            int result = ::ExcludeUpdateRgn(GetHDC(),control->GetSafeHandle());
            if(result == ERROR)
            {
                ThrowLastOSError();
            }
            return RegionType(result);
        }
        HWIN_EXPORT void DeviceContextHandle::Flush()
        {
            if(GdiFlush() == FALSE)
            {
                if(GetLastError())
                {
                    ThrowLastOSError();
                }
            }
        }
        HWIN_EXPORT DWORD DeviceContextHandle::BatchLimit()
        {
            DWORD result = GdiGetBatchLimit();
            if(!result)
            {
                ThrowLastOSError();
            }
            return result;
        }
        HWIN_EXPORT DWORD DeviceContextHandle::SetBatchLimit(DWORD newBatchLimit)
        {
            DWORD result = GdiSetBatchLimit(newBatchLimit);
            if(!result)
            {
                ThrowLastOSError();
            }
            return result;
        }

        HWIN_EXPORT ColorRef DeviceContextHandle::BackgroundColor() const
        {
            ColorRef result = GetBkColor(GetHDC());
            return result;
        }
        HWIN_EXPORT ColorRef DeviceContextHandle::SetBackgroundColor(COLORREF color)
        {
            ColorRef result = SetBkColor(GetHDC(),color);
            if( result.Invalid())
            {
                ThrowLastOSError();
            }
            return result;
        }

        HWIN_EXPORT harlinn::windows::BackgroundMixMode DeviceContextHandle::BackgroundMixMode() const
        {
            int result = GetBkMode(GetHDC());
            if(!result)
            {
                ThrowLastOSError();
            }
            return harlinn::windows::BackgroundMixMode(result);
        }

        HWIN_EXPORT harlinn::windows::BackgroundMixMode DeviceContextHandle::SetBackgroundMixMode(harlinn::windows::BackgroundMixMode mixMode)
        {
            int mode = int(mixMode);
            int result = SetBkMode(GetHDC(),mode);
            if(!result)
            {
                ThrowLastOSError();
            }
            return harlinn::windows::BackgroundMixMode(result);
        }

        HWIN_EXPORT BoundsAccumulationFlags DeviceContextHandle::BoundsRect(RECT& boundingRectangle) const
        {
            int result = GetBoundsRect(GetHDC(),&boundingRectangle,0);
            if(!result)
            {
                ThrowLastOSError();
            }
            return BoundsAccumulationFlags(result);
        }
        HWIN_EXPORT BoundsAccumulationFlags DeviceContextHandle::BoundsRect(RECT& boundingRectangle, bool clear)
        {
            int result = GetBoundsRect(GetHDC(),&boundingRectangle,clear?DCB_RESET:0);
            if(!result)
            {
                ThrowLastOSError();
            }
            return BoundsAccumulationFlags(result);
        }


        HWIN_EXPORT BoundsAccumulationFlags DeviceContextHandle::SetBoundsRect(const RECT& boundingRectangle, BoundsAccumulationFlags flags)
        {
            int iFlags = int(flags);
            int result = ::SetBoundsRect(GetHDC(),&boundingRectangle,iFlags);
            if(!result)
            {
                ThrowLastOSError();
            }
            return BoundsAccumulationFlags(result);
        }

        HWIN_EXPORT harlinn::windows::ForegroundMixMode DeviceContextHandle::ForegroundMixMode() const
        {
            int result = GetROP2(GetHDC());
            if(!result)
            {
                ThrowLastOSError();
            }
            return harlinn::windows::ForegroundMixMode(result);
        }
        HWIN_EXPORT harlinn::windows::ForegroundMixMode DeviceContextHandle::SetForegroundMixMode(harlinn::windows::ForegroundMixMode mixMode)
        {
            int mode = int(mixMode);
            int result = SetROP2(GetHDC(),mode);
            if(!result)
            {
                ThrowLastOSError();
            }
            return harlinn::windows::ForegroundMixMode(result);
        }

        HWIN_EXPORT DeviceContextHandle& DeviceContextHandle::DrawGrayString(const String& theText,int X,int Y,int nWidth,int nHeight)
        {
            if(theText.length())
            {
                if(::GrayString(GetHDC(),nullptr,nullptr,LPARAM(theText.c_str()),int(theText.length()),X,Y,nWidth,nHeight) == 0)
                {
                    ThrowLastOSError();
                }
            }
            return *this;
        }

        HWIN_EXPORT DeviceContextHandle& DeviceContextHandle::DrawGrayString(std::shared_ptr<BrushHandle> brush,const String& theText,int X,int Y,int nWidth,int nHeight)
        {
            if(theText.length())
            {
                HBRUSH hBrush = nullptr;
                if(brush)
                {
                    hBrush = brush->GetHBRUSH();
                }
                if(::GrayString(GetHDC(),hBrush,nullptr,LPARAM(theText.c_str()),int(theText.length()),X,Y,nWidth,nHeight) == 0)
                {
                    ThrowLastOSError();
                }
            }
            return *this;
        }


        HWIN_EXPORT DeviceContextHandle& DeviceContextHandle::DrawDesktopWallPaper()
        {
            if(PaintDesktop(GetHDC()) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }

        HWIN_EXPORT DeviceContextHandle& DeviceContextHandle::DrawChord(int nLeftRect,int nTopRect,int nRightRect,int nBottomRect,int nXRadial1,int nYRadial1,int nXRadial2,int nYRadial2)
        {
            if(::Chord(GetHDC(),nLeftRect,nTopRect,nRightRect,nBottomRect,nXRadial1,nYRadial1,nXRadial2,nYRadial2) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }
        HWIN_EXPORT DeviceContextHandle& DeviceContextHandle::DrawChord(const RECT& rectangle,const POINT& start,const POINT& end)
        {
            if(::Chord(GetHDC(),rectangle.left,rectangle.top,rectangle.right,rectangle.bottom,start.x,start.y,end.x,end.y) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }

        HWIN_EXPORT DeviceContextHandle& DeviceContextHandle::DrawEllipse(int nLeftRect,int nTopRect,int nRightRect,int nBottomRect)
        {
            if(::Ellipse(GetHDC(),nLeftRect,nTopRect,nRightRect,nBottomRect) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }
        HWIN_EXPORT DeviceContextHandle& DeviceContextHandle::DrawEllipse(const RECT& rectangle)
        {
            if(::Ellipse(GetHDC(),rectangle.left,rectangle.top,rectangle.right,rectangle.bottom) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }

        HWIN_EXPORT DeviceContextHandle& DeviceContextHandle::DrawFilledRectangle(int nLeftRect,int nTopRect,int nRightRect,int nBottomRect, std::shared_ptr<BrushHandle> brush)
        {
            CheckPointerNotNull(brush);
            RECT rect = {nLeftRect,nTopRect,nRightRect,nBottomRect};
            if(::FillRect(GetHDC(),&rect,brush->GetHBRUSH()) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }
        HWIN_EXPORT DeviceContextHandle& DeviceContextHandle::DrawFilledRectangle(const RECT& rectangle, std::shared_ptr<BrushHandle> brush)
        {
            CheckPointerNotNull(brush);
            if(::FillRect(GetHDC(),&rectangle,brush->GetHBRUSH()) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }

        HWIN_EXPORT DeviceContextHandle& DeviceContextHandle::DrawFrameRectangle(int nLeftRect,int nTopRect,int nRightRect,int nBottomRect, std::shared_ptr<BrushHandle> brush)
        {
            CheckPointerNotNull(brush);
            RECT rect = {nLeftRect,nTopRect,nRightRect,nBottomRect};
            if(::FrameRect(GetHDC(),&rect,brush->GetHBRUSH()) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }
        HWIN_EXPORT DeviceContextHandle& DeviceContextHandle::DrawFrameRectangle(const RECT& rectangle, std::shared_ptr<BrushHandle> brush)
        {
            CheckPointerNotNull(brush);
            if(::FrameRect(GetHDC(),&rectangle,brush->GetHBRUSH()) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }

        HWIN_EXPORT DeviceContextHandle& DeviceContextHandle::DrawInvertedRectangle(int nLeftRect,int nTopRect,int nRightRect,int nBottomRect)
        {
            RECT rect = {nLeftRect,nTopRect,nRightRect,nBottomRect};
            if(::InvertRect(GetHDC(),&rect) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }
        HWIN_EXPORT DeviceContextHandle& DeviceContextHandle::DrawInvertedRectangle(const RECT& rectangle)
        {
            if(::InvertRect(GetHDC(),&rectangle) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }

        HWIN_EXPORT DeviceContextHandle& DeviceContextHandle::DrawPie(int nLeftRect,int nTopRect,int nRightRect,int nBottomRect,int nXRadial1,int nYRadial1,int nXRadial2,int nYRadial2)
        {
            if(::Pie(GetHDC(),nLeftRect,nTopRect,nRightRect,nBottomRect,nXRadial1,nYRadial1,nXRadial2,nYRadial2) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }
        HWIN_EXPORT DeviceContextHandle& DeviceContextHandle::DrawPie(const RECT& rectangle,const POINT& start,const POINT& end)
        {
            if(::Pie(GetHDC(),rectangle.left,rectangle.top,rectangle.right,rectangle.bottom,start.x,start.y,end.x,end.y) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }

        HWIN_EXPORT DeviceContextHandle& DeviceContextHandle::DrawPolygon(const POINT *lpPoints, int nCount)
        {
            if(::Polygon(GetHDC(),lpPoints, nCount) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }
        HWIN_EXPORT DeviceContextHandle& DeviceContextHandle::DrawPolygon(const std::vector<POINT>& points)
        {
            if(::Polygon(GetHDC(),points.data(), int(points.size())) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }
        HWIN_EXPORT DeviceContextHandle& DeviceContextHandle::DrawPolygon(std::shared_ptr<const std::vector<POINT> > polygon)
        {
            CheckPointerNotNull(polygon);
            if(::Polygon(GetHDC(),polygon->data(), int(polygon->size())) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }

        HWIN_EXPORT DeviceContextHandle& DeviceContextHandle::DrawPolyPolygons(const std::vector< std::vector<POINT> >& polyPolygons)
        {
            std::vector<INT> polyCounts;
            polyCounts.reserve(polyPolygons.size());
            size_t totalNumberOfPoints = 0;
            for ( auto polygon : polyPolygons)
            {
                if(polygon.size() < 2)
                {
                    throw ArgumentException("Not enough points in the polygon");
                }
                int numberOfPoints = INT(polygon.size());
                polyCounts.push_back(numberOfPoints);
                totalNumberOfPoints += numberOfPoints;
            }
            std::vector<POINT> points;
            points.reserve(totalNumberOfPoints);
            for ( auto polygon : polyPolygons)
            {
                for (auto point : polygon)
                {
                    points.push_back(point);
                }
            }
            if(::PolyPolygon(GetHDC(),points.data(),polyCounts.data(), int(polyCounts.size())) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }
        HWIN_EXPORT DeviceContextHandle& DeviceContextHandle::DrawPolyPolygon(const POINT *lpPoints,const INT *lpPolyCounts,int nCount)
        {
            if(::PolyPolygon(GetHDC(),lpPoints,lpPolyCounts,nCount) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }

        HWIN_EXPORT DeviceContextHandle& DeviceContextHandle::DrawRectangle(int nLeftRect,int nTopRect,int nRightRect,int nBottomRect)
        {
            if(::Rectangle(GetHDC(),nLeftRect,nTopRect,nRightRect,nBottomRect) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }
        HWIN_EXPORT DeviceContextHandle& DeviceContextHandle::DrawRectangle(const RECT& rectangle)
        {
            if(::Rectangle(GetHDC(),rectangle.left,rectangle.top,rectangle.right,rectangle.bottom) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }

        HWIN_EXPORT DeviceContextHandle& DeviceContextHandle::DrawRoundedRectangle(int nLeftRect,int nTopRect,int nRightRect,int nBottomRect,int nWidth,int nHeight)
        {
            if(::RoundRect(GetHDC(),nLeftRect,nTopRect,nRightRect,nBottomRect,nWidth,nHeight) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }
        HWIN_EXPORT DeviceContextHandle& DeviceContextHandle::DrawRoundedRectangle(const RECT& rectangle,int nWidth,int nHeight)
        {
            if(::RoundRect(GetHDC(),rectangle.left,rectangle.top,rectangle.right,rectangle.bottom,nWidth,nHeight) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }
        HWIN_EXPORT DeviceContextHandle& DeviceContextHandle::DrawRoundedRectangle(const RECT& rectangle,const SIZE& ellipseSize)
        {
            if(::RoundRect(GetHDC(),rectangle.left,rectangle.top,rectangle.right,rectangle.bottom,ellipseSize.cx,ellipseSize.cy) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }

        HWIN_EXPORT DeviceContextHandle& DeviceContextHandle::DrawAngleArc(int X,int Y,DWORD dwRadius,FLOAT eStartAngle,FLOAT eSweepAngle)
        {
            if(::AngleArc(GetHDC(),X,Y,dwRadius,eStartAngle,eSweepAngle) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }
        HWIN_EXPORT DeviceContextHandle& DeviceContextHandle::DrawAngleArc(const POINT& center,DWORD dwRadius,FLOAT eStartAngle,FLOAT eSweepAngle)
        {
            if(::AngleArc(GetHDC(),center.x,center.y,dwRadius,eStartAngle,eSweepAngle) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }

        HWIN_EXPORT DeviceContextHandle& DeviceContextHandle::DrawArc(int nLeftRect,int nTopRect,int nRightRect,int nBottomRect,int nXStartArc,int nYStartArc,int nXEndArc,int nYEndArc)
        {
            if(::Arc(GetHDC(),nLeftRect,nTopRect,nRightRect,nBottomRect,nXStartArc,nYStartArc,nXEndArc,nYEndArc) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }
        HWIN_EXPORT DeviceContextHandle& DeviceContextHandle::DrawArc(const RECT& rectangle,const POINT& start,const POINT& end)
        {
            if(::Arc(GetHDC(),rectangle.left,rectangle.top,rectangle.right,rectangle.bottom,start.x,start.y,end.x,end.y) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }

        HWIN_EXPORT harlinn::windows::ArcDirection DeviceContextHandle::ArcDirection() const
        {
            int result = GetArcDirection(GetHDC());
            if(!result)
            {
                ThrowLastOSError();
            }
            return harlinn::windows::ArcDirection(result);
        }
        HWIN_EXPORT harlinn::windows::ArcDirection DeviceContextHandle::SetArcDirection(harlinn::windows::ArcDirection newArcDirection)
        {
            int nad = int(newArcDirection);
            int result = ::SetArcDirection(GetHDC(),nad);
            if(!result)
            {
                ThrowLastOSError();
            }
            return harlinn::windows::ArcDirection(result);
        }

        HWIN_EXPORT DeviceContextHandle& DeviceContextHandle::DrawLineTo(int nXEnd,int nYEnd)
        {
            if(::LineTo(GetHDC(),nXEnd,nYEnd) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }
        HWIN_EXPORT DeviceContextHandle& DeviceContextHandle::DrawLineTo(const POINT& endPoint)
        {
            if(::LineTo(GetHDC(),endPoint.x,endPoint.y) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }

        HWIN_EXPORT DeviceContextHandle& DeviceContextHandle::MoveTo(int newX,int newY)
        {
            if(::MoveToEx(GetHDC(),newX,newY,nullptr) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }
        HWIN_EXPORT DeviceContextHandle& DeviceContextHandle::MoveTo(int newX,int newY, int& previousX, int& previousY )
        {
            POINT p = {0,};
            if(::MoveToEx(GetHDC(),newX,newY,&p) == FALSE)
            {
                ThrowLastOSError();
            }
            previousX = p.x;
            previousY = p.y;
            return *this;
        }
        HWIN_EXPORT DeviceContextHandle& DeviceContextHandle::MoveTo(const POINT& newPosition)
        {
            if(::MoveToEx(GetHDC(),newPosition.x,newPosition.y,nullptr) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }
        HWIN_EXPORT DeviceContextHandle& DeviceContextHandle::MoveTo(const POINT& newPosition, POINT& previousPosition)
        {
            if(::MoveToEx(GetHDC(),newPosition.x,newPosition.y,&previousPosition) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }

        HWIN_EXPORT DeviceContextHandle& DeviceContextHandle::DrawPolyBezier(const POINT *lppt,DWORD cPoints)
        {
            if(::PolyBezier(GetHDC(),lppt,cPoints) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }
        HWIN_EXPORT DeviceContextHandle& DeviceContextHandle::DrawPolyBezier(const std::vector<POINT>& points)
        {
            if(::PolyBezier(GetHDC(),points.data(),DWORD(points.size())) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }
        HWIN_EXPORT DeviceContextHandle& DeviceContextHandle::DrawPolyBezier(std::shared_ptr<const std::vector<POINT> > points)
        {
            CheckPointerNotNull(points);
            if(::PolyBezier(GetHDC(),points->data(),DWORD(points->size())) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }

        HWIN_EXPORT DeviceContextHandle& DeviceContextHandle::DrawPolyBezierTo(const POINT *lppt,DWORD cPoints)
        {
            if(::PolyBezierTo(GetHDC(),lppt,cPoints) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }
        HWIN_EXPORT DeviceContextHandle& DeviceContextHandle::DrawPolyBezierTo(const std::vector<POINT>& points)
        {
            if(::PolyBezierTo(GetHDC(),points.data(),DWORD(points.size())) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }
        HWIN_EXPORT DeviceContextHandle& DeviceContextHandle::DrawPolyBezierTo(std::shared_ptr<const std::vector<POINT> > points)
        {
            CheckPointerNotNull(points);
            if(::PolyBezier(GetHDC(),points->data(),DWORD(points->size())) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }

        HWIN_EXPORT DeviceContextHandle& DeviceContextHandle::Draw(const POINT *lppt,const PolyDrawCommand *lpbTypes,int cCount)
        {
            if(::PolyDraw(GetHDC(),lppt,(BYTE*)lpbTypes,cCount) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }

        HWIN_EXPORT DeviceContextHandle& DeviceContextHandle::DrawPolyLine(const POINT *lppt,DWORD cPoints)
        {
            if(::Polyline(GetHDC(),lppt,cPoints) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }
        HWIN_EXPORT DeviceContextHandle& DeviceContextHandle::DrawPolyLine(const std::vector<POINT>& points)
        {
            if(::Polyline(GetHDC(),points.data(),DWORD(points.size())) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }
        HWIN_EXPORT DeviceContextHandle& DeviceContextHandle::DrawPolyLine(std::shared_ptr<const std::vector<POINT> > points)
        {
            CheckPointerNotNull(points);
            if(::Polyline(GetHDC(),points->data(),DWORD(points->size())) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }

        HWIN_EXPORT DeviceContextHandle& DeviceContextHandle::DrawPolyLineTo(const POINT *lppt,DWORD cPoints)
        {
            if(::PolylineTo(GetHDC(),lppt,cPoints) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }
        HWIN_EXPORT DeviceContextHandle& DeviceContextHandle::DrawPolyLineTo(const std::vector<POINT>& points)
        {
            if(::PolylineTo(GetHDC(),points.data(),DWORD(points.size())) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }

        HWIN_EXPORT ColorRef DeviceContextHandle::TextColor() const
        {
            COLORREF resultClr = GetTextColor(GetHDC());
            if(resultClr == CLR_INVALID)
            {
                ThrowLastOSError();
            }
            return ColorRef(resultClr);
        }
        HWIN_EXPORT ColorRef DeviceContextHandle::SetTextColor(COLORREF colorRef)
        {
            COLORREF resultClr = ::SetTextColor(GetHDC(),colorRef);
            if(resultClr == CLR_INVALID)
            {
                ThrowLastOSError();
            }
            return ColorRef(resultClr);
        }


        HWIN_EXPORT harlinn::windows::TextAlignment DeviceContextHandle::TextAlignment() const
        {
            auto result = GetTextAlign(GetHDC());
            if(result == GDI_ERROR)
            {
                ThrowLastOSError();
            }
            return harlinn::windows::TextAlignment(result);
        }
        HWIN_EXPORT harlinn::windows::TextAlignment DeviceContextHandle::SetTextAlignment(harlinn::windows::TextAlignment textAlignment)
        {
            UINT ta = UINT(textAlignment);
            auto result = SetTextAlign(GetHDC(),ta);
            if(result == GDI_ERROR)
            {
                ThrowLastOSError();
            }
            return harlinn::windows::TextAlignment(result);
        }

        HWIN_EXPORT DeviceContextHandle& DeviceContextHandle::DrawPolyLineTo(std::shared_ptr<const std::vector<POINT> > points)
        {
            CheckPointerNotNull(points);
            if(::PolylineTo(GetHDC(),points->data(),DWORD(points->size())) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }

        HWIN_EXPORT int DeviceContextHandle::DrawText(const String& theText,RECT& rect, DrawTextFlags uFormat)
        {
            int result = ::DrawTextW(GetHDC(),theText.c_str(),int(theText.length()),&rect, UINT(uFormat));
            if(!result)
            {
                ThrowLastOSError();
            }
            return result;
        }

        HWIN_EXPORT int DeviceContextHandle::DrawText(LPCTSTR lpchText,int nCount,RECT& rect, DrawTextFlags uFormat)
        {
            int result = ::DrawTextW(GetHDC(),lpchText,nCount,&rect, UINT(uFormat));
            if(!result)
            {
                ThrowLastOSError();
            }
            return result;
        }
        HWIN_EXPORT int DeviceContextHandle::DrawText(LPWSTR lpchText,int nCount,RECT& rect, DrawTextFlags uFormat, DRAWTEXTPARAMS& drawTextParams)
        {
            int result = ::DrawTextExW(GetHDC(),lpchText,nCount,&rect, UINT(uFormat),&drawTextParams);
            if(!result)
            {
                ThrowLastOSError();
            }
            return result;
        }
        HWIN_EXPORT DeviceContextHandle& DeviceContextHandle::DrawText(int nXStart,int nYStart,LPCTSTR lpString,int cchString)
        {
            if(::TextOutW(GetHDC(),nXStart,nYStart,lpString,cchString) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }
        HWIN_EXPORT DeviceContextHandle& DeviceContextHandle::DrawText(int nXStart,int nYStart,const String& theText)
        {
            if(::TextOutW(GetHDC(),nXStart,nYStart,theText.c_str(),int(theText.length())) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }
        HWIN_EXPORT DeviceContextHandle& DeviceContextHandle::DrawText(const POINT& startPosition,const String& theText)
        {
            if(::TextOutW(GetHDC(),startPosition.x,startPosition.y,theText.c_str(),int(theText.length())) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }
        HWIN_EXPORT SIZE DeviceContextHandle::DrawText(int X, int Y,LPCTSTR lpString, int nCount, int nTabPositions, const LPINT lpnTabStopPositions, int nTabOrigin)
        {
            LONG res = ::TabbedTextOutW(GetHDC(),X, Y,lpString, nCount, nTabPositions, lpnTabStopPositions, nTabOrigin);
            if(!res)
            {
                ThrowLastOSError();
            }
            SIZE result = {LOWORD(res),HIWORD(res)};
            return result;
        }
        HWIN_EXPORT DeviceContextHandle& DeviceContextHandle::DrawText(int X,int Y, UINT fuOptions, const RECT *lprc, LPCTSTR lpString, UINT cbCount, const INT *lpDx)
        {
            if(::ExtTextOutW(GetHDC(),X,Y, fuOptions, lprc, lpString, cbCount, lpDx) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }


        HWIN_EXPORT POINT DeviceContextHandle::CurrentPosition() const
        {
            POINT result = {0,};
            if(GetCurrentPositionEx(GetHDC(),&result) == FALSE)
            {
                ThrowLastOSError();
            }
            return result;
        }

        HWIN_EXPORT const DeviceContextHandle& DeviceContextHandle::CurrentPosition(POINT& currentPosition) const
        {
            if(GetCurrentPositionEx(GetHDC(),&currentPosition) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }


        HWIN_EXPORT harlinn::windows::GraphicsMode DeviceContextHandle::GraphicsMode() const
        {
            auto gm = GetGraphicsMode(GetHDC());
            if(!gm)
            {
                ThrowLastOSError();
            }
            return harlinn::windows::GraphicsMode(gm);
        }

        HWIN_EXPORT harlinn::windows::GraphicsMode DeviceContextHandle::SetGraphicsMode(harlinn::windows::GraphicsMode newGraphicsMode)
        {
            auto gm = ::SetGraphicsMode(GetHDC(),int(newGraphicsMode));
            if(!gm)
            {
                ThrowLastOSError();
            }
            return harlinn::windows::GraphicsMode(gm);
        }


        HWIN_EXPORT harlinn::windows::MapMode DeviceContextHandle::MapMode() const
        {
            auto mm = GetMapMode(GetHDC());
            if(!mm)
            {
                ThrowLastOSError();
            }
            return harlinn::windows::MapMode(mm);
        }
        HWIN_EXPORT harlinn::windows::MapMode DeviceContextHandle::SetMapMode(harlinn::windows::MapMode newMapMode)
        {
            auto mm = ::SetMapMode(GetHDC(),int(newMapMode));
            if(!mm)
            {
                ThrowLastOSError();
            }
            return harlinn::windows::MapMode(mm);
        }

        HWIN_EXPORT SIZE DeviceContextHandle::ViewportExtent() const
        {
            SIZE result = {0,};
            if(GetViewportExtEx(GetHDC(),&result) == FALSE)
            {
                ThrowLastOSError();
            }
            return result;
        }

        HWIN_EXPORT SIZE DeviceContextHandle::SetViewportExtent(const SIZE& newViewportExtent )
        {
            SIZE result = {0,};
            if(SetViewportExtEx(GetHDC(),newViewportExtent.cx,newViewportExtent.cy,&result) == FALSE)
            {
                ThrowLastOSError();
            }
            return result;
        }

        HWIN_EXPORT SIZE DeviceContextHandle::ScaleViewportExtent(int Xnum,int Xdenom,int Ynum,int Ydenom)
        {
            SIZE result = {0,};
            if(ScaleViewportExtEx(GetHDC(),Xnum,Xdenom,Ynum,Ydenom,&result) == FALSE)
            {
                ThrowLastOSError();
            }
            return result;
        }


        HWIN_EXPORT POINT DeviceContextHandle::ViewportOrigin() const
        {
            POINT result = {0,};
            if(GetViewportOrgEx(GetHDC(),&result) == FALSE)
            {
                ThrowLastOSError();
            }
            return result;
        }
        HWIN_EXPORT POINT DeviceContextHandle::SetViewportOrigin(const POINT& newViewportOrigin)
        {
            POINT result = {0,};
            if(SetViewportOrgEx(GetHDC(),newViewportOrigin.x,newViewportOrigin.y,&result) == FALSE)
            {
                ThrowLastOSError();
            }
            return result;
        }

        HWIN_EXPORT POINT DeviceContextHandle::OffsetViewportOrigin(int xOffset, int yOffset)
        {
            POINT result = {0,};
            if(OffsetViewportOrgEx(GetHDC(),xOffset, yOffset,&result) == FALSE)
            {
                ThrowLastOSError();
            }
            return result;
        }

        HWIN_EXPORT SIZE DeviceContextHandle::WindowExtent() const
        {
            SIZE result = {0,};
            if(GetWindowExtEx(GetHDC(),&result) == FALSE)
            {
                ThrowLastOSError();
            }
            return result;
        }

        HWIN_EXPORT SIZE DeviceContextHandle::SetWindowExtent(const SIZE& newWindowExtent )
        {
            SIZE result = {0,};
            if(SetWindowExtEx(GetHDC(),newWindowExtent.cx,newWindowExtent.cy,&result) == FALSE)
            {
                ThrowLastOSError();
            }
            return result;
        }

        HWIN_EXPORT SIZE DeviceContextHandle::ScaleWindowExtent(int Xnum,int Xdenom,int Ynum,int Ydenom)
        {
            SIZE result = {0,};
            if(ScaleWindowExtEx(GetHDC(),Xnum,Xdenom,Ynum,Ydenom,&result) == FALSE)
            {
                ThrowLastOSError();
            }
            return result;
        }


        HWIN_EXPORT POINT DeviceContextHandle::WindowOrigin() const
        {
            POINT result = {0,};
            if(GetWindowOrgEx(GetHDC(),&result) == FALSE)
            {
                ThrowLastOSError();
            }
            return result;
        }
        HWIN_EXPORT POINT DeviceContextHandle::SetWindowOrigin(const POINT& newWindowOrigin)
        {
            POINT result = {0,};
            if(SetWindowOrgEx(GetHDC(),newWindowOrigin.x,newWindowOrigin.y,&result) == FALSE)
            {
                ThrowLastOSError();
            }
            return result;
        }

        HWIN_EXPORT POINT DeviceContextHandle::OffsetWindowOrigin(int xOffset, int yOffset)
        {
            POINT result = {0,};
            if(OffsetWindowOrgEx(GetHDC(),xOffset, yOffset,&result) == FALSE)
            {
                ThrowLastOSError();
            }
            return result;
        }



        HWIN_EXPORT const DeviceContextHandle& DeviceContextHandle::WorldTransform(XFORM& xform) const
        {
            if(GetWorldTransform(GetHDC(),&xform) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }
        HWIN_EXPORT XFORM DeviceContextHandle::WorldTransform( ) const
        {
            XFORM xform;
            if(GetWorldTransform(GetHDC(),&xform) == FALSE)
            {
                ThrowLastOSError();
            }
            return xform;
        }

        HWIN_EXPORT DeviceContextHandle& DeviceContextHandle::SetWorldTransform(XFORM& xform)
        {
            if(::SetWorldTransform(GetHDC(),&xform) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }

        HWIN_EXPORT DeviceContextHandle& DeviceContextHandle::ModifyWorldTransform(const XFORM& xform, bool rightMultiply)
        {
            if(::ModifyWorldTransform(GetHDC(),&xform,rightMultiply?MWT_RIGHTMULTIPLY:MWT_LEFTMULTIPLY) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }

        HWIN_EXPORT DeviceContextHandle& DeviceContextHandle::ResetWorldTransform( )
        {
            if(::ModifyWorldTransform(GetHDC(),nullptr,MWT_IDENTITY) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }


        HWIN_EXPORT DeviceContextHandle& DeviceContextHandle::DrawBitmap(std::shared_ptr<BitmapHandle> bitmap)
        {
            POINT position = {0,};
            SIZE size = bitmap->Size();
            auto mdc = std::make_shared<MemoryDeviceContextHandle>(As<DeviceContextHandle>(),bitmap);
            
            
            return DrawBitmap(mdc,position,size);
        }
        HWIN_EXPORT DeviceContextHandle& DeviceContextHandle::DrawBitmap(std::shared_ptr<BitmapHandle> bitmap, const POINT& position)
        {
            auto mdc = std::make_shared<MemoryDeviceContextHandle>(As<DeviceContextHandle>(),bitmap);
            SIZE size = bitmap->Size();
            return DrawBitmap(mdc,position,size);
        }
        HWIN_EXPORT DeviceContextHandle& DeviceContextHandle::DrawBitmap(std::shared_ptr<BitmapHandle> bitmap, const POINT& position, const SIZE size)
        {
            auto mdc = std::make_shared<MemoryDeviceContextHandle>(As<DeviceContextHandle>(),bitmap);
            return DrawBitmap(mdc,position,size);
        }

        HWIN_EXPORT DeviceContextHandle& DeviceContextHandle::DrawBitmap(std::shared_ptr<DeviceContextHandle> source)
        {
            auto size = source->ViewportExtent();
            POINT position = {0,};
            return DrawBitmap(source,position,size);
        }
        HWIN_EXPORT DeviceContextHandle& DeviceContextHandle::DrawBitmap(std::shared_ptr<DeviceContextHandle> source, const POINT& position)
        {
            auto size = source->ViewportExtent();
            return DrawBitmap(source,position,size);
        }
        HWIN_EXPORT DeviceContextHandle& DeviceContextHandle::DrawBitmap(std::shared_ptr<DeviceContextHandle> source, const POINT& position, const SIZE size)
        {
            if(::BitBlt(GetHDC(), position.x, position.y, size.cx, size.cy, source->GetHDC(), 0, 0, SRCCOPY) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }


        // ----------------------------------------------------------------------
        // PaintDeviceContextHandle
        // ----------------------------------------------------------------------
        HWIN_EXPORT PaintDeviceContextHandle::PaintDeviceContextHandle(const std::shared_ptr<Control> theControl)
        {
            CheckPointerNotNull(theControl);
            windowHandle = theControl->GetSafeHandle();
            auto theHandle = BeginPaint(windowHandle,&paintStruct);
            if(!theHandle)
            {
                ThrowLastOSError();
            }
            SetValue(theHandle,true);
            SaveDefaultObjects();
        }
        HWIN_EXPORT PaintDeviceContextHandle::PaintDeviceContextHandle(HWND hWnd)
        {
            windowHandle = hWnd;
            auto theHandle = BeginPaint(windowHandle,&paintStruct);
            if(!theHandle)
            {
                ThrowLastOSError();
            }
            SetValue(theHandle,true);
            SaveDefaultObjects();
        }
        HWIN_EXPORT PaintDeviceContextHandle::~PaintDeviceContextHandle()
        {
            HDC hDC = GetHDC();
            if(hDC)
            {
                RestoreDefaultObjects();
            }
            if(OwnsHandle() && hDC)
            {
                EndPaint(windowHandle,&paintStruct);
            }
        }

        // ----------------------------------------------------------------------
        // MemoryDeviceContextHandle
        // ----------------------------------------------------------------------
        HWIN_EXPORT MemoryDeviceContextHandle::MemoryDeviceContextHandle(std::shared_ptr<DeviceContextHandle> deviceContext)
        {
            CheckPointerNotNull(deviceContext);
            HDC theHandle = CreateCompatibleDC(deviceContext->GetHDC());
            if(!theHandle)
            {
                ThrowLastOSError();
            }
            SetValue(theHandle,true);
            SaveDefaultObjects();
        }

        HWIN_EXPORT MemoryDeviceContextHandle::MemoryDeviceContextHandle(std::shared_ptr<DeviceContextHandle> deviceContext, std::shared_ptr<BitmapHandle> bitmap)
        {
            CheckPointerNotNull(deviceContext);
            CheckPointerNotNull(bitmap);

            HDC theHandle = CreateCompatibleDC(deviceContext->GetHDC());
            if(!theHandle)
            {
                ThrowLastOSError();
            }
            SetValue(theHandle,true);
            SaveDefaultObjects();

            SetBitmap(bitmap);

        }

        HWIN_EXPORT MemoryDeviceContextHandle::~MemoryDeviceContextHandle()
        {
            HDC hDC = GetHDC();
            if(hDC)
            {
                RestoreDefaultObjects();
            }
            if(OwnsHandle() && hDC)
            {
                DeleteDC(hDC);
            }
        }


    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Architect Sea Surveillance AS
Norway Norway
Chief Architect - Sea Surveillance AS.

Specializing in integrated operations and high performance computing solutions.

I’ve been fooling around with computers since the early eighties, I’ve even done work on CP/M and MP/M.

Wrote my first “real” program on a BBC micro model B based on a series in a magazine at that time. It was fun and I got hooked on this thing called programming ...

A few Highlights:

  • High performance application server development
  • Model Driven Architecture and Code generators
  • Real-Time Distributed Solutions
  • C, C++, C#, Java, TSQL, PL/SQL, Delphi, ActionScript, Perl, Rexx
  • Microsoft SQL Server, Oracle RDBMS, IBM DB2, PostGreSQL
  • AMQP, Apache qpid, RabbitMQ, Microsoft Message Queuing, IBM WebSphereMQ, Oracle TuxidoMQ
  • Oracle WebLogic, IBM WebSphere
  • Corba, COM, DCE, WCF
  • AspenTech InfoPlus.21(IP21), OsiSoft PI


More information about what I do for a living can be found at: harlinn.com or LinkedIn

You can contact me at espen@harlinn.no

Comments and Discussions