Click here to Skip to main content
15,886,518 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.9K   4.1K   163  
Windows API, menus, C++ lambda expressions, std::enable_shared_from_this
// StopwatchExample2.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "hwindatetime.h"
#include "hwinvariant.h"
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>  
#include <algorithm> 
#include <vector> 


using namespace harlinn::windows;
using namespace std;

/*
template<typename T>
class Buffer
{ 
    size_t length; 
    T* ptr;
public:
    Buffer(); 
    Buffer(const Buffer& other); 
    Buffer(const Buffer& first,const Buffer& second);
    Buffer( size_t theLength, const T& theValue);
    ~Buffer(); 
    int compare(const Buffer& other) const;
    bool operator < ( const Buffer& other );
    bool operator > ( const Buffer& other );
    Buffer& operator = ( const Buffer& other ); 
    inline friend Buffer operator + (const Buffer& first,const Buffer& second);
};


template<typename T>
class Buffer2
{ 
    size_t length; 
    T* ptr;
public:
    Buffer2(); 
    Buffer2(const Buffer2& other); 
    Buffer2(Buffer2&& other); 
    Buffer2(const Buffer2& first,const Buffer2& second);
    Buffer2( size_t theLength, const T& theValue); 
    ~Buffer2(); 
    int compare(const Buffer2& other) const;
    bool operator < ( const Buffer2& other );
    bool operator > ( const Buffer2& other );
    Buffer2& operator = ( const Buffer2& other ); 
    Buffer2& operator = ( Buffer2&& other ); 
    inline friend Buffer2 operator + (const Buffer2& first,const Buffer2& second);
};
 */

//////////////////////////////////////////////////////////////////////////////////////////////
template<typename T>
class Buffer
{ 
    size_t length; 
    T* ptr;
public:
    Buffer() 
        : length(0),
          ptr(0) 
    {}

    Buffer(const Buffer& other) 
        : length(other.length),
          ptr(0) 
    {
        if(length)
        {
            ptr = new T[length]; 
            copy(other.ptr,other.ptr+length,ptr);
        }
    }

    Buffer(const Buffer& first,const Buffer& second)
        : length(first.length,second.length),
          ptr(0) 
    {
        if(length)
        {
            ptr = new T[length]; 
            copy(first.ptr,first.ptr+first.length,ptr);
            copy(second.ptr,second.ptr+second.length,ptr+first.length);
        }
    }


    Buffer( size_t theLength, const T& theValue) 
        : length(theLength),
          ptr(0) 
    {
        if(theLength)
        {
            ptr = new T[length];
            fill(ptr,ptr+length,theValue);
        }
    }

    ~Buffer() 
    {
        delete ptr;
    }

int compare(const Buffer& other) const
{
    int result = 0;
    size_t compareLength = min(length,other.length);
    for(size_t i = 0; i < compareLength; i++)
    {
        const T& v1 = ptr[i];
        const T& v2 = other.ptr[i];
        if(v1 > v2)
        {
            result = 1;
            break;
        }
        if(v1 < v2)
        {
            result = -1;
            break;
        }
    }
    if(result == 0)
    {
        if(length > other.length)
        {
            result = 1;
        }
        else if(length < other.length)
        {
            result = -1;
        }
    }
    return result;
    //return ptr[0] - other.ptr[0];
}

    bool operator < ( const Buffer& other )
    {
        return compare(other) < 0;
    }

    bool operator > ( const Buffer& other )
    {
        return compare(other) > 0;
    }


    Buffer& operator = ( const Buffer& other ) 
    { 
        if(other.ptr != ptr)
        {
            delete ptr;
            length = other.length;
            ptr = new T[length]; 
            copy(other.ptr,other.ptr+length,ptr);
        }
        return *this;
    }

    inline friend Buffer operator + (const Buffer& first,const Buffer& second)
    {
        return Buffer(first,second);
    }

};


template<typename T>
class Buffer2
{ 
    size_t length; 
    T* ptr;
public:
    Buffer2() 
        : length(0),
          ptr(0) 
    {}

