|
Bram van Kampen
|
|
|
|
|
The fact you have been programming for years and the weird behaviour leads me to ask. The usual trap for someone of that experience and first moving into multitasking is not knowing when to use the word "VOLATILE" in front of a variable declaration.
So lets ask the obvious do you know when you have to use "VOLATILE" in some instances and why. The corollary to that is are you sure you haven't missed any in your code given your symptoms.
In normal single thread work you may only have ever run across the word when directly accessing hardware ports but it is far more critical in multitasking. You get symptoms very similar to what you describe.
In vino veritas
|
|
|
|
|
Well,
I know and use 'volatile' (where appropriate). It is essentially a compiler directive to tread carefully when optimising.
It indicates that an agent of which the compiler is not aware can change the value unexpectedly. (which could include other threads). First of all, one can not really rely on this for synchronisation, (One does not know when the monitor thread is interrupted, and the Other thread changes the value.) Furthermore it is quite inefficient as a synchronisation method. It typically means burning CPU Cycles waiting for something to happen. The better way is to put the thread to sleep, by the use of something like WaitForSingleObject(). That means that the CPU Cycles, in stead of being burned, can be used to speed up the printing of that 40 page report in Excell that is churning in the background. By using other synchronisation objects, such as CriticalSections, Mutexes and Semaphores (I prefer the SDK Versions, as the MFC versions are really Crap in MFC42), you can Manage and Control access to sections of code and GLOBAL and STATIC variables
Note that the Stack is thread safe, as in Windows, every thread has it's own private stack. Globals and Static Data however is stored on the same heap to which is available to all threads, however, not so easily by hardware threads, but that's a (very long) story for another day
Well, I'm 99.9% Sure that the use of 'volatile' is not at issue here, but I will certainly keep your much valued comment in mind
Kind Regards
N.B.
I Like your Signature
Bram van Kampen
|
|
|
|
|
You said
"Furthermore it is quite inefficient as a synchronisation method. It typically means burning CPU Cycles waiting for something to happen. The better way is to put the thread to sleep, by the use of something like WaitForSingleObject()."
First the method is not necessarily inefficient (it can be a lot faster than alternatives) and you can not use WaitForSingleObject to solve the problem in any way because the problem is you don't know when the change will occur. WaitForSingleObject hangs around and waits when you know a CHANGE OF SOMETHING MUST OCCUR. That function is of no use for the sort of problem you are dealing with it is used more for asynchronous transfers. The next part is correct.
Sychronization is the issue and CriticalSections, Mutexes and Semaphores are the only real way to get around it but THEY CAN BE EXTREMELY INEFFICIENT. A well used volatile with careful coding around the variable can save lots of messing around with synchronization in the simplest situations which is often 90% of cases. It is however NO GUARANTEED FIX you still have to understand what your threads are doing with memory access, the when where and how factors.
This statement by you => "All worked to perfection when I built a Skeleton Application, of essentially blank Dialogs.
Started to fill in Details, Controls, etc, and the App Clock Ticks are no longer recognised."
That tends to suggest you have a synchronization issue because your message posts are going AWL. The app clock tick should be picked up and delivered by DispatchMessage and it can't get lost unless something is going wrong with the memory .... It is delivered to a window based on handle. I would start with following the code for that tick message because it should be dead easy to put a watch on and see where it is getting dispatched to and why it is failing.
In vino veritas
|
|
|
|
|
I am trying to build an MFC application the uses a form with two panes, one for controls and the other for an OpenGL graphics window. I followed 2 code project for this task.
1. 15338/SDI-with-split-window by kencocomputers
2. Setting up OpenGL in an MFC control from codeguru C10975
The split window application part worked fine but I cannot initialize the openGL context in the graphics pane.
The classes in the project are:
1. CAboutDlg
2. CFormLeft
3. CFormRight
4. CMainForm
5. CMFC_SurfaceViwerApp
6. COpenGLControl
CFormLeft and CFormRight views are created in the CManFrame function
BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
Specifically with:
if (!m_wndSplitter.CreateView(0, 0, RUNTIME_CLASS(CFormLeft), CSize(300, 100), pContext) ||
!m_wndSplitter.CreateView(0, 1, RUNTIME_CLASS(CFormRight), CSize(100, 100), pContext))
{
m_wndSplitter.DestroyWindow();
return FALSE;
}
My question is how to actually implement the OpenGL Window; I suspect that it requires some code like:
void COpenGLControl::oglInitialize()
{
static PIXELFORMATDESCRIPTOR pfd =
{
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA,
32,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
16,
0, 0, 0, 0, 0, 0, 0,
};
hdc = GetDC()->m_hDC;
m_nPixelFormat = ChoosePixelFormat(hdc, &pfd);
SetPixelFormat(hdc, m_nPixelFormat, &pfd);
hrc = wglCreateContext(hdc);
wglMakeCurrent(hdc, hrc);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClearDepth(1.0f);
glFrontFace(GL_CCW);
glCullFace(GL_BACK);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
OnDraw(NULL);
}
But how does it activate? I put a call inside the oglCreate() function but nothing happened.
void COpenGLControl::oglCreate(CRect rect, CWnd *parent)
{
CString className = AfxRegisterWndClass(CS_HREDRAW |
CS_VREDRAW | CS_OWNDC, NULL,
(HBRUSH)GetStockObject(BLACK_BRUSH), NULL);
CreateEx(0, className, L"OpenGL", WS_CHILD | WS_VISIBLE |
WS_CLIPSIBLINGS | WS_CLIPCHILDREN, rect, parent, 0);
m_oldWindow = rect;
m_originalRect = rect;
hWnd = parent;
oglInitialize();
}
I would appreciate any help I can get. Thanks
John H. Chumley
|
|
|
|
|
Since all this code is based on CodeProject articles you may get more help by using the forum at the end of the article. Also, you should not call OnDraw() directly, you should use the standard Windows rules for updating Windows. See UpdateWindow function (Windows)[^].
|
|
|
|
|
I have a existing function to communicate between Java and c++Activex I am using DISP_FUNCTION_ID. I need to add a default argument to the function so that I can call it from Java script. Is is possible to do so ?
Not sure how to add a default argument in the function which is accessed by using DISP_FUNCTION_ID. Need some assitance.
Thanks in advance.
|
|
|
|
|
Well,
I Know very little about Java, and this is an MFC/CPP Forum. In CPP a default argument is declared in the function declaration in a class, as in
class CMyClass{ int MyFunct(int Arg=0);};
This is a Declaration that MyClass has a Method named'MyFunct', which returns an int, and Optionally takes a Parameter (Arg),
and, that when I call this function without a parameter, that 0 will be assumed. You make those declarations in a 'Header File'
You Implement the function in the Implementation File,(Typically a CPP File) were you actually Implement the function:
int MyClass::MyFunct(int Arg)
if(Arg==0)return 1;
else return 2;
}
The above means that when using the class, you write:
MyClass myclass;myclass.MyFunct();myclass.MyFunct(0);myclass.MyFunct(12);
Your Marshalling Software beteween Java and CPP should give more details.
Bram van Kampen
|
|
|
|
|
Hi,
I have a console application that spawns a childprocess
I am initially able to get the MainFrame Window in the console app thru EnumThreadWindows
Later I create a modeless Dialog in the childprocess for which I would like the to get the HWND handle
I am running this code (both apps) under the Visual Studio debugger
So I can see when the child process creates the modeless dialogbox
I then step thru (under VS debugger) both GetWindow(MainFrame,GW_CHILD) and EnumChildWindows
and neither API return anything
|
|
|
|
|
What on Earth are you trying to Achieve!
Writing a Console Program trying to spawn an MFC Wnd App is not really possible, or desirable!
The only practical way this is possible is by the Console Program calling the Standard 'C' 'system(...)' function to launch the Windows App.
If you are looking for tooling to restart a misbehaving Windows Program, you came to the right door. I have just that.
The actual code is proprietary, but I can explain how it works.
Regards,
Bram.
Bram van Kampen
|
|
|
|
|
First of I apologize maybe I should spent more time looking up critical section
As all it is thread synchronization
I am a MainFrame assembler programmer by trade and was trying to learn new technology
I picked windows I wrote a front end for this C console program originally the code
was C then I re-wrote it in MFC C++ I am sure a more experienced C++ programmer could
have done a better job. But this was my way of learning
I created the Windows MFC C++ program with CreateProcess
|
|
|
|
|
ForNow wrote: I ended up having the debugging modeless dialog box HWND being returned to me from the SendMessage to the main window as both LRESULT and HWND are both 64 bits wide running 64 bit mode as I don't want the console program to sit around and wait for a response (and hold it up) I do a PostMessage from the console program
Thanks I (like Bram) am confused as to what you are trying to do here. Or indeed what your point is of using a console application to launch a Windows application, to launch a modeless dialog.
|
|
|
|
|
Without sight of your code it is anyone's guess what you are doing wrong.
|
|
|
|
|
I have three suggestion/comments:
1.) You said quote: "Later I create a modeless Dialog in the childprocess for which I would like the to get the HWND handle."
Doesn't matter which create method you use you get the handle back right then ... so why don't you hold it??????
2.) Like others I wonder why you are using MFC at all which will be problematic why would you not just use the WIN32 API.
3.) If GetWindow(MainFrame,GW_CHILD) and EnumChildWindows are returning false the your created window isn't parented
to the window at all. It's most likely parented to the desktop and again go back to number 1 above show us the how
you created the modeless dialog and check you gave it a parent.
The key point here is a show use the lines of code around the modeless dialog creation call.
In vino veritas
|
|
|
|
|
I did use GetWindow and got NULL. I was able to get Window Handle by doing a SendMessage to the other app as the return Value is From the other Window App (not Windows like PostMessage) I returned the dialog window in LRESULT
Thanks
|
|
|
|
|
Well,
Using MFC, in a multithreaded environment, communication via SendMessage(...) is an essential.
Trying to sculpt WDK Messages for my own purpose. Use WM_USER+x, Major Crash,turned out, WM_USER+x was already used by MFC42 in a control I used in my Dialog!
has Anyone any idea what the range of messages are used or reserved by MFC in general, and what the Real Message range is, available to MFC developers.
++"#define WM_MFC_USERS 0xABXD1234
Or, something of that kind in some header somewhere. If this is the case, please let me know the Name and the value of the macro is.
Regards
Bram van Kampen
|
|
|
|
|
WM_USER is obsolete. Use WM_APP instead. Or better use registered messages.
A good description about this topic can be found in the CodeProject article Message Management[^].
|
|
|
|
|
WM_USER+x should only ever be used inside a single application, as it is free to use by everyone. Using it in a driver is almost bound to cause tears before bedtime.
[edit]
WM_USER (Windows)[^] and WM_APP (Windows)[^] list the rules.
[/edit]
|
|
|
|
|
Thanks,
I am aware of RegisterMessage(...) etc, but have always considered it as a canon to shoot a fly. It may be the better Idea for future, particularly after the nightmare I encounter now. Your idea of attaching a GUID is particularly fetching.
WM_USER +X, It worked for me many a time in the past. I can now see the flaws
Thanks,
Bram.
Bram van Kampen
|
|
|
|
|
|
It looks like a reply to my answer posted to yours inadvertently.
|
|
|
|
|
I don't know what Bram is smoking these days, but I think he should cut down.
|
|
|
|
|
Hi,
Good to talk again.
My header files do not provide a macro for WM_APP. Maybe you could let me know for future reference, if it is a single value. Also AOP has advised me to Register a Windows Message. Probably the way forward for the Future.
Thanks for your contribution.
Bram.
Bram van Kampen
|
|
|
|
|
|
Is a crtical section a way of ensuring the your code runs synchrounsly as window message processing seems to take precedence in code execution
|
|
|
|
|