Windows 

www.madshi.net

Not really a "kernel" handle, but not less important are "Window" handles. So madKernel encapsulates those, too. A single window is wrapped up in the "IWindow" interface, while a list of windows is managed by "IWindows". See also the IWindow Reference and the IWindows Reference.

type
  IWindow  = interface (IBasic)           ['{F70A8420-C1D6-11D3-A530-00005A180D69}'];
  IWindows = interface (ICustomBasicList) ['{58831900-C282-11D3-A530-00005A180D69}'];

There are tons of ways to get an IWindow or an IWindows instance. You can use IProcess.Windows_, IProcess.TaskbarWindows, IThread.Windows_, IThread.TaskbarWindows, ITrayIcon.Window or one of the following functions. There are functions for getting the common explorer shell windows like the "Taskbar" and "DesktopWindow". Then you can get the currently "FocusedWindow" and "ForegroundWindow". Also you can convert a win32 window handle dword value into an IWindow instance or search for a specific window. Finally you can call the function "Windows_" to enumerate all windows of your process or all windows system wide. And with "TaskbarWindows" you can enumerate all windows which are visible in the taskbar. You see, lots of possibilities...

function Taskbar          : IWindow;
function StartButton      : IWindow;
function TaskButtonWindow : IWindow;
function TrayWindow       : IWindow;
function ClockWindow      : IWindow;

function DesktopWindow    : IWindow;
function DesktopListView  : IWindow;

function FocusedWindow    : IWindow;
function ForegroundWindow : IWindow;

function Window (handle    : cardinal    ) : IWindow; overload;
function Window (className : string;
                 caption   : string = '*') : IWindow; overload;
function Window (pos       : TPoint      ) : IWindow; overload;

function Windows_       (systemWide: boolean = false) : IWindows;
function TaskbarWindows (systemWide: boolean = true ) : IWindows;

// Examples:
ClockWindow.Close);
MessageBox(0, pchar('we have ' + IntToStr(TaskbarWindows.ItemCount) + ' taskbar windows'), 'info', 0);
if Taskbar.IsValid then ...

Check whether this window still exists:

function IWindow.IsStillValid : boolean;

The property "Handle" returns the window handle of this window. Caution, this is no kernel handle, it's a window handle.

property IWindow.Handle : cardinal;

With the following property you can access the text of the window. This is e.g. the caption of a main window or the content of an edit box.

property IWindow.Text : string;

// Example:
StartButton.Text := 'Oops';  // this example works only in XP

With the following methods/property you can show/hide this window or ask whether it is currently visible:

property  IWindow.Visible : boolean;
procedure IWindow.Hide;
procedure IWindow.Show (activate : boolean = true);

// Example:
if StartButton.Visible then
  MessageBox(0, 'start button is visible', 'info', 0);

Is this window enabled?

property IWindow.Enabled : boolean;

// Example:
StartButton.Enabled := false;

Does this window show up in the taskbar?

property IWindow.InTaskbar : boolean;

Which window is the owner/parent of this window? If there is no owner/parent the result is an invalid IWindow instance.

property IWindow.OwnerWindow  : IWindow;
property IWindow.ParentWindow : IWindow;

Which thread/process is the owner of this window? If there is no owner thread/process result is an invalid IThread/IProcess instance.

property IWindow.OwnerThread  : IThread;
property IWindow.OwnerProcess : IProcess;

// Example:
Assert(PosText('explorer.exe', Taskbar.OwnerProcess.ExeFile) > 0);

With the following methods you can access the size and position of this window:

property IWindow.Rect       : TRect;
property IWindow.ClientRect : TRect;

function IWindow.SetRectEx       (rect     : TRect;
                                  copyBits : boolean = true;
                                  redraw   : boolean = true;
                                  activate : boolean = true) : boolean;
function IWindow.SetClientRectEx (rect     : TRect;
                                  copyBits : boolean = true;
                                  redraw   : boolean = true;
                                  activate : boolean = true) : boolean;

In order to minimize, maximize or restore this window, you can use:

property IWindow.Minimized : boolean;
property IWindow.Maximized : boolean;
property IWindow.Restored  : boolean;

procedure IWindow.Minimize (activate: boolean = false);
procedure IWindow.Maximize (activate: boolean = true );
procedure IWindow.Restore  (activate: boolean = true );

Accesses the minimal/maximal/normal window size:

property IWindow.MinimizePos : TPoint;
property IWindow.MaximizePos : TPoint;
property IWindow.NormalPos   : TRect;

If you want to bring this window to the top of the application wide Z order you can call "IWindow.BringToTop":

function IWindow.BringToTop (copyBits : boolean = true;
                             redraw   : boolean = true;
                             activate : boolean = true) : boolean;

You can bring this window together with the whole application to the foreground (system wide) and give it input focus by calling the method "BringToForeground". In winME, win2k and newer OSs this often doesn't work when calling the pure win32 API "SetForegroundWindow", instead the window often only blinks. When you set the parameter "noBlink" to "true", the blinking effect is gone and the window comes really always to front.

