|
No need to interact with the desktop for hidden windows.
That's only if you want a user to see the windows, which is really frowned upon
from services going forward with Vista+.
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
|
Hello,
long title, short story: a rather old third-party library uses the following code to register its own edit control class:
static const TCHAR BASED_CODE szEdit[] = _T("GXEDIT");<br />
WNDCLASS wcls;<br />
if (!::GetClassInfo(hResource, szEdit, &wcls))<br />
{<br />
VERIFY(::GetClassInfo(NULL, _T("edit"), &wcls));<br />
<br />
wcls.style |= GX_GLOBALCLASS;<br />
wcls.hInstance = hResource;<br />
wcls.lpszClassName = szEdit;<br />
<br />
AfxRegisterClass(&wcls);
This works fine unless XP themes are enabled.
If they are and I use GetWindowText(CString-variable) with this edit control, the CString destructor causes a heap corruption because ::GetWindowTextLength reports less bytes than ::GetWindowText actually receives, and thus CString::GetBufferSetLength allocates not enough memory.
Is there a simple solution to change the above code so that this GXEDIT works with XP themes?
I already tried rewriting it using WNDCLASSEX instead, but that didn't help.
adTHANKSvance, Jens
|
|
|
|
|
Are you sure there is such a bug affecting GetWindowTextLength ? I cannot find related info.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
|
|
|
|
|
Part of this third-party library is a grid control, and the problems occurs when a GXEDIT control is created in-place to edit the contents of a cell.
The cell contains a 4-digit number, and the value returned by GetWindowTextLength is 12.
But only if I discard this value and reserve 25 bytes or more in CString::GetBufferSetLength, the heap doesn't get corrupted.
It's strange, but I think this is only a side effect of some error in the class registration.
If I don't use the XP visual styles for this app (no manifest file), everything works fine.
Other edit controls that are of the systems standard "edit" class type, work ok with or without styles enabled...
Regards, Jens
|
|
|
|
|
Maybe its a Unicode/ANSI issue.
The third party control may be using Unicode. Windows Unicode (UTF-16) uses 2 bytes to represent each character.
Try changing your GetWindowText to GetWindowTextW and see what happens, perhaps you need a CStringW.
Best Wishes,
-Randor (David Delaune)
|
|
|
|
|
The control does not use unicode, I have checked that. As I wrote, the problem only occurs if I enable XP visual styles and themes for the application by including a manifest file in the executables directory.
I already tried to write replacements for Get/SetWindowText:
void CGXEditControl::GetWindowText(CString& s)<br />
{<br />
if (IsThemeActive())<br />
{<br />
const int nLen = ::GetWindowTextLengthW(m_hWnd);<br />
CStringW sW;<br />
::GetWindowTextW(m_hWnd, sW.GetBufferSetLength(nLen), nLen+1);<br />
sW.ReleaseBuffer();<br />
<br />
s = sW;<br />
}<br />
else<br />
{<br />
CEdit::GetWindowText(s);<br />
}<br />
}<br />
<br />
void CGXEditControl::SetWindowText(const CString& s)<br />
{<br />
if (IsThemeActive())<br />
{<br />
CStringW sW(s);<br />
::SetWindowTextW(GetSafeHwnd(), sW);<br />
}<br />
else<br />
{<br />
CEdit::SetWindowText(s);<br />
}<br />
}
This prevents the heap corruption, but then the edit control contains a lot of unreadable stuff like arabic letters even though the debugger shows that sW seems to contain a correct string like "1120".
The problem seems to be the registration process of the class GXEDIT.
In CGXEditControl::CreateControl, if I replace the class name "GXEDIT" with the standard "edit" class in the call to CEdit::Create, everything works!
But I don't know what side effects this will have for the rest of the library , so I want to avoid this workaround if possible.
BTW, this library is a very antique version of Stingray's Objective Grid, dated 1997 .
Regards, Jens
|
|
|
|
|
Friends,
Do you have any smart idea to display animated gif on the status bar,
Thax
|
|
|
|
|
you'd better search for using AVIs rather than GIFs...
|
|
|
|
|
|
Search! There's lots of samples out there for rendering animated GIFs.
For example: Adding GIF-animation using GDI+[^]
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
I have created a worker thread to connect to a data server. The thread needs to wait a few seconds and exit if no data arrives (i.e. server is not online). I need to trap the thread exit code so my main thread can know if the workher thread terminated with an error. I have the following code:
<br />
static UINT Connect(void* p_this);<br />
UINT Connect();<br />
<br />
<br />
UINT Client::Connect(void* p_this)<br />
{<br />
<br />
Client* pClient = (Client*)p_this;<br />
pClient->Connect();<br />
<br />
}<br />
<br />
UINT Client::Connect()<br />
{<br />
<br />
CDataServer pServer = new CDataServer();<br />
<br />
........<br />
<br />
int nError = pServer->Connect();<br />
<br />
if ( nError != 0 )
return nError;<br />
<br />
.......<br />
<br />
}<br />
From the documentation I know I can use GetExitCodeThread to get the error code but where is the best place to put this? Should I post an exit message to the main thread and read the code there? Are there any other solutions that would be better?
Thanks.
|
|
|
|
|
masnu wrote: so my main thread can know if the workher thread terminated with an error.
What error? Use of thread exit codes are most often replaced with a form of communication of your own design. You are doing Object Oriented Programming aren't you?
led mike
|
|
|
|
|
The exit code I want is the one I have defined as nError in the above example. Based on that number I can determine why the thread exited.
|
|
|
|
|
From your code, I can say that you need:
1. return the error code in your thread function Connect(void* param)
2. From the main thread you can call GetExitCodeThread
Better solution is something like Mike suggested, define an interface to receive the error or success is much better.
God bless,
Ernest Laurentin
|
|
|
|
|
Your assumption is correct. You can return nError and then read that number via GetExitCodeThread from the main thread.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
|
|
|
|
|
|
O M G
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
I am coding under vc 6.0
every time I debug, I find that if a list is pointed by the pointer,
I can only see the first content of the list in the watch window, any ideas how to watch all the list ?
PS. some say we can see them in a memory window but it is too hard to read.
some say I can indicate the specific index of the list ,say list[5], but I want to see all the content in a list.
|
|
|
|
|
a pointer is only an address in memory.
if you handle an array, you actually use a pointer to the 1st element.
the VC6 debugger is not very powerful (actually, VC6 itself is far outdated by its new versions).
so if you want to see the other elements, you have to specify yourself the address of the element you need to watch AFAIK...
|
|
|
|
|
toxcct wrote: the VC6 debugger is not very powerful (actually, VC6 itself is far outdated by its new versions).
so if you want to see the other elements, you have to specify yourself the address of the element you need to watch AFAIK...
you are correct, But viewing the List items is very simple from VC6.0, we don't want to explicitly specify the address of the next element, it shows tree view in the watch window and expands the list if the first element is in the watch window.
struct ListNode
{
int iData;
struct ListNode *pNext;
};
int main(int argc, char* argv[])
{
struct ListNode Head, Middle, Tail;
Head.pNext = &Middle;
Middle.pNext = &Tail;
Tail.pNext = 0;
return 0;
}
I can view the list items in the above program as tree view in the watch window of VC6.0, even VC6.0 supports drag and drop variable to watch window.
|
|
|
|
|
I know what is a linked list, but I don't think the OP is using them at all.
hence my reply, refering to arrays and pointer arithmetic. I think he used the term "list" when he wanted to say "array"...
|
|
|
|
|
toxcct wrote: I think he used the term "list" when he wanted to say "array"...
struct ListNode list[3];
struct ListNode *plist = list;
still i can view as tree control of array element with tree labels like [0], [1], [2] .. in VC6.0 watch window
when watching variable as "list" and "plist,3"
|
|
|
|
|
I think in VC6, you can type something like: 'list,m' in the watch window
This will show you the entire memory. VS2003, 2005, 2008 supports this.
God bless,
Ernest Laurentin
|
|
|
|
|
thanks , you answer is right.
|
|
|
|