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.
Best Regards
Jian shen
This posting is provided "AS IS" with no warranties, and confers no rights.
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...
Best Regards
Jian Shen
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...