ATL ActiveX Control hosting code fails to initialize ActiveX Controls on Win9x 
Author Message
 ATL ActiveX Control hosting code fails to initialize ActiveX Controls on Win9x

Hello!

Take a look at the following items:

First is an extract from the MSDN Library regarding the WM_CREATE message:

--------------------------------------------------------------------------------

WM_CREATE
The WM_CREATE message is sent when an application requests that a window be created by calling the CreateWindowEx or CreateWindow function. (The message is sent before the function returns.) The window procedure of the new window receives this message after the window is created, but before the window becomes visible.

A window receives this message through its WindowProc function.

LRESULT CALLBACK WindowProc(
  HWND hwnd,       // handle to window
  UINT uMsg,       // WM_CREATE
  WPARAM wParam,   // not used
  LPARAM lParam    // creation data (LPCREATESTRUCT)
);
Parameters
  wParam
  This parameter is not used.
  lParam
  Pointer to a CREATESTRUCT structure that contains information about the window being created.
Return Values
If an application processes this message, it should return zero to continue creation of the window. If the application returns -1, the window is destroyed and the CreateWindowEx or CreateWindow function returns a NULL handle.

Requirements
  Windows NT/2000: Requires Windows NT 3.1 or later.
  Windows 95/98: Requires Windows 95 or later.
  Windows CE: Requires version 1.0 or later.
  Header: Declared in winuser.h; include windows.h.

See Also
Windows Overview, Window Messages, CreateWindow, CreateWindowEx, CREATESTRUCT, WM_NCCREATE

Built on Wednesday, August 18, 1999
Requirements
  Windows NT/2000: Requires Windows NT 3.1 or later.
  Windows 95/98: Requires Windows 95 or later.
  Windows CE: Requires version 1.0 or later.
  Header: Declared in winuser.h; include windows.h.

See Also

--------------------------------------------------------------------------------

Following the link to CREATESTRUCT you end up in the following text:

--------------------------------------------------------------------------------

CREATESTRUCT
The CREATESTRUCT structure defines the initialization parameters passed to the window procedure of an application. These members are identical to the parameters of the CreateWindowEx function.

typedef struct tagCREATESTRUCT {
    LPVOID    lpCreateParams;
    HINSTANCE hInstance;
    HMENU     hMenu;
    HWND      hwndParent;
    int       cy;
    int       cx;
    int       y;
    int       x;
    LONG      style;
    LPCTSTR   lpszName;
    LPCTSTR   lpszClass;
    DWORD     dwExStyle;

Quote:
} CREATESTRUCT, *LPCREATESTRUCT;

Members
  lpCreateParams
  Contains additional data which may be used to create the window. If the window is being created as a result of a call to the CreateWindow or CreateWindowEx function, this member contains the value of the lpParam parameter specified in the function call.
  If the window being created is an MDI window, this member contains a pointer to an MDICREATESTRUCT structure.

  Windows NT/2000: If the window is being created from a dialog template, this member is the address of a SHORT value that specifies the size, in bytes, of the window creation data. The value is immediately followed by the creation data. For more information, see the following Remarks section.

  hInstance
  Handle to the module that owns the new window.
  hMenu
  Handle to the menu to be used by the new window.
  hwndParent
  Handle to the parent window, if the window is a child window. If the window is owned, this member identifies the owner window. If the window is not a child or owned window, this member is NULL.
  cy
  Specifies the height of the new window, in pixels.
  cx
  Specifies the width of the new window, in pixels.
  y
  Specifies the y-coordinate of the upper left corner of the new window. If the new window is a child window, coordinates are relative to the parent window. Otherwise, the coordinates are relative to the screen origin.
  x
  Specifies the x-coordinate of the upper left corner of the new window. If the new window is a child window, coordinates are relative to the parent window. Otherwise, the coordinates are relative to the screen origin.
  style
  Specifies the style for the new window.
  lpszName
  Pointer to a null-terminated string that specifies the name of the new window.
  lpszClass
  Pointer to a null-terminated string that specifies the class name of the new window.
  dwExStyle
  Specifies the extended window style for the new window.
Remarks
Windows NT/2000: You should access the data represented by the lpCreateParams member using a pointer that has been declared using the UNALIGNED type, because the pointer may not be DWORD aligned. This is demonstrated in the following example:

typedef struct tagMyData
{
    // Define creation data here.

Quote:
} MYDATA;

typedef struct tagMyDlgData
{
    SHORT   cbExtra;
    MYDATA  myData;

Quote:
} MYDLGDATA, UNALIGNED *PMYDLGDATA;

