home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic 4 Unleashed / Visual_Basic_4_Unleashed_SAMS_Publishing_1995.iso / tedevkit / tvb.c < prev    next >
C/C++ Source or Header  |  1995-08-17  |  18KB  |  440 lines

  1. /*==============================================================================
  2.    TVB.V
  3.    Visual Basic VBX shell for the TER DLL
  4.  
  5.    Version 4.0
  6.    ===========
  7.    
  8.    Sub Systems, Inc.
  9.    Software License Agreement  (1994)              
  10.    ----------------------------------
  11.    This license agreement allows the purchaser the right to modify the 
  12.    source code to incorporate in an application larger than the editor itself.
  13.    The target application must not be a programmer's utility 'like' a text editor.
  14.    Sub Systems, Inc. reserves the right to prosecute anybody found to be 
  15.    making illegal copies of the executable software or compiling the source
  16.    code for the purpose of selling there after.
  17. ===============================================================================*/
  18.  
  19. #define  STRICT
  20.  
  21. #include "windows.h"
  22. #include "stdio.h"
  23. #include "stdlib.h"
  24. #include "ctype.h"
  25. #include "dos.h"
  26. #include "fcntl.h"
  27. #include "io.h"
  28. #include "sys\types.h"
  29. #include "sys\stat.h"
  30. #include "string.h"
  31. #include "vbapi.h"
  32.  
  33. #if defined(__TURBOC__)
  34.    #include "alloc.h"
  35.    #include "mem.h"
  36.    #define   _fmemmove memmove
  37. #else
  38.    #include "malloc.h"
  39.    #include "memory.h"
  40.    #define farmalloc _fmalloc
  41.    #define farrealloc _frealloc
  42.    #define farfree   _ffree
  43. #endif
  44.  
  45. #include "ter.h"
  46.  
  47. #define  PREFIX 
  48. #include "tvb.h"
  49.  
  50. /******************************************************************************
  51.    VBINITCC: Visual Basic control intialization function
  52. ******************************************************************************/
  53. BOOL FAR PASCAL _export VBINITCC(USHORT usVersion, BOOL rRuntime)
  54. {
  55.     return VBRegisterModel(hTvbInst,&model);
  56. }
  57.  
  58. /******************************************************************************
  59.    TerCtlProc: Control Proceedure
  60. ******************************************************************************/
  61. LONG FAR PASCAL _export TerCtlProc(HCTL hCtl, HWND hWnd, USHORT message, USHORT wParam, LONG lParam)
  62. {
  63.     int processed=FALSE;
  64.     LONG result;
  65.     LPCTL pCtl;
  66.     BOOL far *pBool;
  67.     BOOL flag;
  68.     CREATESTRUCT FAR *pCS;
  69.  
  70.  
  71.     if (message>=VBM__BASE) goto VBX_MESSAGE;   // process VBX messages
  72.  
  73.     // Apply control style during the WM_NCCREATE message
  74.     if (message==WM_NCCREATE || message==WM_CREATE) {
  75.        pCtl=(LPCTL)VBDerefControl(hCtl);
  76.        pCS=(CREATESTRUCT FAR *)lParam;
  77.        pCS->style=pCS->style|pCtl->style;       // apply editor control styles
  78.     }
  79.  
  80.     // call the ter window message processing function
  81.     result=(LONG)VbxProcessMessage(hWnd,message,wParam,lParam,&processed);
  82.  
  83.     // Register the VBX callback with the TER DLL
  84.     if (message==WM_CREATE) {
  85.         TerRegisterVbxCallback(hWnd,(VBX_CALLBACK)MakeProcInstance((FARPROC)VbxCallback,hTvbInst));
  86.     }
  87.     // fire events after editor processing
  88.     else if (message==WM_KEYDOWN) {
  89.         LPINT ptr=&wParam;
  90.         VBFireEvent(hCtl,IEVENT_KEYDOWN,(LPVOID)&ptr);
  91.     }
  92.     else if (message==WM_KEYUP) {
  93.         LPINT ptr=&wParam;
  94.         VBFireEvent(hCtl,IEVENT_KEYUP,(LPVOID)&ptr);
  95.     }
  96.     else if   (processed) {                         // fire the events
  97.        if      (message==WM_LBUTTONDOWN)   VBFireEvent(hCtl,IEVENT_CLICK,NULL);
  98.        else if (message==WM_LBUTTONDBLCLK) VBFireEvent(hCtl,IEVENT_DBLCLICK,NULL);
  99.        else if (message==WM_SETFOCUS)      VBFireEvent(hCtl,IEVENT_GOTFOCUS,NULL);
  100.        else if (message==WM_KILLFOCUS)     VBFireEvent(hCtl,IEVENT_LOSTFOCUS,NULL);
  101.        else if (message==WM_KEYDOWN)       VBFireEvent(hCtl,IEVENT_KEYDOWN,(LPVOID)&wParam);
  102.        else if (message==WM_KEYUP)         VBFireEvent(hCtl,IEVENT_KEYUP,(LPVOID)&wParam);
  103.        else if (message==WM_CHAR) {
  104.            LPINT ptr=&wParam;
  105.            VBFireEvent(hCtl,IEVENT_KEYPRESS,(LPVOID)&ptr);
  106.        }
  107.        return result;
  108.     }
  109.     else return VBDefControlProc(hCtl, hWnd, message, wParam, lParam);
  110.  
  111.     VBX_MESSAGE:
  112.     pCtl=(LPCTL)VBDerefControl(hCtl);
  113.     switch (message) {
  114.         case VBM_INITIALIZE:                      // initialize the properties
  115.            pCtl->style=TER_WORD_WRAP|TER_VSCROLL; // default TER styles
  116.            pCtl->repaint=TRUE;                    // repaint after each API calls
  117.            return NULL;                           // processed
  118.         
  119.         case VBM_GETPROPERTY:                 // Inform VB about the current properties
  120.            // Process design time propertiles
  121.            pBool=(BOOL far *)lParam;
  122.            if (wParam==IPROP_WORD_WRAP)    (*pBool)=(BOOL)(pCtl->style&TER_WORD_WRAP);
  123.            if (wParam==IPROP_VSCROLL)      (*pBool)=(BOOL)(pCtl->style&TER_VSCROLL);
  124.            if (wParam==IPROP_HSCROLL)      (*pBool)=(BOOL)(pCtl->style&TER_HSCROLL);
  125.            if (wParam==IPROP_PRINT_VIEW)   (*pBool)=(BOOL)(pCtl->style&TER_PRINT_VIEW);
  126.            if (wParam==IPROP_SHOW_STATUS)  (*pBool)=(BOOL)(pCtl->style&TER_SHOW_STATUS);
  127.            if (wParam==IPROP_SHOW_RULER)   (*pBool)=(BOOL)(pCtl->style&TER_SHOW_RULER);
  128.            if (wParam==IPROP_BORDER_MARGIN)(*pBool)=(BOOL)(pCtl->style&TER_BORDER_MARGIN);
  129.            if (wParam==IPROP_OUTPUT_RTF)   (*pBool)=(BOOL)(pCtl->style&TER_OUTPUT_RTF);
  130.            if (wParam==IPROP_READ_ONLY)    (*pBool)=(BOOL)(pCtl->style&TER_READ_ONLY);
  131.            if (wParam==IPROP_PAGE_MODE)    (*pBool)=(BOOL)(pCtl->style&TER_PAGE_MODE);
  132.            if (wParam==IPROP_SHOW_TOOLBAR) (*pBool)=(BOOL)(pCtl->style&TER_SHOW_TOOLBAR);
  133.  
  134.            // Process runtime properties
  135.            if (wParam==IPROP_DATA)         GetData(hWnd,(HLSTR far *)lParam);
  136.            if (wParam==IPROP_REPAINT)      (*pBool)=pCtl->repaint;
  137.  
  138.            if (wParam>=FIRST_PROP_DESIGN) return NULL;  // processed
  139.            break;                             
  140.  
  141.         case VBM_SETPROPERTY:                 // set property
  142.            // Process design time propertiles
  143.            flag=(BOOL)lParam;
  144.            if (wParam==IPROP_WORD_WRAP)    flag?(pCtl->style=pCtl->style|TER_WORD_WRAP):(pCtl->style=pCtl->style&(~((DWORD)TER_WORD_WRAP)));
  145.            if (wParam==IPROP_VSCROLL)      flag?(pCtl->style=pCtl->style|TER_VSCROLL):(pCtl->style=pCtl->style&(~((DWORD)TER_VSCROLL)));
  146.            if (wParam==IPROP_HSCROLL)      flag?(pCtl->style=pCtl->style|TER_HSCROLL):(pCtl->style=pCtl->style&(~((DWORD)TER_HSCROLL)));
  147.            if (wParam==IPROP_PRINT_VIEW)   flag?(pCtl->style=pCtl->style|TER_PRINT_VIEW):(pCtl->style=pCtl->style&(~((DWORD)TER_PRINT_VIEW)));
  148.            if (wParam==IPROP_SHOW_STATUS)  flag?(pCtl->style=pCtl->style|TER_SHOW_STATUS):(pCtl->style=pCtl->style&(~((DWORD)TER_SHOW_STATUS)));
  149.            if (wParam==IPROP_SHOW_RULER)   flag?(pCtl->style=pCtl->style|TER_SHOW_RULER):(pCtl->style=pCtl->style&(~((DWORD)TER_SHOW_RULER)));
  150.            if (wParam==IPROP_BORDER_MARGIN)flag?(pCtl->style=pCtl->style|TER_BORDER_MARGIN):(pCtl->style=pCtl->style&(~((DWORD)TER_BORDER_MARGIN)));
  151.            if (wParam==IPROP_OUTPUT_RTF)   flag?(pCtl->style=pCtl->style|TER_OUTPUT_RTF):(pCtl->style=pCtl->style&(~((DWORD)TER_OUTPUT_RTF)));
  152.            if (wParam==IPROP_READ_ONLY)    flag?(pCtl->style=pCtl->style|TER_READ_ONLY):(pCtl->style=pCtl->style&(~((DWORD)TER_READ_ONLY)));
  153.            if (wParam==IPROP_PAGE_MODE)    flag?(pCtl->style=pCtl->style|TER_PAGE_MODE):(pCtl->style=pCtl->style&(~((DWORD)TER_PAGE_MODE)));
  154.            if (wParam==IPROP_SHOW_TOOLBAR) flag?(pCtl->style=pCtl->style|TER_SHOW_TOOLBAR):(pCtl->style=pCtl->style&(~((DWORD)TER_SHOW_TOOLBAR)));
  155.            
  156.            // Process runtime properties
  157.            if (wParam==IPROP_DATA)               SetData(hWnd,(HLSTR)lParam);
  158.            if (wParam==IPROP_REPAINT)            pCtl->repaint=flag;
  159.            if (wParam==IPROP_SET_CHAR_STYLE)     SetTerCharStyle(hWnd,(WORD)lParam,TRUE,pCtl->repaint);
  160.            if (wParam==IPROP_RESET_CHAR_STYLE)   SetTerCharStyle(hWnd,(WORD)lParam,FALSE,pCtl->repaint);
  161.            if (wParam==IPROP_PARA_RESET)         ParaNormal(hWnd,pCtl->repaint);
  162.            if (wParam==IPROP_PARA_STYLE)         SetTerParaFmt(hWnd,(WORD)lParam,TRUE,pCtl->repaint);
  163.            if (wParam==IPROP_PARA_INDENT_LEFT)   ParaLeftIndent(hWnd,flag,pCtl->repaint);
  164.            if (wParam==IPROP_PARA_INDENT_RIGHT)  ParaRightIndent(hWnd,flag,pCtl->repaint);
  165.            if (wParam==IPROP_PARA_INDENT_HANGING)ParaHangingIndent(hWnd,flag,pCtl->repaint);
  166.  
  167.            if (wParam==IPROP_SAVE_FORMAT)        TerSetOutputFormat(hWnd,(int)lParam);
  168.            if (wParam==IPROP_COMMAND)            VbxProcessMessage(hWnd,WM_COMMAND,(WORD)lParam,0L,&processed);
  169.  
  170.            if (wParam==IPROP_READ_FILE)          ReadTvbFile(hWnd,(HLSTR)lParam);
  171.            if (wParam==IPROP_SAVE_FILE)          SaveTvbFile(hWnd,(HLSTR)lParam);
  172.  
  173.            // Design time: recreate the window
  174.            if  (MODE_DESIGN==VBGetMode() 
  175.                 &&  (wParam==IPROP_SHOW_RULER 
  176.                   || wParam==IPROP_SHOW_STATUS
  177.                   || wParam==IPROP_SHOW_TOOLBAR
  178.                   || wParam==IPROP_VSCROLL
  179.                   || wParam==IPROP_HSCROLL)
  180.                 && (VBGetControlHwnd(hCtl)!=NULL)
  181.                 ) VBRecreateControlHwnd(hCtl);
  182.  
  183.            if (wParam>=FIRST_PROP_DESIGN) return NULL;  // processed
  184.            break;
  185.  
  186.         case VBM_WANTSPECIALKEY:                  // initialize the properties
  187.            return TRUE;                           // we want all special keys
  188.  
  189.         default:
  190.            break;
  191.     }
  192.  
  193.     return VBDefControlProc(hCtl, hWnd, message, wParam, lParam);
  194. }
  195.  
  196. /******************************************************************************
  197.    VbxCallback:
  198.    This function is called by the DLL to pass the messages intended to the
  199.    parent.
  200. ******************************************************************************/
  201. LONG FAR PASCAL _export VbxCallback(HWND hWnd, USHORT message, USHORT wParam, LONG lParam)
  202. {
  203.    HCTL hCtl=VBGetHwndControl(hWnd);
  204.    ERR  err;
  205.  
  206.    if (!hCtl) return (LRESULT)FALSE;
  207.  
  208.    // process the link message
  209.    if (message==TER_LINK) {
  210.        HLSTR hString[2];
  211.        struct StrHyperLink far *link;
  212.  
  213.        link=(struct StrHyperLink far *)lParam;
  214.        hString[0]=VBCreateHlstr(link->code,lstrlen(link->code));   // pack in the reverse order
  215.        hString[1]=VBCreateHlstr(link->text,lstrlen(link->text));   // packed in reverse order
  216.        err=VBFireEvent(hCtl,IEVENT_HYPERTEXT,(LPVOID)hString);
  217.        if (err) return FALSE;                         // control may have been deleted
  218.        VBDestroyHlstr(hString[0]);                    // release the basic strings
  219.        VBDestroyHlstr(hString[1]);
  220.        return TRUE;
  221.    }
  222.  
  223.    return (LRESULT)FALSE;
  224. }
  225.  
  226. /******************************************************************************
  227.    GetData:
  228.    Get the text data from the TER dll and pass to visual basic.
  229. ******************************************************************************/
  230. GetData(HWND hWnd, HLSTR FAR *phStr)
  231. {
  232.    HGLOBAL hMem;
  233.    long len;
  234.    LPSTR pSrc;
  235.  
  236.    if (NULL==(hMem=GetTerBuffer(hWnd,&len))) return FALSE;
  237.  
  238.    if (len>=65400) {        // max length of Basic string
  239.       MessageBox(NULL,"TER Data Exceeds 65400 bytes!","Data Truncated",MB_OK);
  240.       len=65400;            // leave one byte for NULL
  241.    }
  242.  
  243.    // allocate the basic string
  244.    if (NULL==(pSrc=GlobalLock(hMem))) {
  245.       MessageBox(NULL,"Ran out of memory","GetData in tvb",MB_OK);
  246.       return FALSE;
  247.    }
  248.    (*phStr)=VBCreateHlstr(pSrc,(USHORT)len);
  249.  
  250.    // Free the gloabl buffer
  251.    GlobalUnlock(hMem);
  252.    GlobalFree(hMem);
  253.  
  254.    return TRUE;
  255. }
  256.  
  257. /******************************************************************************
  258.    SetData:
  259.    Set the control data.  The argument specifies the handle to the basic string
  260. ******************************************************************************/
  261. SetData(HWND hWnd, HLSTR hStr)
  262. {
  263.    LPSTR pSrc,pDest;
  264.    USHORT len;
  265.    HGLOBAL hMem;
  266.  
  267.    // get the source pointer
  268.    pSrc=VBDerefHlstrLen(hStr,&len);
  269.    if (pSrc==NULL) len=0;
  270.  
  271.    // Allocate a global buffer
  272.    hMem=GlobalAlloc(GMEM_MOVEABLE,len+1);
  273.    if (NULL==(pDest=GlobalLock(hMem))) {
  274.       MessageBox(NULL,"Ran out of memory to set data","Set Data in tvb",MB_OK);
  275.       return FALSE;
  276.    }
  277.  
  278.    // Copy the data and unlock the buffer
  279.    if (len>0) FarMove(pSrc,pDest,len);
  280.  
  281.    // call the TER DLL
  282.    GlobalUnlock(hMem);
  283.    SetTerBuffer(hWnd,hMem,len,"",TRUE);
  284.  
  285.    return TRUE;
  286. }
  287.  
  288. /******************************************************************************
  289.    ReadTvbFile:
  290.    Assign the contents of a file to the current window.
  291. ******************************************************************************/
  292. ReadTvbFile(HWND hWnd, HLSTR hFileName)
  293. {
  294.    LPSTR pFileName;
  295.    USHORT len;
  296.    char file[129];
  297.  
  298.    // get the source pointer
  299.    pFileName=VBDerefHlstrLen(hFileName,&len);
  300.    if (pFileName==NULL || len==0 || len>(sizeof(file)-1)) return FALSE;
  301.  
  302.    // Extract the file name
  303.    FarMove(pFileName,file,len);
  304.    file[len]=0;
  305.  
  306.    // call the TER DLL
  307.    ReadTerFile(hWnd,file);
  308.  
  309.    return TRUE;
  310. }
  311.  
  312. /******************************************************************************
  313.    SaveTvbFile:
  314.    Write the contents of the window to the specified file.
  315. ******************************************************************************/
  316. SaveTvbFile(HWND hWnd, HLSTR hFileName)
  317. {
  318.    LPSTR pFileName;
  319.    USHORT len;
  320.    char file[129];
  321.  
  322.    // get the source pointer
  323.    pFileName=VBDerefHlstrLen(hFileName,&len);
  324.    if (pFileName==NULL || len==0 || len>(sizeof(file)-1)) return FALSE;
  325.  
  326.    // Extract the file name
  327.    FarMove(pFileName,file,len);
  328.    file[len]=0;
  329.  
  330.    // call the TER DLL
  331.    SaveTerFile(hWnd,file);
  332.  
  333.    return TRUE;
  334. }
  335.  
  336. /******************************************************************************
  337.    LibMain: Function to initialize DLL
  338. ******************************************************************************/
  339. int CALLBACK LibMain(HINSTANCE hInstance, WORD wDataSeg, WORD cbHeapSize,  LPSTR lpszCmdLine)
  340. {
  341.     // Initialize the common global variables
  342.     hTvbInst=hInstance;
  343.  
  344.     // fill the model structure
  345.     model.usVersion=VB_VERSION;      // visual basic version supported
  346.     model.fl=MODEL_fArrows|MODEL_fFocusOk|MODEL_fInitMsg;
  347.     model.pctlproc=(PCTLPROC) TerCtlProc;
  348.     model.fsClassStyle=CS_DBLCLKS|CS_OWNDC|CS_HREDRAW|CS_VREDRAW|CS_GLOBALCLASS;  // allocate a DC for this class 
  349.     model.flWndStyle=WS_BORDER;      // window styles
  350.     model.cbCtlExtra=sizeof(struct StrCtl);  // size to hold a pointer
  351.     model.idBmpPalette=IDR_TOOLBAR_UP;// first resource id for the icon
  352.     model.npszDefCtlName="Ter";      // control name
  353.     model.npszClassName=TER_CLASS;   // class name
  354.     model.npszParentClassName=NULL;  // parent class
  355.     model.npproplist=TvbProp;        // near pointer to the near property pointers
  356.     model.npeventlist=TvbEvent;      // near pointer to the near event pointers
  357.     model.nDefProp=0;                // index of the default property 
  358.     model.nDefEvent=IEVENT_CLICK;    // index of the default event
  359.     model.nValueProp=0xFF;           // default property for asignement
  360.     model.usCtlVersion=40;           // V4.0 of TER 
  361.  
  362.     return TRUE;
  363. }
  364.  
  365. /*****************************************************************************
  366.     WEP:
  367.     Library exit routine.
  368. ******************************************************************************/
  369. CALLBACK _export WEP(int nParameter)
  370. {
  371.     if (nParameter==WEP_SYSTEM_EXIT || nParameter==WEP_FREE_DLL) return 1;
  372.     
  373.     return TRUE;
  374. }
  375.  
  376. /******************************************************************************
  377.     OurPrintf:
  378.     This routine formats and display a given set of arguments.  The format
  379.     is given by the first argument.  The argument 2 to n contain the
  380.     arguments for the specified format.  The function uses MessageBox to
  381.     display the formatted string.
  382. ******************************************************************************/
  383. OurPrintf(LPSTR fmt,...)
  384. {
  385.     LPSTR ArgStart;
  386.     char string[256];
  387.  
  388.     ArgStart=(LPSTR) &fmt;  // pointer to first argument 
  389.     ArgStart=&ArgStart[4];  // go past the first argument 
  390.     wvsprintf(string,fmt,ArgStart);
  391.     if (FindWindow("DBWin",NULL)) { // debug window open
  392.         lstrcat(string,"\n");
  393.         OutputDebugString(string);  // send to the debug terminal
  394.     }
  395.     else MessageBox(NULL,string,NULL,MB_OK);
  396.     return TRUE;
  397. }
  398.  
  399. /******************************************************************************
  400.     Copy a specified number of bytes from the source to the destination location.
  401.     Both the source and destination locations are specified by using far pointers.
  402.     
  403.     When source and destination memory overlaps,  use FarMoveOl function for
  404.     a proper trasfer.
  405.  
  406.     Small/Medium Model Note:  This function will not work if compiled 
  407.     as an EXECUTABLE under small/medium model using the Borland compiler.
  408.     This is because Borland 'C' does not have a fmemmove library function.
  409. *******************************************************************************/
  410. void FarMove(void far * src,void far * dest, WORD count)
  411. {
  412.     WORD i,SrcOff,DestOff,SrcSeg,DestSeg;
  413.     char huge *SrcPtr,huge *DestPtr;
  414.  
  415.     if (count==0) return;             // nothing to move
  416.  
  417.     SrcSeg=HIWORD((DWORD)(src));     // source segment
  418.     DestSeg=HIWORD((DWORD)(dest));   // destination segment
  419.     SrcOff=LOWORD((DWORD)(src));     // source offset
  420.     DestOff=LOWORD((DWORD)(dest));   // destination offset
  421.  
  422.     // use _fmemmove function if source and destination do not wrap
  423.     if ((SrcOff+count)>SrcOff && (DestOff+count)>DestOff) _fmemmove(dest,src,count);
  424.     else {                            // move one by one if source of destination wrap
  425.         SrcPtr=(char huge *)src;
  426.         DestPtr=(char huge *)dest;
  427.  
  428.         if ( (GetSelectorBase(SrcSeg)+SrcOff)
  429.            > (GetSelectorBase(DestSeg)+DestOff) ){  // source at higher address
  430.            for (i=0;i<count;i++) DestPtr[i]=SrcPtr[i];
  431.         }
  432.         else {  // src at lower address, move in reverse order
  433.            for (i=count-1;i!=0xFFFF;i--) DestPtr[i]=SrcPtr[i];
  434.         }
  435.     }
  436.  
  437.     return;
  438. }
  439.  
  440.