无法在 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 类的句柄?的主要内容,如果未能解决你的问题,请参考以下文章