事件驱动调度

问题如下:
设有K个工序,每个工序编号为Ji,i=1,2,…,K。总工序数。
在M个设备上加工,要求:
1.一台设备在某一时刻只能加工一道工序;
2.一台设备一旦加工某道工序,则直到该工序加工完毕后,这台设备才能加工其它工序;
3.一道工序只能被一台设备加工;
4.每道工序都必须在其紧前工序加工完后,方可开始加工;
5.每道工序的加工时间已知,且与加工顺序无关;
6.允许工序之间等待,允许设备在工序达到之前闲置


针对加工工序加工顺序的不确定性,利用构造事件驱动的思想,提出根据事件驱动产品加工的综合调度。
系统初始时所有设备的均空闲,此时由系统产生设备空闲事件,并驱动工序集中的可调度工序可在其加工设备上安排调度,使得该时刻工序集产生加工开始事件。随着系统加工时间推移,当有工序加工完毕时,工序集产生加工完毕事件,同时由于有工序加工完毕,其加工设备会在此时出现空闲,此时设备集产生设备空闲事件。
加工完毕事件与设备空闲事件在同一时刻发生,该时刻设备集中产生了新的空闲设备,工序集中产生了加工完毕的工序且有可能产生新的可调度工序。这两个事件更新了设备集和工序集中元素的状态,为触发新的加工开始事件创造了条件。
此时产生的设备空闲事件驱动空闲设备进行一次可调度工序的寻找,对于满足可调度约束条件的工序(即可调度工序),在该时刻安排调度,并由工序集产生新的加工开始事件。
通过以上描述,每次加工开始事件代表着工序的一次调度,加工完毕事件代表工序调度的结束,如此反复当加工完毕事件和设备空闲事件发生时,若所有设备均空闲,且无可调度工序,即工序集中的所有工序均已加工完毕,则系统加工结束。
具体思路是以每次工序加工结束作为一次设备空闲事件,驱动空闲设备进行一次可调度工序的寻找;如果可调度工序唯一,则调度此工序;如果可调度工序不唯一,选择用时短的工序。
数据结构分析
 


    
    
// BatchDis.cpp : Defines the class behaviors for the application.
//

#include "stdafx.h"
#include "BatchDis.h"
#include "BatchDisDlg.h"
#pragma comment(lib,"SkinPPWTL.lib");
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/
// CBatchDisApp

BEGIN_MESSAGE_MAP(CBatchDisApp, CWinApp)
	//{{AFX_MSG_MAP(CBatchDisApp)
		// NOTE - the ClassWizard will add and remove mapping macros here.
		//    DO NOT EDIT what you see in these blocks of generated code!
	//}}AFX_MSG
	ON_COMMAND(ID_HELP, CWinApp::OnHelp)
END_MESSAGE_MAP()

/
// CBatchDisApp construction

CBatchDisApp::CBatchDisApp()
{
	// TODO: add construction code here,
	// Place all significant initialization in InitInstance
}

/
// The one and only CBatchDisApp object

CBatchDisApp theApp;

/
// CBatchDisApp initialization

BOOL CBatchDisApp::InitInstance()
{
	AfxEnableControlContainer();

	// Standard initialization
	// If you are not using these features and wish to reduce the size
	//  of your final executable, you should remove from the following
	//  the specific initialization routines you do not need.
	skinppLoadSkin(_T("Devoir.ssk"));
#ifdef _AFXDLL
	Enable3dControls();			// Call this when using MFC in a shared DLL
#else
	Enable3dControlsStatic();	// Call this when linking to MFC statically
#endif

	CBatchDisDlg dlg;
	m_pMainWnd = &dlg;
	int nResponse = dlg.DoModal();
	if (nResponse == IDOK)
	{
		// TODO: Place code here to handle when the dialog is
		//  dismissed with OK
	}
	else if (nResponse == IDCANCEL)
	{
		// TODO: Place code here to handle when the dialog is
		//  dismissed with Cancel
	}

	// Since the dialog has been closed, return FALSE so that we exit the
	//  application, rather than start the application's message pump.
	return FALSE;
}

int CBatchDisApp::ExitInstance() 
{
	// TODO: Add your specialized code here and/or call the base class
	skinppExitSkin();
	return CWinApp::ExitInstance();
}

// BatchDisDlg.cpp : implementation file
//

#include "stdafx.h"
#include "BatchDis.h"
#include "BatchDisDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/
// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
public:
	CAboutDlg();

// Dialog Data
	//{{AFX_DATA(CAboutDlg)
	enum { IDD = IDD_ABOUTBOX };
	//}}AFX_DATA

	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CAboutDlg)
	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
	//}}AFX_VIRTUAL

// Implementation
protected:
	//{{AFX_MSG(CAboutDlg)
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
	//{{AFX_DATA_INIT(CAboutDlg)
	//}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CAboutDlg)
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
	//{{AFX_MSG_MAP(CAboutDlg)
		// No message handlers
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/
// CBatchDisDlg dialog

CBatchDisDlg::CBatchDisDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CBatchDisDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CBatchDisDlg)
		// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);

}

void CBatchDisDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CBatchDisDlg)
		// NOTE: the ClassWizard will add DDX and DDV calls here
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CBatchDisDlg, CDialog)
	//{{AFX_MSG_MAP(CBatchDisDlg)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_ADD_DATA, OnAddData)
	ON_BN_CLICKED(IDC_DATA_SHOW, OnDataShow)
	ON_WM_MOUSEMOVE()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/
// CBatchDisDlg message handlers

BOOL CBatchDisDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// Add "About..." menu item to system menu.

	// IDM_ABOUTBOX must be in the system command range.
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		CString strAboutMenu;
		strAboutMenu.LoadString(IDS_ABOUTBOX);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);// Set small icon
	this->SetWindowText(_T("主对话框"));
	GetDlgItem(IDC_DATA_SHOW)->EnableWindow(FALSE);
	// TODO: Add extra initialization here
	CShowDlg dlgshow;
	dlgshow.DoModal();
	return TRUE;  // return TRUE  unless you set the focus to a control
}

void CBatchDisDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialog::OnSysCommand(nID, lParam);
	}
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CBatchDisDlg::OnPaint() 
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{

		CDialog::OnPaint();
	}
}

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CBatchDisDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}

void CBatchDisDlg::OnAddData() 
{
	// TODO: Add your control notification handler code here
	if(dlg.DoModal() == IDOK)
	{
		GetDlgItem(IDC_DATA_SHOW)->EnableWindow(TRUE);
	}
}
void CBatchDisDlg::OnDataShow() 
{
	// TODO: Add your control notification handler code here
		CClientDC dc(this);
	//dc.Ellipse(CRect(100,100,200,200));
	//划y拱形线
		dc.MoveTo(65,55);
		dc.LineTo(70,50);
		dc.LineTo(75,55);
	//划xy轴
		dc.MoveTo(70,50);
		dc.LineTo(70,420);
		dc.LineTo(800,420);
	//画x拱形线
		dc.MoveTo(795,415);
		dc.LineTo(800,420);
		dc.LineTo(795,425);
	//画机器标线
		dc.MoveTo(70,330);
		dc.LineTo(76,330);
		dc.MoveTo(70,240);
		dc.LineTo(76,240);
		dc.MoveTo(70,150);
		dc.LineTo(76,150);
	//画机器坐标并且画出M0-7机器
		int zone= (420-50)/dlg.m_macCount;
		int halfzone=zone/2;
		UINT i;
		for(i=0;i<dlg.m_macCount;i++)
		{
			dc.MoveTo(70,420-halfzone-i*zone);
			dc.LineTo(76,420-halfzone-i*zone);
			CString tmp;
			tmp.Format("M%d",i+1);
			dc.TextOut(40,420-halfzone-i*zone-5,tmp);
		}
	//画x轴的标线
		dc.TextOut(60,430,"0");
		int o;
		for(o=1;o<=18;o++)
		{
			dc.MoveTo(70+o*40,420);
			dc.LineTo(70+o*40,415);
			CString tmp;
			tmp.Format("%d",o*40/2);
			dc.TextOut(70+o*40-10,430,tmp);
		}
	//这里有个问题:就是看CPen如何输出的笔画是矩形?
		LOGBRUSH m_logbrush;
		m_logbrush.lbColor = RGB(255,255,0);
		m_logbrush.lbHatch = HS_HORIZONTAL;
		m_logbrush.lbStyle = BS_SOLID;
		//CPen m_newPen(PS_GEOMETRIC|PS_ENDCAP_SQUARE|PS_JOIN_ROUND ,20,&m_logbrush);
		//CPen *oldPen=dc.SelectObject(&m_newPen);
		COLORREF color[3]={RGB(255,0,0),RGB(0,255,0),RGB(0,0,255)};
		CBrush brush;

	//	dc.MoveTo(80,420);
	//	dc.LineTo(100,420);	
	//	brush.CreateSolidBrush(RGB(255,0,0));
	//	dc.FillRect(CRect(70,420,110,440),&brush);

		UINT *time=new UINT[dlg.m_macCount];
		UINT *clor=new UINT[dlg.m_macCount];
		
		for(i=0;i<dlg.m_macCount;i++)
		{
			time[i]=0;
			clor[i]=0;
		}
		CMyList *mylist = new CMyList[dlg.m_macCount];
		m_vecTotalTrue.RemoveAll();
		for(o=0;o<dlg.m_vecTotalTrue.GetSize();o++)
		{
			m_vecTotalTrue.Add(dlg.m_vecTotalTrue[o]);
		}
		int m_count=m_vecTotalTrue.GetSize();
		//完成深拷贝
		for(o=0;o<m_vecTotalTrue.GetSize();o++)
		{
			m_vecTotalTrue[o].m_parent = FindParent(m_vecTotalTrue[o].m_parentName);
		//	m_vecTotalTrue[o].m_leftchild = FindLeftChild(m_vecTotalTrue[o].m_leftName);
		//	m_vecTotalTrue[o].m_rightchild = FindRightChild(m_vecTotalTrue[o].m_rightName);
		//	if(m_vecTotalTrue[o].m_leftchild ==NULL&&m_vecTotalTrue[o].m_rightchild == NULL)
			m_vecTotalTrue[o].m_childAddress.RemoveAll();
			for(int j=0;j<m_vecTotalTrue[o].m_child.GetSize();j++)
			{
				m_vecTotalTrue[o].m_childAddress.AddTail(FindLeftChild(m_vecTotalTrue[o].m_child[j]));
			}
			m_vecTotalTrue[o].childFinishTime = 0;
			m_vecTotalTrue[o].m_flags = TRUE;
		
		}
	//初始化各个链表

		InitialMylist(mylist);
	//进行处理,画出图像
		bool mhave;
		bool m_vechave;
		do
		{
			mhave =false;
			m_vechave = false;
			UINT minRange;
			for(i=1;i<=dlg.m_macCount;i++)
			{
				minRange=CompareTime(time,i);
				if(mylist[minRange].GetCount() != 0)
				{
					break;
				}
			}
			if(i==dlg.m_macCount+1)
			{
				MessageBox("所有链表全部为空");
				return ;
			}
			brush.CreateSolidBrush(color[clor[minRange]%3]);

			bool have =false;
			for(i=0;i<mylist[minRange].GetCount();i++)
			{
				if(time[minRange]>=mylist[minRange].GetAt(mylist[minRange].FindIndex(i)).childFinishTime)
				{
					have=true;
					break;
				}
			}
			if(have)
			{
				CRect rect=CRect(time[minRange]+70,420-halfzone-minRange*zone-10,time[minRange]\
					+70+mylist[minRange].GetAt(mylist[minRange].FindIndex(i)).m_usedtime*2,\
					420-halfzone-minRange*zone+10);
				dc.FillRect(rect,&brush);
				dc.TextOut(time[minRange]+70,420-halfzone-minRange*zone+10,\
					mylist[minRange].GetAt(mylist[minRange].FindIndex(i)).m_name);
				time[minRange]+=mylist[minRange].GetAt(mylist[minRange].FindIndex(i)).m_usedtime*2;
				if(mylist[minRange].GetAt(mylist[minRange].FindIndex(i)).m_parent != NULL)
				{
					if(mylist[minRange].GetAt(mylist[minRange].FindIndex(i)).m_parent->childFinishTime<time[minRange])
					{
						mylist[minRange].GetAt(mylist[minRange].FindIndex(i)).m_parent->childFinishTime=time[minRange];
					}
				}
				mylist[minRange].RemoveAt(mylist[minRange].FindIndex(i));
				InitialMylist(mylist);
			}
			else
			{
				UINT min;
				min=mylist[minRange].GetHead().childFinishTime;
				i=0;
				for(UINT pp=0;pp<mylist[minRange].GetCount();pp++)
				{
					if(min>mylist[minRange].GetAt(mylist[minRange].FindIndex(pp)).childFinishTime)
					{
						min=mylist[minRange].GetAt(mylist[minRange].FindIndex(pp)).childFinishTime;
						i=pp;
					}
				}
				dc.FillRect(CRect(min+70,420-halfzone-minRange*zone-10,min\
					+70+mylist[minRange].GetAt(mylist[minRange].FindIndex(i)).m_usedtime*2,\
					420-halfzone-minRange*zone+10),&brush);
				dc.TextOut(min+70,420-halfzone-minRange*zone+10,\
					mylist[minRange].GetAt(mylist[minRange].FindIndex(i)).m_name);
				time[minRange]=min+mylist[minRange].GetAt(mylist[minRange].FindIndex(i)).m_usedtime*2;
				if(mylist[minRange].GetAt(mylist[minRange].FindIndex(i)).m_parent != NULL)
				{
					mylist[minRange].GetAt(mylist[minRange].FindIndex(i)).m_parent->childFinishTime=time[minRange];
				}
				mylist[minRange].RemoveAt(mylist[minRange].FindIndex(i));
				InitialMylist(mylist);
			}
			clor[minRange]++;
			brush.Detach();
			for(i=0;i<dlg.m_macCount;i++)
			{
				if(mylist[i].GetCount()!=0)
				{
					mhave=true;
				}
			}
			for(i=0;i<m_vecTotalTrue.GetSize();i++)
			{
				if(m_vecTotalTrue.GetAt(i).m_flags == TRUE)
				{
					m_vechave=true;
				}
			}

		}while(m_vechave || mhave);
		delete [] time ;
		delete [] clor ;
		delete [] mylist ;
		m_vecTotalTrue.RemoveAll();
}
//找出第几xiao的数的索引?还未解决   
// 程序已经验证了,符合ok
UINT CBatchDisDlg::CompareTime(UINT *time,int parmMin)
{
	UINT maxNumber=0;
	UINT min=10000;
	CArray<UINT,UINT> tmp;
	BOOL judge=FALSE;
	for(int m=1;m<=parmMin;m++)
	{	
		min=10000;
		for(UINT i=0;i<dlg.m_macCount;i++)
		{
			judge = FALSE;
			for(int n=0;n<tmp.GetSize();n++)
			{
				if(i==tmp.GetAt(n))
				{
					judge = TRUE;
				}
			}
			if(judge)
				continue;
			if(min>time[i])
			{
				maxNumber=i;
				min=time[i];
			}
		}
		tmp.Add(maxNumber);
	}
	return tmp[parmMin-1];
}
//这个函数应该没问题
// this function is OK
//这个函数是为了把m_vecTotalTrue中的变量加入到mylist链表中(按增序)同时删除该元素在m_vecTotalTrue中的存在
void CBatchDisDlg::InitialMylist(CMyList *mylist)
{
	for(int i=0;i<m_vecTotalTrue.GetSize();i++)
	{
		bool child_check=false;
		int j=0;
		for(;j<m_vecTotalTrue[i].m_childAddress.GetCount();j++)
		{
			if(m_vecTotalTrue[i].m_childAddress.GetAt(m_vecTotalTrue[i].m_childAddress.FindIndex(j))!=NULL)
			{
				child_check=true;
				break;
			}
		}
		//if(m_vecTotalTrue[i].m_leftchild ==NULL&&m_vecTotalTrue[i].m_rightchild == NULL&&m_vecTotalTrue[i].m_flags)
		if(!child_check && m_vecTotalTrue[i].m_flags)
		{
			ListStructTrue tmp(m_vecTotalTrue[i]);
			//这里处理不当
			//tmp.childFinishTime = 0;
			POSITION pt;
			bool mparent=false;
			//这里是处理当第一次初始化链表的时候,而且mylist中的数据还没处理完所以判断是否子节点完成
			//如果没有完成则该父节点不加入链表即:continue
			//(因为mylist并没有进行深拷贝,所以这种地址操作是可以的)
			for(int j=0;j<dlg.m_macCount;j++)
			{
				for(int q=0;q<mylist[j].GetCount();q++)
				{
					if(mylist[j].GetAt(mylist[j].FindIndex(q)).m_parent == &m_vecTotalTrue[i])
					{
						mparent=true;
					}
				}
			}
			if(mparent)
			{
				continue;
			}
			if(m_vecTotalTrue[i].m_parent != NULL)
			{
/*				if(m_vecTotalTrue[i].m_parent->m_leftchild == &m_vecTotalTrue[i])
				{
					m_vecTotalTrue[i].m_parent->m_leftchild =NULL;
				}
				else
				{
					m_vecTotalTrue[i].m_parent->m_rightchild =NULL;
				}
*/
				for(j=0;j<m_vecTotalTrue[i].m_parent->m_childAddress.GetCount();j++)
				{
					if(m_vecTotalTrue[i].m_parent->m_childAddress.GetAt(\
						m_vecTotalTrue[i].m_parent->m_childAddress.FindIndex(j)) == &m_vecTotalTrue[i])
					{
						m_vecTotalTrue[i].m_parent->m_childAddress.SetAt(\
						m_vecTotalTrue[i].m_parent->m_childAddress.FindIndex(j),NULL);
						break;
					}
				}
			}
		//	m_vecTotalTrue.RemoveAt(i);
		//	i--;
			m_vecTotalTrue[i].m_flags =FALSE;
			if(mylist[tmp.m_machine].GetCount() == 0)
			{
				mylist[tmp.m_machine].AddHead(tmp);
				//continue;
			}
			else
			{
				pt=mylist[tmp.m_machine].GetHeadPosition();
				for(int p=0; p<mylist[tmp.m_machine].GetCount();p++)
				{
					if(tmp.m_usedtime < mylist[tmp.m_machine].GetAt(pt).m_usedtime)
					{
						mylist[tmp.m_machine].InsertBefore(pt,tmp);
						break;
					}
					mylist[tmp.m_machine].GetNext(pt);
				}
				if(p == mylist[tmp.m_machine].GetCount())
				{
					mylist[tmp.m_machine].AddTail(tmp);
				}
			}
		}
	}
}
//this function is OK
//confirm
//查找name所代表的父节点
ListStructTrue * CBatchDisDlg::FindParent(CString name)
{

	if(name !="")
	{
		for(int i=0; i < m_vecTotalTrue.GetSize(); i++)
		{
			if(m_vecTotalTrue[i].m_name == name)
			{
			 return &m_vecTotalTrue[i];	
			}
		}
	}
	return NULL;
}

