Hello all, I reciently ran across a need to subclass edit boxes on a dialog box. My first hack had some problems, and I eventually goto them figured out. Now that i have the "method" understood i thought i would toss the code out for anyone who cares :) BTW: Credit also goes to Iczelion's Tutorial as a starting point. Create the Dialog box:

	invoke CreateDialogParam,hInstance,Dialog_ID,NULL,addr DialogProc,NULL
	mov   hDlg,eax
DialogProc Initialization Code:

  .if uMsg == WM_INITDIALOG
     
     invoke GetDlgItem, hWnd, 3001 ; Edit box 1
     mov hEdit0, eax
     invoke GetDlgItem, hWnd, 3002 ; Edit box 2
     mov hEdit1, eax
     invoke GetDlgItem, hWnd, 3003 ; Edit box 3
     mov hEdit2, eax
     invoke GetDlgItem, hWnd, 3004 ; Edit box 4
     mov hEdit3, eax
     
     ; SubClass them all to same Proc...
     invoke SetWindowLong,hEdit0,GWL_WNDPROC,addr SubEditProc
     mov OldEdit0,eax
     invoke SetWindowLong,hEdit1,GWL_WNDPROC,addr SubEditProc
     mov OldEdit1,eax
     invoke SetWindowLong,hEdit2,GWL_WNDPROC,addr SubEditProc
     mov OldEdit2,eax 
     invoke SetWindowLong,hEdit3,GWL_WNDPROC,addr SubEditProc
     mov OldEdit3,eax 
The New Edit SubClass:

SubEditProc proc hEdit:DWORD, uMsg:DWORD, wParam:DWORD, lParam:DWORD
     LOCAL DoIt:DWORD
     mov DoIt, 0
     
    .if uMsg==WM_CHAR 
        mov eax,wParam 
        .if (al>="0" && al<="9") || al==VK_BACK 
          mov DoIt, 1
        .endif
    .endif
    
    mov ecx, hEdit
    .if( ecx == hEdit0) 
      mov DoIt, 0
    .endif

    .if ((DoIt==1) || (uMsg!=WM_CHAR) )
          
          .if (ecx == hEdit1)
            invoke CallWindowProc,OldEdit1,hEdit,uMsg,wParam,lParam 
          .elseif (ecx == hEdit2)
            invoke CallWindowProc,OldEdit2,hEdit,uMsg,wParam,lParam
          .elseif (ecx == hEdit3)
            invoke CallWindowProc,OldEdit3,hEdit,uMsg,wParam,lParam
          .elseif (ecx == hEdit0)
            invoke CallWindowProc,OldEdit0,hEdit,uMsg,wParam,lParam
          .endif
          ret 
    .endif 
    xor eax,eax 
    ret
SubEditProc endp
The Subclassed Edit windows in the dialog box are to restict only numeric input. As well, I added a revision to hEdit0 (Edit 1) such that it will not allow any form of input. Anywho, this is my hack of subclassing dialog boxes.. Hope it helps someone :) NaN
Posted on 2001-05-02 02:19:00 by NaN
Your method works but it's not efficient. If you want to create multiple controls with the same characteristics, use superclassing, not subclassing. Of course, you can subclass every control but it's quite tedious.
Posted on 2001-05-02 09:13:00 by Iczelion
Thanx for the tip.. I didnt realize this :) Iczelion's Superclassing Tut:
In your programming career, you will surely encounter a situation where you need several controls with *slightly* different behavior. For example, you may need 10 edit controls which accept only number. There are several ways to achieve that goal: Create your own class and instantiate the controls Create those edit control and then subclass all of them Superclass the edit control
However, Im now a bit lost :( The window i made was a dialog-based main window, and all controls are defined by the resource file. It appears i dont have any control 'how' the resourced edit windows are created, and thus i can't superclass them directly as outlined in your tutorial. A bit of brain storming suggests that perhaps i could build the WINCLASS structure (derived from edit) before i call the CreateDialogParam, but i would need to somehow tell the resource file to use 'this class' for the control. Is this even remotely possible? NaN This message was edited by NaN, on 5/2/2001 12:39:23 PM
Posted on 2001-05-02 12:12:00 by NaN
the custom control is the way to go if you want to use your own window class in a dialog. you create the wndclass and register it before you create the dialog, and specify the class name in the resource file. i'm not sure it's really worth all the trouble though.
Posted on 2001-05-02 16:16:00 by fresh
I tried a hack at it, and appearently hitting a wall with no answers (since the window abruptly destroyes itself as fast as it is created.. ???). I would like to be as flexible with dialog boxes as normal window classes so i dont want to leave this alone untill i understand the nature of this beast.. :) Here is my latest hack, if anyone can see my flaw lemme know: The main.asm:

WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD
	LOCAL wc:WNDCLASSEX
	LOCAL msg:MSG
	LOCAL hDlg:HWND
	szText szClassName, "POINTS"
	mov   wc.cbSize,SIZEOF WNDCLASSEX
	mov   wc.style, CS_HREDRAW or CS_VREDRAW
	mov   wc.lpfnWndProc, OFFSET DialogProc
	mov   wc.cbClsExtra,NULL
	mov   wc.cbWndExtra,DLGWINDOWEXTRA
	push  hInst
	pop   wc.hInstance
	mov   wc.hbrBackground,COLOR_BTNFACE+1
	mov   wc.lpszMenuName, NULL
	mov   wc.lpszClassName,OFFSET szClassName
	invoke LoadIcon,hInstance,500
	mov   wc.hIcon,eax
	mov   wc.hIconSm,eax
	invoke LoadCursor,NULL,IDC_ARROW
	mov   wc.hCursor,eax
	invoke RegisterClassEx, addr wc
	; ############################ SUPERCLASSING ##############################
        mov wc.cbSize,sizeof WNDCLASSEX 
        invoke GetClassInfoEx,NULL,addr szEditClass,addr wc 
        push wc.lpfnWndProc 
        pop OldEdit4 
        mov wc.lpfnWndProc, OFFSET SubEditProc 
        push hInstance 
        pop wc.hInstance 
        mov wc.lpszClassName,OFFSET szNEWEDIT
        invoke RegisterClassEx, addr wc 
	; ############################ SUPERCLASSING ##############################
     MAKEMESSAGE "HERE"   	
	invoke CreateDialogParam,hInstance,6000,NULL,addr DialogProc,NULL
	mov   hDlg,eax
     MAKEMESSAGE "HERE TO"
     invoke GetDlgItem,hDlg,3002
	invoke SetFocus,eax	
     invoke SetWindowText, hDlg, addr szDisplayName
     INVOKE ShowWindow, hDlg,SW_SHOWNORMAL
	INVOKE UpdateWindow, hDlg
	.WHILE TRUE
                INVOKE GetMessage, ADDR msg,NULL,0,0
                .BREAK .IF (!eax)
                invoke IsDialogMessage, hDlg, ADDR msg
                .if eax==FALSE
                        INVOKE TranslateMessage, ADDR msg
                        INVOKE DispatchMessage, ADDR msg
                .endif
	.ENDW
	mov     eax,msg.wParam
	ret
WinMain endp
Nothing too special here, except im registering the main window instance, as well trying to register a new EditClass. (szEditClass == "EDIT",0 ) and (szNEWEDIT == "NEWEDIT",0). The Resource file has a new control added: (At the end)

6000 DIALOGEX MOVEABLE IMPURE LOADONCALL DISCARDABLE	10, 10, 191, 74, 0
STYLE DS_MODALFRAME | 0x0004 | DS_SETFOREGROUND | DS_CENTER |\
                  WS_CAPTION | WS_SYSMENU | WS_VISIBLE | WS_POPUP
CAPTION "Ponts Finder"
CLASS "POINTS"
FONT 8, "MS Sans Serif", 700, 0 /*FALSE*/
BEGIN
    LTEXT           "A", -1, 	8,4,60,12, SS_LEFT, , 0
    LTEXT           "B", -1, 	8,20,60,12, SS_LEFT, , 0
    LTEXT           "C", -1, 	8,36,60,12, SS_LEFT, , 0
    LTEXT           "D", -1, 	116,4,60,12, SS_LEFT, , 0
    EDITTEXT        3001, 	116,16,68,12, ES_AUTOHSCROLL | ES_LEFT, , 0
    PUSHBUTTON      "Calculate", 5000, 	116,32,72,16, 0, , 0
    EDITTEXT        3002, 	68,4,36,12, ES_AUTOHSCROLL | ES_LEFT, , 0
    EDITTEXT        3003, 	68,20,36,12, ES_AUTOHSCROLL | ES_LEFT, , 0
    EDITTEXT        3004, 	68,36,36,12, ES_AUTOHSCROLL | ES_LEFT, , 0
    CONTROL         "NEWEDIT", 3005,"NEWEDIT" , WS_TABSTOP, 	68,56,36,12, , 0
END
I added this control with a resource editor, and assume correct (could be wrong tho), Im leaning this way because when tested, if the above code runs fine if i comment out the control ('//') above, but if i dont, the above code simple intantiates and quits in a few milli-seconds.. (nothing to learn from)! :( The SubEditClass is still the same, (expanded to handle for this control, but same none the less). The two messages were my testing points. Again, when not commented, i get the first message box (HERE), and only hear the ding of the second but never see its box (since the i
Posted on 2001-05-02 21:42:00 by NaN
Common, someone has to have tried using a resource 'CONTROL' with a specially registered class?? How do you do it right? NaN
Posted on 2001-05-04 00:49:00 by NaN
The syntax of your control statement in the RC file is correct. You could try replacing the NEWEDIT with EDIT, and use the standard edit control, but defined as a 'CONTROL', just to check that it works (you don't need the extra bits on the end of the line either, as the resource compiler should take defaults if they're not specified).

    CONTROL "", 3005,"EDIT", WS_TABSTOP, 68, 56, 36, 12
Also worth trying to comment out the lines that change the behaviour of your new class, and leave the default behaviour of the edit control, but use your newly registered class. You could also check the error condition of each function when it returns! Hope this is useful Nick
Posted on 2001-05-04 07:39:00 by Nick