René Nyffenegger's collection of things on the web
René Nyffenegger on Oracle - Most wanted - Feedback -
 

Some C++ classes that support the creation of common Windows Elements

Wnd, the root class for all windows

This class is the base class from which all Window classes are derived.

Wnd.h

#ifndef __WINDOW_H_
#define __WINDOW_H_

#include <windows.h>

#include <string>
using namespace std;

class Wnd {
  public:
    HWND hwnd_;

    Wnd();
    
    void Create(wstring const& className, int x, int y, int w, int h, int styles, wstring const& title = L"");

    virtual ~Wnd();
    
    void ClientRect(unsigned int& width, unsigned int& height) const;
    
    void Show(bool b=true) const;

    void Enable(bool b=true) const;

    void Focus() const;
    
    void Refresh() const;

    void DefaultGuiFont();

    // void SetFont(const Font&);
              
    void    Text(const wstring&);

    virtual Wnd* Parent() const = 0;

    virtual int  StylesToAddInCreate() const = 0;

    wstring Text() const;

    virtual void Move(int x, int y, int width, int height, bool repaint=true);
};

// #define W_CHECKWINDOWHANDLE if (!hwnd_) throw "Window Handle is 0";

#endif

Wnd.cpp

#include "Wnd.h"

#include <windows.h>

Wnd::Wnd() : hwnd_(0) {
}

Wnd::~Wnd() {
}

void Wnd::Create(wstring const& className, int x, int y, int w, int h, int styles, wstring const& title) {
Wnd* parent = Parent();
HWND hparent = parent ? parent->hwnd_ : 0;

styles |= StylesToAddInCreate();

HMENU hmenu = (HMENU) (hparent ? 1 : 0);

hwnd_ = ::CreateWindowExW(
  0,                // Ex Styles
  className.c_str(),
  title.c_str(),
  styles,
  x, y, w, h,
  hparent,        
  hmenu,      // Menu, or windows id if child
  0,       
  0           // Pointer to window specific data
);

::SetWindowLong(hwnd_,GWL_USERDATA,(LONG) this);
}

void Wnd::ClientRect(unsigned int& width, unsigned int& height) const {
RECT r;

::GetClientRect(hwnd_, &r);
width  = r.right;
height = r.bottom;
}

void Wnd::Show(bool b) const {
if (b) ::ShowWindow(hwnd_, SW_SHOW);
else   ::ShowWindow(hwnd_, SW_HIDE);
}

void Wnd::Enable(bool b) const {
::EnableWindow(hwnd_, b);
}

void Wnd::Focus() const {
::SetFocus(hwnd_);
}

void Wnd::DefaultGuiFont() {
::SendMessage(hwnd_,WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), FALSE);
}

void Wnd::Refresh() const {
::InvalidateRect(hwnd_, 0, 1);
}

void Wnd::Text(const wstring& t) {
::SetWindowTextW(hwnd_, t.c_str());
}

wstring Wnd::Text() const {
int textLength = ::GetWindowTextLength(hwnd_) + 1;
wchar_t *t = new wchar_t[textLength];
::GetWindowTextW(hwnd_, t, textLength);
wstring ret(t);
delete [] t;
return ret;
}

void Wnd::Move(int x, int y, int width, int height, bool repaint) {
::MoveWindow(hwnd_,x,y,width,height,repaint);
}

OverlappedWindow

This class is derived from Wnd and serves as the class that encapsulates an application's main window.

OverlappedWindow.h

#ifndef __OVERLAPPED_WINDOW_H__
#define __OVERLAPPED_WINDOW_H__

#include <windows.h>

#include <string>
using namespace std;

#include "Wnd.h"

class OverlappedWindow : public Wnd {
public:
OverlappedWindow(
  WNDPROC WndProc,
  wstring const& title,
  int   x = CW_USEDEFAULT,
  int   y = CW_USEDEFAULT,
  int   w = CW_USEDEFAULT,
  int   h = CW_USEDEFAULT,
  int    windowStyles = 0);

virtual Wnd* Parent() const { return 0;};

virtual int  StylesToAddInCreate() const {return WS_OVERLAPPEDWINDOW;};
};

