views:

466

answers:

2

This code below is not closing a tab in Internet Explorer 8. If I post wm_close command to Wnd it closes Internet Explorer but I want to close the current tab not the entire 'ieframe'. Is FindWindowEX(Wnd , 0, 'Frame Tab', nil) supposed to retun a handle to ie frame? If yes why is it not closing the current tab in Internet Explorer?

var
   Wnd, WndChild : hwnd;
begin
   Wnd := FindWindow('IEFrame', nil);
   WndChild := FindWindowEX(Wnd, 0, 'Frame Tab', nil);
   postmessage(WndChild, wm_close, 0, 0);
end;
A: 
var
  hie,
  hftab,
  htab : DWORD;
begin
  hie := FindWindow('IEFrame', nil);
  hftab := FindWindowEx(hie, 0, 'Frame Tab', nil);
  htab := FindWindowEX(hftab, 0, 'TabWindowClass', nil);
  PostMessage(htab, WM_CLOSE, 0, 0);
  CloseHandle(hie);
end;`

IE8 Window structure is shown in screenshot below

alt text

Im0rtality
thanks for the replyi have few confusions:1.why did you use dword instead of hwnd.2. is closehandle(htab) equvalent to htab := nil3. is closehandle necessary, wont the handles be automaticaly closed once my program exits?
Omair Iqbal
Very bad code example. 1) You should check the result of FindWindow[Ex]. 2) You do NOT close handles returned by the FindWindow[Ex].
gabr
Actually, this was to show an idea of how that should be done, leaving some space for thinking (error catching). Where you found about not closing handles (http://msdn.microsoft.com/en-us/library/ms633500(VS.85).aspx says nothing of it)? And yes, closing handle of window received WM_CLOSE indeed generates exception (that's why I didn't closed it).
Im0rtality
Help for FindWindow[Ex] says nothing about necessity to close handles. What you get from the FindWindow[Ex] is a globally visible handle; the call does not 'open' something for you so there's no need to close anything.
gabr
+1 for the screencap from Spy++, -1 for not removing `CloseHandle()` from your code even after you were (correctly) told it was wrong.
egrunin
+5  A: 

You missed 1 layer, the tab itself, other than that, it was fine..

var
  Wnd, WndChild: THandle;
begin
  Wnd := FindWindow('IEFrame', nil); // Top most IE
  if Wnd > 0 then
  begin
    WndChild := FindWindowEx(Wnd, 0, 'Frame Tab', nil); // Tabs holder
    if WndChild > 0 then
    begin
      WndChild := FindWindowEX(WndChild, 0, 'TabWindowClass', nil); // top most tab
      if WndChild > 0 then
        if PostMessage(WndChild, WM_CLOSE, 0, 0) then
          ShowMessage('Close request succeeded...')
        else
          ShowMessage('Failed!');
    end
    else
      // not tabbed, close IE
        if PostMessage(Wnd, WM_CLOSE, 0, 0) then
          ShowMessage('Close request succeeded...')
        else
          ShowMessage('Failed!');
  end
  else
    ShowMessage('No IE');
end;
François
+1 because of the correct approach to Win32 API checking
gabr