注册 登录
编程论坛 VFP论坛

请问VFP可以订阅windows的事件消息吗?

金太狼 发布于 2024-06-20 10:06, 662 次点击
EVT_HANDLE EvtSubscribe(
  [in] EVT_HANDLE             Session,
  [in] HANDLE                 SignalEvent,
  [in] LPCWSTR                ChannelPath,
  [in] LPCWSTR                Query,
  [in] EVT_HANDLE             Bookmark,
  [in] PVOID                  Context,
  [in] EVT_SUBSCRIBE_CALLBACK Callback,
  [in] DWORD                  Flags
);
VFP可以使用这个API订阅windows事件消息吗?总是失败,头大啊。
14 回复
#2
吹水佬2024-06-20 11:39
请问Callback参数是怎么实现的?

#3
金太狼2024-06-20 12:33
byte sCode[] = {
            0x8B, //MOV EDI,EDI //(主要起到内存对齐的作用,网上查的,不知是否有用,就保存了)
            0xFF,0x55,//PUSH EBP
            0x8B,0xEC,//MOV EBP,ESP
            0x53,//PUSH EBX
            0x51,//PUSH ECX
            0x52,//PUSH EDX
            0xFF,0x75,0x30,//PUSH DWORD PTR [EBP + 0x30]
            0xFF,0x75,0x2C,//PUSH DWORD PTR [EBP + 0x2C]
            0xFF,0x75,0x28,
            0xFF,0x75,0x24,
            0xFF,0x75,0x20,
            0xFF,0x75,0x2C,
            0xFF,0x75,0x28,
            0xFF,0x75,0x24,
            0xFF,0x75,0x20,
            0xFF,0x75,0x1C,
            0xFF,0x75,0x18,
            0xFF,0x75,0x14,
            0xFF,0x75,0x10,
            0xFF,0x75,0x0C,
            0xFF,0x75,0x08, //PUSH DWORD PTR [EBP + 0x08]
            0x68,0x00,0x00,0x00,0x00,//cmd_dz   PUSH vfpcmd
            0x68,0x00,0x00,0x00,0x00,//nums    PUSH nums //参数个数
            0x68,0x00,0x00,0x00,0x00,//vfp_dz  PUSH vfpcom句柄
            0xB8,0x00,0x00,0x00,0x00,//my_fun_dz mov eax my_vfp_func
            0xFF,0xD0, //call eax               
            0x5A, //POP EDX
            0x59, //POP ECX
            0x5B, //POP EBX   
            0x8B,0xE5,//MOV ESP, EBP
            0x5D,//POP EBP
            0xC3,//RET
            0x00,0x00            
    };
基础代码就是在原来行者的基础上做些修改,可以最多接受15个参数,在一般应用上面是没有问题的。
后来,我又单独直接在c++的环境里测试了这里的代码,也是有报错的情况,只是没有把程序卡坏,可以不断运行。
https://learn.,下来我再单独在独立的线程里再试一下,是不是需要独立的线程。
因为这个回调函数是会不断被调用的,某种程度上会阻塞当前线程的,如果在VFP的主线程中调用的话,也是自找麻烦了。麻烦版主帮看看。



[此贴子已经被作者于2024-6-20 12:37编辑过]

#4
金太狼2024-06-20 12:42
测试结果还是成功调用了VFP的callback回调函数,传递参数和返回参数都是正确的,只是执行完后,Wevtapi.dll的后续处理会报错,引起程序崩溃。不得原因。
#5
金太狼2024-06-20 12:50
回调函数的原理就是在 my_vfp_func函数中,根据nums的函数个数,取得相应的参数与vfpcmd拼装成“vfpcmd(参数1,参数2,参数3..)”,然后交vfpcomobj(就是_VFP)的docmd来执行。
这样就一劳永逸了,不需要每次都去写那段汇编代码了。
#6
金太狼2024-06-20 15:02
还真是需要在独立的线程去运行。目前微软官方的c++代码在独立线程中没有问题了。下来再测一下VFP的在独立线程中的情况。
#7
金太狼2024-06-20 16:09
VFP多线程也失败。不玩了。一天时间又花过去了。
#8
吹水佬2024-06-20 16:56
会用C++了,可以不用vfp来处理这些相对较为底层的事情,vfp坐享C++的结果好了。
#9
金太狼2024-06-20 18:56
只有本站会员才能查看附件,请 登录

能成功一盘,不能持续。

[此贴子已经被作者于2024-6-20 19:00编辑过]

#10
金太狼2024-06-21 08:18
坚持学习,总是一件好事情,特别是AI出现后,更是方便学习了。原来有这个讲究,学习行者的代码还没有学透。
AI:
__cdecl调用约定

特点:该调用约定要求调用者负责清理栈上的参数。

应用情景:在__cdecl约定中,一般使用ret指令返回,因为调用者需要自行清理参数,所以被调用函数不需要调整ESP的值。

示例:如果函数原型是int __cdecl myFunction(int a, double b);,在汇编中返回时只需使用ret指令。

__stdcall调用约定

特点:该调用约定要求被调用函数负责清理栈上的参数。

应用情景:在这种情况下,通常使用retn指令并附带立即数来调整ESP的值,从而清除参数。

示例:对于函数void __stdcall myFunction(int a, int b, int c);,如果有三个参数每个参数4字节,则返回指令应为retn 0xC(12字节)。
#11
iswith2024-06-23 21:56
c32.fll有回调函数,但是创建回调参数类型我写了一次真就不想写了,很麻烦!创建回调用C++,个人觉得功能深厚的才驾驭的住,首先那个回调线程安全就难到一大片,其次线程回调的VfP函数调试就没办进行,我用C#创建回调,至少VFP调试还好,偶尔C0005,C++每次进入VFP回调的函数就直接c005,果断放弃,用MS允许给的方式创建回调才安全可靠,原本想写个通用C#版的回调函数,但结果这个参数个数以及类型,我半天,呀。。。。C#是静态语言,搞动态也麻烦呀。。。。。,需要c32.fll的回调VFP写法可以加我WX传送吧。。。。

[此贴子已经被作者于2024-6-23 22:00编辑过]

#12
金太狼2024-06-24 17:58
回复 11楼 iswith
这个回调函数有讲究的。如果是跨线程的回调函数,需要在线程中加载VFPCOM多线程组件来解析执行VFP的回调函数代码。如果不是跨线程的就很简单了,直接用行者的代码就OK了。
#13
金太狼2024-06-24 18:03
回调函数要准确地返回VFP里执行的返回值,这样第三方才会准确获取这个返回值确定其正确的后续处理行为。这个也是非常重要的。行者的代码里是没有这个处理环节的,只能处理一些简单的回调处理。
#14
iswith2024-06-25 17:25
有个不成熟的构想就是做一个c#  Callbak 然后让其回调VFP 函数,再把C# CallBack 指针传给c/c++就可以完成VFP函数线程异/同步回调,至于参数打包成为一个object再到c#去解析这个ojects,这样就有了VFP版的通用回调功能,好像MYFLL就是这么完成的吧。。。
#15
金太狼2024-06-25 18:07
我前面那段汇编代码就是VFP的通用回调函数,可以接受15以内(含)的参数的情况,应该是比较通用的了。
1