home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Pier Shareware 6
/
The_Pier_Shareware_Number_6_(The_Pier_Exchange)_(1995).iso
/
035
/
cenvi29.zip
/
TEXTBOSS.LIB
< prev
next >
Wrap
Text File
|
1994-11-16
|
16KB
|
409 lines
// TextBoss.lib - Functions for controlling a windowed DOS or windowed OS/2
// ver.4 session. Read the screen and send keystrokes. These
// routines work with both OS/2 and DOS windows alike, except
// SendDosKey() and SendOS2Key(), and specific routines
// for full-screen OS/2 sessions.
//
//**** KeyStroke(): Press and release a key or combination of keys
// See KeyStroke in KEYPUSH.LIB. KeyStroke() can be used in most
// situations to send keystrokes to windowed DOS sessions.
//
//***** ReadTextWindow(): Return contents of Text window in buffer
// SYNTAX: string ReadTextWindow(int TextWindowHandle[,int DataLen])
// string ReadTextWindow(string WindowTitle[,int DataLen])
// WHERE: TextWindowHandle: Integer identifier for this window
// TextWindowTitle: Partial text title of the window (case-insensitive)
// DataLen: Length of string returned if not NULL
// RETURN: Returns NULL if failed to read, else returns string containing the
// contents of the Text window.
//
//
//***** CopyTextBufferToLines(): Convert Text window string to lines
// SYNTAX: string[] CopyTextBufferToLines(string Buffer,int LineCount)
// WHERE: Buffer: Text buffer as returned by ReadTextWindow()
// LineCount: Return number of lines in the returned array
// MODIFY: Linecount is set to number of returned lines
// RETURN: Returns an array of strings where each element represents
// the next row of the Text screen.
//
//
//***** PasteToTextWindow(): Send characters to a Text window's keyboard
// SYNTAX: void PasteToTextWindow(int TextWindowHandle,string String)
// void PasteToTextWindow(string WindowTitle,string String)
// WHERE: TextWindowHandle: Integer identifier for this window
// TextWindowTitle: Partial text title of the window (case-insensitive)
// String: String of characters to paste into the Text window
// NOTE: If this function fails after about 15 calls, and won't work again,
// then call IBM at 1-800-992-4777 and ask for fix for APAR PJ11939.
// new report # 3X128,PSZ
//
//
//**** SendDosKey(): Send keystrokes (key and scancode) to DOS window running ServeOS2
// SYNTAX: bool SendDosKey(string ServerSpec,string AsciiBuffer)
// bool SendDosKey(string ServerSpec,int KeyCode)
// bool SendDosKey(string ServerSpec,int[] KeyCodes,KeyCount)
// bool SendDosKey(string ServerSpec,int KeyCode,K_CTRL or K_ALT or K_SHIFT)
// WHERE: ServerSpec: Unique 8.3 name that ServeOS2 was started with
// AsciiBuffer: Character string to send, will translate to KeyCode
// KeyCode: ScanCode is high byte, and CharCode is low byte; if not ScanCode
// then this function will determine one
// KeyCodes: An array of ScanCode/CharCode key codes
// KeyCount: How many keys in the KeyCodes array
// K_CTRL or K_ALT or K_SHIFT: Use one of these pre-defined values to send code that
// this key was held while Key is pressed
// RETURN: Return True if communication with DOS works, else False
// NOTE: You cannot send more than 255 keys in one call
//
//
//**** SendOS2Key(): Send keystrokes (key and scancode) to OS/2 window
// SYNTAX: bool SendOS2Key(WindowSpec,string AsciiBuffer)
// bool SendOS2Key(WindowSpec,int KeyCode)
// bool SendOS2Key(WindowSpec,int[] KeyCodes,KeyCount)
// bool SendOS2Key(WindowSpec,int KeyCode,K_CTRL or K_ALT or K_SHIFT)
// WHERE: WindowSpec: integer window handle, or partial title string
// AsciiBuffer: Character string to send, will translate to KeyCode
// KeyCode: ScanCode is high byte, and CharCode is low byte; if not ScanCode
// then this function will determine one
// KeyCodes: An array of ScanCode/CharCode key codes
// KeyCount: How many keys in the KeyCodes array
// K_CTRL | K_ALT | K_SHIFT: Use one of these pre-defined values to send code that
// this key was held while Key is pressed
// RETURN: Return True if communication with window works, else False
//
//
//**** SendFullOS2Key(): Send keystrokes (key and scancode) to full-screen OS/2
//**** session running FSSlave.cmm
// SYNTAX: bool SendFullOS2Key(string FSSlaveSpec,string AsciiBuffer)
// bool SendFullOS2Key(string FSSlaveSpec,int KeyCode)
// bool SendFullOS2Key(string FSSlaveSpec,int[] KeyCodes,KeyCount)
// bool SendFullOS2Key(string FSSlaveSpec,int KeyCode,K_CTRL or K_ALT or K_SHIFT)
// WHERE: FSSlaveSpec: Unique 8.3 name that FSSlave.cmm was started with
// AsciiBuffer: Character string to send, will translate to KeyCode
// KeyCode: ScanCode is high byte, and CharCode is low byte; if not ScanCode
// then this function will determine one
// KeyCodes: An array of ScanCode/CharCode key codes
// KeyCount: How many keys in the KeyCodes array
// K_CTRL or K_ALT or K_SHIFT: Use one of these pre-defined values to send code that
// this key was held while Key is pressed
// RETURN: Return True if communication with FSSlave.cmm works, else False
// NOTE: This function returns before all keystrokes have been removed by
// FSServer.cmm
//
//
//**** ReadFullOS2Text(): Read contents of OS/2 full-screen text window
// SYNTAX: string ReadFullOS2Text(string FSSlaveSpec[,int Col,int Row[,int Timeout]])
// WHERE: FSSlaveSpec: Unique 8.3 name that FSSlave.cmm was started with
// Col,Row: If specified, set how many columns and rows of data
// Timeout: Time to wait, in milliseconds, for data to be filled, if
// not supplied then use a long default
// RETURN: Returns NULL if failed to read, else returns string containing the
// contents of the full-screen OS/2 text window.
//
//
#define K_CTRL 1
#define K_ALT 2
#define K_SHIFT 3
#define K_F1 0x3B00
#define K_F2 0x3C00
#define K_F3 0x3D00
#define K_F4 0x3E00
#define K_F5 0x3F00
#define K_F6 0x4000
#define K_F7 0x4100
#define K_F8 0x4200
#define K_F9 0x4300
#define K_F10 0x4400
#define K_INS 0x5200
#define K_DEL 0x4300
#define K_UP 0x4800
#define K_DOWN 0x5000
#define K_LEFT 0x4B00
#define K_RIGHT 0x4D00
#define K_PGUP 0x4900
#define K_PGDN 0x5100
#define K_END 0x4F00
#define K_HOME 0x4700
#define K_ESC 0x011B
#define K_SHIFT_TAB 0x0F00
#include <WinTools.lib>
#include <ClipBrd.lib>
#include <WinMsg.lib>
#include <FileIO.lib>
#include <NamePipe.lib>
#include <ScanCode.lib>
#include <GiveMem.lib>
ReadTextWindow(pWindowSpec,pDataLen)
{
lTextWindowData = NULL; // assume failure
lDataLen = 0;
if ( (lReadHandle = GetWindowHandle(pWindowSpec)) ) {
// Clear the clipboard, so we'll know when new data is here
PutClipboardData(NULL);
// Send MENU message to the Window to paste all data into the clipboard
#define WM_SYSCOMMAND 0x0021
#define CMDSRC_MENU 2
#define COPY_ALL_COMMAND 0x9E
WinSendMsg(lReadHandle,WM_SYSCOMMAND,COPY_ALL_COMMAND,CMDSRC_MENU);
if ( NULL != (lTextWindowData = GetClipboardData(CF_TEXT,lDataLen)) )
lDataLen = strlen(lTextWindowData);
}
if ( 1 < va_arg() )
pDataLen = lDataLen;
return lTextWindowData;
}
CopyTextBufferToLines(pBuffer,pLineCount)
{
for ( lBuf = pBuffer, pLineCount = 0; lBuf[0];
pLineCount++, lBuf += lStringLen + 1 ) {
lStringLen = strcspn(lBuf,"\n");
strncpy(lLines[pLineCount],lBuf,lStringLen);
}
return lLines;
}
PasteToTextWindow(pWindowSpec,pString)
{
if ( (lTypeHandle = GetWindowHandle(pWindowSpec)) ) {
// Put the pString data into the clipboard
PutClipboardData(pString,1+strlen(pString),CF_TEXT);
// Send menu message to paste from the clipboard
#define PASTE_COMMAND 0x9F
WinPostMsg(lTypeHandle,WM_SYSCOMMAND,PASTE_COMMAND,CMDSRC_MENU,False);
}
}
BuildScanCharBuffer(pArgCount,pKeyCode,pHoldKey,pKeyCount)
// return buffer containing scan-code/keycode, or NULL if error.
// pArgCount shows how many; set pKeyCount to keys in buffer
{
// Build lBuffer based on type of input
lHoldAKeyDown = ( 2 < pArgCount );
lBuffer[0] = '\0'; // initialize lBuffer as a byte buffer
if ( 1 == DataDimension(pKeyCode) ) {
if ( CMM_BYTE == DataType(pKeyCode) ) {
// pKeyCode is an ascii string, for all of string add this key code
// and look up its scan code too
for ( pKeyCount = 0; pKeyCode[pKeyCount]; pKeyCount++ ) {
// char code is written first, then scan code
lBuffer[pKeyCount*2] = pKeyCode[pKeyCount];
lBuffer[1+(pKeyCount*2)] = GetScanCode(pKeyCode[pKeyCount]);
}
} else {
// this is an array of pkeycode, scancode and charcode
for ( pKeyCount = 0; pKeyCount < pHoldKey; pKeyCount++ ) {
// char code is written first, then scan code
lBuffer[pKeyCount*2] = pKeyCode[pKeyCount] & 0xFF;
lBuffer[1+(pKeyCount*2)] = (pKeyCode[pKeyCount] >> 8) & 0xFF;
}
}
} else {
// pKeyCode is a single key if no scan code then must get it
pKeyCount = 1;
lCharCode = pKeyCode & 0xFF;
lScanCode = (pKeyCode & 0xFF00) >> 8;
if ( 0 == lScanCode )
lScanCode = GetScanCode(lCharCode);
if ( lHoldAKeyDown ) {
// adjust keys for pHoldKey
switch( pHoldKey ) {
case K_CTRL:
if ( 'A' <= toupper(lCharCode) && toupper(lCharCode) <= 'Z' )
lCharCode -= 'A' - 1;
else if ( K_F1 <= pKeyCode && pKeyCode <= K_F10 )
lScanCode += 0x23;
else {
switch ( lScanCode ) {
case K_LEFT: lScanCode = 0x73; break;
case K_RIGHT: lScanCode = 0x74; break;
case K_PGUP: lScanCode = 0x84; break;
case K_PGDN: lScanCode = 0x76; break;
case K_END: lScanCode = 0x77; break;
case K_HOME: lScanCode = 0x75; break;
}
}
break;
case K_ALT:
if ( 'A' <= toupper(lCharCode) && toupper(lCharCode) <= 'Z' )
lCharCode = 0;
else if ( K_F1 <= pKeyCode && pKeyCode <= K_F10 )
lScanCode += 0x2D;
else if ( 0x02 <= ScanCode && ScanCode <= 0x0D )
lScanCode += 0x76, lCharCode = 0;
break;
case K_SHIFT:
if ( islower(lCharCode) )
lCharCode = toupper(lCharCode);
else if ( K_F1 <= pKeyCode && pKeyCode <= K_F10 )
lScanCode += 0x19;
break;
default:
printf("\aHoldKey = %d unknown!\a\n",pHoldKey); abort();
}
}
lBuffer[0] = lCharCode;
lBuffer[1] = lScanCode;
}
return ( 0 == pKeyCount ) ? NULL : lBuffer ;
}
SendDosKey(pServerSpec,pKeyCode,pHoldKey)
{
lArgCount = va_arg();
lBuffer = BuildScanCharBuffer(lArgCount,pKeyCode,2<lArgCount?pHoldKey:NULL,lKeyCount);
if ( !lBuffer || 255 < lKeyCount ) return False;
return SendKeyBufferToDOSServer(pServerSpec,lBuffer,lKeyCount);
}
SendKeyBufferToDOSServer(pPipeName,pBuffer,pBufferLen/*max 255*/)
{
bool lSuccess = False; // assume failure
sprintf(lFullName,"\\PIPE\\%s",pPipeName);
if ( !DosCreateNPipe(lFullName,lPipeHandle,
NP_ACCESS_DUPLEX | NP_NOINHERIT,
NP_NOWAIT | NP_TYPE_BYTE | NP_UNLIMITED_INSTANCES | NP_READMODE_BYTE,
4096, 0, 0) ) {
// Give the DOS program up to 10 seconds to open the file
for ( lrepeat = 10 * 10; lRepeat--; ) {
suspend(100);
if ( !DosConnectNPipe(lPipeHandle) ) {
lSuccess = True;
break;
}
}
if ( lSuccess ) {
// change pipe to blocking state to make sure reads and writes are
// finished
DosSetNPHState(lPipeHandle,NP_WAIT | NP_READMODE_BYTE);
_SendBuf[0] = byte(pBufferLen);
memcpy(_SendBuf+1,pBuffer,2*pBufferLen);
if ( DosWrite(lPipeHandle,_SendBuf,2*pBufferLen+1,lBytesSent)
|| lBytesSent != 2*pBufferLen+1 ) {
lSuccess = False;
} else {
// Will be finished when DOS closes the file, which will
// break the pipe. A READ will hang until pipe is broken.
lDummyBuf[0] = '\0';
DosRead(lPipeHandle,lDummyBuf,1,lByteRead);
}
DosDisconnectNPipe(lPipeHandle);
}
DosClose(lPipeHandle);
}
return(lSuccess);
}
SendOS2Key(pWindowSpec,pKeyCode,pHoldKey)
{
lArgCount = va_arg();
lBuffer = BuildScanCharBuffer(lArgCount,pKeyCode,2<lArgCount?pHoldKey:NULL,lKeyCount);
if ( !lBuffer ) return False;
lWindowHandle = GetWindowHandle(pWindowSpec);
if ( !lWindowHandle ) return False;
// the window to send keystrokes to is the FID_CLIENT window
#define FID_CLIENT 0x8008
#define ORD_WIN32WINDOWFROMID 899
lWindowHandle = DynamicLink("PMWIN",ORD_WIN32WINDOWFROMID,BIT32,CDECL,
lWindowHandle,FID_CLIENT);
if ( !lWindowHandle ) return False;
lParam1 = 1 << 16;
for ( lKey = 0; lKey < lKeyCount; lKey++, lBuffer += 2 ) {
#define WM_CHAR 0x007a
WinPostMsg(lWindowHandle,WM_CHAR,lParam1,BLObGet(lBuffer,0,UWORD16));
}
return True;
}
SendFullOS2Key(pFSSlaveSpec,pKeyCode,pHoldKey)
{
lArgCount = va_arg();
lBuffer = BuildScanCharBuffer(lArgCount,pKeyCode,2<lArgCount?pHoldKey:NULL,lKeyCount);
return SendKeyBufferToFullOS2Server(pFSSlaveSpec,lBuffer,lKeyCount);
}
SendKeyBufferToFullOS2Server(pQueueName,pBuffer,pBufferLen,pReadTimeout)
{ // if ReadTimeout then waiting for text to be passed back
sprintf(lQueueName,"\\QUEUES\\%s",pQueueName);
// open queue to send messages
#define ORD_DOS32OPENQUEUE 15
if ( DynamicLink("QUECALLS",ORD_DOS32OPENQUEUE,BIT32,CDECL,
lQueueProcess,lQueueHandle,lQueueName) )
return False;
lKeyBuffer = GiveMemoryToProcess(lQueueProcess);
// if timeout then reading from screen
lTimeout = (ReadingScreen = (3 < va_arg())) ? pReadTimeout : 20000;
poke(lKeyBuffer,ReadingScreen ? 0xFACE : 0xFEED,UWORD16);
// add keystroke as big buffer; but must first give memory to server
poke(lKeyBuffer+2,pBuffer,pBufferLen*2);
#define ORD_DOS32WRITEQUEUE 14
lRc = DynamicLink("QUECALLS",ORD_DOS32WRITEQUEUE,BIT32,CDECL,
lQueueHandle,0,2+pBufferLen*2,lKeyBuffer,0);
// close the queue
#define ORD_DOS32CLOSEQUEUE 11
assert( !DynamicLink("QUECALLS",ORD_DOS32CLOSEQUEUE,BIT32,CDECL,lQueueHandle) );
if ( !lRc ) {
// wait until timeout for buffer to change from 0xFEEF
EndTime = clock() + lTimeout*CLOCKS_PER_SEC/1000;
lRc = 1; // assume failure
do {
suspend(334); // wait 1/3 second
if ( !peek(lKeyBuffer,UWORD16) ) {
pBuffer = peek(lKeyBuffer+2,pBufferLen*2);
lRc = 0;
break;
}
} while ( clock() <= EndTime )
}
TerminateGMSharedMemoryPointer();
return !lRc;
}
ReadFullOS2Text(pFSSlaveSpec,pCol,pRow,pTimeout)
{
lArgCount = va_arg();
lTimeout = lArgCount < 4 ? 15000 : pTimeout ;
#define MAX_ROWCOUNT 50
#define MAX_COLCOUNT 80
lBufferLen = MAX_ROWCOUNT * MAX_COLCOUNT + 2 + 2;
BLObSize(lBLOb,lBufferLen);
if ( !SendKeyBufferToFullOS2Server(pFSSlaveSpec,lBLOb,lBufferLen/2,lTimeout) )
return NULL;
lColCount = BLObGet(lBLOb,0,UWORD16);
lRowCount = BLObGet(lBLOb,2,UWORD16);
lDataLength = lColCount * lRowCount;
lData = BLObGet(lBLOb,4,lColCount * lRowCount);
if ( 1 < lArgCount ) {
pCol = lColCount;
pRow = lRowCount;
}
return lData;
}