Click here to Skip to main content
15,881,709 members
Articles / Desktop Programming / Win32

Windows Development in C++, Working with Menus

Rate me:
Please Sign up or sign in to vote.
4.96/5 (60 votes)
3 Jan 2015CPOL19 min read 171.5K   4.1K   163  
Windows API, menus, C++ lambda expressions, std::enable_shared_from_this
#include "stdafx.h"

#include "hwinclass.h"
#include "hwinapplication.h"


namespace harlinn
{
    namespace windows
    {
        String HWIN_EXPORT WindowClass::animate_class_name = String(ANIMATE_CLASS);
        String HWIN_EXPORT WindowClass::datetimepick_class_name = String(DATETIMEPICK_CLASS);
        String HWIN_EXPORT WindowClass::hotkey_class_name = String(HOTKEY_CLASS);
        String HWIN_EXPORT WindowClass::link_class_name = String(WC_LINK);
        String HWIN_EXPORT WindowClass::monthcal_class_name = String(MONTHCAL_CLASS);
        String HWIN_EXPORT WindowClass::nativefontctl_class_name = String(WC_NATIVEFONTCTL);
        String HWIN_EXPORT WindowClass::progress_class_name = String(PROGRESS_CLASS);
        String HWIN_EXPORT WindowClass::rebar_class_name = String(REBARCLASSNAME);
        String HWIN_EXPORT WindowClass::status_class_name = String(STATUSCLASSNAME);
        String HWIN_EXPORT WindowClass::toolbar_class_name = String(TOOLBARCLASSNAME);
        String HWIN_EXPORT WindowClass::tooltips_class_name = String(TOOLTIPS_CLASS);
        String HWIN_EXPORT WindowClass::trackbar_class_name = String(TRACKBAR_CLASS);
        String HWIN_EXPORT WindowClass::updown_class_name = String(UPDOWN_CLASS);
        String HWIN_EXPORT WindowClass::button_class_name = String(WC_BUTTON);
        String HWIN_EXPORT WindowClass::combobox_class_name = String(WC_COMBOBOXEX);
        String HWIN_EXPORT WindowClass::edit_class_name = String(WC_EDIT);
        String HWIN_EXPORT WindowClass::header_class_name = String(WC_HEADER);
        String HWIN_EXPORT WindowClass::listbox_class_name = String(WC_LISTBOX);
        String HWIN_EXPORT WindowClass::ipaddress_class_name = String(WC_IPADDRESS);
        String HWIN_EXPORT WindowClass::listview_class_name = String(WC_LISTVIEW);
        String HWIN_EXPORT WindowClass::pagescroller_class_name = String(WC_PAGESCROLLER);
        String HWIN_EXPORT WindowClass::scrollbar_class_name = String(WC_SCROLLBAR);
        String HWIN_EXPORT WindowClass::static_class_name = String(WC_STATIC);
        String HWIN_EXPORT WindowClass::tabcontrol_class_name = String(WC_TABCONTROL);
        String HWIN_EXPORT WindowClass::treeview_class_name = String(WC_TREEVIEW);



        HWIN_EXPORT WindowClass::WindowClass()
            : style(0), procedure(0), classExtraBytes(0), windowExtraBytes(0), moduleHandle(0),
                icon(0), cursor(0), backgroundBrush(0), smallIcon(0)
        {}

        HWIN_EXPORT WindowClass::WindowClass(const WNDCLASSEX& wndClass)
            : style(wndClass.style), procedure(wndClass.lpfnWndProc), classExtraBytes(wndClass.cbClsExtra), 
            windowExtraBytes(wndClass.cbWndExtra), moduleHandle(wndClass.hInstance),
            icon(wndClass.hIcon), cursor(wndClass.hCursor), backgroundBrush(wndClass.hbrBackground), smallIcon(wndClass.hIconSm)
        {
            if(wndClass.lpszClassName)
            {
                name = String(wndClass.lpszClassName);
            }
            if(wndClass.lpszMenuName)
            {
                menuName = String(wndClass.lpszMenuName);
            }
        }


