Valhalla Legends Forums Archive | General Programming | C++ (win32 api programming) (GUI)

AuthorMessageTime
n00blar
I got tired of writing code to display windows for me, so I came up with a reusable method using classes! You guys can rip this appart, expand, and reuse this as much and as free as you want!


(window.h)
[code]
#include "windows.h"

class CWindow
{
public:
     void SetX(int x);
     int GetX() const;

     void SetY(int y);
     int GetY() const;

     void SetWidth(int width);
     int GetWidth() const;

     void SetHeight(int height);
     int GetHeight() const;

     void SetClassName(char *classname);
     char *GetClassName() const;

     void SetWindowName(char *windowname);
     char *GetWindowName() const;

     void SetIcon(HICON icon);
     HICON GetIcon() const;

     void SetCursor(HCURSOR cursor);
     HCURSOR GetCursor() const;

     void SetBackGround(HBRUSH background);
     HBRUSH GetBackGround() const;

     void SetWndProc(WNDPROC wndproc);
     WNDPROC GetWndProc() const;

     HWND GetHwnd() const;

     bool InitalizeWindow();

private:
     int m_x;
     int m_y;
     int m_nWidth;
     int m_nHeight;
     char *m_pcClassName;
     char *m_pcWindowName;
     HICON m_hIcon;
     HCURSOR m_hCursor;
     HBRUSH m_hbrBackGround;
     HWND m_hWnd;
     WNDPROC m_pWndProc;
};
[/code]

(window.cpp)
[code]
#include "stdafx.h"
#include "window.h"

void CWindow::SetX(int x)
{
     m_x = x;
}
int CWindow::GetX() const
{
     return m_x;
}


void CWindow::SetY(int y)
{
     m_y = y;
}
int CWindow::GetY() const
{
     return m_y;
}


void CWindow::SetWidth(int width)
{
     m_nWidth = width;
}
int CWindow::GetWidth() const
{
     return m_nWidth;
}


void CWindow::SetHeight(int height)
{
     m_nHeight = height;
}
int CWindow::GetHeight() const
{
     return m_nHeight;
}


void CWindow::SetClassName(char *classname)
{
     m_pcClassName = classname;
}
char *CWindow::GetClassName() const
{
     return m_pcClassName;
}


void CWindow::SetWindowName(char *windowname)
{
     m_pcWindowName = windowname;
}
char *CWindow::GetWindowName() const
{
     return m_pcWindowName;
}



void CWindow::SetIcon(HICON icon)
{
     m_hIcon = icon;
}
HICON CWindow::GetIcon() const
{
     return m_hIcon;
}


void CWindow::SetCursor(HCURSOR cursor)
{
     m_hCursor = cursor;
}
HCURSOR CWindow::GetCursor() const
{
     return m_hCursor;
}


void CWindow::SetBackGround(HBRUSH background)
{
     m_hbrBackGround = background;
}
HBRUSH CWindow::GetBackGround() const
{
     return m_hbrBackGround;
}

void CWindow::SetWndProc(WNDPROC wndproc)
{
     m_pWndProc = wndproc;
}
WNDPROC CWindow::GetWndProc() const
{
     return m_pWndProc;
}

HWND CWindow::GetHwnd() const
{
     return m_hWnd;
}

bool CWindow::InitalizeWindow()
{
     WNDCLASSEX wcx;

     wcx.cbSize = sizeof(wcx);
     wcx.style = CS_HREDRAW | CS_VREDRAW;
     wcx.lpfnWndProc = m_pWndProc;
     wcx.cbClsExtra = NULL;
     wcx.cbWndExtra = NULL;
     wcx.hInstance = GetModuleHandle(NULL);
     wcx.hIcon = m_hIcon;
     wcx.hCursor = m_hCursor;
     wcx.hbrBackground = m_hbrBackGround;
     wcx.lpszMenuName = NULL;
     wcx.lpszClassName = m_pcClassName;
     wcx.hIconSm = m_hIcon;
     
     RegisterClassEx(&wcx);

     m_hWnd = CreateWindow(m_pcClassName, m_pcWindowName, WS_OVERLAPPEDWINDOW, m_x, m_y, m_nWidth, m_nHeight, (HWND) NULL, (HMENU) NULL, GetModuleHandle(NULL), (LPVOID) NULL);

     if (!m_hWnd)
           return FALSE;

     ShowWindow(m_hWnd, SW_SHOW);
     UpdateWindow(m_hWnd);
     return TRUE;
}
[/code]

