Jump to content

dummzeuch

Members
  • Content Count

    2624
  • Joined

  • Last visited

  • Days Won

    91

Everything posted by dummzeuch

  1. dummzeuch

    Delphi and "Use only memory safe languages"

    Even with has its uses. But a convert tool that can remove them sounds really interesting. Is that part of Uwe's MMX explorer?
  2. dummzeuch

    Delphi and "Use only memory safe languages"

    Actually, in my case it sometimes is "just because I can". I use Delphi not only to pay my bills, sometimes I just want to have some programming fun, and I imagine I'm not alone. But yes, there are actual reasons to use features in Delphi that are frowned upon by some people, even the discouraged goto.
  3. I suggest you make your own tests with a simple project to check how the compiler / linker options behave with regards of adding line numbers to the map file. There may be more options that affect it.
  4. I just tested a program in Delphi 10.2 and got the following call stack: Exception at [0092DF9A] w_SigAbout.Tf_SigAbout.Execute (Line 79, "w_SigAbout.pas"): Test <begin call stack> [0092DF95] w_SigAbout.Tf_SigAbout.Execute (Line 77, "w_SigAbout.pas" + 3) + $11 [0093D548] w_AnonymisierungRestApi.Tf_AnonymisierungRestApi.act_GetProgramInfoExecute (Line 2055, "w_AnonymisierungRestApi.pas" + 1) + $8 [004D0C0B] System.Classes.TBasicAction.Execute (Line 16901, "System.Classes.pas" + 3) + $7 [0052FE8A] Vcl.ActnList.TCustomAction.Execute (Line 260, "Vcl.ActnList.pas" + 19) + $35 [004D0A77] System.Classes.TBasicActionLink.Execute (Line 16812, "System.Classes.pas" + 2) + $7 [0060339B] Vcl.Menus.TMenuItem.Click (Line 2539, "Vcl.Menus.pas" + 17) + $7 [00604AFC] Vcl.Menus.TMenu.DispatchCommand (Line 3482, "Vcl.Menus.pas" + 5) + $4 [00605D8E] Vcl.Menus.TPopupList.WndProc (Line 4655, "Vcl.Menus.pas" + 4) + $E [00605CDD] Vcl.Menus.TPopupList.MainWndProc (Line 4630, "Vcl.Menus.pas" + 2) + $5 [004D1970] System.Classes.StdWndProc (Line 17405, "System.Classes.pas" + 8) + $0 [0061E18B] Vcl.Forms.TApplication.ProcessMessage (Line 10641, "Vcl.Forms.pas" + 23) + $1 [0061E1CE] Vcl.Forms.TApplication.HandleMessage (Line 10671, "Vcl.Forms.pas" + 1) + $4 [0061E501] Vcl.Forms.TApplication.Run (Line 10809, "Vcl.Forms.pas" + 26) + $3 [0095195D] Anonymisierung.Anonymisierung (Line 36, "" + 4) + $7 <end call stack> As you can see there are line numbers for the system units as well as for the ones of the program. This is from the debug build. But, if I compile with the release configuration, I get the following: Exception at [0090B884] w_SigAbout.Tf_SigAbout.Execute: Test <begin call stack> [0090B87F] w_SigAbout.Tf_SigAbout.Execute + $37 [0091AC2B] w_AnonymisierungRestApi.Tf_AnonymisierungRestApi.act_GetProgramInfoExecute + $7 [004D0763] System.Classes.TBasicAction.Execute + $F [0052F88E] Vcl.ActnList.TCustomAction.Execute + $86 [004D05CF] System.Classes.TBasicActionLink.Execute + $13 [00602D77] Vcl.Menus.TMenuItem.Click + $93 [006044D8] Vcl.Menus.TMenu.DispatchCommand + $18 [0060576A] Vcl.Menus.TPopupList.WndProc + $82 [006056B9] Vcl.Menus.TPopupList.MainWndProc + $1D [004D14C8] System.Classes.StdWndProc + $14 [0061DB67] Vcl.Forms.TApplication.ProcessMessage + $F3 [0061DBAA] Vcl.Forms.TApplication.HandleMessage + $A [0061DEDD] Vcl.Forms.TApplication.Run + $C9 [0092E77D] Anonymisierung.Anonymisierung + $49 <end call stack> As you can see, there are no line numbers, neither for system units nor for the ones of the program. I could have sworn it should have worked. The configuration for the map file is identical in both. If I change the configuration to use debug dcus, I get line numbers for the system units: Exception at [0090B87C] w_SigAbout.Tf_SigAbout.Execute: Test <begin call stack> [0090B877] w_SigAbout.Tf_SigAbout.Execute + $37 [0091AC23] w_AnonymisierungRestApi.Tf_AnonymisierungRestApi.act_GetProgramInfoExecute + $7 [004D075B] System.Classes.TBasicAction.Execute (Line 16901, "System.Classes.pas" + 3) + $7 [0052F886] Vcl.ActnList.TCustomAction.Execute (Line 260, "Vcl.ActnList.pas" + 19) + $35 [004D05C7] System.Classes.TBasicActionLink.Execute (Line 16812, "System.Classes.pas" + 2) + $7 [00602D6F] Vcl.Menus.TMenuItem.Click (Line 2539, "Vcl.Menus.pas" + 17) + $7 [006044D0] Vcl.Menus.TMenu.DispatchCommand (Line 3482, "Vcl.Menus.pas" + 5) + $4 [00605762] Vcl.Menus.TPopupList.WndProc (Line 4655, "Vcl.Menus.pas" + 4) + $E [006056B1] Vcl.Menus.TPopupList.MainWndProc (Line 4630, "Vcl.Menus.pas" + 2) + $5 [004D14C0] System.Classes.StdWndProc (Line 17405, "System.Classes.pas" + 8) + $0 [0061DB5F] Vcl.Forms.TApplication.ProcessMessage (Line 10641, "Vcl.Forms.pas" + 23) + $1 [0061DBA2] Vcl.Forms.TApplication.HandleMessage (Line 10671, "Vcl.Forms.pas" + 1) + $4 [0061DED5] Vcl.Forms.TApplication.Run (Line 10809, "Vcl.Forms.pas" + 26) + $3 [0092E77D] Anonymisierung.Anonymisierung + $49 <end call stack> If I also include debug information, I get line numbers for both, system and program units: Exception at [0090B878] w_SigAbout.Tf_SigAbout.Execute (Line 79, "w_SigAbout.pas"): Test <begin call stack> [0090B873] w_SigAbout.Tf_SigAbout.Execute (Line 77, "w_SigAbout.pas" + 3) + $11 [0091AC1F] w_AnonymisierungRestApi.Tf_AnonymisierungRestApi.act_GetProgramInfoExecute (Line 2055, "w_AnonymisierungRestApi.pas" + 0) + $7 [004D075B] System.Classes.TBasicAction.Execute (Line 16901, "System.Classes.pas" + 3) + $7 [0052F886] Vcl.ActnList.TCustomAction.Execute (Line 260, "Vcl.ActnList.pas" + 19) + $35 [004D05C7] System.Classes.TBasicActionLink.Execute (Line 16812, "System.Classes.pas" + 2) + $7 [00602D6F] Vcl.Menus.TMenuItem.Click (Line 2539, "Vcl.Menus.pas" + 17) + $7 [006044D0] Vcl.Menus.TMenu.DispatchCommand (Line 3482, "Vcl.Menus.pas" + 5) + $4 [00605762] Vcl.Menus.TPopupList.WndProc (Line 4655, "Vcl.Menus.pas" + 4) + $E [006056B1] Vcl.Menus.TPopupList.MainWndProc (Line 4630, "Vcl.Menus.pas" + 2) + $5 [004D14C0] System.Classes.StdWndProc (Line 17405, "System.Classes.pas" + 8) + $0 [0061DB5F] Vcl.Forms.TApplication.ProcessMessage (Line 10641, "Vcl.Forms.pas" + 23) + $1 [0061DBA2] Vcl.Forms.TApplication.HandleMessage (Line 10671, "Vcl.Forms.pas" + 1) + $4 [0061DED5] Vcl.Forms.TApplication.Run (Line 10809, "Vcl.Forms.pas" + 26) + $3 [0092E77D] Anonymisierung.Anonymisierung (Line 36, "" + 4) + $7 <end call stack> Comparing the map files shows that the Line numbers are mostly missing from the release configuration's map file. These are the line numbers for w_SigAbout from the debug build: Line numbers for w_SigAbout(w_SigAbout.pas) segment .text 74 0001:0050A83C 75 0001:0050A843 76 0001:0050A854 77 0001:0050A862 79 0001:0050A878 80 0001:0050A882 82 0001:0050A89A 84 0001:0050A8AF 89 0001:0050A8CC 90 0001:0050A8FF 91 0001:0050A910 92 0001:0050A91E 93 0001:0050A928 94 0001:0050A933 96 0001:0050A94B 98 0001:0050A960 107 0001:0050A98C 108 0001:0050A9C2 110 0001:0050A9CC 112 0001:0050A9D9 113 0001:0050AA96 116 0001:0050AAAF 118 0001:0050AB98 120 0001:0050AC97 121 0001:0050AD98 123 0001:0050ADB1 125 0001:0050ADB9 127 0001:0050ADC1 129 0001:0050ADD8 130 0001:0050ADE0 131 0001:0050ADF2 133 0001:0050AE07 134 0001:0050AE23 135 0001:0050AE30 136 0001:0050AE41 137 0001:0050AE4A 138 0001:0050AE5D 139 0001:0050AE66 140 0001:0050AE6F 141 0001:0050AE78 142 0001:0050AE91 133 0001:0050AE94 145 0001:0050AE99 146 0001:0050AEAA 147 0001:0050AEB3 148 0001:0050AEC6 149 0001:0050AECF 150 0001:0050AED8 156 0001:0050B0F0 157 0001:0050B108 158 0001:0050B127 159 0001:0050B13B 160 0001:0050B13F 161 0001:0050B155 162 0001:0050B159 163 0001:0050B166 169 0001:0050B1E0 170 0001:0050B203 171 0001:0050B211 172 0001:0050B232 173 0001:0050B240 174 0001:0050B250 175 0001:0050B31C 176 0001:0050B32D 178 0001:0050B346 179 0001:0050B35A 177 0001:0050B371 186 0001:0050B396 187 0001:0050B47B 190 0001:0050B566 191 0001:0050B657 192 0001:0050B748 193 0001:0050B839 194 0001:0050B92A 195 0001:0050BA1B 196 0001:0050BB0C 198 0001:0050BC0A 201 0001:0050BC31 202 0001:0050BC64 203 0001:0050BD36 204 0001:0050BD47 205 0001:0050BD57 206 0001:0050BD67 208 0001:0050BE29 211 0001:0050C074 212 0001:0050C0B1 213 0001:0050C0C1 214 0001:0050C199 215 0001:0050C271 216 0001:0050C349 217 0001:0050C421 218 0001:0050C4F9 219 0001:0050C5E1 226 0001:0050C75C 227 0001:0050C762 228 0001:0050C772 230 0001:0050C777 231 0001:0050C78C 230 0001:0050C7A1 232 0001:0050C7A4 233 0001:0050C7C2 234 0001:0050C7C9 236 0001:0050C7D5 That section is completely missing from the release build, even though both are set to write a detailed map file. So I guess it does matter whether the units are compiled with debug information turned on or off as apparently the linker cannot write the line numbers to the map file if the dcus do do not contain debug information. But that's not because jcldebug reads them from the dcus / executable but because the linker does. Edit: I just confirmed that with an empty console application project created with File -> New -> Console Application Turning on the detailed map file for Win32, comiling for debug and release and then comparing the map files: There are line numbers for the debug configuration and no line numbers for the release configuration. Turning on debug information for a unit like this: unit Unit1; {$D+} interface implementation procedure Test; begin WriteLn('bla'); end; end. Creates line number entries for that unit even for the release build: Line numbers for Unit1(Unit1.pas) segment .text 12 0001:00000000 Google found this: Debug information Generates a line-number table for each procedure that maps object-code addresses into source text line numbers. Equivalent to the {$D+} Delphi compiler directive and the -V switch for DCC32. Default = False http://docwiki.embarcadero.com/RADStudio/Alexandria/en/Linking But turning this option on for the release build did not make any difference.
  5. Since the dcu file format is not documented, I doubt that jcldebug uses it to get line number information.
  6. Debug information has nothing to do with line numbers from jcldebug. Jcldebug only uses the map file for that. I'm not that familiar with the inner workings, but what works for me for debug builds is turning on stack frames, turning off inlining and optimization and creating a detailed map file. For release builds I only use that detailed map file. That gets me the line numbers in stack traces. BUT: My experience with that is still mostly based on Delphi 2007. It's possible that it does not work for later Delphi versions.
  7. dummzeuch

    GExperts 1.3.24 Beta1 for Delphi 12

    I have just built an installer for GExperts 1.3.24 Beta1 for Delphi 12. Note the word “Beta” in the release name! We are one step up from Alpha, there are still many bugs, but overall it seems to be stable. Most of the bugs manifest themselves as display glitches on high DPI monitors. Continue reading in the blog post
  8. dummzeuch

    Delphi Low-code No-code?

    Nobody kehrs ( https://images.app.goo.gl/jtQZNqxjkAh559Do9 ) People, who don't know Delphi, will not touch it. People, who like Delphi will continue to use it People, who use Delphi but don't like it (any more) will continue to use it until they find an alternative. Any new buzzword bullsh*t will not change that. To translate: low code = RAD no code = does not exist
  9. dummzeuch

    Delphi 12.1 is available

    No. The point was that Atlassian has discontinued supporting on-premise servers and asked customers to migrate to the Atlassian hosted version, as said in the blog post announcing the migration.
  10. dummzeuch

    GExperts 1.3.24 Beta1 for Delphi 12

    I haven't installed it yet. Download is done though. It's possible that the last Delphi 12.0 release works with Delphi 12.1, if not, you could try to compile your own DLL, until I get around to make a new release.
  11. As mentioned in my previous post on dzDebugVisualizer I was thinking about writing a generalized debug visualizer which can be user-configured to register itself for any data type. Well, that debug visualizer now exists. It’s part of dzDebugVisualizer and called “Universal Visualizer for Delphi”. Read on in the blog post.
  12. That's because the last line of a string grid cannot be deleted. But the delete button should have cleared the line. If it doesn't, that's indeed a bug.
  13. Given a TStringGrid with FixedRows = 1 FixedCols = 0 RowCount = 51 (50 data rows) ColCount = 3 I want to configure the vertical scroll bar so that the thumb represents the part of the string grid that is visible relative to the full height. I found an article on SwissDelphiCenter which gives the folowing code: procedure TForm1.Button1Click(Sender: TObject); var info: TScrollInfo; begin FillChar(info, SizeOf(info), 0); with info do begin cbsize := SizeOf(info); fmask := SIF_ALL; GetScrollInfo(StringGrid1.Handle, SB_VERT, info); fmask := fmask or SIF_PAGE; nPage := 5 * (nmax - nmin) div StringGrid1.RowCount; // whatever number of cells you consider a "page" end; SetScrollInfo(StringGrid1.Handle, SB_VERT, info, True); end; As far as I understand this, it sets the thumb size to represent 5 rows. I looked up the documentation of GetScrollInfo and SetScrollInfo and came up with a slightly modified version: ///<summary> /// Sets the thumb of the scroll bar of a TStringGrid to represent the visible area relative to the full area. /// @param GridHandle is the window handle of a TStringGrid /// @param Which is either SB_VERT or SB_HORZ /// @Param VisibleCount is TStringGrid.VisibleRows (for SB_VERT) or .VisibleCols (for SB_HORZ) /// @param DataCount is number of non-fixed rows (for SB_VERT) or columns (for SB_HORZ) </summary> procedure TStringGrid_AdjustScrollBarPage(_GridHandle: HWND; _Which: Integer; _VisibleCount, _DataCount: Integer); var Info: TScrollInfo; Size: Integer; begin Size := SizeOf(Info); ZeroMemory(@Info, Size); Info.cbSize := Size; Info.fMask := SIF_ALL; GetScrollInfo(_GridHandle, _Which, Info); Info.fMask := SIF_PAGE or SIF_RANGE; Info.nPage := _VisibleCount; Info.nMin := 1; Info.nMax := _DataCount; SetScrollInfo(_GridHandle, _Which, Info, True); end; (I can probably get rid of the call to GetScrollInfo, as I don't need the values of nMin and nMax to calculate nPage) I call it in the form's Resize event like this: TStringGrid_AdjustScrollBarPage(TheGrid.Handle, SB_VERT, TheGrid.VisibleRowCount, TheGrid.RowCount - TheGrid.FixedRows); (Which sets nPage to 10, nMin to 1 and nMax to 50.) And it seems to work ... ... at least visually. Unfortunately moving the thumb down to the bottom no longer shows the last lines of the grid: (Remember: There are 50 data rows + 1 fixed row) What am I doing wrong here? Is there some other value I need to adjust? Edit: The culprit seems to be the code in TCustomGrid.ModifyScrollBar which calculates the new NewTopLeft value wrongly. Possibly because it makes some assumptions that are no longer true when the scrollbar parameters are set like this. So I either need to figure out a different way to set those parameters or handle the WM_VSCROLL message myself.
  14. After playing around with debug visualizers, I found that there is a very simple way to provide a visualiser for many record types: Just add a special method (I called it Dump) to those records that returns a string that you can then evaluate in the debugger and display in the debug windows. There are two caveats though: read on in the blog post...
  15. Value is a property which I have left out in the shortened type declaration. The same goes for the function IsValid, that checks if the field FIsValid is assigned. So, strictly speaking you are right, the example code won't compile. But the point was to show how to implement a Dump method in principle. If you want to have a look at the actual imlementation of TNullableDateTime, see the unit u_dzNullableDateTime in the dzlib svn repositiory on SourceForge.
  16. Hm, maybe the map file? Do you build dcu files containing debug information? If yes, the debug information contains a line number, so the size might change if the number of lines containing code changes. There might be other kinds of information in the dcu which are similarly affected. The dcu format isn't documented, but I remember a project on GitHub that could read them - at least get identifiers out of them - so maybe that project also contains some kind of documentation or at least parsing code that might shed some light on this.
  17. The same would work with explicitly adding the method call to the watch window and allowing side effects. But the point is to show the values in all debugger windows and hints not just in the watch window. You just gave me an additional idea though: The display value could be cached in a string field which gets updated when the record's value changes, and the visualizer would then just read the field. This would be much faster in the visualizer as no code in the debugged program needs to be executed. But it could significantly slow down the executable in debug mode, depending on how often the value changes.
  18. dummzeuch

    Close current form when opening other form

    Closing the main form of an application terminates that application and thereby also frees that form and all other forms. The main form of an application is defined as the first form it creates and that cannot be changed easily. So, creating a login form as the first form, has the side effect of terminating the application as soon as it gets closed. which is usually not desirable. Therefore such a login form should never be the first form an application creates. (Unless something has been changed over the years and my experience is outdated (again).)
  19. I have seen that happen even without using GetIt. I think it is related to converting the files from LF to CR/LF style line ends. But I never actualy verified this, so I might be wrong.
  20. dummzeuch

    Embed line number at design time??

    No, at least if I remember correctly that the generated format was compatible to jcldebug. But thanks for the link anyway. I have wanted to look into synopse logging since I read about it in that blog post ... OMG: 2011? > 10 years ago!
  21. dummzeuch

    Embed line number at design time??

    You should get the line number of the original function if you pass 1 as the parameter to LineByLevel instead of the default 0.
  22. dummzeuch

    Embed line number at design time??

    Just keep in mind that calling GetLocationInfo is rather costly. It's not meant to be called all over the place. If I remember correctly somebody claimed to have improved the jcldebug file format to make it much smaller and lookups faster. Unfortunately I don't remember who it was and where I read about it. It's quite possible that he donated the code to the jcl in the mean time
  23. dummzeuch

    Embed line number at design time??

    It does indeed. It should also be possible to write a function that reads its own return address from the stack and then returns this value as the result. This then could be passed to GetLocationInfo. I'm not sure how to implement this, but it shouldn't be rocket science. Edit: There is System.ReturnAddress, introduced with Delphi XE2, which gives you just that, so function GetCurrentLineNumber: Integer; var ModInfo: TJclLocationInfo; begin ModInfo := GetLocationInfo(ReturnAddress); Result := ModInfo.LineNumber; end; Should do the trick (untested) Edit: Just tried it. It works, at least in Delphi 10.2. Edit: JclDebug already contains such a function called LineByLevel.
  24. dummzeuch

    Formatter line wrapping and indention

    No idea. I currently don't find the time to do anything on it.
×