    Buffer2(const Buffer2& other) 
        : length(other.length),
          ptr(0) 
    {
        if(length)
        {
            ptr = new T[length]; 
            copy(other.ptr,other.ptr+length,ptr);
        }
    }

    Buffer2(Buffer2&& other) 
        : length(other.length),
          ptr(0) 
    {
        if(length)
        {
            ptr = other.ptr; 
            other.ptr = nullptr;
            other.length = 0;
        }
    }


    Buffer2(const Buffer2& first,const Buffer2& second)
        : length(first.length,second.length),
          ptr(0) 
    {
        if(length)
        {
            ptr = new T[length]; 
            copy(first.ptr,first.ptr+first.length,ptr);
            copy(second.ptr,second.ptr+second.length,ptr+first.length);
        }
    }


    Buffer2( size_t theLength, const T& theValue) 
        : length(theLength),
          ptr(0) 
    {
        if(theLength)
        {
            ptr = new T[length];
            fill(ptr,ptr+length,theValue);
        }
    }

    ~Buffer2() 
    {
        delete ptr;
    }

    int compare(const Buffer2& other) const
    {
        
        int result = 0;
        size_t compareLength = min(length,other.length);
        for(size_t i = 0; i < compareLength; i++)
        {
            const T& v1 = ptr[i];
            const T& v2 = other.ptr[i];
            if(v1 > v2)
            {
                result = 1;
                break;
            }
            if(v1 < v2)
            {
                result = -1;
                break;
            }
        }
        if(result == 0)
        {
            if(length > other.length)
            {
                result = 1;
            }
            else if(length < other.length)
            {
                result = -1;
            }
        }
        return result;
        
        //return ptr[0] - other.ptr[0];
    }

    bool operator < ( const Buffer2& other )
    {
        return compare(other) < 0;
    }

    bool operator > ( const Buffer2& other )
    {
        return compare(other) > 0;
    }


    Buffer2& operator = ( const Buffer2& other ) 
    { 
        if(other.ptr != ptr)
        {
            delete ptr;
            length = other.length;
            ptr = new T[length]; 
            copy(other.ptr,other.ptr+length,ptr);
        }
        return *this;
    }

    Buffer2& operator = ( Buffer2&& other ) 
    { 
        if(this != &other)
        {
            delete ptr;
            length = other.length;
            ptr = other.ptr; 
            other.ptr = nullptr;
            other.length = 0;
        }
        return *this;
    }

    inline friend Buffer2 operator + (const Buffer2& first,const Buffer2& second)
    {
        return Buffer2(first,second);
    }

};

void BufferTestPushBack(int bufferCount, size_t bufferSize) 
{
    typedef Buffer <char> buffer_t;
    Stopwatch stopwatch;
    vector< buffer_t > buffers;	
    buffers.reserve(bufferCount);

    printf("Test vector push_back: copy constructible/copy assignable\n");
    stopwatch.Start();
    for(int i = 0; i < bufferCount; i++) 
    {
        char c = i%24;
        buffers.push_back(buffer_t(size_t(bufferSize),c));
    }

    stopwatch.Stop();
    printf("\tpush_back of %d elements in %f ms\n",bufferCount ,stopwatch.Elapsed().TotalMilliseconds() );
    stopwatch.Restart();
    sort(buffers.begin(),buffers.end());
    stopwatch.Stop();
    printf("\tsorted %d elements in %f ms\n\n", bufferCount ,stopwatch.Elapsed().TotalMilliseconds() );
}


void BufferTest(int bufferCount, size_t bufferSize) 
{
    typedef Buffer <char> buffer_t;
    Stopwatch stopwatch;
    vector< buffer_t > destinationBuffers(bufferCount);
    vector< buffer_t > sourceBuffers;
    sourceBuffers.reserve(bufferCount);

    for(int i = 0; i < bufferCount; i++) 
    {
        char c = i%24;
        sourceBuffers.push_back(buffer_t(size_t(bufferSize),c));
    }

    printf("Test vector copy: copy constructible/copy assignable\n");
    stopwatch.Start();
    for(int i = 0; i < bufferCount; i++) 
    {
        destinationBuffers[i] = sourceBuffers[i];
    }
    stopwatch.Stop();
    printf("\tcopy of %d elements in %f ms\n",bufferCount ,stopwatch.Elapsed().TotalMilliseconds() );
    stopwatch.Restart();
    sort(destinationBuffers.begin(),destinationBuffers.end());
    stopwatch.Stop();
    printf("\tsorted %d elements in %f ms\n\n", bufferCount ,stopwatch.Elapsed().TotalMilliseconds() );
}