(control.h)
[code]
class CControl
{
public:
     void SetX(int x);
     int GetX() const;

     void SetY(int y);
     int GetY() const;

     void SetWidth(int width);
     int GetWidth() const;

     void SetHeight(int height);
     int GetHeight() const;

     void SetWindowName(char *windowname);
     char *GetWindowName() const;
protected:
     int m_x;
     int m_y;
     int m_nWidth;
     int m_nHeight;
     char *m_pcWindowName;
};

class CEdit : public CControl
{
public:
     void SetStyle(DWORD style);
     DWORD GetStyle() const;

     void SetText(char *text);
     void GetText(char *buffer) const;

     int GetTextLength() const;

     bool InitializeEdit(HWND parent);
private:
     DWORD m_dwStyle;
     HWND m_hWnd;
};

class CButton : public CControl
{
public:
     void SetStyle(DWORD style);
     DWORD GetStyle() const;

     void SetID(HMENU menu);
     HMENU GetID() const;

     bool InitializeButton(HWND parent);
private:
     DWORD m_dwStyle;
     HWND m_hWnd;
     HMENU m_hMenu;
};
[/code]

(control.cpp)
[code]
#include "stdafx.h"
#include "control.h"

void CControl::SetX(int x)
{
     m_x = x;
}
int CControl::GetX() const
{
     return m_x;
}


void CControl::SetY(int y)
{
     m_y = y;
}
int CControl::GetY() const
{
     return m_y;
}


void CControl::SetWidth(int width)
{
     m_nWidth = width;
}
int CControl::GetWidth() const
{
     return m_nWidth;
}


void CControl::SetHeight(int height)
{
     m_nHeight = height;
}
int CControl::GetHeight() const
{
     return m_nHeight;
}


void CControl::SetWindowName(char *windowname)
{
     m_pcWindowName = windowname;
}
char *CControl::GetWindowName() const
{
     return m_pcWindowName;
}





void CEdit::SetStyle(DWORD style)
{
     m_dwStyle = style;
}
DWORD CEdit::GetStyle() const
{
     return m_dwStyle;
}


void CEdit::SetText(char *text)
{
     SendMessage(m_hWnd,WM_SETTEXT,strlen(text),(LPARAM)(LPCSTR)text);
}

void CEdit::GetText(char *buffer) const
{
     int len = SendMessage(m_hWnd,WM_GETTEXTLENGTH,0,0) + 1 ;
     SendMessage(m_hWnd,WM_GETTEXT,len,(LPARAM)(LPCSTR)buffer);
}


int CEdit::GetTextLength() const
{
     return SendMessage(m_hWnd,WM_GETTEXTLENGTH,0,0) + 1;
}


bool CEdit::InitializeEdit(HWND parent)
{
     m_hWnd = CreateWindow("Edit", m_pcWindowName, m_dwStyle, m_x, m_y, m_nWidth, m_nHeight, parent, (HMENU) NULL, GetModuleHandle(NULL), NULL);
     if (!m_hWnd)
           return FALSE;
     
     return TRUE;
}





void CButton::SetStyle(DWORD style)
{
     m_dwStyle = style;
}
DWORD CButton::GetStyle() const
{
     return m_dwStyle;
}


void CButton::SetID(HMENU menu)
{
     m_hMenu = menu;
}
HMENU CButton::GetID() const
{
     return m_hMenu;
}


bool CButton::InitializeButton(HWND parent)
{
     m_hWnd = CreateWindow("Button", m_pcWindowName, m_dwStyle, m_x, m_y, m_nWidth, m_nHeight, parent, m_hMenu, GetModuleHandle(NULL), NULL);
     if (!m_hWnd)
           return FALSE;
     
     return TRUE;
}
[/code]

I also included an example of this thing in use!
(example.cpp)
[code]
#include "stdafx.h"
#include "window.h"
#include "control.h"

LRESULT CALLBACK MainWndProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam);

