René Nyffenegger's collection of things on the web | |
René Nyffenegger on Oracle - Most wanted - Feedback
- Follow @renenyffenegger
|
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; } ChildWindowChildWindow.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; } |