以下是引用cssnet在2022-3-21 15:22:25的发言:
完啦!vfp2ccallback.cpp + vfp2ccallback.h,光代码就有1300+行,看着眼睛矇、脑壳疼——果断放弃!
今时今日,于我而言:
VFP是玩具,不再是揾食架撑(生产工具)。
vfp真的极少必需要用到callback,API的callback通常都可以NULL,就算是多线程的线程过程,也有其他方法代替多线程。
既然在这提到 vfp to c 的 callback,就来点最精简示例代码参阅
vfpCallback_demo
程序代码:
CLEAR
CLEAR ALL
cDefPath = ADDBS(JUSTPATH(SYS(16)))
SET DEFAULT TO (cDefPath)
DECLARE Integer EnumFontFamilies IN gdi32 As EnumFontFamiliesA Integer hdc ,String lpszFamily ,Integer lpEnumFontFamProc,Integer lParam
DECLARE INTEGER GetDC IN WIN32API INTEGER hwnd
DECLARE LONG vfpGetFunAddr IN vfpCallback long,string@,long
pCallBackFontProc = vfpGetFunAddr(SYS(3095,_VFP), "FontProc", 4)
EnumFontFamiliesA(GetDC(_vfp.hWnd),NULL,pCallBackFontProc,0)
CLEAR ALL
RETURN
FUNCTION FontProc
lparameters lpelfe as long,lpntme as long,fonttype as integer, lparam as long
*!*?lpelfe,lpntme,fonttype,lparam
logfont=sys(2600,lpelfe,28+33)
newtextmetric=sys(2600,lpntme,17*4+1)
facename=alltrim(right(logfont,33))
facename=substr(facename,1,at(0h00,facename)-1)
? facename
return 1
ENDFUNC
程序代码:
/*
vfpCallback.cpp
链接库 ole32、oleaut32
*/
//#define DLLIMPORT __declspec(dllexport)
#include <windows.h>
#include <stdio.h>
#define BUFSIZE 2048
GUID iid_IDispatch = {0x00020400,0x0000,0x0000,{0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}};
GUID iid_NULL = {0x00000000,0x0000,0x0000,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}};
IDispatch* vfpIDispatch;
char vfpFunname[BUFSIZE];
char cmdbuf[BUFSIZE];
wchar_t* CharToWChar(const char *pChar, wchar_t *buf, size_t bufSize)
{
size_t len = MultiByteToWideChar(CP_ACP, 0, pChar, strlen(pChar), NULL, 0);
len = (bufSize<1 ? 0 : (len>bufSize-1 ? bufSize : len));
MultiByteToWideChar(CP_ACP, 0, pChar, strlen(pChar), buf, len);
buf[len] = '\0';
return buf;
}
DISPID GetDispIDByName(IDispatch* This, const char* Name)
{
LCID lcid = GetUserDefaultLCID();
DISPID rgDispId;
wchar_t pwStr[BUFSIZE];
CharToWChar(Name, pwStr, BUFSIZE);
BSTR rgszNames = SysAllocString(pwStr);
HRESULT ret = This->GetIDsOfNames(iid_NULL,(LPOLESTR*)&rgszNames,1,lcid,&rgDispId);
SysFreeString(rgszNames);
if (ret == S_OK)
return rgDispId;
return 0;
}
BOOL Invoke(IDispatch* This, DISPID pid, DISPID* NamedArg, WORD wFlags, VARIANT *varg, UINT Args, VARIANT *var)
{
LCID lcid = GetUserDefaultLCID();
DISPPARAMS params = {NULL,NULL,0,0};
if (varg != NULL)
{
params.rgvarg = varg;
params.rgdispidNamedArgs = NamedArg;
params.cArgs = Args;
= (NamedArg ? 1 : 0);
}
return (This->Invoke(pid,iid_NULL,lcid,wFlags,¶ms,var,NULL,NULL)==S_OK);
}
BOOL InvokeMethod(IDispatch* This, const char* funName, VARIANT *varg, UINT Args, VARIANT *var)
{
DISPID pid = GetDispIDByName(This, funName);
if (pid < 0)
return FALSE;
return Invoke(This, pid, NULL, DISPATCH_METHOD, varg, Args, var);
}
LONG vfpDoCmd(IDispatch* vfpIDispatch, char* vfpCmd)
{
char buffer[BUFSIZE];
VARIANT var, params[10];
LONG ret;
//执行 _VFP 方法 DoCmd()
params[0].vt = VT_BSTR;
params[0].bstrVal = SysAllocString(CharToWChar(vfpCmd, (wchar_t *)buffer, BUFSIZE));
ret = InvokeMethod(vfpIDispatch, "DoCmd", params, 1, &var);
SysFreeString(params[0].bstrVal);
return ret;
}
BOOL CALLBACK vfpCallback(int p1,int p2,int p3,int p4)
{
sprintf(cmdbuf, "%s(%d,%d,%d,%d)", vfpFunname,p1,p2,p3,p4);
return vfpDoCmd(vfpIDispatch, cmdbuf);
}
extern "C" __declspec(dllexport) LONG vfpGetFunAddr(IDispatch* vfp, char* funname, BYTE params)
{
vfpIDispatch = vfp;
sprintf(vfpFunname, "%s", funname);
return (LONG)vfpCallback;
}
BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved)
{
return TRUE;
}