The MASM Forum Archive 2004 to 2012

General Forums => The Campus => Topic started by: oex on March 01, 2012, 06:32:53 PM

Title: Destruction
Post by: oex on March 01, 2012, 06:32:53 PM
I'm sure I'm missing something obvious but maybe one of you genius' could help me

I create a window
CreateWindowEx, WS_EX_OVERLAPPEDWINDOW, chr$("P2D"), chr$("P2D"), WS_EX_OVERLAPPEDWINDOW or WS_VISIBLE, 0, 0, 1366, 768, 0, 0, 400000h, 0
I create an Edit Control

CreateWindowEx, WS_EX_CLIENTEDGE, chr$("EDIT"), oexText, WS_VISIBLE or WS_CHILDWINDOW or ES_AUTOHSCROLL, oexLeft, oexTop, oexWidth, oexHeight, oexParenthWnd, oexID, hInstance, 0

; On Button Command (Submit)
.elseif uMsg == WM_COMMAND
mov eax, wParam
mov edx, eax
shr edx, 16

.if dx == BN_CLICKED && ax == 500

I try everything to destroy Child Window (Edit Control)
ShowWindow, oexChildhWnd, SW_HIDE
SendMessage, oexChildhWnd, WM_CLOSE, 0, 0
DestroyWindow, oexChildhWnd


I refresh the parent window
UpdateWindow, oexParenthWnd

