mirror of
https://github.com/jeremysrand/abCalc.git
synced 2024-12-27 21:29:22 +00:00
765 lines
16 KiB
C
765 lines
16 KiB
C
/*
|
|
abCalcNDA.c
|
|
By: Jeremy Rand
|
|
*/
|
|
|
|
|
|
#pragma nda NDAOpen NDAClose NDAAction NDAInit -1 0xFFFF " abCalc\\H**"
|
|
|
|
|
|
#include <orca.h>
|
|
#include <GSOS.h>
|
|
#include <Locator.h>
|
|
#include <QuickDraw.h>
|
|
#include <Window.h>
|
|
#include <Desk.h>
|
|
#include <Resources.h>
|
|
#include <Memory.h>
|
|
#include <Loader.h>
|
|
#include <Control.h>
|
|
#include <Event.h>
|
|
#include <List.h>
|
|
#include <Sane.h>
|
|
#include <LineEdit.h>
|
|
#include <Scrap.h>
|
|
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
|
|
#include "abCalcNDA.defs"
|
|
#include "abCalc.h"
|
|
#include "abCStack.h"
|
|
#include "abCError.h"
|
|
|
|
#include "expr/abCExpr.h"
|
|
|
|
#include "ops/abCOp.h"
|
|
|
|
|
|
#define MIN_STACK_ITEMS 4
|
|
|
|
void UpdateStack(void);
|
|
|
|
|
|
typedef struct listElement {
|
|
char *memPtr;
|
|
Byte memFlag;
|
|
} listElement;
|
|
|
|
|
|
static BOOLEAN gListStarted = FALSE;
|
|
static Handle gSANEDirectPage = NULL;
|
|
|
|
static BOOLEAN gCalcActive = FALSE;
|
|
static GrafPortPtr gCalcWinPtr = NULL;
|
|
static unsigned int gUserId;
|
|
static unsigned int gResourceId;
|
|
listElement *gOpList = NULL;
|
|
listElement gStackList[AB_CALC_STACK_DEPTH];
|
|
abCalcExpr gNDAExpr;
|
|
|
|
static Str255 gStrBuf;
|
|
static int gSelectedStackItem = -1;
|
|
|
|
char *gBuffer = NULL;
|
|
|
|
|
|
void NDAClose(void)
|
|
{
|
|
int i;
|
|
|
|
if (gCalcActive) {
|
|
CloseWindow(gCalcWinPtr);
|
|
gCalcWinPtr = NULL;
|
|
gCalcActive = FALSE;
|
|
}
|
|
|
|
if (gBuffer != NULL) {
|
|
free(gBuffer);
|
|
gBuffer = NULL;
|
|
}
|
|
|
|
if (gOpList != NULL) {
|
|
free(gOpList);
|
|
gOpList = NULL;
|
|
}
|
|
|
|
for (i = 0; i < AB_CALC_STACK_DEPTH; i++) {
|
|
if (gStackList[i].memPtr != NULL) {
|
|
free(gStackList[i].memPtr);
|
|
gStackList[i].memPtr = NULL;
|
|
}
|
|
}
|
|
|
|
CloseResourceFile(gResourceId);
|
|
ResourceShutDown();
|
|
}
|
|
|
|
|
|
void NDAInit(int code)
|
|
{
|
|
int i;
|
|
|
|
if (code) {
|
|
gCalcActive = FALSE;
|
|
gUserId = MMStartUp();
|
|
|
|
if (!ListStatus()) {
|
|
LoadOneTool(0x1c, 0);
|
|
ListStartUp();
|
|
gListStarted = TRUE;
|
|
}
|
|
|
|
if (!SANEStatus()) {
|
|
LoadOneTool(0x0a, 0);
|
|
gSANEDirectPage = NewHandle(256, gUserId,
|
|
attrBank | attrFixed | attrLocked | attrPage, NULL);
|
|
SANEStartUp((Word) *gSANEDirectPage);
|
|
}
|
|
|
|
abCalcInit();
|
|
|
|
for (i = 0; i < AB_CALC_STACK_DEPTH; i++) {
|
|
gStackList[i].memPtr = NULL;
|
|
}
|
|
} else {
|
|
if (gSANEDirectPage) {
|
|
SANEShutDown();
|
|
DisposeHandle(gSANEDirectPage);
|
|
UnloadOneTool(0x0a);
|
|
gSANEDirectPage = NULL;
|
|
}
|
|
|
|
if (gListStarted) {
|
|
ListShutDown();
|
|
UnloadOneTool(0x1c);
|
|
gListStarted = FALSE;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
#pragma databank 1
|
|
void DrawContents(void)
|
|
{
|
|
PenNormal();
|
|
DrawControls(GetPort());
|
|
}
|
|
#pragma databank 0
|
|
|
|
|
|
GrafPortPtr NDAOpen(void)
|
|
{
|
|
Pointer pathToSelf;
|
|
unsigned int oldResourceApp;
|
|
LevelRecGS levelDCB;
|
|
unsigned int oldLevel;
|
|
SysPrefsRecGS prefsDCB;
|
|
unsigned int oldPrefs;
|
|
int numOps;
|
|
int i;
|
|
Handle opListCtl;
|
|
|
|
if (gCalcActive)
|
|
return NULL;
|
|
|
|
oldResourceApp = GetCurResourceApp();
|
|
ResourceStartUp(gUserId);
|
|
pathToSelf = LGetPathname2(gUserId, 1);
|
|
|
|
levelDCB.pCount = 2;
|
|
GetLevelGS(&levelDCB);
|
|
oldLevel = levelDCB.level;
|
|
levelDCB.level = 0;
|
|
SetLevelGS(&levelDCB);
|
|
|
|
prefsDCB.pCount = 1;
|
|
GetSysPrefsGS(&prefsDCB);
|
|
oldPrefs = prefsDCB.preferences;
|
|
prefsDCB.preferences = (prefsDCB.preferences & 0x1fff) | 0x8000;
|
|
SetSysPrefsGS(&prefsDCB);
|
|
|
|
gResourceId = OpenResourceFile(readEnable, NULL, pathToSelf);
|
|
|
|
gCalcWinPtr = NewWindow2("\p abCalc ", 0, DrawContents, NULL, refIsResource,
|
|
abCalcWinNum, rWindParam1);
|
|
|
|
SetSysWindow(gCalcWinPtr);
|
|
ShowWindow(gCalcWinPtr);
|
|
SelectWindow(gCalcWinPtr);
|
|
SetPort(gCalcWinPtr);
|
|
|
|
if (gOpList == NULL) {
|
|
numOps = abCalcOpNumOps();
|
|
gOpList = malloc(sizeof(*gOpList) * numOps);
|
|
for (i = 0; i < numOps; i++) {
|
|
gOpList[i].memPtr = abCalcOpNth(i)->name;
|
|
gOpList[i].memFlag = 0;
|
|
}
|
|
}
|
|
|
|
opListCtl = (Handle)GetCtlHandleFromID(gCalcWinPtr, abCalcOpList);
|
|
NewList2(NULL, 1, (Ref)gOpList, 0, numOps, opListCtl);
|
|
|
|
UpdateStack();
|
|
|
|
gCalcActive = TRUE;
|
|
|
|
prefsDCB.preferences = oldPrefs;
|
|
SetSysPrefsGS(&prefsDCB);
|
|
|
|
levelDCB.level = oldLevel;
|
|
SetLevelGS(&levelDCB);
|
|
|
|
SetCurResourceApp(oldResourceApp);
|
|
|
|
return gCalcWinPtr;
|
|
}
|
|
|
|
|
|
void UpdateStack(void)
|
|
{
|
|
Handle stackListCtl;
|
|
int i;
|
|
int numToDisplay = abCalcStackNumItems();
|
|
|
|
if (numToDisplay < MIN_STACK_ITEMS) {
|
|
numToDisplay = MIN_STACK_ITEMS;
|
|
}
|
|
|
|
stackListCtl = (Handle)GetCtlHandleFromID(gCalcWinPtr, abCalcStackList);
|
|
|
|
for (i = numToDisplay - 1; i >= 0; i--) {
|
|
if (gStackList[i].memPtr == NULL) {
|
|
gStackList[i].memPtr = malloc(AB_CALC_EXPR_STRING_MAX + 8);
|
|
}
|
|
abCalcStackExprStringAt(numToDisplay - i - 1, gStackList[i].memPtr,
|
|
TRUE);
|
|
gStackList[i].memFlag = 0;
|
|
}
|
|
|
|
NewList2(NULL, numToDisplay - 3, (Ref)gStackList, 0, numToDisplay, stackListCtl);
|
|
gSelectedStackItem = -1;
|
|
}
|
|
|
|
|
|
BOOLEAN ErrorRaised(void)
|
|
{
|
|
char *errorString = abCalcGetError();
|
|
if (errorString == NULL) {
|
|
return FALSE;
|
|
}
|
|
|
|
AlertWindow(awCString+awResource, (Pointer)&errorString, abCalcErrorAlert);
|
|
|
|
abCalcClearError();
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
void PushCalcEntry(CtlRecHndl entryBox)
|
|
{
|
|
abCalcOp *op;
|
|
|
|
GetLETextByID(gCalcWinPtr, abCalcEntryBox, &gStrBuf);
|
|
|
|
if (gStrBuf.textLength > 0) {
|
|
gStrBuf.text[gStrBuf.textLength] = '\0';
|
|
|
|
op = abCalcOpLookup(gStrBuf.text);
|
|
|
|
if (op != NULL) {
|
|
op->execute();
|
|
} else if (abCalcParseExpr(&gNDAExpr, gStrBuf.text) != NULL) {
|
|
abCalcStackExprPush(&gNDAExpr);
|
|
} else {
|
|
LERecHndl leHandle;
|
|
|
|
HLock((Handle)entryBox);
|
|
leHandle = (LERecHndl)(*entryBox)->ctlData;
|
|
HUnlock((Handle)entryBox);
|
|
|
|
LESetSelect(0, gStrBuf.textLength, leHandle);
|
|
abCalcRaiseError(abCalcSyntaxError, NULL);
|
|
return;
|
|
}
|
|
|
|
gStrBuf.textLength = 0;
|
|
SetLETextByID(gCalcWinPtr, abCalcEntryBox, &gStrBuf);
|
|
}
|
|
}
|
|
|
|
|
|
void ExecCalcCmd(char *cmd)
|
|
{
|
|
abCalcOp *op = abCalcOpLookup(cmd);
|
|
CtlRecHndl entryBox = GetCtlHandleFromID(gCalcWinPtr, abCalcEntryBox);
|
|
|
|
PushCalcEntry(entryBox);
|
|
|
|
if ((!ErrorRaised()) &&
|
|
(op != NULL)) {
|
|
op->execute();
|
|
}
|
|
|
|
ErrorRaised();
|
|
|
|
UpdateStack();
|
|
}
|
|
|
|
|
|
void InsertChar(CtlRecHndl entryBox, char ch)
|
|
{
|
|
LERecHndl leHandle;
|
|
|
|
HLock((Handle)entryBox);
|
|
leHandle = (LERecHndl)(*entryBox)->ctlData;
|
|
HUnlock((Handle)entryBox);
|
|
|
|
LEDelete(leHandle);
|
|
LEInsert(&ch, 1, leHandle);
|
|
}
|
|
|
|
|
|
void ExecMinusButton(void)
|
|
{
|
|
int i;
|
|
char aChar;
|
|
BOOLEAN doCmd = FALSE;
|
|
BOOLEAN dotSeen = FALSE;
|
|
|
|
CtlRecHndl entryBox = GetCtlHandleFromID(gCalcWinPtr, abCalcEntryBox);
|
|
GetLETextByID(gCalcWinPtr, abCalcEntryBox, &gStrBuf);
|
|
|
|
if (gStrBuf.textLength > 0) {
|
|
doCmd = TRUE;
|
|
|
|
gStrBuf.text[gStrBuf.textLength] = '\0';
|
|
|
|
aChar = gStrBuf.text[gStrBuf.textLength - 1];
|
|
if (((aChar == 'e') ||
|
|
(aChar == 'E')) &&
|
|
(gStrBuf.textLength > 1)) {
|
|
doCmd = FALSE;
|
|
for (i = 0; i < gStrBuf.textLength - 1; i++) {
|
|
switch (gStrBuf.text[i]) {
|
|
case '-':
|
|
if (i != 0) {
|
|
doCmd = TRUE;
|
|
}
|
|
break;
|
|
|
|
case '0':
|
|
case '1':
|
|
case '2':
|
|
case '3':
|
|
case '4':
|
|
case '5':
|
|
case '6':
|
|
case '7':
|
|
case '8':
|
|
case '9':
|
|
break;
|
|
|
|
case '.':
|
|
if (dotSeen) {
|
|
doCmd = TRUE;
|
|
} else {
|
|
dotSeen = TRUE;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
doCmd = TRUE;
|
|
break;
|
|
}
|
|
if (doCmd)
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (doCmd) {
|
|
ExecCalcCmd("-");
|
|
} else {
|
|
InsertChar(entryBox, '-');
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
void HandleEntryBox(void)
|
|
{
|
|
Handle stackListCtl = (Handle)GetCtlHandleFromID(gCalcWinPtr, abCalcStackList);
|
|
if (gSelectedStackItem != -1) {
|
|
ResetMember2(stackListCtl);
|
|
DrawMember2(gSelectedStackItem, stackListCtl);
|
|
gSelectedStackItem = -1;
|
|
}
|
|
}
|
|
|
|
|
|
void HandleStackClick(void)
|
|
{
|
|
Handle stackListCtl = (Handle)GetCtlHandleFromID(gCalcWinPtr, abCalcStackList);
|
|
int nthOp;
|
|
int numStackItems = abCalcStackNumItems();
|
|
int numDisplayed = numStackItems;
|
|
int selectedStackItem = -1;
|
|
|
|
nthOp = NextMember2(0, stackListCtl);
|
|
if (nthOp == gSelectedStackItem) {
|
|
ResetMember2(stackListCtl);
|
|
DrawMember2(gSelectedStackItem, stackListCtl);
|
|
gSelectedStackItem = -1;
|
|
nthOp = NextMember2(0, stackListCtl);
|
|
}
|
|
if (nthOp == 0)
|
|
return;
|
|
|
|
if (numDisplayed < MIN_STACK_ITEMS)
|
|
numDisplayed = MIN_STACK_ITEMS;
|
|
|
|
selectedStackItem = numDisplayed + 1 - nthOp;
|
|
|
|
if (selectedStackItem > numStackItems) {
|
|
ResetMember2(stackListCtl);
|
|
DrawMember2(nthOp, stackListCtl);
|
|
gSelectedStackItem = -1;
|
|
} else {
|
|
gSelectedStackItem = nthOp;
|
|
}
|
|
}
|
|
|
|
|
|
void HandleOpClick(void)
|
|
{
|
|
Handle opListCtl = (Handle)GetCtlHandleFromID(gCalcWinPtr, abCalcOpList);
|
|
int nthOp = ResetMember2(opListCtl);
|
|
abCalcOp *op;
|
|
|
|
if (nthOp > 0) {
|
|
nthOp--;
|
|
|
|
op = abCalcOpNth(nthOp);
|
|
if (op != NULL) {
|
|
CtlRecHndl entryBox = GetCtlHandleFromID(gCalcWinPtr, abCalcEntryBox);
|
|
PushCalcEntry(entryBox);
|
|
|
|
if (!ErrorRaised()) {
|
|
op->execute();
|
|
}
|
|
|
|
ErrorRaised();
|
|
|
|
UpdateStack();
|
|
}
|
|
|
|
DrawMember2(nthOp + 1, opListCtl);
|
|
}
|
|
}
|
|
|
|
|
|
void HandleControl(EventRecord *event)
|
|
{
|
|
CtlRecHndl entryBox = GetCtlHandleFromID(gCalcWinPtr, abCalcEntryBox);
|
|
SetPort(gCalcWinPtr);
|
|
|
|
switch (event->wmTaskData4) {
|
|
case abCalcBtn0:
|
|
InsertChar(entryBox, '0');
|
|
break;
|
|
|
|
case abCalcBtn1:
|
|
InsertChar(entryBox, '1');
|
|
break;
|
|
|
|
case abCalcBtn2:
|
|
InsertChar(entryBox, '2');
|
|
break;
|
|
|
|
case abCalcBtn3:
|
|
InsertChar(entryBox, '3');
|
|
break;
|
|
|
|
case abCalcBtn4:
|
|
InsertChar(entryBox, '4');
|
|
break;
|
|
|
|
case abCalcBtn5:
|
|
InsertChar(entryBox, '5');
|
|
break;
|
|
|
|
case abCalcBtn6:
|
|
InsertChar(entryBox, '6');
|
|
break;
|
|
|
|
case abCalcBtn7:
|
|
InsertChar(entryBox, '7');
|
|
break;
|
|
|
|
case abCalcBtn8:
|
|
InsertChar(entryBox, '8');
|
|
break;
|
|
|
|
case abCalcBtn9:
|
|
InsertChar(entryBox, '9');
|
|
break;
|
|
|
|
case abCalcBtnEnter:
|
|
PushCalcEntry(entryBox);
|
|
ErrorRaised();
|
|
UpdateStack();
|
|
break;
|
|
|
|
case abCalcBtnDot:
|
|
InsertChar(entryBox, '.');
|
|
break;
|
|
|
|
case abCalcBtnNum:
|
|
InsertChar(entryBox, '#');
|
|
break;
|
|
|
|
case abCalcBtnAdd:
|
|
ExecCalcCmd("+");
|
|
break;
|
|
|
|
case abCalcBtnSub:
|
|
ExecMinusButton();
|
|
break;
|
|
|
|
case abCalcBtnMult:
|
|
ExecCalcCmd("*");
|
|
break;
|
|
|
|
case abCalcBtnDiv:
|
|
ExecCalcCmd("/");
|
|
break;
|
|
|
|
case abCalcBtnPow:
|
|
ExecCalcCmd("^");
|
|
break;
|
|
|
|
case abCalcBtnA:
|
|
InsertChar(entryBox, 'A');
|
|
break;
|
|
|
|
case abCalcBtnB:
|
|
InsertChar(entryBox, 'B');
|
|
break;
|
|
|
|
case abCalcBtnC:
|
|
InsertChar(entryBox, 'C');
|
|
break;
|
|
|
|
case abCalcBtnD:
|
|
InsertChar(entryBox, 'D');
|
|
break;
|
|
|
|
case abCalcBtnE:
|
|
InsertChar(entryBox, 'E');
|
|
break;
|
|
|
|
case abCalcBtnF:
|
|
InsertChar(entryBox, 'F');
|
|
break;
|
|
|
|
case abCalcEntryBox:
|
|
HandleEntryBox();
|
|
break;
|
|
|
|
case abCalcStackList:
|
|
HandleStackClick();
|
|
break;
|
|
|
|
case abCalcOpList:
|
|
HandleOpClick();
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
void DoCut(void)
|
|
{
|
|
LERecHndl leHandle;
|
|
CtlRecHndl entryBox = GetCtlHandleFromID(gCalcWinPtr, abCalcEntryBox);
|
|
|
|
HLock((Handle)entryBox);
|
|
leHandle = (LERecHndl)(*entryBox)->ctlData;
|
|
HUnlock((Handle)entryBox);
|
|
|
|
LECut(leHandle);
|
|
LEToScrap();
|
|
}
|
|
|
|
|
|
void DoCopy(void)
|
|
{
|
|
Handle stackListCtl = (Handle)GetCtlHandleFromID(gCalcWinPtr, abCalcStackList);
|
|
LERecHndl leHandle;
|
|
CtlRecHndl entryBox = GetCtlHandleFromID(gCalcWinPtr, abCalcEntryBox);
|
|
|
|
int numStackItems = abCalcStackNumItems();
|
|
int numDisplayed = numStackItems;
|
|
int selectedStackItem;
|
|
|
|
if (gSelectedStackItem == -1) {
|
|
HLock((Handle)entryBox);
|
|
leHandle = (LERecHndl)(*entryBox)->ctlData;
|
|
HUnlock((Handle)entryBox);
|
|
|
|
LECopy(leHandle);
|
|
LEToScrap();
|
|
return;
|
|
}
|
|
|
|
if (numDisplayed < MIN_STACK_ITEMS)
|
|
numDisplayed = MIN_STACK_ITEMS;
|
|
|
|
selectedStackItem = numDisplayed - gSelectedStackItem;
|
|
|
|
if (gBuffer == NULL) {
|
|
gBuffer = malloc(AB_CALC_EXPR_STRING_MAX);
|
|
}
|
|
|
|
if ((selectedStackItem >= 0) &&
|
|
(selectedStackItem < numStackItems) &&
|
|
(abCalcStackExprStringAt(selectedStackItem, gBuffer, FALSE) != NULL)) {
|
|
ZeroScrap();
|
|
PutScrap(strlen(gBuffer), textScrap, gBuffer);
|
|
}
|
|
|
|
SetPort(gCalcWinPtr);
|
|
ResetMember2(stackListCtl);
|
|
DrawMember2(gSelectedStackItem, stackListCtl);
|
|
gSelectedStackItem = -1;
|
|
}
|
|
|
|
|
|
void DoPaste(void)
|
|
{
|
|
LERecHndl leHandle;
|
|
CtlRecHndl entryBox = GetCtlHandleFromID(gCalcWinPtr, abCalcEntryBox);
|
|
|
|
HLock((Handle)entryBox);
|
|
leHandle = (LERecHndl)(*entryBox)->ctlData;
|
|
HUnlock((Handle)entryBox);
|
|
|
|
LEFromScrap();
|
|
LEPaste(leHandle);
|
|
}
|
|
|
|
|
|
void DoClear(void)
|
|
{
|
|
LERecHndl leHandle;
|
|
CtlRecHndl entryBox = GetCtlHandleFromID(gCalcWinPtr, abCalcEntryBox);
|
|
|
|
HLock((Handle)entryBox);
|
|
leHandle = (LERecHndl)(*entryBox)->ctlData;
|
|
HUnlock((Handle)entryBox);
|
|
|
|
LEDelete(leHandle);
|
|
}
|
|
|
|
|
|
void HandleMenu(int menuItem)
|
|
{
|
|
SetPort(gCalcWinPtr);
|
|
|
|
switch (menuItem) {
|
|
case cutAction:
|
|
DoCut();
|
|
break;
|
|
|
|
case copyAction:
|
|
DoCopy();
|
|
break;
|
|
|
|
case pasteAction:
|
|
DoPaste();
|
|
break;
|
|
|
|
case clearAction:
|
|
DoClear();
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
void HandleKey(EventRecord *event)
|
|
{
|
|
BOOLEAN appleKeyPressed = ((event->modifiers & appleKey) != 0);
|
|
char key = (event->message & 0xff);
|
|
|
|
if (!appleKeyPressed)
|
|
return;
|
|
|
|
switch (key) {
|
|
case 'C':
|
|
case 'c':
|
|
DoCopy();
|
|
break;
|
|
|
|
case 'X':
|
|
case 'x':
|
|
DoCut();
|
|
break;
|
|
|
|
case 'V':
|
|
case 'v':
|
|
DoPaste();
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
BOOLEAN NDAAction(EventRecord *sysEvent, int code)
|
|
{
|
|
int event;
|
|
static EventRecord localEvent;
|
|
unsigned int eventCode;
|
|
BOOLEAN result = FALSE;
|
|
|
|
switch (code) {
|
|
case runAction:
|
|
return result;
|
|
|
|
case eventAction:
|
|
BlockMove((Pointer)sysEvent, (Pointer)&localEvent, 16);
|
|
localEvent.wmTaskMask = 0x001FFFFF;
|
|
eventCode = TaskMasterDA(0, &localEvent);
|
|
switch(eventCode) {
|
|
case updateEvt:
|
|
BeginUpdate(gCalcWinPtr);
|
|
DrawContents();
|
|
EndUpdate(gCalcWinPtr);
|
|
break;
|
|
|
|
case wInControl:
|
|
HandleControl(&localEvent);
|
|
break;
|
|
|
|
case keyDownEvt:
|
|
case autoKeyEvt:
|
|
HandleKey(&localEvent);
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case cutAction:
|
|
case copyAction:
|
|
case pasteAction:
|
|
case clearAction:
|
|
result = TRUE;
|
|
HandleMenu(code);
|
|
break;
|
|
}
|
|
|
|
return result;
|
|
}
|