//this function is OK
//confirm
//查找name所代表的昨孩子
ListStructTrue * CBatchDisDlg::FindLeftChild(CString name)
{
	if(name != "")
	{
		for(int i=0; i < m_vecTotalTrue.GetSize(); i++)
		{
			if(m_vecTotalTrue[i].m_name== name )
			{
				return  &m_vecTotalTrue[i];	
			}
		}
	}
	return NULL;
}
//this function is OK
//confirm
//查找name所代表的右孩子
ListStructTrue* CBatchDisDlg::FindRightChild(CString name)
{
	if(name != "")
	{
		for(int i=0; i < m_vecTotalTrue.GetSize(); i++)
		{
			if(m_vecTotalTrue[i].m_name == name)
			{
				return &m_vecTotalTrue[i];
			}
		}
	}
	return NULL;
}

void CBatchDisDlg::OnMouseMove(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	CFont font;
	CClientDC dc(GetDlgItem(IDC_ZUOBIAO));
	font.CreateFont(10,10,0,0,FW_NORMAL,false,false,false,
	CHINESEBIG5_CHARSET,OUT_CHARACTER_PRECIS,
	CLIP_CHARACTER_PRECIS,DEFAULT_QUALITY,
	FF_MODERN,"黑体");
	dc.SelectObject(&font);
	CPen pen(PS_SOLID,1,RGB(255,0,0));
//	dc.SetBkMode(TRANSPARENT);
	dc.SelectObject(&pen);
	CString str="";
	str.Format("x=%d,y=%d",(point.x-70)/2,420-point.y);
	dc.SetTextColor(RGB(255,0,0));
	dc.TextOut(2,2,str);
	CDialog::OnMouseMove(nFlags, point);
}

