求救!!I关于接口OleInPlaceSite::方法GetWindowContext

xwhmm 2013-08-01 02:28:28
IOleInPlaceFrame* pOleInPlaceFrame=NULL;
IOleInPlaceUIWindow* pOleInPlaceUIwindow=NULL;
IOleInPlaceSite* pOleInPlaceSite=NULL;
OLEINPLACEFRAMEINFO oleInPlaceFrameInfo;
HRESULT hr;
oleInPlaceFrameInfo.cb=sizeof(oleInPlaceFrameInfo);
hr = m_pClientSite->QueryInterface(IID_IOleInPlaceSite, (LPVOID *) &pOleInPlaceSite);
if (hr != S_OK) {
return S_OK;
}
RECT rc1,rc2;
hr=pOleInPlaceSite->GetWindowContext(&pOleInPlaceFrame,&pOleInPlaceUIwindow,&rc1,&rc2,&oleInPlaceFrameInfo);
IOleInPlaceSite *pOleInPlaceSite = NULL;

if (NOERROR == m_pClientSite >QueryInterface(IID_IOleInPlaceSite,
(LPVOID *)&pOleInPlaceSite))
{
pOleInPlaceSite->GetWindow((HWND *)&m_hWndParent);
pOleInPlaceSite->Release();
}


想实现传说中在CRicheditCtr中插入一个OLE的小控件,用于显示超链接,控件是有窗口的,窗口也创建成功了,但是控件的窗口不跟着控件的大小一起变化,只好在OnDraw中取到pcRounds来将控件窗口MoveWindow一下,发现这样在富文本中插入控件第一行的时候没有问题,第二行的第一个也没有问题,自动换行后取到的pcRounds也是正确的但是第二行的第二个网格取到的矩形就不正确了,左边和右边是正确的,但是顶变和底边还是第一行的顶边和底边,但是我在双击的时候InPlaceActivate中取到的prcPosRect又是正确的,于是想通GetWindowContext来获取控件在CRicheditCtr中的位置,可是一直失败,下面的GetWindow却能正确执行,取到父窗口的句柄,真不知道怎么回事,初学COM组件,哪位高手知道原因的帮忙一下啊......
...全文
151 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
fishion 2013-08-04
  • 打赏
  • 举报
回复
说说你给窗口发送消息是怎么实现的,我好学习下。
引用 9 楼 xwhmm 的回复:
[quote=引用 6 楼 fishion 的回复:] 需要控件能够响应鼠标点击和鼠标悬乎这一些消息。 插入到richedit的时候,可以在父窗口richedit中判断,因为插入到richedit中的窗口组件会变成无窗口形式的,如果你把你的组件放到其它地方,就可以触发一般的窗口消息了
我已经可以实现容器给无窗口控件发送消息了,但是又遇到一个问题,好比我在富文本编辑框中插入了三个控件,我怎么能再次取到这些控件呢?就是说针对某个控件操作?[/quote] 所以可以在dwUser里添加特定的标识数据来表示不同的控件
xwhmm 2013-08-03
  • 打赏
  • 举报
回复
引用 6 楼 fishion 的回复:
需要控件能够响应鼠标点击和鼠标悬乎这一些消息。 插入到richedit的时候,可以在父窗口richedit中判断,因为插入到richedit中的窗口组件会变成无窗口形式的,如果你把你的组件放到其它地方,就可以触发一般的窗口消息了
我已经可以实现容器给无窗口控件发送消息了,但是又遇到一个问题,好比我在富文本编辑框中插入了三个控件,我怎么能再次取到这些控件呢?就是说针对某个控件操作?
xwhmm 2013-08-02
  • 打赏
  • 举报
回复
插入到richedit的时候,可以在父窗口richedit中判断,因为插入到richedit中的窗口组件会变成无窗口形式的,如果你把你的组件放到其它地方,就可以触发一般的窗口消息了

而且你说的无窗口形式的好像也不对啊,我的窗口创建成功了,而且在第一行的位置移动过去后可以实现鼠标点击双击移动事件,就是第二行往后就不对了,看截图,也就是说在富文本框里面控件可以有窗口的,只是不知道为什么第二行之后的矩形位置不对了,或者有什么办法能在控件里面正确获取到在宿主窗体的位置吗?
xwhmm 2013-08-02
  • 打赏
  • 举报
回复
[quote=引用 6 楼 fishion 的回复:] 需要控件能够响应鼠标点击和鼠标悬乎这一些消息。 对啊,控件要是没有窗口的话就没法响应点击事件了啊?所以我才做成有窗口的?难道m_bWndLess的控件也能响应鼠标点击消息吗?找了找资料,好像必须是有窗口的啊
fishion 2013-08-02
  • 打赏
  • 举报
