I'm wondering if it's possible to bypass the OutputDebugString? I'd like the OutputDebugString output showing up in DebugView and not in the internal Delphi Event Viewer window. But i can't find a way to tell Delphi not to swallow the OutputDebugString. Any ideas?
regards
That is not possible.
OutputDebugString sends string to debugger (as its name suggests). There can be only 1 active debugger per process. You run your application under Delphi - Delphi got the messages, since its a debugger. You run your application outside Delphi - DebugView can access them, since no debugger claimed it.
However: WHY do you need this? Just disable other types of events in Delphi event log - and you'll get the same functionality as DebugView has.
I think there is no way around this. The situation is still the same in Delphi 2009. You should submit a feature request: http://qc.embarcadero.com
I'm wondering what the advantage instead of Delphi's internal event log window should be?
Instead of DebugView you can try to use Process Monitor and its new "debug output" capability. It does not use OutputDebugString, it uses its own API, and there's also a Delphi wrapper here. You can use Process Monitor filtering features and Delphi won't trap that messages - but it's not a generic features as those of OutputDebugString.
Disabling "output messages" in the Event Log properties does not work?
Not what the original question asked, I realise, but it's worth taking a look at CodeSite from Raize Software. It takes OutputDebugString to a whole new level. Messages (can) get directed to a CodeSite viewer which is roughly equivalent to a highly souped up DebugView. Well worth every penny IMHO.
Related
I'm wondering if it's possible to bypass the OutputDebugString? I'd like the OutputDebugString output showing up in DebugView and not in the internal Delphi Event Viewer window. But i can't find a way to tell Delphi not to swallow the OutputDebugString. Any ideas?
regards
That is not possible.
OutputDebugString sends string to debugger (as its name suggests). There can be only 1 active debugger per process. You run your application under Delphi - Delphi got the messages, since its a debugger. You run your application outside Delphi - DebugView can access them, since no debugger claimed it.
However: WHY do you need this? Just disable other types of events in Delphi event log - and you'll get the same functionality as DebugView has.
I think there is no way around this. The situation is still the same in Delphi 2009. You should submit a feature request: http://qc.embarcadero.com
I'm wondering what the advantage instead of Delphi's internal event log window should be?
Instead of DebugView you can try to use Process Monitor and its new "debug output" capability. It does not use OutputDebugString, it uses its own API, and there's also a Delphi wrapper here. You can use Process Monitor filtering features and Delphi won't trap that messages - but it's not a generic features as those of OutputDebugString.
Disabling "output messages" in the Event Log properties does not work?
Not what the original question asked, I realise, but it's worth taking a look at CodeSite from Raize Software. It takes OutputDebugString to a whole new level. Messages (can) get directed to a CodeSite viewer which is roughly equivalent to a highly souped up DebugView. Well worth every penny IMHO.
I'm using delphi 7.
I need to log to a file the complete informations of any exception that occurs.
Normally I use Eurekalog. This wonderful product shows a dialog with all the stack trace information and many many others for debugging purpouse.
I need to access this informations Eureka log gives me (really I need just the stack trace) because I need to send them in a syslog deamon.
Is there a way to access the information from the Eureka log programmatically ?
I can use the bare delphi 7 or Eurekalog 6.1
Handle the OnExceptionNotify event. In your event handler, do whatever you want with the AExceptionInfo.CallStack property, such as saving it to disk or sending it to some other process. Note that EurekaLog already saves bug reports to disk by default, so if that's all you want to do, you don't need any special code.
Use RegisterEventExceptionNotify to register your event handler, or use a TEurekaLogV7 component. For details and general information on handling EurekaLog events, see the documentation for the EEvents unit.
OnExceptionNotify occurs for unhandled exceptions. If you want to be notified of any exception, including ones that eventually get handled within your program, then you should use the OnRaise event instead.
Most people simply use JCL Debug.
Discussions on TSynlog
http://blog.synopse.info/post/2011/04/14/Enhanced-logging-in-SynCommons
or by Hallvard Vassbotn
http://hallvards.blogspot.co.at/2008/03/tdm9-exceptional-stack-tracing-hvest.html
I'm currently trying to develop a project based upon Firemonkey. I'm using Firemonkey for it's UI features as the project consists of many smaller applications, each with a 3D aspect to it. I'm currently only developing/deploying to Windows with the FMX framework, but may go cross-platform at a later date.
I've gotten around most issues I've come across by building a VCL Windows application in the background to perform a very specific action, and then building an FMX frontend. However, this is only suitable when you only want to execute the application to perform that action it's designed to do, and thus can execute the application with parameters. In one of the applications, i've come upon the need to use messages (or something similar). For example, in my FMX application, if i click "button1", i want it to send a message to the background VCL application to perform "action1", rather than execute it with parameters.
A good example could be using the VCL TMediaPlayer in the background application, with the front-end FMX application being used to display the information and provide control of play, pause, etc. Such that it essentially becomes an FMX UI with VCL ability.
I've so far been unable to find anything on how messages (e.g. in VCL, they'd be done with "SendMessage" or "PostMessage" or something similar) are handled with Firemonkey, either through the local help file, or through extensive Googling. Everything i've turned up has been related to email (presumably because of the word "Message" in most of my search terms).
Can anyone point me in the right direction on how messages would be handled with Firemonkey/FMX?
Regards,
Scott Pritchard
My understanding is that Firemonkey is not based on traditional windows, so sending window messages to Firemonkey controls is not usually an option. Although some controls do use windows (most notibly, TCommonCustomForm), so you can use the FmxHandleToHWND() function in the FMX.Platform.Win unit to extract an HWND from a TFmxHandle when needed. I have no clue how to receive and custom process window messages in FMX controls, if that is even possible.
Firemonkey under Windows has access to the Win32 API, so there should be nothing stopping you from sending window messages to other windowed controls, such as your VCL UI. Include the Winapi.Windows unit in your uses clause to access Win32 API functions, just like you would in a VCL application.
UPDATE: because FireMonkey does not expose access to messages that are sent to a Form's window, you have to manually subclass the window in order to receive messages before FireMonkey sees them. You can override the Form's CreateHandle() method, call the inherited method first to create the window, then use FmxHandleToHWND() to get the HWND that you can subclass. Be sure to also override the DestroyHandle() method to remove the subclass before then calling inherited to release the HWND.
Currently, FireMonkey doesn't have a message handler that you can use to send and post messages.
There is a possibility of hooking things up using listeners like FireMonkey works internally, but none of it is documented.
So, instead, here's what I've done:
I created my own custom "message" class. I create instances of the class and add them to a thread-safe list from any thread I need to. On the main thread, I have a timer that checks the list and processes the "messages".
The Delphi debugger is great for debugging linear code, where one function calls other functions in a predictable, linear manner, and we can step through the program line by line.
I find the debugger less useful when dealing with event driven gui code, where a single line of code can cause new events to be triggered, which may in turn trigger other events.
In this situation, the 'step through the code' approach doesn't let me see everything that is going on.
The way I usually solve this is to 1) guess which events might be part of the problem, then 2) add breakpoints or logging to each of those events.
The problem is that this approach is haphazard and time consuming.
Is there a switch I can flick in the debugger to say 'log all gui events'? Or is there some code I can add to trap events, something like
procedure GuiEventCalled(ev:Event)
begin
log(ev);
ev.call();
end
The end result I'm looking for is something like this (for example):
FieldA.KeyDown
FieldA.KeyPress
FieldA.OnChange
FieldA.OnExit
FieldB.OnEnter
This would take all the guesswork out of Delphi gui debugging.
I am using Delphi 2010
[EDIT]
A few answers suggested ways to intercept or log Windows messages. Others then pointed out that not all Delphi Events are Windows messages at all. I think it is these type of "Non Windows Message" Events that I was asking about; Events that are created by Delphi code. [/EDIT]
[EDIT2]
After reading all the information here, I had an idea to use RTTI to dynamically intercept TNotifyEvents and log them to the Event Log in the Debugging window. This includes OnEnter, OnExit, OnChange, OnClick, OnMouseEnter, OnMouseLeave events. After a bit of hacking I got it to work pretty well, at least for my use (it doesn't log Key events, but that could be added).
I've posted the code here
To use
Download the EventInterceptor Unit and add it to your project
Add the EventInterceptor Unit to the Uses clause
Add this line somewhere in your code for each form you want to track.
AddEventInterceptors(MyForm);
Open the debugger window and any events that are called will be logged to the Event Log
[/EDIT2]
Use the "delphieventlogger" Unit I wrote download here. It's only one method call and is very easy to use. It logs all TNotifyEvents (e.g. OnChange, OnEnter, OnExit) to the Delphi Event Log in the debugger window.
No, there's no generalized way to do this, because Delphi doesn't have any sort of "event type" that can be hooked in some way. An event handler is just a method reference, and it gets called like this:
if assigned(FEventHandler) then
FEventHandler(self);
Just a normal method reference call. If you want to log all event handlers, you'll have to insert some call into each of them yourself.
I know it is a little bit expensive, but you can use Automated QA's (now SmartBear) TestRecorder as an extension to TestComplete (if you want this only on your system, TestComplete alone will do). This piece of software will track your GUI actions and store it in a script like language. There is even a unit that can be linked into your exe to make these recordings directly at the user's system. This is especially helpful when some users are not able to explain what they have done to produce an error.
Use WinSight to see the message flow in real time.
If you really want the program to produce a log, then override WinProc and/or intercept the messages in Application.
The TApplication.OnMessage event can be used to catch messages that are posted to the main message queue. That is primarily for OS-issued messages, not internal VCL/RTL messages, which are usually dispatched to WndProc() methods directly. Not all VCL events are message-driven to begin with. There is no single solution to what you are looking for. You would have to use a combination of TApplication.OnMessage, TApplication.HookMainWindow(), WndProc() overrides, SetWindowsHook(), and selective breakpoints/hooks in code.
Borland's WinSight tool is not distributed anymore, but there are plenty of third-party tools readily available that do the same thing as WinSight, such as Microsoft's Spy++, WinSpector, etc, for tracking the logging window messages in real-time.
As an alternative, to debug the triggered events use the debugger Step Into (F7) instead of Step Over (F8) commands.
The debugger will stop on any available code line reached during the call.
You can try one of the AOP frameworks for Delphi. MeAOP provides a default logger that you can use. It won't tell you what is going on inside an event handler but it will tell you when an event handler is called and when it returns.
When we created our program, it closed properly under XP, but under Vista, even though the program is closed, the process is often still running until I open task manager and manually kill the process.
Any suggestions on how to make sure this is closed when we close the program? What a pain.
Mark Gundy
www.magchat.com
The debugger will be your friend here. Step through the shutdown until you get stuck. That'll be the best bet.
But... assuming for some reason the debugger is affecting the behaviour, or can't be used for some other reason:
A few earlier replies suggest using FastMM. This has been the default memory manager for delphi since D2006. You can try flipping on the options to report memory leaks... but that'll only work after you've finished shutting down the process, which is what isn't working. :) So I doubt it will help you much in this case. The full version of FastMM, as opposed to the standard one packaged with delphi, might have some other helpful features... But I can't recall any that would help here.
To inspect your app while it's stuck, you could try the sysinternals tools, like Process Explorer & Process Monitor. Process Monitor may show you if it's choking on any ACCESS_DENIED errors, etc, and the stack trace at the time of the error. Process Explorer could be especially useful, by listing all the handles your process is still holding open, and allowing you to view the stack of all its living threads. A familiar function or two, in the stack traces of any hung threads, may send you hunting in the right area.
Are you using multiple threads? If one of them can't terminate for some reason, it'll hang the cleanup process.
The short answer is that you have a bug in your application. So, have you tried debugging it?
If you have the Delphi IDE installed on Vista, run the app from the IDE and break it when it 'hangs'. Chances are that you'll have a thread that hasn't terminated itself, and the VCL is waiting for it to finish.
If you don't have the IDE installed on vista, you can probably use the remote debugger, but I'm not familiar with this.
What do you call to close your program? Try using
Application.Terminate;
To force all forms to close and the process to exit.
It probably means you have some memory leak - some resource is not released.
If your application instantiates COM objects, check that you properly close them.
If you use older version of Delphi, you can try to locate possible memory leaks with FastMM
Edit, examples as requested:
I had two situations where application sometimes would stay resident in memory after exit. Both applications would disappear from taskbar, but they would be still active - visible in task manager. Both applications were created with Delphi 7.
First application has one main window with panel in which ather forms are embedded. Each form is standard TForm. Each form is created first time user requests it. Everything worked without problems in test environment, but users reported that from time to time, application would remain in memory, usually after longer usage - when user displayed almost all of the forms in application. I could not replicate this behavior while testing. That was first time I found out about FastMM. When I first run application with FastMM, it reported that some of forms embedded in main form were not released. This version was tested at user site and it turned out that 2 forms that have lots of data aware components would hang up and prevent application from exiting. When I added code that makes sure that all created forms are released before main form, application never hung up on exit.
Second example is application that uses COM to activate GIS editor (Geomedia) to manipulate some map data. I imported type libraries and created Delphi wrapper object. Some of created objects were not freed when application ends. Application icon disappeared from task bar, but application and GIS editor were still active and visible in task manager. Again, it did not happen every time application run. I included FastMM in application and it reported that some objects were not freed. I made sure that every created object gets freed and after that application did not hang on exit any more.
... and if you need to close single form, then use:
Form.Close;
GUI AND HANDLER DELETED. Reference and some parts of memory is left to provide access to variables, constants, etc.
If you need to hide ( something like Minimize, only GUI is cleared ) form, then:
Form.Hide;
GUI is cleared, leaving internal resources untoauched ( reference, handler, memory )
If form is dynamic ( created at runetime ), then use:
Form.Destroy;
ALL RESOURCES WILL BE CLEARED FROM MEMORY, leaving reference and handlers attached so you could access its location in memory.
If form is dynamic and you will not use it for the same interface, then:
Form.Free;
ALL RESOURCES, REFERENCES, HANDLERS ARE DELETED. I recommend to use this to VCL TComponent class, not for TForm class.
Also, there is Form.FreeAndNill, but my guess that it deleted all memory and loaded handlers, only allowing to use same memory space in the same interface again... (I might be wrong though).
P.S. I hope I am not writing wrong things as the last time I read the theory was a long, long time ago... and it was about Destructor DESTROY in general ...
P.P.S ALSO PLEASE BE CAREFUL if you're writing a Vista-ready app - that it includes UAC Handling with manifests / runtime code and SuperBar compatibility requirement. Also Aero requires some additional megabytes to output file due its Aero feature ... :P