Windows Develop Bookmark and Share   
 index > Windows Forms General > Active X inside Table Layout Panel - Undesired Resize
 

Active X inside Table Layout Panel - Undesired Resize

Hi,
I have a Table Layout Panel with Active X controls in each cell. Everything is created in VB.NET, but I should note that the Active X controls are created via COM, and are C++ objects.
Iinstantiate diferent TLP's according to the format selected by the user (3 columns, 3 rows, etc). The TLP's dimensionsare to remain fixed after the user selects the format. From those dimensions, the dimensions of the Active X Controls are calculated and set manually (I can't use DockStyle.Fill because the Active X's dimensions must be a multiple of 8).
This works fine for most formats. But for those formats with smaller column width, the ActiveX controls are resized by user32.dll in an undesired way. Say, if I create themof 150x932 pixels, WM_SIZE is posted and changes it to 192x192 first, and 154x192 later. I wanted it to remain 150x932, but it seems that some property of the TLP and/or the ActiveX is triggering this resize.
Any hints? While I wait for a reply, I'll try to reproduce this issue in an isolated Test Form.
Cheers
dario_ramos  Thursday, September 17, 2009 12:40 PM

This code reproduces the issue:

Public Class Form1

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        'Get width and height inputted in respective textboxes
        Dim iWidth As Integer = Val(tb_Width.Text)
        Dim iHeight As Integer = Val(tb_Height.Text)
        ' Resize TLP
        TableLayoutPanel1.Width = iWidth
        TableLayoutPanel1.Height = iHeight

        'Clear Styles
        TableLayoutPanel1.ColumnStyles.Clear()
        TableLayoutPanel1.RowStyles.Clear()

        TableLayoutPanel1.RowStyles.Add(New RowStyle(SizeType.Percent, 100))
        'TableLayoutPanel1.RowStyles.Item(0).Height = TableLayoutPanel1.Height
        For k As Integer = 0 To TableLayoutPanel1.ColumnCount - 1
            TableLayoutPanel1.ColumnStyles.Add(New ColumnStyle(SizeType.Percent, CSng(100 / 3)))
            'TableLayoutPanel1.ColumnStyles.Item(k).Width = CSng(TableLayoutPanel1.Width / 3)
        Next
        TableLayoutPanel1.GrowStyle = TableLayoutPanelGrowStyle.FixedSize

        TableLayoutPanel1.Controls.Clear()
        For j As Integer = 0 To TableLayoutPanel1.ColumnCount - 1
            Dim console As New AxConsoleLibrary.AxCoConsoleEx
            console.Width = CInt((TableLayoutPanel1.Width \ 3) - (4 + (3 - 1)))
            console.Height = CInt((TableLayoutPanel1.Height \ 1) - ((2 * 1) + (1 + 1)))

            TableLayoutPanel1.Controls.Add(console)
            TableLayoutPanel1.Refresh()
        Next

    End Sub
End Class

Inside the for loop, if I insert a Button or another UserControl defined by mein VB.NET, everything works smoothly. Therefore, AxCoConsole, which is written in C++and uses COM, has a problem. I'll look around its properties, but if this rings a bell to anyone, any help would be appreciated
dario_ramos  Thursday, September 17, 2009 2:42 PM
This is part of the declaration of AxCoConsole:

///////////////////////////////////////////////////////////////////////////////
/////////////////////// CoConsoleEx class definition //////////////////////////
///////////////////////////////////////////////////////////////////////////////