// DataDlg.cpp : implementation file
//

#include "stdafx.h"
#include "BatchDis.h"
#include "DataDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/
// CDataDlg dialog


CDataDlg::CDataDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CDataDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CDataDlg)
	m_macCount = 0;
	//}}AFX_DATA_INIT
	m_vecTmp.RemoveAll();
	m_vecTotal.RemoveAll();
	m_hIcon=(HICON)LoadImage(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDI_ICON1),IMAGE_ICON,0,0,LR_DEFAULTSIZE);
	m_images.Create(32,32,ILC_COLOR32,1,1);
	m_images.Add(m_hIcon);
}


void CDataDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CDataDlg)
	DDX_Control(pDX, IDC_LIST1, m_list);
	DDX_Text(pDX, IDC_MAC_COUNT, m_macCount);
	DDV_MinMaxUInt(pDX, m_macCount, 1, 8);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CDataDlg, CDialog)
	//{{AFX_MSG_MAP(CDataDlg)
	ON_BN_CLICKED(IDC_ADD, OnAdd)
	ON_BN_CLICKED(IDC_CANCLE, OnCancle)
	ON_BN_CLICKED(IDC_DELETE, OnDelete)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/
// CDataDlg message handlers

void CDataDlg::OnAdd() 
{
	// TODO: Add your control notification handler code here
	int nCount = m_list.GetItemCount();
	ListStruct m_lineTmp;
	CInsertDlg dlg;
	if(dlg.DoModal() == IDOK)
	{	CString m_tmp;
		m_lineTmp.m_name = dlg.m_name;
		m_lineTmp.m_parent = dlg.m_parent;
		//m_lineTmp.m_leftchild = dlg.m_leftchild;
		//m_lineTmp.m_rightchild = dlg.m_rightchild;
		m_tmp=dlg.m_child;
		m_tmp.Replace('@',' ');
		m_lineTmp.m_child = m_tmp;
		m_lineTmp.m_usedtime = dlg.m_usedtime;
		m_lineTmp.m_machine = dlg.m_machine;
	
		m_list.InsertItem(nCount,m_lineTmp.m_name);
		m_list.SetItemText(nCount,1,m_lineTmp.m_parent);
		m_list.SetItemText(nCount,2,m_lineTmp.m_child);
	//	m_list.SetItemText(nCount,3,m_lineTmp.m_rightchild);
		m_tmp="";
		m_tmp.Format("%d",dlg.m_usedtime);
		m_list.SetItemText(nCount,3,m_tmp);
		m_tmp="";
		m_tmp.Format("%d",m_lineTmp.m_machine);
		m_list.SetItemText(nCount,4,m_tmp);
		m_vecTmp.Add(m_lineTmp);
	}
}