void Buffer2TestPushBack(int bufferCount, size_t bufferSize) 
{
    typedef Buffer2 <char> buffer_t;
    Stopwatch stopwatch;
    vector< buffer_t > buffers;	
    buffers.reserve(bufferCount);

    printf("Test vector push_back: move constructible/move assignable\n");
    stopwatch.Start();
    for(int i = 0; i < bufferCount; i++) 
    {
        char c = i%24;
        buffers.push_back(buffer_t(size_t(bufferSize),c));
    }

    stopwatch.Stop();
    printf("\tpush_back of %d elements in %f ms\n", bufferCount ,stopwatch.Elapsed().TotalMilliseconds() );
    stopwatch.Restart();
    sort(buffers.begin(),buffers.end());
    stopwatch.Stop();
    printf("\tsorted %d elements in %f ms\n\n", bufferCount ,stopwatch.Elapsed().TotalMilliseconds() );
}

void Buffer2Test(int bufferCount, size_t bufferSize) 
{
    typedef Buffer2 <char> buffer_t;
    Stopwatch stopwatch;
    vector< buffer_t > destinationBuffers(bufferCount);	
    vector< buffer_t > sourceBuffers;
    sourceBuffers.reserve(bufferCount);

    for(int i = 0; i < bufferCount; i++) 
    {
        char c = i%24;
        sourceBuffers.push_back(buffer_t(size_t(bufferSize),c));
    }

    printf("Test vector move constructible/move assignable\n");
    stopwatch.Start();
    for(int i = 0; i < bufferCount; i++) 
    {
        destinationBuffers[i] = sourceBuffers[i];
    }
    stopwatch.Stop();
    printf("\tcopy of %d elements in %f ms\n", bufferCount ,stopwatch.Elapsed().TotalMilliseconds() );
    stopwatch.Restart();
    sort(destinationBuffers.begin(),destinationBuffers.end());
    stopwatch.Stop();
    printf("\tsorted %d elements in %f ms\n\n", bufferCount ,stopwatch.Elapsed().TotalMilliseconds() );
}


void BufferPointerTestPushBack(int bufferCount, size_t bufferSize) 
{
    typedef Buffer <char> buffer_t;
    vector<buffer_t*> buffers;
    buffers.reserve(bufferCount);

    Stopwatch stopwatch;
    printf("Test vector of raw pointers\n");
    stopwatch.Start();
    for(int i = 0; i < bufferCount; i++) 
    {
        char c = i%24;
        buffers.push_back(new buffer_t(size_t(bufferSize),c));
    }
    stopwatch.Stop();
    printf("\tpush_back of %d pointers in %f ms\n", bufferCount ,stopwatch.Elapsed().TotalMilliseconds() );
    stopwatch.Restart();
    sort(buffers.begin(),buffers.end(), [] (buffer_t* a, buffer_t* b) 
    { 
        if(a && b)
        {
            return a->compare(*b) < 0;
        }
        if(b)
        {
            return true;
        }
        return false; 
    });

    stopwatch.Stop();
    printf("\tsorted %d pointers in %f ms\n\n", bufferCount ,stopwatch.Elapsed().TotalMilliseconds() );
    for(auto it = buffers.begin(); it != buffers.end(); it++) 
    {  
        buffer_t* ptr = *it;
        delete ptr;
    }
}

