home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Visual Basic 4 Unleashed
/
Visual_Basic_4_Unleashed_SAMS_Publishing_1995.iso
/
tedevkit
/
tvb.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-08-17
|
18KB
|
440 lines
/*==============================================================================
TVB.V
Visual Basic VBX shell for the TER DLL
Version 4.0
===========
Sub Systems, Inc.
Software License Agreement (1994)
----------------------------------
This license agreement allows the purchaser the right to modify the
source code to incorporate in an application larger than the editor itself.
The target application must not be a programmer's utility 'like' a text editor.
Sub Systems, Inc. reserves the right to prosecute anybody found to be
making illegal copies of the executable software or compiling the source
code for the purpose of selling there after.
===============================================================================*/
#define STRICT
#include "windows.h"
#include "stdio.h"
#include "stdlib.h"
#include "ctype.h"
#include "dos.h"
#include "fcntl.h"
#include "io.h"
#include "sys\types.h"
#include "sys\stat.h"
#include "string.h"
#include "vbapi.h"
#if defined(__TURBOC__)
#include "alloc.h"
#include "mem.h"
#define _fmemmove memmove
#else
#include "malloc.h"
#include "memory.h"
#define farmalloc _fmalloc
#define farrealloc _frealloc
#define farfree _ffree
#endif
#include "ter.h"
#define PREFIX
#include "tvb.h"
/******************************************************************************
VBINITCC: Visual Basic control intialization function
******************************************************************************/
BOOL FAR PASCAL _export VBINITCC(USHORT usVersion, BOOL rRuntime)
{
return VBRegisterModel(hTvbInst,&model);
}
/******************************************************************************
TerCtlProc: Control Proceedure
******************************************************************************/
LONG FAR PASCAL _export TerCtlProc(HCTL hCtl, HWND hWnd, USHORT message, USHORT wParam, LONG lParam)
{
int processed=FALSE;
LONG result;
LPCTL pCtl;
BOOL far *pBool;
BOOL flag;
CREATESTRUCT FAR *pCS;
if (message>=VBM__BASE) goto VBX_MESSAGE; // process VBX messages
// Apply control style during the WM_NCCREATE message
if (message==WM_NCCREATE || message==WM_CREATE) {
pCtl=(LPCTL)VBDerefControl(hCtl);
pCS=(CREATESTRUCT FAR *)lParam;
pCS->style=pCS->style|pCtl->style; // apply editor control styles
}
// call the ter window message processing function
result=(LONG)VbxProcessMessage(hWnd,message,wParam,lParam,&processed);
// Register the VBX callback with the TER DLL
if (message==WM_CREATE) {
TerRegisterVbxCallback(hWnd,(VBX_CALLBACK)MakeProcInstance((FARPROC)VbxCallback,hTvbInst));
}
// fire events after editor processing
else if (message==WM_KEYDOWN) {
LPINT ptr=&wParam;
VBFireEvent(hCtl,IEVENT_KEYDOWN,(LPVOID)&ptr);
}
else if (message==WM_KEYUP) {
LPINT ptr=&wParam;
VBFireEvent(hCtl,IEVENT_KEYUP,(LPVOID)&ptr);
}
else if (processed) { // fire the events
if (message==WM_LBUTTONDOWN) VBFireEvent(hCtl,IEVENT_CLICK,NULL);
else if (message==WM_LBUTTONDBLCLK) VBFireEvent(hCtl,IEVENT_DBLCLICK,NULL);
else if (message==WM_SETFOCUS) VBFireEvent(hCtl,IEVENT_GOTFOCUS,NULL);
else if (message==WM_KILLFOCUS) VBFireEvent(hCtl,IEVENT_LOSTFOCUS,NULL);
else if (message==WM_KEYDOWN) VBFireEvent(hCtl,IEVENT_KEYDOWN,(LPVOID)&wParam);
else if (message==WM_KEYUP) VBFireEvent(hCtl,IEVENT_KEYUP,(LPVOID)&wParam);
else if (message==WM_CHAR) {
LPINT ptr=&wParam;
VBFireEvent(hCtl,IEVENT_KEYPRESS,(LPVOID)&ptr);
}
return result;
}
else return VBDefControlProc(hCtl, hWnd, message, wParam, lParam);
VBX_MESSAGE:
pCtl=(LPCTL)VBDerefControl(hCtl);
switch (message) {
case VBM_INITIALIZE: // initialize the properties
pCtl->style=TER_WORD_WRAP|TER_VSCROLL; // default TER styles
pCtl->repaint=TRUE; // repaint after each API calls
return NULL; // processed
case VBM_GETPROPERTY: // Inform VB about the current properties
// Process design time propertiles
pBool=(BOOL far *)lParam;
if (wParam==IPROP_WORD_WRAP) (*pBool)=(BOOL)(pCtl->style&TER_WORD_WRAP);
if (wParam==IPROP_VSCROLL) (*pBool)=(BOOL)(pCtl->style&TER_VSCROLL);
if (wParam==IPROP_HSCROLL) (*pBool)=(BOOL)(pCtl->style&TER_HSCROLL);
if (wParam==IPROP_PRINT_VIEW) (*pBool)=(BOOL)(pCtl->style&TER_PRINT_VIEW);
if (wParam==IPROP_SHOW_STATUS) (*pBool)=(BOOL)(pCtl->style&TER_SHOW_STATUS);
if (wParam==IPROP_SHOW_RULER) (*pBool)=(BOOL)(pCtl->style&TER_SHOW_RULER);
if (wParam==IPROP_BORDER_MARGIN)(*pBool)=(BOOL)(pCtl->style&TER_BORDER_MARGIN);
if (wParam==IPROP_OUTPUT_RTF) (*pBool)=(BOOL)(pCtl->style&TER_OUTPUT_RTF);
if (wParam==IPROP_READ_ONLY) (*pBool)=(BOOL)(pCtl->style&TER_READ_ONLY);
if (wParam==IPROP_PAGE_MODE) (*pBool)=(BOOL)(pCtl->style&TER_PAGE_MODE);
if (wParam==IPROP_SHOW_TOOLBAR) (*pBool)=(BOOL)(pCtl->style&TER_SHOW_TOOLBAR);
// Process runtime properties
if (wParam==IPROP_DATA) GetData(hWnd,(HLSTR far *)lParam);
if (wParam==IPROP_REPAINT) (*pBool)=pCtl->repaint;
if (wParam>=FIRST_PROP_DESIGN) return NULL; // processed
break;
case VBM_SETPROPERTY: // set property
// Process design time propertiles
flag=(BOOL)lParam;
if (wParam==IPROP_WORD_WRAP) flag?(pCtl->style=pCtl->style|TER_WORD_WRAP):(pCtl->style=pCtl->style&(~((DWORD)TER_WORD_WRAP)));
if (wParam==IPROP_VSCROLL) flag?(pCtl->style=pCtl->style|TER_VSCROLL):(pCtl->style=pCtl->style&(~((DWORD)TER_VSCROLL)));
if (wParam==IPROP_HSCROLL) flag?(pCtl->style=pCtl->style|TER_HSCROLL):(pCtl->style=pCtl->style&(~((DWORD)TER_HSCROLL)));
if (wParam==IPROP_PRINT_VIEW) flag?(pCtl->style=pCtl->style|TER_PRINT_VIEW):(pCtl->style=pCtl->style&(~((DWORD)TER_PRINT_VIEW)));
if (wParam==IPROP_SHOW_STATUS) flag?(pCtl->style=pCtl->style|TER_SHOW_STATUS):(pCtl->style=pCtl->style&(~((DWORD)TER_SHOW_STATUS)));
if (wParam==IPROP_SHOW_RULER) flag?(pCtl->style=pCtl->style|TER_SHOW_RULER):(pCtl->style=pCtl->style&(~((DWORD)TER_SHOW_RULER)));
if (wParam==IPROP_BORDER_MARGIN)flag?(pCtl->style=pCtl->style|TER_BORDER_MARGIN):(pCtl->style=pCtl->style&(~((DWORD)TER_BORDER_MARGIN)));
if (wParam==IPROP_OUTPUT_RTF) flag?(pCtl->style=pCtl->style|TER_OUTPUT_RTF):(pCtl->style=pCtl->style&(~((DWORD)TER_OUTPUT_RTF)));
if (wParam==IPROP_READ_ONLY) flag?(pCtl->style=pCtl->style|TER_READ_ONLY):(pCtl->style=pCtl->style&(~((DWORD)TER_READ_ONLY)));
if (wParam==IPROP_PAGE_MODE) flag?(pCtl->style=pCtl->style|TER_PAGE_MODE):(pCtl->style=pCtl->style&(~((DWORD)TER_PAGE_MODE)));
if (wParam==IPROP_SHOW_TOOLBAR) flag?(pCtl->style=pCtl->style|TER_SHOW_TOOLBAR):(pCtl->style=pCtl->style&(~((DWORD)TER_SHOW_TOOLBAR)));
// Process runtime properties
if (wParam==IPROP_DATA) SetData(hWnd,(HLSTR)lParam);
if (wParam==IPROP_REPAINT) pCtl->repaint=flag;
if (wParam==IPROP_SET_CHAR_STYLE) SetTerCharStyle(hWnd,(WORD)lParam,TRUE,pCtl->repaint);
if (wParam==IPROP_RESET_CHAR_STYLE) SetTerCharStyle(hWnd,(WORD)lParam,FALSE,pCtl->repaint);
if (wParam==IPROP_PARA_RESET) ParaNormal(hWnd,pCtl->repaint);
if (wParam==IPROP_PARA_STYLE) SetTerParaFmt(hWnd,(WORD)lParam,TRUE,pCtl->repaint);
if (wParam==IPROP_PARA_INDENT_LEFT) ParaLeftIndent(hWnd,flag,pCtl->repaint);
if (wParam==IPROP_PARA_INDENT_RIGHT) ParaRightIndent(hWnd,flag,pCtl->repaint);
if (wParam==IPROP_PARA_INDENT_HANGING)ParaHangingIndent(hWnd,flag,pCtl->repaint);
if (wParam==IPROP_SAVE_FORMAT) TerSetOutputFormat(hWnd,(int)lParam);
if (wParam==IPROP_COMMAND) VbxProcessMessage(hWnd,WM_COMMAND,(WORD)lParam,0L,&processed);
if (wParam==IPROP_READ_FILE) ReadTvbFile(hWnd,(HLSTR)lParam);
if (wParam==IPROP_SAVE_FILE) SaveTvbFile(hWnd,(HLSTR)lParam);
// Design time: recreate the window
if (MODE_DESIGN==VBGetMode()
&& (wParam==IPROP_SHOW_RULER
|| wParam==IPROP_SHOW_STATUS
|| wParam==IPROP_SHOW_TOOLBAR
|| wParam==IPROP_VSCROLL
|| wParam==IPROP_HSCROLL)
&& (VBGetControlHwnd(hCtl)!=NULL)
) VBRecreateControlHwnd(hCtl);
if (wParam>=FIRST_PROP_DESIGN) return NULL; // processed
break;
case VBM_WANTSPECIALKEY: // initialize the properties
return TRUE; // we want all special keys
default:
break;
}
return VBDefControlProc(hCtl, hWnd, message, wParam, lParam);
}
/******************************************************************************
VbxCallback:
This function is called by the DLL to pass the messages intended to the
parent.
******************************************************************************/
LONG FAR PASCAL _export VbxCallback(HWND hWnd, USHORT message, USHORT wParam, LONG lParam)
{
HCTL hCtl=VBGetHwndControl(hWnd);
ERR err;
if (!hCtl) return (LRESULT)FALSE;
// process the link message
if (message==TER_LINK) {
HLSTR hString[2];
struct StrHyperLink far *link;
link=(struct StrHyperLink far *)lParam;
hString[0]=VBCreateHlstr(link->code,lstrlen(link->code)); // pack in the reverse order
hString[1]=VBCreateHlstr(link->text,lstrlen(link->text)); // packed in reverse order
err=VBFireEvent(hCtl,IEVENT_HYPERTEXT,(LPVOID)hString);
if (err) return FALSE; // control may have been deleted
VBDestroyHlstr(hString[0]); // release the basic strings
VBDestroyHlstr(hString[1]);
return TRUE;
}
return (LRESULT)FALSE;
}
/******************************************************************************
GetData:
Get the text data from the TER dll and pass to visual basic.
******************************************************************************/
GetData(HWND hWnd, HLSTR FAR *phStr)
{
HGLOBAL hMem;
long len;
LPSTR pSrc;
if (NULL==(hMem=GetTerBuffer(hWnd,&len))) return FALSE;
if (len>=65400) { // max length of Basic string
MessageBox(NULL,"TER Data Exceeds 65400 bytes!","Data Truncated",MB_OK);
len=65400; // leave one byte for NULL
}
// allocate the basic string
if (NULL==(pSrc=GlobalLock(hMem))) {
MessageBox(NULL,"Ran out of memory","GetData in tvb",MB_OK);
return FALSE;
}
(*phStr)=VBCreateHlstr(pSrc,(USHORT)len);
// Free the gloabl buffer
GlobalUnlock(hMem);
GlobalFree(hMem);
return TRUE;
}
/******************************************************************************
SetData:
Set the control data. The argument specifies the handle to the basic string
******************************************************************************/
SetData(HWND hWnd, HLSTR hStr)
{
LPSTR pSrc,pDest;
USHORT len;
HGLOBAL hMem;
// get the source pointer
pSrc=VBDerefHlstrLen(hStr,&len);
if (pSrc==NULL) len=0;
// Allocate a global buffer
hMem=GlobalAlloc(GMEM_MOVEABLE,len+1);
if (NULL==(pDest=GlobalLock(hMem))) {
MessageBox(NULL,"Ran out of memory to set data","Set Data in tvb",MB_OK);
return FALSE;
}
// Copy the data and unlock the buffer
if (len>0) FarMove(pSrc,pDest,len);
// call the TER DLL
GlobalUnlock(hMem);
SetTerBuffer(hWnd,hMem,len,"",TRUE);
return TRUE;
}
/******************************************************************************
ReadTvbFile:
Assign the contents of a file to the current window.
******************************************************************************/
ReadTvbFile(HWND hWnd, HLSTR hFileName)
{
LPSTR pFileName;
USHORT len;
char file[129];
// get the source pointer
pFileName=VBDerefHlstrLen(hFileName,&len);
if (pFileName==NULL || len==0 || len>(sizeof(file)-1)) return FALSE;
// Extract the file name
FarMove(pFileName,file,len);
file[len]=0;
// call the TER DLL
ReadTerFile(hWnd,file);
return TRUE;
}
/******************************************************************************
SaveTvbFile:
Write the contents of the window to the specified file.
******************************************************************************/
SaveTvbFile(HWND hWnd, HLSTR hFileName)
{
LPSTR pFileName;
USHORT len;
char file[129];
// get the source pointer
pFileName=VBDerefHlstrLen(hFileName,&len);
if (pFileName==NULL || len==0 || len>(sizeof(file)-1)) return FALSE;
// Extract the file name
FarMove(pFileName,file,len);
file[len]=0;
// call the TER DLL
SaveTerFile(hWnd,file);
return TRUE;
}
/******************************************************************************
LibMain: Function to initialize DLL
******************************************************************************/
int CALLBACK LibMain(HINSTANCE hInstance, WORD wDataSeg, WORD cbHeapSize, LPSTR lpszCmdLine)
{
// Initialize the common global variables
hTvbInst=hInstance;
// fill the model structure
model.usVersion=VB_VERSION; // visual basic version supported
model.fl=MODEL_fArrows|MODEL_fFocusOk|MODEL_fInitMsg;
model.pctlproc=(PCTLPROC) TerCtlProc;
model.fsClassStyle=CS_DBLCLKS|CS_OWNDC|CS_HREDRAW|CS_VREDRAW|CS_GLOBALCLASS; // allocate a DC for this class
model.flWndStyle=WS_BORDER; // window styles
model.cbCtlExtra=sizeof(struct StrCtl); // size to hold a pointer
model.idBmpPalette=IDR_TOOLBAR_UP;// first resource id for the icon
model.npszDefCtlName="Ter"; // control name
model.npszClassName=TER_CLASS; // class name
model.npszParentClassName=NULL; // parent class
model.npproplist=TvbProp; // near pointer to the near property pointers
model.npeventlist=TvbEvent; // near pointer to the near event pointers
model.nDefProp=0; // index of the default property
model.nDefEvent=IEVENT_CLICK; // index of the default event
model.nValueProp=0xFF; // default property for asignement
model.usCtlVersion=40; // V4.0 of TER
return TRUE;
}
/*****************************************************************************
WEP:
Library exit routine.
******************************************************************************/
CALLBACK _export WEP(int nParameter)
{
if (nParameter==WEP_SYSTEM_EXIT || nParameter==WEP_FREE_DLL) return 1;
return TRUE;
}
/******************************************************************************
OurPrintf:
This routine formats and display a given set of arguments. The format
is given by the first argument. The argument 2 to n contain the
arguments for the specified format. The function uses MessageBox to
display the formatted string.
******************************************************************************/
OurPrintf(LPSTR fmt,...)
{
LPSTR ArgStart;
char string[256];
ArgStart=(LPSTR) &fmt; // pointer to first argument
ArgStart=&ArgStart[4]; // go past the first argument
wvsprintf(string,fmt,ArgStart);
if (FindWindow("DBWin",NULL)) { // debug window open
lstrcat(string,"\n");
OutputDebugString(string); // send to the debug terminal
}
else MessageBox(NULL,string,NULL,MB_OK);
return TRUE;
}
/******************************************************************************
Copy a specified number of bytes from the source to the destination location.
Both the source and destination locations are specified by using far pointers.
When source and destination memory overlaps, use FarMoveOl function for
a proper trasfer.
Small/Medium Model Note: This function will not work if compiled
as an EXECUTABLE under small/medium model using the Borland compiler.
This is because Borland 'C' does not have a fmemmove library function.
*******************************************************************************/
void FarMove(void far * src,void far * dest, WORD count)
{
WORD i,SrcOff,DestOff,SrcSeg,DestSeg;
char huge *SrcPtr,huge *DestPtr;
if (count==0) return; // nothing to move
SrcSeg=HIWORD((DWORD)(src)); // source segment
DestSeg=HIWORD((DWORD)(dest)); // destination segment
SrcOff=LOWORD((DWORD)(src)); // source offset
DestOff=LOWORD((DWORD)(dest)); // destination offset
// use _fmemmove function if source and destination do not wrap
if ((SrcOff+count)>SrcOff && (DestOff+count)>DestOff) _fmemmove(dest,src,count);
else { // move one by one if source of destination wrap
SrcPtr=(char huge *)src;
DestPtr=(char huge *)dest;
if ( (GetSelectorBase(SrcSeg)+SrcOff)
> (GetSelectorBase(DestSeg)+DestOff) ){ // source at higher address
for (i=0;i<count;i++) DestPtr[i]=SrcPtr[i];
}
else { // src at lower address, move in reverse order
for (i=count-1;i!=0xFFFF;i--) DestPtr[i]=SrcPtr[i];
}
}
return;
}