⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wpw_wapi_res_95.html

📁 VC programing
💻 HTML
📖 第 1 页 / 共 2 页
字号:
<HTML>


<HR><A NAME=WINAPI_RES_EDITCONTROL>
Return to <a href="wpw_wapi_index.html#TOC">Table of Contents for this chapter</a><br>
<H4>Subject: Windows resource and Text EDIT control</H4><PRE>
Recently there was a discussion in comp.lang.pascal
regarding what appeared to be a limit on the 
number of TEdit controls that could exist 
within a Delphi application. The debate raged
as to whether it was a Delphi bug or
a Windows limitation. Accoringly I
would like to hear form those who know
what the real story is:

Briefly it was found that when a tabbed
notebook with approximately 150 TEdit
controls was made visible then the app
crashed with an EOutOfResources Exception.
This appeared to be a generic problem when
about 220 child windows were open on the
same app. However it appeared that there
were plenty of local and plenty of global
resoruces available both by the GetFreeSystemResources
functions and the ability to run other 
Windows apps.  Additionally there appeared to
be plenty of local system resources (stack,
local heap and static data) available.

What follows is the most recent posting 
regarding this issue. IF youve got any comments
I'd be interested to hear them:

--------------------------------------------
Hi Brad,
        Firstly let me say that
I spend most of my time in OSF/1 networking
so Im not a Windows guru rather more of a novice
so as I said this is a lot of conjecture.

        In article <3rm92c$7ct@nntpd.lkg.dec.com> you wrote:
        : After much discussion the problem has been found, many
        : thanks go to Chuck Jazdzewski from Borland.

        : A little explanation and then a solution. The following
        : is somewhat conjecture.

        : The real problem is the TEdit class which I presume
        : (I dont have source code) is based on the native
        : Windows Edit control. When each program starts

        It is not based on it, it is a Window's Edit control.
        The TEdit is ONLY an object "wrapper".

That could well be, as I dont have the source code for
the VCL library I cant confirm or deny this but I suspect
you are correct.

        : in Windows the USER.EXE module assigns a "secret"
        : 64k heap to store such things as windows handles,

        This does not happen when each programs starts, but
        when WINDOWS starts.  64k is ALL there is for ALL
        windows.

As I said i dont know ebnough to argue on this point
However two things are against what you say:

1: Borland Delphi team who are, you must admit,
preety familiar with Windows internals say not

2: When the problem happens I can still run many
other large applications in Windows without exiting
the problem causing app. It is implicit that
the problem is local to the App and is absolutely
NOT a global problem with Windows as there are
plenty of global resources to load and run other
apps when the problem IS occurring (see below).   

3: Both fixes presented solve the problem

        : menu handles and other data. This is not the
        : When components such as TEdit are contained on
        : a "persistant" item such as a notebook these
        : components do not go away while the parent form is       
        : still in existance.

        I'll look at the source code and see what I can find.      
        If they do not go away, WinSight should see them as
        child windows.

It does but I would appreciate any insight you can give
as I am reticent to invest any more time in the Delphi
port in case there are any more "gotchas" like this
one.

        : Now TEdit has a default string length of 255 characters, the
        : length is not a functionof the MaxSize property.
        : Guess where the string is stored? Give up? well
        : it is stored in the USER.EXE secret heap. 200

        This heap is hardly a secret.  The API function
        GetFreeSystemResources will tell you what is available.    

This function returns plenty of resources when the
problem happens. As I had the argument/discussion with Vince       
this is not the Global Windows heap which most
people know about nor is it the local 64k heap
allocated to each program. From what I can glen
this is a third heap that acts like a cache that
Windows allocates to each prog that it has running
and is NOT documented!!

        : or so TEdits and you have used up all your
        : USER.EXE heap.

        Absolutely false.  The Edit control global allocates       
        memory for it's storage.  Delphi may duplicate this
        but it would come out of the data segment or the stack     
        depending on how it is allocated.   The windows max length 
        is 64k (actually slightly less than) You can get 32k       
        without any work at all.  I have a program running now     
        with 4 or 5 64k edit controls open and still have plenty 
        of system resources.

