Re: Forum for windows programming?
From: Martijn Mulder (i_at_m)
Date: 02/19/05
- Next message: Tabrez Iqbal: "Re: is VC++ compiler different from gcc compiler?"
- Previous message: Tom: "Re: Answer needed"
- In reply to: JoeC: "Forum for windows programming?"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Date: Sat, 19 Feb 2005 07:10:04 +0100
JoeC wrote:
> I am trying to learn win32 API prograaaming with C++.
> Where can I go to get basic advice and discuss that
> topic? I wrtite my porgram in C++ using the windows.h
> library and my C++ compiler. I am trying to write good
> C++ programs with graphics and GUIs.
Use this code as a basic two-mouse-button drawing tool and hack! Also look at
http://www.relisoft.com/win32/index.htm
for a nice Windows API tutorial.
#include <string>
#include <vector>
#include<iostream>
#include<windows.h>
using namespace std;
/* function DebugMSG()
Function DebugMSG() displays debug information about Windows messages like
WM_CREATE, WM_INITMENUPOPUP, WM_COMMAND etc. that are send from Windows
to WindowProc().
*/
void DebugMSG(const string&a,UINT b,WPARAM c,LPARAM d)
{
cout<<"\nMSG: "<<a<<'('<<b<<')';
cout<<"\t\t"<<LOWORD(c)<<'-'<<HIWORD(c);
cout<<'\t'<<LOWORD(d)<<'-'<<HIWORD(d);
}
/* pointer HWND hwnd
Forward declaration of global data member hwnd. It's value is set
in function Window::Create(). There is only one HWND for the whole
program.
*/
static HWND hwnd;
//struct Color
struct Color
{
//data members red, green, blue
int red,green,blue;
//constructor
Color(int a=0,int b=0,int c=0):red(a),green(b),blue(c)
{
red=rand()%256;
green=rand()%256;
blue=rand()%256;
}
//operator COLORREF
operator COLORREF()const{return RGB(red,green,blue);}
};
//struct Pen
struct Pen
{
//data member color
Color color;
//data member width
int width;
//constructor
Pen(int a=1):width(a)
{
width=rand()%75+1;
}
//operator HPEN
operator HPEN()const{return::CreatePen(PS_SOLID,width,color);}
};
//struct DC
struct DC
{
//data member paintstruct
PAINTSTRUCT paintstruct;
//data member hdc
HDC hdc;
//constructor
DC()
{
hdc=::BeginPaint(hwnd,&paintstruct);
cout<<"\nDC.constructor";
cout<<"\nPAINTSTRUCT.rcPaint: ";
cout<<paintstruct.rcPaint.left<<", ";
cout<<paintstruct.rcPaint.top<<", ";
cout<<paintstruct.rcPaint.right<<", ";
cout<<paintstruct.rcPaint.bottom;
}
//destructor
~DC()
{
cout<<"\nDC.destructor";
::DeleteObject(::SelectObject(hdc,::GetStockObject(BLACK_PEN)));
::EndPaint(hwnd,&paintstruct);
}
};
//struct BackDC
struct BackDC
{
//data member hdc
HDC hdc;
//data member bitmap
HBITMAP bitmap;
//data members width, height
int width,height;
//constructor
BackDC()
:
width(::GetSystemMetrics(SM_CXSCREEN)),
height(::GetSystemMetrics(SM_CYSCREEN))
{
cout<<"\nBackDC.constructor";
HDC a=::GetDC(hwnd);
hdc=::CreateCompatibleDC(a);
bitmap=::CreateCompatibleBitmap(a,width,height);
::ReleaseDC(hwnd,a);
::SelectObject(hdc,bitmap);
::SelectObject(hdc,::GetStockObject(WHITE_BRUSH));
::PatBlt(hdc,0,0,width,height,PATCOPY);
}
//destructor
~BackDC()
{
cout<<"\nBackDC.destructor";
::DeleteObject(::SelectObject(hdc,::GetStockObject(BLACK_PEN)));
::DeleteObject(bitmap);
::DeleteDC(hdc);
}
//clear
void clear()const{::PatBlt(hdc,0,0,width,height,PATCOPY);}
//moveTo
void moveTo(int a,int b)const
{
POINT c;
::MoveToEx(hdc,a,b,&c);
}
//lineTo
void lineTo(int a,int b)const{::LineTo(hdc,a,b);}
//selectPen
void selectPen(const Pen&a)const{::DeleteObject(::SelectObject(hdc,a));}
//update
void update()const
{
DC dc;
::BitBlt(dc.hdc,0,0,width,height,hdc,0,0,SRCCOPY);
}
};
//struct Point
struct Point
{
//data members x, y
long x,y;
//constructor
Point(long a=0,long b=0):x(a),y(b){}
};
//struct Line
struct Line
{
//data member points
vector<Point>points;
//data member pen
Pen pen;
//constructor
Line(){}
//addPoint
void addPoint(int a,int b)
{
points.push_back(Point(a,b));
InvalidateRect(hwnd,0,false);
}
//paint
void paint(const BackDC&a)
{
POINT b;
a.selectPen(pen);
a.moveTo(points[0].x,points[0].y);
for(int c=1;c<points.size();c++)a.lineTo(points[c].x,points[c].y);
}
};
//struct Drawing
struct Drawing
{
//data member lines
vector<Line>lines;
//enum DRAWINGSTYLE
enum DRAWINGSTYLE{NONE,DRAW,LINE};
//drawingstyle
DRAWINGSTYLE drawingstyle;
//constructor
Drawing():drawingstyle(NONE){}
//addPoint
void addPoint(int a,int b){lines[lines.size()-1].addPoint(a,b);}
//addLine
void addLine(){lines.push_back(Line());}
//mouseMove
void mouseMove(int a,int b)
{
switch(drawingstyle)
{
case NONE:break;
case LINE:
lines[lines.size()-1].points[1]=Point(a,b);
break;
case DRAW:
lines[lines.size()-1].addPoint(a,b);
break;
}}
//rButtonDown
void rButtonDown(int a,int b)
{
drawingstyle=LINE;
addLine();
addPoint(a,b);
addPoint(a,b);
}
//lButtonDown
void lButtonDown(int a,int b)
{
drawingstyle=DRAW;
addLine();
addPoint(a,b);
}
//ButtonUp
void ButtonUp(){drawingstyle=NONE;}
//paint
void paint(const BackDC&a)
{
a.clear();
for(int c=0;c<lines.size();c++){lines[c].paint(a);}
a.update();
}
};
//global data member drawing
Drawing drawing;
//global data member backdc
BackDC backdc;
//WindowProc
LRESULT CALLBACK WindowProc(HWND a,UINT b,WPARAM c,LPARAM d)
{
switch(b)
{
case WM_CHAR:
::DebugMSG("WM_CHAR",b,c,d);
break;
case WM_CREATE:
::DebugMSG("WM_CREATE",b,c,d);
break;
case WM_COMMAND:
::DebugMSG("WM_COMMAND",b,c,d);
break;
case WM_DESTROY:
::DebugMSG("WM_DESTROY",b,c,d);
::PostQuitMessage(0);
break;
case WM_DRAWITEM:
::DebugMSG("WM_DRAWITEM",b,c,d);
break;
case WM_ENTERIDLE:
::DebugMSG("WM_ENTERIDLE",b,c,d);
break;
case WM_ENTERMENULOOP:
::DebugMSG("WM_ENTERMENULOOP",b,c,d);
break;
case WM_EXITMENULOOP:
::DebugMSG("WM_EXITMENULOOP",b,c,d);
break;
case WM_INITMENU:
::DebugMSG("WM_INITMENU",b,c,d);
break;
case WM_INITMENUPOPUP:
::DebugMSG("WM_INITMENUPOPUP",b,c,d);
break;
case WM_KEYDOWN:
::DebugMSG("WM_KEYDOWN",b,c,d);
break;
case WM_KEYUP:
::DebugMSG("WM_KEYUP",b,c,d);
break;
case WM_LBUTTONDOWN:
::DebugMSG("WM_LBUTTONDOWN",b,c,d);
::SetCapture(hwnd);
drawing.lButtonDown(LOWORD(d),HIWORD(d));
break;
case WM_LBUTTONUP:
::DebugMSG("WM_LBUTTONUP",b,c,d);
::ReleaseCapture();
drawing.ButtonUp();
break;
case WM_MOUSEMOVE:
drawing.mouseMove(LOWORD(d),HIWORD(d));
InvalidateRect(hwnd,0,false);
break;
case WM_NOTIFY:
::DebugMSG("WM_NOTIFY",b,c,d);
break;
case WM_PAINT:
::DebugMSG("WM_PAINT",b,c,d);
drawing.paint(backdc);
break;
case WM_RBUTTONDOWN:
::DebugMSG("WM_RBUTTONDOWN",b,c,d);
::SetCapture(hwnd);
drawing.rButtonDown(LOWORD(d),HIWORD(d));
break;
case WM_RBUTTONUP:
::DebugMSG("WM_RBUTTONUP",b,c,d);
drawing.ButtonUp();
::ReleaseCapture();
break;
default:return::DefWindowProc(a,b,c,d);
}
return 0;
}
//struct Window
struct Window
{
//data member name
const char*name;
//constructor
Window(const char*a)
:
name(a)
{
Register();
Create();
}
//Create
void Create()
{
hwnd=::CreateWindow
(
name,
name,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
0,
0,
NULL,//hinstance,
0
);
::ShowWindow(hwnd,SW_SHOWNORMAL);
::UpdateWindow(hwnd);
}
//Register
void Register()
{
WNDCLASSEX a=
{
sizeof(WNDCLASSEX),
CS_HREDRAW|CS_VREDRAW|CS_BYTEALIGNCLIENT,
WindowProc,
0,
0,
NULL,//hinstance,
NULL,
LoadCursor(0,IDC_ARROW),
(HBRUSH)(::GetStockObject(WHITE_BRUSH)),
name,
name
};
if(!::RegisterClassEx(&a))cout<<"\nRegisterClassEx failed";
}};
//global data member window
static Window window("Minimal Windows Application");
//WinMain
int WINAPI WinMain(HINSTANCE a,HINSTANCE b,char*c,int d)
{
MSG msg;
int status;
while((status=::GetMessage(&msg,0,0,0))!=0)
{
if(status==-1)return -1;
{
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}}
return msg.wParam;
}
- Next message: Tabrez Iqbal: "Re: is VC++ compiler different from gcc compiler?"
- Previous message: Tom: "Re: Answer needed"
- In reply to: JoeC: "Forum for windows programming?"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]