#endif

OverlappedWindow.cpp

#include "OverlappedWindow.h"

OverlappedWindow::OverlappedWindow(
  WNDPROC WndProc,
  wstring const& title,
  int    x,
  int    y,
  int    w,
  int    h,
  int    windowStyles
  ) {

WNDCLASSEXW wce;

wce.cbSize        = sizeof(wce);
wce.style         = CS_VREDRAW | CS_HREDRAW; 
wce.lpfnWndProc   = WndProc; 
wce.cbClsExtra    = 0; 
wce.cbWndExtra    = 0; 
wce.hInstance     = 0; 
wce.hIcon         = LoadIcon(0, IDI_APPLICATION); 
wce.hCursor       = LoadCursor(0, IDC_ARROW); 
wce.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH); 
wce.lpszMenuName  = 0;
wce.lpszClassName = L"DummyClassName",
wce.hIconSm       = 0;

if (!RegisterClassExW(&wce)) throw "Couldn not register class";

Create(L"DummyClassName", x, y, w, h, windowStyles, title);
};

A Test Programm for OverlappedWindow

You need the graphic classes to make this example run. Download the entire Project
#include "OverlappedWindow.h"
#include "PaintDc.h"
#include "Color.h"

LRESULT CALLBACK WndProc(
  HWND   hWnd,
  UINT   msg,
  WPARAM wParam,
  LPARAM lParam ) {

switch( msg ) {
  case WM_PAINT: {
    PaintDc pdc(hWnd);
    pdc.Text(30,50,L"Hello World", Color(200,100,80));
  }
  break;

  case WM_DESTROY:
    PostQuitMessage(0);
  break;

  default:
    return DefWindowProc( hWnd, msg, wParam, lParam);
} 
return 0;
}


int WINAPI WinMain(
           HINSTANCE hInstance, HINSTANCE hPrevInstance,
           LPSTR lpCmdLine, int nCmdShow) {


OverlappedWindow ow(WndProc, L"Hallo Welt", 50, 100, 400, 600, 0);

ow.Show();

MSG msg;
int r;
while ((r = GetMessage(&msg, NULL, 0, 0 )) != 0) { 
  if (r == -1) {
    ;  // Error!
  }
  else {
    TranslateMessage(&msg); 
    DispatchMessage(&msg); 
  }
} 

// The application's return value
return msg.wParam;

return 0;
}

ChildWindow

ChildWindow.h

#ifndef __CHILDWIND0W_H__
#define __CHILDWIND0W_H__

#include "Wnd.h"

class ChildWindow : public Wnd {
public:
  ChildWindow(Wnd& parent);

virtual Wnd* Parent() const { return parent_;};
  
virtual int  StylesToAddInCreate() const {return WS_CHILDWINDOW;};

private:
  Wnd* parent_;
};

#endif

ChildWindow.cpp

#include "ChildWindow.h"

ChildWindow::ChildWindow(Wnd& parent) : parent_(&parent) {

}

WndApplication

EnterMsgLoop can be used to enter the Message Loop. EnterMsgLoop returns not until a PostQuitMessage was posted.

WndApplication.h

#ifndef __WND_APPLICATION_H__
#define __WND_APPLICATION_H__

int EnterMsgLoop();

#endif

WndApplication.cpp

#include <windows.h>
#include "WndApplication.h"

int EnterMsgLoop() {
MSG msg;
int r;
while ((r = GetMessage(&msg, NULL, 0, 0 )) != 0) { 
  if (r == -1) {
    ;  // Error!
  }
  else {
    TranslateMessage(&msg); 
    DispatchMessage(&msg); 
  }
} 

// The application's return value
return msg.wParam;
}