Announcement

Collapse
No announcement yet.

Stamping out a toolwindow

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Stamping out a toolwindow

    The visual parallel to the problem I am having with a child window toolbar is this: picture a guy trying to blow out a trick candle and the thing just doesn't want to go out!

    My child toolwindow will close out fine if I use the "X" to close it... but when I close the parent window (which SHOULD close all children-- including this toolwindow) my application looks like it closes alright but it stays in the tasklist and is really still open.

    I've tried doing a destroywindow, a postmessage %wm_syscommand,%sc_close, a sendmessage %wm_syscommand,%sc_close, and didn't let the app close until iswindow(handle) was false.
    Nothing has worked.
    The toolwindow closes fine using the "View" menu item in the parent window too.

    Any ideas? (The code for my app is huge-- compiles to well over a megabyte without any resources-- so I couldn't possibly include it all)
    Jim Seekamp

  • #2
    First, try ending your application by posting WM_CLOSE to yourself. You should not be sending WM_SYSCOMMAND notification messages , those are sent by Windows.

    If that doesn't work, when you want to end your program, first simulate hitting the View Menu option to close the toolwindow (post/send WM_COMMAND) (which you said works) before you (DestroyWindow ()+ PostQuitMessage() ???)

    >and didn't let the app close until iswindow(handle) was false.

    Huh?

    Show message loop code.

    MCM
    Michael Mattias
    Tal Systems (retired)
    Port Washington WI USA
    [email protected]
    http://www.talsystems.com

    Comment


    • #3
      Originally posted by Jim Seekamp View Post
      I've tried doing a destroywindow, a postmessage %wm_syscommand,%sc_close, a sendmessage %wm_syscommand,%sc_close, and didn't let the app close until iswindow(handle) was false.
      Are you attempting to close the wrong window?

      Comment


      • #4
        WM_CLOSE doesn't work either.

        Here's the iswindow check I was talking about:

        Code:
               case %wm_syscommand
                 if lowrd(wparam&)<>%sc_close then exit select
        
                 if showitemlist&<>0 then
                   destroywindow hostoolbar&
        
                   '''''this is the check I was talking about:
                   'do until iswindow(hostoolbar&)=%false
                   '  ''wait for window to be destroyed
                   'loop
        
                   showitemlist&=0
        
                    ''tried invoking the "View" menu here
                 end if
        I tried invoking the "View" menu by posting a message to simulate it but that doesn't work either.
        Jim Seekamp

        Comment


        • #5
          A child window will be closed by its parent. As long as the toolwindow was created correctly and it truly is a "owned" window (doesn't use WS_CHILD, but is owned by a parent window), then it will close properly.

          Likely the problem is associated with something else, which prevents it from closing properly and not whether it is getting the close message or not.

          Track the WM_DESTROY message in the tool window (use BEEP command) to see it if is being generated. If it is then track WM_DESTROY in the parent window to see if it is being generated (use BEEP).

          If both windows are getting WM_DESTROY, then the problem is not associated with how you close them down. The problem is somewhere else (maybe the message loop).

          It is important to remember that what keeps a program in memory, even if its windows are properly closed is the message loop in winmain. The message loop must exit properly, so winmain terminates and the app terminates.
          Chris Boss
          Computer Workshop
          Developer of "EZGUI"
          http://cwsof.com
          http://twitter.com/EZGUIProGuy

          Comment


          • #6
            >if lowrd(wparam&)<>%sc_close then exit select

            Please check the documentation on testing wparam on WM_SYSCOMMAND.

            (Hint: above is not correct)

            MCM
            Michael Mattias
            Tal Systems (retired)
            Port Washington WI USA
            [email protected]
            http://www.talsystems.com

            Comment


            • #7
              Code:
              if showitemlist&<>0 then
                         destroywindow hostoolbar&
              
                         '''''this is the check I was talking about:
                         'do until iswindow(hostoolbar&)=%false
                         '  ''wait for window to be destroyed
                         'loop
              That this test failed is no surprise... your program can't receive any notifications while it's in this loop because it thinks it's still processing the WM_SYSYCOMMAND notification. Of course you may have never even got to this point, since your test for SC_CLOSE is incorrect.

              But even at that, if the toolwindow is a child of this window, Windows will destroy it when the main window is destroyed. Let Windows work for you instead of against you.
              Michael Mattias
              Tal Systems (retired)
              Port Washington WI USA
              [email protected]
              http://www.talsystems.com

              Comment


              • #8
                "...since your test for sc_close is incorrect..."

                ?????
                I have over 100 apps that test for sc_close exactly this same way, and it ALWAYS gets through on close. (If it didn't, multiple saves and assignments of various types would not happen that ARE happening)

                Since this has never, ever, ever, ever failed in all my years of programming, I'm interested in knowing what you think IS the proper way to test for sc_close???
                Jim Seekamp

                Comment


                • #9
                  In WM_SYSCOMMAND messages, the four low-order bits of the wParam parameter are used internally by the system. To obtain the correct result when testing the value of wParam, an application must combine the value 0xFFF0 with the wParam value by using the bitwise AND operator.
                  -- SDK under WM_SYSCOMMAND, Remarks.
                  Michael Mattias
                  Tal Systems (retired)
                  Port Washington WI USA
                  [email protected]
                  http://www.talsystems.com

                  Comment


                  • #10
                    Thanks for that interesting bit of info, Michael.
                    I find it fascinating that, for whatever reason, the lowrd of wparam is always exactly %sc_close when the %sc_close is sent.
                    Jim Seekamp

                    Comment


                    • #11
                      Thanks Chris,
                      Both the wm_destroy messages are getting through fine, so evidently the way I'm closing it is not what's keeping it from closing.
                      I'm looking elsewhere for the problem...
                      Jim Seekamp

                      Comment


                      • #12
                        Jim --

                        Without the FFF0 mask, it's definitely possible to close a window without getting a message that is exactly equal to SC_CLOSE. I forget the details, but Alt-F4 gives you one value, SystemMenu>Close gives you another value, double-clicking the caption bar icon gives you another, the X button gives you another, and I seem to remember there's one more way to close a window with the Windows System Menu. Also IIRC not all versions of Windows are consistent. But the FFF0 mask solves all of the issues.

                        -- Eric
                        "Not my circus, not my monkeys."

                        Comment


                        • #13
                          Thanks again, Eric.
                          Wow. Live and learn.
                          I wonder why I've never come across a problem before while using this for the last 12 years that 32 bit Windows has been out????

                          Code:
                          if (wparam& and &hfff0)<>%sc_close then exit select
                          Unfortunately, it has nothing to do with the problem I outlined in this thread...
                          I looked for other threads that are dedicated to addressing this and didn't find any...
                          Last edited by Jim Seekamp; 31 Dec 2007, 01:49 PM.
                          Jim Seekamp

                          Comment


                          • #14
                            As Eric pointed out, the low-order 4 bits can change depending on "how" you exit the screen.

                            I'll bet not a whole lot of users have so much as a clue that Alt+F4 will terminate a (properly-written) GUI application. (Or that ctrl+F6 will rotate amongst multiple MDI windows of a single application).

                            I use Alt+F4 every now and then*, but for the most part I go right for the little "X" in the upper right hand corner of the screen or use the application's exit facilty... and I will bet I'm not alone in those tendencies.

                            Your problem remains the same (If I may return to the topic) - you are trying to do too much yourself. Just let Windows destroy the child tool window when the main window gets destroyed, and don't send WM_SYSCOMMAND yourself.

                            MCM
                            * OK, so it's usually when I forget to add WS_SYSMENU style to a new screen and can't othewise exit my own program.
                            Last edited by Michael Mattias; 31 Dec 2007, 02:29 PM.
                            Michael Mattias
                            Tal Systems (retired)
                            Port Washington WI USA
                            [email protected]
                            http://www.talsystems.com

                            Comment


                            • #15
                              Both the wm_destroy messages are getting through fine, so evidently the way I'm closing it is not what's keeping it from closing.
                              I'm looking elsewhere for the problem
                              You ARE posting a quit message (using the deviously-named "PostQuitMessage" function), which then causes your message loop in WinMain to exit, right?

                              My psychic abilities must be used up for 2007 .. or maybe I have been in too close proximity to Red Kryptonite because I just can't see the relevant code ......

                              MCM
                              Michael Mattias
                              Tal Systems (retired)
                              Port Washington WI USA
                              [email protected]
                              http://www.talsystems.com

                              Comment


                              • #16
                                Yes I am, Michael. THAT would have been a problem, now, wouldn't it??

                                Code:
                                       case %wm_destroy
                                         ''first, cleaned up some object handles, etc.
                                          ''then....
                                         postquitmessage 0
                                         function=0
                                         exit function
                                     end select
                                
                                     function=defwindowproc(hwnd&,msg&,wparam&,lparam&)
                                Jim Seekamp

                                Comment


                                • #17
                                  Well, I tried doing absolutely nothing to the toolwindow, and that didn't help either... the program still sits in the task list after closing.

                                  If I CLOSE the toolwindow MANUALLY, and THEN close the following 3 windows in order, there is no problem; the program is not in the task list, and everything is a-ok.

                                  But when I close the parent window of the toolwindow, and exit the following windows in order, the program remains in the task list and is still open as a process.

                                  If I use the "View" menu to turn off the toolwindow, it turns off and I am able to exit successfully also, with the program not in the task list and not running as a process.
                                  Jim Seekamp

                                  Comment


                                  • #18
                                    in short
                                    Code:
                                    PostQuitMessage 0
                                    Happy New Year
                                    Engineer's Motto: If it aint broke take it apart and fix it

                                    "If at 1st you don't succeed... call it version 1.0"

                                    "Half of Programming is coding"....."The other 90% is DEBUGGING"

                                    "Document my code????" .... "WHYYY??? do you think they call it CODE? "

                                    Comment


                                    • #19
                                      Here's the main part of the code for the toolwindow that is giving me trouble:

                                      Code:
                                      function ostoolbar(byval hparent&) as long
                                      
                                           dim rc as rect
                                           dim wclassname as asciiz*80
                                      
                                           getclientrect hparent&,rc
                                      
                                           xl&=(((rc.nright-rc.nleft)+1)/8) _
                                              +(getsystemmetrics(%sm_cxvscroll)*2) _
                                              +(getsystemmetrics(%sm_cxborder)*2)
                                      
                                           yl&=(rc.nbottom-rc.ntop)+1
                                           xs&=rc.nleft+(rc.nright-xl&)
                                      
                                           ys&=rc.ntop+getsystemmetrics(%sm_cycaption) _
                                                      +getsystemmetrics(%sm_cymenu) _
                                                      +getsystemmetrics(%sm_cyborder)+1
                                      
                                           wclassname="ThisHereToolbar"
                                      
                                           dim wclass as wndclass
                                      
                                           wclass.style=%cs_hredraw or %cs_vredraw
                                           wclass.lpfnwndproc=codeptr(ostoolbarproc)
                                           wclass.cbclsextra=0
                                           wclass.cbwndextra=0
                                           wclass.hinstance=hinstance&
                                           wclass.hicon=loadicon(hdll&,"icon")
                                           wclass.hcursor=loadcursor(%null,byval %idc_arrow)
                                           wclass.hbrbackground=getstockobject(%gray_brush)
                                           wclass.lpszmenuname=%null
                                           wclass.lpszclassname=varptr(wclassname)
                                      
                                           registerclass wclass
                                      
                                           style&=%ws_visible or %ws_caption or %ws_sysmenu
                                           xstyle&=%ws_ex_toolwindow or %ws_ex_topmost
                                      
                                           hwnd&=createwindowex(xstyle&, _         ''extended windows style
                                                                wclassname, _      ''window class name
                                                                "Items", _         ''window caption
                                                                style&,_           ''window style
                                                                xs&, _             ''initial x position
                                                                ys&, _             ''initial y position
                                                                xl&, _             ''initial x size
                                                                yl&, _             ''initial y size
                                                                hparent&, _        ''parent window handle
                                                                %null, _           ''window menu handle
                                                                hinstance&, _      ''program instance handle
                                                                byval %null)       ''creation parameters
                                      
                                           showwindow hwnd&,%sw_show
                                           updatewindow hwnd&
                                      
                                           hostoolbar&=hwnd&
                                      
                                           dim tbmsg as tagmsg
                                      
                                           while istrue(getmessage(tbmsg,byval %null,0,0))
                                             translatemessage tbmsg
                                             dispatchmessage tbmsg
                                           wend
                                      
                                      end function
                                      
                                      function ostoolbarproc(byval hwnd&,byval msg&,byval wparam&,byval lparam&) as long
                                      
                                           hostoolbar&=hwnd&
                                      
                                           static htree&,hmicrofont&
                                           static trmnu$   ''holds treeview data
                                      
                                           dim ztext as asciiz*256
                                           dim rc as rect
                                      
                                           select case msg&
                                             case %wm_create
                                      
                                               ysize&=getsystemmetrics(%sm_cyscreen)
                                               xsize&=getsystemmetrics(%sm_cxscreen)
                                      
                                               smfontheight&=(8*ysize&)/480
                                               smfontwidth&=ceil(smfontheight&/2)
                                               hmicrofont&=fontmaker("Arial",smfontheight&,smfontwidth&,1)
                                      
                                               treestyle&=%ws_child or %ws_visible or %ws_group or %ws_tabstop _
                                                          or %ws_border or %tvs_hasbuttons or %tvs_haslines _
                                                          or %tvs_linesatroot or %tvs_disabledragdrop _
                                                          or %tvs_showselalways
                                      
                                               getclientrect hwnd&,rc
                                      
                                               xlen&=((((rc.nright-rc.nleft)+1)*640)/xsize&)
                                               yhght&=((((rc.nbottom-rc.ntop)+1)*480)/ysize&)*(.75)
                                      
                                               htree&=createcontrol("SysTreeView32","",treestyle&, _
                                                                    0,0,xlen&,yhght&, _
                                                                    hwnd&,100,hinstance&,%null)
                                      
                                               setctlfont htree&,hmicrofont&
                                      
                                               ''gosub getitemlist  ''creates treeview listing
                                      
                                               ''create buttons
                                      
                                               bstyle&=%bs_pushbutton or %bs_bitmap _
                                                       or %ws_child or %ws_visible
                                      
                                               xstt&=2
                                               ystt&=yhght&+10
                                      
                                               hbtn&=createcontrol("button","Open",bstyle&, _
                                                                   xstt&,ystt&,25,25, _
                                                                   hwnd&,201,hinstance&,%null)
                                      
                                               style&=%lr_defaultsize
                                               hbitmap&=loadbitmap(hdll&,"OPEN")
                                               sendmessage hbtn&,%bm_setimage,%image_bitmap,hbitmap&
                                      
                                               hbtn&=createcontrol("button","Magnify",bstyle&, _
                                                                   (xstt&+26),ystt&,25,25, _
                                                                   hwnd&,101,hinstance&,%null)
                                      
                                               style&=%lr_defaultsize
                                               hbitmap&=loadbitmap(hdll&,"MAGNIFY")
                                               sendmessage hbtn&,%bm_setimage,%image_bitmap,hbitmap&
                                      
                                               hbtn&=createcontrol("button","Shrink",bstyle&, _
                                                                   (xstt&+52),ystt&,25,25, _
                                                                   hwnd&,102,hinstance&,%null)
                                      
                                               style&=%lr_defaultsize
                                               hbitmap&=loadbitmap(hdll&,"SHRINK")
                                               sendmessage hbtn&,%bm_setimage,%image_bitmap,hbitmap&
                                      
                                               hbtn&=createcontrol("button","Close",bstyle&, _
                                                                   (xstt&+78),ystt&,25,25, _
                                                                   hwnd&,210,hinstance&,%null)
                                      
                                               style&=%lr_defaultsize
                                               hbitmap&=loadbitmap(hdll&,"CLOSE")
                                               sendmessage hbtn&,%bm_setimage,%image_bitmap,hbitmap&
                                      
                                               hbtn&=createcontrol("button","Colors",bstyle&, _
                                                                   xstt&,(ystt&+26),25,25, _
                                                                   hwnd&,331,hinstance&,%null)
                                      
                                               style&=%lr_defaultsize
                                               hbitmap&=loadbitmap(hdll&,"PAINT")
                                               sendmessage hbtn&,%bm_setimage,%image_bitmap,hbitmap&
                                      
                                               hbtn&=createcontrol("button","Thicker",bstyle&, _
                                                                   (xstt&+26),(ystt&+26),25,25, _
                                                                   hwnd&,103,hinstance&,%null)
                                      
                                               style&=%lr_defaultsize
                                               hbitmap&=loadbitmap(hdll&,"THICKER")
                                               sendmessage hbtn&,%bm_setimage,%image_bitmap,hbitmap&
                                      
                                               hbtn&=createcontrol("button","Thinner",bstyle&, _
                                                                   (xstt&+52),(ystt&+26),25,25, _
                                                                   hwnd&,104,hinstance&,%null)
                                      
                                               style&=%lr_defaultsize
                                               hbitmap&=loadbitmap(hdll&,"THINNER")
                                               sendmessage hbtn&,%bm_setimage,%image_bitmap,hbitmap&
                                      
                                               hbtn&=createcontrol("button","Undo",bstyle&, _
                                                                   (xstt&+78),(ystt&+26),25,25, _
                                                                   hwnd&,341,hinstance&,%null)
                                      
                                               style&=%lr_defaultsize
                                               hbitmap&=loadbitmap(hdll&,"UNDO")
                                               sendmessage hbtn&,%bm_setimage,%image_bitmap,hbitmap&
                                      
                                      
                                               hbtn&=createcontrol("button","Erase",bstyle&, _
                                                                   (xstt&+78),(ystt&+52),25,25, _
                                                                   hwnd&,342,hinstance&,%null)
                                      
                                               style&=%lr_defaultsize
                                               hbitmap&=loadbitmap(hdll&,"BLANK")
                                               sendmessage hbtn&,%bm_setimage,%image_bitmap,hbitmap&
                                      
                                             case %wm_paint
                                               dim ps as paintstruct
                                               hdc&=beginpaint(hwnd&,ps)
                                      
                                               endpaint hwnd&,ps
                                             case %wm_keydown
                                      
                                               select case lowrd(wparam&)
                                                 case %vk_f6
                                               end select
                                      
                                             case %wm_syscommand
                                               if (wparam& and &hfff0)<>%sc_close then exit select
                                               ''351 turns off the toolwindow via View menu
                                               wparam&=maklng(351,%bn_clicked)
                                               postmessage hmainwindow&,%wm_command,wparam&,lparam&
                                               destroywindow hwnd&
                                               function=1
                                               exit function
                                             case %wm_notify
                                               dim nmh as nmhdr ptr
                                               nmh=lparam&
                                      
                                               select case @nmh.idfrom
                                                 case 100  '' treeview handled here
                                      
                                                   select case @nmh.code
                                                     case %tvn_selchanged
                                      
                                                     case %nm_dblclk
                                                       hitem&=getcurseltreeview(htree&)
                                                       b$=gettexttreeview(htree&,hitem&)
                                      
                                                   end select
                                      
                                               end select
                                      
                                             case %wm_command
                                                ''various buttons handled here
                                             case %wm_destroy
                                               deleteobject hmicrofont&
                                               postquitmessage 0
                                               function=0
                                               exit function
                                           end select
                                      
                                           function=defwindowproc(hwnd&,msg&,wparam&,lparam&)
                                      end function
                                      Last edited by Jim Seekamp; 31 Dec 2007, 04:39 PM.
                                      Jim Seekamp

                                      Comment


                                      • #20
                                        If I CLOSE the toolwindow MANUALLY, and THEN close the following 3 windows in order, there is no problem; the program is not in the task list, and everything is a-ok.

                                        But when I close the parent window of the toolwindow, and exit the following windows in order, the program remains in the task list and is still open as a process.

                                        If I use the "View" menu to turn off the toolwindow, it turns off and I am able to exit successfully also, with the program not in the task list and not running as a process.
                                        Huh? I do not understand these "close manually" things...

                                        Are all these windows executing in the same thread of execution? Are they all child windows of main program window? (They won't be parent-child in different threads of execution).

                                        Show CreateWindowEx call for this tool window (with relevant assignments to any variables used in same)

                                        Are you still ruining a "IsWindow" loop within WM_SYSCOMMAND processing? (you should not be)

                                        Insufficient code shown. But if you enable TRACE you should get a better idea of the flow of your program, maybe that will tell you something.
                                        Michael Mattias
                                        Tal Systems (retired)
                                        Port Washington WI USA
                                        [email protected]
                                        http://www.talsystems.com

                                        Comment

                                        Working...
                                        X