class ATL_NO_VTABLE CCoConsoleEx :	public CComObjectRootEx<CComSingleThreadModel>,
									public CStockPropImpl<CCoConsoleEx,::ICoConsoleEx>,
									public IPersistStreamInitImpl<CCoConsoleEx>,
									public IOleControlImpl<CCoConsoleEx>,
									public IOleObjectImpl<CCoConsoleEx>,
									public IOleInPlaceActiveObjectImpl<CCoConsoleEx>,
									public IViewObjectExImpl<CCoConsoleEx>,
									public IOleInPlaceObjectWindowlessImpl<CCoConsoleEx>,
									public ISupportErrorInfo,
									public IConnectionPointContainerImpl<CCoConsoleEx>,
									public CProxy_ICoConsoleExEvents<CCoConsoleEx>,
									public IPersistStorageImpl<CCoConsoleEx>,
									public ISpecifyPropertyPagesImpl<CCoConsoleEx>,
									public IQuickActivateImpl<CCoConsoleEx>,
									public IDataObjectImpl<CCoConsoleEx>,
									public IProvideClassInfo2Impl<&CLSID_CoConsoleEx, &__uuidof(_ICoConsoleExEvents), &LIBID_ConsoleLibrary>,
									public CComCoClass<CCoConsoleEx, &CLSID_CoConsoleEx>,
									public CComControl<CCoConsoleEx> {
public:

	CCoConsoleEx();

	DECLARE_OLEMISC_STATUS( OLEMISC_RECOMPOSEONRESIZE | OLEMISC_CANTLINKINSIDE | OLEMISC_INSIDEOUT | OLEMISC_ACTIVATEWHENVISIBLE | OLEMISC_SETCLIENTSITEFIRST )
	DECLARE_REGISTRY_RESOURCEID( IDR_COCONSOLEEX )
After the COM_MAP:

BEGIN_PROP_MAP(CCoConsoleEx)
		PROP_DATA_ENTRY("_cx", m_sizeExtent.cx, VT_UI4)
		PROP_DATA_ENTRY("_cy", m_sizeExtent.cy, VT_UI4)
		PROP_ENTRY_TYPE("Font",DISPID_FONT,CLSID_StockFontPage,VT_DISPATCH)
	END_PROP_MAP()

	BEGIN_CONNECTION_POINT_MAP(CCoConsoleEx)
		CONNECTION_POINT_ENTRY(__uuidof(_ICoConsoleExEvents))
	END_CONNECTION_POINT_MAP()

	BEGIN_MSG_MAP(CCoConsoleEx)
		MESSAGE_HANDLER(WM_MOUSEMOVE, OnMouseMove)
		MESSAGE_HANDLER(WM_TIMER, OnTimer)
		MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBkgnd)
		MESSAGE_HANDLER(WM_DROPFILES, OnDropFiles)
		MESSAGE_HANDLER(WM_MOUSEWHEEL, OnMouseWheel)
		MESSAGE_HANDLER(WM_LBUTTONDOWN, OnLButtonDown)
		MESSAGE_HANDLER(WM_LBUTTONUP, OnLButtonUp)
		MESSAGE_HANDLER(WM_RBUTTONUP, OnRButtonUp)
		MESSAGE_HANDLER(WM_MBUTTONDOWN, OnMButtonDown)
		MESSAGE_HANDLER(WM_RBUTTONDOWN, OnRButtonDown)
		MESSAGE_HANDLER(WM_LBUTTONDBLCLK, OnLButtonDblClk)
		MESSAGE_HANDLER(WM_CHAR, OnChar)
		MESSAGE_HANDLER(WM_SIZE, OnSize)
		MESSAGE_HANDLER(WM_CREATE, OnCreate)
		CHAIN_MSG_MAP(CComControl<CCoConsoleEx>)
		DEFAULT_REFLECTION_HANDLER()
	END_MSG_MAP()

	// ISupportsErrorInfo
	STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid) {
	
		static const IID* arr[] = {
			&IID_ICoConsoleEx,
		};

		for (int i=0; i<sizeof(arr)/sizeof(arr[0]); i++)
			if (InlineIsEqualGUID(*arr[i], riid))
				return S_OK;
		
		return S_FALSE;
	}

	// IViewObjectEx
	DECLARE_VIEW_STATUS( VIEWSTATUS_SOLIDBKGND | VIEWSTATUS_OPAQUE )

	// Font Property
	CComPtr<IFontDisp> m_pFont;

	void OnFontChanged() {
		ATLTRACE(_T("OnFontChanged\n"));
	}

public:
	
	HRESULT OnDrawAdvanced(ATL_DRAWINFO& di);
	DECLARE_PROTECT_FINAL_CONSTRUCT()
	DECLARE_GET_CONTROLLING_UNKNOWN() //Permite agregar objetos COM al ActiveX
	HRESULT FinalConstruct();
	VOID FinalRelease();

After that, a lot of methods are declared
  • Edited bydario_ramos Thursday, September 17, 2009 5:01 PMMissing line break
  •  
dario_ramos  Thursday, September 17, 2009 5:00 PM
After some investigation, it seems that ATL controls cannot control their own size. That's done by their container, in this case a Table Layout Panel. But how the ____ do I avoid those resizes? I'm setting the ATL controls manually in the Form, so why is it changing?
dario_ramos  Thursday, September 17, 2009 6:16 PM
I solved it with this hack in VB.NET:

console.Width = CInt((TableLayoutPanel1.Width \ 3) - (4 + (3 - 1)))
console.Height = CInt((TableLayoutPanel1.Height \ 1) - ((2 * 1) + (1 + 1)))
console.MinimumSize = New System.Drawing.Size(console.Width, console.Height)

The third line prevents resizes which reduce the console's size. As I said before, this is a hack and not an acceptable solution. If someone finds a better one, I'm all eyes for it
dario_ramos  Thursday, September 17, 2009 6:36 PM

Hi,

Do you mean the Active X control has been resized when you add it to tableLayoutPanel?

I suggest you to set style of the TableLayoutPanel control to autosize and check whether the Active Xcontrol has been resized. AtuoSize will make the TableLayoutPanel control be sized with its content. This will avoid the TableLayoutPanel to resize the control.

If Active X control still resized, I think you need to check the Active X control.

TableLayoutPanel1.ColumnStyles.Clear()

TableLayoutPanel1.ColumnStyles.Add(New ColumnStyle(SizeType.AutoSize))

TableLayoutPanel1.RowStyles.Clear()

TableLayoutPanel1.RowStyles.Add(New RowStyle(SizeType.AutoSize))

TableLayoutPanel1.AutoScroll = True

Best regards,

Ling Wang


Please remember to click “Mark as Answer�on the post that helps you, and to click “Unmark as Answer�if a marked post does not actually answer your question. This can be beneficial to other community members reading the thread.
Ling Wang  Wednesday, September 23, 2009 11:46 AM

You can use google to search for other answers

Custom Search

More Threads

• How to implement Instant Notification from webservice?
• Adding controls dynamically and optimizing performances
• Window alert
• Unspecified Error
• Data bind to Menu Items
• Asynchronous Threads, UI and Activex â€?Webbrowser Control
• focus on Windows elements
• App Selfdestruct is it possible?
• *** Drawing without e.Graphics ***
• Scroll bars in tab control