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);
}