Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

ATL Hostwindow doesn't resize along with hosted ATL Control

152 views
Skip to first unread message

Thomas Pagh

unread,
May 28, 2003, 9:53:54 AM5/28/03
to
How can I make my ATL Control dictate/restrict the size of its Host Window?

I have created an ATL Control with m_bWindowOnly=TRUE, in my control I have
implemented SetExtent.
When I set the size of my control by calling MoveWindow() on the host
window, and afterwards check the new size by calling GetExtent and
GetClientRect, I get two different sizes?

example:

CATLCtrl::CATLCtrl()
{
m_bWindowOnly = true;
.
.
}

CATLCtrl::SetExtent(DWORD dwDrawAspect, SIZEL*psizel)
{
//example - keep proportions
psizel->cy = psizel->cx;
return IOleObjectImpl<CATLCtrl>::SetExtent(DWORD dwDrawAspect,
SIZEL*psizel);
}

CContainerWindow::OnSize(..)
{
HWND hHost = GetDlgItem(ID_CATLCTRL);
IOleObjectPtr ipATLCtrl;
GetDlgControl(ID_CATLCTRL, &ipATLCtrl);

MoveWindow(hHost, 0, 0, 100, 200);

CRect cr;
GetClientRect(hHost, &cr);

SIZEL sizel;
ipATLCtrl->GetExtent(DVASPECT_CONTENT, &sizel);
ATLHiMetricToPixel(&sizel, &sizel);

//sizel - cx = 100, cy = 100
//cr - width = 100, height =200 ........WHY!!!!!!!!!!!!!
}

I have also tried by setting m_bRecomposeOnResize and m_bResizeNatural, and
by implementing CATLCtrl::OnWindowsPosChanging(), so that it uses SetExtent.

I hope you can enlighten me.

Thnx from Thomas Pagh.


Jian-Shen Lin[MS]

unread,
May 29, 2003, 4:56:27 AM5/29/03
to

Set m_bAutoSize = TRUE in the controls constructor. This will force the
control to always be at the size of m_sizeExtent.

Best Regards

Jian shen

This posting is provided "AS IS" with no warranties, and confers no rights.

Thomas Pagh

unread,
Jun 2, 2003, 12:06:52 PM6/2/03
to
It didn't work with m_bAutoSize = TRUE;
If m_bAutoSize is TRUE, IOleObjectImpl<T>::SetExtent(DWORD dwDrawAspect,
SIZEL*psizel) returns E_FAIL.

I have noticed though, that the control's ClientRect in fact is restricted
by SetExtent, if I host my control in a MFC Dialog, but not if I host my
control in a Composite ATL control.
How do I make the control's m_sizeExtent decide the size of the clientrect
when hosted in a Composite ATL control? Maybe I need to change the behaviour
of the Composite Control?

Best regards, Thomas Pagh

"Jian-Shen Lin[MS]" <js...@online.microsoft.com> wrote in message
news:ODqr2AcJ...@cpmsftngxa06.phx.gbl...

"Thomas Pagh" <t...@nospam.dk> wrote in message
news:%23tflQDS...@TK2MSFTNGP11.phx.gbl...

Jian-Shen Lin[MS]

unread,
Jun 3, 2003, 11:11:23 PM6/3/03
to
You can implement the WM_SIZE handler for your composite control. Another
thing that you need to do is implement the IOlnPlaceObject::SetObjectRects
for the composite control. This method is called by the container when the
window is resized. So in this method you can get the new position and
accordingly set the new positions of the embedded
child controls using the SetWindowPos.


Best Regards

Jian Shen

Thomas Pagh

unread,
Jun 4, 2003, 8:02:36 AM6/4/03
to
Hi, thank you for your time!
I am still having trouble though, so I hope you can help me out.

I have implemented the WM_SIZE handler for my composite control, so that it
resizes the embedded child control, in the same way the dialog resizes the
imbedded control.

I have tried tracing the MFC and ATL sourcecode, and monitoring the windows
with Spy++.
With Spy++ I have noticed, that when hosting my embedded control (with
m_bWindowOnly = TRUE) in a Composite ATL control, an ATL host window called
"AtlAxWinLic7" is wrapped around the embedded control's window. So when used
in a dialog we have 2 windows, the dialog's window and the embedded
control's window, but when used in a composite control, then I get 3
windows, the composite control's window, the ATL host's window
(AtlAxWinLic7), and the embedded control's window.

