home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
wpentk.zip
/
WBPENTK1.DSK
/
RECODISP.C
< prev
next >
Wrap
C/C++ Source or Header
|
1994-10-06
|
22KB
|
478 lines
/****************************************************************************
* *
* File Name : RECODISP.C *
* *
* Description : Example PENPM Aware Application *
* *
* Copyright (C) 1992 IBM Corporation *
* *
* NOTE: The RECODISP program can NOT run by itself. It must be given as *
* a command name in Gesture setting page. Click right mouse button *
* on a program object in work place shell, for example, calculator. *
* Click the arrow in Open and then Settings. Get the Gesture page *
* and edit a gesture. Highlight a gesture and click the Edit button. *
* Give RECODISP as Command and click OK button. If you give the *
* gesture on the Calculator, the Pen for OS/2 will initiate the *
* RECODISP program. *
* *
* The RECODISP.EXE must be in a directory given in "PATH=" in *
* CONFIG.SYS file. *
* *
* If you access (read/write) any file, you have to give full path *
* for the file. *
* *
* If you call DosQueryCurrentDir or DosQueryCurrentDisk, the root *
* directory of boot disk is usually returned, but this is NOT *
* always true. It is unpredictable. *
* *
* While you process the WM_RECO_COMMAND message, do NOT give a *
* message/dialog box. Simply post a message to yourself to give *
* such box. Otherwise deadlock can occur. *
* *
* The RECODATA can be retrieved by RedRecoDataFromEnv at the *
* WM_CREATE message and by WM_RECO_COMMAND message. The command, *
* arguments, and prefix command handling is NOT same in two messages.*
* Please check the codes below. *
* *
* DISCLAIMER OF WARRANTIES. The following [enclosed] code is *
* sample code created by IBM Corporation. This sample code is not *
* part of any standard or IBM product and is provided to you solely *
* for the purpose of assisting you in the development of your *
* applications. The code is provided "AS IS", without *
* warranty of any kind. IBM shall not be liable for any damages *
* arising out of your use of the sample code, even if they have been *
* advised of the possibility of such damages. *
* *
****************************************************************************/
#define INCL_DOS
#define INCL_PM
#define INCL_GPI
#include <os2.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <penpm.h>
#include "recodisp.h"
int main(VOID)
{
QMSG qmsgMain;
HMQ hmqMain;
HWND hwndFrame;
HWND hwndClient;
ULONG flCreate;
habMain = WinInitialize( (ULONG)NULL );
hmqMain = WinCreateMsgQueue( habMain, 0L );
WinRegisterClass( habMain,
"MyClient",
(PFNWP)ClientWndProc,
CS_SIZEREDRAW,
0UL );
/************************************************************************
* Tell PM that we want the standard frame window, but we will set the *
* the size and position the frame window. This frame window will *
* surround a "MyClient" class client window. *
************************************************************************/
flCreate = FCF_STANDARD & ~FCF_SHELLPOSITION | FCF_ICON;
hwndFrame = WinCreateStdWindow( HWND_DESKTOP,
0L,
(PULONG) &flCreate,
"MyClient",
"",
0L,
(HMODULE)NULL,
ID_MAIN,
(PHWND)&hwndClient );
/*************************************************************************
* Tell PM to display our window at the designated size and place. *
*************************************************************************/
WinSetWindowPos( hwndFrame,
HWND_TOP,
50, 50, 540, 100,
SWP_SIZE | SWP_MOVE | SWP_ACTIVATE | SWP_SHOW );
while( WinGetMsg( habMain, &qmsgMain, (HWND)NULL, 0, 0 ) )
{
WinDispatchMsg( habMain, &qmsgMain );
}
WinDestroyWindow( hwndFrame );
WinDestroyMsgQueue( hmqMain );
WinTerminate( habMain );
return(FALSE);
}
MRESULT EXPENTRY ClientWndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
{
HPS hpsClient;
RECTL rcClient;
APIRET RedRC;
HWND hwndHotspot;
HWND hwndActive;
HWND hwndFocus;
ULONG nLen;
HRECO hReco;
RECOID rID;
CHAR achRecoSubsys[15], achRecoEvent[15];
ULONG ulEventCnt;
ULONG ulVID; /* virtual ID of event */
ULONG ulCC; /* charactor code of event */
static POINTL ptText, ptText2;
static RECODATA *pRecodata;
static BOOL fClearClientWindow = FALSE;
static CHAR achLine[STR_LEN];
static CHAR achLine2[STR_LEN];
static CHAR achMsg[STR_LEN], achMsg2[STR_LEN], achMsg3[STR_LEN];
static PCHAR pCmd, pArg, pPrefixCmd;
static BOOL fInit = FALSE;
switch( msg )
{
case WM_CREATE:
{
/********************************************************************
* The APIs being used in this procedure depend on the PenPM sub- *
* system being correctly initialized. Thus we check to make sure *
* PenPM is up before we do anything else. *
********************************************************************/
if( WrtWaitActive( WRT_IMMEDIATE_RETURN ) )
{
/******************************************************************
* If PenPM is NOT active then put up a message box and terminate *
* the program. *
******************************************************************/
RedRC = 0; /* fool the compiler to aviod warning error */
GetString(hwnd, STR_1, FALSE, RedRC, TRUE);
break;
}
/********************************************************************
* Register reco cmd with PenPM. *
* If you have another command handler running and if you want to *
* remove it, the RedQueryRecoCommand and RedDeregisterRecoCommand *
* API's can be used. *
********************************************************************/
RedRC = RedRegisterRecoCommand( CMD_STR, ID_CMD, hwnd );
if (RedRC)
{
GetString(hwnd, STR_5, TRUE, RedRC, TRUE);
break;
}
/********************************************************************
* Retrieve RECODATA from environment. *
* First put NULL for the buffer pointer to get the actual size. *
* If NULL is given as buffer pointer, then NO error returned. *
* If it is not NULL but the lenght is not sufficient, then *
* REDERR_BUF_TOO_SMALL is returned. *
********************************************************************/
nLen = 0;
RedRecoDataFromEnv( NULL, &nLen );
/********************************************************************
* Check whether this program is initiated by Pen system. *
********************************************************************/
if (!nLen)
{
GetString(hwnd, STR_6, FALSE, RedRC, FALSE);
fInit = TRUE;
nLen = sizeof(RECODATA) + CCHMAXPATH;
WinLoadString(habMain,
0UL,
STR_7,
sizeof(achLine2),
achLine2);
}
/*****************************************************************
* The actual length of data is returned in nLen. *
*****************************************************************/
pRecodata = (RECODATA *) malloc(nLen);
if (!pRecodata)
{
GetString(hwnd, STR_4, FALSE, RedRC, TRUE);
break;
}
if (!fInit)
{
RedRC = RedRecoDataFromEnv( pRecodata, &nLen );
if (RedRC)
{
GetString(hwnd, STR_2, TRUE, RedRC, TRUE);
break;
}
}
/****************************************************************
* Allocate memory for command, argument, and prefix command. *
****************************************************************/
pCmd = malloc(LEN_CMD);
pArg = malloc(LEN_ARG);
pPrefixCmd = malloc(LEN_PCMD);
if (!pCmd || !pArg || !pPrefixCmd)
{
GetString(hwnd, STR_4, FALSE, RedRC, TRUE);
break;
}
/*****************************************************************
* Set position in window. *
*****************************************************************/
ptText.x = ptText2.x = 20;
ptText.y = 26;
ptText2.y = 10;
/*****************************************************************
* Load the strings used to give the RECODATA. *
*****************************************************************/
WinLoadString(habMain, 0UL, STR_3, sizeof(achMsg), achMsg);
WinLoadString(habMain, 0UL, STR_8, sizeof(achMsg2), achMsg2);
WinLoadString(habMain, 0UL, STR_9, sizeof(achMsg3), achMsg3);
/*****************************************************************
* When the RECODATA is retrieved from environment, the Command, *
* Argument, and PrefixCommand are attached after the RECODATA. *
* So, the pszCmd points after the pszPrefixCmd, the pszArg *
* points after the command data, and so forth. *
* All three data are terminated by NULL character. *
* But the retrieval of RECODATA by WM_RECO_COMMAND message is *
* quite different. Check the message below. *
*****************************************************************/
WinPostMsg(hwnd, WM_RECO_INFO, NULL, NULL);
break;
}
case WM_RECO_COMMAND:
{
/********************************************************************
* Replace this message handling code with yours for your own *
* command handler based upon the command and argument in RECODATA. *
********************************************************************/
fInit = FALSE;
/********************************************************************
* Copy the RECODATA. *
********************************************************************/
*pRecodata = * (RECODATA *) PVOIDFROMMP(mp2);
/*****************************************************************
* The RECODATA is retrieved, but the command, argument, and *
* prefix command must be copied too. These data are valid *
* while the WM_RECO_COMMAND message is processed. *
*****************************************************************/
if (pRecodata->pszCommand)
{
strcpy(pCmd, pRecodata->pszCommand);
}
if (pRecodata->pszCmdArgs)
{
strcpy(pArg, pRecodata->pszCmdArgs);
}
if (pRecodata->pszPrefixCmd)
{
strcpy(pPrefixCmd, pRecodata->pszPrefixCmd);
}
/*****************************************************************
* Do NOT call WinMessageBox or WinDlgBox because deadlock can *
* occur. You can check the command or recoID field in RECODATA, *
* and then, based upon the command or ID, you can run program *
* designated for the command or ID. *
*****************************************************************/
WinPostMsg(hwnd, WM_RECO_INFO, NULL, NULL);
return( (MRESULT)(TRUE) );
}
case WM_RECO_INFO:
/*****************************************************************
* Pull out desired data *
*****************************************************************/
if (!fInit)
{
hwndHotspot = pRecodata->hwnd;
hwndActive = pRecodata->hwndActive;
hwndFocus = pRecodata->hwndFocus;
WinLoadString(habMain, 0UL, STR_3, sizeof(achMsg), achMsg);
sprintf(achLine, achMsg, hwndHotspot, hwndActive, hwndFocus);
}
/******************************************************************
* Invalidate the client window to force a repaint *
******************************************************************/
WinInvalidateRect( hwnd, NULL, TRUE );
break;
case WM_PAINT:
{
hpsClient = WinBeginPaint( hwnd, (HPS) NULL, &rcClient );
WinFillRect( hpsClient, &rcClient, SYSCLR_WINDOW );
/********************************************************************
* If there was a clear cmd, then clear the client window. *
********************************************************************/
if( fClearClientWindow )
{
fClearClientWindow = FALSE;
}
else
{
GpiCharStringAt(hpsClient,
&ptText,
STR_LEN,
fInit ? achLine2 : achLine);
if (!fInit)
{
/************************************************************
* Give the subsystem and event names if RECODISP is *
* initiated by gesture. *
************************************************************/
/************************************************************
* Get the reco ID and reco handle from RECODATA. *
* These will give event and subsystem names. *
* Get the virtual ID and character code from RECODATA. *
************************************************************/
rID = pRecodata->id;
hReco = pRecodata->hReco;
ulVID = pRecodata->virtual_id;
ulCC = pRecodata->char_code;
/****************************************************************
* Get the Reco Subsystem name and Number of Events from handle.*
* If you have the subsystem name, then the RedQueryRecoHandle *
* API can be used to get the reco handle. achRecoSubsys has *
* "GESTURE". *
****************************************************************/
RedQueryRecoSubsystem(hReco, achRecoSubsys, &ulEventCnt);
/****************************************************************
* Get the Event Name. *
* If the event name is available, then the event ID can be *
* retrieved by RedRecoIDFromName. *
****************************************************************/
RedRecoNameFromID(hReco, rID, achRecoEvent);
if (ulVID <= 32)
{
ulVID--; /* Adjust subscript */
sprintf(achLine2, achMsg2, achRecoEvent, achVEID[ulVID]);
}
else
{
/***********************************************************
* For alphabet chacter gesture *
***********************************************************/
sprintf(achLine2, achMsg3, achRecoEvent, ulCC );
}
GpiCharStringAt(hpsClient,
&ptText2,
STR_LEN,
achLine2);
}
}
WinEndPaint( hpsClient );
break;
}
case WM_COMMAND:
{
switch( SHORT1FROMMP(mp1) )
{
case ID_CLEAR:
{
/***************************************************************
* If there was a clear cmd, then tell the procedure to clear *
* the client window. *
***************************************************************/
fClearClientWindow = TRUE;
WinInvalidateRect( hwnd, NULL, TRUE );
break;
}
case ID_EXIT:
default:
WinPostMsg(hwnd, WM_CLOSE, NULL, NULL);
/**************************************************************
* Free memory allocated for Recodata, command, argument, *
* and prefix command. *
**************************************************************/
free(pRecodata);
free(pCmd);
free(pArg);
free(pPrefixCmd);
break;
}
break;
}
default:
{
return( WinDefWindowProc( hwnd, msg, mp1, mp2 ) );
}
}
return FALSE;
}
/******************************************************************************
* *
* Function Name: GetString *
* *
* Description : Load string for each string ID. *
* *
* Input: hwnd : Client window handle *
* nStr_ID : String ID *
* fPr : print flag *
* RedRC : if fPr is TRUE, print this return code. *
* fRet : if FALSE, return without deregistering the command handler.*
* *
* Output: None. *
* *
******************************************************************************/
VOID GetString(HWND hwnd, ULONG nStr_ID, BOOL fPr, APIRET RedRC, BOOL fRet)
{
CHAR achLine[80], achMsg[80];
WinLoadString(habMain,
0UL,
nStr_ID,
sizeof(achMsg),
achMsg);
if (fPr)
{
sprintf(achLine, achMsg, RedRC);
}
WinMessageBox( HWND_DESKTOP,
hwnd,
fPr ? achLine : achMsg,
fRet ? NULL : (PSZ) "Warning",
1, MB_OK );
if (!fRet)
{
return;
}
/*****************************************************************
* Deregister the reco command. *
*****************************************************************/
RedDeregisterRecoCommand(hwnd);
WinSendMsg( hwnd, WM_CLOSE, NULL, NULL );
return;
}