Jump to content

ChrisChuah

Members
  • Content Count

    108
  • Joined

  • Last visited

Posts posted by ChrisChuah


  1. The DetailForm close event will have Action := caFree

    I tried this way

     

    ===== Ghosting Windows

    procedure DisableProcessWindowsGhosting;

    var
      DisableProcessWindowsGhostingProc: procedure;
    begin
      DisableProcessWindowsGhostingProc := GetProcAddress(
        GetModuleHandle('user32.dll'),
        'DisableProcessWindowsGhosting');
      if Assigned(DisableProcessWindowsGhostingProc) then
        DisableProcessWindowsGhostingProc;

    end;

     

    begin
      Application.Initialize;
      DisableProcessWindowsGhosting;
      TStyleManager.TrySetStyle('Iceberg Classico');
      Application.CreateForm(TDataModule1, DataModule1);
      Application.CreateForm(TfrmMain, frmMain);
      Application.Run;
    end.
    =======================

     

    But will also have the same effect that open and close the form too many times will result in hanging of the application or the form will not show.

     

    Only when i removed the Style Manager, then i will not have this problem.

    The Grid is also having its own DrawColumnCell Event

     

    =====================

    procedure TfrmMain.dbgACTDrawColumnCell(Sender: TObject; const Rect: TRect;
      DataCol: Integer; Column: TColumn; State: TGridDrawState);
    var
      l_bitmap : TBitmap;
      l_rect : TRect;
      l_bmpWidth, l_width : integer;
      l_str : string;
    begin
      with dbgACT do begin
        if (gdSelected in State) then begin
          Canvas.Font.Color := clBlack;
          Canvas.Brush.Color := clLime;
        end
        else begin
          if ( (DataSource.Dataset).RecNo mod 2 = 0) then begin
            if Canvas.Brush.Color = Color then begin
              Canvas.Brush.Color := clSkyBlue;
            end;
          end;
        end;
      end;
      l_rect := Rect;
      l_str := Column.Field.DisplayText;
      l_width := dbgACT.Canvas.TextExtent(l_str).cx + 5;
      if Column.FieldName = 'ROW_ID' then begin
        l_bitmap := TBitmap.create;
        try
          ImageList2.GetBitmap(tsACT.ImageIndex, l_bitmap);
          l_bmpWidth := (Rect.bottom - Rect.Top);
          l_rect.Right := Rect.Left + l_bmpWidth;
          dbgACT.Canvas.StretchDraw(l_rect, l_bitmap);
        finally
          l_bitmap.Free;
        end;
        // cc : reset the output rectangle
        l_rect := Rect;
        l_rect.Left := l_rect.Left + l_bmpWidth;
        l_width := 5 + dbgACT.Canvas.TextExtent(l_str).cx;
      end;
        if (l_width > Column.Width) then
          Column.Width := l_width;
      dbgACT.DefaultDrawColumnCell(l_rect, DataCol, (Column as TColumn), State);
    end;
    ====================

     

    But not sure if this affected the style manager or not

     

    regards

    chris

     


  2. HI 

    I am having this funny problem in Delphi 11.1 using VCL.

     

    ====

      FDetailForm := TfrmAircraftTypesNew.Create(self);
      try
        (FDetailForm as TfrmAircraftTypesNew).setData(UpdateRow, l_rec);
        FDetailForm.Visible := false;
        FDetailForm.ShowModal;
      finally
        l_rec.Free;
      end;
      FDetailForm := nil;
    =======

    When i open and close the FDetailForm a few times, the detail form would not show and the main window will hang.

    See this video to see what i mean.

     

    In the Form Close of the TfrmAircraftTypesNew, i will have

    Action := caFree;

    1655068418_Screenshot2022-08-22at20_58_57.thumb.png.44d4ad21823c1bf09bcda563e4cbe085.png

    Can help why the form is not able to show on top. 

    I have already tried to put the PopupMode to Explicit.

     

    Another Finding:

    when i remove or commented the style from the startup, i did not have this problem of not able to showModal

     

    Application.Initialize;
    //  TStyleManager.TrySetStyle('Iceberg Classico');  <== Remove/commented this line
      Application.CreateForm(TDataModule1, DataModule1);
      Application.CreateForm(TfrmMain, frmMain);
      Application.Run;

     

    Not sure why this style is giving problem....

     

    Please advise

    regards

    chris


  3. Thanks. need to use locate with disable/enable controls so that the table will not have moving effect.

    However, for my dataset, it has 50 columns but the dbgrid can only show first 10 columns on the screen.

    If need to show next 10 columns, i will need to scroll to the next 10 columns.

    So, when i am looking at the next 10 columns and the table refreshed, can the refresh go to the next 10 columns rather than always go back to the 1st 10 columns?

     

    regards

    cris

     


  4. Hi

    When the database table is updated and i use dbgrid.datasource.dataset.refresh, the dbgrid is refreshed back to the first row.

    Is it possible to refresh the grid without going back to the first row?

    This is because if there is frequent update to the database and this Refresh notification is sent to my app each time another app updates the table, the dbgrid will always move back to the first row when it is refreshed.

    Any advise

     

    regards

    chris

     


  5. Hi

    I managed to implement it in windows using this event

    TfrmMain : TForm

            Gauge1 : TGauge;

            tmrInactivity: TTimer;
            procedure FormCreate(Sender: TObject);
            procedure tmrInactivityTimer(Sender: TObject);
    private    

            FInactivityTimeout : cardinal;
            FInactivityCounter : cardinal;

     

            // cc : application event to handle key down and left mouse click
            // cc : for activity timeout
            procedure ApplicationEventMsg(var Msg: tagMSG; var Handled: Boolean);
    public

     

    end;

     

    procedure TfrmMain.FormCreate(Sender: TObject);

    var

      l_ini : TIniFile;

    begin

        // this event msg is to capture keyboard and mouse event

        Application.OnMessage := ApplicationEventMsg;

     

        // cc : get the amount of seconds allowed before timeout

         l_ini := TIniFile.create(ChangeFileExt(Application.ExeName, '.ini'));

        FInactivityTimeout := l_ini.ReadInteger('Main', 'Inactivity Timeout', 60);
        Gauge1.MaxValue := FInactivityTimeout;
        Gauge1.MinValue := 0;
        FInactivityCounter := 0;

       l_ini.Free;

    end;
     

    procedure TfrmMain.tmrInactivityTimer(Sender: TObject);
    begin
      // Inactivity timeout will disconnect every connection
      tmrInactivity.Enabled := false;
      if (not DataModule1.getLoginSuccess) then begin
        FInactivityCounter := 0;
        Gauge1.Progress := 0;
        tmrInactivity.Enabled := true;
        exit;
      end;
      if (FInactivityCounter > FInactivityTimeout) then begin
          DataModule1.closeAll;
        end;
        FInactivityCounter := 0;
        Gauge1.Progress := 0;
      end
      else begin
        FInactivityCounter := FInActivityCounter +1;
        Gauge1.Progress := FInactivityCounter;
      end;
      tmrInactivity.Enabled := true;
    end;
     

     


  6. Hi

    I have another question.

    After i use the AddIndex and set the IndexName to the index field created, how can i get back the information of what index field is used and what is the sorting order (asc or desc)

     

    e.g.

      l_indexName := 'ABN_REM' + '_INDEX';
      l_indexes := TStringList.create;
      (TntDBGrid1.DataSource.DataSet as TClientDataSet).GetIndexNames(l_indexes);
      if l_indexes.IndexOf(l_indexName) > -1 then
        (TntDBGrid1.DataSource.DataSet as TClientDataset).DeleteIndex(l_indexName);
      l_indexes.Free;
      (TntDBGrid1.DataSource.DataSet as TClientDataset).AddIndex(l_indexName, 'FREE_REM', [ixDescending],'','',0 );

      (TntDBGrid1.DataSource.DataSet as TClientDataset).IndexName := l_indexName;
     

    In the above code, i have set the IndexName to 'ABN_REM_INDEX' with field 'FREE_REM' used and sort in descending order.

     

    So, how can i get back this information that the field name 'FREE_REM' is used and the sorting is in descending order?

     

     

    regards

    chris

     


  7. Hi

    I am not sure if this function affected the drawing

     

    procedure TForm1.ClientDataSet1AfterOpen(DataSet: TDataSet);
    var
      l_index : integer;
      l_fieldName : string;
    begin
      for l_index := 0 to ClientDataSet1.FieldCount - 1 do begin
        l_fieldName := ClientDataSet1.Fields[l_index].FieldName;
        ClientDataSet1.Fields[l_index].DisplayWidth :=10;
        if (l_fieldName  = 'SDT') or (l_fieldName = 'EST_D') or
           (l_fieldName = 'LAST_D') or (l_fieldName = 'ACT_D') or
           (l_fieldName = 'CREATED_AT') or (l_fieldName = 'UPDATED_AT') then
          ClientDataSet1.Fields[l_index].OnGetText := getDateTimeStr
        else if (l_fieldName = 'STIME') then
          ClientDataSet1.Fields[l_index].OnGetText := getTimeStr
        else if (l_fieldName = 'SDATE') then
          ClientDataSet1.Fields[l_index].OnGetText := getDateStr
        else if (l_fieldName = 'ORDEST_N_C') or (l_fieldName = 'FREE_REM') then
          ClientDataSet1.Fields[l_index].OnGetText := getForeignStr;
      end;
      Dataset.Last;
    end;

     

    procedure TForm1.TntDBGrid1DrawColumnCell(Sender: TObject;
      const Rect: TRect; DataCol: Integer; Column: TColumn;
      State: TGridDrawState);
    var
      l_bitmap : TBitmap;
      l_rect : TRect;
      l_bmpWidth, l_width : integer;
      l_str : string;
    begin
      if (ClientDataSet1.RecNo mod 2 = 0) then begin
        if TntDBGrid1.Canvas.Brush.Color = TntDBGrid1.Color then begin
          TntDBGrid1.Canvas.Brush.Color := clSkyBlue;
        end;

      end;
      l_rect := Rect;
      l_str := Column.Field.DisplayText;
      if Column.FieldName = 'ROW_ID' then begin
        l_bitmap := TBitmap.create;
        try
            ImageList3.GetBitmap(1, l_bitmap);
          l_bmpWidth := (Rect.bottom - Rect.Top);
          l_rect.Right := Rect.Left + l_bmpWidth;
          TntDBGrid1.Canvas.StretchDraw(l_rect, l_bitmap);
        finally
          l_bitmap.Free;
        end;
        // cc : reset the output rectangle
        l_rect := Rect;
        l_rect.Left := l_rect.Left + l_bmpWidth;
        l_width := 5 + TntDBGrid1.Canvas.TextExtent(l_str).cx;  <==
        if (l_width > Column.Width) then <==
          Column.Width := l_width;  <==
      end;
      TntDBGrid1.DefaultDrawColumnCell(l_rect, DataCol, (Column as TTntColumn), State);
    end;
     

    As i store all the dates as Unix Epoch format. hence i need to translate all the values to date time format when drawn on the grid.

    However, is there a way to know when the drawing on the grid is completed?

    Or is there a better way to make the grid draw out faster?

     

    Seems like if i dont make it auto size for every column, the drawing is faster.

    The longest column is the Foreign Characters and the resizing took quite long there

    Is there a way to auto size and auto fit the column which is not done during the drawing part?

     

     

    please advise

     

    regards

    chris

     


  8. I just found out that i can use the dataset to refresh rather than Open and close.

    The dbgrid will refresh with updated content.

     

    Now i have another problem is when i open the dataset, the dbgrid is filled to the bottom and it will somehow stop there..

    i need to scroll down to request it to draw again.

    anyone have this problem?

    is there a way to scroll all the way down the grid automatically once the drawing is completed?

    please see this video on the problem.. anyone can advise?

     

    source

    procedure TfrmMain.dbgABNDrawColumnCell(Sender: TObject; const Rect: TRect;
      DataCol: Integer; Column: TColumn; State: TGridDrawState);
    var
      l_bitmap : TBitmap;
      l_rect : TRect;
      l_bmpWidth, l_width : integer;
      l_str : string;
    begin
      if ( (dbgABN.DataSource.Dataset as TClientDataset).RecNo mod 2 = 0) then begin
        if dbgABN.Canvas.Brush.Color = dbgABN.Color then begin
          dbgABN.Canvas.Brush.Color := clSkyBlue;
        end;

      end;
      l_rect := Rect;
      l_str := Column.Field.DisplayText;
      if Column.FieldName = 'ROW_ID' then begin
        l_bitmap := TBitmap.create;
        try
          ImageList2.GetBitmap(0, l_bitmap);
          l_bmpWidth := (Rect.bottom - Rect.Top);
          l_rect.Right := Rect.Left + l_bmpWidth;
          dbgABN.Canvas.StretchDraw(l_rect, l_bitmap);
        finally
          l_bitmap.Free;
        end;
        // cc : reset the output rectangle
        l_rect := Rect;
        l_rect.Left := l_rect.Left + l_bmpWidth;
      end;
      l_width := 5 + dbgABN.Canvas.TextExtent(l_str).cx;
      if (l_width > Column.Width) then
          Column.Width := l_width;
      dbgABN.DefaultDrawColumnCell(l_rect, DataCol, (Column as TTntColumn), State);
    end;

     


  9. Hi

    I am using TSQLQuery, TClientDataSet and TDataSetProvider with DBGrid

    I will click on the record row in the middle of the grid and the grid shows that it is highlighted

    HOwever, when i close and open the ClientDataSet to refresh the data, 

    i would use the bookmark to go back to the last bookmark before the Client dataset is Close

     

      l_bookmark := TntDBGrid1.Datasource.DataSet.GetBookmark;
      TntDBGrid1.DataSource.DataSet.Close;
      TntDBGrid1.DataSource.Dataset.Open;
      TntDBGrid1.DataSource.DataSet.GotoBookmark(l_bookmark);
      TntDBGrid1.DataSource.Dataset.FreeBookmark(l_bookmark);
     

    After open, the indicator is shown correctly on the dbgrid but the highlighted row is on the first row.

    see pic 

     

    please advise

     

    regards

    chris

    1389271130_Record100selected.thumb.png.408121fb4857ce6087f7d9f241aa7059.png386449203_RefreshRecord100notselected.thumb.png.78cf37b4a3cf962806c55618cb2ef4ee.png


  10. Hi

    I am using TSQLQuery, TClientDataSet and TDataSetProvider with DBGrid

    If i want to sort the DBGrid based on title column click, i can use the event OnTitleClick on DBGrid

     

    ClientDataSet.IndexFieldsName := Column.FieldName

     

    However, this will sort the Field in ascending order.

     

    How can i sort it in descending order?

    please advise

     

    regards

    chris

     


  11. 9 hours ago, Remy Lebeau said:

    On some platforms, you might be able to just set the TIdUDPClient.BoundIP property to the IP of the network adapter you are sending broadcasts from.  On other platforms, you might have to resort to using TIdUDPClient.Binding.SetSockOpt(SO_BINDTODEVICE) to bind to a network interface by name instead of IP.  But either way, this should prevent your outgoing network adapter from receiving duplicates of its own broadcasts.

    Not quite sure I understand what you are asking.

     

    If you are asking how to ignore the IP of the broadcaster, then whenever you receive a packet, you are also given the sender's IP (and port).  You can just ignore packets that come from your own IP.

     

    If you are asking what a broadcast IP is in general, then it is a network IP that is masked by its subnet mask, and then OR'ed with the inverse of the subnet mask.  So, for example, if you have an IP of 192.168.100.5 and a subnet mask of 255.255.255.0, then the broadcast IP is 192.168.100.255:

     

    192.168.100.5 & 255.255.255.0 = 192.168.100.0

    ~255.255.255.0 = 0.0.0.255

    192.168.100.0 | 0.0.0.255 = 192.168.100.255

    Hi Remy

    Yes. As i send a UDP packet to a 192.168.100.255, the IP address that returns to me is also 192.168.100.255 as well as a reply from other servers.

    Is there a function to say isBroadcastAddress(aIPAddress: string) that i can use so as to know its a broadcast address?

    Does Indy library has such function?

     

    regards

    chris

     


  12. Hi

    On my mac, it seems that i have many network interfaces.

    I used Indy GStack.GetLocalAddressList to obtain all these interface name and IP address.

     

    Stack Local Address 0: en0: FE80:0:0:0:102B:BAE3:A50E:FEDA
    Stack Local Address 1: en0: 192.168.1.10
    Stack Local Address 2: en1: FE80:0:0:0:C55:FF1F:977A:4ECD
    Stack Local Address 3: en1: 192.168.1.11
    Stack Local Address 4: awdl0: FE80:0:0:0:380D:36FF:FE0A:D127
    Stack Local Address 5: llw0: FE80:0:0:0:380D:36FF:FE0A:D127
    Stack Local Address 6: utun0: FE80:0:0:0:FE2C:6391:70B1:32E5
    Stack Local Address 7: utun1: FE80:0:0:0:D512:288C:E8D7:52E1
    Stack Local Address 8: utun2: FE80:0:0:0:CE81:B1C:BD2C:69E
    Stack Local Address 9: bridge100: 172.16.90.1
    Stack Local Address 10: bridge100: FE80:0:0:0:787B:8AFF:FE3C:7864
    Stack Local Address 11: bridge101: 192.168.83.1
    Stack Local Address 12: bridge101: FE80:0:0:0:787B:8AFF:FE3C:7865
    Stack Local Address 13: bridge102: 192.168.84.1
    Stack Local Address 14: bridge102: FE80:0:0:0:787B:8AFF:FE3C:7866
    Stack Local Address 15: bridge103: 192.168.85.1
    Stack Local Address 16: bridge103: FE80:0:0:0:787B:8AFF:FE3C:7867
    Stack Local Address 17: bridge104: 172.16.49.1
    Stack Local Address 18: bridge104: FE80:0:0:0:787B:8AFF:FE3C:7868

     

    If i want to send a broadcast packet onto 192.168.84.255 (Bridge102), How can i specify it in idUDPClient?

    Or will idUDPClient able to automatically send it out via that interface?

     

    Please advise

     

    regards

    chris

     

     

     

×