Code/Resource
Windows Develop
Linux-Unix program
Internet-Socket-Network
Web Server
Browser Client
Ftp Server
Ftp Client
Browser Plugins
Proxy Server
Email Server
Email Client
WEB Mail
Firewall-Security
Telnet Server
Telnet Client
ICQ-IM-Chat
Search Engine
Sniffer Package capture
Remote Control
xml-soap-webservice
P2P
WEB(ASP,PHP,...)
TCP/IP Stack
SNMP
Grid Computing
SilverLight
DNS
Cluster Service
Network Security
Communication-Mobile
Game Program
Editor
Multimedia program
Graph program
Compiler program
Compress-Decompress algrithms
Crypt_Decrypt algrithms
Mathimatics-Numerical algorithms
MultiLanguage
Disk/Storage
Java Develop
assembly language
Applications
Other systems
Database system
Embeded-SCM Develop
FlashMX/Flex
source in ebook
Delphi VCL
OS Develop
MiddleWare
MPI
MacOS develop
LabView
ELanguage
Software/Tools
E-Books
Artical/Document
genem.c
Package: shell.rar [view]
Upload User: xhy777
Upload Date: 2007-02-14
Package Size: 24088k
Code Size: 42k
Category:
Windows Kernel
Development Platform:
Visual C++
- /*----------------------------------------------------------------------------
- %%File: EMTEST.C
- %%Unit: Event Monitor (mntr)
- %%Contact: daleg
- Event Monitor Sample Application, Main Program.
- The purpose of this application is to demonstrate how to process events
- using the Event Monitor's Rule Compiler and rule engine.
- ----------------------------------------------------------------------------*/
- //*** genem.c -- 'generic' evtmon client-side stuff
- // DESCRIPTION
- // the client-side of an evtmon app has two parts:
- // - evtmon generic code (client-side)
- // - application-specific rules
- // this file is reusable (and semi-frozen) generic code. it should be
- // #include'ed from the app.
- // NOTES
- // WARNING: do *not* put app-specific code here. put it in the
- // client (emclient/libem.c). in fact in general, think twice before
- // modifying this file at all.
- //*** YY_* -- generic rules support
- //
- #define YY_BASE 1 // base features (always needed)
- #ifdef YY_BASE
- // rulc.exe doesn't create all files if a given feature isn't used,
- // so we can't unconditionally include these guys. plus, we don't
- // want the helper code if we don't need it.
- // turn on these features here if you use them
- #ifndef YY_DELAYED
- #define YY_DELAYED 0 // delayed actions
- #endif
- #ifndef YY_CTOR
- #define YY_CTOR 0 // action ctors
- #endif
- #ifndef YY_SEQCHECK
- #define YY_SEQCHECK 0 // seq_check
- #endif
- #define YY_OTHER 0 // BUGBUG not sure what emactr.h is for
- //#define YY_BRKPT()
- #endif
- //*** FEATURE_* -- domain-specific rules support
- // NOTES
- // BUGBUG untested! not sure if these #if's are done right
- #define FEATURE_DEMO 0 // demo code (e.g. wndproc test app)
- #define FEATURE_SAMPLE 0 // sample code (e.g. joe-event firer)
- #define FEATURE_OFFICE 0 // base office stuff
- #define FEATURE_TEXT 0 // text parser
- #define FEATURE_WORD 0 // format parser
- #define FEATURE_DEAD 0 // unused/dead code
- #define FEATURE_NYI 0 // BUGBUG things i don't understand
- #include "mso.h"
- #include "msoem.h"
- DEBUGASSERTSZ
- #include "msolex.h"
- #include "emrule.h"
- #include "emkwd.h"
- #include "emact.h"
- #if FEATURE_DEMO
- #include "emtest.h"
- #include "emres.h"
- #endif
- // { Files generated by Rule Compiler
- #include "emdef.h" // rules (#defines)
- #if YY_CTOR // {
- #include "emacts.h" // ctor macro wrappers
- #endif // }
- #define DEBUG_RULE_POINTERS // Want ptrs to nodes
- #include "emruli.h" // rulebase
- #if YY_SEQCHECK // seq_check
- #include "emsqck.c_" // sequences
- #endif
- // }
- #if FEATURE_TEXT // {
- // Constants
- #define cbEditText 1024
- #ifdef STATIC_INIT
- #define grfLexFlagsEm (MsoGrfLexFNoReset
- | MsoGrfLexFLookup
- | MsoGrfLexFLookupIntsAndSyms
- | MsoGrfLexFAllCapsAsFormat)
- // EM data structures
- MSORULTK rgrultkEmToken[200]; // Text Token cache
- MSORULTK rgrultkEmFormat[100]; // Format Token cache
- MSOLEXS vlexs =
- {
- &vkwtbEmTOKEN_KEYTABLE, // pkwtb
- {rgrultkEmToken, 200, }, // rultkhToken
- {rgrultkEmFormat, 100, }, // rultkhFormat
- fTrue, // fInited
- isttblDefault, // isttbl
- grfLexFlagsEm, // grpfLexFlags
- _hObjectNil, // hObjectNil
- MsoWchLexGetNextBufferDoc, // pfnlexbuf
- FGetNextLexRun, // pfnlexrun
- FGetTokenTextObject, // pfnlextxt
- NULL, // pfnlexfmt
- NULL, // pfnlexrunDiscontig
- NULL, // pfnlexrunForceCompl
- iNil, // ichRun
- -1, // cchLookahead
- };
- MSOLEXS *vplexs = &vlexs; // Global lexer state
- #else /* !STATIC_INIT */
- MSOLEXS vlexs; // Global lexer state
- MSOLEXS *vplexs; // Global lexer state
- #endif /* STATIC_INIT */
- #endif // }
- #if YY_BASE // {
- // Global variables
- RULS *vlpruls = &vrulsEm;
- #ifndef STATIC_LINK_EM
- RULS **_pvlprulsDLL = &vlpruls; // App's Global state
- #endif /* !STATIC_LINK_EM */
- #endif // }
- #if FEATURE_DEMO // {
- char vszAppName[20]; // Application name
- HWND vhInst; // Instance
- HWND vhWndMain; // Main window
- HWND vhWndDlg; // Dialog window
- char vszEditText[cbEditText]; // Text of edit control
- int vcchEditText; // #chs in edit control
- static int vcchPrev = 0; // Prev edit box len
- static int vcpIpPrev = 0; // Prev edit box ip
- int vfSettingDlgItem = fFalse; // Avoid Win recursion
- #endif // }
- #if YY_BASE // {
- #if YY_DELAYED
- #include "emactr.h" // data tables
- MSOACTTBL vacttbl = {vrgacttrecEm}; // Global action table
- MSOACTTBL *_pacttbl = &vacttbl; // Glob action tbl ptr
- #endif
- #endif // }
- #if FEATURE_OFFICE // {
- EMS vems; // EM global state
- EMS *vpems = &vems; // Ptr to global state
- #endif // }
- #if YY_BASE // {
- #ifdef DEBUG
- #ifndef STATIC_LINK_EM
- int vwDebugLogFilter = fDebugFilterAll;
- int vwDebugLogLvl = -2;
- #endif // !STATIC_LINK_EM
- // Pointers to global debug logging vars in Mso DLL
- int *pvwDebugLogFilter = &vwDebugLogFilter;
- int *pvwDebugLogLvl = &vwDebugLogLvl;
- #endif /* DEBUG */
- #endif // }
- #if YY_BASE // {
- #ifdef STATIC_INIT // {
- /* F I N I T E M */
- /*----------------------------------------------------------------------------
- %%Function: FInitEm
- %%Contact: daleg
- Initialize the static (compiled) Event Monitor rules.
- ----------------------------------------------------------------------------*/
- int FInitEm(void)
- {
- #ifndef STATIC_LINK_EM
- /* Mirror global debug pointers in Mso97.dll */
- Debug(pvwDebugLogLvl = MsoPwDebugLogLvl(&pvwDebugLogFilter);)
- #endif /* !STATIC_LINK_EM */
- Debug(*pvwDebugLogLvl = 7);
- #ifndef STATIC_LINK_EM
- /* Mirror global pointers (vlpruls, etc) in Mso97.dll */
- _pvlprulsDLL = MsoPvlprulsMirror(&vlpruls);
- *_pvlprulsDLL = &vrulsEm;
- #endif /* !STATIC_LINK_EM */
- #ifdef DYN_RULES
- /* Load dynamic rules */
- FLoadDynEmRules();
- #endif /* DYN_RULES */
- #if FEATURE_OFFICE
- /* For performance reasons, action table is global */
- vacttbl.prultkh = &vplexs->rultkhToken;
- #endif
- #if FEATURE_DEMO
- /* Allow Event Drivers to run */
- EnableEM();
- #endif
- /* Propagate the values through the rule network */
- MsoScheduleIrul(irul_YYSTD_INIT, fTrue);
- #ifdef DYN_RULES
- MsoScheduleIrul(irul_YYSTD_LOADING_RULEBASE, fTrue);
- #endif /* DYN_RULES */
- MsoEvaluateEvents(rulevtEm_YYSTD);
- return fTrue;
- }
- #else /* }{ !STATIC_INIT */
- /* F I N I T E M */
- /*----------------------------------------------------------------------------
- %%Function: FInitEm
- %%Contact: daleg
- Initialize the static (compiled) Event Monitor rules.
- ----------------------------------------------------------------------------*/
- int FInitEm(void)
- {
- #ifndef STATIC_LINK_EM
- /* Mirror global debug pointers in Mso97.dll */
- Debug(pvwDebugLogLvl = MsoPwDebugLogLvl(&pvwDebugLogFilter);)
- #endif /* !STATIC_LINK_EM */
- Debug(*pvwDebugLogLvl = 7);
- /* Initialize rule base, for performance reasons, rulebase is global */
- if (!MsoFInitStaticRuls(&vrulsEm, &vrulsEm))
- return fFalse;
- #ifndef STATIC_LINK_EM
- /* Mirror global pointers (vlpruls, etc) in Mso97.dll */
- _pvlprulsDLL = MsoPvlprulsMirror(&vlpruls);
- *_pvlprulsDLL = &vrulsEm;
- #endif /* !STATIC_LINK_EM */
- #ifdef DYN_RULES
- /* Load dynamic rules */
- FLoadDynEmRules();
- #endif /* DYN_RULES */
- #if FEATURE_OFFICE
- /* Initialize the lexer to scan the doc */
- if (!(vplexs = MsoPlexsLexInitDoc
- (&vlexs, _hObjectNil, FGetNextLexRun,
- FGetTokenTextObject, NULL, NULL, 200, 100)))
- return fFalse;
- vplexs->pkwtb = &vkwtbEmTOKEN_KEYTABLE;
- /* For performance reasons, action table is global */
- vacttbl.prultkh = &vplexs->rultkhToken;
- #endif
- #if FEATURE_DEMO
- /* Allow Event Drivers to run */
- EnableEM();
- #endif
- /* Propagate the values through the rule network */
- MsoScheduleIrul(irul_YYSTD_INIT, fTrue);
- #ifdef DYN_RULES
- MsoScheduleIrul(irul_YYSTD_LOADING_RULEBASE, fTrue);
- #endif /* DYN_RULES */
- MsoEvaluateEvents(rulevtEm_YYSTD);
- return fTrue;
- }
- #endif /* } STATIC_INIT */
- #endif // }
- #if YY_BASE // {
- /* F E V A L E M R U L E */
- /*----------------------------------------------------------------------------
- %%Function: FEvalEmRule
- %%Contact: daleg
- Evaluate the rule associated with the given rule ID number.
- Return a boolean value for whether its value was TRUE or FALSE.
- ----------------------------------------------------------------------------*/
- #include "emeval.c"
- #endif // }
- #if FEATURE_DEMO // {
- /* W I N M A I N */
- /*----------------------------------------------------------------------------
- %%Function: WinMain
- %%Contact: daleg
- Main routine.
- ----------------------------------------------------------------------------*/
- int CALLBACK WinMain(
- HANDLE hInstance,
- HANDLE hPrevInstance,
- LPSTR lpszCmdLine,
- int nCmdShow
- )
- {
- MSG msg;
- int nRc;
- char szString[256];
- GdiSetBatchLimit(1);
- strcpy(vszAppName, "EMTEST");
- vhInst = hInstance;
- if (!hPrevInstance)
- {
- /* Register window classes if first instance of application */
- if ((nRc = nCwRegisterClasses()) == -1)
- {
- /* Put up msg if registering one of the windows failed */
- LoadString(vhInst, IDS_ERR_REGISTER_CLASS, szString,
- sizeof(szString));
- MessageBox(NULL, szString, NULL, MB_ICONEXCLAMATION);
- return nRc;
- }
- }
- /* Create application's Main window */
- vhWndMain = CreateWindow(vszAppName,
- NULL,
- WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX
- | WS_MAXIMIZEBOX | WS_THICKFRAME
- | WS_CLIPCHILDREN | WS_OVERLAPPED,
- 0, 0, 400, 400,
- NULL, NULL, vhInst, NULL);
- /* If could not create main window, be nice before quitting */
- if (vhWndMain == NULL)
- {
- LoadString(vhInst, IDS_ERR_CREATE_WINDOW, szString, sizeof(szString));
- MessageBox(NULL, szString, NULL, MB_ICONEXCLAMATION);
- return IDS_ERR_CREATE_WINDOW;
- }
- /* Initialize the rulebase */
- if (!FInitEm())
- return 1;
- /* Display main window */
- ShowWindow(vhWndMain, nCmdShow);
- /* Until WM_QUIT message */
- while (GetMessage(&msg, NULL, 0, 0))
- {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- /* Do clean up before exiting from the application */
- CwUnRegisterClasses();
- return msg.wParam;
- }
- /* W N D P R O C */
- /*----------------------------------------------------------------------------
- %%Function: WndProc
- %%Contact: daleg
- Windows proc for main window.
- ----------------------------------------------------------------------------*/
- LONG CALLBACK WndProc(
- HWND hWnd,
- UINT Message,
- WPARAM wParam,
- LPARAM lParam
- )
- {
- HMENU hMenu = 0;
- int nRc = 0;
- switch (Message)
- {
- case WM_COMMAND:
- FEmEvalDialog(wParam);
- switch (LOWORD(wParam))
- {
- case IDM_DIALOG:
- /* Respond to the menu item named "Dialog" */
- {
- FARPROC lpfnDIALOGSMsgProc;
- lpfnDIALOGSMsgProc = MakeProcInstance((FARPROC) DIALOGSMsgProc,
- vhInst);
- nRc = DialogBox(vhInst, MAKEINTRESOURCE(IDM_DIALOG), hWnd,
- lpfnDIALOGSMsgProc);
- FreeProcInstance(lpfnDIALOGSMsgProc);
- }
- break;
- default:
- return DefWindowProc(hWnd, Message, wParam, lParam);
- }
- break;
- case WM_CLOSE:
- /* Destroy child windows, modeless dialogs, then, this window */
- DestroyWindow(hWnd);
- /* Quit the application */
- if (hWnd == vhWndMain)
- PostQuitMessage(0);
- break;
- default:
- return DefWindowProc(hWnd, Message, wParam, lParam);
- }
- return 0L;
- }
- /* D I A L O G S M S G P R O C */
- /*----------------------------------------------------------------------------
- %%Function: DIALOGSMsgProc
- %%Contact: daleg
- Dialog proc for inner window.
- ----------------------------------------------------------------------------*/
- BOOL CALLBACK DIALOGSMsgProc(
- HWND hWndDlg,
- UINT Message,
- WPARAM wParam,
- LPARAM lParam
- )
- {
- switch (Message)
- {
- case WM_INITDIALOG:
- cwCenter(hWndDlg, 0);
- vcchPrev = 0;
- vcpIpPrev = 0;
- vhWndDlg = hWndDlg;
- break;
- case WM_CLOSE:
- break;
- case WM_COMMAND:
- switch (LOWORD(wParam))
- {
- case IDC_EDIT1:
- switch (HIWORD(wParam))
- {
- case EN_CHANGE:
- vcchEditText = GetDlgItemText(hWndDlg, IDC_EDIT1, vszEditText,
- cbEditText);
- if (!vfSettingDlgItem)
- {
- MSOCP cpIp;
- XCHAR wch;
- /* Get IP (Insertion Point) position */
- SendDlgItemMessage(hWndDlg, IDC_EDIT1, EM_GETSEL, 0,
- (LPARAM)&cpIp);
- /* Get character typed */
- wch = (vcchEditText > vcchPrev
- ? vszEditText[cpIp - 1] // Char typed
- : xchBackspace); // Backspace
- /* Notify Event Monitor CHAR driver */
- FEmEvalChar(wch, cpIp, vszEditText, vcchEditText);
- /* Track prev text positions for invalidation detect */
- vcchPrev = vcchEditText;
- vcpIpPrev = cpIp;
- }
- break;
- }
- break;
- case IDC_BUTTON1:
- case IDC_BUTTON2:
- case IDC_START:
- case IDC_STOP:
- default:
- FEmEvalDialog(wParam);
- break;
- case IDOK:
- FEmEvalDialog(wParam);
- EndDialog(hWndDlg, FALSE);
- break;
- }
- break;
- default:
- return FALSE;
- }
- return TRUE;
- }
- #endif // }
- #if FEATURE_SAMPLE // { joe event firer
- /* F E M E V A L D I A L O G */
- /*----------------------------------------------------------------------------
- %%Function: FEmEvalDialog
- %%Contact: daleg
- Event Monitor Event Driver for DIALOG events.
- ----------------------------------------------------------------------------*/
- int FEmEvalDialog(WPARAM wParam)
- {
- short idc = LOWORD(wParam);
- IRUL irul;
- #if FEATURE_DEMO
- /* Make sure we are enabled (e.g. macros not running) */
- if (FEmDisabled())
- return fFalse;
- #endif
- /* Match the (sparse) dialog object to its associated (contig) event, if any */
- vlpruls->irulPrimaryEvent = irul
- = (IRUL) MsoPkwdlhLookupL(idc, &vkwtbEmIDC_KEYTABLE)->tk;
- debugEM1(2, "DIALOG EVENT: %-20.20sn",
- LpchRulName(LprulFromIrul(irul)));
- /* Push event into appropriate queue (resets depth) */
- MsoScheduleIrul(irul, fTrue);
- MsoScheduleIrul(irulIDC_, idc); // non-mapped event (autoclear global)
- /* Propagate the values through the rule network */
- MsoEvaluateEvents(rulevtEmDIALOG);
- // n.b. IDC_ is now autocleared
- /* Evaluate any pending actions */
- if (_pacttbl->pactPending)
- DoPendingActions();
- }
- /* F E M E V A L C H A R */
- /*----------------------------------------------------------------------------
- %%Function: FEmEvalChar
- %%Contact: daleg
- Event Driver for CHAR events in Event Monitor.
- Evaluate CHAR (KEYBOARD) events within the Event Monitor rulebase.
- Return whether or not it was handled.
- ----------------------------------------------------------------------------*/
- int FEmEvalChar(
- XCHAR wch,
- MSOCP cpIp,
- XCHAR *wz,
- int ichMac
- )
- {
- IRUL irul;
- #if FEATURE_DEMO
- /* Make sure we are enabled (e.g. macros not running) */
- if (FEmDisabled())
- return fFalse;
- #endif
- /* Primitive invalidation */
- if (FCheckIfMustReset(wch, ichMac, cpIp))
- InvalLex(vplexs);
- /* If our running state is still valid, adjust run variables */
- if (FInvalLex(vplexs))
- FResetEm((vplexs->cpIp = cpIp) - 1, wz, ichMac);
- /* Create a "lookahead" token to hold chars not yet scanned by lexer */
- vplexs->cchLookahead++;
- _CacheTkTextNext(vplexs);
- /* Look up character in keyword table */
- irul = (IRUL) MsoPkwdLookupName(&wch, 1, &vkwtbEmCHAR_KEYTABLE)->tk;
- debugEM3(2, "CHAR EVENT: %-20.20s for '%s' (0x%x)n",
- LpchRulName(LprulFromIrul(irul)),
- MsoSzFromRgxchDebug(&wch, 1), wch);
- /* Push text token into appropriate queue (resets depth) */
- MsoScheduleIrul(irulCH_, wch);
- MsoScheduleIrul(vlpruls->irulPrimaryEvent = irul, fTrue);
- /* Propagate the values through the rule network */
- MsoEvaluateEvents(rulevtEmCHAR);
- /* Call TOKEN event driver to process any token events */
- FEmEvalToken(cpIp, wz, ichMac);
- }
- /* E M E V A L T K I R U L */
- /*----------------------------------------------------------------------------
- %%Function: EmEvalTkIrul
- %%Contact: daleg
- Evaluate a TOKEN event irul.
- ----------------------------------------------------------------------------*/
- void EmEvalTkIrul(IRUL irul)
- {
- MSORULTK *prultk;
- debugEM2(2, "TOKEN EVENT: %-20.20s "%.100s"n",
- LpchIrulName(irul), MsoSzLexTokenText(vplexs));
- /* Push pending token events into appropriate queues */
- prultk = PrultkFromTokenIrultk(vplexs, vplexs->rultkhToken.irultkMin);
- while (vplexs->rultkhToken.irultkMin != vplexs->rultkhToken.irultkLim)
- {
- #ifdef DEBUG
- if (prultk->tk != irul)
- {
- debugEM2(4, "EXTRA TOKEN EVENT: %-20.20s %dn",
- LpchIrulName(prultk->tk), prultk->lValue);
- debugEM1(8, " at CP %ldn", prultk->cpFirst);
- }
- #endif /* DEBUG */
- /* Push text token into appropriate queue (resets depth) */
- MsoSignalEventIrul(IrulFromTk(prultk->tk), prultk->lValue);
- /* Move to next cache record, wrapping around if necessary */
- IncrTokenPrultk(vplexs, &prultk, &vplexs->rultkhToken.irultkMin);
- }
- /* Push any applicable format tokens into appropriate queues */
- if (vplexs->rultkhFormat.irultkMin != vplexs->rultkhFormat.irultkLim)
- PushIrultkFormatPending();
- /* Push text token into appropriate queue (resets depth) */
- MsoScheduleIrul(irulTOKEN_, vlpruls->irulPrimaryEvent = irul);
- /* Propagate the values through the rule network */
- MsoEvaluateEvents(rulevtEmTOKEN);
- }
- #endif // }
- #if FEATURE_SAMPLE // {
- /* F E M E V A L T O K E N */
- /*----------------------------------------------------------------------------
- %%Function: FEmEvalToken
- %%Contact: daleg
- Event Monitor Event Driver for TOKEN events.
- ----------------------------------------------------------------------------*/
- int FEmEvalToken(
- MSOCP cpIp,
- XCHAR *wz,
- int ichMac
- )
- {
- IRUL irul;
- #if FEATURE_DEMO
- /* Make sure we are enabled (e.g. macros not running) */
- if (FEmDisabled())
- return fFalse;
- #endif
- /* If our running state is still valid, adjust run variables */
- if (!FInvalLex(vplexs))
- {
- long dwz = wz - vplexs->pxchBuffer;
- vplexs->pxchTkStart += dwz;
- vplexs->pxchNext += dwz;
- vplexs->pxchRun += dwz;
- vplexs->pxchBuffer += dwz;
- vplexs->cpIp = cpIp;
- vplexs->cpLim = ichMac;
- vplexs->cchRemain = vplexs->pxchBuffer + vplexs->cpLim
- - vplexs->pxchNext;
- }
- /* Else rescan back up to IP */
- else if (!FResetEm((vplexs->cpIp = cpIp) - 1, wz, ichMac))
- return fFalse;
- /* Inject and eval any complete tokens up to IP */
- while (FValidIrul(irul = IrulFromTk(MsoTkLexTextCpLim(vplexs, cpIp))))
- EmEvalTkIrul(irul);
- /* Evaluate any pending actions */
- if (_pacttbl->pactPending)
- DoPendingActions();
- /* All typed characters must now have been seen by the lexer */
- if (vplexs->cchLookahead > 0)
- vplexs->cchLookahead = 0;
- }
- #endif // }
- #if FEATURE_TEXT // {
- /* P U S H I R U L T K F O R M A T P E N D I N G */
- /*----------------------------------------------------------------------------
- %%Function: PushIrultkFormatPending
- %%Contact: daleg
- Push any pending format tokens into appropriate queues.
- ----------------------------------------------------------------------------*/
- void PushIrultkFormatPending(void)
- {
- MSORULTK *prultk;
- debugEM1(8, "Checking for formatting before CP %ldn",
- CpLexTokenFirst(vplexs));
- prultk = PrultkFormatFromIrultk(vplexs, vplexs->rultkhFormat.irultkMin);
- while (vplexs->rultkhFormat.irultkMin != vplexs->rultkhFormat.irultkLim
- && (prultk->cpFirst
- < CpLexTokenFirst(vplexs) + DcpLexToken(vplexs)
- || (DcpLexToken(vplexs) == 0
- && prultk->cpFirst <= CpLexTokenFirst(vplexs))))
- {
- debugEM2(2, "FORMAT : %-20.20s %ldn",
- LpchIrulName(prultk->tk), prultk->lValue);
- debugEM1(6, " at CP %ldn", prultk->cpFirst);
- /* Push format token into appropriate queue (resets depth) */
- MsoSignalEventIrul(IrulFromTk(prultk->tk), prultk->lValue);
- /* Move to next cache record, wrapping around if necessary */
- IncrFormatPrultk(vplexs, &prultk, &vplexs->rultkhFormat.irultkMin);
- }
- }
- #endif // }
- #if FEATURE_TEXT // {
- /* F R E S E T E M */
- /*----------------------------------------------------------------------------
- %%Function: FResetEm
- %%Contact: daleg
- Reset the Event Monitor rules and lexer due to an IP (cursor) change,
- or due to some form of invalidation.
- ----------------------------------------------------------------------------*/
- int FResetEm(
- MSOCP cpIp,
- XCHAR *wz,
- int ichMac
- )
- {
- MSOCP cpObject = 0;
- IRUL irul;
- /* Initialize lexer to point to start of buffer */
- vplexs->pObjectIp = PObjectCur();
- vplexs->pxchBuffer = vplexs->pxchBufferIp = vplexs->pxchRun = wz;
- MsoLexSetPos(vplexs, cpObject, 0);
- debugEM0(0, "====================================================n");
- debugEM3(0, " FResetEm: RESETTING: pObjectIp %x cpLine %ld cp %ldn",
- vplexs->pObjectIp, cpObject, cpIp);
- debugEM0(0, "====================================================n");
- /* Reset rule base TOKEN state variables */
- MsoClearEventsForRulevts(rulevtEmTOKEN, drulevtToken,
- (vpems->fInternalReset
- ? rultPersistentRule | rultAlwaysPersist
- : rultAlwaysPersist),
- fTrue, fFalse);
- vplexs->wInterval = CIntervalsRulevt(rulevtEmTOKEN);
- /* Reset lexer base state */
- MsoResetLexState(vplexs, fTrue/*fFullReset*/);
- vplexs->cpLim = 0;
- vplexs->fInvalLexer = fFalse;
- /* Mark start of scan */
- MsoCacheTkText(vplexs, irulSTART, fTrue);
- MsoScheduleIrul(irulSTART, fTrue);
- /* Mark start of token cache, but not as events */
- MsoCacheTkText(vplexs, irulEND_OBJ, fTrue);
- vplexs->rultkhToken.irultkMin = vplexs->rultkhToken.irultkLim;
- /* Run only rules not marked as INTERACTIVE_ONLY */
- SetCurrRulg(rulgEmALWAYS);
- /* Inject and eval any complete tokens up to IP */
- while (FValidIrul(irul = IrulFromTk(MsoTkLexTextCpLim(vplexs, cpIp))))
- EmEvalTkIrul(irul);
- /* Run only rules not marked as INTERACTIVE_ONLY */
- SetCurrRulg(rulgEmINTERACTIVE_ONLY);
- /* Mark that we are synchronized */
- vplexs->cchLookahead = 0;
- return fTrue;
- }
- /* F G E T T O K E N T E X T O B J E C T */
- /*----------------------------------------------------------------------------
- FGetTokenTextObject
- %%Contact: smueller
- Determine whether the text of the requested token needs to be fetched
- from the document. If so, do so, leaving the results in ppxch and pcch,
- and return fTrue. Otherwise, return fFalse.
- ----------------------------------------------------------------------------*/
- int WIN_CALLBACK FGetTokenTextObject(
- MSORULTK *prultk,
- const XCHAR **ppxch, // RETURN
- int *pcch, // RETURN
- struct _MSOLEXS *plexs
- )
- {
- if (plexs->pObject != NULL)
- {
- // NOT SUPPORTED YET
- return fTrue;
- }
- return fFalse;
- }
- /* F G E T N E X T L E X R U N */
- /*----------------------------------------------------------------------------
- %%Function: FGetNextLexRun
- %%Contact: daleg
- Return next run of text within the current object , and set the lexer
- run-state variables.
- For this demo, there ain't any, but we will show a commented-out sample.
- ----------------------------------------------------------------------------*/
- int WIN_CALLBACK FGetNextLexRun(MSOCP cpLim, MSOLEXS *plexs)
- {
- int fStatus = fTrue;
- const XCHAR *pxchPrevEnd = plexs->pxchNext;
- /* If prev run at end of current object, move to next object */
- if (FLexEndOfScan(vplexs))
- {
- /* If still have a pending token, complete it first */
- if (DcpLexCurr(vplexs) > 0)
- return fFalse;
- /* Create exactly one inter-object "created" tkEND_OBJ character */
- if (plexs->fCreateEndObjCh)
- {
- /* Make this run "created" text, i.e. no dcp */
- fStatus = fFalse;
- plexs->cpRun += plexs->ccpRun;
- plexs->ichRun += plexs->cchRun;
- plexs->cchRun = 1;
- plexs->ccpRun = 0;
- #ifdef READY
- /* Mark run as "created", so dcp calcs will work properly */
- plexs->fAdjustTokenCps = fTrue;
- plexs->dcpCreated += 1;
- if (plexs->cpFirstCreated == 0L)
- plexs->cpFirstCreated = plexs->cpRun;
- #endif /* READY */
- }
- /* Else get next object's text */
- else
- {
- if (!FGetNextLexObject(cpLim, plexs))
- return fFalse;
- /* If in object of IP has passed upper lim of scan, block lexer */
- if (plexs->pObject == plexs->pObjectIp && cpLim != msocpMax
- && cpLim <= 0 /* plexs->cpRun */)
- fStatus = fFalse;
- }
- }
- /* Else move to next run */
- else
- {
- plexs->cpRun += plexs->ccpRun;
- plexs->ichRun += plexs->cchRun;
- #ifdef PORT_THIS
- plexs->cchRun = vcchEditText - plexs->ichRun;
- #endif /* PORT_THIS */
- plexs->ccpRun = plexs->cchRun;
- // Reset buffer pointer if run in a different buffer
- #ifdef PORT_THIS
- plexs->pxchBuffer = vszEditText;
- #endif /* PORT_THIS */
- }
- /* Set Run length and pointer */
- plexs->cchRemain = plexs->cchRun;
- plexs->pxchNext = (plexs->pxchRun = plexs->pxchBuffer + plexs->ichRun);
- AssertSz0(pxchPrevEnd == plexs->pxchNext
- || pxchPrevEnd == plexs->pxchTkStart,
- "Discontiguous runs!");
- /* If run starts new text (line), reset non-cached tk start pointer */
- if (pxchPrevEnd == plexs->pxchTkStart)
- plexs->pxchTkStart = plexs->pxchNext;
- return fStatus;
- }
- /* F G E T N E X T L E X O B J E C T */
- /*----------------------------------------------------------------------------
- %%Function: FGetNextLexObject
- %%Contact: daleg
- Set the "run" state variables to the first run of a new object, including
- the text buffer, and the run lengths.
- ----------------------------------------------------------------------------*/
- int WIN_CALLBACK FGetNextLexObject(MSOCP cpLim, MSOLEXS *plexs)
- {
- // If this is the first time thru, do initialization stuff
- if (plexs->ichRun == iNil)
- {
- // YOUR INITS HERE
- }
- // Fetch new object text
- plexs->pObject = PObjectCur();
- // Fetch new text (in our case, it is globally static)
- plexs->pxchBuffer = vszEditText;
- plexs->cchRun = plexs->cpLim = vcchEditText;
- plexs->pxchRun = plexs->pxchBuffer;
- // Set up other state variables
- plexs->ichRun = 0;
- plexs->cpRun = 0;
- plexs->cpObject = 0;
- plexs->ccpRun = plexs->cchRun;
- SetCpLexTokenFirst(vplexs, SetCpLexTokenNext(vplexs, 0));
- return fTrue;
- }
- /* F L E X F O R C E C O M P L E T E */
- /*----------------------------------------------------------------------------
- %%Function: FLexForceComplete
- %%Contact: daleg
- Force the current token to complete within the lexer. This is a callback
- function that gets called when we wish to cause the lexer to finish a
- token without peeking at the next character. This is generally when we
- are moving the IP out of a cell in a table, and wish to perform automatic
- actions anyway.
- Once we have completed the token, we clear the callback flag, to resume
- normal operation.
- ----------------------------------------------------------------------------*/
- int WIN_CALLBACK FLexForceComplete(MSOCP cpLim, MSOLEXS *plexs)
- {
- XCHAR wch;
- /* If in the middle of a token complete it if next is EOO or delim */
- // REVIEW daleg: This should check for more than just spaces after
- if (plexs->iuState > 0
- && (cpLim == vplexs->cpLim
- || (wch = *vplexs->pxchNext) == xchSpace))
- return fTrue;
- /* Do not call this routine next time */
- plexs->pfnlexrunForceComplete = NULL;
- /* Force an END_OBJ token (event) if we are at the cell boundary */
- return (cpLim == vplexs->cpLim);
- }
- #endif // }
- #if YY_BASE // {
- /* P A C T P C A */
- /*----------------------------------------------------------------------------
- %%Function: PactPca
- %%Contact: daleg
- Create a Delayed-Action record, using a MSOCA to define the edit range.
- ----------------------------------------------------------------------------*/
- MSOACT *PactPca(
- MSOACTTBL *pacttbl,
- int actt,
- MSOCA *pca,
- ...
- )
- {
- va_list ap;
- MSOACT *pact;
- /* Safety first: make sure we have an action structure */
- if (!pacttbl)
- return NULL;
- /* Start varargs */
- va_start(ap, pca);
- /* Create a new Delayed Action record, and push arg list into it */
- pact = MsoPactAp(pacttbl, actt,
- (sizeof(MSOCA) + sizeof(long) - 1)/sizeof(long), ap);
- /* End varargs */
- va_end(ap);
- /* Calculate starting CP */
- pact->rec1_ca.ca = *pca;
- /* Insert the MSOACT record into the edit queue in CP sorted order */
- MsoInsertPact(pact, &pacttbl->pactPending);
- return pact;
- }
- #if YY_DELAYED // {
- long WIN_CALLBACK DcpDoAct(
- MSOACT *pact,
- MSOACTTBL *pacttbl,
- long *pdcp,
- MSOCA *pca,
- MSOACT **ppactNext,
- int *pfDiscard
- );
- /* D O P E N D I N G A C T I O N S */
- /*----------------------------------------------------------------------------
- %%Function: DoPendingActions
- %%Contact: daleg
- Execute pending actions in delay action queue.
- ----------------------------------------------------------------------------*/
- void DoPendingActions(void)
- {
- _pacttbl->cpFirstEditPrev = -1;
- _pacttbl->dcpEditPrev = 0;
- _pacttbl->cpLimEdit = 0;
- MsoReversePact(&_pacttbl->pactPending);
- MsoDcpDoActs(&_pacttbl->pactPending, _pacttbl, 0, fTrue, -1, DcpDoAct);
- }
- /* D C P D O A C T */
- /*----------------------------------------------------------------------------
- %%Function: DcpDoAct
- %%Contact: daleg
- Execute the action given by the MSOACT record.
- ----------------------------------------------------------------------------*/
- long WIN_CALLBACK DcpDoAct(
- MSOACT *pact,
- MSOACTTBL *pacttbl,
- long *pdcp,
- MSOCA *pca,
- MSOACT **ppactNext,
- int *pfDiscard
- )
- {
- switch (pact->rec1.actt)
- {
- #include "emact.c_"
- }
- return 0;
- }
- #endif // }
- #endif // }
- #if FEATURE_DEMO // {
- /* D C P R E P L A C E T E X T */
- /*----------------------------------------------------------------------------
- %%Function: DcpReplaceText
- %%Contact: daleg
- Replace the text range given by the range of chars with the new string.
- ----------------------------------------------------------------------------*/
- int DcpReplaceText(
- void *pObject,
- int cpFirst,
- int cpLim,
- char *sz
- )
- {
- int cch = CchSz(sz);
- int dcp = cch - (cpLim - cpFirst);
- int cchOrig;
- char rgch[cbEditText];
- MSOCP cpIp;
- /* Get current edit control value */
- cchOrig = GetDlgItemText(vhWndDlg, IDC_EDIT1, rgch, cbEditText);
- /* Do not attempt to expand beyond control's capacity. */
- if (cchOrig + dcp >= cbEditText)
- return 0;
- /* Replace the string */
- CopyRgb(rgch + cpLim, rgch + cpLim + dcp, cchOrig - cpLim + 1);
- CopyRgbNo(sz, rgch + cpFirst, cch);
- /* Set the edit control value with the new string, preserving the IP */
- vfSettingDlgItem = fTrue; // Prevent recursion
- SendDlgItemMessage(vhWndDlg, IDC_EDIT1, EM_GETSEL, 0, (LPARAM)&cpIp);
- SendDlgItemMessage(vhWndDlg, IDC_EDIT1, WM_SETTEXT, 0, (LPARAM)&rgch[0]);
- SendDlgItemMessage(vhWndDlg, IDC_EDIT1, EM_SETSEL, cpIp + dcp, cpIp + dcp);
- vcchEditText += dcp;
- vfSettingDlgItem = fFalse;
- debugEM0(2, "Replaced textn");
- return dcp;
- }
- #endif // }
- #if FEATURE_TEXT // {
- /* F C H E C K I F M U S T R E S E T */
- /*----------------------------------------------------------------------------
- %%Function: FCheckIfMustReset
- %%Contact: daleg
- Do a primitive check to see if we should invalidate our running rulebase
- state, and do a full reset scan.
- THIS IS NOT A CANONICAL ROUTINE, but there should be something equivalent
- in each app.
- ----------------------------------------------------------------------------*/
- int FCheckIfMustReset(XCHAR wch, int ichMac, MSOCP cpIp)
- {
- if (wch == xchBackspace)
- return fTrue;
- /* If user typed a new character, emit character event */
- /* REVIEW: pasting will result in multiple new characters, of which we
- only notice the last */
- if (ichMac > vcchPrev)
- {
- Assert (cpIp > 0);
- /* Without notification of IP moves, there is no way to accurately
- identify when lexer needs invalidating; for safety, we could do so
- on every character. For demonstrating the lexer, we'll do so only
- when the IP didn't move forward by exactly one character, which is
- a decent approximation of the right time. */
- /* REVIEW: find a more pleasant way to deal with this, like subclassing
- the edit control to get precise control over notifications. */
- if (cpIp != vcpIpPrev + 1)
- return fTrue;
- }
- return fFalse;
- }
- #endif // }
- #if FEATURE_DEMO // {
- /* N C W R E G I S T E R C L A S S E S */
- /*----------------------------------------------------------------------------
- %%Function: nCwRegisterClasses
- %%Contact: daleg
- Register window classes
- ----------------------------------------------------------------------------*/
- int nCwRegisterClasses(void)
- {
- WNDCLASS wndclass;
- memset(&wndclass, 0x00, sizeof(WNDCLASS));
- /* load WNDCLASS with window's characteristics */
- wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_BYTEALIGNWINDOW;
- wndclass.lpfnWndProc = WndProc;
- /* Extra storage for Class and Window objects */
- wndclass.cbClsExtra = 0;
- wndclass.cbWndExtra = 0;
- wndclass.hInstance = vhInst;
- wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
- wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
- /* Create brush for erasing background */
- wndclass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
- wndclass.lpszMenuName = vszAppName; /* Menu Name is App Name */
- wndclass.lpszClassName = vszAppName; /* Class Name is App Name */
- if (!RegisterClass(&wndclass))
- return -1;
- return (0);
- }
- /* C W C E N T E R */
- /*----------------------------------------------------------------------------
- %%Function: cwCenter
- %%Contact: daleg
- Center the main window.
- ----------------------------------------------------------------------------*/
- void cwCenter(hWnd, top)
- HWND hWnd;
- int top;
- {
- POINT pt;
- RECT swp;
- RECT rParent;
- int iwidth;
- int iheight;
- /* get the rectangles for the parent and the child */
- GetWindowRect(hWnd, &swp);
- GetClientRect(vhWndMain, &rParent);
- /* calculate the height and width for MoveWindow */
- iwidth = swp.right - swp.left;
- iheight = swp.bottom - swp.top;
- /* find the center point and convert to screen coordinates */
- pt.x = (rParent.right - rParent.left) / 2;
- pt.y = (rParent.bottom - rParent.top) / 2;
- ClientToScreen(vhWndMain, &pt);
- /* calculate the new x, y starting point */
- pt.x = pt.x - (iwidth / 2);
- pt.y = pt.y - (iheight / 2);
- /* top will adjust the window position, up or down */
- if (top)
- pt.y = pt.y + top;
- /* move the window */
- MoveWindow(hWnd, pt.x, pt.y, iwidth, iheight, FALSE);
- }
- /* C W U N R E G I S T E R C L A S S E S */
- /*----------------------------------------------------------------------------
- %%Function: CwUnRegisterClasses
- %%Contact: daleg
- Un-register the windows classes.
- ----------------------------------------------------------------------------*/
- void CwUnRegisterClasses(void)
- {
- WNDCLASS wndclass;
- memset(&wndclass, 0x00, sizeof(WNDCLASS));
- UnregisterClass(vszAppName, vhInst);
- }
- #endif // }
- #if FEATURE_DEAD // {
- /* A S S E R T L S Z P R O C */
- /*----------------------------------------------------------------------------
- %%Function: AssertLszProc
- %%Contact: daleg
- Print assertion message, and prompt for whether to (f)ail, or (i)gnore.
- ----------------------------------------------------------------------------*/
- int AssertLszProc(
- const char *szExtra,
- const char *szFile,
- int line
- )
- {
- Fail("ASSERTION FAILED: %s IN %s line %dn", szExtra, szFile, line);
- return 1;
- }
- /* F A I L */
- /*----------------------------------------------------------------------------
- %%Function: Fail
- %%Contact: daleg
- Emit a failure message and exit.
- ----------------------------------------------------------------------------*/
- void __cdecl Fail(const char *sz, ...)
- {
- va_list ap;
- char szBuf[256];
- /* Start variable arglist */
- va_start(ap, sz);
- wvsprintf(szBuf, sz, ap);
- OutputDebugStringA("FATAL ERROR: ");
- OutputDebugStringA(szBuf);
- OutputDebugStringA("n");
- /* End variable arglist */
- va_end(ap);
- // _asm int 3;
- exit(1);
- }
- #endif // }
- #if FEATURE_DEAD // {
- /* F N E N C L P C H */
- /*----------------------------------------------------------------------------
- %%Function: FNeNcLpch
- %%Contact: daleg
- Compare two strings, case insensitive.
- ----------------------------------------------------------------------------*/
- BOOL FNeNcLpch(
- register const uchar *pch1,
- register const uchar *pch2,
- register int cch
- )
- {
- while (cch-- > 0)
- {
- if (ChUpper(*pch1++) != ChUpper(*pch2++))
- return fTrue;
- }
- return fFalse;
- }
- #endif // }