|
Thanks for the feedback, but I was looking for something that would work on both NT and 9x.
There are quite many apps out there that work on 95/98, so it must be possible. As the apps are fairly small I guess it doesn't take an awful lot of code to make it work.
I'll keep searching, if you got an idea please tell me.
Thanks in advance
|
|
|
|
|
In Win9x it's completely unsupported. I've seen references to apps being _really_ ugly and to "switch desktop" they just grab a handle to any other apps window and move it to e.g. "appWnd.currpos - screenWidth", but I'd say yo get no friends from that approach even that it appears to work.
Now you know how some others do it. I just hope you don't do it yourself...
And even if you do, you'd have to track e.g. ALT+TAB to either not display the apps on "another desktop", or to swith desktop when alt-tabbing to an app on "another desktop".
|
|
|
|
|
Okay, thanks.
I guess I have to do it in the dirty way, as there appears to be no proper solution.
But as the desktop is a class of some sort it should be possible to create an array of them. I wonder why it isn't an array of desktops in the first place....
|
|
|
|
|
Hello there,
This isn't so much a problem (because I've got a solution for it) but I would like to know why it has happened in the first place. I've made use of a CPropertySheet control in one of my applications, it has two tabs (CPropertyPages) on it inherited from dialogues as CPropPage1 and CPropPage2 etc., pretty standard MFC via MSDN stuff. The sheet is constructed using AddPage (I think it's called that) not member variables in the CPropertySheet, everything works just perfectly, it constructs, shows and all the controls work great.
Now, when a button on the first property page is clicked, some extended processing needs to occur so I launch a worker thread and do some work. This works great too. Recently I added some options on the second property page and needed to make use of them during the extended processing thread on the first property page - still with me?
I wrote code (quickly guestimated) something like this:
void PropPage1::ButtonClick()
{
AfxBeginThread( Thread, this );
}
UINT Thread(LPVOID pParam)
{
CPropPage1 *caller = (CPropPage1 *)pParam;
CPropPage2 *options = NULL;
CPropertySheet *parent = NULL;
if(caller)
{
parent = (CPropertySheet *)GetParent();
if(parent) options = parent->GetPage(1);
... on and on - the rest doesn't matter.
}
return( preset_errorcode_from_somewhere );
}
Does that look OK? The reason I stop here is because at the "..." I get an Access Violation from CPropertySheet::GetPage(...) - the exact violation is from a CPtrArray I believe. No matter how many variations I do on this code, the same thing always happens. I might add that GetPageCount() correctly returns 2 indicating that there are two pages available.
The EXACT same code does not crash, if it is called from the CPropPage1::ButtonClick() handler instead of the worker thread. Now I'm aware that the code isn't exactly thread safe but should it really be crashing? I aren't aware of the behind the scenes operation, but obviously something is crossing a boundary somewhere. Why? My solution was to pass pointers to the PropertyPages via a structure into the thread and that works fine. The problem would seem to be a fault with the way GetPage(...) works because all of the other CPropertyPage members appear to function perfectly.
Just curious to know if anyone has a potential explanation for this behaviour?
Jon.
|
|
|
|
|
The problem is a very frequent one, and stems from the fact that CWnd -derived objects do funny things across threads. The explanation is a little long, please bear with me:
Given a Cwnd , its associated HWND handle is simply stored in the m_hWnd member. The other way around, obtaining the associated CWnd from a given HWND , is not that simple. There's no easy way to have Win32 store some pointer to the CWnd inside the data hold for a particualr HWND . To work around this problem, MFC guys decided to keep a global map of HWND s to CWnd pointers. Now comes the key point: for historical and performance reasons, this HWND to CWnd map is not unique, but instead each thread has its own, stored in so called thread local storage (TLS). In your particular case, the worker thread is given a pointer to CPropPage . So far so good. But when GetParent is called, the following sequence of events happen:- Win32
::GetParent is called, returning a valid HWND .
- The associated
CWnd is sought for, and as there is none local to this thread, a mock-up one is created (and inserted into the map). This object is not the CPropertySheet you began with. And the rest is easy. GetPage fails because it is issued on a CWnd constructed out of nothing, with no information about the original CPropertySheet (apart from being associated to the same HWND .)
Calls to methods of caller will work OK nevertheless, as this time caller is actually the real object.
The moral of this story is: don't pass CWnd pointers across threads.
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
How can I make a Combo Box uneditable. ie The user will not be allowed to type characters into it, only select something from the list
|
|
|
|
|
use the CBS_DROPDOWNLIST style instead of CBS_DROPDOWN .
--------
Well actually they are sort of interesting Nish, on Nudes
|
|
|
|
|
|
Hello,
The MSDN docs don't say how to respond when the serialization tries to serialized an unsupported version (see code snippet). Any ideas?
void MyObj::Serialize(CArchive& ar)
{
if (ar.IsLoading() == TRUE) {
int nVersion = ar.GetObjectSchema();
switch (nVersion) {
case 1:
ar >> m_id;
break;
// unknown version
default:
--> WHAT TO DO HERE????
break;
}
}
else {
ar << m_id;
}
}
|
|
|
|
|
WHAT TO DO HERE????
Throw an exception?
|
|
|
|
|
MSDN doc about CArchive::Serialize features this interface:
virtual void Serialize( CArchive& ar );
throw( CMemoryException );
throw( CArchiveException );
throw( CFileException ); which means that the framework expects the method to throw any of the exceptions listed above. In your particular case, CArchiveException is the appropriate one to throw, with the m_cause member set to CArchiveException::badSchema .
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
I have an application that is very memory intensive being used with other applications that are also very memory intensive. I execute the code that allocates memory in a try/catch block so that I catch any problems that may occur. The problem is that when I try to display a message box to inform the user what happened, my application crashes when MessageBox ultimately calls AfxCallWndProc with a NULL pointer. After looking in wincore.cpp, I was able to see the problem is the FromHandlePermanent call in AfxWndProc returns NULL, and AfxCallWndProc proceeds to used that NULL pointer to call WindowProc. Since the window pointer is NULL, the WindowProc call crashes my app. Is there any way around this short of try/catching all of my AfxMessageBox calls???
|
|
|
|
|
Try using a raw call to Win32 MessageBox instead.
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
::MessageBox and AfxMessageBox both have the same problem.
|
|
|
|
|
How come? MessageBox cannot fail in MFC module wincore.cpp , as it has nothing to do with MFC.
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
That's what I thought. I tried using ::MessageBox(m_hWnd, "Error message...", "MyApp", MB_OK|MB_ICONEXCLAMATION). My application is an MFC dialog application and I get the following stack
AfxCallWndProc(CWnd * 0x00000000 {CWnd hWnd=???}, HWND__ * 0x01c305c0, unsigned int 134, unsigned int 0, long 21629170) line 215 + 3 bytes
AfxWndProc(HWND__ * 0x01c305c0, unsigned int 134, unsigned int 0, long 21629170) line 368
AfxWndProcBase(HWND__ * 0x01c305c0, unsigned int 134, unsigned int 0, long 21629170) line 220 + 21 bytes
USER32! UserCallWinProc@20 + 24 bytes
USER32! DispatchClientMessage@20 + 47 bytes
USER32! __fnDWORD@4 + 34 bytes
NTDLL! KiUserCallbackDispatcher@12 + 19 bytes
USER32! DispatchClientMessage@20 address 0x77e13974
USER32! MB_DlgProcW@16 + 23 bytes
USER32! UserCallWinProc@20 + 24 bytes
USER32! DefDlgProcWorker@20 + 129 bytes
USER32! DefDlgProcA@16 + 33 bytes
USER32! UserCallWinProc@20 + 24 bytes
USER32! CallWindowProcAorW@24 + 61 bytes
USER32! CallWindowProcA@20 + 25 bytes
_AfxActivationWndProc(HWND__ * 0x014a08f2, unsigned int 272, unsigned int 38734006, long 15133252) line 405
USER32! UserCallWinProc@20 + 24 bytes
USER32! SendMessageWorker@20 + 188 bytes
USER32! InternalCreateDialog@28 + 2472 bytes
USER32! InternalDialogBox@24 + 161 bytes
USER32! SoftModalMessageBox@4 + 1399 bytes
USER32! MessageBoxWorker@4 + 302 bytes
USER32! MessageBoxExW@20 + 82 bytes
USER32! MessageBoxExA@20 + 111 bytes
USER32! MessageBoxA@16 + 36 bytes
MyFunc() calls messagebox here!
|
|
|
|
|
Never thought about it! This (fascinating) stack dump shows that MessageBox is executed in the context of the local message pump. If one considers it carefully, it makes a lot of sense after all.
Well, if it's lack of memory what's causing the error in AfxCallWndProc (which I'm far from sure), you might try reserving some safeguard memory that is released on the catch block just before calling AfxMessageBox . Please tell us if this works (in case you decide to test it.)
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
|
Just a thought here - I think it might not be a good idea to use a messagebox in this context. I've worked on code that had some very strange things happen when message boxes were invoked 'asynchronously' wrt the main user gui.
Consider what would happen if a 'proper' message box were on screen (by 'proper' I mean used in response to a user 'action' - validation etc) and another thread popped up a message box. First, neither mb will have proper app modality, allowing the user to do all manner of 'things they shouldn't do'. Also, the serialization of messages in the queue seems to get messed up with in ways that are almost impossible to trace.
You could ship a 'debug' app - which would enable you to use an assert dialog, but I think its better to have some designated status bar or dialog for this type of alert.
Just my 2 cents, and I could be missing something.
|
|
|
|
|
Hi,
Does anyone now how to debug a VC++ COM component that is a Pipeline component in a Commerce Server 2000 pipeline
Cheers
Ollie
|
|
|
|
|
Create an application that will call the pipeline. That is what we do with our pipeline.
Michel
It is a lovely language, but it takes a very long time to say anything in it, because we do not say anything in it, unless it is worth taking a very long time to say, and to listen to.
- TreeBeard
|
|
|
|
|
Hello, not sure where to ask this and it's probably a stupid question but here goes:
I currently use Visual c++ 6.0.
If I purchase and install Visual Studio .net will my projects still compile in vc 7 or will I need to make changes?
I really don't want to have to learn C# or anything else at this point so is there any other advantage to using VC 7?
Ground Zero Tech-Works
http://www.ayanova.com
|
|
|
|
|
J Cardinal wrote:
f I purchase and install Visual Studio .net will my projects still compile in vc 7
Yes,there is no problem.
Mazy
"The path you tread is narrow and the drop is shear and very high,
The ravens all are watching from a vantage point near by,
Apprehension creeping like a choo-train uo your spine,
Will the tightrope reach the end;will the final cuplet rhyme?"Cymbaline-Pink Floyd
|
|
|
|
|
Yes,there is no problem.
This is simply not true. There are reports of numerous projects that don't convert/compile. The problems range from project not converting as it should and MFC changes, to display of (terminal) compiler bugs in MSVC7.
This is not something I'm making up, MS themselves acknowledge these problems.
Not to mention the MSVC7 bug in ATL that makes it uncompilable. :->
|
|
|
|
|
hmmmmmm,Can you tell me some of them or show me the link?
Mazy
"The path you tread is narrow and the drop is shear and very high,
The ravens all are watching from a vantage point near by,
Apprehension creeping like a choo-train uo your spine,
Will the tightrope reach the end;will the final cuplet rhyme?"Cymbaline-Pink Floyd
|
|
|
|
|