void BufferPointerTest(int bufferCount, size_t bufferSize) 
{
    typedef Buffer <char> buffer_t;
    vector<buffer_t*> destinationBuffers(bufferCount);	
    vector<buffer_t*> sourceBuffers;
    sourceBuffers.reserve(bufferCount);

    for(int i = 0; i < bufferCount; i++) 
    {
        char c = i%24;
        sourceBuffers.push_back(new buffer_t(size_t(bufferSize),c));
    }


    Stopwatch stopwatch;
    printf("Test vector of raw pointers \n");
    stopwatch.Start();
    for(int i = 0; i < bufferCount; i++) 
    {
        destinationBuffers[i] = sourceBuffers[i];
    }
    stopwatch.Stop();
    printf("\tcopy of %d pointers in %f ms\n", bufferCount ,stopwatch.Elapsed().TotalMilliseconds() );
    stopwatch.Restart();
    sort(destinationBuffers.begin(),destinationBuffers.end(), [] (buffer_t* a, buffer_t* b) 
    { 
        if(a && b)
        {
            return a->compare(*b) < 0;
        }
        if(b)
        {
            return true;
        }
        return false; 
    });

    stopwatch.Stop();
    printf("\tsorted %d pointers in %f ms\n\n", bufferCount ,stopwatch.Elapsed().TotalMilliseconds() );
    for(auto it = destinationBuffers.begin(); it != destinationBuffers.end(); it++) 
    {  
        buffer_t* ptr = *it;
        delete ptr;
    }
}


void BufferArrayOfPointerTest(int bufferCount, size_t bufferSize) 
{
    typedef Buffer <char> buffer_t;
    buffer_t** destinationBuffers = new buffer_t*[bufferCount];
    buffer_t** sourceBuffers = new buffer_t*[bufferCount];

    for(int i = 0; i < bufferCount; i++) 
    {
        char c = i%24;
        sourceBuffers[i] = new buffer_t(size_t(bufferSize),c);
    }


    Stopwatch stopwatch;
    printf("Test array of raw pointers\n");
    stopwatch.Start();
    for(int i = 0; i < bufferCount; i++) 
    {
        destinationBuffers[i] = sourceBuffers[i];
    }
    stopwatch.Stop();
    printf("\tcopy of %d pointers in %f ms\n", bufferCount ,stopwatch.Elapsed().TotalMilliseconds() );
    stopwatch.Restart();
    buffer_t** first = destinationBuffers;
    buffer_t** last = &destinationBuffers[size_t(bufferCount)];
    sort(first,last, [] (buffer_t* a, buffer_t* b) 
    { 
        if(a && b)
        {
            return a->compare(*b) < 0;
        }
        if(b)
        {
            return true;
        }
        return false; 
    });

    stopwatch.Stop();
    printf("\tsorted %d pointers in %f ms\n\n", bufferCount ,stopwatch.Elapsed().TotalMilliseconds() );
    for(int i = 0; i < bufferCount; i++) 
    {  
        delete destinationBuffers[i];
    }
    delete destinationBuffers;
    delete sourceBuffers;
}

void BufferArrayTest(int bufferCount, size_t bufferSize) 
{
    typedef Buffer <char> buffer_t;
    buffer_t* destinationBuffers = new buffer_t[bufferCount];
    buffer_t* sourceBuffers = new buffer_t[bufferCount];

    for(int i = 0; i < bufferCount; i++) 
    {
        char c = i%24;
        sourceBuffers[i] = buffer_t(size_t(bufferSize),c);
    }


    Stopwatch stopwatch;
    printf("Test array: copy constructible/copy assignable\n");
    stopwatch.Start();
    for(int i = 0; i < bufferCount; i++) 
    {
        destinationBuffers[i] = sourceBuffers[i];
    }
    stopwatch.Stop();
    printf("\tcopy of %d elements in %f ms\n", bufferCount ,stopwatch.Elapsed().TotalMilliseconds() );
    stopwatch.Restart();
    buffer_t* first = destinationBuffers;
    buffer_t* last = &destinationBuffers[size_t(bufferCount)];
    sort(first,last, [] (const buffer_t& a, const buffer_t& b) 
    { 
        return a.compare(b) < 0;
    });

    stopwatch.Stop();
    printf("\tsorted %d elements in %f ms\n\n", bufferCount ,stopwatch.Elapsed().TotalMilliseconds() );
    delete[] destinationBuffers;
    delete[] sourceBuffers;
}


