Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Problem with Open-Save Dialog boxes under Windows 7

I am using Delphi 2010. I have to set UseLatestCommonDialogs to False and additionally set ofOldStyleDialog property of Open and Save dialogs to true if I want that Open and Save Dialogs works in Windows 7 (otherwise they do not open at all). It is also true that I reserve quite a lot of space for a stack:

{$M 16384, 60048576}

since I use recursive algorithms on large datasets. Now I wonder what is the problem:

  1. New dialogs seem very space consuming, sometimes they work at the beginning and after a set of open and save dialogs executions it does not open dialogs any more (maybe also dialogs do not free memory after they are executed?)

  2. Is there a bug in Windows 7?

Anybody else experienced a similar problem?

It looks a little strange to work on Windows 7 with ancient dialogs (they are even older that XP style, I think they look like in Windows NT).

Any suggestion will be very appreciated.

Thanks in advance.

like image 346
Petra Avatar asked Dec 13 '22 19:12

Petra


1 Answers

The default stack space allocation specified by $M is global to all threads in the process that don't specify their own specific requirements. 60M is a lot for this, far more than almost any stack will ever grow to.

The File dialogs are essentially a hosted version of Windows Explorer. They load up shell extensions into your process for things like thumbnails, column handlers, context menus, etc. As Windows grows more featured, both MS and third parties feel free to use more and more resources - including threads - to add more info asynchronously, without blocking the UI. A simple test with notepad.exe on my Windows 7 64-bit machine shows that it has 1 thread before the dialog, but 19 threads while the dialog is open. In a 32-bit process with a default stack reservation close to 60M, that would want to reserve over 1G, or over half the total address space accessible to 32-bit applications by default. If there's much data being worked with in the application at all, it's very easy to see one running out of address space through memory fragmentation - all the code from the EXE, system DLLs, etc. needs to fit in there somewhere too. 60M is simply too high a default stack reservation to expect to work without problems.

Have you considered moving your deeply recursive computations in a thread you create? You'd need to use BeginThread() from System directly though, in order to explicitly specify the stack reservation.

Alternatively, is it possible to try reducing the stack usage of your algorithms? If you're allocating records or arrays on the stack, consider allocating them dynamically. If you have a function which recurs a lot (nested deeply) and has a lot of local variables, consider creating a record containing the locals and allocating it dynamically. If you're depending on the recursion to sequence work (e.g. depth-first traversals of trees / graphs), consider using the recursion simply to sequence work (e.g. add nodes to a list), and do the real processing iteratively. And if necessary, look at redoing the algorithm to work with an explicit stack. Another advantage of having an explicit stack is that you can trivially switch to breadth-first when desired, by using a queue instead of a stack, a one-liner if the stack and queue implementations use a polymorphic interface.

like image 77
Barry Kelly Avatar answered Dec 28 '22 06:12

Barry Kelly