home *** CD-ROM | disk | FTP | other *** search
- #define WIN31
- #include <windows.h>
- #include <penwin.h>
- #include <penwoem.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include "snoop.h"
-
-
- /************************* Module Data **************************************/
-
- //Class name
- static char szSnoopClassMain[] = "SnoopyClass";
-
- //Window Caption
- static char szAppName[] = "SnoopyWindow";
-
- //Name of penwindows dll
- static char szPenWin[] = "penwin.dll";
-
- //Instance handle
- static HANDLE hInstanceCur;
-
- //Main window handle
- static HANDLE hwndWindow;
-
- static TEXTMETRIC tm;
-
- static HANDLE hwndGraph, hwndResult;
- static FARPROC lpfnGraph, lpfnResult, lpfnRoHeditProc;
-
- HCURSOR hcurAltSelect;
-
- //Ink data copy
- static HPENDATA hpendataCopy;
-
- //Ink width
- static int nInkWidth;
-
- //Ink color
- static DWORD rgbInk;
-
- //TRUE if hook has been set
- static BOOL fHookSet;
-
- //TRUE if the current display is to be retained
- static BOOL fHold = FALSE;
-
- //Buffers used in translation
- static char szSyeBuff[2048];
- static char szSyvBuff[2048];
-
- //Mapping table for Gesture Strings
- static SYVID rgGestures[]=
- {
- SYV_EXTENDSELECT, " ExtendSelect! ",
- SYV_UNDO, " Undo! ",
- SYV_COPY, " Copy! ",
- SYV_CUT, " Cut! ",
- SYV_PASTE, " Paste! ",
- SYV_CLEARWORD, " Delete Words!",
- SYV_CORRECT, " Correct! ",
- SYV_BACKSPACE, " Backspace! ",
- SYV_SPACE, " Space! ",
- SYV_RETURN, " Return! ",
- SYV_TAB, " Tab! ",
- SYV_CLEAR, " Delete!",
- };
-
- // Prefix for displaying circled letter gestures
- static char szCircleG[] = "Circle - ";
-
- //Annotation strings
- static char szGraph[] = "Graph";
- static char szResult[] = "Result";
-
- // Ink display offset
- static POINT ptInk;
-
- static POINT grTOrg = {0, 2};
-
- static POINT grOrg;
- static POINT grExt;
-
- static POINT resOrg;
- static POINT resExt;
-
- static POINT resTOrg;
-
- static int grXText, resXText;
-
- static char szInitError[] = "Error during init process";
-
- /****************************************************************************/
-
- int PASCAL WinMain(HANDLE hInstance, HANDLE hPrevInstance,
- LPSTR lpszCommandLine, int cmdShow)
- /*******************************************************************
-
- FUNCTION: WinMain(hInstance, hPrevInstance, lpszCommandLine, cmdShow)
-
- PURPOSE: Windows Entry Point
-
- *******************************************************************/
- {
- MSG msg;
-
- // register classes, init objects, set globals, prefs, etc:
- if (!FInitSnoop(hInstance, hPrevInstance))
- exit(-1);
-
- // Initialize the application instance
- if (FInitInstance(hInstance, hPrevInstance, cmdShow))
- {
- while (GetMessage((LPMSG)&msg, NULL, 0, 0) )
- {
- TranslateMessage((LPMSG)&msg);
- DispatchMessage((LPMSG)&msg);
- }
- }
- else
- msg.wParam = (WPARAM)-1;
-
- return msg.wParam;
- }
-
- BOOL PASCAL FInitSnoop(HANDLE hInstance, HANDLE hPrevInstance)
- /****************************************************************
-
- FUNCTION: FInitSnoop(hInstance, hPrevInstance)
-
- PURPOSE: Init for all instances of the application
-
- COMMENTS: Register the main window class for the first
- instance of the program.
-
- *****************************************************************/
- {
- WNDCLASS wndClass;
-
- hInstanceCur = hInstance; // set global
-
- if (!hPrevInstance)
- {
- // Main Window
- wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
- wndClass.hIcon = LoadIcon(hInstance, (LPSTR)"iconSnoop");
- wndClass.lpszMenuName = NULL;
- wndClass.lpszClassName = (LPSTR)szSnoopClassMain;
- wndClass.hbrBackground = (HBRUSH)COLOR_WINDOW+1;
- wndClass.hInstance = hInstance;
- wndClass.style = CS_VREDRAW | CS_HREDRAW;
- wndClass.lpfnWndProc = SnoopWndProc;
- wndClass.cbClsExtra = 0;
- wndClass.cbWndExtra = 0;
- if (!RegisterClass((LPWNDCLASS) &wndClass))
- return FALSE;
- }
- return TRUE;
- }
-
- BOOL PASCAL FInitInstance(HANDLE hInstance, HANDLE hPrevInstance, int cmdShow)
- /*******************************************************************************
-
- FUNCTION: FInitInstance(hInstance, hPrevInstance, cmdShow)
-
- PURPOSE: Initialize this instance of the application
-
- COMMENTS:
- Create main window. Set the hook so that all recognition
- results are delivered to this instance before being
- passed on to the recipient.
-
- ********************************************************************************/
- {
- HANDLE hPenWin;
-
- //Create the main window
- hwndWindow = CreateWindow((LPSTR)szSnoopClassMain,
- (LPSTR)szAppName,
- WS_OVERLAPPEDWINDOW,
- 0, 0, GetSystemMetrics(SM_CXFULLSCREEN),
- 7 * GetSystemMetrics(SM_CYCAPTION),
- (HWND)NULL,
- (HMENU)LoadMenu(hInstance, MAKEINTRESOURCE(menuSnoop)),
- (HANDLE)hInstance,
- (LPSTR)NULL);
-
- if (!hwndWindow)
- return FALSE;
-
- // Calculate the relative positions of all items on the screen
- CalcTopology(hwndWindow);
-
- // Create the EDIT control to show the Symbol Graph
- hwndGraph = CreateWindow("EDIT", NULL
- , WS_CHILDWINDOW|WS_BORDER|WS_VISIBLE|ES_AUTOHSCROLL|ES_READONLY,
- grOrg.x, grOrg.y,
- grExt.x, grExt.y,
- hwndWindow,
- idGraph,
- (HANDLE)hInstance,
- (LPSTR)NULL);
-
- // Create the EDIT control to show the recognition result
- hwndResult = CreateWindow("EDIT", NULL
- , WS_CHILDWINDOW|WS_BORDER|WS_VISIBLE|ES_AUTOHSCROLL|ES_READONLY
- ,resOrg.x, resOrg.y
- ,resExt.x, resExt.y
- ,hwndWindow
- ,idResult
- ,(HANDLE)hInstance
- ,NULL);
-
-
- //Set the results hook
- fHookSet = SetRecogHook(HWR_RESULTS, HKP_SETHOOK, hwndWindow);
-
- //If any of these steps failed bail out
- if(!hwndGraph || !hwndResult || !fHookSet)
- {
- MessageBox(hwndWindow, szInitError, NULL, MB_ICONEXCLAMATION|MB_OK);
- DestroyWindow(hwndWindow);
- return(FALSE);
- }
-
- // Subclass the controls to show alternate cursor
-
- lpfnRoHeditProc = MakeProcInstance((FARPROC)RoHeditProc, hInstanceCur);
-
- lpfnGraph = (FARPROC)SetWindowLong(hwndGraph, GWL_WNDPROC, (LPARAM)lpfnRoHeditProc);
- lpfnResult = (FARPROC)SetWindowLong(hwndResult, GWL_WNDPROC, (LPARAM)lpfnRoHeditProc);
-
- // Load the alternate cursor from penwin.dll
- hPenWin = LoadLibrary(szPenWin);
- hcurAltSelect = LoadCursor(hPenWin, IDC_ALTSELECT);
- FreeLibrary(hPenWin);
-
- ShowWindow(hwndWindow, cmdShow);
- UpdateWindow(hwndWindow);
-
- return(TRUE);
- }
-
- long FAR PASCAL __export SnoopWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
- /***************************************************************************
-
- FUNCTION: SnoopWndProc(hwnd, message, wParam, lParam)
-
- PURPOSE: Windows message handling procedure
-
- COMMENTS:
- Also handles WM_HOOKRCRESULT which the penwin.dll sends
- to every window that has set the hook.
-
- ***************************************************************************/
- {
- HDC hDC;
- long lRet = 1L;
- static long lCall=0;
- LPRCRESULT lpResT;
- PAINTSTRUCT ps;
-
- switch (message)
- {
- case WM_CREATE:
- EnableMenuItem(GetMenu(hwnd), miRelease, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
- break;
- case WM_SIZE:
- {
- //Recalculate the width of both the edit controls
- grExt.x = resExt.x = LOWORD(lParam) - (max(grXText, resXText)+5) - 5;
- grExt.y = resExt.y = (int)(1.5 * tm.tmHeight);
-
- //Resize them
- if(hwndGraph)
- MoveWindow(hwndGraph, grOrg.x, grOrg.y, grExt.x, grExt.y, TRUE);
- if(hwndResult)
- MoveWindow(hwndResult, resOrg.x, resOrg.y, resExt.x, resExt.y, TRUE);
- }
- break;
- case WM_PAINT:
- if(hpendataCopy)
- {
- hDC = BeginPaint(hwnd, &ps);
- SetBkMode(hDC, TRANSPARENT);
- SetTextColor(hDC, GetSysColor(COLOR_WINDOWTEXT));
-
- //Draw annotation text
- TextOut(hDC, grTOrg.x, grTOrg.y, szGraph, _fstrlen(szGraph));
- TextOut(hDC, resTOrg.x, resTOrg.y, szResult, _fstrlen(szResult));
-
- //Show the ink exactly the user drew it
- RedisplayPenData(hDC, hpendataCopy, &ptInk, NULL, nInkWidth, rgbInk);
-
- EndPaint(hwnd, &ps);
- }
- break;
-
- case WM_HOOKRCRESULT:
- {
- PENDATAHEADER pendataheader;
-
- // Break if we are holding the results of earlier recognition
- if (fHold)
- break;
-
- //Get the pointer to the recognition results structure
- lpResT = (LPRCRESULT)lParam;
-
- //Convert the result into ANSI string
- SyvToStr(lpResT->lpsyv, lpResT->cSyv, szSyvBuff, sizeof(szSyvBuff)-1, FALSE);
-
- //Show it in the Result EDIT control
- SetWindowText(hwndResult, szSyvBuff);
-
- //Convert the symbol graph into ANSI string
- SyvToStr(lpResT->syg.lpsye, lpResT->syg.cSye, szSyeBuff, sizeof(szSyeBuff)-1, TRUE);
-
- //Show it in the Graph EDIT control
- SetWindowText(hwndGraph, szSyeBuff);
-
- //Delete any older pen data
- if (hpendataCopy)
- DestroyPenData(hpendataCopy);
-
- // Make a copy of the pendata
- hpendataCopy = DuplicatePenData(lpResT->hpendata, 0);
-
- //Save the ink color
- rgbInk = lpResT->lprc->rgbInk;
-
- //and the width
- nInkWidth = lpResT->lprc->nInkWidth;
-
- GetPenDataInfo(hpendataCopy, &pendataheader, NULL, 0);
-
- // Offset the pendata so all points are wrt. the top left
- //corner of it's bounding rect which is at 0, 0
- OffsetPenData(hpendataCopy, -pendataheader.rectBound.left
- ,-pendataheader.rectBound.top);
-
- InvalidateRect(hwnd, NULL, TRUE);
- UpdateWindow(hwnd);
- break;
- }
-
- case WM_CLOSE:
- //Remove the hook
- if(fHookSet)
- SetRecogHook(HWR_RESULTS, HKP_UNHOOK, hwnd);
-
- //Destroy the edit controls
- if(hwndGraph)
- DestroyWindow(hwndGraph);
- if(hwndResult)
- DestroyWindow(hwndResult);
-
- if(lpfnRoHeditProc)
- FreeProcInstance(lpfnRoHeditProc);
-
- if(hcurAltSelect)
- DestroyCursor(hcurAltSelect);
-
- PostQuitMessage(0);
- break;
-
- case WM_COMMAND:
- if (FDispatchMenu(hwnd, wParam, lParam))
- return 1;
- break;
-
- case WM_DESTROY:
- break;
-
- default:
- break;
- }
-
- return DefWindowProc(hwnd, message, wParam, lParam);
- }
-
- VOID PASCAL SyvToStr(LPVOID lpData, int cItem, LPSTR lpstr, int cMax, BOOL fSye)
- /*******************************************************************************
-
- FUNCTION: SyvToStr(lpData, cItem, lpstr, cMax, fSye)
-
- PURPOSE: Converts from SYV to form to ANSI in order to display
-
- COMMENTS:
- Converts meta symbols SYV_BEGINOR, SYV_ENDOR and SYV_OR
- to '{', '}' and '|' respectively.
- Also converts gestures to strings
-
- *******************************************************************************/
- {
- int i, j, cLen;
- SYV syvT;
- char buff[33];
-
- for(i=j=0; i< cItem; ++i)
- {
- syvT = (fSye)?((LPSYE)lpData)[i].syv : ((LPSYV)lpData)[i];
-
- cLen = 1;
- switch(syvT)
- {
- case SYV_BEGINOR:
- lpstr[j] = '{';
- break;
- case SYV_ENDOR:
- lpstr[j] = '}';
- break;
- case SYV_OR:
- lpstr[j] = '|';
- break;
- case SYV_EMPTY:
- lpstr[j] = '_';
- break;
- case SYV_SPACENULL:
- cLen = 0;
- break;
- case SYV_SOFTNEWLINE:
- lpstr[j] = (char)ANSI_PARA_MARK; // parragraph mark
- break;
-
- default:
- //If this is a gesture
- if(FIsGesture(syvT))
- {
- //Convert to string
- cLen = IGestureString(syvT, buff, sizeof(buff)-1);
-
- //And append it to the output buffer.
- if(cLen)
- {
- cLen = ((cLen + j) < cMax)?cLen:(cMax-j-1);
- if(cLen>0)
- _fstrncpy(&lpstr[j], buff, cLen);
- }
- }
- //This could just be a SYV for an ANSI character
- else if(!SymbolToCharacter(&syvT, 1, &lpstr[j], NULL))
- lpstr[j] = '?';
-
- if (lpstr[j] == '\0')
- cLen = 0;
- else if (lpstr[j] == ANSI_NEW_LINE) // New Line
- lpstr[j] = (char)ANSI_PARA_MARK; // parragraph mark
- }
- j += cLen;
- }
- lpstr[j] = '\0';
- }
-
-
- int PASCAL IGestureString(SYV syvGes, LPSTR lpstr, int cMac)
- /*****************************************************************************
-
- FUNCTION: IGestureString(syvGes, lpstr, cMac)
-
- PURPOSE: Convert the SYV for a gesture to a corresponding string
-
- COMMENTS:
-
- the rgGestures table above maps the SYVs to the corresponding strings
-
- *****************************************************************************/
- {
- int i, cLen=0;
- BOOL fFound = FALSE;
-
- // If this a Circled letter gesture
- if (FIsAppGesture(syvGes))
- {
- // Form a string with "circle -" prefix
-
- _fstrncpy(lpstr, szCircleG, sizeof(szCircleG));
- if (syvGes >= SYV_CIRCLEUPA && syvGes <= SYV_CIRCLEUPZ)
- lpstr[sizeof(szCircleG) - 1] = (BYTE)LOWORD(syvGes - SYV_CIRCLEUPA + 'A');
- else
- lpstr[sizeof(szCircleG) - 1] = (BYTE)LOWORD(syvGes - SYV_CIRCLELOA + 'a');
- lpstr[sizeof(szCircleG)] = '\0';
- cLen = sizeof(szCircleG);
- }
- else
- {
- //Must be a command gesture, look in the table
- for(i=0; i<(sizeof(rgGestures)/sizeof(SYVID)); ++i)
- {
- if(syvGes == rgGestures[i].syv)
- {
- cLen = _fstrlen(rgGestures[i].lpstr);
- cLen = min(cLen, cMac);
- _fstrncpy(lpstr, rgGestures[i].lpstr, cLen);
- fFound = TRUE;
- break;
- }
- }
-
- }
- return(cLen);
- }
-
-
- BOOL PASCAL FDispatchMenu(HWND hwnd, WORD wParam, long lParam)
- /*****************************************************************************
-
- FUNCTION: FDispatchMenu(hwnd, wParam, lParam)
-
- PURPOSE: Executes the menu commands
-
- COMMENTS:
-
- *****************************************************************************/
- {
- BOOL fOk = hwnd != NULL;
-
- if (fOk)
- {
- switch (wParam)
- {
- case miHold:
- fHold = TRUE;
- EnableMenuItem(GetMenu(hwnd), miHold, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
- EnableMenuItem(GetMenu(hwnd), miRelease, MF_BYCOMMAND | MF_ENABLED);
- DrawMenuBar(hwnd);
- break;
-
- case miRelease:
- fHold = FALSE;
- EnableMenuItem(GetMenu(hwnd), miRelease, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
- EnableMenuItem(GetMenu(hwnd), miHold, MF_BYCOMMAND | MF_ENABLED);
- DrawMenuBar(hwnd);
- break;
-
- default:
- fOk = FALSE;
- break;
- }
- }
- return fOk;
- }
-
- VOID PASCAL CalcTopology(HWND hwndWindow)
- /*****************************************************************************
-
- FUNCTION: VOID CalcTopology(hwndWindow)
-
- PURPOSE: To calculate the relative positions of various items
- on the screen
-
- COMMENTS:
-
- *****************************************************************************/
- {
- HDC hDC;
-
- hDC = GetDC(hwndWindow);
-
- //Get the textmetrics for the default font in the device context
- GetTextMetrics(hDC, &tm);
-
- grXText = LOWORD(GetTextExtent(hDC, szGraph, _fstrlen(szGraph)));
- resXText = LOWORD(GetTextExtent(hDC, szResult, _fstrlen(szResult)));
-
- grOrg.y = grTOrg.y;
- grOrg.x = grTOrg.x + max(grXText, resXText)+5;
-
- resOrg.x = grOrg.x;
- resOrg.y = (int)(grOrg.y + 1.5 * tm.tmHeight+5);
-
- resTOrg.x = grTOrg.x;
- resTOrg.y = resOrg.y;
-
- // Setup the negative offset for the pendata origin.
- // The x and y values are chosen so that the ink is displayed
- // just below the Hedit control showing the results
-
- ptInk.x = -grOrg.x;
- ptInk.y = (int)(-(resTOrg.y+1.5 * tm.tmHeight+4));
-
- ReleaseDC(hwndWindow, hDC);
- }
-
- /***************************************************************************
-
- FUNCTION: RoHeditProc(hwnd, message, wParam, lParam)
-
- PURPOSE: Subclassed message handling procedure for the two edit controls.
-
- COMMENTS:
- Handles only thw WM_SETCURSOR message. This is done in order
- not to show the pen cursor in a readonly edit control, to
- indicate that the control cannot be written into.
- ***************************************************************************/
- long FAR PASCAL __export RoHeditProc(HWND hwnd, unsigned message, WORD wParam, long lParam)
- {
- switch(message)
- {
- case WM_SETCURSOR:
- SetCursor(hcurAltSelect);
- //Tell windows we took care of it
- return(0L);
- }
- // Pass on all the other messages to the original procedure(s)
- CallWindowProc((hwnd==hwndGraph)?lpfnGraph:lpfnResult, hwnd, message, wParam, lParam);
- }
-