void BufferArrayNoLambdaTest(int bufferCount, size_t bufferSize) 
{
    typedef Buffer <char> buffer_t;
    buffer_t* destinationBuffers = new buffer_t[bufferCount];
    buffer_t* sourceBuffers = new buffer_t[bufferCount];

    for(int i = 0; i < bufferCount; i++) 
    {
        char c = i%24;
        sourceBuffers[i] = buffer_t(size_t(bufferSize),c);
    }


    Stopwatch stopwatch;
    printf("Test array: Copy constructible/copy assignable (no lambda)\n");
    stopwatch.Start();
    for(int i = 0; i < bufferCount; i++) 
    {
        destinationBuffers[i] = sourceBuffers[i];
    }
    stopwatch.Stop();
    printf("\tcopy of %d elements in %f ms\n", bufferCount ,stopwatch.Elapsed().TotalMilliseconds() );
    stopwatch.Restart();
    buffer_t* first = destinationBuffers;
    buffer_t* last = &destinationBuffers[size_t(bufferCount)];
    sort(first,last);

    stopwatch.Stop();
    printf("\tsorted %d elements in %f ms\n\n", bufferCount ,stopwatch.Elapsed().TotalMilliseconds() );
    delete[] destinationBuffers;
    delete[] sourceBuffers;
}


void Buffer2ArrayNoLambdaTest(int bufferCount, size_t bufferSize) 
{
    typedef Buffer2 <char> buffer_t;
    buffer_t* destinationBuffers = new buffer_t[bufferCount];
    buffer_t* sourceBuffers = new buffer_t[bufferCount];

    for(int i = 0; i < bufferCount; i++) 
    {
        char c = i%24;
        sourceBuffers[i] = buffer_t(size_t(bufferSize),c);
    }


    Stopwatch stopwatch;
    printf("Test array: Copy of move constructible/move assignable (no lambda)\n");
    stopwatch.Start();
    for(int i = 0; i < bufferCount; i++) 
    {
        destinationBuffers[i] = sourceBuffers[i];
    }
    stopwatch.Stop();
    printf("\tcopy of %d elements in %f ms\n", bufferCount ,stopwatch.Elapsed().TotalMilliseconds() );
    stopwatch.Restart();
    buffer_t* first = destinationBuffers;
    buffer_t* last = &destinationBuffers[size_t(bufferCount)];
    sort(first,last);

    stopwatch.Stop();
    printf("\tsorted %d elements in %f ms\n\n", bufferCount ,stopwatch.Elapsed().TotalMilliseconds() );
    delete[] destinationBuffers;
    delete[] sourceBuffers;
}


void Buffer_shared_ptr_TestPushBack(int bufferCount, size_t bufferSize) 
{
    typedef Buffer <char> buffer_t;
    vector< shared_ptr<buffer_t> > buffers;	
    buffers.reserve(bufferCount);

    Stopwatch stopwatch;
    printf("Test vector: push_back of shared_ptrs'\n");
    stopwatch.Start();

    for(int i = 0; i < bufferCount; i++) 
    {
        char c = i%24;
        buffers.push_back(make_shared<buffer_t>(size_t(bufferSize),c));
    }
    stopwatch.Stop();
    printf("\tpush_back of %d shared_ptrs' in %f ms\n", bufferCount ,stopwatch.Elapsed().TotalMilliseconds() );
    stopwatch.Restart();
    sort(buffers.begin(),buffers.end(), [] (const shared_ptr<buffer_t>& a, const shared_ptr<buffer_t>& b) 
    { 
        if(a && b)
        {
            return a->compare(*b.get()) < 0;
        }
        if(b)
        {
            return true;
        }
        return false;
    });

    stopwatch.Stop();
    printf("\tsorted %d shared_ptrs' in %f ms\n\n", bufferCount ,stopwatch.Elapsed().TotalMilliseconds() );
}