BOOL CDataDlg::OnInitDialog() 
{
	CDialog::OnInitDialog();
	this->SetWindowText(_T("插入数据对话框"));
	// TODO: Add extra initialization here
		if(m_list.InsertColumn(0,_T("工序名"),LVCFMT_LEFT,100)==-1)
	{
		MessageBox("插入失败");
	}
	
	m_list.InsertColumn(1,_T("父节点"),LVCFMT_LEFT,100);
	m_list.InsertColumn(2,_T("儿子节点"),LVCFMT_LEFT,200);
//	m_list.InsertColumn(3,_T("右子节点"),LVCFMT_LEFT,100);
	m_list.InsertColumn(3,_T("所用时间"),LVCFMT_LEFT,100);
	m_list.InsertColumn(4,_T("所用机器"),LVCFMT_LEFT,100);
	int nCount = m_list.GetItemCount();
	for(int i=0;i<m_vecTotal.GetSize();i++)
	{
		m_list.InsertItem(nCount,m_vecTotal.GetAt(i).m_name);
		m_list.SetItemText(nCount,1,m_vecTotal.GetAt(i).m_parent);
		m_list.SetItemText(nCount,2,m_vecTotal.GetAt(i).m_child);
	//	m_list.SetItemText(nCount,3,m_vecTotal.GetAt(i).m_rightchild);
		CString m_tmp;
		m_tmp.Format("%d",m_vecTotal.GetAt(i).m_usedtime);
		m_list.SetItemText(nCount,3,m_tmp);
		m_tmp="";
		m_tmp.Format("%d",m_vecTotal.GetAt(i).m_machine);
		m_list.SetItemText(nCount,4,m_tmp);
		nCount++;
	}


	m_list.SetImageList(&m_images,LVSIL_SMALL);
	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}

void CDataDlg::OnDataSave2() 
{
	// TODO: Add your control notification handler code here
	for(int m=0;m<m_vecTmp.GetSize();m++)
	{
		m_vecTotal.Add(m_vecTmp.GetAt(m));

	}
	
	m_vecTmp.RemoveAll();
	this->DestroyWindow();
}

void CDataDlg::OnCancle() 
{
	// TODO: Add your control notification handler code here
	EndDialog(IDCANCEL);
}

void CDataDlg::OnOK() 
{
	// TODO: Add extra validation here
	ListStructTrue tmp;
	for(int m=0;m<m_vecTmp.GetSize();m++)
	{
		m_vecTotal.Add(m_vecTmp.GetAt(m));
		tmp.m_flags = FALSE;
		tmp.m_name =m_vecTmp[m].m_name;
		tmp.m_usedtime =m_vecTmp[m].m_usedtime;
		tmp.m_machine = m_vecTmp[m].m_machine-1;
		tmp.m_parent = NULL;
		tmp.m_parentName =m_vecTmp[m].m_parent;
	//	tmp.m_leftchild =NULL;
	//	tmp.m_rightchild =NULL;
	//	tmp.m_leftName=m_vecTmp[m].m_leftchild;
	//	tmp.m_rightName =m_vecTmp[m].m_rightchild;
		CString str=m_vecTmp[m].m_child;
		str.TrimLeft();
		str.TrimRight();
		tmp.m_child.RemoveAll();
		if(str=="")
		{
			tmp.m_child.RemoveAll();
		}else
		{
			do
			{	
				CString stradd=SplitCString(str,' ');
				if(stradd == "")
				{
					break;
				}
				tmp.m_child.Add(stradd);
			}while(str.Find(' ')!=-1);
			tmp.m_child.Add(str);

		}
		m_vecTotalTrue.Add(tmp);
	}

	for(int i=0;i<m_vecTotalTrue.GetSize();i++)
	{
		m_vecTotalTrue[i].m_parent = FindParent(m_vecTotalTrue[i].m_parentName);
		//m_vecTotalTrue[i].m_leftchild = FindLeftChild(m_vecTotalTrue[i].m_leftName);
		//m_vecTotalTrue[i].m_rightchild = FindRightChild(m_vecTotalTrue[i].m_rightName);
		for(int j=0;j<m_vecTotalTrue[i].m_child.GetSize();j++)
		{
			ListStructTrue *tmp=FindLeftChild(m_vecTotalTrue[i].m_child[j]);
			m_vecTotalTrue[i].m_childAddress.AddTail(tmp);
		}
		int test1=m_vecTotalTrue[i].m_childAddress.GetCount();
	}
	int test= m_vecTotal.GetSize();
	//验证数据输入的是否正确,算法是遍历整个树,遍历时候记得吧m_flag标志设置一下,最后遍历CArray数组这样
	//看看是否所有数据是否设置了,如果有没有设置的说明输入的数据是不能组成一棵树的
	if(m_vecTotalTrue.GetSize()!=0)
	{
		TravelTree(&m_vecTotalTrue[0]);
	}
	for(int n=0;n<m_vecTotalTrue.GetSize();n++)
	{
		if(m_vecTotalTrue[n].m_flags == FALSE)
		{
			CString err;
			err.Format("该节点%s(第%d行)未被遍历到,请查看输入是否有问题",m_vecTotalTrue[n].m_name.GetBuffer(0),n+1);
			for(int q=1;q<=m_vecTmp.GetSize();q++)
			{
				int r=m_vecTotalTrue.GetSize()-1;
				m_vecTotalTrue.RemoveAt(r);
				r=m_vecTotal.GetSize()-1;
				m_vecTotal.RemoveAt(r);
			}
			MessageBox(err);
			return ;
		}
		if(m_vecTotalTrue[n].m_parent == NULL && n != 0)
		{
			CString err;
			err.Format("该节点%s(第%d行)的父节点不能为空,请查看是否有问题",m_vecTotalTrue[n].m_name.GetBuffer(0),n+1);
			MessageBox(err);
			return ;
		}
	}
	m_vecTmp.RemoveAll();
	CDialog::OnOK();
}

