I've been trying to add a custom property page to Japheth's Asmctrl with little success. It crashes VB when drawing the property frame. I believe I must be returning a bad pointer to VB. Any help?


Get it here:
http://us.f2.yahoofs.com/bc/41d369a4_14d10/bc/Public/AsmCtlPP.zip?BCEBv.BB2GTefdME
Posted on 2005-01-28 19:58:51 by Wayne
Hi Wayne,

regretably the download location cannot be found.

I have an AsmCtrl version with a property page, but recently I switched to other include files and somehow managed to add a bug in the sample's drawing code, so it wont be any help.
Posted on 2005-01-29 09:45:56 by japheth
Sorry about the link.
Please try :
http://f2.pg.briefcase.yahoo.com/wayne.lozinski@sbcglobal.net

Select the Public folder.

At this point I am only trying to get a blank Prop Page.
Posted on 2005-01-29 10:53:23 by Wayne
I think method GetPageInfo isnt correct. Besides that, my property page version (CAsmProp.asm) looks pretty similiar (dont let yourself confuse by some include file changes at the top):





;*** methods of CAsmProp coclass

.586
.model flat, stdcall
option casemap:none ; case sensitive
option proc:private

.nolist
.nocref
WIN32_LEAN_AND_MEAN equ 1
INC_OLE2 equ 1
include windows.inc
include olectl.inc

include macros.inc
include disphlp.inc
include olecntrl.inc
include debugout.inc

include AsmCtrl.inc ;type information (COMView generated)
.list
.cref

include CAsmClass.inc
include CAsmProp.inc

IDD_PROPPAGE equ 1001
IDC_EDIT1 equ 40000

Destroy@CAsmProp proto :ptr CAsmProp

.const

CLSID_CAsmProp sCLSID_AsmProp

;--------------------------------------------------------------------------
;--- IUnknown interface: the table of supp. interfaces must be defined
;--------------------------------------------------------------------------

.const

DEFINE_KNOWN_INTERFACES CAsmProp, IPropertyPage

;--------------------------------------------------------------------------
;--- define table of registry entries for this CLSID
;--- REGSTRUCT = {LPSTR lpszSubKey; LPSTR lpszValueName; LPSTR lpszData}
;--- -1 in lpszSubKey -> key in HKEY_CLASSES_ROOT, in which next
;--- entries will be written. %s is szCLSID in such entries.
;--- else: -1 in lpszData: replaced by szCLSID, -2 in lpszData: replaced by szTLBID
;--- %s is module path in such entries
;--------------------------------------------------------------------------

Description textequ <"OCX control in ASM Property Page">

RegKeys_CAsmProp label REGSTRUCT
REGSTRUCT <-1, 0, CStr("CLSID\%s")>
REGSTRUCT <0, 0, CStr(Description)>
REGSTRUCT <CStr("InprocServer32"), 0, CStr("%s")>
REGSTRUCT <CStr("InprocServer32"), CStr("ThreadingModel"), CStr("Apartment")>
REGSTRUCT <CStr("Programmable"), 0, 0>
REGSTRUCT <-1, 0, 0>

;-----------------------------------------------------------------
.const

CAsmPropVtbl label IPropertyPageVtbl
IUnknownVtbl {QueryInterface@CAsmProp, AddRef@CAsmProp, Release@CAsmProp}
dd SetPageSite
dd Activate
dd Deactivate
dd GetPageInfo
dd SetObjects
dd Show
dd Move
dd IsPageDirty
dd Apply
dd Help
dd TranslateAccelerator_

.code

__this textequ <ebx>
_this textequ <[__this].CAsmProp>

MEMBER pPropertyPageSite, hWnd, pObject, rect, bModal

DEFINE_STD_COM_METHODS CAsmProp

;--------------------------------------------------------------------------
;--------------- constructor CAsmProp
;--------------------------------------------------------------------------

Create@CAsmProp proc public uses __this pClass: ptr ObjectEntry, pUnkOuter:LPUNKNOWN

DebugOut "Create@CAsmProp"

invoke LocalAlloc, LMEM_FIXED or LMEM_ZEROINIT,sizeof CAsmProp
.if (eax == NULL)
ret
.endif
mov __this,eax
mov m__IPropertyPage, OFFSET CAsmPropVtbl
STD_COM_CONSTRUCTOR CAsmProp