I can still see the Child Control.... :(????



Obviously the code is a bit more complicated than this.... I just need to be sure I'm understanding the process right.... there are many Controls with ChildhWnds saved to a buffer which is looped and all controls are meant to be destroyed.... I dont think there is a problem there.... I dont want to reuse the controls Just delete them after the form has completed.... Any issues here?
Title: Re: Destruction
Post by: dedndave on March 01, 2012, 06:50:35 PM
what ? - you didn't try CloseHandle ???   :lol

DestroyWindow should work, unless you are trying to do it from a different thread than the one that created it
Title: Re: Destruction
Post by: oex on March 01, 2012, 06:51:48 PM
Quote from: dedndave on March 01, 2012, 06:50:35 PM
what ? - you didn't try CloseHandle ???   :lol

DestroyWindow should work, unless you are trying to do it from a different thread than the one that created it

I have tried the DIEDIEDIE!!! function but that doesnt work either.... Same thread....

I'll check some more that I am passing the correct hWnd handles but I think I am :(
Title: Re: Destruction
Post by: dedndave on March 01, 2012, 06:53:04 PM
if you destroy a window or dialog, it will (should) destroy all children, as well

perhaps the WndProc for the edit control is not handling default message processing correctly ?
Title: Re: Destruction
Post by: oex on March 01, 2012, 06:53:48 PM
I am trying to destroy the child and not the parent.... Whatever the default on a static/edit control is what is being processed I havent subclassed the edit control yet
Title: Re: Destruction
Post by: jj2007 on March 01, 2012, 06:54:32 PM
Works perfectly... your problem must be elsewhere. What's your error message?

Button1 proc
invoke DestroyWindow, hButton2
MsgBox 0, LastError$(), "Button 2 is gone:", MB_OK
ret
Button1 endp
Title: Re: Destruction
Post by: oex on March 01, 2012, 06:55:47 PM
No error message just the form still appears (*but I can't click in the edit boxes....*)

This works:
.elseif uMsg==WM_PARENTNOTIFY
mov eax, wParam
mov edx, eax
shr edx, 16

.if ax == 2
invoke MessageBox,0,"Control Deleted","Action",MB_OK
.endif
xor eax, eax
ret


The Parent hWnd does not refresh properly with UpdateWindow?

Is there something I am doing wrong to Update/Refresh the ParenthWnd?
Title: Re: Destruction
Post by: jj2007 on March 01, 2012, 07:10:20 PM
Quote from: oex on March 01, 2012, 06:55:47 PM
The Parent hWnd does not refresh properly with UpdateWindow?

Try an InvalidateRect before.
Title: Re: Destruction
Post by: oex on March 01, 2012, 07:13:09 PM
Quote from: jj2007 on March 01, 2012, 07:10:20 PM
Quote from: oex on March 01, 2012, 06:55:47 PM
The Parent hWnd does not refresh properly with UpdateWindow?

Try an InvalidateRect before.

no joy
Title: Re: Destruction
Post by: dedndave on March 01, 2012, 07:19:54 PM
Peter, you may have to show us more code - or perhaps attach
Title: Re: Destruction
Post by: oex on March 01, 2012, 07:22:39 PM
Yeah I'll keep at it for a while and see if I can fix it.... There is a lot of code :(.... At least I have basically confirmed I have the process correct, I'm now testing all my inputs :'(

Thanks for your help I'll keep you posted
Title: Re: Destruction
Post by: qWord on March 01, 2012, 07:34:34 PM
maybe you are creating several controls about each other ...
Title: Re: Destruction
Post by: oex on March 01, 2012, 07:44:50 PM
I think I must had a more annoying issue somewhere WM_PARENTNOTIFY just failed to be called in testing....

Going to take it all to pieces again and then put it back together with the missing screw ::)

That'll teach me to paint a picture with all the paint brushes at the same time
Title: Re: Destruction
Post by: oex on March 01, 2012, 08:19:04 PM
Yes cheers guys, idiot error somewhere, it's all working now it seems.... :red

(http://2.bp.blogspot.com/-Zyui8l4jCKM/Ts4GkbirYtI/AAAAAAAACjw/zIJFK5LBLJs/s1600/alien+mona.jpg)
Title: Re: Destruction
Post by: dedndave on March 01, 2012, 08:27:58 PM
what was it ???   :red
Title: Re: Destruction
Post by: oex on March 01, 2012, 08:34:34 PM
No it's still an issue....

I can destroy the form in the WM_CREATE msg (Where I create the form) with the method below

But calling the destroy code in other messages such as WM_LBUTTONUP and WM_COMMAND -> BN_CLICKED will not remove the form....

      mov esi, FormFieldhWndPtrs
      .while DWORD PTR [esi]
         invoke DestroyWindow, [esi]
         add esi, 4
      .endw


OK.... Placing the following after the DestroyWindow code:

Fails
      invoke UpdateWindow, hWnd

Fails
      invoke InvalidateRect, hWnd, 0, TRUE
      invoke UpdateWindow, hWnd

Works
      invoke ShowWindow, hWnd, SW_HIDE
      invoke ShowWindow, hWnd, SW_SHOW

Can I do this without hiding and then reshowing the window?
Title: Re: Destruction
Post by: jj2007 on March 01, 2012, 09:09:07 PM
Peter,
It's almost impossible to find the solution without having the full code. One last attempt: SendMessage hWnd, WM_PAINT, 0, 0  ... brute force ::)
Title: Re: Destruction
Post by: oex on March 01, 2012, 10:24:05 PM
OK I will pull it to pieces tomorrow and send the relevent sections.... The exe is 600Kb ASM app so it's rather complicated :lol.... I thought maybe it's just the order in which I call stuff or something....

I will make it an independant app tomorrow, the section with the issues is pretty small
Title: Re: Destruction
Post by: dedndave on March 01, 2012, 10:38:51 PM
when you get the desired button click in the parent window, execute this...
        INVOKE  SendMessage,hEditControl,WM_SYSCOMMAND,SC_CLOSE,NULL

that should cause the default processing to prepare for closing, and send a WM_CLOSE message
when you receive the WM_CLOSE message in the Edit Control WndProc, execute this...
        INVOKE  DestroyWindow,hWnd
        xor     eax,eax
        ret

(hWnd from WndProc parms should now be same as hEditControl)
Title: Re: Destruction
Post by: MichaelW on March 02, 2012, 07:07:29 AM
I didn't have time to try this with an application window, but with a dialog it works as expected:

;==============================================================================
    include \masm32\include\masm32rt.inc
;==============================================================================
    .data
    .code
;==============================================================================
DlgProc proc hwndDlg:dword, uMsg:dword, wParam:dword, lParam:dword
    SWITCH uMsg
      CASE WM_INITDIALOG
      CASE WM_COMMAND
          .IF WORD PTR wParam+2 == BN_CLICKED
              invoke DestroyWindow, lParam
              add wParam, 1000
              invoke GetDlgItem, hwndDlg, wParam
              invoke DestroyWindow, eax
          .ENDIF
      CASE WM_CLOSE
        invoke EndDialog, hwndDlg, 0
    ENDSW
    xor eax, eax
    ret
DlgProc endp
;==============================================================================
start:
;==============================================================================
    Dialog "Test", "MS Sans Serif",10, \
           WS_OVERLAPPED or WS_SYSMENU or DS_CENTER, \
           16,0,0,103,112,1024
    ID=1000
    Y=0
    REPEAT 8
        Y=Y+10
        DlgButton "X",WS_TABSTOP,10,Y,10,10,ID
        DlgEdit  WS_BORDER,30,Y,60,10,ID+1000
        ID=ID+1
    ENDM
    invoke GetModuleHandle, NULL
    CallModalDialog eax,0,DlgProc,NULL
    exit
;==============================================================================
end start


And now I have determined that it also works as expected in an application window.

;==============================================================================
    include \masm32\include\masm32rt.inc
;==============================================================================
    .data
        hWnd      HWND        0
        hInst     HINSTANCE   0
        wcx       WNDCLASSEX  <>
        msg       MSG         <>
        posx      dd          0
        posy      dd          0
        className db          "test_class",0
    .code
;==============================================================================
WindowProc proc hwnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
    LOCAL rc:RECT
    SWITCH uMsg
      CASE WM_CREATE
        ID=1000
        Y=0
        REPEAT 8
          Y=Y+25
          invoke CreateWindowEx,0,chr$("BUTTON"),chr$("X"),
                                WS_CHILD or WS_VISIBLE or WS_TABSTOP,
                                25,Y,25,25,hwnd,ID,0,NULL
          invoke CreateWindowEx,WS_EX_CLIENTEDGE,chr$("EDIT"),0,
                                WS_CHILD or WS_VISIBLE or \
                                ES_AUTOHSCROLL or ES_NOHIDESEL,
                                75,Y,160,25,hwnd,ID+1000,0,NULL
          ID=ID+1
        ENDM
      CASE WM_COMMAND
          .IF WORD PTR wParam+2 == BN_CLICKED
              invoke DestroyWindow, lParam
              add wParam, 1000
              invoke GetDlgItem, hwnd, wParam
              invoke DestroyWindow, eax
          .ENDIF
      CASE WM_CLOSE
        invoke DestroyWindow, hwnd
      CASE WM_DESTROY
        invoke PostQuitMessage, NULL
      DEFAULT
        invoke DefWindowProc, hwnd, uMsg, wParam, lParam
        ret
    ENDSW
    return 0
WindowProc endp
;==============================================================================
start:
;==============================================================================
    invoke GetModuleHandle, NULL
    mov hInst, eax
    mov wcx.cbSize,        SIZEOF WNDCLASSEX
    mov wcx.style,         CS_HREDRAW or CS_VREDRAW or CS_BYTEALIGNWINDOW
    mov wcx.lpfnWndProc,   OFFSET WindowProc
    mov wcx.cbClsExtra,    NULL
    mov wcx.cbWndExtra,    NULL
    push hInst
    pop wcx.hInstance
    mov wcx.hbrBackground, COLOR_BTNFACE + 1
    mov wcx.lpszMenuName,  NULL
    mov wcx.lpszClassName, OFFSET className
    invoke LoadIcon, NULL, IDI_APPLICATION
    mov wcx.hIcon, eax
    invoke LoadCursor, NULL, IDC_ARROW
    mov wcx.hCursor, eax
    mov wcx.hIconSm, 0
    invoke RegisterClassEx, addr wcx
    WW = 260
    WH = 280
    invoke GetSystemMetrics, SM_CXSCREEN
    shr eax, 1
    sub eax, WW / 2
    mov posx, eax
    invoke GetSystemMetrics, SM_CYSCREEN
    shr eax, 1
    sub eax, WH / 2
    mov posy, eax
    invoke CreateWindowEx,  0,
                            ADDR className,
                            chr$("Test"),
                            WS_VISIBLE or WS_OVERLAPPED or WS_SYSMENU,
                            posx, posy, WW, WH,
                            NULL, NULL,
                            NULL, NULL
    mov   hWnd, eax
    invoke ShowWindow, hWnd, SW_SHOWDEFAULT
    invoke UpdateWindow, hWnd
  msgLoop:
    invoke GetMessage, addr msg, NULL, 0, 0
    .IF eax != 0
        invoke IsDialogMessage, hWnd, addr msg
        .IF eax == 0
            invoke TranslateMessage, addr msg
            invoke DispatchMessage, addr msg
        .ENDIF
        jmp   msgLoop
    .ENDIF
    exit msg.wParam
;==============================================================================
end start


Note that both versions have a problem with the Escape key. Since the message loop calls IsDialogMessage, pressing the Escape key causes a BN_CLICKED notification with the control ID value of IDCANCEL to be sent to the window procedure, and the third button gets deleted. I did not try to determine how whatever window handle was sent with the IDCANCEL BN_CLICKED notification could cause this, because I can't see how this could have any bearing on the behavior I am trying to test.

Title: Re: Destruction
Post by: oex on March 02, 2012, 11:33:05 AM
Sorry to not post all the code in a working example before....

This application doesnt quit properly (only closes the window, cant think what I have missed) however it shows the problem without too much added bs....
Title: Re: Destruction
Post by: qWord on March 02, 2012, 12:06:50 PM
there are several issues:
- DefWindowProc is called at wrong place
- there is no background brush specified -> that is why InvalidateRect doesn't work
- PostQuitMessage is commonly used while handling WM_CLOSE
- WM-DESTROY is used to free resources
( - do not send WM_CLOSE explicit)
( - ExitProcess missing)
Title: Re: Destruction
Post by: oex on March 02, 2012, 12:11:08 PM
 :bdg yes a rush job also doesn't help.... I will check your post now q, cheers
Title: Re: Destruction
Post by: MichaelW on March 02, 2012, 12:17:45 PM
Just setting the hbrBackground member of WNDCLASSEX will solve the primary problem. You can tell that there is problem with the background update by the transparent background and by dragging the window partially outside the desktop and dragging it back.
Title: Re: Destruction
Post by: oex on March 02, 2012, 01:06:15 PM
Yep perfect, thanks guys....!

This windows stuff is all new to me