void CDataDlg::OnDelete() 
{
	// TODO: Add your control notification handler code here
	int nCount =m_list.GetItemCount()-1;
	for(int i=nCount;i>=0;i--)
	{
		if(m_list.GetItemState(i,LVIS_SELECTED) == LVIS_SELECTED)
		{
			m_list.DeleteItem(i);
			if(i<=(m_vecTotal.GetSize()-1))
			{
				m_vecTotal.RemoveAt(i);
				m_vecTotalTrue.RemoveAt(i);
			}
			else
			{
				int test= m_vecTmp.GetSize();
				test= i-m_vecTotal.GetSize();
				m_vecTmp.RemoveAt(test);
			}
		}
	}
}

void CDataDlg::TravelTree( ListStructTrue *root)
{
	//注释是2叉遍历
//	if(root)
//	{
//		root->m_flags=TRUE;
//		
//		TravelTree(root->m_leftchild);
//		TravelTree(root->m_rightchild);
//	}
	//遍历n叉树
/*	queue<TreeNode*> queue ;
  queue.push((TreeNode*)this);
  TreeNode *p = NULL;
  while (!queue.empty())
  {
  p = queue.front();
  queue.pop();
  cout<<"treenode is: "<<p->getSelfId()<<endl;
  if (NULL!= p->getChildList())
  {
  list<TreeNode*>::iterator it = (p->getChildList())->begin();
  while(it!= (p->getChildList())->end())
  {
  queue.push((*it));
  ++it;
  }
  }
  }
*/
	CList<ListStructTrue*,ListStructTrue*> Travel;
	Travel.AddHead(root);
	ListStructTrue* p=NULL;
	while(Travel.GetCount())
	{
		p=Travel.GetHead();
	
		p->m_flags=TRUE;
		if(p->m_childAddress.GetCount())
		{
			for(int i=0;i<(p->m_childAddress.GetCount());i++)
			{
				Travel.AddTail(p->m_childAddress.GetAt(p->m_childAddress.FindIndex(i)));
			}
		}
			Travel.RemoveHead();
	}
}

ListStructTrue * CDataDlg::FindParent(CString name)
{
	if(name !="")
	{
		for(int i=0; i < m_vecTotalTrue.GetSize(); i++)
		{
			if(m_vecTotalTrue[i].m_name == name)
			{
			 return &m_vecTotalTrue[i];	
			}
		}
		MessageBox("父节点:%s 未找到,请查看某节点的父节点输入是否正确",name);
	}

	return NULL;
}

ListStructTrue * CDataDlg::FindLeftChild(CString name)
{	
	if(name != "")
	{
		for(int i=0; i < m_vecTotalTrue.GetSize(); i++)
		{
			if(m_vecTotalTrue[i].m_name== name )
			{
				return  &m_vecTotalTrue[i];	
			}
		}
		MessageBox("子节点:%s 未找到,请查看某节点的自节点是否正确",name);
	}
	return NULL;
}

ListStructTrue * CDataDlg::FindRightChild(CString name)
{	
	if(name != "")
	{
		for(int i=0; i < m_vecTotalTrue.GetSize(); i++)
		{
			if(m_vecTotalTrue[i].m_name == name)
			{
				return &m_vecTotalTrue[i];
			}
		}
	}
	return NULL;
}

CString CDataDlg::SplitCString(CString &str, char split_char)
{
	str.TrimLeft();
	str.TrimRight();
	int index=str.Find(split_char);
	if(index==-1)
	{
		return "";
	}
	else
	{
		
		CString tmp= str.Left(index);
		str=str.Right(str.GetLength()-index);
		return tmp;
	}
}

// InsertDlg.cpp : implementation file
//

#include "stdafx.h"
#include "BatchDis.h"
#include "InsertDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/
// CInsertDlg dialog


CInsertDlg::CInsertDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CInsertDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CInsertDlg)
	m_name = _T("");
	m_parent = _T("");
	m_usedtime = 0;
	m_machine = 0;
	m_child = _T("");
	//}}AFX_DATA_INIT
}


void CInsertDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CInsertDlg)
	DDX_Text(pDX, IDC_EDIT1, m_name);
	DDX_Text(pDX, IDC_EDIT2, m_parent);
	DDX_Text(pDX, IDC_EDIT5, m_usedtime);
	DDX_Text(pDX, IDC_EDIT6, m_machine);
	DDV_MinMaxUInt(pDX, m_machine, 1, 8);
	DDX_Text(pDX, IDC_EDIT3, m_child);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CInsertDlg, CDialog)
	//{{AFX_MSG_MAP(CInsertDlg)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/
// CInsertDlg message handlers

void CInsertDlg::OnOK() 
{
	// TODO: Add extra validation here
	CString name;
	CString usedtime;
	CString machine;
	this->GetDlgItem(IDC_EDIT1)->GetWindowText(name);
	this->GetDlgItem(IDC_EDIT5)->GetWindowText(usedtime);
	this->GetDlgItem(IDC_EDIT6)->GetWindowText(machine);
	if(name.IsEmpty())
	{
		MessageBox("工序名称不能为空");
		return;
	}
	if(usedtime=="0")
	{
		MessageBox("所用时间不能为0");
		return;
	}
	if(!machine)
	{
		MessageBox("所使用的机器编号不能为0");
		return;
	}
	CDialog::OnOK();
}

BOOL CInsertDlg::OnInitDialog() 
{
	CDialog::OnInitDialog();
	
	// TODO: Add extra initialization here
	this->SetWindowText(_T("插入一条数据"));
	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}

