I've been playing around with subclassing & have had no problems with the code or the filter in EditWndProc which only accepts decimal digits, that piece of code is below :-
.ELSEIF ax==1310
mov icount,0
invoke CreateWindowEx,NULL, ADDR ButtonClassName,ADDR ButtonText,\
WS_CHILD or WS_VISIBLE or BS_DEFPUSHBUTTON,\
75,70,140,25,hWnd,ButtonID,hInstance,NULL
mov hwndButton,eax
invoke CreateWindowEx,WS_EX_CLIENTEDGE,ADDR EditClass,NULL,\
WS_CHILD+WS_VISIBLE+WS_BORDER,380,\
300,25,25,hWnd,NULL,hInstance,NULL
mov hwndEdit,eax
invoke SetFocus,eax
invoke SetWindowLong,hwndEdit,GWL_WNDPROC,addr EditWndProc
mov OldWndProc,eax
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
ret
But when I tried to superclass 10 edit boxes using the same filter the edit boxes don't display, there is no error assmbling & If I uncomment the MessageBox that dislays OK so I know it's getting to the correct menu item. Can anyone see whats wrong :( Code below :-
.ELSEIF ax==1200
mov wc.cbSize,sizeof WNDCLASSEX
invoke GetClassInfoEx,NULL,addr EditClass,addr wc
push wc.lpfnWndProc
pop OldWndProc
mov wc.lpfnWndProc, OFFSET EditWndProc
push hInstance
pop wc.hInstance
mov wc.lpszClassName,OFFSET OurClass
invoke RegisterClassEx, addr wc
xor ebx,ebx
mov edi,20
.while ebx<11
invoke CreateWindowEx,WS_EX_CLIENTEDGE,ADDR OurClass,NULL,\
WS_CHILD or WS_VISIBLE or WS_BORDER,20,75,edi,25,hWnd,NULL,\
hInstance,NULL
mov dword ptr [hwndEdit+4*ebx],eax
add edi,25
inc ebx
.endw
invoke SetFocus,hwndEdit
;invoke MessageBox,hWnd,NULL,ADDR szDisplayName,MB_OK
An error message would be useful, if you could give us the error message or code it would make it a lot easier than building a skeleton and plugging in your code.
Edgar
I agree with Edgar, where is the error occuring. There are two possibilities and either the window is not being created at all, or there is a problem in the handler.
I don't believe it's necessary to create a new class.
1. Create the control
2. SetWindowLong, NewControl, GWL_WNDPROC, Your_Handler
After that, all controls of that class EDIT, BUTTON, STATIC or whatever will respond to your handler
Neil,
The trick is to get the first control and subclass working properly then use the same SetWindowLong() for the handle of each additional control.
Actually I agree with Neil, with 11 controls or so he's better off superclassing them, his code seems to do the creation based on a button being pressed or something so they are dynamically created and probably destroyed. A superclass makes sense in this situation especially because he is changing a particular behaviour of the control.
Edgar
Thanks for your comments, this is a 'TEST' piece written so that I can learn all the ins & outs of writing a GUI.
Back to the problem, the edit boxes should display when a menu item is clicked - they don't & there is no error message & as I said if the message box is uncommented that displays correctly, so I'm a bit baffled :dazzled:
There will be no error message unless you display one. Instead of your message box, you might use MsgBox 0, LastError$(), "Test", MB_OK.
Tried that JJ & there is no error message. It's as if the edit boxes are being displayed & then immediately destroyed before I have time to see them?
What do you mean by "no error messsage"? No error or no message? The problem could be solved in no time if you simply posted your complete code...
JJ yes the message box displays & says that "The application completed successfully". I'm still playing with it at the moment, if I can't get anywhere I'll post the source.
What happens if you comment mov wc.lpfnWndProc, OFFSET EditWndProc ?
I get 1 long edit box which accepts only decimal digits, EDIT my mistake it accepts all characters
The 1 long Edit Box could be 10 edit boxes side by side, maybe I haven't left enough space in between.
No, it is one long Edit Box. It doesn't get focus as the message box displays as well, or is that normal behaviour?
WS_BORDER,20,75,edi,25,
You have ten boxes, but the last one covers all previous ones.
I,ve Changed it to :- WS_BORDER,20,edi,75,25
Now I've got the edit Boxes but Instead of being side by side they are underneath one another.
I'll check through the parameters to find out what I'm doing wrong.
Right, changed the parameters to :- WS_BORDER,edi,20,25,25.
Now I've got the Edit Boxes displaying side by side, Thanks JJ :U
So it seems that the display problem is in EditWndProc, I'll study it & try & pin the problem down, if not I'll post it.
I've looked at EditWndProc & commented everything out so all that's left in it is xor eax,eax & ret & the edit boxes still don't show but if as JJ suggested I comment out mov wc.lpfnWndProc, OFFSET EditWndProc they do I'm baffled :(
Quote from: Neil on February 08, 2010, 03:44:18 PM
I've looked at EditWndProc & commented everything out so all that's left in it is xor eax,eax & ret
Is
ret the right way to leave that proc? Have you tried a call to DefWindowProc?
Quote from: jj2007 on February 08, 2010, 04:19:15 PM
Quote from: Neil on February 08, 2010, 03:44:18 PM
I've looked at EditWndProc & commented everything out so all that's left in it is xor eax,eax & ret
Is ret the right way to leave that proc? Have you tried a call to DefWindowProc?
In Superclassing he should call the old window procedure, although DefWindowProc will do in a pinch, after all you only superclassed to get some functionality from the global class and that it done through its old window procedure. Under no circumstances should he be returning with a simple RET, there are a lot of messages that need to be processed. Returning 0 generally means that the message has been processed (for example WM_NCPAINT), if it was not then you must pass it to Windows for processing.
Here is the complete EditWndProc, this works OK when I subclass 1 Edit Box.
EditWndProc PROC hEdit:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD
cmp uMsg,WM_CHAR
jne ERT
mov eax,wParam
jmp @F
cmp al,VK_RETURN
jne @F
cmp icount,2
jne ERT
invoke DestroyWindow, hEdit
ERT: xor eax,eax
ret
@@: cmp al,VK_BACK
jne ERTT
cmp icount,0
je ERT
dec icount
jmp ERTTT
ERTT: cmp icount,2
je ERT
cmp al,"0"
jb ERT
cmp al,"9"
ja ERT
cmp icount,0
jne ER
cmp al,"4"
ja ERT
ER: inc icount
ERTTT: invoke CallWindowProc,OldWndProc,hEdit,uMsg,eax,lParam
ret
EditWndProc endp
Discovered that if I comment out everything except invoke CallWindowProc,OldWndProc,hEdit,uMsg,eax,lParam ret 1 edit box is displayed?
And what happens if you replace eax with wParam?
It works!! :U :U
I'm puzzled why
Unfortunately it only displays the Edit Boxes when everything else is commented out :(
But it still works OK with the subclassed Edit Box.
EDIT There is one difference with the subclassed Edit Box in that it now doesn't get destroyed when ENTER is pressed.
Neil,
What you would normally do in production code is to make a procedure that contains the CreateWindowEx() function call to make the control and make a normal subclass to go with the procedure that does what you want with that control. Once this is working correctly you can duplicate the control by just calling the first procedure as many times as you need.
Quote from: Neil on February 08, 2010, 07:35:43 PM
It works!! :U :U
I'm puzzled why
Imagine a sub/superclassing procedure as a kind of break point where Windows allows you to intervene before it continues to do its job. For example, if a WM_CHAR message with a 9 in wParam passes by this break point, Windows gives you a chance to decide whether you want to insert a tab or not. By returning null, you tell Windows "no further processing", and no tab will be inserted. By jumping to the end, CallWindowProc or DefWindowProc will take over and do the default processing.
So if you get a WM_PAINT message and you do NOT call CallWindowProc, nothing will be painted (except you do it yourself by hand...).
This is certainly a steep learning curve, thanks for all the info, I'm now going to 'sleep' on it & start afresh tomorrow.
Happy to report I've cracked it. After studying Iczelion's Tutorial Number 22 I could see where I was going wrong.
Now all I've got to do is refine it so that it does what i want it to do :bg
Thanks everyone for pointing me in the right direction, without that I would still be looking in the wrong place :clap:
I'm implementing a 'CANCEL' button for the above Edit Boxes. The way I'm getting rid of them at the moment is by means of a loop which adds 4 to hwndEdit & then Invokes DestroyWindow on each pass through the loop. It works but is this the correct way to do it or is there an easier method?