回复
需要控件能够响应鼠标点击和鼠标悬乎这一些消息。 插入到richedit的时候,可以在父窗口richedit中判断,因为插入到richedit中的窗口组件会变成无窗口形式的,如果你把你的组件放到其它地方,就可以触发一般的窗口消息了
xwhmm 2013-08-01
  • 打赏
  • 举报
回复
引用 2 楼 fishion 的回复:
对了,你的控件最好在REOBJECT的dwUser中添加自己的标识
另外,为什么我用IOleInPlaceSite::GetWindowContext这个函数一直获取失败呢?是使用这个函数有什么限制吗?还是我用得不对呢? 还有如果有窗体的控件实现麻烦,那么无窗体的控件我鼠标在上边点击,或者悬乎,控件怎么才能捕获到事件呢? 如果有办法在无窗体控件中能接收到鼠标点击这些个事件,我也可以不用有窗体的控件来实现.就是不知道能不能在无窗体控件中响应事件?还望高手指点一二.最近被折腾的够呛
xwhmm 2013-08-01
  • 打赏
  • 举报
回复
引用 2 楼 fishion 的回复:
对了,你的控件最好在REOBJECT的dwUser中添加自己的标识
而且在富文本框中插入第一行的时候控件位置获取就是正确的,然后长度不够自动换行的时候取到的矩形位置也是正确的也是顶部和底部也都是加上了之前已有的行的高度的,但是在换行之后的那些控件获取矩形就不正确了,不管现在的控件在的位置是多少行,每次获取的控件位置的左边和右边都是正确的但是顶边和底边一直都是第一行的也就是rect.top=0,rect.bottom=16,一直是这样,然后到换行的时候又正确了,接着换行的那个又不对了,所以我没有办法在控件里面自动调整窗口到正确的位置,窗口不在控件的位置上,所以我点击的时候就没有任何事件,这个问题不知道是怎么回事啊?
xwhmm 2013-08-01
  • 打赏
  • 举报
回复
引用 2 楼 fishion 的回复:
对了,你的控件最好在REOBJECT的dwUser中添加自己的标识
这个的确可以在插入控件之后通过遍历的方法获取到控件在宿主窗口中的位置,那有没没有什么办法在控件里面可以自己获取呢?因为我的控件其实是实现的超链接的功能,需要控件能够响应鼠标点击和鼠标悬乎这一些消息.所以我的这个控件做的是有窗口的控件,而且每个控件的窗体我设置的父窗体都是富文本编辑框,但是控件的窗口不会随着控件的矩形区域来自动调整,所以我都是在控件的OnDraw里面获取控件在富文本编辑框中的矩形位置,然后来手动把窗口移动过去的.
fishion 2013-08-01
  • 打赏
  • 举报
回复
对了,你的控件最好在REOBJECT的dwUser中添加自己的标识
fishion 2013-08-01
  • 打赏
  • 举报
回复
void EnumRichEditObjects()
{
    IRichEditOle* lpRichEditOle = NULL;
    ::SendMessage(m_RichCtrl.m_hWnd, EM_GETOLEINTERFACE, 0, (LPARAM)&lpRichEditOle);

    if (lpRichEditOle != NULL)
    {
        HRESULT hr = 0;
        int objectCount = lpRichEditOle->GetObjectCount();
        for (int i = 0; i < objectCount; i++)
        {
            REOBJECT reObj;
            ZeroMemory(&reObj, sizeof(REOBJECT));
            reObj.cbStruct = sizeof(REOBJECT);

            hr = lpRichEditOle->GetObject(i, &reObj, REO_GETOBJ_ALL_INTERFACES);
            if(SUCCEEDED(hr))
            {
                if (reObj.dwUser == 1)
                {
                    LRESULT lRet = ::SendMessage(m_RichCtrl.m_hWnd, EM_POSFROMCHAR, (WPARAM)reObj.cp, NULL);
                    POINT point = {LOWORD(lRet), HIWORD(lRet)};
                    RECT rcOle = {point.x, point.y, point.x + reObj.sizel.cx, point.y + reObj.sizel.cy};
                }
                lpRichEditOle->Release();
            }

        }
    }
}
上面代码是遍历得到控件的位置的代码,或许你有用

3,245

社区成员

发帖
与我相关
我的任务
社区描述
ATL,Active Template Library活动(动态)模板库,是一种微软程序库,支持利用C++语言编写ASP代码以及其它ActiveX程序。
社区管理员
  • ATL/ActiveX/COM社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