Click here to Skip to main content
15,896,456 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 "hwincontrol.h"
#include "hwinapplication.h"
#include "hwinmenu.h"
#include "hwincomcontrol.h"
#include <typeinfo>

namespace harlinn
{
    namespace windows
    {
        // --------------------------------------------------------------------
        // Controls
        // --------------------------------------------------------------------
        HWIN_EXPORT Controls::Controls(Control* theControl)
            : control(theControl)
        {
            if(!theControl)
            {
                ThrowPointerIsNULL();
            }
        }

        HWIN_EXPORT void Controls::DoOnHandleCreated( )
        {
            for(auto weakItem : items)
            {
                auto item = weakItem.lock();
                if(item)
                {
                    item->GetSafeHandle();
                }
            }
        }

        HWIN_EXPORT void Controls::DoBeforeHandleDestroy( )
        {
        }

        HWIN_EXPORT void Controls::Remove(const std::shared_ptr< Control >& theControl)
        {
            if(theControl)
            {
                for(auto it = items.begin(); it != items.end(); it++)
                {
                    auto item = (*it).lock();
                    if(item == theControl)
                    {
                        items.erase(it);
                        break;
                    }
                }
            }
        }
        HWIN_EXPORT void Controls::Add(const std::shared_ptr< Control >& theControl)
        {
            if(theControl)
            {
                if(Contains(theControl) == false)
                {
                    items.push_back(theControl);
                }
            }
        }


        HWIN_EXPORT void Controls::DisconnectParentControl()
        {
            for(auto weakItem : items)
            {
                auto item = weakItem.lock();
                if(item)
                {
                    item->DisconnectParentControl();
                }
            }
        }



        HWIN_EXPORT bool Controls::Contains(const std::shared_ptr< const Control >& theChildControl) const
        {
            
            bool result = false;
            if(theChildControl)
            {
                for(auto weakItem : items)
                {
                    auto item = weakItem.lock();
                    if(item == theChildControl)
                    {
                        result = true;
                        break;
                    }
                }
            }
            return result;
        }

        // --------------------------------------------------------------------
        // ControlWindowClass
        // --------------------------------------------------------------------
        class ControlWindowClass : public WindowClass
        {
        public:
            static String HWIN_EXPORT ClassName;

            HWIN_EXPORT ControlWindowClass();
        };

        String HWIN_EXPORT ControlWindowClass::ClassName = String(L"HarlinnWindowsControlWindowClassName");

        typedef ControlMessageDispatcher<Control> DefaultControlMessageDispatcher;

        HWIN_EXPORT ControlWindowClass::ControlWindowClass()
        {
            SetName(ClassName);
            WNDPROC procedure = DefaultControlMessageDispatcher::WndProc;
            SetProcedure(procedure);
            
        }


        // --------------------------------------------------------------------
        // Control
        // --------------------------------------------------------------------
        UINT Control::REFLECTED_WM_COMMAND = RegisterWindowMessage(L"Control::REFLECTED_WM_COMMAND");
        UINT Control::REFLECTED_WM_NOTIFY = RegisterWindowMessage(L"Control::REFLECTED_WM_NOTIFY");
        UINT Control::REFLECTED_WM_DRAWITEM = RegisterWindowMessage(L"Control::REFLECTED_WM_DRAWITEM");
        UINT Control::WM_GET_CONTROL = RegisterWindowMessage(L"Control::WM_GET_CONTROL");


        HWIN_EXPORT Control::Control( )
            : Base( ), 
              handle(0),
              id(0),
              dock(DockStyle::None),
              enabled(true),
              visible(true),
              tabStop(true),
              recreatingHandle(false),
              anchorStyles(AnchorStyles::Left | AnchorStyles::Top),
              automaticallyAddParentlessOwnedControls(true),
              originalWindowsProcedure(nullptr),
              position(CW_USEDEFAULT,CW_USEDEFAULT),
              size(CW_USEDEFAULT,CW_USEDEFAULT)
        {
            

            controls = std::make_shared<harlinn::windows::Controls>(this);
            
        }


        HWIN_EXPORT Control::~Control()
        {
            SetParent(nullptr);
            DisconnectParentControl();
            if(handle)
            {
                DestroyHandle();
            }
            
        }

        HWIN_EXPORT ComObject* Control::CreateComObject() const
        {
            auto self = std::const_pointer_cast< Control, const Control >(As<Control>());
            ComControl* result = new ComControl(self);
            return result;
        }

        HWIN_EXPORT void Control::DoOnInitialize( )
        {
            Base::DoOnInitialize();    
        }


        HWIN_EXPORT std::shared_ptr<WindowClass> Control::GetWindowClass() const
        {
            auto windowClass = Application::GetWindowClass(ControlWindowClass::ClassName);
            if(!windowClass)
            {
                auto newWindowClass = std::make_shared<ControlWindowClass>();
                newWindowClass->Register();
                return newWindowClass;
            }
            return windowClass;
        }

        HWIN_EXPORT DWORD Control::GetStyle() const
        {
            DWORD result = WS_CHILD;
            if(visible)
            {
                result |= WS_VISIBLE;
            }
            if(tabStop)
            {
                result |= WS_TABSTOP;
            }
            if(!enabled)
            {
                result |= WS_DISABLED;
            }
            return result;
        }


        HWIN_EXPORT DWORD Control::GetStyleEx() const
        {
            return 0;
        }

        HWIN_EXPORT Control& Control::SetWindowStyle(DWORD theStyle)
        {
            SetWindowLong(GWL_STYLE,theStyle);
            return *this;
        }
        HWIN_EXPORT Control& Control::SetWindowStyleEx(DWORD theExStyle)
        {
            SetWindowLong(GWL_EXSTYLE,theExStyle);
            return *this;
        }