Ok I will believe you. I think this discussion has pointed
out some serious problem with Delphi and/or Windows. Whatever      
the case it should be held in the public domain so
Ill will post this reply to the group for open discussion.
Like you I have other Windows apps which have 500+ child
windows with no problems, although they are not all Edit Controls. 


        : So the take home message is: TEdit is especially
        : dangerous in this regard because of its large
        : usage, use sparingly.       


        No it is not, see above.  One thing that may be happening  
        is that Delphi is reserving extra bytes in the window class
        which are stored in the user heap, but I find it hard to believe  

        that they are storing more than a few bytes this way.  Any 
        more would be absolutely stupid.

No you may be incorrect, you have missed the previous discussion,  
there is plenty of the following left over when the problem happens:

1: Local heap
2: local stack
3: data
4: global system resources

As to whether they are storing extra bytes in the class
I dont know, wouild have to have a look at the VCL source
when I can afford to buy it!!


        : You analized it correctly.  The TEdit is more than the 20 characters
        : but VCL can't do much about it since it is the Windows edit control.
        : We can't do much about how much it stores but you can change where it
        : stores the data.  Below is a new control TNLEdit (for non-local edit)
        : that stores the data in global memory instead of "local" storage.  If
        : you replace all you edit controls with this control won't run into
        : the problem.  I create several thousand of these edit controls where
        : I could only create 250 normal edit controls.

        This is different.  A normal edit control takes it's storage space
        from the parent window's data space.  (Not the "secret" heap).  The

do you mean the applications local heap instead of the "parent windows
data space" ?

        non-local edit control described below is merely an edit control  
        that stores it's data on the global heap.  The limit of 250 probably
        came from the 255 control limit of a dialog.  (Or the parent ran out
        of data space and could not create any more)  To create a control like
        this take a look at the DS_LOCALEDIT creation style and the
EM_SETHANDLE
        and the EM_GETHANDLE messages (yes, it's API time)

You lost me back at the train station :-) But I do know that this NOT
a local heap or a global resource probelm for the reasons stated above:

1: there is no local heap/stack shortage
2: there is no global resource problem

when the probelm is actually happening i.e. with out
closing the bombing app. I can even start a second instance
of the app which will "crash" at the same point.


        Having just looked at what they are doing below, I don't think that
        they have done it quite right.  You should pass the hiword of the 
        pointer returned by Globallock to LocalInit to create a data segment
        for the edit control to use.  They seem to have skipped that part.
        All of this is in a file called GLBEDIT.EXE at ftp.microsoft.com//
        softlib/mslfiles.  I am somewhat familiar with it because this is 
        the only way that I have ever found to get an edit control to hold
        more than 32k.  But then I have gotten a quite a few wrong answers
        from Borland Tech support.    

Ok thanks for your insights Brad, however both the fixes work for  
my purposes and definitely solve the problem.

Just out of interest my machine reports the following
resources when the problem occurrs while running
the app outside of Delphi:

free system resources:  50%
free gdi resources:     67%
free user resources:    50%
free local stack:       22k
free local heap:        11k
free global heap:       8M
largest global:         2M

As you can see there is no problem here
----------------------------------------

PS there were two fixes/workarounds for this problem:

1: Send a WM_CLOSE to each child Window as it becomes invisible
2: Rewrite the TEdit code to do a globalAlloc() for its text buffer

These are detailed in the series of articles in comp.lang.pascal
if interested. I think the real questions are:

1: Is there a third "secret" 64k heap used by Windows 

2: Where is the text for a TEdit (or an Edit control) stored.

3: Is ti possible to get an OutOfResources exception when 
   the GetFreeResources returns lots of spare space ?
   and if so how and why and which resource is in short supply ?

4: Is there a limit in how much of the 64k global pie an app can have ?

5: Does anyone know of any other instances where 220+ edit controls
   use up too much of anything ?.

Thanks for your time,

Jon

-- 
----------------------------------------------------------------------
Name:        Dr Jon Jenkins
Location:    Digital Equipment Corp, NaC, 
             Burnett Place, Research Park, 
             Bond University, Gold Coast
             QLD, AUSTRALIA 4229
Phone:       61-75-75-0151
Fax:         61-75-75-0100
Internet:    jenkinsj@ozy.dec.com

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -