News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

Subclassing textbox

Started by cozofdeath, June 29, 2012, 02:13:32 AM

Previous topic - Next topic

cozofdeath

Does anyone know why subclassing a textbox leaves it uneditable? The textbox can be updated with an api like SetWindowText or SetDlgItemText but it won't allow you to click or manually edit text. Below is my code.

Main  window proc:
DlgProc proc hWin:DWORD, uMsg:DWORD, wParam:DWORD, lParam:DWORD

.if uMsg == WM_INITDIALOG
invoke LoadIcon, hInstance, ICO_MAIN
invoke SendMessage, hWin, WM_SETICON, NULL, eax
invoke GetDlgItem, hWin, TB_OPEN
mov hOpenTextbox, eax
invoke GetDlgItem, hWin, TB_DEST
mov hDestTextbox, eax
invoke SetFocus, hOpenTextbox
invoke SetWindowLong, hOpenTextbox, GWL_WNDPROC, DragDropProc
mov pOrigDlgProc, eax

.elseif uMsg == WM_COMMAND
.if wParam == BTN_OPEN
invoke GetFileDialog
invoke DisplayFilePaths, hWin

.elseif wParam == BTN_GEN
invoke GetDlgItem, hWin, LB_OUTPUT
mov hListBox, eax

        .elseif wParam == BTN_ABOUT
invoke EndDialog,hWin,0
.endif

.elseif uMsg == WM_DESTROY
invoke SetWindowLong, hOpenTextbox, GWL_WNDPROC, pOrigDlgProc
invoke PostQuitMessage, 0

.elseif uMsg == WM_CLOSE
invoke EndDialog,hWin,0
.else
invoke DefWindowProc, hWin, uMsg, wParam, lParam
.endif

xor eax,eax
ret
DlgProc endp


Textbox window proc:
DragDropProc proc hWin:DWORD, uMsg:DWORD, wParam:DWORD, lParam:DWORD

.if uMsg == WM_DROPFILES

invoke DragQueryFile, wParam, -1, addr szFullPath, SIZEOF szFullPath
...
invoke DragFinish, wParam
xor eax,eax
            ret
.endif

invoke CallWindowProc, pOrigDlgProc, hWin, uMsg, wParam, lParam

xor eax, eax
ret


Thanks for any constructive help :biggrin:

qWord

hi,

Remove the XOR EAX,EAX after CallWindowProc().

EDIT: also add a RET after DefWindowProc()
MREAL macros - when you need floating point arithmetic while assembling!

cozofdeath

hi qWord,

The "xor eax, eax" did it! Thank you :biggrin: All this time spent trying different things. Man do I feel dumb. Masm often makes me feel this way. :dazzled: So I'm guessing eax has to retain its value after calling CallWindowProc because its the return value from what gets executed in the original window procedure? And this is needed by windows itself?

qWord

Quote from: cozofdeath on June 29, 2012, 04:01:12 AMSo I'm guessing eax has to retain its value after calling CallWindowProc because its the return value from what gets executed in the original window procedure?
Exact.
The same applies to DefWindowProc.
MREAL macros - when you need floating point arithmetic while assembling!

MichaelW

coz,

If you look at the Microsoft examples for DefWindowProc and CallWindowProc, you will see that when these functions are called the enclosing window or subclass procedure returns whatever these functions return. The documentation implies this but does not clearly state it. For example, the documentation for WindowProc and DefWindowProc both state "The return value is the result of the message processing and depends on the message."
Well Microsoft, here's another nice mess you've gotten us into.

hutch--

Its worth keeping in mind that if and when you need to exit a WndProc style procedure for a normal CreateWindowEx() style window that you check the return value of the message that is being processed.

Some messages require that you return zero and this you do simply by the code sequence,


    xor eax, eax    ; set EAX to zero
    ret


This bypasses the DefWindowProc. Apart from this you actually need to call DefWindowProc so that the default message processing occurs.

Just to make life confusing, when you have a dialog message handler, it MUST set EAX to zero then return. You exit a dialog with the API call, not the value in EAX or the trailing RET.

cozofdeath

I really appreciate the constructive replies. I'll take any information I can get. I'm my own defense I did look at pretty much everything MSDN provides on this subject as well as closely related subjects and I just couldn't understand I guess. I even tried various Google links with no luck. To actually post was my last option and you guys came through again.  Without this site I don't know what I'd do.


QuoteJust to make life confusing, when you have a dialog message handler, it MUST set EAX to zero then return. You exit a dialog with the API call, not the value in EAX or the trailing RET.

By dialog message handler, do you mean DefDlgProc? I am working with only a dialog box invoked with DialogBoxParam so should I be using DefDlgProc instead or does it not matter?

dedndave

it does matter   :P
but, no - you should not use DefDlgProc with a dialog created with DialogBoxParam
just return 0 in EAX

DefDlgProc is used for dialog boxes that have a private window class

cozofdeath

Quote from: dedndave on June 30, 2012, 05:41:07 AM
it does matter   :P
but, no - you should not use DefDlgProc with a dialog created with DialogBoxParam
just return 0 in EAX

DefDlgProc is used for dialog boxes that have a private window class

Thanks for the info :biggrin: I can now drag and drop successfully.  :eusa_dance: