炫彩界面库源码分析---简单的应用程序过程分析

炫彩界面库免费开源后,可以方便使用。它的原理是DirectUI,直接绘制控件并做出相关响应,下面来一一分析。

一个简单的应用程序过程分析:  源码如下

int WINAPI _tWinMain(HINSTANCE hInstance,  HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
{
    XInitXCGUI(); //界面库初始化

    //创建窗口
    HWINDOW hWindow=XWnd_CreateWindow(400,200,300,200,L"炫彩界面库 - 窗口");
    if(hWindow) //创建成功
        XWnd_ShowWindow(hWindow,SW_SHOW); //显示窗口
    else
        return 0; //创建失败

    XRunXCGUI(); //运行
    return 0;
}

总体的过程分为四部分。

一.界面库初始化XInitXCGUI

二.创建普通窗口XWnd_CreateWindow

三.显示窗口XWnd_ShowWindow

四.运行消息循环XRunXCGUI


下面开始分析每个部分

一.界面库初始化XInitXCGUI

    XInitXCGUI函数内部做了如下工作:

 1、注册窗口
2、注册剪切板格式
3、初始化4个临界资源对象
4、创建后台线程

简化后代码

	HMODULE hInstance = GetModuleHandle(NULL);

	HMODULE hInsIcon = hInstance;

	//注册窗口
	WNDCLASSEXW wcex = {0};
	wcex.cbSize = sizeof(WNDCLASSEX);
	wcex.style			= CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc	= XCGUI_WndProc;
	wcex.hInstance		= hInstance;
	wcex.hIcon			= LoadIcon(hInsIcon,MAKEINTRESOURCE(IDI_ICON1));
	wcex.hCursor		= LoadCursor(NULL, IDC_ARROW);
	wcex.hbrBackground	= (HBRUSH)(COLOR_WINDOW+1);
	wcex.lpszMenuName	= NULL;
	wcex.lpszClassName	= XCGUI_CLASS_NAME;
	wcex.hIconSm		= LoadIcon(hInsIcon,MAKEINTRESOURCE(IDI_SMALL));

	::RegisterClassEx(&wcex)

	//注册剪切板格式
	g_clipborad_HTMLFormat=RegisterClipboardFormat(L"HTML Format");
	g_clipbroad_RichEditFormat=RegisterClipboardFormat(L"XCGUI_RichEdit_Format");

	Resource_Init();  //资源初始化

	GdiplusStartupInput gdiplusStartInput;
	GdiplusStartup(&gdiplusToken, &gdiplusStartInput, NULL);//GDI++

	if(g_fun_init && FALSE==g_fun_init())	//UI文件解析库XML初始化
	{
		return FALSE;
	}

	//初始化临界资源对象
	InitializeCriticalSection(&g_timer_CriticalSection);
	InitializeCriticalSection(&g_CriticalSection_Animation_button);
	InitializeCriticalSection(&g_CriticalSection_Animation_richEdit);
	InitializeCriticalSection(&g_CriticalSection_WindowDraw);

	//后台循环线程
	g_hThread_Loop=CreateThread(NULL,0,XCGUI_Loop_ThreadProc,0,0,NULL);   

	if (NULL==g_hThread_Loop)
	{
		return FALSE;
	}
	return TRUE;

后台线程

/////////////////////////////////////////////////////////////////////
DWORD WINAPI XCGUI_Loop_ThreadProc(LPVOID lpParameter)
{
	DWORD ms=20;//USER_TIMER_MINIMUM*2; //最小延时单位

	while (1)
	{
		Sleep(ms);

		if(NULL==g_hThread_Loop)
			break;

		DWORD timer=GetTickCount();

		//处理定时器
		EnterCriticalSection(&g_timer_CriticalSection);
		if (g_hArray_Timer)
			XCGUI_Loop_timer(timer);
		LeaveCriticalSection(&g_timer_CriticalSection);

		//////////////////////////////////////////////////////////////////////

		//处理按钮动画
		EnterCriticalSection(&g_CriticalSection_Animation_button);
		if(g_hArray_Animation_button)
			XCGUI_Loop_Animation(timer);
		LeaveCriticalSection(&g_CriticalSection_Animation_button);

		//////////RichEdit GIF/////////////////////////////////////////////////

		EnterCriticalSection(&g_CriticalSection_Animation_richEdit);
		if(g_hArray_Animation_RichEdit)
			XCGUI_Loop_Animation_RichEdit(timer);
		LeaveCriticalSection(&g_CriticalSection_Animation_richEdit);

		/////////处理窗口绘制优化////////////////////

		EnterCriticalSection(&g_CriticalSection_WindowDraw);
		resource_manager_window_  *pWindowNode=resource_manager.pWindowList;
		while (pWindowNode)
		{
			window_ *pWindow=(window_*)pWindowNode->hWindow;
			if(pWindow->drawWindow.bValid)
			{
				PostMessage(pWindow->hWnd,XWM_DRAW_T,0,0);
			}
			pWindowNode=pWindowNode->pNext;
		}
		LeaveCriticalSection(&g_CriticalSection_WindowDraw);
	}

	if(g_hThread_Loop)
	{	
		CloseHandle(g_hThread_Loop);
		g_hThread_Loop=NULL;
	}

	return 0;
}

窗口消息回调函数

//总窗口消息过程
LRESULT CALLBACK XCGUI_WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	if(WM_CREATE==message)
	{
		LONG L=(LONG)(((LPCREATESTRUCT)lParam)->lpCreateParams);
		SetWindowLong(hWnd,GWL_USERDATA,L);

		window_ *pWindow=(window_*)(((LPCREATESTRUCT)lParam)->lpCreateParams);
		if(XC_IsHWINDOW((HWINDOW)pWindow))
		{
			windowProc_ *pFunT=pWindow->pWndProc;
			while(pFunT)
			{
				if(((pFunWndMsgProc)pFunT->pFun)((HWINDOW)pWindow,message,wParam,lParam))
					return 0;
				pFunT=pFunT->pNext;
			}
		}
		return DefWindowProc(hWnd, message, wParam, lParam);
	}

	window_ *pWindow=(window_*)GetWindowLong(hWnd,GWL_USERDATA);
	if(FALSE==XC_IsHWINDOW((HWINDOW)pWindow))
		return DefWindowProc(hWnd, message, wParam, lParam);

	switch(message)
	{
	case WM_KILLFOCUS:
		{
		//	XTRACE("失去焦点 \n");
		}break;
	case WM_SETFOCUS:
		{
		//	XTRACE("获得焦点 \n");
		}break;
	}

	windowProc_ *pFunT=pWindow->pWndProc;
	while(pFunT)
	{
		if(((pFunWndMsgProc)pFunT->pFun)((HWINDOW)pWindow,message,wParam,lParam))
			return 0;
		pFunT=pFunT->pNext;
	}

	switch(message)
	{
	case WM_NCPAINT:     return 0;
	case WM_ERASEBKGND:  return 1;
	case WM_NCACTIVATE:	 return 1;
	case WM_ACTIVATE:
		{
			//XTRACE("激活 WM_ACTIVATE \n");
			XWnd_RedrawWnd((HWINDOW)pWindow);
		}break;
	case WM_NCCALCSIZE:
		if(pWindow->transparentFlag & XC_WIND_TRANSPARENT_SHADOW)
		{
			if(wParam)
			{
				NCCALCSIZE_PARAMS *pInfo=(NCCALCSIZE_PARAMS*)lParam;
				pInfo->rgrc[0].left+=XC_WIND_SHADOW_SIZE;
				pInfo->rgrc[0].top+=XC_WIND_SHADOW_SIZE;
				pInfo->rgrc[0].right-=XC_WIND_SHADOW_SIZE;
				pInfo->rgrc[0].bottom-=XC_WIND_SHADOW_SIZE;
				return 0;
			}
		}else
		{
			if(wParam)
				return 0;
		}
	}

	return DefWindowProc(hWnd, message, wParam, lParam);
}


