Categories: MSDN / DotNet / Java / Scripts / Linux / PHP Ask - La ask - La Answer

GetItem Causes Crash in ComCtl32.dll

Hello,

I have a function that accepts a CWnd* and converts it to a CTabCtrl*. I
then try the GetItem member function, and it causes the application receiving
the message to crash. The exception occurrs in the ComCtl32.dll module.
This also happens with other controls such as CTreeCtrl and CToolBar. What
is happening here and how do I avoid this problem?? Any help you can give
is appreciated. Some code follows:

void MyFunction(CWnd* Win, int id)
{
CTabCtrl* Tab = (CTabCtrl*)Win;
TC_ITEM* Item = new TC_ITEM;
char Text[255];

Item->mask = TCIF_TEXT;
Item->pszText = Text;
Item->cchTextMax = sizeof(Text);

/* Execption Occurs Here (In Win's Parent App, not this application) */
Tab->GetItem(id, TC_ITEM);
}
[817 byte] By [Johnny] at [2007-11-10 12:51:14]
# 1 Re: GetItem Causes Crash in ComCtl32.dll
Hello,

> void MyFunction(CWnd* Win, int id)
> {
> CTabCtrl* Tab = (CTabCtrl*)Win;
> TC_ITEM* Item = new TC_ITEM;
> char Text[255];
>
> Item->mask = TCIF_TEXT;
> Item->pszText = Text;
> Item->cchTextMax = sizeof(Text);
>
> /* Execption Occurs Here (In Win's Parent App, not this application) */
> Tab->GetItem(id, TC_ITEM);

Tab->GetItem(id, Item);

Note: Do not forget to "delete Item"

--
ChainsaW
Stanislav Simicek at 2007-11-11 20:41:43 >
# 2 Re: GetItem Causes Crash in ComCtl32.dll
Thank you very much for your response. However, I dont think I made my situation
very clear, and I appologize for that.

The code I listed was kind of a pseudo-code to show what I was doing. I
am indeed passing the 'Item' structure to Tab->GetItem, and I am deleting
the structure after use. These were mis-types on my part on my original
post.

However, my code does compile and link properly, so I am sure it is not a
syntax problem. Also, there are no known memory leaks in my application,
so all memory allocated is freed.

The problem I am encountering only happens when I try to get structured information
from a control (such as a TC_ITEM, TV_ITEM, etc...). And, the problem does
not seem to originate from my application, but from the application I am
interfacing with (Win). Actually, the exception occurs in ComCtl32.dll.

All other methods of getting the information (ie SendMessage, and several
'experimental' methods) cause the same failure. And it happens on all applications
I interface with that have these controls. I am pretty much stumped. I
hope there is another way of getting structured information from a control.

Thanks for our help, and I appreciate any other help you can give.

-Johnny

"Stanislav Simicek" <Stanislav.Simicek@sasprg.cz> wrote:
>Hello,
>
>> void MyFunction(CWnd* Win, int id)
>> {
>> CTabCtrl* Tab = (CTabCtrl*)Win;
>> TC_ITEM* Item = new TC_ITEM;
>> char Text[255];
>>
>> Item->mask = TCIF_TEXT;
>> Item->pszText = Text;
>> Item->cchTextMax = sizeof(Text);
>>
>> /* Execption Occurs Here (In Win's Parent App, not this application) */
>> Tab->GetItem(id, TC_ITEM);
>
>Tab->GetItem(id, Item);
>
>Note: Do not forget to "delete Item"
>
>--
>ChainsaW
>
>
Johnny at 2007-11-11 20:42:40 >
# 3 Re: GetItem Causes Crash in ComCtl32.dll
Sounds like you're essentially trying to pass a pointer to a structure that
lives in one process to a control that lives in another process, no? The
problem is that the address you're passing to that other process is invalid
as far as that other process is concerned (each process has its own virtual
address space, right?).

For the basic common controls, Windows performs under-the-hood marshaling
(i.e. copying the data from one process to another), but for the Treeview
and Listview it does not. So the crash is occurring when the other app tries
to write to the pointer (invalid from its perspective) you pass it.

The solution, assuming you're dead-set on doing this, is to use special Windows
APIs to allocate a block of memory that both processes can "see." This is
a bit of a pain, but fortunately there's an article somewhere in the MSDN
library--by Jeffrey Richter I believe, or perhaps it's Jeff Prosise--that
shows the exact code to do it. Sorry I don't know the exact reference.

HTH,

Steve Zimmerman
CodeMarine, Inc.
Steve Zimmerman at 2007-11-11 20:43:42 >
# 4 Re: GetItem Causes Crash in ComCtl32.dll
Johnny,

: The problem I am encountering only happens when I try to get structured
information
: from a control (such as a TC_ITEM, TV_ITEM, etc...). And, the problem
does
: not seem to originate from my application, but from the application I am
: interfacing with (Win). Actually, the exception occurs in ComCtl32.dll.

Is the code that has this problem in an ActiveX component (DLL, OCX, EXE)?
If so, is it running in-process or out-of-process? The most likely cause for
an exception would be that the application is in a different process from
your own, and so, what is a pointer to a valid TC_ITEM in your address space
is likely to be a pointer to nowhere (or at least to something that is not a
TC_ITEM).

Even if it's not in a component, you can't just pass a TC_ITEM (or similar)
*that you declared* and get information about a window in another process...
just try sending a TCM_GETITEM message to the taskbar! (Trust me, it does
*not* work unless you somehow place yourself in the shell's address space)

You didn't say what exception you were receiving, but I bet it would be
c0000005 (Access Violation). If so, this (passing an "invalid" pointer) is a
good suspect. Adding C++ new and delete to the mix, oh my... :-)

Hmm... that's another thought - which RTL are you linking to (Debug
Multithreaded etc)? It *has* to be the same (or similar) as the other EXE.
Oh wait, that's for a standard DLL. :-(

: All other methods of getting the information (ie SendMessage, and several
: 'experimental' methods) cause the same failure. And it happens on all
applications
: I interface with that have these controls.

This makes it rather clear, IMO, that you're trying to send the structure
across process boundaries... what happens if you send a message such as
TCM_GETITEMCOUNT, LVM_GETITEMCOUNT etc? The return values of those messages
are returned to you as the return value of SendMessage (and the MFC
equivalents), and AFAIK, those are safe.

--
Damit Senanayake | damit@mvps.org
Please reply to newsgroups, not by e-mail.
http://members.xoom.com/damit | {http,ftp}://damit.dyndns.org (experimental)
ICQ: 6930718
Damit Senanayake at 2007-11-11 20:44:49 >
# 5 Re: GetItem Causes Crash in ComCtl32.dll
Steve and Damit,

Thank you both for your help! I will try your suggestions soon and let you
know the results (via a post here).

Thanks again!!

-Johnny

"Damit Senanayake" <damit@mvps.org> wrote:
>Johnny,
>
>: The problem I am encountering only happens when I try to get structured
>information
>: from a control (such as a TC_ITEM, TV_ITEM, etc...). And, the problem
>does
>: not seem to originate from my application, but from the application I
am
>: interfacing with (Win). Actually, the exception occurs in ComCtl32.dll.
>
>Is the code that has this problem in an ActiveX component (DLL, OCX, EXE)?
>If so, is it running in-process or out-of-process? The most likely cause
for
>an exception would be that the application is in a different process from
>your own, and so, what is a pointer to a valid TC_ITEM in your address space
>is likely to be a pointer to nowhere (or at least to something that is not
a
>TC_ITEM).
>
>Even if it's not in a component, you can't just pass a TC_ITEM (or similar)
>*that you declared* and get information about a window in another process...
>just try sending a TCM_GETITEM message to the taskbar! (Trust me, it does
>*not* work unless you somehow place yourself in the shell's address space)
>
>You didn't say what exception you were receiving, but I bet it would be
>c0000005 (Access Violation). If so, this (passing an "invalid" pointer)
is a
>good suspect. Adding C++ new and delete to the mix, oh my... :-)
>
>Hmm... that's another thought - which RTL are you linking to (Debug
>Multithreaded etc)? It *has* to be the same (or similar) as the other EXE.
>Oh wait, that's for a standard DLL. :-(
>
>: All other methods of getting the information (ie SendMessage, and several
>: 'experimental' methods) cause the same failure. And it happens on all
>applications
>: I interface with that have these controls.
>
>This makes it rather clear, IMO, that you're trying to send the structure
>across process boundaries... what happens if you send a message such as
>TCM_GETITEMCOUNT, LVM_GETITEMCOUNT etc? The return values of those messages
>are returned to you as the return value of SendMessage (and the MFC
>equivalents), and AFAIK, those are safe.
>
>--
>Damit Senanayake | damit@mvps.org
>Please reply to newsgroups, not by e-mail.
>http://members.xoom.com/damit | {http,ftp}://damit.dyndns.org (experimental)
>ICQ: 6930718
>
>
Johnny at 2007-11-11 20:45:43 >