        HWIN_EXPORT void Control::RecreateHandle()
        {
            if(controls->items.size())
            {
                throw InvalidOperationException("RecreateHandle called for a control with children");
            }
            if((IsSubClassed() == false)&&(IsValid()))
            {
                try
                {
                    recreatingHandle = true;
                    this->DoOnBeforeRecreatingHandle();
                    ::DestroyWindow(handle);
                    handle = this->CreateHandle();
                    this->DoOnAfterRecreatingHandle();
                }
                catch(...)
                {
                    recreatingHandle = false;
                    throw;
                }
                recreatingHandle = false;
            }
        }
        HWIN_EXPORT void Control::DoOnBeforeRecreatingHandle()
        {
        }
        HWIN_EXPORT void Control::DoOnAfterRecreatingHandle()
        {
        }



        HWIN_EXPORT bool Control::IsChild() const
        {
            bool result = (GetStyle() & WS_CHILD) != 0;
            return result;
        }
        HWIN_EXPORT bool Control::IsToplevel() const
        {
            bool result = (GetStyle() & WS_CHILD) == 0;
            return result;
        }
        HWIN_EXPORT bool Control::IsPopup() const
        {
            bool result = (GetStyle() & WS_POPUP) != 0;
            return result;
        }


        HWIN_EXPORT bool Control::Enabled() const
        {
            return enabled;
        }
        HWIN_EXPORT Control& Control::SetEnabled(bool theValue)
        {
            if(theValue != enabled)
            {
                this->DoOnSetEnabled(theValue);
                enabled = theValue;
            }
            return *this;
        }

        HWIN_EXPORT bool Control::Visible() const
        {
            return visible;
        }
        HWIN_EXPORT Control& Control::SetVisible(bool theValue)
        {
            if(visible != theValue)
            {
                visible = theValue;
                if(IsHandleCreated())
                {
                    if(SetWindowPos(handle,
                                    nullptr,
                                    0, 0, 0, 0, 
                                    SWP_NOSIZE
                                    | SWP_NOMOVE 
                                    | SWP_NOZORDER 
                                    | SWP_NOACTIVATE
                                    | (theValue ? SWP_SHOWWINDOW : SWP_HIDEWINDOW)) == 0)
                    {
                        ThrowLastOSError();
                    }
                }
            }
            return *this;
        }

        HWIN_EXPORT bool Control::TabStop() const
        {
            return tabStop;
        }
        HWIN_EXPORT Control& Control::SetTabStop(bool theValue)
        {
            if(tabStop != theValue)
            {
                tabStop = theValue;
                if(IsHandleCreated())
                {
                    DWORD style = this->GetStyle();
                    SetWindowStyle(style);
                }
            }
            return *this;
        }

        
        HWIN_EXPORT void Control::DoOnSetEnabled(bool theValue)
        {
        }

        HWIN_EXPORT long Control::Id() const
        {
            return id;
        }
        HWIN_EXPORT Control& Control::SetId(long theValue)
        {
            if(id != theValue)
            {
                id = theValue;
                if(IsValid())
                {
                    SetWindowLong(GWL_ID,theValue);
                }
            }
            return *this;
        }


        HWIN_EXPORT HWND Control::CreateHandle( )
        {
            auto windowClass = this->GetWindowClass();
            HWND result = NULL;
            if(windowClass)
            {
                const String& className = windowClass->GetName();
                if(className.length())
                {
                    HWND hWndParent = 0;
                    auto theParentControl = parentControl.lock();
                    if(theParentControl)
                    {
                        hWndParent = theParentControl->GetSafeHandle();
                    }
                    result = ::CreateWindowExW(this->GetStyleEx(),
                        className.c_str(),
                        nullptr,this->GetStyle(),
                        position.X(), position.Y(), size.Width(), size.Height(), 
                        hWndParent,0,0,(LPVOID)this);
                    if(!result)
                    {
                        ThrowLastOSError();
                    }
                }
            }
            return result;
        }

        HWIN_EXPORT void Control::DoOnHandleCreated( )
        {
            if(text.length())
            {
                ::SetWindowTextW(handle,text.c_str());
            }
            if(id)
            {
                SetWindowLong(GWLP_ID,id);
            }
            if(automaticallyAddParentlessOwnedControls)
            {
                auto theComponents = this->GetComponents();
                for(auto it = theComponents->begin();it != theComponents->end(); it++)
                {
                    auto theComponent = *it;
                    if(theComponent->Is<Control>())
                    {
                        auto theControl = theComponent->As<Control>();
                        if( (theControl->HasParent() == false )&& ((theControl->GetStyle() & WS_CHILD) != 0))
                        {
                            theControl->SetParent(As<Control>());
                        }
                    }
                }
            }
            this->DoOnSetEnabled(Enabled());
            controls->DoOnHandleCreated();
        }


        HWIN_EXPORT void Control::DestroyHandle( )
        {
            if(IsValid())
            {
                this->DoBeforeHandleDestroy( );
                bool succeeded = ::DestroyWindow(handle) != FALSE;
                handle = NULL;
                if(!succeeded)
                {
                    ThrowLastOSError();
                }
            }
            handle = NULL;
        }

        HWIN_EXPORT void Control::DoBeforeHandleDestroy( )
        {

        }

        HWIN_EXPORT void Control::DisconnectParentControl()
        {
            controls->DisconnectParentControl();
            parentControl = std::weak_ptr<Control>();
        }


        HWIN_EXPORT Control& Control::RestoreSubClassedWindowsProcedure()
        {
            if(IsSubClassed() && handle)
            {
                SetWindowLongPtrW(handle,GWLP_WNDPROC,LONG_PTR(originalWindowsProcedure));
            }
            return *this;
        }

