home *** CD-ROM | disk | FTP | other *** search
- /***********************************************************************
- File vbintf.cpp
-
- APIgid32 VB Interface demonstration file for Visual Basic Programmer's Guide to Win32 API
-
- Written By Daniel Appleman
- Copyright (c) 1995 by Desaware - All rights reserved
-
- You have a royalty-free right to use, modify, reproduce and distribute
- this file (and/or any modified versions) in any way you find useful,
- provided that you agree that Desaware and Ziff-Davis Press has no warranty,
- obligation or liability for its contents, and that you
- include an acknowledgement identifying those portions of
- the code that were authored by Desaware. You are also required
- to change the name of the file before distributing modified
- versions of these files.
-
- This file is provided "As-Is". No support is provided for the contents
- or use of this file by Ziff-Davis Press, Daniel Appleman or Desaware.
-
- Refer to the Ziff-Davis Visual Basic Programmer's Guide to the
- Win32 API for further information.
-
-
-
- ************************************************************************/
-
- #include "stdafx.h"
- #include "apigid32.h"
-
- #ifdef _DEBUG
- #undef THIS_FILE
- static char BASED_CODE THIS_FILE[] = __FILE__;
- #endif
-
-
- char tbuf[80]; // Temporary character buffer
-
- STDAPI_(VOID) fToString(double d, char *t)
- {
- int x;
- static int decimalvar, signvar;
- char *buffer;
- buffer = _fcvt(d,5,&decimalvar, &signvar);
- if(signvar) *t++ = '-';
- for(x=0; x<decimalvar && *buffer; x++) *t++ = *buffer++;
- if(*buffer) *t++ = '.';
- while(*buffer) *t++ = *buffer++;
- *t = '\0';
- }
-
-
- /* These function demonstrates passing numeric variables by value, and
- returning numeric variables. The MessageBox statement in each
- routine shows the value of the variable received.
- */
-
- STDAPI_(short) ReceivesInteger(short x)
- {
-
- _itoa(x, tbuf, 10); /* Place value in temporary buffer */
- MessageBox(GetFocus(), (LPSTR)tbuf, (LPSTR)"ReceivesInteger", MB_OK);
- return(x);
- }
-
- STDAPI_(BYTE) ReceivesBytes(BYTE a, BYTE b)
- {
-
- tbuf[0] = a;
- tbuf[1] = b;
- tbuf[2] = '\0';
- MessageBox(GetFocus(), (LPSTR)tbuf, (LPSTR)"ReceivesBytes", MB_OK);
- return('x');
- }
-
-
- STDAPI_(long) ReceivesLong(long y)
- {
- _ltoa(y, tbuf, 10); /* Place value in temporary buffer */
- MessageBox(GetFocus(), (LPSTR)tbuf, (LPSTR)"ReceivesLong", MB_OK);
- return(y);
- }
-
- STDAPI_(float) ReceivesSingle(float f)
- {
- fToString((double)f, tbuf); /* Place value in temporary buffer */
- MessageBox(GetFocus(), (LPSTR)tbuf, (LPSTR)"ReceivesSingle", MB_OK);
- return(f);
- }
-
- STDAPI_(double) ReceivesDouble(double d)
- {
- fToString(d, tbuf); /* Place value in temporary buffer */
- MessageBox(GetFocus(), (LPSTR)tbuf, (LPSTR)"ReceivesDouble", MB_OK);
- return(d);
- }
-
- /* These functions demonstrate passing numeric variables by reference.
- Note how the DLL function can modify the variable used by VB.
- These particular examples are defined as VOID to be used by SUB
- declarations in VB. One could just as easily had these return
- results as done in the examples above.
- */
-
- STDAPI_(VOID) Add5ToInteger(short FAR *x)
- {
- *x = (*x) + 5;
- }
-
- STDAPI_(VOID) Add5ToLong(long FAR *y)
- {
- *y = (*y) + 5;
- }
-
- STDAPI_(VOID) Add5ToSingle(float FAR *f)
- {
- *f = (*f) + 5;
- }
-
- STDAPI_(VOID) Add5ToDouble(double FAR *d)
- {
- *d = (*d) + 5;
- }
-
-
- /* This example shows passing a currency variable by value, and returning
- a currency value */
-
- STDAPI_(currency) ReceivesCurrency(currency curr)
- {
- double tres = 0;
- double factor = 1;
- double tval;
- short x;
-
- /* This currency variable is in base 10 with 4 digits to the right of
- the decimal point */
-
- /* This conversion (for display purposes) involves a loss of precision
- and does not handle negative numbers */
- for(x=0; x<8; x++) { /* Convert the currency into a double data type */
- tval = (double)((WORD)curr.cbuf[x]);
- tres+= tval*factor;
- factor *=256;
- }
- tres/=10000; /* Number is fixed 4 digit precision, so we divide to
- obtain the actual value */
- fToString(tres, tbuf);
- MessageBox(GetFocus(), (LPSTR)tbuf, (LPSTR)"ReceivesCurrency", MB_OK);
-
- return(curr);
- }
-
-
-
- /* This example is call by reference. */
- STDAPI_(void) AddPennyToCurrency(currency FAR *curptr)
- {
- short x;
- WORD temp, toadd;
-
- /* This currency variable is in base 10 with 4 digits to the right of
- the decimal point */
-
- /* Now you can use whatever math routines you have to maniuplate this
- buffer - consider this trivial 'add penny' algorithm */
- toadd = 100; /* 1 penny in this scale */
- for(x=0; x<8 && toadd; x++) {
- temp = curptr->cbuf[x];
- temp+=toadd;
- if(temp>=256) {
- temp-=256; toadd=1; /* Need to continue with carry */
- }
- else toadd=0; /* Finished with the addition */
- curptr->cbuf[x] = (char)temp;
- }
- }
-
- /* Method used for most API calls. VB passes a null terminated string
- */
- STDAPI_(VOID) ReceivesString(LPSTR tptr)
- {
- /* Warning - it's not a copy despite the byval part in the declaration */
- MessageBox(GetFocus(), (LPSTR)tptr, (LPSTR)"ReceivesString", MB_OK);
- }
-
- /* This example shows how a string can be modified - as long as you don't
- go beyond the space allocated */
-
- STDAPI_(VOID) ChangesString(LPSTR tptr)
- {
- /* Warning on overwriting null!!! */
- if (*tptr) *tptr = '!';
- }
-
- /* This example shows how you can pass Visual Basic strings to a DLL,
- but the DLL must be linked with VBAPI.LIB - part of the VB control
- development kit.
- */
-
- STDAPI_(VOID) ReceivesVBString(BSTR *sptr)
- {
- LPSTR tptr;
- WORD vbstrlen;
- WORD x;
- if(!sptr) {
- MessageBox(GetFocus(), "Invalid pointer as parameter", "ReceivesVBString", MB_OK);
- return;
- }
- // We can actually pass *sptr directly to the MessageBox function, but this shows some
- // extra manipulation we can do.
- vbstrlen = SysStringByteLen(*sptr); /* Get length of VB string */
- tptr = (LPSTR)*sptr;
- for(x=0; x<vbstrlen && x<sizeof(tbuf)-1; x++)
- tbuf[x] = *tptr++;
- tbuf[x] = '\0'; /* Null terminate the string */
- /* Remember - VB strings can contain NULLs */
- MessageBox(GetFocus(), (LPSTR)tbuf, (LPSTR)"ReceivesVBString", MB_OK);
- }
-
- /* This example shows how you can change a string that was passed as
- a parameter in a DLL.
- No length restrictions apply when using this technique (other than
- the usual VB string length limits
- */
- STDAPI_(VOID) ChangesVBString(BSTR *sptr)
- {
- if(!sptr) return; // Should never happen - just being paranoid
- if(*sptr) SysFreeString(*sptr);
- *sptr = SysAllocString((OLECHAR *)"Any Length Ok");
- }
-
- /* This example shows how you can return a VB string from a DLL. */
- STDAPI_(BSTR) ReturnsVBString()
- {
- char *a = "This string is created in the DLL";
- return(SysAllocString((OLECHAR *)a));
- }
-
-
- /* Call by reference only */
- STDAPI_(VOID) ReceivesUserType(usertype FAR *u)
- {
- wsprintf((LPSTR)tbuf, (LPSTR)"usertype contains %d %d %d %d",
- u->a, u->b, u->c, u->d);
- MessageBox(GetFocus(), (LPSTR)tbuf, (LPSTR)"ReceivesUserType", MB_OK);
- }
-
- /* VB strings in a user defined type can be accessed. If not initialized,
- they may be null (though I have never actually seen this),
- in which case the DLL can create the string - otherwise
- the DLL should use VBSetHlstr().
- */
- STDAPI_(VOID) AddUserString(usertype FAR *u)
- {
- if(!u->hs) {
- /* Documentation suggests that this case may be possible */
- u->hs = SysAllocString((OLECHAR *)"New string here!");
- }
- else {
- MessageBox(GetFocus(), (LPSTR)u->hs, (LPSTR)"Existing string is:", MB_OK);
- SysFreeString(u->hs);
- u->hs = SysAllocString((OLECHAR *)"Replaced string");
- }
- }
-
- STDAPI_(usertype) ReturnUserType()
- {
- usertype u;
- u.a = 1; u.b = 3; u.c = 5; u.d = 7;
- u.hs = NULL;
- return(u);
- }
-
-
-
- /* Array of integers - Be careful not to exceed the limit of the array!
- This technique can be used on all numeric data types.
- Note the special calling sequence in the VB example.
- It will not work on strings.
- */
-
- STDAPI_(VOID) ReceivesIntArray(short FAR *iptr)
- {
- wsprintf((LPSTR)tbuf, (LPSTR)"1st 4 entries are %d %d %d %d",
- *(iptr), *(iptr+1), *(iptr+2), *(iptr+3));
- MessageBox(GetFocus(), (LPSTR)tbuf, (LPSTR)"ReceivesIntArray", MB_OK);
- (*iptr)++; // Increment the int array for to verify the by reference features (that way you
- // can tell if you are using a temporary copy
- }
-
-
-
-
-
- STDAPI_(short) ReceivesVBArray(SAFEARRAY **lpsa)
- {
- SAFEARRAY *psa;
- short *pdata;
-
- if(!lpsa) return(-1);
- psa = *lpsa;
- if(!psa) return(-1);
- pdata = (short *)psa->pvData;
-
- wsprintf((LPSTR)tbuf, (LPSTR)"Array of %d dimensions, %ld bytes per element\nFlags: %x, First int entry is %d",
- psa->cDims, psa->cbElements, psa->fFeatures, *pdata);
-
- MessageBox(GetFocus(), (LPSTR)tbuf, (LPSTR)"ReceivesVBArray", MB_OK);
- (*pdata)++;
- return(0);
- }
-
-
-
-
-
- STDAPI_(short) ReceivesVariantByVal(VARIANTARG vr)
- {
- short res;
-
- res = vr.vt;
-
- wsprintf((LPSTR)tbuf, (LPSTR)"Variant Type %d", res);
- MessageBox(GetFocus(), (LPSTR)tbuf, (LPSTR)"ReceivesVariantByVal", MB_OK);
- return(0);
- }
-
-
- STDAPI_(VARIANTARG) ReceivesVariant(VARIANTARG *vr)
- {
- short res;
- long l = 12345678;
-
- res = vr->vt;
-
- wsprintf((LPSTR)tbuf, (LPSTR)"Variant Type %d", res);
- MessageBox(GetFocus(), (LPSTR)tbuf, (LPSTR)"ReceivesVariantByVal", MB_OK);
- VariantClear(vr);
- vr->vt = VT_I4;
- vr->lVal = l;
- return(*vr);
- }
-
-
- STDAPI_(double) UsesDate(double d)
- {
- fToString(d, tbuf); /* Place value in temporary buffer */
- MessageBox(GetFocus(), (LPSTR)tbuf, (LPSTR)"Date as float", MB_OK);
- return(d+1);
- }
-
- STDAPI_(VOID) ReceivesObject(LPUNKNOWN lpv)
- {
- HRESULT hr;
- LPDISPATCH lpd;
- ITypeInfo *lti;
- BSTR bst, bst2;
- hr = lpv->QueryInterface(IID_IDispatch, (LPVOID FAR *)&lpd);
- if(SUCCEEDED(hr) && lpd) {
- hr = lpd->GetTypeInfo(0, LOCALE_SYSTEM_DEFAULT, <i);
- if(SUCCEEDED(hr) && lti) {
- hr = lti->GetDocumentation(MEMBERID_NIL, &bst, NULL, NULL, NULL);
- if(SUCCEEDED(hr)) {
- bst2 = SysAllocStringByteLen(NULL, SysStringLen(bst));
- wcstombs((LPSTR)bst2,(LPWSTR)bst,SysStringLen(bst));
- MessageBox(GetFocus(), (LPSTR)bst2, "First Type", MB_OK);
- SysFreeString(bst);
- SysFreeString(bst2);
- }
- lti->Release();
- }
- lpd->Release();
- }
- return;
- }
-
-
- STDAPI_(LPUNKNOWN) ReceivesObject2(LPUNKNOWN lpv)
- {
- lpv->AddRef();
- return(lpv);
- }
-
- STDAPI_(VOID) ChangesObject(LPUNKNOWN lpv1, LPUNKNOWN *lpv2)
- {
- lpv1->AddRef();
- (*lpv2)->Release();
- *lpv2 = lpv1;
- }
-
- STDAPI_(LONG) ShowAddress(LPVOID lp)
- {
- wsprintf((LPSTR)tbuf, (LPSTR)"Received address %.8lx", lp);
- MessageBox(GetFocus(), (LPSTR)tbuf, (LPSTR)"ShowAddress", MB_OK);
- return((LONG)lp);
- }
-
- STDAPI_(VOID) DumpValues(LPVOID lp, short cnt)
- {
- char t2buf[10];
- short x;
- LPBYTE lpb = (LPBYTE)lp;
- tbuf[0] = '\0';
- for (x=0;x<cnt;x++) {
- wsprintf((LPSTR)t2buf,"%.2x ", *(lpb + x));
- lstrcat(tbuf, t2buf);
- }
- MessageBox(GetFocus(), (LPSTR)tbuf, (LPSTR)"Data View", MB_OK);
- }
-
- STDAPI_(VOID) ChangeValues(LPBYTE lp, LPBYTE newval, short cnt)
- {
- short x;
- for (x=0; x<cnt; x++) *lp++ = *newval++;
- }
-