I'm trying to learn how to subclass a control in objasm32. So I've created an EditControl 
object using a WinControl object as the parent. Here's the object:

Object EditControl,EditControlID,WinControl ; class "EDIT"
RedefineMethod Init, Pointer, Handle, Pointer
RedefineMethod Done
RedefineMethod WndProc,     dword, dword, dword

DefineVariable hEdit,      Handle, 0
ObjectEnd

and here's the methods:

if IMPLEMENT

; ????????????????????
; Method:    EditControl.Init
; Purpose:
; Arguments: pOwner: Pointer to an owner object
;            hParentWnd: Handle to a parent window
;            pDefStruc: Pointer to initialization structure
; Return:    Nothing

Method EditControl.Init, uses esi, pOwner:Pointer, hParentWnd:Handle, pDefStruc:Pointer
    SetObject esi

    mov ecx, pDefStruc
    assume ecx:ptr EditDef
    mov eax, .dStyle
    or eax, WS_CHILD or WS_VISIBLE
    @invoke CreateWindowEx, .dExStyle, "EDIT", NULL, eax, \
            .sdPosX, .sdPosY, .dWidth, .dHeight, \
            hParentWnd, .dCtlID, hInstance, 0
    mov .hEdit, eax
    assume ecx:nothing
    ACall esi.Init, pOwner, eax
    Subclass EditControl                            ;Uses esi

MethodEnd

; ???????????????????????????
; Method:    EditControl.Done
; Purpose:
; Arguments: None.
; Return:    Nothing

Method EditControl.Done, uses esi
    SetObject esi

    Unsubclass EditControl                          ;Uses esi
    ACall Done
MethodEnd
; ???????????????????????
; Method:    EditControl.WndProc
; Purpose:
; Arguments: uMsg:  Message identifier
;              wParam: First message parameter
;              lParam:  Second message parameter
;                          Window handle passed in esi
; Return:

Method EditControl.WndProc,, uMsg:dword, wParam:dword, lParam:dword
    GetSubclassingInst EditControl, Self
    OCall eax::EditControl.Dispatch, Self, uMsg, wParam, lParam
MethodEnd

The initialization structure is defined as:

EditDef struc
  dCtlID      dword    ?  ; Control ID
  sdPosX      sdword    ?  ; X position
  sdPosY      sdword    ?  ; Y position
  dWidth      dword    ?  ; Width
  dHeight    dword    ?  ; Height
  dStyle      dword    ?  ; Control style.
  dExStyle   dword ?  ; Extended style.
EditDef ends

I can create and place an edit control on a window with this object.
Just for learning purposes using Icz's tut as an example, I tried using an "Event" for the WM_Char message and a Static method to filter out unwanted characters.
Here's the method:

Method EditControl.OnChar, , wParam:dword, lParam:dword

    mov eax, wParam

    .if (eax >= 'a') && (eax <= 'f')
      GetSubclassingInst EditControl, Self
      OCall eax::EditControl.Dispatch, Self, WM_CHAR, wParam, lParam
    .endif
    xor eax, eax
MethodEnd

Well the unwanted chars are filtered out, but when I press a char in the wanted range ,the pro craps out and drwin pops up.
What am I missing/ doing wrong?
Regards,
    Rags
Posted on 2007-02-06 12:22:57 by rags
Hi rags
First the good news: using the WinControl as the ancestor for the EditControl is a good choice. Take a look at it methods to see what it does. Basically, it has a message dispatch mechanism build in the Dispatch method and an abstract method for the new descendant method that will receive the Window messages and pass them to the dispatcher. Tollbar.inc is a short file you can use as orientation. Looking at your code I cant see nothing wrong with this.

OK, now the problem is the last method, EditControl.OnChar. I guess that you only want the the characters in the range from a..f reach the Edit control. In that case you have to forward the message to the original Edit window using

Method EditControl.OnChar, , wParam:dword, lParam:dword
    SetObject ecx
    mov eax, wParam
    .if (eax >= 'a') && (eax <= 'f')
      invoke SendMessage, .hWnd, WM_CHAR, wParam, lParam
    .else
      xor eax, eax
    .endif
MethodEnd


A second issue is where you store the handle if the subclassed Edit control. The parent of WinControl is called WinPrimer. It defines the hWnd member and there you must store it. You will see that the Subclass macro (WinHelpers.inc) makes use of it.
My suggestion is to remove the hEdit member and use something like

Object EditControl,EditControlID,WinControl      ; class "EDIT"
  RedefineMethod Init,      Pointer, Handle, Pointer
  RedefineMethod Done
  StaticMethod  OnChar,    dword, dword
  RedefineMethod WndProc,  dword, dword, dword
 
  Event OnChar, WM_CHAR

ObjectEnd



Method EditControl.Init, uses esi, pOwner:Pointer, hParentWnd:Handle, pDefStruc:Pointer
    SetObject esi
    mov ecx, pDefStruc
    assume ecx:ptr EditDef
    mov eax, .dStyle
    or eax, WS_CHILD or WS_VISIBLE
    @invoke CreateWindowEx, .dExStyle, "EDIT", NULL, eax, \
            .sdPosX, .sdPosY, .dWidth, .dHeight, \
            hParentWnd, .dCtlID, hInstance, 0
    assume ecx:nothing
    ACall esi.Init, pOwner, eax
    Subclass EditControl                            ;Uses esi
MethodEnd


I hope this helps  ;)

Regards,

Biterider
Posted on 2007-02-06 14:58:05 by Biterider
BiteRider,
I finally got a chance to sit down and look at and make the changes you suggested.
The proposed changes to the code you made, seems to send the code into an endless loop.
After studying your code in the objects I came up with this, which seems to work properly.:

Method EditControl.OnChar,, wParam:dword, lParam:dword
    SetObject ecx

    mov eax, wParam


    .if  (eax >= 'a') && (eax <= 'f')

    invoke CallWindowProc ,.pPrevWndProc,.hWnd,WM_CHAR,wParam,lParam
    xor eax, eax
    .else
      xor eax, eax
    .endif

MethodEnd


Thanks for taking the time to reply :)
regards,
    Rags

Posted on 2007-02-12 12:27:12 by rags