www.pudn.com > MathHead > MathHead.cpp


// MathHead.cpp : Defines the entry point for the application. 
// 
 
#include "stdafx.h" 
#include "MathHead.h" 
#include "MathSys.h" 
 
// Define 
 
#define UWM_PARSE	WM_USER + 0 
 
 
// Prototypes 
LRESULT WINAPI WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); 
 
WCHAR szMainTitle[]	= L"MathHead"; 
 
WCHAR szWndClass[]	= L"MathHead.Window"; 
WCHAR szDBarClass[]	= L"MathHead.DialogBar"; 
 
 
HINSTANCE	g_hInst; 
HWND		g_hWnd; 
 
int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE, LPSTR lpCmdLine, int nCmdShow) 
{ 
	g_hInst = hInstance; 
 
	// Register the Window 
	WNDCLASSEX wcx; 
 
	wcx.cbSize			= sizeof WNDCLASSEX; 
	wcx.cbClsExtra		= 0; 
	wcx.cbWndExtra		= 0; 
	wcx.lpszClassName	= szWndClass; 
	wcx.lpfnWndProc		= WndProc; 
	wcx.hInstance		= hInstance; 
	wcx.hIcon			= LoadIcon(hInstance, MAKEINTRESOURCE(IDI_MATHHEAD)); 
	wcx.hIconSm			= LoadIcon(hInstance, MAKEINTRESOURCE(IDI_SMALL)); 
	wcx.hCursor			= LoadCursor(NULL, MAKEINTRESOURCE(IDC_ARROW)); 
	wcx.style			= 0; 
	wcx.lpszMenuName	= MAKEINTRESOURCE(ID_MENU); 
	wcx.hbrBackground	= (HBRUSH)(COLOR_WINDOW+1); 
	 
	RegisterClassEx(&wcx); 
 
	g_hWnd = CreateWindowEx(0, szWndClass, szMainTitle, WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,  
							CW_USEDEFAULT, CW_USEDEFAULT, 600, 450, NULL, NULL, hInstance, 0); 
	ShowWindow(g_hWnd, SW_SHOW); 
	UpdateWindow(g_hWnd); 
 
 
	// Message Loop... 
 
	MSG msg; 
 
	while (GetMessage(&msg, NULL, 0, 0))  
	{ 
		TranslateMessage(&msg); 
		DispatchMessage(&msg); 
	} 
 
	return 0; 
} 
 
BOOL	WINAPI AboutProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 
{ 
	switch(uMsg) 
	{ 
	case WM_COMMAND: 
		switch(LOWORD(wParam)) 
		{ 
		case IDOK: 
			EndDialog(hWnd, IDOK); 
			return TRUE; 
		} 
		break;		 
	} 
	return FALSE; 
} 
 
 
BOOL	WINAPI DialogBarProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 
{ 
	WCHAR wBuffer[512]; 
 
	switch(uMsg) 
	{ 
	case WM_INITDIALOG: 
		SendMessage(GetDlgItem(hWnd, IDC_EXPR_TEXT), EM_LIMITTEXT, MATHSYS__MAX_TOKEN_BUFFER-1, 0); 
		return TRUE; 
 
	case WM_COMMAND: 
		switch(LOWORD(wParam)) 
		{ 
		case IDC_PARSE: 
 
			GetDlgItemText(hWnd, IDC_EXPR_TEXT, wBuffer, 512); 
			EnableWindow(GetDlgItem(hWnd, IDC_PARSE), FALSE); 
			SendMessage(g_hWnd, UWM_PARSE, (WPARAM)wBuffer, 0); 
			EnableWindow(GetDlgItem(hWnd, IDC_PARSE), TRUE); 
			return TRUE; 
		} 
		break; 
	} 
	return FALSE; 
} 
 