CWindow WindowWizard;
CEdit edit;
CButton button;

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow)
{
     MSG msg;

     WindowWizard.SetClassName("MainWClass");
     WindowWizard.SetWindowName("Win32 API Window!");
     WindowWizard.SetIcon(LoadIcon(NULL, IDI_APPLICATION));
     WindowWizard.SetCursor(LoadCursor(NULL, IDC_ARROW));  
     WindowWizard.SetBackGround((HBRUSH)GetStockObject(BLACK_BRUSH));    
     WindowWizard.SetX(CW_USEDEFAULT);
     WindowWizard.SetY(CW_USEDEFAULT);
     WindowWizard.SetHeight(100);
     WindowWizard.SetWidth(218);
     WindowWizard.SetWndProc(MainWndProc);      
     if (!WindowWizard.InitalizeWindow())
     {
           MessageBox(NULL, "Window Failed!", "Error", NULL);
           return 0;
     }

     edit.SetHeight(20);
     edit.SetWidth(200);
     edit.SetX(5);
     edit.SetY(5);
     edit.SetWindowName("Hello World!");
     edit.SetStyle(WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | WS_BORDER);
     if(edit.InitializeEdit(WindowWizard.GetHwnd()) == FALSE)
     {
           MessageBox(NULL, "Edit Failed!", "Error", NULL);
           return 0;
     }

     button.SetID((HMENU)101);
     button.SetHeight(20);
     button.SetWidth(140);
     button.SetX(40);
     button.SetY(40);
     button.SetStyle(WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON);
     button.SetWindowName("Enter");
     if(button.InitializeButton(WindowWizard.GetHwnd()) == FALSE)
     {
           MessageBox(NULL, "Button Failed!", "Error", NULL);
           return 0;
     }

     while (GetMessage(&msg, NULL, 0, 0))
     {
           TranslateMessage(&msg);
           DispatchMessage(&msg);
     }

     return msg.wParam;
}


LRESULT CALLBACK MainWndProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam)
{
     switch(msg)
     {
           case WM_DESTROY:
                 PostQuitMessage(0);
                 break;

           case WM_COMMAND:
                 if (HIWORD(wparam) == BN_CLICKED)
                 {
                       switch LOWORD(wparam)
                       {
                             case 101:
                                   char *buffer = new char[edit.GetTextLength()];
                                   edit.GetText(&buffer[0]);
                                   MessageBox(NULL, buffer, buffer, NULL);
                                   delete [] buffer;
                       }
                 }

           default:
                 return DefWindowProc(hwnd, msg, wparam, lparam);
     }
     return 0;
}
[/code]

Enjoy, and have fun! If you need help because you just can't figure it out! gimmie a call on aim, icq, msn whatever..
March 17, 2003, 11:48 PM
iago
That looks really handy :D
March 17, 2003, 11:53 PM
Eibro
You could offer some default initialization in your constructors of commonly used commands. I'd start with a base class, then derive a class from it which offers this. It seems pretty pointless to use a class which in the end you end up typing out just as much.

You can even derive from existing structures and implement default behavior for them, too.
[code]
class WndClass : public WNDCLASSEX
{
public:
      WndClass(TCHAR* szWindowClass, WNDPROC wProc, HINSTANCE hInst = GetModuleHandle(NULL))
      {
             ZeroMemory(this, sizeof(*this));

             cbSize = sizeof(WNDCLASSEX);
             lpszClassName = szWindowClass;
             style = CS_HREDRAW | CS_VREDRAW;
             lpfnWndProc = wProc;
             hInstance = hInst;
             hCursor = LoadCursor(NULL, IDC_ARROW);
             hbrBackground = (HBRUSH)COLOR_WINDOW;

      }

      inline BOOL Register() { return RegisterClassEx(this) ? TRUE : FALSE; }
      inline BOOL Unregister() { return UnregisterClass(lpszClassName , hInstance); }
};
[/code]
Of course, it would be wise to include Set and Get member functions to allow the user to customize any functionality desired.
I can't count on one hand the different window wrappers i've created, although many of the preliminary ones sucked in one way or another.
Hope this helps in some way.
March 18, 2003, 12:40 AM
n00blar
Eibro, I know what you mean, I actually just finished implementing something into mine similar to that prior to reading your post..
March 18, 2003, 12:53 AM
TheMinistered
hmm
June 13, 2003, 8:40 PM
TrojanMan
hmm what is the "stdafx.h" header file? im not familiar with it
June 20, 2003, 2:47 AM
Eibro
stdafx.h is a "precompiled header", specific to MSVC.
Since this topic has been resurrected from the dead, I figure i'll post my window wrapper.