        LRESULT CALLBACK Control::SubClassWndProc(HWND hWnd, UINT messageId, WPARAM wParam, LPARAM lParam)
        {
            Message message;
            message.hwnd = hWnd;
            message.message = messageId;
            message.wParam = wParam;
            message.lParam = lParam;
            message.time = GetMessageTime();
            DWORD pos = GetMessagePos();

            message.pt.x = GET_X_LPARAM(pos);
            message.pt.y = GET_Y_LPARAM(pos);

            LONG_PTR userData = (LONG_PTR)0;

            userData = GetWindowLongPtr(hWnd,GWLP_USERDATA);

            if(userData)
            {
                Control* control = (Control*)userData;

                control->HandleMessage(message);
                if(!message.handled)
                {
                    message.result = control->originalWindowsProcedure(hWnd, message.message, message.wParam, message.lParam);
                }
                if(messageId == WM_NCDESTROY)
                {
                    control->RestoreSubClassedWindowsProcedure();
                }
            }
            

            if(messageId == WM_NCDESTROY)
            {
                Control::UnregisterControl(hWnd);
            }
            return message.result;
        }
        
        HWIN_EXPORT Control& Control::SubClass(HWND hWnd)
        {
            
            if(IsSubClassed())
            {
                throw InvalidOperationException("Window is already subclassed");
            }
            Message::Result res = ::SendMessageW(hWnd,WM_GET_CONTROL,0,0);
            if(res)
            {
                throw InvalidOperationException("Window should not be subclassed, it's already a Control");
            }
            
            originalWindowsProcedure = (WNDPROC)GetWindowLongPtrW(handle,GWLP_WNDPROC);
            SetWindowLongPtrW(handle,GWLP_WNDPROC,LONG_PTR(SubClassWndProc));
            SetWindowLongPtrW(hWnd,GWLP_USERDATA,LONG_PTR(this));
            Control::RegisterControl(hWnd,this);

            return *this;
        }
        HWIN_EXPORT bool Control::IsSubClassed() const
        {
            return originalWindowsProcedure != nullptr;
        }

        HWIN_EXPORT void Control::DoOnWindowSubClassed( )
        {

        }


        HWIN_EXPORT HWND Control::GetSafeHandle() const
        {
            if(!handle)
            {
                Control* self = const_cast<Control*>(this);
                self->handle = self->CreateHandle( );
                self->DoOnHandleCreated( );
            }
            return handle;
        }

        HWIN_EXPORT bool Control::IsHandleCreated() const
        {
            return handle != 0;
        }


