Dennis, I have finally made the conversion - well most of it.

We ended up changing TApplication & TCustomForm in the Forms unit to make it
simple for us.
Code as follows. For the form in the project that acts as the main form. Add
the interface marker and a OnClose to caFree the form.

{ ISDIMainForm }
  //This is a marker interface to indicate for a SDI application if this
form can behave as a TApplication.MainForm

  ISDIMainForm = interface
    ['{C1C6B827-89E1-4508-8E17-FF95473E23F7}']
  end;

TApplication
...
public
...
    property SDIApplication: Boolean read FSDIApplication write
SetSDIApplication;  //We set this in the project file after
Application.Initialize has been called.
...
end;

procedure TApplication.SetSDIApplication(const Value: Boolean);
//Declare a var to retrieve current window information
var
  ExtendedStyle : Integer;
begin
  if (FSDIApplication <> Value) then begin;
    FSDIApplication := Value;
    //Get the Extended Styles of the Application, by passing its
    //handle to GetWindowLong
    ExtendedStyle := GetWindowLong(Application.Handle, GWL_EXSTYLE);
    if Value then begin

      //Now, set the Extended Style by doing a bit masking operation.
      //OR in the WS_EX_TOOLWINDOW bit, and AND out the WS_EXAPPWINDOW bit
      //This effectively converts the application from an App Windows to a
      //Tool Window.
      SetWindowLong( Handle, GWL_EXSTYLE, ExtendedStyle OR WS_EX_TOOLWINDOW
AND NOT WS_EX_APPWINDOW);
    end else begin
      SetWindowLong( Handle, GWL_EXSTYLE, ExtendedStyle AND NOT
WS_EX_TOOLWINDOW OR WS_EX_APPWINDOW);
    end;
  end;
end;

procedure TApplication.SwitchSDIMainForms;
var
  I: Integer;
  Form: TForm;
  SDIMainForm: ISDIMainForm;
begin
  //This is called if the current mainform is about to be destroyed ...
  //We need to find another mainform instead.
  for I := 0 to Screen.FormCount -1 do begin
    Form := Screen.Forms[ I ];
    if (Form <> MainForm)
    and Form.Visible
    and Supports( Form, ISDIMainForm, SDIMainForm )
    and not (fsModal in Form.FormState) then begin
      FMainForm := Form;
      Exit;
    end;
  end;
end;

procedure TCustomForm.Close;
var
  CloseAction: TCloseAction;
begin
  if fsModal in FFormState then
    ModalResult := mrCancel
  else
    if CloseQuery then
    begin
      if FormStyle = fsMDIChild then
        if biMinimize in BorderIcons then
          CloseAction := caMinimize else
          CloseAction := caNone
      else
        CloseAction := caHide;
      DoClose(CloseAction);
      if CloseAction <> caNone then

//!!!!!!!Added for SDI Apps ...
        if   Application.SDIApplication
        and (Application.MainForm = Self) then
Application.SwitchSDIMainForms;


        if Application.MainForm = Self then Application.Terminate
        else if CloseAction = caHide then Hide
        else if CloseAction = caMinimize then WindowState := wsMinimized
        else Release;
    end;
end;

procedure TCustomForm.WMSysCommand(var Message: TWMSysCommand);
begin
  with Message do
  begin
    if Application.SDIApplication then begin
      if (CmdType and $FFF0 <> SC_MOVE) or (csDesigning in ComponentState)
or
        (Align = alNone) or (WindowState = wsMinimized) then
        inherited;
    end else begin
      if (CmdType and $FFF0 = SC_MINIMIZE) and (Application.MainForm = Self)
then
        Application.WndProc(TMessage(Message))
      else if (CmdType and $FFF0 <> SC_MOVE) or (csDesigning in
ComponentState) or
        (Align = alNone) or (WindowState = wsMinimized) then
        inherited;
    end;
    if ((CmdType and $FFF0 = SC_MINIMIZE) or (CmdType and $FFF0 =
SC_RESTORE)) and
      not (csDesigning in ComponentState) and (Align <> alNone) then
      RequestAlign;
  end;
end;

Dennis,

Have fun!

Myles.

-----Original Message-----
From: Dennis Chuah [mailto:[EMAIL PROTECTED]
Sent: Friday, 12 December 2003 10:39
To: NZ Borland Developers Group - Delphi List
Subject: Re: [DUG] Change from MDI to SDI type windows ...



Myles,

I was planning to do this to one of my projects.  Here are some of my
thoughts:

1.  Keep single instance of application - which means a hidden / off screen
main form?
2.  Need to simulate the Windows menu - no tile, cascade, etc.
3.  Set WS_* style to make child window visible to ALT+TAB, and unset WS_*
style to remove main form from ALT+TAB.
4.  Close app when last child closes.
5.  If only one child need, display [x] button on right of menu - when
clicked will close the document, but leave the child window still open with
blank document.

Please let me know how you get on.

Dennis.

----- Original Message -----
From: "Myles Penlington" <[EMAIL PROTECTED]>
To: "'NZ Borland Developers Group - Delphi List'" <[EMAIL PROTECTED]>
Sent: Friday, December 12, 2003 9:09 AM
Subject: [DUG] Change from MDI to SDI type windows ...


> Hi,
>
> We want to change a application from MDI style to SDI style windows ala MS
> Word 2000 - ie have each window as a main form that appears on the task
bar
> so you can switch between the windows using alt-tab etc.
>
> So, has anybody done this and is willing to share the pitfalls, issues and
> code snippets?
>
> Or is there a component out there that does the hard work for me?
>
> Else I will have to jump in and find the issues later ...
>
> Thanks
> Myles.
>
>
>


----------------------------------------------------------------------------
----


> _______________________________________________
> Delphi mailing list
> [EMAIL PROTECTED]
> http://ns3.123.co.nz/mailman/listinfo/delphi
>
_______________________________________________
Delphi mailing list
[EMAIL PROTECTED]
http://ns3.123.co.nz/mailman/listinfo/delphi
_______________________________________________
Delphi mailing list
[EMAIL PROTECTED]
http://ns3.123.co.nz/mailman/listinfo/delphi

Reply via email to