News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Browse For File Button Inside Textbox

Started by fearless, September 27, 2011, 12:57:01 AM

Previous topic - Next topic

fearless

Hi,

Im been trying to create a browse ... button inside a textbox, for browsing for a file. I looked at combobox inside listview subitems (http://www.masm32.com/board/index.php?topic=1955.0) as a rough example of how i might go about this task, but im kinda stuck. So im wondering if anyone can point out what i may be missing. I can see the button appear at the right of the textbox inside it, and it disappears when focus is lost (kinda stumbled on it working), but button only shows a single . instead of ... and does not seem to be clickable. Not sure if i have the coding for the subclassed proc correct, ive tried various combinations, and also not sure if checking for EN_KILLFOCUS is the right way to remove the button. So here is the relevant code, with the IDC_ModxInstaller (CONST ID) and hModxInstaller (GetDlgItem handle) textbox being the control in question.

    .elseif eax==WM_COMMAND
mov eax, wParam
shr eax, 16
mov wNotify_code, eax   
mov eax,wParam
and eax,0FFFFh
.IF eax == IDC_CboModxDifficulty
    .IF wNotify_code == CBN_SELCHANGE
        Invoke SendMessage, hCboModxDifficulty, CB_GETCURSEL, 0, 0
        .IF eax == 0 ; easy
            Invoke SetDlgItemText, hWin, IDC_ModxEstimateTime, CTEXT("5 Minutes")
        .ELSEIF eax == 1 ; intermediate
            Invoke SetDlgItemText, hWin, IDC_ModxEstimateTime, CTEXT("15+ Minutes")
        .ELSEIF eax == 2 ; advanced       
            Invoke SetDlgItemText, hWin, IDC_ModxEstimateTime, CTEXT("30+ Minutes")
        .endif
    .ENDIF

; This is the control i want to add the ... browse button to
.ELSEIF eax == IDC_ModxInstaller
    .IF wNotify_code == EN_SETFOCUS
                        invoke SendDlgItemMessage, hModxInstaller, 999, WM_CLOSE, 0, 0
                        invoke SendMessage, hModxInstaller, EM_GETRECT, 0, Addr rect

                        mov edx, rect.right
                        sub edx, 42
                        sub rect.top, 2
                        invoke CreateWindowEx, NULL, CTEXT("Button"), CTEXT("..."), 50010000h, edx, rect.top, 42, 18, hModxInstaller, 999, hInstance, NULL
                        mov ebx,eax
                        invoke SetWindowLong,ebx,GWL_WNDPROC, OFFSET BrowseFileProc
                        mov pBrowseFileOldProc,eax

    .ELSEIF wNotify_code == EN_KILLFOCUS
        invoke SendDlgItemMessage, hModxInstaller, 999, WM_CLOSE, 0, 0
    .ENDIF
   
.ENDIF 



And here is my messy sublcassed proc for the browse button

BrowseFileProc  PROC hWin:HWND, iMsg:UINT, wParam:WPARAM, lParam:LPARAM
    ;mov  eax,iMsg
    ;.if eax==WM_KILLFOCUS
    ;    invoke SendMessage,hWin,WM_CLOSE,0,0

;.else
    invoke GetWindowLong, hWin, GWL_USERDATA
    invoke CallWindowProc, [eax+pBrowseFileOldProc], hWin, iMsg, wParam, lParam
      mov eax,TRUE
ret
;.endif
;mov  eax, FALSE
    ;ret

BrowseFileProc endp


Any help at all would be great, or even a similar example, or just info on what im missing. Thanks in advance.
ƒearless

ToutEnMasm

Bad BrowseFileProc
Quote
BrowseFileProc  PROC hWin:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
   .if uMsg == ..
   .elseif uMsg == ..
   .else
       invoke CallWindowProc,pBrowseFileOldProc, hWin, iMsg, wParam, lParam      
   ret
BrowseFileProc endp

fearless

Thanks, the button shows correctly now, but unfortunately still doesnt click or respond to a click - i tried adding WM_COMMAND to the BrowseFileProc to show a message box on succesful click, but nothing happens. Any ideas?
ƒearless

dedndave

in the documentation for WM_COMMAND, at the beginning of the Remarks section, there is a small table...
Message Source  wParam (high word)  wParam (low word)               lParam

Menu            0                   Menu identifier (IDM_*)     0
Accelerator     1                   Accelerator identifier (IDM_*)  0
Control         Control-defined     Control identifier              Handle to the
                notification code                                   control window

http://msdn.microsoft.com/en-us/library/ms647591%28v=VS.85%29.aspx

Buttons are in the Control catagory - not the same as a Menu Item   :P

the Control-defined notification code you are interested in is BN_CLICKED
http://msdn.microsoft.com/en-us/library/bb761825%28v=VS.85%29.aspx

so, when you receive a WM_COMMAND message:
1) examine the high word of wParam to see if it is a BN_CLICKED notification
2) if it is, examine the low word of wParam to see if it matches the button ID

