我有一个 C# 控制台应用程序,其中使用 CEN XFS(金融服务扩展)规范来获取 ATM 信息。我正在使用 PInvoke 与 msxfs.dll 进行通信。我正在注册监听 SERVICE_EVENTS、USER_EVENTS、SYSTEM_EVENTS、EXECUTE_EVENTS 调用方法
HRESULT WFSRegister(hService, dwEventClass, hWndReg)
在我的代码中,我创建了一个 WNDCLASSEX 实例,并将一个将处理 Windows 消息的方法分配给它的 lpfnWndProc 字段;然后我使用 RegisterClassEx([In] ref WNDCLASSEX lpWndClass) 注册一个类并创建一个调用 CreateWindowEx 的窗口。
稍后在我的代码中执行 WFS_CMD_CDM_SET_CASH_UNIT_INFO 命令,它返回 WFS_SUCCESS,根据文档,此命令将生成 WFS_SRVE_CDM_CASHUNITINFOCHANGED 服务事件,但我没有收到任何值为 304 的窗口消息(#define WFS_SRVE_CDM_CASHUNITINFOCHANGED (CDM_SERVICE_OFFSET + 4))或任何消息与 XFS 事件相关。
我正在使用的 msxfs.dll 或服务提供商可能没有实现事件通知。 我是否错过了阻止我获取 Windows 消息的某些内容?
为了接收窗口消息,您必须有一个单独的线程,该线程运行相当于标准 Windows 消息泵:
MSG msg = { 0 };
BOOL bRet;
while ((bRet = GetMessage(&msg, hWnd, 0, 0)) != 0) {
if (bRet == -1) {
// handle the error and possibly exit
} else {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
此外,没有必要通过 P/Invoke 来完成所有这些操作 - 您可以通过创建隐藏表单并覆盖
WndProc
在 C# 中本地完成此操作。您仍然必须在单独的线程上创建并运行该表单,并在需要关闭它时使用 Invoke
。
请注意,要完全隐藏表单,除了将
FormBorderStyle
设置为 None
、ShowIcon
为 false
、ShownInTaskbar
为 false、Visible
为 false
、WindowState
为Minimized
,您还应该在表单创建过程中更改扩展窗口样式以包含WS_EX_TOOLWINDOW
:
protected override CreateParams CreateParams {
get {
var Params = base.CreateParams;
Params.ExStyle |= WS_EX_TOOLWINDOW;
return Params;
}
}
最后,请注意,当您收到事件时,需要使用
WFSRESULT
释放通过 lParam
中的 WndProc
获取的 FreeResult()
指针。检查 Buffer
结构的 WFSRESULT
成员并封送其中返回的任何嵌套结构需要在调用 FreeResult()
之前完成,否则数据将无效。