Jump to content

Kas Ob.

Members
  • Content Count

    373
  • Joined

  • Last visited

  • Days Won

    8

Kas Ob. last won the day on May 25

Kas Ob. had the most liked content!

Community Reputation

106 Excellent

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. Well, as Francois said it, and i will elaborate a little on that. TCanvas is Delphi/Pascal RTL encapsulation for Device Context: https://learn.microsoft.com/en-us/windows/win32/gdi/device-contexts https://learn.microsoft.com/en-us/windows/win32/gdi/about-device-contexts These are Output devices and has no Input, and by Input i mean there is no hardware user input or interaction, their input is solemnly comes from drawing APIs, and in other words they are GDI drawing object that simulate a painting canvas (real life canvas) to be processed further, like to be rendered on monitor or to be passed to printer.... they are build that way to unify User mode GDI and supply one Interface to different hardware, their functionalities differ based on what the hardware and its driver support, while the interface is the same for them all.
  2. Kas Ob.

    Avoid parameter evaluation

    Can't shake it off without trying to validate the type, so here what i tried and it is working perfectly {$APPTYPE CONSOLE} {$R *.res} uses System.SysUtils; procedure DoProcess(const Args: array of const); var i, Count: Integer; begin Count := Length(Args); if Count > 0 then for i := 0 to Pred(Count) do begin case Integer(Args[i].VType) of vtString, vtChar, vtWideChar, vtAnsiString, vtWideString, vtUnicodeString: Writeln(string(Args[i].VString)); vtInteger: Writeln(Args[i].VInteger); vtInt64: Writeln(Int64(Args[i].VInt64)); else Writeln('Type handling not implemented yet ' + IntToStr(Args[i].VType)); end; end; end; procedure Test; var st: string; begin st := 'Param1'; DoProcess([st, 'Param2', 5]); end; begin Test; Readln; end. output The generated assembly is nice and short, one thing though, don't forget to declare Args itself as const as in procedure DoProcess(const Args: array of const) or it will be copied locally, in other words it will be ugly.
  3. Kas Ob.

    Avoid parameter evaluation

    I never thought about this. Thank you !
  4. Kas Ob.

    Avoid parameter evaluation

    Well my point was about to not call SysErrorMessage in the first place, just pass the GetLastError, even more on this, if the code between Log and where actually it implemented can't modify The GetLastError, then you could use ttTraceIWithError and there you can call SysErrorMessage. In case you care about performance then just use a method and track the generated assembly And by replacing the most repeated or even the specific phrases like 'Test' and 'Exception'... with LOG_String_XX you can short and fast logging. Again food for thoughts.
  5. Kas Ob.

    Avoid parameter evaluation

    There is few ways i can think of like these 2 approaches type TLogLevel = (llInfo, llTrace, llError); procedure Log(LogLevel: TLogLevel; const LogText: string); overload; begin end; procedure Log(LogLevel: TLogLevel; const Text: array of string); overload; var Count: Integer; begin Count := Length(Text); case LogLevel of llInfo: ; llTrace: begin if Count > 0 then begin end; end; llError: ; end; end; procedure Log(LogLevel: TLogLevel; const LogText: string = ''; const Error: string = ''; const Additional: string = ''); overload; begin end; procedure Log(LogLevel: TLogLevel; const LogText: string = ''; ErrorCode: Integer = 0; const Additional: string = ''); overload; begin end; procedure TForm10.FormCreate(Sender: TObject); var BuildStringFromContext: string; begin Log(llTrace, ['Test', IntToStr(GetLastError), BuildStringFromContext]); Log(llError, 'Test', GetLastError, BuildStringFromContext); Log(llError, 'Simple Text', 0); Log(llInfo, 'Simple Text', 0, 'Additional Info'); Log(llInfo, 'Simple Text', ''); end; Just food for thoughts for you, using array of string is easy and will make you life easier, but you should remember the order, while the overloaded versions with default empty values, are more readable and harder to confuse. Each had its own shortcoming, like i had to add 0 do the ambiguity, but if you make you mind you can build them right and remove the need for these extra 0 or ''. It is up to your need to think of a solution that you are comfortable with.
  6. Yes , and to be more accurate explaining this case with both addresses are the same, The EIP register pointing to a page-protected address, means the CPU is already try to fitch an instruction while the virtual mode triggered a page fault, hence the same address of the execution and accessing, this happens with few cases, like the stack is corrupted and a ret instruction caused the CPU to pick an invalid address to return to, or a hook or resolved API addresses pointing to a library, and that library has been already freed and its memory returned to the OS where marked again as protected or not allocated. Not long ago there was similar bug discussed in the German forum comes from broken hooking that corrupt the stack after calling the hook, sorry can't find it now ! may be someone can help with that. @christos papapostolou i would suggest to check and refine your uses clauses and find any exotic units or library that are outdated, also try to capture the stack list, it will help.
  7. Frankly speaking, this part is quite unexpected for me, since I never had a chance to dive deep into RTTI, and the “classical” Pascal treated types T1 and T2 equal whenever there ould be a T1 = T2 declaration. I think I understand the reasons, but I’ll have to read more on topic to be sure. Well, hold your horse here for minute. I might made a mistake here, or did i ? Things seems a little different between Delphi 2010 and XE8, so it might be different for you with your version. My mistake is between these type TSomeType = MyTypes.TSomeType; type TSomeType = type MyTypes.TSomeType; the latter does have different RTTI for sure, but for the first is does not, and that is my mistake, yet helpers is confused as hell between the two type and my two already old Delphi versions compiler, one allow it and the other is buggy and confuse them, and from there my mistake did come. i rarely used similar approach for such renaming or like this var LDefObject: TObject; LObject: TMyObject; LMyObjectEx: TMyObjectEx absolute LObject; begin Memo1.Lines.Add(LDefObject.HelperName); Memo1.Lines.Add(LObject.HelperName); Memo1.Lines.Add(LMyObjectEx.HelperName); To have my own string helper with casting and without losing the default string helper, and i don't know if this is working on the newer versions, yet now i trying to add a helper for string on my Delphi 2010 and it does allow it
  8. Hi, Few thoughts on this: 1) If MyTypes is used through out the project then no point of renaming or redefining its types in other units, it will be there and everywhere. 2) From what i understand, UnitB is to somehow can be named as UnitAEx or UnitAHighLevel, this will draw clear path of using and remind of adding UnitA where it extended version is used, the one (not/ex) called UnitB. 3) About this I don't think i ever used such renaming easily as it is easily can tangle things and cause more and different problem in the future, the one you missed now, see TSomeType on the left is a rename or redefine of MyTpes.TSomeType, yes they are the same, but in you view not for the compiler, example RTTI is different for them and they are not equal ! also in some places you will see the compiler might complain about the definition, usage and passing them as parameters .... also it might broke things badly in case such units used in an Design Time package. I see if that is needed then use it where is the impact is smallest, like in UnitB to rename types from UnitA instead of redefining types from MyType unit into UnitA, try to narrow the scope in it is needed. Now to the questions I am no aware of such best practice if it is exist, i follow best practice and simple and short logic, keep it stupid simple, and also untangled as much as possible. OK it is, yet it depends on the case and what could be changed in the future, rarely one can see that today, i made so many mistakes, not real mistakes as this is not a mistake per se, it is just short sighting and not leaving doors open but .... not tangle many things together. No sure i do understand the question, but i hope my points above could give you some insights. The above is my personal opinion, and i am sure many in the forum can have helpful insights on this.
  9. Kas Ob.

    TControlList — need help!

    @#ifdef Well , while i hate my life nowadays, and while just waiting for the blackout to brighten my day after only 3 hours of power, i tried to build you something Far from finished or polished, take it as example or prototype for what you can do with custom drawing, notice it is 10000 strings ! ListBoxAsStringList.zip My suggestion is to use VirtualTreeView, i couldn't find working copy of VTV on my PC now, and don't want to waste time downloading my encrypted archives from the cloud, so i used TListBox, it is simple easy and pretty straight forward. Notes: 1) i didn't use FillRec on the whole Listbox, while it is more efficient and faster to clear the background for all the items in one go, this will introduce an ugly flicker in the bottom half, do the system rendering which doesn't wait for anyone, by clearing the background for each item in time, we prevent this flicker, but will introduce small performance hit in overall drawing. 2) i disabled the selected item highlighting, because it does need little different approach, yet it is easy, just adjust the canvas brush color before the FillRect, this will be up to you to implement, as i said i don't have time and don't have the skins on the latest IDE versions to test and play with. 3) customize as you wish, like ... can you this ? ( there is no noticeable performance change) Hope that helps, also never underestimate Windows custom drawing, it is fucking blazing fast when done right.
  10. This access violation is classic corrupted stack, the stack either being overwritten or wrong casting being used with some procedure/function led to not aligned call/ret addresses on the stack. On sidenote: that address is more like the EXE is not there at all, like it gone, yet the debugger/OS reporting a failed execution on no execution memory address, ... ( it also could be a DLL though). I can't compile the code and don't have experience with MadExcept, but this doesn't sound right at all, and this brings me again to the why MadExcept failed to report the hundreds of leaks and stopped at string with 3 refCount ? There is something wrong with MadExcept or miss configuration in its usage, are you using it with FastMM or any other unit as first use in the dpr file uses clauses ?
  11. That is 58 object leak of TGadgetMetaAccesseor ! This should be easy to track and fix, fixing this part most likely will fix most of the others in that screenshot. Now, and from the pasted code, i can't figure out where "GadgetAccessor: TGadgetMetaAccessor;" is freed, these are local variables so where are they used and to whom they are shipped, notice and follow how these variables are referencing each other. procedure TGadgetMetaInfo.Load(aCollection,aPiece: String; aTheme: TNeoTheme); var .. GadgetAccessor: TGadgetMetaAccessor; NewAnim: TGadgetAnimation; .. begin .. GadgetAccessor := GetInterface(false, false, false); // <----- .. NewAnim := TGadgetAnimation.Create(0, 0); // <----- GadgetAccessor.Animations.AddPrimary(NewAnim); NewAnim.Load(aCollection, aPiece, Sec.Section['PRIMARY_ANIMATION'], aTheme); fFrameCount := NewAnim.FrameCount; PrimaryWidth := NewAnim.Width; // Used later Sec.DoForEachSection('ANIMATION', procedure (aSection: TParserSection; const aIteration: Integer) begin NewAnim := TGadgetAnimation.Create(GadgetAccessor.Animations.PrimaryAnimation.Width, GadgetAccessor.Animations.PrimaryAnimation.Height); GadgetAccessor.Animations.Add(NewAnim); NewAnim.Load(aCollection, aPiece, aSection, aTheme); end ); ... end; Where and how these are released, that what you should find and fix, as for the UnicodeString leak, it might be simply a confusion/confliction in madshi with MemoryManager, that lead to miss identifying the leaks and their types.
  12. Kas Ob.

    TControlList — need help!

    By the way Notepad++ with 14mb text file with longs lines, very fast without Word Wrap, does stutter on resizing with Word Wrap enabled.
  13. Kas Ob.

    TControlList — need help!

    It is owner drawn in full. Well i said i can't compile your project, and if all of these text segments are ... What ? (i don't care) TLable or TMemo, then use 50-80 and just update their content simulating hundreds or thousands, instead of creating hundreds, update their contents based on the scroll bar. You could also try to create the needed amount and try to clear the non visible and fill the few visible when resizing, i am throwing ideas here and hope might help.
  14. Kas Ob.

    TControlList — need help!

    So these are TMemo(s) in the list ! not even simple and plain text lines in a list box. Anyway, same recommendation as for single Memo or ListBox, switch to owner drawing, then limit what you are using/rendering/showing to the visible ones, while simulate/emulate a scroll bar on the side, or it might support its own scrollbar, who knows.
  15. Kas Ob.

    TControlList — need help!

    @#ifdef Well i can't compile your project nor i have an idea what TControlList is, yet from your last post i can deduce the problem. Se, same behavior is visible with Windows Notepad, you can try it, open a big text file something around few MBs and make sure that Word Wrap is enabled, and see for your self, same behavior, disabling the Word Wrap will make it fast like it was few lines. Calculating the height of paragraph is demanding process, because it only possible with a font and a width, after that rendering will happen again with the font applying device context parameters, so it might be doable but not like that it must involve caching. The only components i know of that do this right (or lets say fast) is the controls from Delphi HTML components. Yet, there is may be a workaround in your case, which is switching to virtual drawing, and rendering only what should be visible while emulating the scrollbar position at side, in other words you need to switch to owner draw and draw text manually what is enough to fill the control.
×