无法在 MFC 无窗口 Activex 中获取 Cwnd 类的句柄?

Posted

技术标签:

【中文标题】无法在 MFC 无窗口 Activex 中获取 Cwnd 类的句柄?【英文标题】:Can't get the handle of a Cwnd Class in MFC Windowless Activex? 【发布时间】:2011-11-24 12:49:31 【问题描述】:

我之前已经问过两个问题,对于每个帖子,我都尝试了一些解决方案,但问题仍然存在。

我的第一个问题是:为什么没有窗口的 Activex 不返回句柄。建议是“更改创建设置以关闭无窗口激活,我已经尝试过了,但 m_hWnd 属性仍然返回零,就像 GetSafeHwnd() 方法所做的那样。

第二个问题是同样的问题,这个问题集中在 COleControl 类和它的祖先 CWnd 上。解决方法是这样“在控件初始化代码的某处创建不可见窗口。处理发送到该窗口的消息,并直接调用控件方法”。所以我这样做了,但创建的类仍然返回零句柄。

这是我新的隐形类源:

// moWind.cpp : implementation file
//
#include "stdafx.h"
#include "PINActive.h"
#include "moWind.h"
#include "include\xfspin.h"
#include <math.h>
// moWind

IMPLEMENT_DYNAMIC(moWind, CWnd)

moWind::moWind()

moWind::~moWind()

//=============================================================
LRESULT moWind::OnExecuteEvent (WPARAM wParam, LPARAM lParam)

    WFSRESULT *pResult = (WFSRESULT *)lParam;
    CString EK=_T("");
    CString str;
    int reskey=0;
    if (pResult->u.dwEventID=WFS_EXEE_PIN_KEY)
           
        LPWFSPINKEY pressedkey;
        pressedkey=(LPWFSPINKEY)pResult->lpBuffer;

    reskey = log10((double)pressedkey->ulDigit) / log10((double)2);

        EK.Format("%d",reskey);
        xfsOnKeyEvent->OnKeyRecieved(reskey);
    
    else
    
        str.Format("ExecuteEvent:  ID = %d\r\n", pResult->u.dwEventID);
    
    MessageBox("a Execute message Recieved");
    return 0;

    
BEGIN_MESSAGE_MAP(moWind, CWnd)
        
    ON_MESSAGE(WFS_EXECUTE_EVENT,OnExecuteEvent)
    
END_MESSAGE_MAP()

这是类的 .h 文件:

// moWind.h
class IXFSEvents

protected:
    IXFSEvents();
    virtual ~IXFSEvents();
public:
    virtual void OnKeyRecieved(int key)=0;
;

class moWind : public CWnd

    DECLARE_DYNAMIC(moWind)

public:
    moWind();
    virtual ~moWind();
    void Register(IXFSEvents* obj)
    
        xfsOnKeyEvent= obj;
    
protected:
    IXFSEvents* xfsOnKeyEvent;
    LRESULT OnExecuteEvent (WPARAM wParam, LPARAM lParam);
    DECLARE_MESSAGE_MAP()
;

最后,这是我在 Activex 中使用此类的方式: 在 myActivex.h 文件中:

包括“moWind.h”

class CmyActivexCtrl : public COleControl, public IXFSEvents

...
Class definition
...
protected:
      moWind tmpWind;
 .
 .
 ;

最后在 myActivex 的创建方法中,我初始化了组件回调方法,并希望得到它的句柄:

CmyActivexCtrl::CmyActivexCtrl()

    InitializeIIDs(&IID_DmyActivex, &IID_DmyActivexEvents);
    tmpWind.Register(this);
    myOtherComponent.WindowsHandle=tmpWind.GetSafeHwnd(); //here my Cwnd derived class returns zero
        //my other component gets the handle and call an API with it to register 
        //the given handle and force the API to send the messages to that handle.

【问题讨论】:

这里有人听我的故事吗? :D 对不起,请问又是什么问题? 好吧,如果它是一个无窗口的 ActiveX 控件,它自然不会有任何窗口句柄。你需要手柄做什么?有很多 COM 接口可以让你在没有窗口句柄的情况下实现事情。请说明。 我需要调用一个 API 来注册句柄以通过它向控件或窗口发送特定的 WM_USER windows 消息。 【参考方案1】:

正如您提到的,您需要一个窗口句柄才能通过它接收用户消息,您始终可以选择创建一个帮助窗口,例如仅消息窗口,请参阅Using CreateWindowEx to Make a Message-Only Window。

对于您的无窗口控件,完全没有任何窗口句柄是可以的,因此除非您自己拥有一个窗口,否则您不能真正依赖句柄的可用性。

【讨论】:

那么我如何以这种方式通过创建的窗口处理消息? 与任何窗口一样 - 定义处理程序并调用它们。第一次机会谷歌结果给了我这个:How to make a Message Only Window,它显示了一个窗口类CMyMessageOnlyWindowClass,这是你在 MFC 中需要的东西。 ATL 代码可能会更简单。

以上是关于无法在 MFC 无窗口 Activex 中获取 Cwnd 类的句柄?的主要内容,如果未能解决你的问题,请参考以下文章

不支持无窗口 ActiveX 控件

我可以编辑具有 x64 ActiveX 控件的 MFC 对话框吗?

无窗口插件1

无法在 MFC ActiveX 中调用方法

activex 如何调用OnDraw函数

MFC中TAB控件的编辑