When looking at the sourcecode (see Sample 1), it seems that the
COleControlSite class hosting the embedded control, when on a CDialog, calls
m_pObject->SetExtent, m_pObject->GetExtent and then
m_pInPlaceObject->SetObjectRects, as one would expect.

When looking at the sourcecode (see Sample 2), a CAxHostWindow class is
hosting the embedded control, and calling m_spOleObject->SetExtent, and then
m_spInPlaceObjectWindowless->SetObjectRects, but without using the new
extent that the embedded control has decided in SetExtent.

When hosted i a dialog, it is sufficient to implement SetExtent on my
embedded control, to decide the size of the controls window (because of the
COleControlSite impl.). But when hosted in a composite control, SetExtent is
not enough (probably because of CAxHostWindow::OnSize), so I tried to add an
implementation for SetObjectRects, that modifies m_rcPos, this will change
the size of my embedded controls window, but it will not affect the size of
the host window (AtlAxWinLic7). As a last way out, I tried to have my
embedded control call SetWindowPos on the host window retrieved with
m_spInPlaceSite->GetWindow(), but this naturally causes a lot of problems,
e.g. endless recursive loops.

Sample 1:
Hosted in a MFC CDialog
void CWnd::MoveWindow(int x, int y, int nWidth, int nHeight, BOOL bRepaint)

{

ASSERT(::IsWindow(m_hWnd) || (m_pCtrlSite != NULL));

if (m_pCtrlSite == NULL)

::MoveWindow(m_hWnd, x, y, nWidth, nHeight, bRepaint);

else

m_pCtrlSite->MoveWindow(x, y, nWidth, nHeight);

}

void COleControlSite::MoveWindow(int x, int y, int nWidth, int nHeight)

{

ASSERT(m_pInPlaceObject != NULL);

ASSERT(m_pObject != NULL);

CRect rectOld(m_rect);

m_rect.SetRect(x, y, x + nWidth, y + nHeight);

if (SetExtent())

{

m_rect.SetRect(x, y, x + m_rect.Width(), y + m_rect.Height());

m_pInPlaceObject->SetObjectRects(m_rect, m_rect);

}

else

{

m_rect = rectOld;

}

}

BOOL COleControlSite::SetExtent()

{

CSize size(m_rect.Size());

CClientDC dc(NULL);

dc.DPtoHIMETRIC(&size);

HRESULT hr;

if (SUCCEEDED(hr = m_pObject->SetExtent(DVASPECT_CONTENT,
(SIZEL*)&size)))

{

if (SUCCEEDED(m_pObject->GetExtent(DVASPECT_CONTENT,
(SIZEL*)&size)))

{

dc.HIMETRICtoDP(&size);

m_rect.right = m_rect.left + size.cx;

m_rect.bottom = m_rect.top + size.cy;

}

}

return SUCCEEDED(hr);

}


Sample 2:
Hosted in ATL Composite Control
class CAxHostWindow:

LRESULT OnSize(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL&
bHandled)

{

int nWidth = GET_X_LPARAM(lParam); // width of client area

int nHeight = GET_Y_LPARAM(lParam); // height of client area

m_rcPos.right = m_rcPos.left + nWidth;

m_rcPos.bottom = m_rcPos.top + nHeight;

m_pxSize.cx = m_rcPos.right - m_rcPos.left;

m_pxSize.cy = m_rcPos.bottom - m_rcPos.top;

AtlPixelToHiMetric(&m_pxSize, &m_hmSize);

if (m_spOleObject)

m_spOleObject->SetExtent(DVASPECT_CONTENT, &m_hmSize);

if (m_spInPlaceObjectWindowless)

m_spInPlaceObjectWindowless->SetObjectRects(&m_rcPos, &m_rcPos);

if (m_bWindowless)

InvalidateRect(NULL, TRUE);

bHandled = FALSE;

return 0;

}

Hope that you can help me with the right solution,
best regards, Thomas Pagh

"Jian-Shen Lin[MS]" <js...@online.microsoft.com> wrote in message

news:SkQ8DckK...@cpmsftngxa06.phx.gbl...

0 new messages