        HWIN_EXPORT const Control& Control::GetClientRect(RECT* rectangle) const
        {
            CheckPointerNotNull(rectangle);
            if(::GetClientRect(GetSafeHandle(),rectangle) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }
        HWIN_EXPORT const Control& Control::GetClientRect(RECT& rectangle) const
        {
            if(::GetClientRect(GetSafeHandle(),&rectangle) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }
        HWIN_EXPORT RECT Control::GetClientRect( ) const
        {
            RECT result;
            if(::GetClientRect(GetSafeHandle(),&result) == FALSE)
            {
                ThrowLastOSError();
            }
            return result;
        }


        HWIN_EXPORT D2D1_SIZE_F Control::ClientSize() const
        {
            RECT rect;
            if(::GetClientRect(GetSafeHandle(),&rect) == FALSE)
            {
                ThrowLastOSError();
            }
            D2D1_SIZE_F result;
            result.width = float(rect.right - rect.left);
            result.height = float(rect.bottom - rect.top);
            return result;
        }


        
        

        HWIN_EXPORT void Control::RegisterControl(HWND hWnd,Control* constrol)
        {
            auto application = Application::Current();
            if(application)
            {
                application->AddControl(hWnd,constrol);
            }

        }

        HWIN_EXPORT void Control::UnregisterControl(HWND hWnd)
        {
            auto application = Application::Current();
            if(application)
            {
                application->RemoveControl(hWnd);
            }
        }

        HWIN_EXPORT Control* Control::GetControlFromHWND(HWND hWnd)
        {
            auto application = Application::Current();
            if(application)
            {
                Control* result = application->GetControl(hWnd);
                return result;
            }
            return nullptr;
        }

        


        HWIN_EXPORT std::shared_ptr<Controls> Control::Controls() const
        {
            return controls;
        }

        HWIN_EXPORT std::shared_ptr<Control> Control::Parent() const
        {
            return parentControl.lock();
        }
        HWIN_EXPORT Control& Control::SetParent(std::shared_ptr<Control> theParentControl)
        {
            auto currentParent = Parent();
            if(theParentControl != currentParent)
            {
                auto self = As<Control>();
                if(theParentControl)
                {
                    if(theParentControl->IsChildOf(self))
                    {
                        throw InvalidOperationException("Attempted to create a cyclic parent/child control relationship.");
                    }
                    if(currentParent)
                    {
                        currentParent->Controls()->Remove(self);
                    }
                    theParentControl->Controls()->Add(self);
                    parentControl = theParentControl;
                    if(theParentControl->IsValid())
                    {
                        if(IsValid() == false)
                        {
                            GetSafeHandle();
                        }
                        else
                        {
                            if(::SetParent(handle,theParentControl->handle) == FALSE)
                            {
                                ThrowLastOSError();
                            }    
                        }
                    }
                    else
                    {
                        this->DestroyHandle();
                    }
                    
                }
                else if(currentParent)
                {
                    currentParent->Controls()->Remove(self);
                    parentControl = std::weak_ptr<Control>();
                    if(handle)
                    {
                        if((this->GetStyle() & WS_CHILD) == 0)
                        {
                            if(State() == ComponentState::Destructing)
                            {
                                if(::SetParent(handle,NULL) == FALSE)
                                {
                                    ThrowLastOSError();
                                }
                            }
                        }
                        else
                        {
                            this->DestroyHandle();
                        }
                    }
                
                }
            }
            return *this;
        }

        HWIN_EXPORT bool Control::HasParent() const
        {
            return parentControl.lock().get() != nullptr;
        }


        HWIN_EXPORT const Control& Control::UpdateRect(RECT& updateRectangle) const
        {
            if(GetUpdateRect(GetSafeHandle(),&updateRectangle,false) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }
        HWIN_EXPORT Control& Control::UpdateRect(RECT& updateRectangle, bool erase)
        {
            if(GetUpdateRect(GetSafeHandle(),&updateRectangle,erase) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }
        HWIN_EXPORT RECT Control::UpdateRect( ) const
        {
            RECT result = {0,};
            if(GetUpdateRect(GetSafeHandle(),&result,false) == FALSE)
            {
                ThrowLastOSError();
            }
            return result;
        }
        HWIN_EXPORT RECT Control::UpdateRect( bool erase )
        {
            RECT result = {0,};
            if(GetUpdateRect(GetSafeHandle(),&result,erase) == FALSE)
            {
                ThrowLastOSError();
            }
            return result;
        }


        /*
        BOOL CALLBACK EnumChildWindowsProcedure(HWND hWnd, LPARAM lParam)
        {
            std::vector< Control* >* vector = (std::vector< Control* >*)lParam;

            Control* control = Control::GetControlFromHWND(hWnd);
            if(control)
            {
                vector->push_back(control);
            }
            return TRUE;
        }

        HWIN_EXPORT std::vector< Control* > Control::GetChildren() const
        {
            std::vector< Control* > result;
            LPARAM lParam = (LPARAM)&result;

            // Even if EnumChildWindows has a return type of BOOL the return value is not used
            ::EnumChildWindows(GetSafeHandle(),EnumChildWindowsProcedure,lParam);

            return result;
        }
        */

        HWIN_EXPORT bool Control::IsChildOf(std::shared_ptr<const Control> theParentControl) const
        {
            bool result = false;
            if(theParentControl)
            {
                 auto pControl = Parent();
                 while(pControl)
                 {
                     if(pControl == theParentControl)
                     {
                         result = true;
                         break;
                     }
                     pControl = pControl->Parent();
                 }
            }
            return result;
        }

        HWIN_EXPORT bool Control::IsChildOf(HWND theParentControl) const
        {
            bool result = ::IsChild(theParentControl,GetSafeHandle()) != FALSE;
            return result;
        }

        HWIN_EXPORT bool Control::IsParentOf(std::shared_ptr<const Control> theChildControl) const
        {
            bool result = false;
            if(theChildControl)
            {
                result = theChildControl->IsChildOf(As<Control>());
            }
            return result;
        }

        HWIN_EXPORT bool Control::IsParentOf(HWND theChildControl) const
        {
            bool result = ::IsChild(GetSafeHandle(),theChildControl) != FALSE;
            return result;
        }

        HWIN_EXPORT bool Control::IsValid() const
        {
            bool result = false;
            if(handle)
            {
                result = ::IsWindow(handle) != FALSE;
            }
            return result;
        }

        HWIN_EXPORT bool Control::IsVisible() const
        {
            bool result = false;
            if(handle)
            {
                result = ::IsWindowVisible(handle) != FALSE;
            }
            return result;
        }

        HWIN_EXPORT Control& Control::InvalidateRect(bool erase)
        {
            if(handle)
            {
                if(::InvalidateRect(handle,NULL,erase) == FALSE)
                {
                    ThrowLastOSError();
                }
            }
            return *this;
        }
        HWIN_EXPORT Control& Control::InvalidateRect(const RECT& rectangle,bool erase)
        {
            if(handle)
            {
                if(::InvalidateRect(handle,&rectangle,erase) == FALSE)
                {
                    ThrowLastOSError();
                }
            }
            return *this;
        }

        HWIN_EXPORT Control& Control::MoveWindow(int x, int y, int width, int height, bool repaint)
        {
            if(handle)
            {
                if(::MoveWindow(handle,x,y,width, height, repaint) == FALSE)
                {
                    ThrowLastOSError();
                }
            }
            position.Set(x,y);
            size.Set(width,height);
            
            return *this;
        }

        HWIN_EXPORT LONG Control::SetWindowLong(int index, LONG theNewValue)
        {
            if(IsValid() == false)
            {
                throw InvalidOperationException("Valid window handle required");
            }
            SetLastError(0);

            LONG result = ::SetWindowLong(handle,index, theNewValue);

            if(GetLastError() != 0)
            {
                ThrowLastOSError();
            }
            return result;
        }
        HWIN_EXPORT LONG Control::GetWindowLong(int index) const
        {
            if(IsValid() == false)
            {
                throw InvalidOperationException("Valid window handle required");
            }
            SetLastError(0);

            LONG result = ::GetWindowLong(handle,index);

            if(GetLastError() != 0)
            {
                ThrowLastOSError();
            }
            return result;
        }


        HWIN_EXPORT LRESULT Control::SendMessage(UINT Msg, WPARAM wParam, LPARAM lParam ) const
        {
            return ::SendMessage(GetSafeHandle(),Msg, wParam, lParam);
        }

        HWIN_EXPORT const Control& Control::PostMessage(UINT Msg, WPARAM wParam, LPARAM lParam) const
        {
            if(::PostMessage(GetSafeHandle(),Msg, wParam, lParam) == FALSE)
            {
                ThrowLastOSError();
            }
            return *this;
        }

        HWIN_EXPORT int Control::TextLength() const
        {
            int size = ::GetWindowTextLengthW(GetSafeHandle());
            return size;
        }
        
        HWIN_EXPORT String Control::Text() const
        {
            int size = ::GetWindowTextLengthW(GetSafeHandle());
            if(size > 0)
            {
                wchar_t *buffer = (wchar_t *)alloca((size + 1)*sizeof(wchar_t));

                ::GetWindowTextW(handle,buffer,size+1);

                String result = String(buffer);
                return result;
            }
            else
            {
                return String();
            }
        }


        HWIN_EXPORT bool Control::SetText(const String& theText)
        {
            bool result = true;
            if(handle)
            {
                result = ::SetWindowText(GetSafeHandle(),theText.c_str()?theText.c_str():L"") != FALSE;
            }
            text = theText;
            return result;
        }
        HWIN_EXPORT bool Control::SetText(const wchar_t* theText)
        {
            bool result = true;
            if(handle)
            {
                if((theText)&&(theText[0]))
                {
                    result = ::SetWindowText(GetSafeHandle(),theText) != FALSE;
                }
                else
                {
                    result = ::SetWindowText(GetSafeHandle(),L"") != FALSE;
                }
            }
            if((theText)&&(theText[0]))
            {
                text = theText;
            }
            else
            {
                text = String();
            }
            return result;
        }


        HWIN_EXPORT bool Control::Show()
        {
            bool result = ::ShowWindow(GetSafeHandle(),SW_SHOW) != FALSE;
            return result;
        }

        HWIN_EXPORT bool Control::ValidateRect(const RECT& rectangle)
        {
            bool result = ::ValidateRect(GetSafeHandle(),&rectangle) != FALSE;
            return result;
        }

        HWIN_EXPORT bool Control::ValidateRect( )
        {
            bool result = ::ValidateRect(GetSafeHandle(),NULL) != FALSE;
            return result;
        }


        HWIN_EXPORT harlinn::windows::Size Control::Size() const
        {
            return size;
        }

        HWIN_EXPORT Control& Control::SetSize(int width, int height)
        {
            if(IsHandleCreated())
            {
                MoveWindow(position.X(),position.Y(),width,height);
            }
            else
            {
                size = harlinn::windows::Size(width,height);
            }
            return *this;
        }

        HWIN_EXPORT Control& Control::SetSize(const harlinn::windows::Size& theSize)
        {
            if(IsHandleCreated())
            {
                MoveWindow(position.X(),position.Y(),theSize.Width(),theSize.Height());
            }
            else
            {
                size = theSize;
            }
            return *this;
        }
        
        
        HWIN_EXPORT Point Control::Position() const
        {
            return position;
        }
        HWIN_EXPORT Control& Control::SetPosition(int x, int y)
        {
            if(IsHandleCreated())
            {
                MoveWindow(x,y,size.Width(),size.Height());
            }
            else
            {
                position.Set(x,y);
            }
            return *this;
        }
        HWIN_EXPORT Control& Control::SetPosition(const Point& thePosition)
        {
            if(IsHandleCreated())
            {
                MoveWindow(thePosition.X(),thePosition.Y(),size.Width(),size.Height());
            }
            else
            {
                position.Set(thePosition.X(),thePosition.Y());
            }
            return *this;
        }



        HWIN_EXPORT bool Control::IsInputChar(wchar_t charCode)
        {
            int mask = DLGC_WANTCHARS | DLGC_WANTALLKEYS; 
            if (charCode == (wchar_t)Keys::Tab) 
            { 
                mask |= DLGC_WANTTAB;
            } 
            if (IsHandleCreated()) 
            { 
                return (SendMessage(WM_GETDLGCODE) & mask) != 0;
            } 
            return false;
        }

        HWIN_EXPORT bool Control::IsInputKey(Keys keyData)
        {
            if ((keyData & Keys::Alt) == Keys::Alt) 
            {
                return false;
            }
            int mask = DLGC_WANTALLKEYS; 
            int keyCode = int(keyData & Keys::KeyCode);
            switch (keyCode) 
            {
                case Keys::Tab:
                    mask |= DLGC_WANTTAB;
                    break; 
                case Keys::Left:
                case Keys::Right: 
                case Keys::Up: 
                case Keys::Down:
                    mask |= DLGC_WANTARROWS; 
                    break;
            }

            if (IsHandleCreated()) 
            { 
                return (SendMessage(WM_GETDLGCODE) & mask) != 0;
            } 
            return false;
        }

        HWIN_EXPORT bool Control::ProcessMnemonic(wchar_t charCode)
        {
            return false;
        }



        HWIN_EXPORT void Control::HandleMessage(Message& message)
        {
            if(message.message == REFLECTED_WM_COMMAND)
            {
                this->DoOnCommand(message);
                message.result = 1;
            }
            else if(message.message == REFLECTED_WM_NOTIFY)
            {
                this->DoOnNotify(message);
            }
            else if(message.message == REFLECTED_WM_DRAWITEM)
            {
                this->DoOnDrawItem(message);
            }
            else if(message.message == WM_GET_CONTROL)
            {
                message.handled = true;
                message.result = (Message::Result)this;
            }
            else
            {
                switch(message.message)
                {
                case WM_CANCELMODE:
                    this->DoOnCancelMode(message);
                    break;
                case WM_CHAR:
                    this->DoOnChar(message);
                    break;
                case WM_CHARTOITEM:
                    this->DoOnCharToItem(message);
                    break;
                case WM_CLOSE:
                    this->DoOnClose(message);
                    break;
                case WM_COMPAREITEM:
                    this->DoOnCompareItem(message);
                    break;
                case WM_COMMAND:
                    if(message.lParam != 0)
                    {
                        HWND hWnd = (HWND)message.lParam;
                        LRESULT result = ::SendMessageW(hWnd,REFLECTED_WM_COMMAND,message.wParam,message.lParam);
                        if(result)
                        {
                            message.result = 0;
                            return;
                        }
                    }
                    this->DoOnCommand(message);
                    break;
                case WM_COPYDATA:
                    this->DoOnCopyData(message);
                    break;
                case WM_DEADCHAR:
                    this->DoOnDeadChar(message);
                    break;
                case WM_DELETEITEM:
                    this->DoOnDeleteItem(message);
                    break;
                case WM_DESTROY:
                    this->DoOnDestroy(message);
                    break;
                case WM_DISPLAYCHANGE:
                    this->DoOnDisplayChange(message);
                    break;
                case WM_DRAWITEM:
                    this->DoOnDrawItem(message);
                    break;
                case WM_ENABLE:
                    this->DoOnEnable(message);
                    break;
                case WM_ENTERSIZEMOVE:
                    this->DoOnEnterSizeMove(message);
                    break;
                case WM_ERASEBKGND:
                    this->DoOnEraseBackground(message);
                    break;
                case WM_EXITSIZEMOVE:
                    this->DoOnExitSizeMove(message);
                    break;
                case WM_GETHOTKEY:
                    this->DoOnGetHotKey(message);
                    break;
                case WM_GETTEXT:
                    this->DoOnGetText(message);
                    break;
                case WM_GETTEXTLENGTH:
                    this->DoOnGetTextLength(message);
                    break;
                case WM_INITMENU:
                    this->DoOnInitMenu(message);
                    break;
                case WM_KEYDOWN:
                    this->DoOnKeyDown(message);
                    break;
                case WM_KEYUP:
                    this->DoOnKeyUp(message);
                    break;
                case WM_KILLFOCUS:
                    this->DoOnKillFocus(message);
                    break;
                case WM_MEASUREITEM:
                    this->DoOnMeasureItem(message);
                    break;
                case WM_MENUCOMMAND:
                    this->DoOnMenuCommand(message);
                    break;
                case WM_MOUSEMOVE:
                    this->DoOnMouseMove(message);
                    break;
                case WM_LBUTTONDOWN:
                    this->DoOnMouseLeftButtonDown(message);
                    break;
                case WM_LBUTTONUP:
                    this->DoOnMouseLeftButtonUp(message);
                    break;
                case WM_LBUTTONDBLCLK:
                    this->DoOnMouseLeftButtonDoubleClick(message);
                    break;
                case WM_RBUTTONDOWN:
                    this->DoOnMouseRightButtonDown(message);
                    break;
                case WM_RBUTTONUP:
                    this->DoOnMouseRightButtonUp(message);
                    break;
                case WM_RBUTTONDBLCLK:
                    this->DoOnMouseRightButtonDoubleClick(message);
                    break;
                case WM_MBUTTONDOWN:
                    this->DoOnMouseMiddleButtonDown(message);
                    break;
                case WM_MBUTTONUP:
                    this->DoOnMouseMiddleButtonUp(message);
                    break;
                case WM_MBUTTONDBLCLK:
                    this->DoOnMouseMiddleButtonDoubleClick(message);
                    break;
                case WM_XBUTTONDOWN:
                    this->DoOnMouseXButtonDown(message);
                    break;
                case WM_XBUTTONUP:
                    this->DoOnMouseXButtonUp(message);
                    break;
                case WM_XBUTTONDBLCLK:
                    this->DoOnMouseXButtonDoubleClick(message);
                    break;
                case WM_MOUSEHWHEEL:
                    this->DoOnMouseWheel(message);
                    break;
                case WM_MOVE:
                    position.Set((int)(short) LOWORD(message.lParam),(int)(short) HIWORD(message.lParam));
                    this->DoOnMove(message);
                    break;
                case WM_MOVING:
                    this->DoOnMoving(message);
                    break;
                case WM_NCACTIVATE:
                    this->DoOnNcActivate(message);
                    break;
                case WM_NCCALCSIZE:
                    this->DoOnNcCalcSize(message);
                    break;
                case WM_NCDESTROY:
                    this->DoOnNcDestroy(message);
                    break;
                case WM_NOTIFY:
                    {
                        NMHDR* nmhdr = (NMHDR*)message.lParam;
                        if(nmhdr)
                        {
                            HWND hWnd = nmhdr->hwndFrom;
                            message.result = ::SendMessageW(hWnd,REFLECTED_WM_NOTIFY,message.wParam,message.lParam);
                        }
                    }
                    break;
                case WM_PAINT:
                    this->DoOnPaint(message);
                    break;
                case WM_SETCURSOR:
                    this->DoOnSetCursor(message);
                    break;
                case WM_SETFOCUS:
                    this->DoOnSetFocus(message);
                    break;
                case WM_SETHOTKEY:
                    this->DoOnSetHotKey(message);
                    break;
                case WM_SETREDRAW:
                    this->DoOnSetRedraw(message);
                    break;
                case WM_SETTEXT:
                    this->DoOnSetText(message);
                    break;
                case WM_SHOWWINDOW:
                    this->DoOnShowWindow(message);
                    break;
                case WM_SIZE:
                    {
                    RECT rect = {0,};
                    GetWindowRect(message.hwnd,&rect);
                    size.Set(rect.right - rect.left,rect.bottom - rect.top);
                    this->DoOnSize(message);
                    }
                    break;
                case WM_SIZING:
                    this->DoOnSizing(message);
                    break;
                case WM_SYSCHAR:
                    this->DoOnSysChar(message);
                    break;
                case WM_SYSCOMMAND:
                    this->DoOnSysCommand(message);
                    break;
                case WM_SYSDEADCHAR:
                    this->DoOnSysDeadChar(message);
                    break;
                case WM_SYSKEYDOWN:
                    this->DoOnSysKeyDown(message);
                    break;
                case WM_SYSKEYUP:
                    this->DoOnSysKeyUp(message);
                    break;
                case WM_UNICHAR:
                    this->DoOnUniChar(message);
                    break;
                case WM_VKEYTOITEM:
                    this->DoOnVKeyToItem(message);
                    break;
                case WM_WINDOWPOSCHANGING:
                    this->DoOnWindowPosChanging(message);
                    break;
                case WM_WINDOWPOSCHANGED:
                    this->DoOnWindowPosChanged(message);
                    break;
                }
            }
        }

        HWIN_EXPORT void Control::DoOnCancelMode(Message& message)
        {
            OnCancelMode(this,message);
        }

        HWIN_EXPORT void Control::DoOnChar(Message& message)
        {
            OnChar(this,message);
        }

        HWIN_EXPORT void Control::DoOnCharToItem(Message& message)
        {
            OnCharToItem(this,message);
        }

        HWIN_EXPORT void Control::DoOnClose(Message& message)
        {
            OnClose(this,message);
        }

        HWIN_EXPORT void Control::DoOnCompareItem(Message& message)
        {
            OnCompareItem(this,message);
        }

        HWIN_EXPORT void Control::DoOnCommand(Message& message)
        {
            OnCommand(this,message);
        }

        HWIN_EXPORT void Control::DoOnCopyData(Message& message)
        {
            OnCopyData(this,message);
        }

        HWIN_EXPORT void Control::DoOnDeadChar(Message& message)
        {
            OnDeadChar(this,message);
        }

        HWIN_EXPORT void Control::DoOnDeleteItem(Message& message)
        {
            OnDeleteItem(this,message);
        }

        HWIN_EXPORT void Control::DoOnDestroy(Message& message)
        {
            OnDestroy(this,message);
        }

        HWIN_EXPORT void Control::DoOnDisplayChange(Message& message)
        {
            OnDisplayChange(this,message);
        }

        HWIN_EXPORT void Control::DoOnDrawItem(Message& message)
        {
            OnDrawItem(this,message);
            if(!message.handled)
            {
                DRAWITEMSTRUCT* drawItemStruct = (DRAWITEMSTRUCT*)message.lParam;
                if(drawItemStruct && drawItemStruct->CtlType == ODT_MENU)
                {
                    MenuItem* menuItem = (MenuItem*)drawItemStruct->itemData;
                    if(menuItem)
                    {
                        menuItem->DoOnDrawItem(*drawItemStruct);
                        message.handled = true;
                        message.result = true;
                    }
                }
            }
        }

        HWIN_EXPORT void Control::DoOnEnable(Message& message)
        {
            OnEnable(this,message);
        }

        HWIN_EXPORT void Control::DoOnEnterSizeMove(Message& message)
        {
            OnEnterSizeMove(this,message);
        }

        HWIN_EXPORT void Control::DoOnEraseBackground(Message& message)
        {
            OnEraseBackground(this,message);
        }

        HWIN_EXPORT void Control::DoOnExitSizeMove(Message& message)
        {
            OnExitSizeMove(this,message);
        }

        HWIN_EXPORT void Control::DoOnGetHotKey(Message& message)
        {
            OnGetHotKey(this,message);
        }

        HWIN_EXPORT void Control::DoOnGetText(Message& message)
        {
            OnGetText(this,message);
        }

        HWIN_EXPORT void Control::DoOnGetTextLength(Message& message)
        {
            OnGetTextLength(this,message);
        }

        HWIN_EXPORT void Control::DoOnInitMenu(Message& message)
        {
            OnInitMenu(this,message);
            if(!message.handled)
            {
                HMENU hMenu = (HMENU)message.lParam;
                if(hMenu)
                {
                    auto menu = Menu::GetFromMenuMap(hMenu);
                    if(menu)
                    {
                        menu->DoOnInitMenu(message);
                    }
                }
            }
        }

        HWIN_EXPORT void Control::DoOnInitMenuPopup(Message& message)
        {
            OnInitMenuPopup(this,message);
            if(!message.handled)
            {
                HMENU hMenu = (HMENU)message.wParam;
                if(hMenu)
                {
                    auto menu = Menu::GetFromMenuMap(hMenu);
                    if(menu)
                    {
                        menu->DoOnInitMenuPopup(message);
                    }
                }
            }
        }


        HWIN_EXPORT void Control::DoOnKeyDown(Message& message)
        {
            OnKeyDown(this,message);
        }

        HWIN_EXPORT void Control::DoOnKeyUp(Message& message)
        {
            OnKeyUp(this,message);
        }

        HWIN_EXPORT void Control::DoOnKillFocus(Message& message)
        {
            OnKillFocus(this,message);
        }

        HWIN_EXPORT void Control::DoOnMeasureItem(Message& message)
        {
            OnMeasureItem(this,message);
            if(!message.handled)
            {
                MEASUREITEMSTRUCT* measureItemStruct = (MEASUREITEMSTRUCT*)message.lParam;
                if(measureItemStruct && measureItemStruct->CtlType == ODT_MENU)
                {
                    MenuItem* menuItem = (MenuItem*)measureItemStruct->itemData;
                    if(menuItem)
                    {
                        menuItem->DoOnMeasureItem(*measureItemStruct);
                        message.handled = true;
                        message.result = true;
                    }
                }
            }
        }

        HWIN_EXPORT void Control::DoOnMenuCommand(Message& message)
        {
            OnMenuCommand(this,message);
            if(!message.handled)
            {
                HMENU hMenu = (HMENU)message.lParam;
                if(hMenu)
                {
                    auto menu = Menu::GetFromMenuMap(hMenu);
                    if(menu)
                    {
                        menu->DoOnMenuCommand(message);
                    }
                }
            }
        }

        HWIN_EXPORT void Control::DoOnMouseMove(Message& message)
        {
            OnMouseMove(this,message);
        }

        HWIN_EXPORT void Control::DoOnMouseLeftButtonDown(Message& message)
        {
            OnMouseLeftButtonDown(this,message);
        }

        HWIN_EXPORT void Control::DoOnMouseLeftButtonUp(Message& message)
        {
            OnMouseLeftButtonUp(this,message);
        }

        HWIN_EXPORT void Control::DoOnMouseLeftButtonDoubleClick(Message& message)
        {
            OnMouseLeftButtonDoubleClick(this,message);
        }

        HWIN_EXPORT void Control::DoOnMouseMiddleButtonDown(Message& message)
        {
            OnMouseMiddleButtonDown(this,message);
        }

        HWIN_EXPORT void Control::DoOnMouseMiddleButtonUp(Message& message)
        {
            OnMouseMiddleButtonUp(this,message);
        }

        HWIN_EXPORT void Control::DoOnMouseMiddleButtonDoubleClick(Message& message)
        {
            OnMouseMiddleButtonDoubleClick(this,message);
        }

        HWIN_EXPORT void Control::DoOnMouseRightButtonDown(Message& message)
        {
            OnMouseRightButtonDown(this,message);
        }

        HWIN_EXPORT void Control::DoOnMouseRightButtonUp(Message& message)
        {
            OnMouseRightButtonUp(this,message);
        }

        HWIN_EXPORT void Control::DoOnMouseRightButtonDoubleClick(Message& message)
        {
            OnMouseRightButtonDoubleClick(this,message);
        }

        HWIN_EXPORT void Control::DoOnMouseXButtonDown(Message& message)
        {
            OnMouseXButtonDown(this,message);
        }

        HWIN_EXPORT void Control::DoOnMouseXButtonUp(Message& message)
        {
            OnMouseXButtonUp(this,message);
        }

        HWIN_EXPORT void Control::DoOnMouseXButtonDoubleClick(Message& message)
        {
            OnMouseXButtonDoubleClick(this,message);
        }

        HWIN_EXPORT void Control::DoOnMouseWheel(Message& message)
        {
            OnMouseWheel(this,message);
        }



        HWIN_EXPORT void Control::DoOnMove(Message& message)
        {
            OnMove(this,message);
        }

        HWIN_EXPORT void Control::DoOnMoving(Message& message)
        {
            OnMoving(this,message);
        }

        HWIN_EXPORT void Control::DoOnNcActivate(Message& message)
        {
            OnNcActivate(this,message);
        }    

        HWIN_EXPORT void Control::DoOnNcCalcSize(Message& message)
        {
            OnNcCalcSize(this,message);
        }

        HWIN_EXPORT void Control::DoOnNcDestroy(Message& message)
        {
            OnNcDestroy(this,message);
        }

        HWIN_EXPORT void Control::DoOnNotify(Message& message)
        {
            OnNotify(this,message);
        }

        HWIN_EXPORT void Control::DoOnPaint(Message& message)
        {
            OnPaint(this,message);
        }

        HWIN_EXPORT void Control::DoOnSetCursor(Message& message)
        {
            OnSetCursor(this,message);
        }

        HWIN_EXPORT void Control::DoOnSetFocus(Message& message)
        {
            OnSetFocus(this,message);
        }

        HWIN_EXPORT void Control::DoOnSetHotKey(Message& message)
        {
            OnSetHotKey(this,message);
        }

        HWIN_EXPORT void Control::DoOnSetRedraw(Message& message)
        {
            OnSetRedraw(this,message);
        }

        HWIN_EXPORT void Control::DoOnSetText(Message& message)
        {
            OnSetText(this,message);
        }
        HWIN_EXPORT void Control::DoOnShowWindow(Message& message)
        {
            OnShowWindow(this,message);
        }

        HWIN_EXPORT void Control::DoOnSize(Message& message)
        {
            OnSize(this,message);
        }

        HWIN_EXPORT void Control::DoOnSizing(Message& message)
        {
            OnSizing(this,message);
        }

        HWIN_EXPORT void Control::DoOnSysChar(Message& message)
        {
            OnSysChar(this,message);
        }

        HWIN_EXPORT void Control::DoOnSysCommand(Message& message)
        {
            OnSysCommand(this,message);
        }

        HWIN_EXPORT void Control::DoOnSysDeadChar(Message& message)
        {
            OnSysDeadChar(this,message);
        }

        HWIN_EXPORT void Control::DoOnSysKeyDown(Message& message)
        {
            OnSysKeyDown(this,message);
        }

        HWIN_EXPORT void Control::DoOnSysKeyUp(Message& message)
        {
            OnSysKeyUp(this,message);
        }


        HWIN_EXPORT void Control::DoOnUniChar(Message& message)
        {
            OnUniChar(this,message);
        }

        HWIN_EXPORT void Control::DoOnVKeyToItem(Message& message)
        {
            OnVKeyToItem(this,message);
        }

        HWIN_EXPORT void Control::DoOnWindowPosChanging(Message& message)
        {
            OnWindowPosChanging(this,message);
        }

        HWIN_EXPORT void Control::DoOnWindowPosChanged(Message& message)
        {
            OnWindowPosChanged(this,message);
        }







    };
};

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