Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!tut.cis.ohio-state.edu!unmvax!ncar!boulder!pikes!udenva!isis!nbires!matt From: matt@nbires.nbi.com (Matthew Meighan) Newsgroups: comp.windows.ms Subject: Re: Why does SetFocus fail? Summary: Summary of solutions Keywords: SetFocus Child WM_ACTIVATEAPP Message-ID: <228@nbires.nbi.com> Date: 22 Feb 89 00:33:02 GMT References: <224@nbires.nbi.com> Distribution: na Organization: NBI Inc., Boulder, CO. Lines: 62 A while back, in <224@nbires.nbi.com>, I posted: >I have an app that has a parent window with three child windows. Each >of the children's message handling procedures detects when the tab key >is pressed and sets the focus to the next of the three. > >This works fine except when the app loses the focus and then regains >it (e.g., if I alt-tab to the dos executive and back). In response to >the WM_ACTIVATEAPP message, I call SetFocus with one of the child's >handles. However, the child does not get the focus; WM_KEYDOWN messages >go to the parent's window, not the child window, despite the SetFocus call. >I tried calling SetFocus twice, and looking at its return; it is zero >BOTH times -- which would imply that the first SetFocus did not set >the focus at all. Here is a summary of what I've learned since then: The problem seems to be that _after_ the WM_ACTIVATEAPP message, the main window gets a WM_ACTIVATE message. DefWindowProc calls SetFocus when it gets this message. So if you set the focus in response to WM_ACTIVATEAPP, windows sets it back on the WM_ACTIVATE message. The simplest solution I've found is to handle the WM_ACTIVATE message in the parent window. I check wParam to see if the window is being activated, and HIWORD(lParam) to make sure it's not an icon. If so, I call SetFocus; otherwise, I call DefWindowProc: case WM_ACTIVATE: if (wParam && (! HIWORD(lParam) ) ) SetFocus (whichever) ; else return DefWindowProc (win, message, wParam, lParam) ; break ; This seems to work fine for me. Another suggestion was: >From: cig@genrad.UUCP (Charles I. Ganimian Jr.) > >What I have found to work is to process WM_ACTIVATEAPP in the parent and >check if wParam != 0 (then you are are receiving the focus) and PostMessage >WM_ACTIVATE to child window, which processes WM_ACTIVATE and sets focus to >a child window control (button) or its self in your case. This also worked for me, but I found I also had to PostMessage when my app was returning from being an icon (on the WM_COMMAND message); I also got a WM_ACTIVATEAPP message then but it came while the app was still an icon and that was too early for the child to handle things properly. Finally, I had to do an explicit SetFocus to the child after each DialogBox() call. With the first method (setting focus on WM_ACTIVATE), all of these cases were handled. -- Matt Meighan matt@nbires.nbi.com (nbires\!matt) -- Matt Meighan matt@nbires.nbi.com (nbires\!matt)