Master-Detail (Expand/Collapse) in TwwDBGrid

object Form1: TForm1
  Left = 278
  Top = 133
  Width = 1057
  Height = 540
  Caption = 'Form1'
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'MS Sans Serif'
  Font.Style = []
  OldCreateOrder = False
  PixelsPerInch = 96
  TextHeight = 13
  object wwDBGrid1: TwwDBGrid
    Left = 48
    Top = 64
    Width = 593
    Height = 433
    ControlType.Strings = (
      'OrderID;CustomEdit;wwExpandButton1;T')
    Selected.Strings = (
      'ID'#9'20'#9'ID'
      'OrderID'#9'20'#9'OrderID'#9'F')
    IniAttributes.Delimiter = ';;'
    TitleColor = clBtnFace
    FixedCols = 0
    ShowHorzScrollBar = True
    DataSource = DataSource2
    TabOrder = 0
    TitleAlignment = taLeftJustify
    TitleFont.Charset = DEFAULT_CHARSET
    TitleFont.Color = clWindowText
    TitleFont.Height = -11
    TitleFont.Name = 'MS Sans Serif'
    TitleFont.Style = []
    TitleLines = 1
    TitleButtons = False
  end
  object wwExpandButton1: TwwExpandButton
    Left = 304
    Top = 96
    Width = 124
    Height = 16
    Grid = wwDataInspector1
    AutoHideExpand = True
    Caption = 'wwExpandButton1'
    DataField = 'OrderID'
    DataSource = DataSource2
    TabOrder = 1
  end
  object wwDataInspector1: TwwDataInspector
    Left = 256
    Top = 144
    Width = 320
    Height = 120
    ScrollBars = ssBoth
    TabOrder = 2
    DataSource = DataSource1
    Items = <
      item
        DataSource = DataSource1
        DataField = 'ID'
        Caption = 'ID'
        ReadOnly = True
        WordWrap = False
      end
      item
        DataSource = DataSource1
        DataField = 'Naam'
        Caption = 'Naam'
        WordWrap = False
      end
      item
        DataSource = DataSource1
        DataField = 'Bla'
        Caption = 'Bla'
        WordWrap = False
      end>
    CaptionWidth = 100
    Options = [ovColumnResize, ovRowResize, ovEnterToTab, ovHighlightActiveRow, ovCenterCaptionVert]
    CaptionFont.Charset = DEFAULT_CHARSET
    CaptionFont.Color = clWindowText
    CaptionFont.Height = -11
    CaptionFont.Name = 'MS Sans Serif'
    CaptionFont.Style = []
    Visible = False
  end
  object ADOConnection1: TADOConnection
    Connected = True
    ConnectionString = 
      'Provider=SQLOLEDB.1;Persist Security Info=False;User ID=sa;Initi' +
      'al Catalog=Test;Data Source=LOMPERTJE;Use Procedure for Prepare=' +
      '1;Auto Translate=True;Packet Size=4096;Workstation ID=LOMPERTJE'
    LoginPrompt = False
    Provider = 'SQLOLEDB.1'
    Left = 144
    Top = 336
  end
  object ADOQuery1: TADOQuery
    Active = True
    Connection = ADOConnection1
    CursorType = ctStatic
    Parameters = <>
    SQL.Strings = (
      'select * from Orders,dossiers'
      'where orders.id = dossiers.orderid')
    Left = 272
    Top = 384
    object ADOQuery1ID: TAutoIncField
      FieldName = 'ID'
      ReadOnly = True
    end
    object ADOQuery1Naam: TStringField
      FieldName = 'Naam'
      FixedChar = True
      Size = 10
    end
    object ADOQuery1Bla: TStringField
      FieldName = 'Bla'
      FixedChar = True
      Size = 10
    end
  end
  object DataSource1: TDataSource
    DataSet = ADOQuery1
    Left = 272
    Top = 432
  end
  object DataSource2: TDataSource
    DataSet = ADOQuery2
    Left = 368
    Top = 432
  end
  object ADOQuery2: TADOQuery
    Active = True
    Connection = ADOConnection1
    CursorType = ctStatic
    DataSource = DataSource1
    Parameters = <>
    SQL.Strings = (
      'select * from Dossiers'
      'where orderid = id')
    Left = 368
    Top = 384
  end
end

Mimize to System Tray

If you want to avoid your exe displayed in the Taskbar and want to display the same into the System Tray then here is the code you are looking for….

First you need to creat the NotifyIcon like below

procedure TfrmWSCMIMICSNotify.CreateTrayIcon;

begin

IconData.cbSize           := sizeof(IconData); // Should be Declared as IconData: TNotifyIconData;

IconData.Wnd              := Handle;  // Handle to our Form

IconData.uID              := 100;

IconData.uFlags           := NIF_MESSAGE + NIF_ICON + NIF_TIP;

IconData.uCallbackMessage := WM_USER + 1;  // Our Callback ID

IconData.hIcon            := Application.Icon.Handle;  // Use our application Icon

StrPCopy(IconData.szTip, Application.Title);

end;

Then use this procedure

procedure TfrmWSCMIMICSNotify.MinimizeToTray;
begin
Shell_NotifyIcon(NIM_ADD, @IconData);  // Add Tray Icon here
Self.Hide;  // Hide our Form…
ShowWindow(Application.Handle, SW_HIDE);  // …and hide application from TaskBar.
end;

procedure TfrmWSCMIMICSNotify.MinimizeToTray;

begin

Shell_NotifyIcon(NIM_ADD, @IconData);  // Add Tray Icon here

Self.Hide;  // Hide our Form…

ShowWindow(Application.Handle, SW_HIDE);  // …and hide application from TaskBar.

end;

Adding Checkboxes To TStringGrid

The best way is to add a check box in a grid is using the “Objects” property of TStringGrid, Instead you can also find the code to draw checkbox inside the grid in most of the websites, but i feel this one is the best way than that, Let we see how to implement this.

To implement this here we we have two procedures which helps you to add a checkbox to the system. One of them help as to Add a checkbox to the TStringGrid and another will help us to align a checkbox in the grid. They are…..

 

SetCheckBoxAlignment

procedure TForm1.SetCheckBoxAlignment(iColNumber, iRowNumber:integer; bChecked :Boolean);

var

  NewCheckBox :TCheckBox;

  Rect        :TRect;

  TempInt     :Integer;

begin

  NewCheckBox := (StringGrid1.Objects[iColNumber, iRowNumber] as TCheckBox);

  if NewCheckBox <> nil then

  begin

    Rect := StringGrid1.CellRect(iColNumber,iRowNumber);

    TempInt := TRUNC((Rect.Right – Rect.Left)/2);

    NewCheckBox.Left  := StringGrid1.Left + Rect.Left + TempInt;

    NewCheckBox.Top   := StringGrid1.Top + Rect.Top+2;

    NewCheckBox.Width := TempInt;

    NewCheckBox.Height := Rect.Bottom – Rect.Top;

    NewCheckBox.Visible := True;

    if bChecked then

    begin

      NewCheckBox.Checked := True;

    end else

    begin

      NewCheckBox.Checked := False;

      NewCheckBox.Color := clBlue;

    end;

  end;

end;


AddCheckBox

procedure TForm1.AddCheckBox(iColNumber: integer; iRowNumber: Integer);

var

  NewCheckBox :TCheckBox;

begin

  NewCheckBox := TCheckBox.Create(StringGrid1);

  NewCheckBox.Visible := False;

  NewCheckBox.Color :=  clWhite;

  NewCheckBox.OnClick := CheckBox1.OnClick; //Place one check box on you form..

  NewCheckBox.Parent := Panel1; // Place string grid on one panel

  StringGrid1.Objects[iColNumber, iRowNumber] := NewCheckBox;

  SetCheckBoxAlignment(iColNumber, iRowNumber, True); // Calling align function

end;

 

You can change modify the above to make it work for your project, Thanks.

Delphi – Single application instance

Limiting an application to start just once per machine is usually required when an external resource such as a Comport is accessed. This feature is achieved by allocation of a global variable, such as a mutex.

FINDWINDOW METHOD:

The easiest way to look for an already running instance of an application is to use the FindWindow API function. The FindWindow function retrieves the handle of the window provided with the class name and window caption. In Delphi, the name of the window (form) class is the name of the form’s class, for example ‘TForm1’. Here’s the code:

 

program Project1;

uses
  Forms, Windows,
  Unit1 in 'Unit1.pas' {Form1};

{$R *.res}
var
  PreviousHandle : THandle;
begin
  PreviousHandle := FindWindow('TForm1','Form1');
  if PreviousHandle = 0 then
  begin
    Application.Initialize;
    Application.CreateForm(TForm1, Form1);
    Application.Run;
  end
  else
    SetForegroundWindow(PreviousHandle);
end.

 

In our sample application we have only one form: Form1. This form is the main form of the project. To find a copy of the application already running, we can call the FindWindow API function that retrieves the handle of an existing window (the main form of the application). If the function fails (window with a specified class name and caption canot be found) the function returns 0. If the function returns the non-zero handle value, meaning that the system has found a window with specified parameters, we use the SetForegroundWindow API call. This function, provided with the window handle, activates the window and brings it to the foreground – making it the active window. Since Form1 is the main window of the application – the (already running) application becomes active. However, if the window was minimized we’ll first need to restore it to its previous state and then bring it to “top”.

The code above might look ok, but is not what we want.
First, such a code would prevent you from running your application from the IDE (at design time) – since at design time the window with the specified class name and the caption already exists, it’s the design time window of your main form.
Second, this code is not so safe, since there may be many Delphi applications on the system running, that have a form whose class name is “TForm1” – how can you be sure that this particular form (window) found by the FindWindow function is in fact a form belonging to your application? You cannot.

To overcome this problem, we’ll turn to threading. In Windows, one common way of object synhronization is creating a mutex object (mutually exclusive). In general, mutexes are used to synchronize two (or more) different applications – in our case we’ll create a mutex to synchronize instances of the same application. 

 

Mutex – could do
The following code attempts to create a named mutex. If the function (CreateMutex) fails, you can be sure that an instance of the application is already running.

program Project1;

uses
  Forms, Windows,
  Unit1 in 'Unit1.pas' {Form1};

{$R *.res}
var
  Mutex : THandle;
begin
  Mutex := CreateMutex(nil, True, 'My_Unique_Application_Mutex_Name');
  if (Mutex = 0) OR (GetLastError = ERROR_ALREADY_EXISTS) then
  begin

    // code to searh for, and activate
    // the previous (first) instance

  end
  else
  begin
    Application.Initialize;
    Application.CreateForm(TForm1, Form1);
    Application.Run;
    if Mutex <> 0 then
      CloseHandle(Mutex);
    end;
  end;
end.
.
 Continue reading