[code]class WindowBase
{
public:
class Class : public WNDCLASSEX
{
public:
    Class(TCHAR* szWindowClass, HINSTANCE hInst = GetModuleHandle(NULL))
    {
       ZeroMemory(this, sizeof(*this));

       cbSize = sizeof(WNDCLASSEX);
       lpszClassName = szWindowClass;
style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
lpfnWndProc = WindowBase::MessageRouter;
       hInstance = hInst;
       hCursor = LoadCursor(NULL, IDC_ARROW);
hbrBackground = (HBRUSH)COLOR_WINDOW;
}

BOOL Register() { return RegisterClassEx(this) ? TRUE : FALSE; }
BOOL Unregister() { return UnregisterClass(lpszClassName , hInstance); }

};

friend class WindowBase::Class;

public:
WindowBase(Class& WindowClass)
: m_wc(WindowClass) { m_wc.Register(); }

virtual ~WindowBase() { m_wc.Unregister(); }

BOOL Create(TCHAR* lpszName, DWORD dwStyle, int cx, int cy, HWND hParent = NULL)
{
m_hWnd = CreateWindow(m_wc.lpszClassName, lpszName,
dwStyle, CW_USEDEFAULT, CW_USEDEFAULT, cx, cy,
hParent, NULL, m_wc.hInstance, this);

return m_hWnd ? TRUE : FALSE;
}

virtual LRESULT MessageHandler(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) = 0;

BOOL Destroy() { return DestroyWindow(m_hWnd); }
BOOL Show(int nCmd) { return ShowWindow(m_hWnd, nCmd); }

protected:
HWND m_hWnd;
Class& m_wc;

private:
static LRESULT CALLBACK MessageRouter(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
static WindowBase* WindowObject = NULL;
if (uMsg == WM_NCCREATE)
{
WindowObject =
reinterpret_cast<WindowBase*>
(reinterpret_cast<CREATESTRUCT*>(lParam)->lpCreateParams);

BindObjectToHandle(hWnd, WindowObject);
WindowObject->m_hWnd = hWnd;
} else {
WindowObject = GetObjectFromHandle(hWnd);
if (WindowObject != NULL)
return WindowObject->MessageHandler(hWnd, uMsg, wParam, lParam);
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}

inline static WindowBase* GetObjectFromHandle(HWND hWnd)
{
return reinterpret_cast<WindowBase*>(GetWindowLong(hWnd, GWL_USERDATA));
}

inline static LONG BindObjectToHandle(HWND hWnd, WindowBase* Window)
{
return SetWindowLong(hWnd, GWL_USERDATA, reinterpret_cast<LONG>(Window));
}
};

class Window : public WindowBase
{
public:
Window(WindowBase::Class& WindowClass)
: WindowBase(WindowClass) {};

virtual BOOL OnCreate(CREATESTRUCT* pCS) = 0;
virtual BOOL OnPaint(PAINTSTRUCT* pPS) = 0;
virtual BOOL OnDestroy() = 0;
virtual BOOL OnSize(WORD Width, WORD Height) = 0;

LRESULT MessageHandler(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_SIZE:
return OnSize(LOWORD(lParam), HIWORD(lParam));
case WM_CREATE:
return OnCreate(reinterpret_cast<CREATESTRUCT*>(lParam));
case WM_DESTROY:
return OnDestroy();
case WM_PAINT:
return OnPaint(reinterpret_cast<PAINTSTRUCT*>(lParam));
default:
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
}
};[/code]
June 20, 2003, 3:03 AM
TrojanMan
precompiled i dont have it, and i got fuckin VC++ 6.0
June 20, 2003, 3:06 AM
Eibro
They're project specific headers. If your project has precompiled headers disabled then feel free to remove '#include "stdafx.h" '
June 20, 2003, 3:12 AM
TrojanMan
if i remove it ill get errors, by the way, stdafx.h is not in my MSVC include directory, maybe during installatiion sumthing got screwed up perhaps
June 20, 2003, 3:16 AM
Eibro
[quote author=TrojanMan link=board=5;threadid=246;start=0#msg12673 date=1056078961]
if i remove it ill get errors, by the way, stdafx.h is not in my MSVC include directory, maybe during installatiion sumthing got screwed up perhaps
[/quote]You will get errors, or you did get errors? Did you even try it?
Yes, I realize "stdafx.h" is not in the MSVC include directory. Notice the quotes around the name instead of brackets (< >), that means the path of the include is relative to the location of the current file. (Read: It's project specific; if the project file you're using has precompiled headers enabled then you'll need stdafx.h in the same directory of your project.)
June 20, 2003, 3:20 AM
TrojanMan
38 errors when removing #include "stdafx.h"
June 20, 2003, 3:40 AM
Eibro
Just because you got 32 errors when you removed the include doesn't mean they were caused by the absence of stdafx.h. Most likely, the compiler just spit out that it couldn't locate the file and quit compiling.
Did you even try fixing the errors?
Perhaps you did you not #include <windows.h> ::)
June 20, 2003, 4:10 AM
TrojanMan
#include <windows.h> in the cpp files?
June 20, 2003, 5:39 AM
Eibro
Yes.
June 20, 2003, 2:45 PM
DarkMinion
This will solve all your god damned GUI trouble. I swear, you people do everything the hard way (or the gay MFC-like way) ;)

http://dmbot.virtualave.net/SampleWin32.zip
June 21, 2003, 11:21 PM
TheMinistered
If I recall my example did not use MFC. Perhaps your blatant remark was not aimed towards me?
June 24, 2003, 2:44 AM
DarkMinion
Ok, considering your example isn't in this thread, it wasn't aimed at you.
June 24, 2003, 3:49 AM
TheMinistered
Ok, considering That I == n00blar, then you are wrong ;)
June 24, 2003, 9:32 PM
DarkMinion
;D

Oh, then your example IS MFC-like
June 24, 2003, 11:06 PM
TheMinistered
Please define "MFC-LIKE" and describe what the difference between "MFC" & "MFC-LIKE" IS.
June 24, 2003, 11:51 PM
Eibro
I'd say "MFC-like" is synonymous for object-oriented.
Some people prefer writing object oriented code; others prefer pure procedural. That's all there is to it.
June 25, 2003, 12:43 AM
Camel
[quote author=Eibro link=board=5;threadid=246;start=15#msg12873 date=1056501833]
Some people prefer writing object oriented code; others prefer pure procedural. That's all there is to it.
[/quote]

Not true; there are advantages to both. In some cases, one is clearly better than the other. In other cases, it is highly debatable (see: 'tagbans' in the botdev forum). :)
June 25, 2003, 1:03 AM
DarkMinion
Nah, just your class names look MFC-like, I was just joking with you ;)

Oh, and VB sucks Camel.
June 25, 2003, 1:21 AM
Eibro
Eh, this is exactly what I was trying to avoid.

[quote author=Camel link=board=5;threadid=246;start=15#msg12879 date=1056503026]
[quote author=Eibro link=board=5;threadid=246;start=15#msg12873 date=1056501833]
Some people prefer writing object oriented code; others prefer pure procedural. That's all there is to it.
[/quote]

<snip>there are advantages to both</snip>
[/quote]That's pretty much the point I was making.

I get what you're saying now, DM :) I hate the prefixed 'C' on class names, I think it's completely pointless (and ugly)

Edit: And please tell me, Camel, how is reading all that long-winded garbage in the tagbans topic going to help me? I can tell you, it's certainly not going to give me any better understanding of OOP vs. Procedural programming.
June 25, 2003, 1:59 AM
Camel
[quote author=DarkMinion link=board=5;threadid=246;start=15#msg12884 date=1056504078]
Nah, just your class names look MFC-like, I was just joking with you ;)

Oh, and VB sucks Camel.
[/quote]

that's brilliant, dm!
June 25, 2003, 7:42 PM
DarkMinion
At least you can admit that. ;)
June 26, 2003, 12:20 AM

Search