function IWindow.BringToForeground (noBlink: boolean = true) : boolean;

In order to access the stay on top state of this window you can use:

property IWindow.StayOnTop : boolean;

function IWindow.SetStayOnTopEx (onTop    : boolean;
                                 copyBits : boolean = true;
                                 redraw   : boolean = true;
                                 activate : boolean = true) : boolean;

With the following methods you can ask and change several parameters of the window, including the style and the extended style. See the documentation of the win32 API "GetWindowLong" for more information. But while the win32 API "SetWindowLong" only works on windows of your own process, the following properties also work on windows of other processes.

property IWindow.Param   [index: integer] : integer;
property IWindow.Style   : integer;
property IWindow.ExStyle : integer;

Show/hide all owned popup windows of this window (see API "ShowOwnedPopups"):

function IWindow.ShowOwnedPopups (show: boolean = true) : boolean;

If you want to find a specific child window, look here:

type
  TSkipWindows  = (swInvisible, swDisabled, swTransparent);
  TSSkipWindows = set of TSkipWindows;

function IWindow.ChildWindow (pos       : TPoint;
                              skip      : TSSkipWindows = [] ) : IWindow; overload;
function IWindow.ChildWindow (className : string;
                              caption   : string        = '*') : IWindow; overload;

property IWindow.TopChildWindow : IWindow;

You can ask, set, change or delete a window property by using:

property IWindow.Prop       [name: string] : cardinal;
function IWindow.DeleteProp (name: string) : boolean;

Is this a native Unicode window?

function IWindow.IsUnicode : boolean;

The result value of the following method is only valid, if the window was created by a Delphi TWinControl object:

function IWindow.SelfAsTWinControl : TObject;

You can set the window procedure of this window by using the property "WndProc". But be cautious: If you set the window procedure of a window that belongs to another process the code of this new window procedure MUST be accessible inside of the context of the other process!

type
  TWndProc = function (window : cardinal;
                       msg    : cardinal;
                       wParam : integer;
                       lParam : integer ) : integer; stdcall;

property IWindow.WndProc : TWndProc;

Post/send a message to this window:

type
  TSendAsyncProc = procedure (window       : cardinal;
                              msg          : cardinal;
                              callbackInfo : cardinal;
                              result       : integer );

function IWindow.PostMessage (msg                  : cardinal;
                              wParam               : integer  = 0;
                              lParam               : integer  = 0       ) : boolean;
function IWindow.SendMessage (msg                  : cardinal;
                              wParam               : integer  = 0;
                              lParam               : integer  = 0;
                              timeOut              : cardinal = INFINITE;
                              abortIfHung          : boolean  = false;
                              blockThread          : boolean  = false;
                              noTimeOutWhenNotHung : boolean  = false   ) : integer; overload;
function IWindow.SendMessage (msg                  : cardinal;
                              wParam               : integer;
                              lParam               : integer;
                              callbackProc         : TSendAsyncProc;
                              callbackInfo         : cardinal = 0       ) : boolean; overload;

You can "Close" or "Destroy" this window. Destroying only works if this window belongs to the current thread. "Close" works on all windows, it simply posts a WM_CLOSE message to the window.

function IWindow.Close   : boolean;
function IWindow.Destroy : boolean;

The following properties give you some infos about the window class to which this window belongs:

property IWindow.ClassName       : string;
property IWindow.BackgroundBrush : cardinal;
property IWindow.Cursor          : cardinal;
property IWindow.Icon            : cardinal;
property IWindow.SmallIcon       : cardinal;

The IWindows interface gives you easy access to it's items. With the method "RefreshItems" you can refresh the window list, if you like (that is look for new, deleted and changed windows).

property IWindows.Items [index: integer] : IWindow;

function IWindows.RefreshItems : boolean;

The following IWindows methods are more or less identical to the IWindow methods with the same name. It's just that if you call the IWindows methods, they are called for all windows in the list.

procedure IWindows.Hide;
procedure IWindows.Show (activate: boolean = true);

procedure IWindows.SetEnabled (value: boolean);

procedure IWindows.Minimize (activate: boolean = false);
procedure IWindows.Maximize (activate: boolean = true );
procedure IWindows.Restore  (activate: boolean = true );

function IWindows.SetStayOnTop (onTop    : boolean;
                                copyBits : boolean = true;
                                redraw   : boolean = true;
                                activate : boolean = true) : boolean;

function IWindows.ShowOwnedPopups (show: boolean = true) : boolean;

function IWindows.PostMessage (msg    : cardinal;
                               wParam : integer = 0;
                               lParam : integer = 0) : boolean;

function IWindows.Close   : boolean;
function IWindows.Destroy : boolean;

Does this IWindows instance only enumerate windows that belong to a specific thread/process or that are visible in the taskbar?

property IWindows.OwnerThread  : IThread;
property IWindows.OwnerProcess : IProcess;
property IWindows.InTaskbar    : boolean;