// ShowDlg.cpp : implementation file
//

#include "stdafx.h"
#include "BatchDis.h"
#include "ShowDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/
// CShowDlg dialog


CShowDlg::CShowDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CShowDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CShowDlg)
		// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT
}


void CShowDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CShowDlg)
		// NOTE: the ClassWizard will add DDX and DDV calls here
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CShowDlg, CDialog)
	//{{AFX_MSG_MAP(CShowDlg)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/
// CShowDlg message handlers

BOOL CShowDlg::OnInitDialog() 
{
	CDialog::OnInitDialog();
	
	// TODO: Add extra initialization here
	this->SetWindowText(_T("软件使用说明"));
	GetDlgItem(IDC_EDIT2)->SetWindowText("		  软件说明				\n 软件仅仅支持二叉树,即:加工树的度最多为2 。数据\n       输入后进行树的遍历,可以对用户输入的数据进行验证\n\n      软件所用算法:\n					  把加工树的叶子节点截取下来,根据该节点所用机器编号加入到相对应的链表中,之后再遍历所用的链表时间,看哪个时间最短,之后处理时间最短的链表中数据,如果链表中没数据的话,就在比较时间找第二小的,以此类推,进行处理,直到链表和树中的数据处理完之后,进行算法演示");
	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}
皮肤文件

#ifndef _SKINPPWTL_H_
#define _SKINPPWTL_H_

#ifdef _SKINPP_STATIC
	#define SKINPPWTL_API
#else
	#ifdef SKINPPWTL_EXPORTS
		#define SKINPPWTL_API __declspec(dllexport)
	#else
		#define SKINPPWTL_API __declspec(dllimport)
	#endif
#endif

#define WM_TOOLBARPAINTPRE (WM_USER + 802)
#define WM_TOOLBARPAINTEND (WM_USER + 803)

#define SM_LBUTTONUP (WM_USER + 804)

//按钮状态
enum BUTTONSTATE 
{
	NORMAL	= 0,
	PRESS	= 1,
	DISABLE	= 2,
	HOT		= 3,
	FOCUS   = 4,
	LAST	= 5
};

//绘制类型
enum DRAWTYPE
{
	BUTTON = 0,
	SCROLLARROWUP = 1,
	SCROLLARROWDOWN = 2,
	SPLITTERBARHORZ = 3,
	SPLITTERBARVERT = 4,
	SPLITTERBARBORDER = 5,
	LISTHEAD = 6
};

//获得皮肤资源的类型
enum SKINOBJTYPE
{
	DIALOGTYPE = 0,
	BUTTONTYPE = 1,
	CHECKBOXTYPE = 2,
	RADIOBOXTYPE = 3,
	STATICTYPE = 4,
	TRACKBARTYPE = 5,
};

struct ListBoxItem
{
	HIMAGELIST	hImageList;
	int			nImageIndex;

	ListBoxItem()
	{
		hImageList = NULL;
		nImageIndex = -1;
	}
};

#define REST_BITMAP      0x0001 //.bmp
#define REST_ICON        0x0002 //.ico
#define REST_CURSOR      0x0003 //.cur
#define REST_ANIMATE	 0x0004 //.ani

typedef struct _ResourceInfo
{
	HGDIOBJ hGdiObj;//[OUT]
	DWORD   dwType; //[OUT]
	int		nWidth; //[OUT]
	int		nHeight;//[OUT]

	TCHAR	szResImageName[_MAX_FNAME];//[IN]
	BOOL	bHorzSplit;//[IN]
	int		nLength;//[IN]
	int		nCount; //[IN]
	int		nIndex; //[IN]
	
	_ResourceInfo()
	{
		hGdiObj = NULL;
		dwType = REST_BITMAP;
		nWidth = 0;
		nHeight = 0;

		_tcscpy(szResImageName,_T(""));
		bHorzSplit = TRUE;
		nLength = -1;
		nCount = -1;
		nIndex = -1;
	}
	
}ResInfo,* PRESINFO;

//

//加载皮肤
//SkinFile		:皮肤路径,注意可以是*.ssk,也可以是皮肤目录中的INI文件.
//bFromIni		:该参数指定皮肤文件是从*.ssk读取,还是从INI文件读取.
SKINPPWTL_API BOOL  skinppLoadSkin(TCHAR* szSkinFile,BOOL bFromIni = FALSE);

SKINPPWTL_API BOOL skinppLoadSkinFromRes(HINSTANCE hInstance,LPCTSTR szResourceName,
										 LPCTSTR szResourceType,TCHAR* szSkinFileName);

//移除皮肤
SKINPPWTL_API BOOL  skinppRemoveSkin();

//退出界面库,做清理工作。
SKINPPWTL_API BOOL  skinppExitSkin();

//设置ListBox控件的自画信息
//hWnd			: ListBox控件的句柄
//nIndex		: Item项的索引
//pListBoxItem	: Item项自画的结构信息
SKINPPWTL_API void skinppSetListBoxItemDrawInfo(HWND hWnd,int nIndex,struct ListBoxItem* pListBoxItem);

//获得换肤后的系统颜色
//nColorIndex	: 要获取的颜色类型
SKINPPWTL_API COLORREF skinppGetSkinSysColor(int nColorIndex);

//获得Windows系统默认的颜色
//nColorIndex	: 要获取的颜色类型
SKINPPWTL_API COLORREF skinppGetDefaultSysColor(int nColorIndex);

//hWnd			: 对话框窗口的句柄
//nResID		: 对话框资源ID
SKINPPWTL_API BOOL skinppSetWindowResID(HWND hWnd,int nResID);//[多语言]

SKINPPWTL_API BOOL skinppSetFreeDlgID(HWND hWnd,int nResID);

SKINPPWTL_API BOOL skinppSetSkinResID(HWND hWnd,int nResID);