you can use MOVZX to extend the word-sized parameters into dwords
        movzx   eax,word ptr wParam+2  ;EAX = wParam high word
        cmp     eax,BN_CLICKED
        jnz     message_handled_or_next_test

        movzx   edx,word ptr wParam    ;EAX = wParam low word
        cmp     edx,ButtonID
        jz      button_clicked_code

of course, you can use an IF/ELSE/ELSEIF/ENDIF structure if you like

if you are not handling many WM_COMMAND messages or do not have many buttons, it may be more efficient to test directly
        cmp word ptr wParam+2,BN_CLICKED
;
        cmp word ptr wParam,ButtonID

not sure how you do that with IF/ELSE/ELSEIF/ENDIF structures   :P

hutch--

Maybe I have missed something but what is wrong with using a container window and putting BOTH the edit control and the button in the container but with neither over the other ? Whichever occurs first in the control creation order will have priority over the next control, they should not overlap each other at all.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

drizz

The truth cannot be learned ... it can only be recognized.

fearless

Thanks drizz, great find.. Looking at that example, it seems there is more to inserting a button than i first thought, have to play around with the code a bit :D

Thanks to everyone else as well, i had a play around with some of the code and was thinking of just leaving the browse button outside of the editbox as i would normally do, but this example gives me renewed hope :D
ƒearless

ToutEnMasm

Quote
Thanks to everyone else as well, i had a play around with some of the code and was thinking of just leaving the browse button outside of the editbox as i would normally do, but this example gives me renewed hope :D
No more Hope,here is a simple sample in masm

dedndave

HeditProc proc uses ebx hCtl:DWORD,uMsg,wParam,lParam

.if uMsg == WM_COMMAND
HIWORD wParam,edx ;évènements des contrôles edx
LOWORD wParam,eax ;IDentificateurs de  commandes eax
mov ebx,lParam ; handle du controle
.if ebx == Hbutton

invoke MessageBox,NULL,SADR("From button in edit"),SADR("Hello !"),MB_OK
.endif
;suite
xor eax,eax ;la valeur de retour

.else
invoke CallWindowProc,lpHeditProc,hCtl,uMsg,wParam,lParam
.endif
ret
HeditProc endp


ouch !

ToutEnMasm

Ouch ?

just add the WS_CLIPCHILDREN style to the edit control to avoid a half blank button when the edit is in use.

dedndave

hi Yves,
i was refering to this part...
        .if uMsg == WM_COMMAND
                HIWORD wParam,edx ;évènements des contrôles edx
                LOWORD wParam,eax ;IDentificateurs de  commandes eax
                mov ebx,lParam ; handle du controle
                .if ebx == Hbutton

it might be better to test the notification code and control ID than the handle   :bg
otherwise, it is a nice example   :U

ToutEnMasm

Quote
it might be better to test the notification code and control ID than the handle   
otherwise, it is a nice example
Seems that  Microsoft don't agree with that.The handle is granted  UNIQUE (recommended usage)
Don't see what is a notification code with the WM_COMMAND ?
notification code is in the WM_NOTIFY message.


PBrennick

Also, WM_NOTIFY should be processed After WM_COMMAND

Paul
The GeneSys Project is available from:
The Repository or My crappy website

oex

Quote from: PBrennick on September 28, 2011, 11:09:00 PM
Also, WM_NOTIFY should be processed After WM_COMMAND

hmm interesting.... Sorry to divert from the post but what is the WM processing ordering issue?

Update: PS. I did not read the code maybe I misunderstood contextually
We are all of us insane, just to varying degrees and intelligently balanced through networking

http://www.hereford.tv