【封装】Windows窗口程序的封装:WndX
用了这个以后,你不必每次写窗口程序都重复写RegisterClassEx、CreateWindowEx、WndProc等各种烦人的每次都要写的玩意儿了。这个程序现在被我改进了,请看改进后的程序:http://www.0xaa55.com/thread-878-1-1.html
用法:#include<stdio.h>
#include"WndX.h"
#define ErrRet(err) {fputs(err,stderr);goto Cleanup;}
int main(int argc,char**argv)
{
WndXP pWnd=NULL;
//初始化WndX库
InitWndXGlobal(GetModuleHandle(NULL));
//创建窗口
pWnd=CreateWndX(NULL);
if(!pWnd)ErrRet("Create WndX failed.\n");
//初始化窗口
if(!InitWndX(pWnd,WS_OVERLAPPEDWINDOW,0,TEXT("0xAA55->WndX"),TEXT("窗口类名是扯鸡吧"),CW_USEDEFAULT,CW_USEDEFAULT,448,336,NULL,NULL,SW_SHOW))
ErrRet("Initialize WndX failed.\n");
//消息循环
while(WaitForWndXMessages());
//清理WndX库
DestroyWndXGlobal();
return 0;
Cleanup:
DestroyWndXGlobal();
return 2;
}你可以通过调用AddWndXMsgHandler来给特定的消息设定消息处理函数,而不必每次都非得写一个WndProc。是不是很方便呢?
这个WndX库,就是我为了使编写Windows程序更方便而写的。大家可以随便拿去用。
WndX.c://=============================================================================
//作者:0xAA55
//论坛:http://www.0xaa55.com/
//版权所有 2013-2014 技术宅的结界
//请保留原作者信息,否则视为侵权
//-----------------------------------------------------------------------------
#include<malloc.h>
#include"WndX.h"
#ifndef WXInternal
#define WXInternal static
#endif // !WXInternal
WXInternal
LRESULT CALLBACK WndXWndProc(HWND hWnd,UINT uMsg,WPARAM wp,LPARAM lp);
WXInternal
WNDCLASSEX g_WCEx=
{
sizeof(WNDCLASSEX),
0,
(WNDPROC)WndXWndProc,
0,
0,
NULL,//hInstance
NULL,
NULL,
(HBRUSH)(COLOR_BTNFACE+1),
NULL,
NULL,//Class name
NULL
};
WXInternal size_t g_NbWndX;
WXInternal WndXP *g_ppWndX;
//=============================================================================
//PushWndXP:
//将WndXP压入全局容器
//-----------------------------------------------------------------------------
WXInternal
BOOL PushWndXP(WndXP p)
{
size_t NewCount=g_NbWndX+1;
WndXP*pNewPtr=(WndXP*)realloc(g_ppWndX,NewCount*sizeof(WndXP));
if(!pNewPtr)
return FALSE;
g_ppWndX=pNewPtr;
g_ppWndX=p;
g_NbWndX=NewCount;
return TRUE;
}
//=============================================================================
//PopWndXP:
//将全局容器最后一个WndXP去掉
//-----------------------------------------------------------------------------
WXInternal
void PopWndXP()
{
if(g_NbWndX)
g_ppWndX=(WndXP*)realloc(g_ppWndX,(--g_NbWndX)*sizeof(WndXP));
}
//=============================================================================
//InitWndXGlobal:
//初始化WndX库
//-----------------------------------------------------------------------------
WXFunc
void InitWndXGlobal(HINSTANCE hInstance)
{
g_NbWndX=0;
g_ppWndX=NULL;
g_WCEx.hInstance=hInstance;
}
//=============================================================================
//DestroyWndXGlobal:
//结束WndX库的使用
//-----------------------------------------------------------------------------
WXFunc
void DestroyWndXGlobal()
{
while(g_NbWndX)
DestroyWndX(g_ppWndX);
}
//=============================================================================
//CreateWndX:
//创建WndX对象
//-----------------------------------------------------------------------------
WXFunc
WndXP CreateWndX(void*pUserData)
{
WndXP pNewPtr=(WndXP)malloc(sizeof(WndX));
if(!pNewPtr)
return NULL;
if(PushWndXP(pNewPtr))
{
memset(pNewPtr,0,sizeof(WndX));
pNewPtr->pUserData=pUserData;
return pNewPtr;
}
else
{
free(pNewPtr);
return NULL;
}
}
//=============================================================================
//DestroyWndX:
//销毁WndX对象
//-----------------------------------------------------------------------------
WXFunc
void DestroyWndX(WndXP pThis)
{
size_t i;
UnregisterClass((LPCTSTR)(pThis->aClass),g_WCEx.hInstance);
ClearWndXMsgHandler(pThis);
free(pThis);
//遍历存储的窗口表,删掉记录
for(i=0;i<g_NbWndX;i++)
{
if(g_ppWndX==pThis)
{
g_ppWndX=g_ppWndX;//和最后一个交换
PopWndXP();//删掉最后一个的记录
break;//记录不会重复
}
}
}
//=============================================================================
//InitWndX:
//初始化WndX对象
//-----------------------------------------------------------------------------
WXFunc
BOOL
#ifdef UNICODE
InitWndXW
#else
InitWndXA
#endif // UNICODE
(
WndXP pThis,
DWORD dwStyle,
DWORD dwExStyle,
LPCTSTR szTitle,
LPCTSTR szClass,
int x,int y,
int Width,int Height,
HWND hWndParent,HMENU hMenu,
int nCmdShow
)
{
pThis->szTitle=szTitle;
pThis->szClass=szClass;
g_WCEx.lpszClassName=szClass;
pThis->aClass=RegisterClassEx(&g_WCEx);
if(!pThis->aClass)
return FALSE;
pThis->hWnd=CreateWindowEx(dwExStyle,(LPCTSTR)pThis->aClass,szTitle,dwStyle,x,y,Width,Height,hWndParent,hMenu,g_WCEx.hInstance,NULL);
if(pThis->hWnd)
{
ShowWindow(pThis->hWnd,nCmdShow);
UpdateWindow(pThis->hWnd);
}
else
return FALSE;
return TRUE;
}
//=============================================================================
//AddWndXMsgHandler:
//给WndX对象添加指定的消息的处理函数
//-----------------------------------------------------------------------------
WXFunc
BOOL AddWndXMsgHandler(WndXP pThis,UINT uMsg,WNDPROC pfnCallBack)
{
UINT uNewCount=pThis->uNbMsgCallBacks+1;
MsgCallBackP pNewPtr=(MsgCallBackP)realloc(pThis->pMsgCallBacks,uNewCount*sizeof(MsgCallBack));
if(!pNewPtr)
return FALSE;
pThis->pMsgCallBacks=pNewPtr;
pNewPtr.pCallBack=pfnCallBack;
pNewPtr.uMsg=uMsg;
pThis->uNbMsgCallBacks=uNewCount;
return TRUE;
}
//=============================================================================
//RemoveWndXMsgHandler:
//移除WndX对象指定的消息处理函数
//-----------------------------------------------------------------------------
WXFunc
void RemoveWndXMsgHandler(WndXP pThis,UINT uMsg)
{
UINT i;
for(i=0;i<pThis->uNbMsgCallBacks;i++)
{
if(pThis->pMsgCallBacks.uMsg==uMsg)//如果是该消息的处理函数
{//与最后一个交换,然后删除
memcpy(&(pThis->pMsgCallBacks),&(pThis->pMsgCallBacks[--pThis->uNbMsgCallBacks]),sizeof(MsgCallBack));
pThis->pMsgCallBacks=(MsgCallBackP)realloc(pThis->pMsgCallBacks,pThis->uNbMsgCallBacks*sizeof(MsgCallBack));
}
}
}
//=============================================================================
//ClearWndXMsgHandler:
//移除WndX对象所有的消息处理函数
//-----------------------------------------------------------------------------
WXFunc
void ClearWndXMsgHandler(WndXP pThis)
{
free(pThis->pMsgCallBacks);
pThis->pMsgCallBacks=NULL;
pThis->uNbMsgCallBacks=0;
}
//=============================================================================
//WndXWndProc:
//所有WndX对象的消息处理函数
//-----------------------------------------------------------------------------
WXInternal
LRESULT CALLBACK WndXWndProc(HWND hWnd,UINT uMsg,WPARAM wp,LPARAM lp)
{
size_t i;//i用来遍历已有的WndX
for(i=0;i<g_NbWndX;i++)
{
if(hWnd==g_ppWndX->hWnd)
{
size_t j;//j用来遍历已注册的消息处理函数
for(j=0;j<g_ppWndX->uNbMsgCallBacks;j++)
{
if(uMsg==g_ppWndX->pMsgCallBacks.uMsg)//如果注册了这个消息的处理函数则处理它
return g_ppWndX->pMsgCallBacks.pCallBack(hWnd,uMsg,wp,lp);
}
}
}
//如果是未经处理的WM_DESTROY,则生成WM_QUIT消息
if(uMsg==WM_DESTROY)
{
PostQuitMessage(0);
return 0;
}
//没有注册的窗口和消息则直接用默认方式处理。
return DefWindowProc(hWnd,uMsg,wp,lp);
}
//=============================================================================
//CheckWndXMessages:
//检查消息,自动调用所有的回调函数,有消息返回真,无消息返回假
//-----------------------------------------------------------------------------
WXFunc
BOOL CheckWndXMessages(void)
{
MSG msg;
if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
return TRUE;
}
return FALSE;
}
//=============================================================================
//WaitForWndXMessages:
//等待消息。窗口关闭后返回假
//-----------------------------------------------------------------------------
WXFunc
BOOL WaitForWndXMessages(void)
{
MSG msg;
if(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
return TRUE;
}
else
return FALSE;
}WndX.h://=============================================================================
//作者:0xAA55
//论坛:http://www.0xaa55.com/
//版权所有 2013-2014 技术宅的结界
//请保留原作者信息,否则视为侵权
//-----------------------------------------------------------------------------
#ifndef _WINDOWX_
#define _WINDOWX_
#include<Windows.h>
#ifndef WXFunc
#define WXFunc
#endif // !WXFunc
#ifndef WXCall
#define WXCall WINAPI
#define WXCallP WXCall*
#endif // !WXCall
#pragma pack(push,1)
typedef struct
{
UINT uMsg;
WNDPROC pCallBack;
}MsgCallBack,*MsgCallBackP;
typedef struct
{
HWND hWnd;
LPCTSTR szTitle;
LPCTSTR szClass;
ATOM aClass;
UINT uNbMsgCallBacks;
MsgCallBackP pMsgCallBacks;
void *pUserData;
}WndX,*WndXP;
#pragma pack(pop)
#ifdef __cplusplus
extern"C"
{
#endif // __cplusplus
WXFunc void InitWndXGlobal(HINSTANCE hInstance);//初始化WndX库
WXFunc void DestroyWndXGlobal(void);//结束WndX库的使用
WXFunc WndXP CreateWndX(void*pUserData);//创建WndX对象
WXFunc void DestroyWndX(WndXP pThis);//销毁WndX对象
//=============================================================================
//InitWndX:
//初始化WndX
//-----------------------------------------------------------------------------
WXFunc BOOL InitWndXA
(
WndXP pThis,
DWORD dwStyle,
DWORD dwExStyle,
LPCSTR szTitle,
LPCSTR szClass,
int x,int y,
int Width,int Height,
HWND hWndParent,
HMENU hMenu,
int nCmdShow
);
WXFunc BOOL InitWndXW
(
WndXP pThis,
DWORD dwStyle,
DWORD dwExStyle,
LPCWSTR szTitle,
LPCWSTR szClass,
int x,int y,
int Width,int Height,
HWND hWndParent,
HMENU hMenu,
int nCmdShow
);
#ifdef UNICODE
#define InitWndX InitWndXW
#else
#define InitWndX InitWndXA
#endif // UNICODE
//给WndX对象添加指定的消息的处理函数
WXFunc BOOL AddWndXMsgHandler(WndXP pThis,UINT uMsg,WNDPROC pfnCallBack);
//移除WndX对象指定的消息处理函数
WXFunc void RemoveWndXMsgHandler(WndXP pThis,UINT uMsg);
//移除WndX对象所有的消息处理函数
WXFunc void ClearWndXMsgHandler(WndXP pThis);
//检查消息
WXFunc BOOL CheckWndXMessages(void);
//等待消息。窗口关闭后返回假。没有消息则不返回。
WXFunc BOOL WaitForWndXMessages(void);
#ifdef __cplusplus
}
#endif // __cplusplus
#endif // !_WINDOW_SRC:
完整的工程: 好诶,大神发福利咯,麻麻再也不用担心我用C开发界面费脑筋啦! 感谢大神分享,可以方便使用了。
页:
[1]