0xAA55 发表于 2014-9-11 02:34:00

【封装】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:


完整的工程:

cyycoish 发表于 2014-9-11 22:07:38

好诶,大神发福利咯,麻麻再也不用担心我用C开发界面费脑筋啦!

hxw 发表于 2019-12-6 12:58:11

感谢大神分享,可以方便使用了。
页: [1]
查看完整版本: 【封装】Windows窗口程序的封装:WndX