-
Content Count
1093 -
Joined
-
Last visited
-
Days Won
24
Everything posted by aehimself
-
WM_SETREDRAW adds the WS_VISIBLE style, but this does not trigger the .Visible property to change. Since according to Delphi the window is not visible it does not even try to hide it - this is why the form stays visible forever. This is why I love to code, we always learn something new: During the OnCreate event the form is invisible. Forcing it visible without being fully created (property loading takes place in a later stage) seems to render it in an unusable state... like it does receive the enable redraw message, but omits it without processing... or something. Removing these calls from the OnCreate and OnClose method solves the issue completely. Verdict: do not use WM_SETREDRAW in any form during construction or destruction. I'll just stick to hiding it before the final expansion to eliminate the flicker, but it's good to know what we can and cannot do with WM_SETREDRAW.
-
No, I did not, as caHide is the default value of Action. The reason why the form pops back up can be found on MSDN: "If the application sends the WM_SETREDRAW message to a hidden window, the window becomes visible (that is, the operating system adds the WS_VISIBLE style to the window)." Maybe this is the reason why it fails to initialize in Modal...?
-
Ooooooookay. Progress. I'm calling the expand logic upon creating and closing the form to set / reset the dimensions. Procedure TForm2.FormClose(Sender: TObject; Var Action: TCloseAction); Begin Self.Visible := False; SendMessage(Self.Handle, WM_SETREDRAW, Ord(False), 0); SendMessage(Self.Handle, WM_SETREDRAW, Ord(True), 0); End; procedure TForm2.FormCreate(Sender: TObject); begin SendMessage(Self.Handle, WM_SETREDRAW, Ord(False), 0); SendMessage(Self.Handle, WM_SETREDRAW, Ord(True), 0); end; If you execute this window with ShowModal, it will freeze upon opening. If you execute it with .Show, it will never disappear (despite having it's .Visible property at false) but remain unpainted for it's lifetime. The problem is calling these upon creating and closing the form. I just don't know why. Yet. Edit: The flicker is there because of the OnClose logic, as I was expanding the window and it popped full-size for a moment before disappearing. The whole story started there, and however it can be done by hiding it before the logic, it disturbs me A LOT on why this method is not working π
-
I know that FreeAndNil is unnecessary here, I just personally use it instead of .Free every single time. A few cycles here is better than a possible false Assigned check somewhere else π I do use VCL Styles in my application, but starting with a fresh project and importing only the message dialog unit has the exact same results. I'll try to strip it down further, as unfortunately the window has to be resizable π
-
Unfortunately no joy for me, window is still frozen on screen. All logic executes only once and goes in the SendMessage block on first try. This message box is displayed with .ShowModal, if that can affect the functionality. Edit: I also saw that 'ownerless' windows can behave like this; and my dialog is created from a class procedure: Class Procedure TMyDialogForm.ShowMe; Var mdf: TMyDialogForm; Begin mdf := TMyDialogForm.Create(nil); Try [...] mdf.ShowModal; Finally FreeAndNil(mdf); End; End; Unfortunately though, changing nil to Application.MainForm had no effect.
-
TJPEGImage is using external methods, like jpeg_CreateDecompress. I don't know if this is being supplied by the compiler or the OS the application is running on, but in this case I don't think it's an issue, as: - if it would be an issue with Win7 x86, it would have affected an awful lot of applications, including browsers too and would have quickly been patched - if the compiler is attaching these methods to the EXE, the application would fail everywhere. Is the application failing with all Win7 x86 OSes, or just one particular PC? If only one PC, is it failing constantly, or just from time to time? I'd look into the configuration of the machine. Ideas: AV locks the file to scan it before the DLL tries to access it; UAC blocking the placement of the file; worn hard drive; any other application hooking into yours / system calls, etc.
-
@PeterBelow, @Anders Melander Good point, I tend to forget about this. However in this case the handle seems to be the same, even when during the destructor.
-
My 2 cents are... not releasing write lock / not closing file, or improper flushing to disk. I personally never had any issues with TJPEGImage like this. @dkprojektai If you really want to make sure, try reloading the saved file with the same, TJPEGImage object and catch any exceptions. As I stated above though, I would be surprised if there would be any. I think @Remy Lebeau is on the right track here and the DLL is not handling the file correctly. At the end of the day it might be a special requirement in the header / pattern what we don't know about.
-
Add aΒ system-menu item to all applications?
aehimself replied to PeterPanettone's topic in Windows API
Come on. Let us to have some fun, life is not only strict and serious work. After all, there are people who always try to put some humor into their writing. -
Add aΒ system-menu item to all applications?
aehimself replied to PeterPanettone's topic in Windows API
Nice, I actually laughed on this π -
JSON as a way to save information in Firebird
aehimself replied to Alberto FornΓ©s's topic in Databases
@Arnaud Bouchez I guess it all comes down to personal preference and possibility. There are cases when you are not allowed to choose the DB engine for your application, and there are cases when your application has to support some / most of them. My situation was exactly like this - someone decided to go with ONE DB engine only, and the whole software was built to use the engine-specific features. You don't necessarily have to agree with the design choices but you can only cook from what you have. As for preference I like the strict typing more but I can see the pros and opportunities of weak types (JSON is still the best for REST-like channels and local application settings store). I'll rather add a column to a database than to verify before each data access if the value exists, if it is a known (and accepted) type and if it has the information which I need. Especially if the user has the freedom or the possibility to access / change these objects (in my consideration if the software is running on their systems, they do). If you have the freedom and do not plan your database to grow too large - go for it. All I'm saying is that I already burned myself with this and therefore quickly became a no-go in future designs. -
Very strange issue, Thread exits without any notice
aehimself replied to dkprojektai's topic in Delphi IDE and APIs
This. I remember having a similar issue a couple of years ago calling .DLL exported functions when I switched from D7 to D10.2. The issue was memory allocation for a string (* SizeOf(Char) was not included) which lead to a nice and beautiful memory corruption. The application always crashed several functions later so it was a pain in the butt to find it. Anyways, memory corruption would indeed be my guess in this case, too. -
POWEREVENT, TIMECHANGE π I already had to make workarounds for these. Good to know, thank you very much!
-
I never had to do anything fancy - reply to stop, start, pause, resume and shutdown events. Just out of my own curiosity and education - what are these features?
-
How to determine a resource and / or Resource suffix
aehimself replied to alnickels's topic in Network, Cloud and Web
Ouch. Why I always tend to overcomplicate things? π This is the correct solution. -
is there any "currency to words" routine for Delphi?
aehimself replied to Attila Kovacs's topic in Algorithms, Data Structures and Class Design
if Num > 999999999 then raise Exception.Create('Can''t express more than 999,999,999 in words'); This made me giggle π Seriously though, ours is somewhat similar. It's not this sophisticated though. -
is there any "currency to words" routine for Delphi?
aehimself replied to Attila Kovacs's topic in Algorithms, Data Structures and Class Design
We did something like this in a commercial application: it only handles numbers up to 9999 but in multiple languages if I'm not mistaken. To be completely honest, it's quicker just to write your own from scratch which will satisfy your needs rather than to look for one. The code I was talking about is about 50-100 lines in Delphi... Due to it's commercial nature I'll not be able to share sniplets, but it's basically these rules in lots of "if" statements π -
Agreed, this is a possibility in most cases; I just don't see a reasonable chance when it comes to Windows Services. Even if Embarcadero would decide to re-write the logic, they'd probably keep the event handlers and the class name so it stays backwards compatible... I hope π if not, most of us will be in a big trouble π
-
When my applications stop processing Windows messages it's always a very long processing in the VCL thread. Like reconnecting to a database, refreshing a huge dataset or I simply messed something up and my code got in an endless loop π This is when correct logging can save your life: I'm usually logging when an action starts and when it ends. When the application freezes just check which action started, which did not report back as finished.
-
How to determine a resource and / or Resource suffix
aehimself replied to alnickels's topic in Network, Cloud and Web
Hello, I will be honest I don't understand the question correctly, but if you'd like to identify if the received string is a JSON or an XML, you can use this: Uses System.JSON; [...] Var x: TJSONValue; begin x := TJSONObject.ParseJSONValue('this is the received file'); If x = nil Then Begin // File is NOT JSON -> it is XML (or other webserver generated error page) End Else Begin // File is JSON, values can now be accessed by object "x" End; end; In the x = nil branch you could make an XML-to-object parsing to confirm if it's XML and simply stop processing if not. I never worked with XMLs from my codes so I have no knowledge on how to do that, though π -
I personally never used SvCom but even if it's unsupported I would not worry about it. The way Windows handles services (service control messages) did not and could not change as it would break backwards compatibility (you wouldn't be able to install / start a service on Windows 2003, only on 2019 - never seen that, unless it was an API dependency in the business logic). A component to create a service application mostly contains a code to handle these SCMs, which are the same since Windows 2000.
-
I wrote all of my Windows service applications based on Delphi's TService and I did not find any showstoppers which made me want to change it. It's robust, small and gets the job done quite well. A small tip though. Since service applications are hard to debug, I started to implement the whole business logic as a simple Class which is being created and destroyed based on what is happening with the service. Change the .DPR like this: If Not FindCmdLineSwitch('console', True) Then Begin If Not Application.DelayInitialize Or Application.Installing Then Application.Initialize; Application.CreateForm(TService1, Service1); Application.Run; End Else StartWithConsole(TMyServiceClass); ...where StartWithConsole is just a small procedure which creates a console window with AllocConsole, creates the service class, redirects the logging output to StdOut and handles the console handlers (like Ctrl-C, etc). This way there's only one executable, which can be started as a command line application for easy debugging and as a Windows Service as well. P.s.: don't forget about creating a custom message pump, some components rely on Windows Messages to work properly!
-
I just checked my old codes and yes - they do take effect after the broadcast was sent. Must have mistaken it with setting it somewhere else in Windows...?
-
Also please note that in Windows several environmental variables requires a logoff-logon for the changes to take affect (like %PATH%).
-
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!