Jump to content


  • Content Count

  • Joined

  • Last visited

Community Reputation

3 Neutral
  1. aehimself

    Setting Environment Variables

    Also please note that in Windows several environmental variables requires a logoff-logon for the changes to take affect (like %PATH%).
  2. aehimself

    Step-by-step debugging exceptions

    Shift-F8 will return at the end of the calling method, in this case the OnClick handler. It will NOT put you inside the Except block in any case. As for TStringList, I just chose something random, you can even put Raise Exception.Create('hello world'); instead. Also, I believe that when you try to access an uninitialized object it does not matter where it comes from, as it does not exist... I am afraid that @Fr0sT.Brutal will be right, and this - too - is going to be a limitation of the IDE. Too bad ๐Ÿ™‚
  3. aehimself

    JSON as a way to save information in Firebird

    Based on experience I am against this type of data storage for several reasons: - Some database engines can not search in BLOB fields. Now it might not be an issue in the beginning but it makes investigating data corruption / debugging processing issues a living nightmare - Downloading blob fields are slow, no matter what. Especially over the network. In our production databases I can select hundreds of thousands of rows with 150+ columns but only a fraction of that 2 fields: an ID and a BLOB storing an XML - Database engines are robust, they were built for having columns. While it can be hard / intimidating to see the relations at first time, they have no issues handling a larger number of columns - Unless the DB engine has built-in JSON support, you'll not be able to query and compare a specific value on database side, you'll always have to download and compare from code, increasing memory, network and CPU usage of your program. Considering a well-fed metal (our slang for a server with enough resource + overhead) running the database, this will always be significantly slower than letting the DB engine to take care of these The only reasonable case when storing a JSON / XML in a database I can see is if you receive that from an external source (like a REST server or a 3rd party sending your software some information) and you want to keep those chunks for auditing purposes. Sooner or later you'll face one of the issues I mentioned, though ๐Ÿ™‚ We did the same about 8 years ago (only with XMLs) and now we are looking into opportunities to undo it...
  4. aehimself

    VCL component issue

    A quick and dirty way of adding this component in design time is to switch the platform back to Win32, drop the component and then switch back (even completely remove the Win32 platform). I usually have to do this with my 64bit applications using database access components.
  5. Hello, I was just wondering if this is "normal" or just an anomaly on my side. Consider the following code: Set a breakpoint on sl.Add and execute. When the execution stops, press F8. However the Except block executes, the Delphi debugger does not continue the step-by-step debugging. I know, you can put a breakpoint on On E:Exception but it would be a lot nicer to see how the exception is flowing (especially through 5-10 units until it reaches the final handler). Is there a way to achieve this or it's just a limitation of the debugger? Cheers!
  6. Hello, Of course, this information is included in the update file and (except for the download link) are published by the thread object as properties. For simplicity's sake I decided not to include them, but here you go ๐Ÿ™‚
  7. A thread with local variables was always my solution as well. When my application starts it launches a background thread which downloads the update definition file and notifies the main form to show the "Updates are available". Everything until here is not locking the UI. When the update form is shown and the user clicked "Yes" the main form calls a .Update method in the thread which downloads the update file, verifies it etc. and returns a simple bool if it was successful or not. This way no global variables were defined, no complex types were passed between threads and most of the work was done without locking the UI. Threads are a good thing.
  8. aehimself

    JSON string value

    I am using Delphi 10.2.3 and wow, I wish I knew about this before I started my first project... now I have to go back and correct them all ๐Ÿ˜„ I can confirm that s.ToJSON is producing the exact same output as it was originally requested: s.ToString with the replacements produces "\"value\\with\n{strange}chars/\"" s.ToJSON produces "\"value\\with\r\n{strange}chars\/\"" Lesson learned. Do not try to reinvent the wheel, just realize if I messed up the implementation. (I wonder why it has a .ToString if it is not producing a correct syntax though...)
  9. aehimself

    Add aย system-menu item to all applications?

    I used the system menu to allow users to change the VCL style of my application. The code looked like this: Procedure TMyApplicationMainForm.FormShow(Sender: TObject); Var sysmenu: THandle; a: Integer; flags: Cardinal; Begin sysmenu := GetSystemMenu(Self.Handle, False); AppendMenu(sysmenu, MF_SEPARATOR, Word(-1), ''); For a := Low(_validstyles) To High(_validstyles) Do Begin flags := MF_STRING; If TStyleManager.ActiveStyle.Name = _validstyles[a] Then flags := flags Or MF_CHECKED; AppendMenu(sysmenu, flags, WM_USER + 1 + a, PWideChar(_validstyles[a])); End; End; Instead of Self.Handle I suppose you can supply a different form handle returned by FindWindow. This solution will send a WM_USER message to the form when the appended item is clicked but the foreign one has to process that correctly... I guess you can append to the system menu of an other application, but I doubt that it will ever work correctly. At least not this way ๐Ÿ˜ž
  10. aehimself

    JSON string value

    Although Delphi has a native JSON implementation (System.JSON unit) it is not perfect. It seems to be good in parsing, but assembly needs a bit of help. I use it in most of my latest codes though. To achieve what you'd like: procedure TForm1.Button1Click(Sender: TObject); const KEK = '"value\with' + sLineBreak + '{strange}chars/"'; Var s: TJSONString; begin s := TJSONString.Create(KEK.Replace('\', '\\').Replace(#9, '\t').Replace(sLineBreak, '\n').Replace(#10, '\n').Replace(#13, '\n')); Try Edit1.Text := s.ToString; Finally FreeAndNil(s); End; end; Without the loads of .Replace statements it tends to generate invalid JSONs. So far this chain always fit my needs. It needs a little bit of time to get used to it, but it's lightweight and fast. Edit: I don't think you actually have to escape forward slashes in JSON string literals, they seem to pass validation without them. I did not read the whitesheet though, so I could be wrong. Just add .Replace('/', '\/') in the chain to do that.
  11. aehimself

    VCL-styled Popupmenu issue if imagelist is assigned

    Uwe, Wow, a 3 year old bug... and indeed it does look the same! So without upgrading my Delphi installation I have no other choice than to forcefully remove icons when using Styles. Or not to use Styles in general ๐Ÿ™‚ Thank you for the quick reply!
  12. aehimself

    Passing back a string from an external program

    I always used this code, which works fine. The only issue is if the other application is expecting an input (even a keypress to finish) because ReadFile will wait endlessly as far as I recall. It is easy to finetune it though. function GetDosOutput(CommandLine: string; var ReturnString: String; var ReturnCode: Cardinal): Boolean; const LOGON_WITH_PROFILE = $00000001; var SA: TSecurityAttributes; SI: TStartupInfo; PI: TProcessInformation; StdOutPipeRead, StdOutPipeWrite: THandle; WasOK: Boolean; Buffer: array[0..255] of AnsiChar; BytesRead: Cardinal; WorkDir: string; Handle: Boolean; begin Handle := False; ReturnCode := 255; Result := False; ReturnString := ''; SA.nLength := SizeOf(SA); SA.bInheritHandle := True; SA.lpSecurityDescriptor := nil; CreatePipe(StdOutPipeRead, StdOutPipeWrite, @SA, 0); Try With SI Do Begin FillChar(SI, SizeOf(SI), 0); cb := SizeOf(SI); dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES; wShowWindow := SW_HIDE; //wShowWindow := SW_MINIMIZE; hStdInput := GetStdHandle(STD_INPUT_HANDLE); // don't redirect stdin hStdOutput := StdOutPipeWrite; hStdError := StdOutPipeWrite; End; WorkDir := '.'; Handle := CreateProcess(nil, PChar(CommandLine), nil, nil, True, CREATE_NEW_PROCESS_GROUP or CREATE_NEW_CONSOLE, nil, PChar(WorkDir), SI, PI); CloseHandle(StdOutPipeWrite); If Handle Then Try Repeat WasOK := ReadFile(StdOutPipeRead, Buffer, 255, BytesRead, nil); If BytesRead > 0 Then Begin Buffer[BytesRead] := #0; ReturnString := ReturnString + Buffer; End; Until Not WasOK Or (BytesRead = 0); WaitForSingleObject(PI.hProcess, INFINITE); GetExitCodeProcess(PI.hProcess, ReturnCode); While (Length(ReturnString)<>0) And ((ReturnString[Length(ReturnString)]=#10) Or (ReturnString[Length(ReturnString)]=#13)) Do Delete(ReturnString,Length(ReturnString),1); Result := True; Finally CloseHandle(PI.hThread); CloseHandle(PI.hProcess); End; Finally CloseHandle(StdOutPipeRead); End; end;
  13. Hello guys, I am developing a lightweight, customized SQL client. The main form only has a PageControl, all business logic reside on a frame. When the user chooses a connection, a new tabsheet is created, and a new instance of the said frame is placed upon it. Simple, and works like a charm. To please some people I decided to allow VLC styling of the application but this introduced a really strange issue. If the popup menu resides on the frame and has an image list assigned, it seems like that the menu is not drawn properly: If I change the Style back to the system default (or simply unassign the imagelist component from the TPopupMenu), everything works perfectly: Menu has no owner draw set. What I tried so far: - Add a new menu item during runtime to force a refresh of the menu - Unassign and reassign the popup menu during runtime from the DBGrid component - Unassign and reassign the image list during runtime - Set all ImageIndexes to -1, even removed all menu items during design time - Added Vcl.Styles to the uses clause of the frame - Changing Style during runtime has no effect. If I change back to System default, popup menu start being drawn correctly - Behavior is the same on additional modal forms, menu is not drawn correctly if image list is assigned In the mean time, the popup menu on the main form works perfectly. Which is even more strange, if I assign the main forms popup menu to the DB grid during runtime, it is drawn correctly. I feel like this will be something to do with the menus not being a child of the main form, or like a special hook I'm missing (like how you are forcing styling on a SynEdit component) but I could be far from the truth. I'm running out of ideas. Did anyone face this issue already? Any tips which I could try to make this to work? Thanks all!
  14. aehimself

    formatting HTML code

    Do you need parsing too, or only to beautify the code? I wrote a unit which beautifies and simplifies (remove idents and formatting to reduce size) XML documents and it's using only string helper functions. It formats a ~14 MB XML file in about 300ms, however this heavily depends on the amount of tags. Since the structure is very close I suppose it can work with HTML. If you don't want to use components / libraries let me know, I can send you the code.
  15. Hello, Thanks for the insanely fast reply, I truly appreciate it! All the code in my threads Execute method was uncommented once (I just commented them out when they did not bring the desired result) so my message pump was indeed in place. The only thing I did not consider is that the component is taking the caller thread as it's parent, and not where it is actually located! When I create the component in Execute it starts to work!!! Thank you very much, I would have never guessed this. Due to the nature of how I see code - is there a way to keep the creation in the OnCreate, and destriction in the Destroy method of the thread? I do not wish to create and assign a Client thread to each connection (Win2000 and Win2003 has really bad thread handling and I would like to stay compatible!) and a simple myhttpsrv.ThreadAttach in the beginning of the Execute does not bring joy. If not - I'll just stick to this solution. Thank you again!