
VB5 OCX and VC5 Atl Mix confusion
Hi,
I wrote an MDI application in VB5 which displays an image. On the child form
I instantiate my own Display OCX built as follow :
I have have width, height, image's handle porperties. Wheen the image's
handle is set, I call an ATL Dll function linked to the control that display
the image on the control.
My problem is that sometimes (-more I have child forms more it happens-) the
image is displayed on the wrong child form :
Application
child form1 -> DisplayOcx1 -----|
child form2 -> DisplayOcx2 -----|---> DLL
child form3 -> DisplayOcx3 -----|
When I debuged, it seemed that when I set the new properties to the new Ocx
of the new Child Form and i want to display the image, I begin the action
for the new Ocx, stop it to give hand to another Ocx which finishes the
action.
I fanally have the last child form with a null image's handle and the
previous one (K-1)th with the image handle Kth
I read in the litterature that win32 dll had for each thread their own data
memory space.
So how datas can Confuse?
What I did bad when coding?
What is wrong in my application with th emultitask process?
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////
My ATL code :
//////////////////////
// Display.h: Definition of the CDisplay class
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_DISPLAY_H__B000000_76BA_11D1_98CC_00A0C918DCDA__INCLUDED_)
#define AFX_DISPLAY_H__B000000_76BA_11D1_98CC_00A0C918DCDA__INCLUDED_
#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
#include "resource.h" // main symbols
////////////////////////////////////////////////////////////////////////////
/
// CDisplay
class CDisplay :
public CComDualImpl<IDisplay, &IID_IDisplay, &LIBID_ANGLEDISPLAYLib>,
public ISupportErrorInfo,
public CComObjectRoot,
public CComCoClass<CDisplay,&CLSID_Display>
{
public:
CDisplay() {}
BEGIN_COM_MAP(CDisplay)
COM_INTERFACE_ENTRY(IDispatch)
COM_INTERFACE_ENTRY(IDisplay)
COM_INTERFACE_ENTRY(ISupportErrorInfo)
END_COM_MAP()
//DECLARE_NOT_AGGREGATABLE(CDisplay)
// Remove the comment from the line above if you don't want your object to
// support aggregation.
DECLARE_REGISTRY_RESOURCEID(IDR_Display)
// ISupportsErrorInfo
STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid);
// IDisplay
public:
STDMETHOD (AngleProcess)(void);
// PUT
STDMETHOD (put_intImageWidth)(short nImageWidth);
STDMETHOD (put_intImageHeight)(short nImageHeight);
STDMETHOD (put_lngSourceHandle)(long hSource);
STDMETHOD (put_lngWindowHandle)(long hWindow);
// GET
// PUT & GET
STDMETHOD(put_lngDisplayView)(long lDisplayView);
STDMETHOD(get_lngDisplayView)(long* plDisplayView);
Quote:
};
#endif //
!defined(AFX_DISPLAY_H__B000000_76BA_11D1_98CC_00A0C918DCDA__INCLUDED_)
/////////////////
// AngleDisplay.idl : IDL source for AngleDisplay.dll
//
// This file will be processed by the MIDL tool to
// produce the type library (AngleDisplay.tlb) and marshalling code.
import "oaidl.idl";
import "ocidl.idl";
[
object,
uuid(B000000-76BA-11D1-98CC-00A0C918DCDA),
dual,
helpstring("IDisplay Interface"),
pointer_default(unique)
]
interface IDisplay : IDispatch
{
[propput, helpstring("")]
HRESULT intImageWidth([in] short nImageWidth);
[propput, helpstring("")]
HRESULT intImageHeight([in] short nImageHeight);
[propput, helpstring("")]
HRESULT lngSourceHandle([in] long hSource);
[propput, helpstring("")]
HRESULT lngWindowHandle([in] long hWindow);
HRESULT lngDisplayView([in] long lDisplayView);
[propget, helpstring("")]
HRESULT lngDisplayView([out, retval] long* plDisplayView);
[helpstring("")]
HRESULT AngleProcess();
[helpstring("")]
HRESULT CreateDisplayViewStruct([out, retval] long* plDisplayView);
};
[
uuid(B72F9AC2-76BA-11D1-98CC-00A0C918DCDA),
version(1.0),
helpstring("AngleDisplay 1.0 Type Library")
]
library ANGLEDISPLAYLib
{
importlib("stdole32.tlb");
importlib("stdole2.tlb");
[
uuid(B000000-76BA-11D1-98CC-00A0C918DCDA),
helpstring("Display Class"),
appobject
]
coclass Display
{
[default] interface IDisplay;
};
Quote:
};
// Display.cpp : Implementation of CAngleDisplayApp and DLL registration.
//------------------------------------------------------------------
#include "stdafx.h"
#include "AngleDisplay.h"
#include "Display.h"
#include "Displayfunc.h"
#include <math.h>
#include "..\Common\MACROS.h"
#include "..\AppTLS32\AppTls32_i.c"
#include "..\AppTLS32\AppTLS32.h"
////////////////////////////////////////////////////////////////////////////
/
//
LPDISPLAYVIEW lpDisplayView;
////////////////////////////////////////////////////////////////////////////
/
//
STDMETHODIMP CDisplay::InterfaceSupportsErrorInfo(REFIID riid)
{
static const IID* arr[] =
{
&IID_IDisplay,
};
for (int i=0;i<sizeof(arr)/sizeof(arr[0]);i++)
{
if (InlineIsEqualGUID(*arr[i],riid))
return S_OK;
}
return S_FALSE;
Quote:
}
//-------------------------------------------------------------------
//
//
//-------------------------------------------------------------------
STDMETHODIMP CDisplay::put_intImageWidth(short nImageWidth)
{
lpDisplayView->nImageWidth = nImageWidth;
return NOERROR;
Quote:
}
//-------------------------------------------------------------------
//
//
//-------------------------------------------------------------------
STDMETHODIMP CDisplay::put_intImageHeight(short nImageHeight)
{
lpDisplayView->nImageHeight = nImageHeight;
return NOERROR;
Quote:
}
//-------------------------------------------------------------------
//
//-------------------------------------------------------------------
[...]
//-------------------------------------------------------------------
//
//-------------------------------------------------------------------
STDMETHODIMP CDisplay::put_lngSourceHandle(long hSource)
{
lpDisplayView->hSource = (HGLOBAL)hSource;
return NOERROR;
Quote:
}
//-------------------------------------------------------------------
//
//
//-------------------------------------------------------------------
STDMETHODIMP CDisplay::put_lngWindowHandle(long hWindow)
{
lpDisplayView->hWindow = (HWND)hWindow;
return NOERROR;
Quote:
}
//-------------------------------------------------------------------
//
//
//-------------------------------------------------------------------
STDMETHODIMP CDisplay::put_lngDisplayView(long lDisplayView)
{
lpDisplayView = (LPDISPLAYVIEW)lDisplayView;
return NOERROR;
Quote:
}
//GET
//-------------------------------------------------------------------
//
//
//-------------------------------------------------------------------
STDMETHODIMP CDisplay::get_lngDisplayView(long* plDisplayView)
{
*plDisplayView = (long)lpDisplayView;
return NOERROR;
Quote:
}
//-------------------------------------------------------------------
//
//
//-------------------------------------------------------------------
STDMETHODIMP CDisplay::get_lngDisplayHandle(long* phDisplay)
{
*phDisplay = (long)lpDisplayView->hDisplay;
return NOERROR;
Quote:
}
//-------------------------------------------------------------------
// AngleProcess
// Cette routine affiche l'image
//-------------------------------------------------------------------
STDMETHODIMP CDisplay::CreateDisplayViewStruct(long* plDisplayView)
{
lpDisplayView =
(LPDISPLAYVIEW)(GlobalLock(GlobalAlloc(LMEM_FIXED,sizeof(DisplayStruct))));
// initialise
lpDisplayView->nImageWidth = 0;
lpDisplayView->nImageHeight = 0;
lpDisplayView->hSource = 0;
[.... ]
lpDisplayView->hDisplay = 0;
lpDisplayView->hWindow = 0;
// return handle
*plDisplayView = (long)lpDisplayView;
return NOERROR;
Quote:
}
//-------------------------------------------------------------------
// AngleProcess
// Display an image
//-------------------------------------------------------------------
STDMETHODIMP CDisplay::AngleProcess( )
{
//------------------------------
PAINTSTRUCT psStruct;
HBRUSH hBrush, hBrushOld;
RECT rectDrawingArea;
HDC hDC;
if(lpDisplayView->hSource) {
// adds a rectangle to all the window's update region
// background is erased
InvalidateRect(lpDisplayView->hWindow, NULL, TRUE);
hDC = BeginPaint(lpDisplayView->hWindow, &psStruct);
GetClientRect(lpDisplayView->hWindow, (LPRECT)&rectDrawingArea);
if( (rectDrawingArea.right - rectDrawingArea.left)
< (rectDrawingArea.bottom - rectDrawingArea.top)) {
lpDisplayView->lDisplayWidth = rectDrawingArea.right -
rectDrawingArea.left;
}
else {
lpDisplayView->lDisplayWidth = rectDrawingArea.bottom -
rectDrawingArea.top;
}
lpDisplayView->lDisplayWidth -= (lpDisplayView->lDisplayWidth)%2;
if (!lpDisplayView->hDisplay) {
// the image under 8 bits already exists
lpDisplayView->hDisplay = CreateDisplayImage();
}
if (!(lpDisplayView->hDisplayPalette)) {
CreateDisplayPalette(hDC);
}
// Create a brush
hBrush = CreateSolidBrush(lpDisplayView->clrFrame);
// select it
hBrushOld = (HBRUSH)SelectObject(hDC, hBrush);
//paint the background
FillRect(hDC, (LPRECT) &psStruct.rcPaint, hBrush);
// select old one
SelectObject(hDC, hBrushOld);
// delete new brush
DeleteObject(hBrush);
if (lpDisplayView->lDisplayWidth) {
//paint routine
DisplayViewPaint(hDC);
}
//entire client area is removed
ValidateRect(lpDisplayView->hWindow, NULL);
EndPaint(lpDisplayView->hWindow, &psStruct);
}
return NOERROR;
Quote:
}
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////
My OCX code :
Option Explicit
Private m_intImageWidth As Integer
Private m_intImageHeigth As Integer
Private m_lngSourceHandle As Long
Private m_lngDisplayHandle As Long
Private m_lngWindowHandle As Long
[.....]
Public Property Let ImageWidth(ByVal intNewImageWidth As Integer)
'---------------------------------------------------
intImageWidth = intNewImageWidth
m_intImageWidth = intNewImageWidth
PropertyChanged "ImageWidth"
End Property
Public Property Get ImageHeigth() As Integer
'---------------------------------------------------
ImageHeigth = m_intImageHeigth
End Property
Public Property Let ImageHeigth(ByVal intNewImageHeigth As Integer)
'---------------------------------------------------
intImageHeight = intNewImageHeigth
m_intImageHeigth = intNewImageHeigth
PropertyChanged "ImageHeigth"
End Property
[.....]
Public Property Get hSource() As Long
'---------------------------------------------------
hSource = m_lngSourceHandle
End Property
Public Property Let hSource(ByVal lngNewhSource As Long)
'---------------------------------------------------
Dim lngRowMax As Long, lngColumnMax As Long
Dim lngRowMin As Long, lngColumnMin As Long
'free all
If lngNewhSource = 0 Then
If m_lngSourceHandle <> 0 Then
AppClose m_lngSourceHandle
lngSourceHandle = 0
m_lngSourceHandle = 0
End If
If m_lngDisplayHandle <> 0 Then
CloseDisplayAndPalette
lngDisplayHandle = 0
m_lngDisplayHandle = 0
End If
If m_lngDisplayView <> 0 Then
GlobalFree (m_lngDisplayView)
End If
m_blnPaletteRealized = False
Else
If lngNewhSource <> m_lngSourceHandle Then
If m_lngSourceHandle <> 0 Then
AppClose m_lngSourceHandle
lngSourceHandle = 0
m_lngSourceHandle = 0
End If
If m_lngDisplayHandle <> 0 Then
CloseDisplayAndPalette
lngDisplayHandle = 0
m_lngDisplayHandle = 0
End If
End If
lngSourceHandle = lngNewhSource
m_lngSourceHandle = lngNewhSource
If Not Me.ImageHeigth And Not Me.ImageWidth Then
getExtremum m_lngSourceHandle, m_lngMaximum, _
m_lngMinimum, lngRowMax, lngColumnMax, _
lngRowMin, lngColumnMin
lngMaximum = m_lngMaximum
lngMinimum = m_lngMinimum
End If
If Not m_blnPaletteRealized Then
Do_PaletteAbscissa
m_blnPaletteRealized = True
End If
UserControl_Paint
End If
PropertyChanged "hSource"
End Property
Private Sub UserControl_Initialize()
'---------------------------------------------------
UserControl.Width = 495
UserControl.Height = 495
m_lngDisplayView = CreateDisplayViewStruct
lngDisplayView = m_lngDisplayView
lngDisplayWidth = 1
lngWindowHandle = UserControl.hWnd
m_blnPaletteRealized = False
End Sub
Public Sub UserControl_Paint()
'---------------------------------------------------
If m_lngSourceHandle <> 0 Then
lngDisplayView = m_lngDisplayView
AngleProcess
m_lngDisplayHandle = lngDisplayHandle
End If
End Sub
Private Sub UserControl_ReadProperties(PropBag As PropertyBag)
'---------------------------------------------------
On Error Resume Next
m_intImageWidth = PropBag.ReadProperty("ImageWidth", 0)
m_intImageHeigth = PropBag.ReadProperty("ImageHeigth", 0)
[.....]
m_lngSourceHandle = PropBag.ReadProperty("hSource", m_lngSourceHandle)
m_lngWindowHandle = PropBag.ReadProperty(hWndControl, hWnd)
End Sub
Private Sub UserControl_WriteProperties(PropBag As PropertyBag)
'---------------------------------------------------
PropBag.WriteProperty "ImageWidth", m_intImageWidth, 0
PropBag.WriteProperty "ImageHeigth", m_intImageHeigth, 0
[.....]
PropBag.WriteProperty "hSource", m_lngSourceHandle, 0
PropBag.WriteProperty "hWndControl", m_lngWindowHandle, hWnd
End Sub
Public Sub UserControl_Resize()
'---------------------------------------------------
If m_lngSourceHandle <> 0 Then
lngDisplayView = m_lngDisplayView
AngleProcess
End If
End Sub