if ?AGGREGATION
lea eax, m__IUnknown
ret
else
return __this
endif

Create@CAsmProp endp

;--------------------------------------------------------------------------
;--------------- destructor
;--------------------------------------------------------------------------

Destroy@CAsmProp PROC public uses __this this_:ptr CAsmProp

DebugOut "Destroy@CAsmProp enter"
mov __this,this_
STD_COM_DESTRUCTOR CAsmProp
invoke LocalFree, __this
ret

Destroy@CAsmProp ENDP

;--- the window proc of the property sheet

dlgproc proc uses __this hWnd:HWND, uMessage:DWORD, wParam:WPARAM, lParam:LPARAM

local dwValue:DWORD
local szText[64]:byte

mov eax,uMessage
.IF (eax == WM_COMMAND)
DebugOut "CAsmProp wndproc WM_COMMAND"
xor eax,eax
.ELSEIF (eax == WM_INITDIALOG)
DebugOut "CAsmProp wndproc WM_INITDIALOG"
invoke SetWindowLong, hWnd, DWL_USER, lParam
mov __this, lParam
.if (m_pObject)
invoke vf(m_pObject, IAsmClass, get_Value), addr dwValue
.if (eax == S_OK)
invoke wsprintf, addr szText, CStr("%u"), dwValue
invoke SetDlgItemText, hWnd, IDC_EDIT1, addr szText
.endif
.endif
mov eax,1
.ELSEIF (eax == WM_CLOSE)
DebugOut "CAsmProp wndproc WM_CLOSE"
invoke DestroyWindow, hWnd
.ELSE
xor eax,eax
.ENDIF
ret
dlgproc endp


SetPageSite proc uses __this this_:ptr CAsmProp, pSite:ptr IPropertyPageSite

DebugOut "SetPageSite@CAsmProp"
mov __this, this_
invoke ComPtrAssign, addr m_pPropertyPageSite, pSite
mov eax, S_OK
ret
SetPageSite endp

Activate proc uses __this this_:ptr CAsmProp, hWnd:HWND, pRect:LPRECT, bModal:BOOL

DebugOut "Activate@CAsmProp"
mov __this, this_
invoke CopyRect, addr m_rect, pRect
invoke CreateDialogParam, g_hInstance, IDD_PROPPAGE, hWnd, offset dlgproc, __this
.if (eax)
mov m_hWnd, eax
mov eax, S_OK
.else
mov eax, E_OUTOFMEMORY
.endif
ret
Activate endp

Deactivate proc uses __this this_:ptr CAsmProp
DebugOut "Deactivate@CAsmProp"
mov __this, this_
.if (m_hWnd)
invoke DestroyWindow, m_hWnd
mov m_hWnd, NULL
.endif
mov eax, S_OK
ret
Deactivate endp

GetPageInfo proc uses __this esi this_:ptr CAsmProp, pPPInfo:ptr PROPPAGEINFO
DebugOut "GetPageInfo@CAsmProp"
mov __this, this_
mov esi, pPPInfo
mov [esi].PROPPAGEINFO.cb, sizeof PROPPAGEINFO
invoke CoTaskMemAlloc, 32*2
mov [esi].PROPPAGEINFO.pszTitle, eax
.if (eax)
invoke lstrcpyW, eax, CStrW(L(AsmCtrl PropPage))
.endif
mov [esi].PROPPAGEINFO.size_.cx_, 240
mov [esi].PROPPAGEINFO.size_.cy, 180
invoke CoTaskMemAlloc, 32*2
mov [esi].PROPPAGEINFO.pszDocString, eax
.if (eax)
invoke lstrcpyW, eax, CStrW(L(AsmCtrl DocString))
.endif
invoke CoTaskMemAlloc, 32*2
mov [esi].PROPPAGEINFO.pszHelpFile, eax
.if (eax)
invoke lstrcpyW, eax, CStrW(L(AsmCtrl HelpFile))
.endif
mov [esi].PROPPAGEINFO.dwHelpContext, 0
mov eax, S_OK
ret
GetPageInfo endp

;--- currently only 1 object supported