void Buffer_shared_ptr_Test(int bufferCount, size_t bufferSize) 
{
    typedef Buffer <char> buffer_t;
    vector< shared_ptr<buffer_t> > destinationBuffers(bufferCount);	
    vector< shared_ptr<buffer_t> > sourceBuffers;
    sourceBuffers.reserve(bufferCount);

    for(int i = 0; i < bufferCount; i++) 
    {
        char c = i%24;
        sourceBuffers.push_back(make_shared<buffer_t>(size_t(bufferSize),c));
    }

    Stopwatch stopwatch;
    printf("Test vector: Copy of shared_ptrs'\n");
    stopwatch.Start();
    for(int i = 0; i < bufferCount; i++) 
    {
        destinationBuffers[i] = sourceBuffers[i];
    }
    stopwatch.Stop();
    printf("\tcopied %d shared_ptrs' in %f ms\n", bufferCount ,stopwatch.Elapsed().TotalMilliseconds() );
    stopwatch.Restart();
    sort(destinationBuffers.begin(),destinationBuffers.end(), [] (const shared_ptr<buffer_t>& a, const shared_ptr<buffer_t>& b) 
    { 
        if(a && b)
        {
            return a->compare(*b.get()) < 0;
        }
        if(b)
        {
            return true;
        }
        return false;
    });

    stopwatch.Stop();
    printf("\tsorted %d shared_ptrs' in %f ms\n\n", bufferCount ,stopwatch.Elapsed().TotalMilliseconds() );
}

void BufferArrayOf_shared_ptr_Test(int bufferCount, size_t bufferSize) 
{
    typedef Buffer <char> buffer_t;
    shared_ptr<buffer_t>* destinationBuffers = new shared_ptr<buffer_t>[bufferCount];	
    shared_ptr<buffer_t>* sourceBuffers = new shared_ptr<buffer_t>[bufferCount];	

    for(int i = 0; i < bufferCount; i++) 
    {
        char c = i%24;
        sourceBuffers[i] = make_shared<buffer_t>(size_t(bufferSize),c);
    }


    Stopwatch stopwatch;
    printf("Test array: shared_ptrs'\n");
    stopwatch.Start();
    for(int i = 0; i < bufferCount; i++) 
    {
        destinationBuffers[i] = sourceBuffers[i];
    }
    stopwatch.Stop();
    printf("\tcopy of %d shared_ptrs' in %f ms\n", bufferCount ,stopwatch.Elapsed().TotalMilliseconds() );
    stopwatch.Restart();

    shared_ptr<buffer_t>* first = destinationBuffers;
    shared_ptr<buffer_t>* last = &destinationBuffers[size_t(bufferCount)];
    sort(first,last, [] (const shared_ptr<buffer_t>& a, const shared_ptr<buffer_t>& b) 
    { 
        if(a && b)
        {
            return a->compare(*b.get()) < 0;
        }
        if(b)
        {
            return true;
        }
        return false;
    });

    stopwatch.Stop();
    printf("\tsorted %d shared_ptrs' in %f ms\n\n", bufferCount ,stopwatch.Elapsed().TotalMilliseconds() );

    delete[] destinationBuffers;
    delete[] sourceBuffers;
}

int _tmain(int argc, _TCHAR* argv[])
{
    size_t bufferSize = 680*480*8;
    int bufferCount = 500;

    int variantSize = sizeof(Variant);
    int propVariantSize = sizeof(PropertyVariant);

    Variant v;
    PropertyVariant pv;

    printf("%d\n",variantSize);
    printf("%d\n",propVariantSize);

    BufferTestPushBack(bufferCount,bufferSize);
    BufferTest(bufferCount,bufferSize);

    Buffer2TestPushBack(bufferCount,bufferSize);
    Buffer2Test(bufferCount,bufferSize);

    BufferPointerTestPushBack(bufferCount,bufferSize);
    BufferPointerTest(bufferCount,bufferSize);

    Buffer_shared_ptr_TestPushBack(bufferCount,bufferSize);
    Buffer_shared_ptr_Test(bufferCount,bufferSize);

    BufferArrayOfPointerTest(bufferCount,bufferSize);
    BufferArrayTest(bufferCount,bufferSize);
    BufferArrayNoLambdaTest(bufferCount,bufferSize);
    Buffer2ArrayNoLambdaTest(bufferCount,bufferSize);
    BufferArrayOf_shared_ptr_Test(bufferCount,bufferSize);
	return 0;
}

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