void GetNodeDescription(CMathNode* pNode, WCHAR * wBuffer) 
{ 
	switch(pNode->m_Type) 
	{ 
	case CMathNode::Node_Null: 
		wsprintf(wBuffer, L"NULL"); 
		break; 
	case CMathNode::Node_Exact: 
		wsprintf(wBuffer, L"Exact Value: %li", pNode->m_Exact); 
		break; 
	case CMathNode::Node_Approx: 
		// Do a little bit more work 
		{ 
 
			char	cValBuffer[100]; 
			wchar_t wValBuffer[100]; 
			_gcvt(pNode->m_Approx, 20, cValBuffer); 
			mbstowcs(wValBuffer, cValBuffer, 99); 
			wsprintf(wBuffer, L"Approximate Value: %ls", wValBuffer); 
		} 
		break; 
	case CMathNode::Node_Var: 
		wsprintf(wBuffer, L"Variable: %c", pNode->m_Var); 
		break; 
	case CMathNode::Node_Op: 
		switch(pNode->m_Op) 
		{ 
		case CMathNode::Op_Null: 
			wsprintf(wBuffer, L"Operation: Null"); 
			break; 
		case CMathNode::Op_Add: 
			wsprintf(wBuffer, L"Operation: Addition"); 
			break; 
		case CMathNode::Op_Sub: 
			wsprintf(wBuffer, L"Operation: Subtraction"); 
			break; 
		case CMathNode::Op_Mul: 
			wsprintf(wBuffer, L"Operation: Multiplication"); 
			break; 
		case CMathNode::Op_Div: 
			wsprintf(wBuffer, L"Operation: Division"); 
			break; 
		case CMathNode::Op_Exp: 
			wsprintf(wBuffer, L"Operation: Exponentiation"); 
			break; 
 
// DEBUG 
		case CMathNode::Op_ParOpen: 
			wsprintf(wBuffer, L"Parentheses: Open"); 
			break; 
		case CMathNode::Op_ParClose: 
			wsprintf(wBuffer, L"Parentheses: Close"); 
			break; 
 
		} 
		break; 
	default: 
		wsprintf(wBuffer, L"[Error]"); 
	} 
} 
 
void AddTreeNode(HWND hTree, CMathNode * pTree, HTREEITEM hParentItem) 
{ 
 
	WCHAR wBuffer[128]; 
 
    GetNodeDescription(pTree, wBuffer); 
	 
	TVINSERTSTRUCT tvi; 
 
	tvi.hParent = hParentItem; 
	tvi.hInsertAfter = TVI_LAST; 
	tvi.itemex.mask = TVIF_TEXT; 
	tvi.itemex.pszText = wBuffer; 
 
	if (pTree->m_Type != CMathNode::Node_Op) 
	{ 
		// No subnodes 
		TreeView_InsertItem(hTree, &tvi); 
	} 
	else 
	{ 
		tvi.itemex.mask |= TVIF_CHILDREN; 
		tvi.itemex.cChildren = 1; 
		 
		HTREEITEM hItem = TreeView_InsertItem(hTree, &tvi); 
 
		for (unsigned int i = 0; i < pTree->m_nSubs; i++) 
			AddTreeNode(hTree, &pTree->m_pSubArray[i], hItem); 
	} 
} 
 