//设置ListHeader窗口的排序信息
//hWnd			: ListHeader的窗口句柄
//nSortColumn	: 要对ListHeader排序的列的索引
//bSortAscending: 是否为升序
SKINPPWTL_API void skinppSetListHeaderSortInfo(HWND hWnd,int nSortColumn,BOOL bSortAscending = TRUE);

//在给定的HDC上,指定相应的绘制类型和状态,在相应的矩形区域中进行绘制.
//hdc			:目标DC
//rect			:绘制区域
//eDrawType		:绘制类型,目前支持SPLITTERBARHORZ,SPLITTERBARVERT,SPLITTERBARBORDER
//nState		:选择绘制状态
SKINPPWTL_API void  skinppDrawSkinObject(HDC hdc,RECT rect,DRAWTYPE eDrawType,int nState);

//通过资源ID,获得相应类型的皮肤资源位图句柄
//nSkinObjType	: 皮肤类型,目前支持	DIALOGTYPE,BUTTONTYPE,CHECKBOXTYPE,RADIOBOXTYPE
//nResID		: 资源ID
//nState		: 状态,对BUTTONTYPE,CHECKBOXTYPE,RADIOBOXTYPE有效
SKINPPWTL_API HBITMAP skinppGetResFromID(SKINOBJTYPE nSkinObjType,int nResID,int nState =0 );

//设置是否自己画对话框背景,该方法用在需要自己对背景进行处理的情况下.
//hWnd			: 对话框的句柄
//bErase		: TRUE 为自己画背景,FALSE 为Skin++画,如果没有调用该方法,Skin++将画对话框背景.
SKINPPWTL_API void skinppSetDialogEraseBkgnd(HWND hWnd,BOOL bErase);

//设置对话框背景是否剪切子控件区域。
//hWnd			: 对话框句柄
//bNoClip		: TRUE为不需要剪切,FALSE为需要剪切区域
//bAllChild		: TRUE为该窗体的所有子对话框都剪切.
SKINPPWTL_API void skinppSetDialogBkClipRgn(HWND hWnd,BOOL bClip,BOOL bAllChild = TRUE);

//通过皮肤资源名称获得皮肤资源中位图
//szName		: 皮肤资源名称
//HBITMAP		: 返回资源中的位图
SKINPPWTL_API HBITMAP skinppGetBitmapRes(LPCTSTR szName);

//通过资源名称取资源的内存指针
//szName		: 资源名称
//nSize			: 资源大小
//pByte			: 返回值,成功返回非NULL,失败返回NULL
SKINPPWTL_API BYTE*  skinppGetSkinResource(LPCTSTR szName,int& nSize);

//通过皮肤资源的名称获得位图不被拉伸的区域值
//szName		: 皮肤资源名称
//nTopHeight	: 返回不被拉伸的顶高
//nBottomHeight : 返回不被拉伸的底高
//nLeftWidth	: 返回不被拉伸的左宽
//nRightWidth	: 返回不被拉伸的右宽
SKINPPWTL_API BOOL skinppGetBitmapResRect(LPCTSTR szName,int& nTopHeight,int& nBottomHeight,
												   int& nLeftWidth,int& nRightWidth);

//设置窗口自画是否自己来处理,该方法用于自画部分需要自己处理的情况下
//hWnd			: 要自画的窗口句柄
//bCustomDraw	: TRUE为自己处理自画,FALSE为交给Skin++处理自画
SKINPPWTL_API void skinppSetCustomDraw(HWND hWnd,BOOL bCustomDraw);

//设置菜单的皮肤标识
//hWnd			: 拥有菜单的窗口句柄
//nSkinObjectID	: 菜单皮肤的标识
SKINPPWTL_API void skinppSetMenuSkinObjectID(HWND hWnd,int nSkinObjectID);

//设置是否对自画菜单进行换肤
//bSkin			: TRUE为换肤
SKINPPWTL_API void skinppSetSkinOwnerMenu(BOOL bSkin);

//对菜单进行换肤控制
//hMenu   : 想换肤的菜单句柄
//bNoSkin : 是否换肤,TRUE为不换肤,FALSE为换肤
SKINPPWTL_API void  skinppSetDrawMenu(HMENU hMenu,BOOL bNoSkin);
	
//对指定的窗口去掉皮肤,并且保证不会再被换肤,即使使用SetSkinHwnd也不会换肤.
//hWnd			: 指定的窗口句柄
//bChildNoSkin	: 是否对该窗口中的子窗口去掉皮肤
SKINPPWTL_API void skinppSetNoSkinHwnd(HWND hWnd,BOOL bChildNoSkin = TRUE);

//对指定的窗口进行换肤
//hWnd			: 指定的窗口句柄
//szClassName	: 要子类化的Skin类型 WC_DIALOGBOX/WC_CONTROLBAR等
SKINPPWTL_API void skinppSetSkinHwnd(HWND hWnd,LPCTSTR szClassName = NULL);

//对指定的窗口临时去掉皮肤,可以通过SetSkinHwnd进行再次换肤
SKINPPWTL_API void skinppRemoveSkinHwnd(HWND hWnd);

//是对SetNoSkinHwnd的进一步处理,可以解决使用SetNoSkinHwnd引起的Debug版的断言错
#define SETNOSKINHWND(x) {\
    HWND w=(x).UnsubclassWindow();\
	skinppSetNoSkinHwnd(w);\
	(x).SubclassWindow(w);\
} 

//是对RemoveSkinHwnd的进一步处理,可以解决使用RemoveSkinHwnd引起的Debug版的断言错
#define REMOVESKINHWND(x){\
    HWND w=(x).UnsubclassWindow();\
	skinppRemoveSkinHwnd(w);\
	(x).SubclassWindow(w);\
}

SKINPPWTL_API HGDIOBJ skinppGetResFromID(PRESINFO pResInfo);


#endif //_SKINPPWTL_H_




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值