二.创建普通窗口XWnd_CreateWindow

HWINDOW WINAPI XWnd_CreateWindow(int x,int y,int cx,int cy,wchar_t *pTitle,HWND hWndParent,int XCStyle)
{
	window_ *pWindow=(window_*)malloc(sizeof(window_));	//创建结构体window_
	if(pWindow)
	{
		memset(pWindow,0,sizeof(window_));	//结构体window_填充0
		if(FALSE==Wnd_Init((HWINDOW)pWindow,NULL,NULL,pTitle,NULL,x,y,cx,cy,hWndParent,XCStyle,XC_WINDOW))
		{
			delete pWindow;
			return NULL;
		}

		//g_fun_create_window函数指针是否存在
		//存在时运行函数g_fun_create_window((HWINDOW)pWindow)
		//不存在return (HWINDOW)pWindow;	
		//XML文件创建
		if(g_fun_create_window && FALSE==g_fun_create_window((HWINDOW)pWindow))
		{
			return FALSE;
		}
	}
	return (HWINDOW)pWindow;
}
里面主要调用了一个函数Wnd_Init  窗口初始化

函数简化后

BOOL Wnd_Init(HWINDOW hWindow,DWORD dwExStyle, wchar_t* lpClassName, wchar_t* lpWindowName,DWORD dwStyle,int x,int y,int cx,int cy,HWND hWndParent,int XCStyle,int exType)
{
	HMODULE hModule=GetModuleHandle(NULL);

	window_ *pWindow=(window_*)hWindow;
	pWindow->exType=exType;
	pWindow->xcStyle=XCStyle;
	pWindow->hArrayEle=XArray_Create();
	pWindow->hArrayEleNC=XArray_Create();
	pWindow->hMenuBar=NULL;
	pWindow->hToolBar=NULL;
	pWindow->minWidth=150;
	pWindow->minHeight=100;
	pWindow->caretColor=RGB(0,0,0);
	pWindow->chartletStyle|=XC_CS_STROKE_INNER;
	pWindow->chartletStyle|=XC_CS_STROKE_OUTER;

	pWindow->strokeOuter_color1=RGB(6,108,156);
	pWindow->strokeOuter_color2=RGB(143,217,253);
	pWindow->strokeInner_color1=RGB(6,108,156);
	pWindow->strokeInner_color2=RGB(143,217,253);
	pWindow->transparentAlpha=230;

	pWindow->iconSize.cx=24;
	pWindow->iconSize.cy=24;
	pWindow->roundSize=5;

	if(NULL==lpClassName)
		lpClassName=XCGUI_CLASS_NAME;

	if(NULL==lpWindowName)
		lpWindowName=L"XCGUI-Window";

	if(NULL==dwStyle)
		dwStyle=WS_SYSMENU | WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX;

	if(XCStyle & XC_SY_CENTER) //窗口居中
	{	
		RECT rect;
		SystemParametersInfo(SPI_GETWORKAREA,0,&rect,0);
		x=(rect.right-rect.left)/2-cx/2;
		y=(rect.bottom-rect.top)/2-cy/2;
	}

	if(dwStyle & WS_CAPTION)
	{
		dwStyle=dwStyle & ~WS_CAPTION;
	}

	((object_*)hWindow)->type=XC_WINDOW;
	AddTypeDebug(hWindow,XC_WINDOW);

	HWND hWnd = CreateWindowExW(dwExStyle,lpClassName,lpWindowName,dwStyle,
		x, y, cx-1, cy, hWndParent, NULL, hModule, hWindow);

	//DWORD err= GetLastError();

	if(hWnd)
	{
		((object_*)hWindow)->type=XC_WINDOW;
		pWindow->hWnd=hWnd;
		Resource_AddWindow(hWindow);	//往资源管理内添加窗口-----必须添加

		pWindow->bkColor=RGB(255,255,255);
		pWindow->hArray_msg=XArray_Create();
		pWindow->hArray_NCmsg=XArray_Create();

		::SetWindowPos(hWnd,NULL,0,0,cx,cy,SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE);

		if(pWindow->xcStyle & XC_SY_ROUND)
		{
			HRGN hrgn = CreateRoundRectRgn(0,0,cx+1,cy+1,pWindow->roundSize,pWindow->roundSize);
			SetWindowRgn(hWnd,hrgn,FALSE);
			DeleteObject(hrgn);
		}

		if(XC_SY_CAPTION & XCStyle)
			XWnd_SetCaptionHeight(hWindow,28);

		if(XC_SY_BORDER & XCStyle)
		{
			XWnd_SetBorderSize(hWindow,8,8,8,8);
		}

		//注册消息
		//分别往数组内添加要处理的消息
		XWnd_RegisterMsgProc(hWindow,Wnd_WindowProc);//窗口过程

		XWnd_RegisterNCMessage(hWindow,XWM_NCMOUSEMOVE,Wnd_OnNCMouseMove);
		XWnd_RegisterNCMessage(hWindow,XWM_NCLBUTTONDOWN,Wnd_OnNCLButtonDown);
		XWnd_RegisterNCMessage(hWindow,XWM_NCLBUTTONUP,Wnd_OnNCLButtonUp);
		XWnd_RegisterNCMessage(hWindow,XWM_NCRBUTTONDOWN,Wnd_OnNCRButtonDown);
		XWnd_RegisterNCMessage(hWindow,XWM_NCRBUTTONUP,Wnd_OnNCRButtonUp);
		XWnd_RegisterNCMessage(hWindow,XWM_NCPAINT,Wnd_OnNCDrawWindow);
		XWnd_RegisterNCMessage(hWindow,XWM_NCMOUSECLICK,Wnd_OnNCMouseClick);
		XWnd_RegisterNCMessage(hWindow,XWM_NCMOUSEDBCLICK,Wnd_OnNCMouseDBClick);

		XWnd_RegisterMessage(hWindow,WM_PAINT,Wnd_OnDrawWindow);
		XWnd_RegisterMessage(hWindow,WM_DESTROY,Wnd_OnDestroy);
		XWnd_RegisterMessage(hWindow,WM_NCDESTROY,Wnd_OnNCDestroy);
		XWnd_RegisterMessage(hWindow,WM_MOUSEMOVE,Wnd_OnMouseMove);
		XWnd_RegisterMessage(hWindow,WM_LBUTTONDOWN,Wnd_OnLButtonDown);
		XWnd_RegisterMessage(hWindow,WM_LBUTTONUP,Wnd_OnLButtonUp);
		XWnd_RegisterMessage(hWindow,WM_RBUTTONDOWN,Wnd_OnRButtonDown);
		XWnd_RegisterMessage(hWindow,WM_RBUTTONUP,Wnd_OnRButtonUp);

		XWnd_RegisterMessage(hWindow,WM_MOUSELEAVE,Wnd_OnMouseLeave);
		XWnd_RegisterMessage(hWindow,WM_SIZE,Wnd_OnSize);
		XWnd_RegisterMessage(hWindow,XWM_MOUSECLICK,Wnd_OnMouseClick);
		XWnd_RegisterMessage(hWindow,XWM_MOUSEDBCLICK,Wnd_OnMouseDBClick);
		XWnd_RegisterMessage(hWindow,XWM_DRAW_T,Wnd_OnDrawT);
		XWnd_RegisterMessage(hWindow,XWM_REDRAW_ELE,Wnd_OnRedrawEle);
		XWnd_RegisterMessage(hWindow,WM_SETFOCUS,Wnd_OnSetFocus);
		XWnd_RegisterMessage(hWindow,WM_KILLFOCUS,Wnd_OnKillFocus);
		XWnd_RegisterMessage(hWindow,WM_KEYDOWN,Wnd_OnKeyDown);
		XWnd_RegisterMessage(hWindow,WM_TIMER,Wnd_OnTimer);
		XWnd_RegisterMessage(hWindow,XWM_TIMER,Wnd_OnTimerEx);

		XWnd_RegisterMessage(hWindow,WM_CHAR,Wnd_OnChar);
		XWnd_RegisterMessage(hWindow,WM_CAPTURECHANGED,Wnd_OnCaptureChanged);
		XWnd_RegisterMessage(hWindow,WM_MOUSEWHEEL,Wnd_OnMouseWheel);
		XWnd_RegisterMessage(hWindow,XWM_REDRAW,Wnd_OnRedraw);
		XWnd_RegisterMessage(hWindow,WM_GETMINMAXINFO,Wnd_OnMinMaxInfo);

		//窗口最大化、最小化、关闭按钮
		if(pWindow->xcStyle & XC_SY_CLOSE)
		{
			pWindow->hClose=XBtn_Create(1,1,40,20);
			XWnd_AddEleNC(hWindow,pWindow->hClose);
			Ele_SetType(pWindow->hClose,XC_BUTTON_CLOSE);
			XEle_EnableFocus(pWindow->hClose,FALSE);
			XEle_RegisterMessage(pWindow->hClose,XM_PAINT,Wnd_OnBtnCloseDraw);
			XEle_RegisterEvent(pWindow->hClose,XE_BNCLICK,Wnd_OnEventBtnCloseClick);
		}
		if(pWindow->xcStyle & XC_SY_MAXIMIZE)
		{
			pWindow->hMaxinize=XBtn_Create(1,1,25,20);
			XWnd_AddEleNC(hWindow,pWindow->hMaxinize);
			Ele_SetType(pWindow->hMaxinize,XC_BUTTON_MAX);
			XEle_EnableFocus(pWindow->hMaxinize,FALSE);
			XEle_RegisterMessage(pWindow->hMaxinize,XM_PAINT,Wnd_OnBtnMaximizeDraw);
			XEle_RegisterEvent(pWindow->hMaxinize,XE_BNCLICK,Wnd_OnEventBtnMaximizeClick);
		}
		if(pWindow->xcStyle & XC_SY_MINIMIZE) //最小化按钮
		{
			pWindow->hMinimize=XBtn_Create(1,1,25,20);
			XWnd_AddEleNC(hWindow,pWindow->hMinimize);
			Ele_SetType(pWindow->hMinimize,XC_BUTTON_MIN);
			XEle_EnableFocus(pWindow->hMinimize,FALSE);
			XEle_RegisterMessage(pWindow->hMinimize,XM_PAINT,Wnd_OnBtnMinimizeDraw);
			XEle_RegisterEvent(pWindow->hMinimize,XE_BNCLICK,Wnd_OnEventBtnMinimizeClick);
		}

		//调整窗口
		Wnd_AdjustCaption(hWindow,cx);

		return TRUE;
	}
	return FALSE;
}


1.该函数首先是填充结构体window_内部成员的相关数值

2.调用了系统API窗口窗口CreateWindowExW
3.Resource_AddWindow(hWindow);//往资源管理内添加窗口-----必须添加
4.设置标题栏和边框等

5.注册窗口过程函数、注册非客户区消息、注册窗口标准消息

6.窗口最大化、最小化、关闭按钮

7.调整窗口

三.显示窗口XWnd_ShowWindow


四.运行消息循环XRunXCGUI

void WINAPI XRunXCGUI()
{
	MSG msg;
	// 主消息循环:
	while (true)
	{
		if(Resource_GetWindowCount()<1)
			break;

		GetMessage(&msg, NULL, 0, 0);

		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
	XExitProcess();
}

XExitProcess 退出函数,处理了一些释放资源
posted @ 2017-06-15 20:14  jadeshu  阅读(712)  评论(0编辑  收藏  举报