LRESULT WINAPI WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 
{ 
	static HWND	hTree		= NULL; 
	static HWND hDialogBar	= NULL; 
 
	static WCHAR szNoInfo[]		= L"(No Input)"; 
	static CMathNode * pTree	= NULL; 
 
	RECT	rClient, rDialogBar; 
 
	TVINSERTSTRUCT	tvi; 
 
	switch(uMsg) 
	{ 
	case UWM_PARSE: 
		if (pTree) 
			delete pTree; 
 
		TreeView_DeleteAllItems(hTree);	 
 
		switch(CMathSys::ParseString((WCHAR*)wParam, &pTree)) 
		{ 
		case MATHSYS__BAD_INPUT: 
			MessageBox(hWnd, L"Bad Input", 0, 0); 
			break; 
		case MATHSYS__NULL_INPUT: 
			MessageBox(hWnd, L"Null Input", 0, 0); 
			break; 
		case MATHSYS__UNKNOWN_INPUT: 
			MessageBox(hWnd, L"Unknown Input", 0, 0); 
			break; 
		case MATHSYS__FAILURE: 
			MessageBox(hWnd, L"Failure", 0, 0); 
			break; 
		case MATHSYS__SUCCESS: 
			AddTreeNode(hTree, pTree, TVI_ROOT); 
			return 0; 
		} 
 
		pTree = NULL; 
 
		// Failure 
 
		tvi.hParent			= NULL; 
		tvi.hInsertAfter	= NULL; 
		tvi.itemex.mask		= TVIF_TEXT; 
		tvi.itemex.pszText	= L"(Error)"; 
 
		TreeView_InsertItem(hTree, &(tvi)); 
 
		return 0; 
 
	case WM_CREATE: 
 
		// Create the Dialog Bar 
		hDialogBar = CreateDialog(g_hInst, MAKEINTRESOURCE(IDD_DIALOGBAR), hWnd, DialogBarProc); 
 
		ShowWindow(hDialogBar, SW_SHOW); 
		UpdateWindow(hDialogBar); 
 
		if (!hDialogBar) 
			MessageBox(0,L"Failure!", 0,0); 
 
		GetClientRect(hDialogBar, &rDialogBar); 
 
 
SetLastError(0); 
		// Create the Tree View 
		GetClientRect(hWnd, &rClient); 
 
		InitCommonControls(); 
 
		hTree = CreateWindowEx(WS_EX_CLIENTEDGE, WC_TREEVIEW, L"MathHead.TreeView",  
							   WS_VISIBLE | WS_CHILD | TVS_FULLROWSELECT | TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT, 
							   0, 0, 0, 0, hWnd, NULL, g_hInst, 0); 
 
		tvi.hParent		= NULL; 
		tvi.hInsertAfter = NULL; 
		tvi.itemex.mask	= TVIF_TEXT; 
		tvi.itemex.pszText = szNoInfo; 
 
		TreeView_InsertItem(hTree, &(tvi)); 
 
		return 0; 
 
	case WM_SIZE: 
		{ 
 
			if (wParam == SIZE_MINIMIZED) 
				return 0;	// Do nothing 
 
			short nWidth	= LOWORD(lParam); 
			short nHeight	= HIWORD(lParam); 
 
			GetWindowRect(hDialogBar, &rDialogBar); 
			MoveWindow(hDialogBar, 0, 0, nWidth, rDialogBar.bottom - rDialogBar.top, TRUE); 
			MoveWindow(hTree, 0, rDialogBar.bottom - rDialogBar.top, nWidth, nHeight - (rDialogBar.bottom - rDialogBar.top), TRUE); 
		} 
		return 0; 
 
	case WM_COMMAND: 
		switch(LOWORD(wParam)) 
		{ 
		case ID_EXIT: 
			SendMessage(hWnd, WM_CLOSE, 0, 0); 
			break; 
 
		case ID_ABOUT: 
			DialogBox(g_hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, AboutProc); 
			break; 
 
		case ID_INSERT_DISTANCEFORMULA: 
			SetDlgItemText(hDialogBar, IDC_EXPR_TEXT, L"(x^2+y^2+z^2)^(1/2)"); 
			break; 
 
		case ID_INSERT_AREAOFATRIANGLE: 
			SetDlgItemText(hDialogBar, IDC_EXPR_TEXT, L"1/2*b*h"); 
			break; 
 
		case ID_INSERT_VOLUMEOFASPHERE: 
			SetDlgItemText(hDialogBar, IDC_EXPR_TEXT, L"4/3*(3.14159)*r^3"); 
			break; 
		} 
		return 0; 
 
	case WM_CLOSE: 
		if (MessageBox(hWnd, L"Are you sure you want to exit?", szMainTitle, MB_YESNO) == IDYES) 
			DestroyWindow(hWnd); 
		return 0; 
 
	case WM_DESTROY: 
		PostQuitMessage(0); 
		return 0; 
 
	} 
	return ::DefWindowProc(hWnd, uMsg, wParam, lParam); 
}