        HWIN_EXPORT WindowClass::WindowClass(std::shared_ptr<const WindowClass> existingClass)
            : name(existingClass->name),menuName(existingClass->menuName),style(existingClass->style), procedure(existingClass->procedure), classExtraBytes(existingClass->classExtraBytes), 
            windowExtraBytes(existingClass->windowExtraBytes), moduleHandle(existingClass->moduleHandle),
            icon(existingClass->icon), cursor(existingClass->cursor), backgroundBrush(existingClass->backgroundBrush), smallIcon(existingClass->smallIcon)
        {
        }


        HWIN_EXPORT WindowClass::~WindowClass()
        {

        }


        HWIN_EXPORT WindowClass& WindowClass::Register()
        {
            auto application = Application::Current();
            if(application)
            {
                auto windowClasses = application->GetWindowClasses();
                if(windowClasses)
                {
                    auto self = As<WindowClass>();
                    windowClasses->Register(self);
                    
                }
            }
            return *this;
        }



        HWIN_EXPORT WNDCLASSEX WindowClass::AsWNDCLASSEX() const
        {
            WNDCLASSEX result = {0,};

            result.cbSize = sizeof(WNDCLASSEX);
            result.style = this->GetStyle();
            result.lpfnWndProc = this->GetProcedure();
            result.cbClsExtra = this->GetClassExtraBytes();
            result.cbWndExtra = this->GetWindowExtraBytes();
            result.hInstance = this->GetModuleHandle();
            result.hIcon = this->GetIcon();
            result.hCursor = this->GetCursor();
            result.hbrBackground = this->GetBackgroundBrush();
            if(menuName.length())
            {
                result.lpszMenuName = menuName.c_str();
            }
            else
            {
                result.lpszMenuName = nullptr;
            }
            if(name.length())
            {
                result.lpszClassName = name.c_str();
            }
            else
            {
                result.lpszClassName = nullptr;
            }
            result.hIconSm = this->GetSmallIcon();

            return result;
        }


        HWIN_EXPORT const String& WindowClass::GetName() const
        {
            return name;
        }

        HWIN_EXPORT WindowClass& WindowClass::SetName( const String& theName)
        {
            name = theName;
            return *this;
        }


        HWIN_EXPORT const String& WindowClass::GetMenuName() const
        {
            return menuName;
        }

        HWIN_EXPORT WindowClass& WindowClass::SetMenuName(const String& theMenuName)
        {
            menuName = theMenuName;
            return *this;
        }


        HWIN_EXPORT UINT WindowClass::GetStyle() const
        {
            return style;
        }

        HWIN_EXPORT WindowClass& WindowClass::SetStyle(UINT theStyle)
        {
            style = theStyle;
            return *this;
        }


        HWIN_EXPORT WNDPROC WindowClass::GetProcedure() const
        {
            return procedure;
        }

        HWIN_EXPORT WindowClass& WindowClass::SetProcedure(WNDPROC theProcedure)
        {
            procedure = theProcedure;
            return *this;
        }


        HWIN_EXPORT int WindowClass::GetClassExtraBytes() const
        {
            return classExtraBytes;
        }

        HWIN_EXPORT WindowClass& WindowClass::SetClassExtraBytes(int theClassExtraBytes)
        {
            classExtraBytes = theClassExtraBytes;
            return *this;
        }


        HWIN_EXPORT int WindowClass::GetWindowExtraBytes() const
        {
            return windowExtraBytes;
        }

        HWIN_EXPORT WindowClass& WindowClass::SetWindowExtraBytes(int theWindowExtraBytes)
        {
            windowExtraBytes = theWindowExtraBytes;
            return *this;
        }


        HWIN_EXPORT HINSTANCE WindowClass::GetModuleHandle() const
        {
            return moduleHandle;
        }

        HWIN_EXPORT WindowClass& WindowClass::SetModuleHandle(HINSTANCE theModuleHandle)
        {
            moduleHandle = theModuleHandle;
            return *this;
        }


        HWIN_EXPORT HICON WindowClass::GetIcon() const
        {
            return icon;
        }

        HWIN_EXPORT WindowClass& WindowClass::SetIcon(HICON theIcon)
        {
            icon = theIcon;
            return *this;
        }


        HWIN_EXPORT HCURSOR WindowClass::GetCursor() const
        {
            return cursor;
        }

        HWIN_EXPORT WindowClass& WindowClass::SetCursor(HCURSOR theCursor)
        {
            cursor = theCursor;
            return *this;
        }