SetObjects proc uses __this this_:ptr CAsmProp, cObjects:DWORD, ppUnk:ptr LPUNKNOWN

DebugOut "SetObjects@CAsmProp"
mov __this, this_
mov ecx, cObjects
.if (ecx)
mov edx, ppUnk
mov eax, [edx]
.if (eax)
lea ecx, m_pObject
invoke vf(eax, IUnknown, QueryInterface), offset IID_IAsmClass, ecx
.endif
.else
.if (m_pObject)
invoke vf(m_pObject, IUnknown, Release)
mov m_pObject, NULL
.endif
.endif
mov eax, S_OK
ret
SetObjects endp

Show proc uses __this this_:ptr CAsmProp, nCmdShow:DWORD
DebugOut "Show@CAsmProp"
mov __this, this_
.if (nCmdShow)
invoke ShowWindow, m_hWnd, SW_SHOW
.else
invoke ShowWindow, m_hWnd, SW_HIDE
.endif
mov eax, S_OK
ret
Show endp

Move proc uses __this this_:ptr CAsmProp, pRect:LPRECT
DebugOut "Move@CAsmProp"
mov __this, this_
invoke CopyRect, addr m_rect, pRect
mov eax, S_OK
ret
Move endp

IsPageDirty proc uses __this this_:ptr CAsmProp
DebugOut "IsPageDirty@CAsmProp"
mov eax, S_FALSE
ret
IsPageDirty endp

Apply proc uses __this this_:ptr CAsmProp
DebugOut "Apply@CAsmProp"
mov __this, this_
.if (m_hWnd)
invoke GetDlgItemInt, m_hWnd, IDC_EDIT1, NULL, FALSE
invoke vf(m_pObject, IAsmClass, put_Value), eax
.endif
mov eax, S_OK
ret
Apply endp

Help proc uses __this this_:ptr CAsmProp, pHelp:LPOLESTR
DebugOut "Help@CAsmProp"
mov eax, E_NOTIMPL
ret
Help endp

TranslateAccelerator_ proc uses __this this_:ptr CAsmProp, pMsg:ptr MSG
DebugOut "TranslateAccelerator@CAsmProp"
mov eax, E_NOTIMPL
ret
TranslateAccelerator_ endp

end


Furthermore, I added the propsheet coclass to AsmCtrl.idl:



[
uuid(B0D96E70-04EB-11D6-B064-8494AF9D1B52),
version(1.0),
// control,
helpstring("AsmClass coclass")
]
coclass AsmClass
{
[default] interface IAsmClass;
[default, source] dispinterface _AsmClassEvent;
};

[
uuid(B0D96E7F-04EB-11D6-B064-8494AF9D1B52),
helpstring("AsmClass PropertyPage coclass")
]
coclass AsmProp
{
interface IUnknown;
};



and AsmProp.inc is:



;--------------------------------------------------------------------------
;--- defines CAsmProp class
;--------------------------------------------------------------------------

CAsmProp struct

BEGIN_COM_MAP CAsmProp
COM_INTERFACE_ENTRY IPropertyPage
END_COM_MAP

pPropertyPageSite LPPROPERTYPAGESITE ?
hWnd HWND ?
pObject LPUNKNOWN ?
rect RECT <>
bModal BOOL ?

CAsmProp ends

;--------------------------------------------------------------------------
;--- externdefs + protos
;--------------------------------------------------------------------------

externdef CLSID_CAsmProp:GUID
externdef RegKeys_CAsmProp:REGSTRUCT

Create@CAsmProp proto pClass:ptr ObjectEntry, pUnkOuter:LPUNKNOWN

;--------------------------------------------------------------------------
;--- debugging support
;--------------------------------------------------------------------------
ifdef _DEBUG
externdef DEBUGPREFIX:LPSTR
endif
;--------------------------------------------------------------------------


the property sheet shows/edits AsmCtrl property "Value"
Posted on 2005-01-29 12:20:07 by japheth
Well, it's back to Assembler 101 for me. I was so tunnel vision'd that my problem was in the COM implementation that I overlooked preserving ebx. A few 'uses __this' solved the crashing problem.

japheth,
Thank you for the advice and code. It was really quite usefull to have other code to compare to.
Posted on 2005-01-30 08:02:55 by Wayne