PMYDLGDATA pMyDlgdata =
    (PMYDLGDATA) (((LPCREATESTRUCT) lParam)->lpCreateParams);
Requirements
  Windows NT/2000: Requires Windows NT 3.1 or later.
  Windows 95/98: Requires Windows 95 or later.
  Windows CE: Requires version 1.0 or later.
  Header: Declared in winuser.h; include windows.h.
  Unicode: Declared as Unicode and ANSI structures.

See Also
Windows Overview, Window Structures, CreateWindow, CreateWindowEx, MDICREATESTRUCT

Built on Wednesday, August 18, 1999
Requirements
  Windows NT/2000: Requires Windows NT 3.1 or later.
  Windows 95/98: Requires Windows 95 or later.
  Windows CE: Requires version 1.0 or later.
  Header: Declared in winuser.h; include windows.h.
  Unicode: Declared as Unicode and ANSI structures.

See Also
Windows Overview, Window Structures, CreateWindow, CreateWindowEx, MDICREATESTRUCT

--------------------------------------------------------------------------------

Note carefully the text about Win2000/NT in the paragraph about the lpCreateParams item. So on Win9x this item directly points at the creation data, but on NT this item points 2 bytes before the creation data.

Now, consider the following code taken from ATL 3.0 Visual Studo 6.0 SP3 file ATLHOST.H:

static LRESULT CALLBACK AtlAxWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
 switch(uMsg)
 {
 case WM_CREATE:
  {
  // create control from a PROGID in the title
   // This is to make sure drag drop works
   ::OleInitialize(NULL);

   CREATESTRUCT* lpCreate = (CREATESTRUCT*)lParam;
   int nLen = ::GetWindowTextLength(hWnd);
   LPTSTR lpstrName = (LPTSTR)_alloca((nLen + 1) * sizeof(TCHAR));
   ::GetWindowText(hWnd, lpstrName, nLen + 1);
   ::SetWindowText(hWnd, _T(""));
   IAxWinHostWindow* pAxWindow = NULL;
   int nCreateSize = 0;
   if (lpCreate && lpCreate->lpCreateParams)
    nCreateSize = *((WORD*)lpCreate->lpCreateParams);
   HGLOBAL h = GlobalAlloc(GHND, nCreateSize);
   CComPtr<IStream> spStream;
   if (h && nCreateSize)
   {
    BYTE* pBytes = (BYTE*) GlobalLock(h);
    BYTE* pSource = ((BYTE*)(lpCreate->lpCreateParams)) + sizeof(WORD);
    // Align to DWORD
    // pSource += (((~((DWORD)pSource)) + 1) & 3);
    memcpy(pBytes, pSource, nCreateSize);
    GlobalUnlock(h);
    CreateStreamOnHGlobal(h, TRUE, &spStream);
   }
   USES_CONVERSION;
   CComPtr<IUnknown> spUnk;

The red marked code indicates that this code only works on NT. The code always assumes that the creation data is preceeded by a WORD. Instead the following code, or something similar should be used:

            ...
            // Determine current operation system platform
            OSVERSIONINFO os;
            ZeroMemory(&os, sizeof(os));
            os.dwOSVersionInfoSize = sizeof(os);
            ::GetVersionEx(&os);
            if(os.dwPlatformId == VER_PLATFORM_WIN32_NT)
            {
               // NT: pCreationData points at the size of the creation data
               BYTE* pSource = ((BYTE*)(lpCreate->lpCreateParams)) + sizeof(WORD);
            }
            else
            {
               // Win9x: pCreationData points directly at the creation data
                BYTE* pSource = ((BYTE*)(lpCreate->lpCreateParams));
            }
            ...

Patrik Pettersson
Caesar Business Systems AB



Fri, 05 Jul 2002 03:00:00 GMT  
 
 [ 1 post ] 

 Relevant Pages 

1. ATL ActiveX hosting (ATL Compisite Control)

2. Windowless ActiveX control hosting with ATL

3. Problem Hosting ActiveX Controls Using ATL AXHost (CAxWindow2) using VC7

4. Hosting ActiveX Control in ATL property page

5. Control webbrowser ActiveX control in composit ActiveX control

6. hosting activex control in user control...

7. ActiveX control inside another activex control

8. Need help with ActiveX control containing other activex controls

9. ActiveX control inside another ActiveX control

10. Need help with ActiveX control containing other activex controls

11. ActiveX control in an ActiveX control

12. Modify Activex Control Properties from other Activex Control.

 

 
Powered by phpBB® Forum Software