        HWIN_EXPORT HBRUSH WindowClass::GetBackgroundBrush() const
        {
            return backgroundBrush;
        }

        HWIN_EXPORT WindowClass& WindowClass::SetBackgroundBrush(HBRUSH theBackgroundBrush)
        {
            backgroundBrush = theBackgroundBrush;
            return *this;
        }


        HWIN_EXPORT HICON WindowClass::GetSmallIcon() const
        {
            return smallIcon;
        }

        HWIN_EXPORT WindowClass& WindowClass::SetSmallIcon(HICON theSmallIcon)
        {
            smallIcon = theSmallIcon;
            return *this;
        }




        HWIN_EXPORT WindowClasses::WindowClasses()
        {
            LoadStandardClasses();
        }

        HWIN_EXPORT WindowClasses::~WindowClasses()
        {
            
        }



        void WindowClasses::LoadStandardClasses()
        {
            LoadStandardClass(WindowClass::animate_class_name);
            LoadStandardClass(WindowClass::datetimepick_class_name);
            LoadStandardClass(WindowClass::hotkey_class_name);
            LoadStandardClass(WindowClass::link_class_name);
            LoadStandardClass(WindowClass::monthcal_class_name);
            LoadStandardClass(WindowClass::nativefontctl_class_name);
            LoadStandardClass(WindowClass::progress_class_name);
            LoadStandardClass(WindowClass::rebar_class_name);
            LoadStandardClass(WindowClass::status_class_name);
            LoadStandardClass(WindowClass::toolbar_class_name);
            LoadStandardClass(WindowClass::tooltips_class_name);
            LoadStandardClass(WindowClass::trackbar_class_name);
            LoadStandardClass(WindowClass::updown_class_name);
            LoadStandardClass(WindowClass::button_class_name);
            LoadStandardClass(WindowClass::combobox_class_name);
            LoadStandardClass(WindowClass::edit_class_name);
            LoadStandardClass(WindowClass::header_class_name);
            LoadStandardClass(WindowClass::listbox_class_name);
            LoadStandardClass(WindowClass::ipaddress_class_name);
            LoadStandardClass(WindowClass::listview_class_name);
            LoadStandardClass(WindowClass::pagescroller_class_name);
            LoadStandardClass(WindowClass::scrollbar_class_name);
            LoadStandardClass(WindowClass::static_class_name);
            LoadStandardClass(WindowClass::tabcontrol_class_name);
            LoadStandardClass(WindowClass::treeview_class_name);

        }


        void WindowClasses::LoadStandardClass(const String& className)
        {
            auto cit = map.find(className);
            if(cit == map.end())
            {
                auto windowClass = GetClassInfo(className);
                map.insert(map_t::value_type(className,windowClass));
            }
        }


        HWIN_EXPORT std::shared_ptr<WindowClass> WindowClasses::GetClassInfo(const String& className)
        {
            auto result = GetClassInfo((HINSTANCE)0,className);
            return result;
        }

        HWIN_EXPORT std::shared_ptr<WindowClass> WindowClasses::GetClassInfo(HINSTANCE hInstance, const String& className)
        {
            WNDCLASSEX wndCls = {0,};
            GetClassInfoEx(hInstance,className.c_str(), &wndCls);
            auto result = std::make_shared<WindowClass>(wndCls);
            return result;
        }

        HWIN_EXPORT std::shared_ptr<WindowClass> WindowClasses::GetWindowClass(const String& className) const
        {
            auto cit = map.find(className);
            if(cit != map.end())
            {
                auto result = (*cit).second;
                return result;
            }
            return std::shared_ptr<WindowClass>();
        }

        HWIN_EXPORT bool WindowClasses::Register(std::shared_ptr<WindowClass> theWindowClass)
        {
            CheckPointerNotNull(theWindowClass);

            auto theName = theWindowClass->GetName();
            if(theName.length())
            {
                auto windowClass = GetWindowClass(theName);
                if(!windowClass)
                {
                    WNDCLASSEX wndCls = theWindowClass->AsWNDCLASSEX();
                    ATOM atom = ::RegisterClassExW(&wndCls);
                    if(!atom)
                    {
                        ThrowLastOSError();
                    }
                    map.insert(map_t::value_type(theName,theWindowClass));
                    return true;
                }
            }
            return false;
        }



    }
}

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