为了写一个gui,要协调好控件和事件监听的关系以及应用程序不同窗口的关系。
为了要写一个良好支持可扩展的控件库,需要写一个泛化组件库,要写一个泛化组件库,需要先实现它的逻辑基础,也就是可能利用到的几何对象(arith::geo),
为了能够让对组件和窗体的事件监听变得透明,需要封装需要被利用的api和注册窗口类。
现在正在两头开始,这样能够不断测试自己的代码,当上下两部分越来越充实,就自然的结合了.
以下是 os::frame 子库半成品,目的是封装windows application.
代码结构如下:
namespace appinfo; 封装应用程序信息.
namespace frame; 应用框架.
frame::api::def; 常量信息集
frame::api::type; api的基本类型集
frame::api::handle; 封装的句柄集
frame::api::paint; 封装的绘制类,实例化后方便的处理所有跟绘制有关的api.
frame::api::mouse; 封装的鼠标信息集
frame::api::message; message处理集
frame::api::proc; form回调函数类,实例化后专门为form池集中处理不同的事件
frame::api::wndclass; 注册窗口类以及窗口相关创建
frame::form; 所有对话框和文档都统一用form类实例化.
由于是两头写,组件库和关键的事件监听框架还没有完全写完,等写到一定阶段再把不同form的事件分开独立处理,
这里是它的入口点界面,在该框架下,入口点是cpp(),当有需要,可以加入隐含变量处理入口点获取的路径和执行参数:
当写到一定时机成熟时,会把appframe里的proc form管理池的接口搬到init.h的入口点函数.
由于之前基于自己写的arith::axiom库实现过关于不规则内陷多边形的点区域检测demo,所以接下来关于组件库和监听框架的实现应该会快了.
该代码的demo是一个多边形围绕一个点旋转,中间不停更新鼠标在Client区的相对坐标.
为了要写一个良好支持可扩展的控件库,需要写一个泛化组件库,要写一个泛化组件库,需要先实现它的逻辑基础,也就是可能利用到的几何对象(arith::geo),
为了能够让对组件和窗体的事件监听变得透明,需要封装需要被利用的api和注册窗口类。
现在正在两头开始,这样能够不断测试自己的代码,当上下两部分越来越充实,就自然的结合了.
以下是 os::frame 子库半成品,目的是封装windows application.
代码结构如下:
namespace appinfo; 封装应用程序信息.
namespace frame; 应用框架.
frame::api::def; 常量信息集
frame::api::type; api的基本类型集
frame::api::handle; 封装的句柄集
frame::api::paint; 封装的绘制类,实例化后方便的处理所有跟绘制有关的api.
frame::api::mouse; 封装的鼠标信息集
frame::api::message; message处理集
frame::api::proc; form回调函数类,实例化后专门为form池集中处理不同的事件
frame::api::wndclass; 注册窗口类以及窗口相关创建
frame::form; 所有对话框和文档都统一用form类实例化.
由于是两头写,组件库和关键的事件监听框架还没有完全写完,等写到一定阶段再把不同form的事件分开独立处理,
/**/
/* frame.h :os::frame */
#ifndef APPFRAME__
#define APPFRAME__
#include < windows.h >
#include < tchar.h >
#include < stdio.h >
#include " axiom.h "
#include " string.h "
#include " geo.h "
namespace appinfo
{
static const int max_form=500;
static int iCmdShow,regNum,listIndex;
static HINSTANCE hInstance;
static HINSTANCE hPrevInstance;
static PSTR szCmdLine;
static MSG msg;
/**//* register windowclass-name */
static TCHAR regList[max_form][4];
static void decform()
{
--regNum;
}
static void incform()
{
++regNum;
}
static void setListIndex(int & reg_index,LPCWSTR & wc_name)
{
reg_index=listIndex;
regList[listIndex][0]=1;
regList[listIndex][1]=reg_index;
regList[listIndex][2]=0;
wc_name=regList[listIndex];
++listIndex;
++regNum;
}
}
namespace frame
{
using adt::ustring;
class api
{
public:
class def
{
public:
static const int nil =0;
static const int sm_x = 0;
static const int sm_y = 1;
static const int wm_create=WM_CREATE;
static const int wm_paint=WM_PAINT;
static const int wm_destroy=WM_DESTROY;
static const int wm_mousemove=WM_MOUSEMOVE;
static const unsigned int cs_default= CS_HREDRAW | CS_VREDRAW ;
};
class type
{
public:
typedef HDC__* hdc;
typedef HWND hwnd;
typedef ustring string;
typedef UINT uint;
typedef RECT rect;
typedef LPRECT lprc;
typedef WPARAM wp;
typedef LPCWSTR lpcwstr;
typedef LPARAM lp;
typedef PAINTSTRUCT ps;
typedef LPPAINTSTRUCT lpps;
typedef BYTE byte;
typedef LONG_PTR result;
typedef WNDCLASS wndclass;
typedef HICON hicon;
typedef HCURSOR hcursor;
typedef HBRUSH__* hbrush;
typedef HINSTANCE hinstance;
typedef PSTR pstr;
typedef MSG msg;
typedef TCHAR tchar;
typedef BOOL state;
typedef POINT point;
};
class handle
{public:
static type::hicon icon(int i=0)
{
return LoadIcon (NULL, IDI_APPLICATION);
}
static type::hcursor cursor(int i=0)
{
return LoadCursor (NULL, IDC_ARROW);
}
static type::hbrush brush(int i=WHITE_BRUSH)
{
return (type::hbrush) GetStockObject (i);
}
};
class paint
{
public:
type::hdc hdc;
type::rect rect;
type::hwnd hwnd;
type::ps ps;
bool ready;
paint():ready(false){}
~paint()
{
if(ready!=false)
end();
ready=false;
}
type::hdc begin(type::hwnd & hwnd)
{
ready=true;
hdc = BeginPaint(hwnd,&ps);
GetClientRect (hwnd, &rect);
return (hdc );
}
int end()
{
ready=false;
return EndPaint(hwnd,&ps);
}
int text(type::string & tx)
{
if(ready)
return DrawTextW (hdc, tx(), -1, &rect,
DT_SINGLELINE | DT_CENTER | DT_VCENTER) ;
else return 0;
}
type::state rectangle(int x,int y,int w,int h)
{
int sx=sm::screenx();
int sy=sm::screeny();
return Rectangle (hdc,x,y,x+w, y+h) ;
}
type::state polygon(type::point *apt,int i)
{
return Polygon (hdc,apt,i) ;
}
};
class mouse
{
public:
static int x(type::lp & lp)
{
return LOWORD(lp) ;
}
static int y(type::lp & lp)
{
return HIWORD(lp) ;
}
};
class sm
{
public:
static int screenx()
{
return GetSystemMetrics(def::sm_x);
}
static int screeny()
{
return GetSystemMetrics(def::sm_y);
}
};
class message
{
public:
};
class proc
{
public:
type::hwnd hwnd;
type::uint msg;
type::wp wp;
type::lp lp;
proc(){}
proc(type::hwnd &hwnd_t,type::uint &msg_t,type::wp &wp_t,type::lp &lp_t)
{
update(hwnd_t,msg_t,wp_t,lp_t);
}
void update(type::hwnd &hwnd_t,type::uint &msg_t,type::wp &wp_t,type::lp &lp_t)
{
hwnd=hwnd_t;
msg=msg_t;
wp=wp_t;
lp=lp_t;
}
type::result defproc()
{
return DefWindowProcW (hwnd, msg, wp, lp);
}
void postquit(int exitCode_t=0)
{
if(appinfo::regNum==1)
{
//WSHOW__(TEXT("啊!是你."))
--appinfo::regNum;
PostQuitMessage(exitCode_t);
}else
{
--appinfo::regNum;
}
}
};
class wndclass
{
public:
type::hwnd hwnd ;
type::hwnd parenthwnd;
type::string title;
type::wndclass wc;/**//* wndclass info */
int regIndex;/**//* self-wndclass index in regList */
static type::result __stdcall wndproc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static proc proc;
static paint pt;
static type::string m(TEXT("啊!是你."));
using geo::polygon;
static polygon plg;
static int angle=0;
if(angle==0)
{
plg.push(100,100);
plg.push(200,100);
plg.push(300,200);
plg.push(300,300);
plg.push(200,250);
plg.push(100,400);
angle=1;
}
static wchar_t buf[20];
proc.update(hwnd,message,wParam,lParam);
switch (message)
{
case api::def::wm_create:
return 0 ;
case api::def::wm_mousemove:
pt.begin(hwnd);
m.set(0);
wsprintf(buf,L"(x:%d ,y:%d)\0",mouse::x(lParam),mouse::y(lParam));
m.set(buf);
pt.end();
InvalidateRect(hwnd,NULL,TRUE);
return 0;
case api::def::wm_paint:
pt.begin(hwnd);
{
POINT apt[6];
plg.rotate(angle);
for(int i=0;i!=6;i++)
{
apt[i].x=plg(i,0);
apt[i].y=plg(i,1);
}
pt.polygon(apt,6);
}
pt.text(m);
pt.end();
return 0;
case api::def::wm_destroy:
proc.postquit();
return 0 ;
}
return proc.defproc();
}
void init()
{
wc.style = def::cs_default;
wc.lpfnWndProc = wndproc ;
wc.cbClsExtra = def::nil ;
wc.cbWndExtra = def::nil ;
wc.hInstance = appinfo::hInstance ;
wc.hIcon = handle::icon() ;
wc.hCursor = handle::cursor();
wc.hbrBackground = handle::brush();
wc.lpszMenuName = def::nil;
appinfo::setListIndex(regIndex,wc.lpszClassName);
if (!RegisterClassW (&wc))
return ;
}
wndclass()
{
init();
}
~wndclass()
{
appinfo::decform();
}
void setStyle(UINT style)
{
wc.style = style;
}
void setIcon(HICON hIcon)
{
wc.hIcon = hIcon;
}
void setCursor(HCURSOR hCursor)
{
wc.hCursor = hCursor;
}
void setBackground(HBRUSH hbr)
{
wc.hbrBackground = hbr;
}
int renew()
{
hwnd = CreateWindowW(appinfo::regList[regIndex], // window class name
title(), // window caption
WS_OVERLAPPEDWINDOW, // window style
CW_USEDEFAULT,// initial x position
CW_USEDEFAULT,// initial y position
CW_USEDEFAULT,// initial x size
CW_USEDEFAULT,// initial y size
NULL, // parent window handle
NULL, // window menu handle
appinfo::hInstance, // program instance handle
NULL) ; // creation parameters
return 1;
}
void setTitle(wchar_t _title[])
{
title.set(_title);
}
};
};
class form
{
api::wndclass tf;
public:
form()
{
tf.setTitle(TEXT("ving"));
tf.init();
tf.renew();
}
~form()
{
}
form(wchar_t *title)
{
tf.setTitle(title);
tf.init();
tf.renew();
}
int show()
{
tf.renew();
int scx=api::sm::screenx();
int scy=api::sm::screeny();
SetWindowPos(tf.hwnd,NULL,scx/3 ,scx/3 ,scx/3,scy/3,SWP_HIDEWINDOW);
ShowWindow (tf.hwnd, appinfo::iCmdShow) ;
UpdateWindow (tf.hwnd) ;
return 1;
}
};
}
int cpp();
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,PSTR szCmdLine, int iCmdShow)
{
appinfo::regNum=0;
appinfo::listIndex=0;
appinfo::hInstance=hInstance;
appinfo::hPrevInstance=hPrevInstance;
appinfo::szCmdLine=szCmdLine;
appinfo::iCmdShow=iCmdShow;
cpp();
while (GetMessageW(&appinfo::msg, NULL, 0, 0))
{
TranslateMessage (&appinfo::msg) ;
DispatchMessage (&appinfo::msg) ;
}
return (int)appinfo::msg.wParam ;
}
#endif
#ifndef APPFRAME__
#define APPFRAME__
#include < windows.h >
#include < tchar.h >
#include < stdio.h >
#include " axiom.h "
#include " string.h "
#include " geo.h "
namespace appinfo
{
static const int max_form=500;
static int iCmdShow,regNum,listIndex;
static HINSTANCE hInstance;
static HINSTANCE hPrevInstance;
static PSTR szCmdLine;
static MSG msg;
/**//* register windowclass-name */
static TCHAR regList[max_form][4];
static void decform()
{
--regNum;
}
static void incform()
{
++regNum;
}
static void setListIndex(int & reg_index,LPCWSTR & wc_name)
{
reg_index=listIndex;
regList[listIndex][0]=1;
regList[listIndex][1]=reg_index;
regList[listIndex][2]=0;
wc_name=regList[listIndex];
++listIndex;
++regNum;
}
}
namespace frame
{
using adt::ustring;
class api
{
public:
class def
{
public:
static const int nil =0;
static const int sm_x = 0;
static const int sm_y = 1;
static const int wm_create=WM_CREATE;
static const int wm_paint=WM_PAINT;
static const int wm_destroy=WM_DESTROY;
static const int wm_mousemove=WM_MOUSEMOVE;
static const unsigned int cs_default= CS_HREDRAW | CS_VREDRAW ;
};
class type
{
public:
typedef HDC__* hdc;
typedef HWND hwnd;
typedef ustring string;
typedef UINT uint;
typedef RECT rect;
typedef LPRECT lprc;
typedef WPARAM wp;
typedef LPCWSTR lpcwstr;
typedef LPARAM lp;
typedef PAINTSTRUCT ps;
typedef LPPAINTSTRUCT lpps;
typedef BYTE byte;
typedef LONG_PTR result;
typedef WNDCLASS wndclass;
typedef HICON hicon;
typedef HCURSOR hcursor;
typedef HBRUSH__* hbrush;
typedef HINSTANCE hinstance;
typedef PSTR pstr;
typedef MSG msg;
typedef TCHAR tchar;
typedef BOOL state;
typedef POINT point;
};
class handle
{public:
static type::hicon icon(int i=0)
{
return LoadIcon (NULL, IDI_APPLICATION);
}
static type::hcursor cursor(int i=0)
{
return LoadCursor (NULL, IDC_ARROW);
}
static type::hbrush brush(int i=WHITE_BRUSH)
{
return (type::hbrush) GetStockObject (i);
}
};
class paint
{
public:
type::hdc hdc;
type::rect rect;
type::hwnd hwnd;
type::ps ps;
bool ready;
paint():ready(false){}
~paint()
{
if(ready!=false)
end();
ready=false;
}
type::hdc begin(type::hwnd & hwnd)
{
ready=true;
hdc = BeginPaint(hwnd,&ps);
GetClientRect (hwnd, &rect);
return (hdc );
}
int end()
{
ready=false;
return EndPaint(hwnd,&ps);
}
int text(type::string & tx)
{
if(ready)
return DrawTextW (hdc, tx(), -1, &rect,
DT_SINGLELINE | DT_CENTER | DT_VCENTER) ;
else return 0;
}
type::state rectangle(int x,int y,int w,int h)
{
int sx=sm::screenx();
int sy=sm::screeny();
return Rectangle (hdc,x,y,x+w, y+h) ;
}
type::state polygon(type::point *apt,int i)
{
return Polygon (hdc,apt,i) ;
}
};
class mouse
{
public:
static int x(type::lp & lp)
{
return LOWORD(lp) ;
}
static int y(type::lp & lp)
{
return HIWORD(lp) ;
}
};
class sm
{
public:
static int screenx()
{
return GetSystemMetrics(def::sm_x);
}
static int screeny()
{
return GetSystemMetrics(def::sm_y);
}
};
class message
{
public:
};
class proc
{
public:
type::hwnd hwnd;
type::uint msg;
type::wp wp;
type::lp lp;
proc(){}
proc(type::hwnd &hwnd_t,type::uint &msg_t,type::wp &wp_t,type::lp &lp_t)
{
update(hwnd_t,msg_t,wp_t,lp_t);
}
void update(type::hwnd &hwnd_t,type::uint &msg_t,type::wp &wp_t,type::lp &lp_t)
{
hwnd=hwnd_t;
msg=msg_t;
wp=wp_t;
lp=lp_t;
}
type::result defproc()
{
return DefWindowProcW (hwnd, msg, wp, lp);
}
void postquit(int exitCode_t=0)
{
if(appinfo::regNum==1)
{
//WSHOW__(TEXT("啊!是你."))
--appinfo::regNum;
PostQuitMessage(exitCode_t);
}else
{
--appinfo::regNum;
}
}
};
class wndclass
{
public:
type::hwnd hwnd ;
type::hwnd parenthwnd;
type::string title;
type::wndclass wc;/**//* wndclass info */
int regIndex;/**//* self-wndclass index in regList */
static type::result __stdcall wndproc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static proc proc;
static paint pt;
static type::string m(TEXT("啊!是你."));
using geo::polygon;
static polygon plg;
static int angle=0;
if(angle==0)
{
plg.push(100,100);
plg.push(200,100);
plg.push(300,200);
plg.push(300,300);
plg.push(200,250);
plg.push(100,400);
angle=1;
}
static wchar_t buf[20];
proc.update(hwnd,message,wParam,lParam);
switch (message)
{
case api::def::wm_create:
return 0 ;
case api::def::wm_mousemove:
pt.begin(hwnd);
m.set(0);
wsprintf(buf,L"(x:%d ,y:%d)\0",mouse::x(lParam),mouse::y(lParam));
m.set(buf);
pt.end();
InvalidateRect(hwnd,NULL,TRUE);
return 0;
case api::def::wm_paint:
pt.begin(hwnd);
{
POINT apt[6];
plg.rotate(angle);
for(int i=0;i!=6;i++)
{
apt[i].x=plg(i,0);
apt[i].y=plg(i,1);
}
pt.polygon(apt,6);
}
pt.text(m);
pt.end();
return 0;
case api::def::wm_destroy:
proc.postquit();
return 0 ;
}
return proc.defproc();
}
void init()
{
wc.style = def::cs_default;
wc.lpfnWndProc = wndproc ;
wc.cbClsExtra = def::nil ;
wc.cbWndExtra = def::nil ;
wc.hInstance = appinfo::hInstance ;
wc.hIcon = handle::icon() ;
wc.hCursor = handle::cursor();
wc.hbrBackground = handle::brush();
wc.lpszMenuName = def::nil;
appinfo::setListIndex(regIndex,wc.lpszClassName);
if (!RegisterClassW (&wc))
return ;
}
wndclass()
{
init();
}
~wndclass()
{
appinfo::decform();
}
void setStyle(UINT style)
{
wc.style = style;
}
void setIcon(HICON hIcon)
{
wc.hIcon = hIcon;
}
void setCursor(HCURSOR hCursor)
{
wc.hCursor = hCursor;
}
void setBackground(HBRUSH hbr)
{
wc.hbrBackground = hbr;
}
int renew()
{
hwnd = CreateWindowW(appinfo::regList[regIndex], // window class name
title(), // window caption
WS_OVERLAPPEDWINDOW, // window style
CW_USEDEFAULT,// initial x position
CW_USEDEFAULT,// initial y position
CW_USEDEFAULT,// initial x size
CW_USEDEFAULT,// initial y size
NULL, // parent window handle
NULL, // window menu handle
appinfo::hInstance, // program instance handle
NULL) ; // creation parameters
return 1;
}
void setTitle(wchar_t _title[])
{
title.set(_title);
}
};
};
class form
{
api::wndclass tf;
public:
form()
{
tf.setTitle(TEXT("ving"));
tf.init();
tf.renew();
}
~form()
{
}
form(wchar_t *title)
{
tf.setTitle(title);
tf.init();
tf.renew();
}
int show()
{
tf.renew();
int scx=api::sm::screenx();
int scy=api::sm::screeny();
SetWindowPos(tf.hwnd,NULL,scx/3 ,scx/3 ,scx/3,scy/3,SWP_HIDEWINDOW);
ShowWindow (tf.hwnd, appinfo::iCmdShow) ;
UpdateWindow (tf.hwnd) ;
return 1;
}
};
}
int cpp();
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,PSTR szCmdLine, int iCmdShow)
{
appinfo::regNum=0;
appinfo::listIndex=0;
appinfo::hInstance=hInstance;
appinfo::hPrevInstance=hPrevInstance;
appinfo::szCmdLine=szCmdLine;
appinfo::iCmdShow=iCmdShow;
cpp();
while (GetMessageW(&appinfo::msg, NULL, 0, 0))
{
TranslateMessage (&appinfo::msg) ;
DispatchMessage (&appinfo::msg) ;
}
return (int)appinfo::msg.wParam ;
}
#endif
这里是它的入口点界面,在该框架下,入口点是cpp(),当有需要,可以加入隐含变量处理入口点获取的路径和执行参数:
/**/
/* init.h */
#include " appframe.h "
int cpp()
{
using frame::form;
form f;
f.show();
return 0;
}
#include " appframe.h "
int cpp()
{
using frame::form;
form f;
f.show();
return 0;
}
当写到一定时机成熟时,会把appframe里的proc form管理池的接口搬到init.h的入口点函数.
由于之前基于自己写的arith::axiom库实现过关于不规则内陷多边形的点区域检测demo,所以接下来关于组件库和监听框架的实现应该会快了.
该代码的demo是一个多边形围绕一个点旋转,中间不停更新鼠标在Client区的相对坐标.