12-14-2007 12:38 PM
12-14-2007 02:25 PM
Hi Cimteker,
I'm still a little confused as to what behavior you are seeing. The RunUserInterface function is responsible for running
the UI and pumping messages (i.e. issuing events to callback functions).
It doesn't return until you call the QuitUserInterface function. Now you mentioned a
different thread but didn't clarify what was running on that thread. There are
things to consider when using multiple threads with regards to RunUserInterface and QuitUserInterface. For example, it is not a
recommended practice to call QuitUserInterface and RunUserInterface in different threads. The best approach when dealing
with UIs and multithreading is to always process messages for the current
window in the same thread that created the window.
However, you could use the PostDeferredCall function which schedules CVI to call a specific
function at the next occurrence of GetUserEvent, RunUserInterface, or ProcessSystemEvents,By default, PostDeferredCall posts the call to the main thread
which called RunUserInterface. To schedule CVI to call a function in a thread other than the main
thread, use PostDeferredCallToThread. The function that is posted to the
main thread would then call QuitUserInterface . Refer to the The
LabWindows/CVI Function QuitUserInterface() Isn't Working KnowledgeBase for
information. This may or may not be applicable to your scenario as I'm not
fully clear on your problem.
Are you spawning off multiple threads?
Do you have multiple panels?
There is a variety of threading topics in the Library Reference >>
User Interface Library >>> Multithreading category in the NI
LabWindows/CVI. The topic Event Processing and Multithreading states
that in general, CVI invokes UI callbacks in the same thread in which you
create the panel or menu bar to which the callback event applies. This applies
to all controls on panel with a few exceptions that are listed in the help.
I assume you are using LoadLibrary and FreeLibrary for your DLL?
At what point in your code are you unloading the DLL (i.e. after RunUserInterface returns, before QuitUserInterface, etc)
Take a look at those topics in the help as they are really good.
Hope this helps!
Best Regards,
12-14-2007 03:02 PM
Hi Jonathan,
Thanks for your reply. I knew it would be difficult to explain. I'll take another stab at it.
I have a test executive that loads my dll. My dll contains test functions and a debugger. I ask the test executive to load my debugger. This is where RunUserInterface gets called, it's a callback to my dll by the test executive. Now the debugger is running. Everything is fine. I can close the debugger and the panel's callback function is called where it calls QuitUserInterface, all's well.
But my test executive's interface (GUI) is active, meaning I can press the X button and unload my dll. This is when the trouble starts. The panel's callback function is never called, I mean maybe it is but not with EVENT_CLOSE, and this is the event that I am handling.
Here's my callback function:
int CVICALLBACK Debugger_plCallback(int panelHandle, int event, void *callbackData, int eventData1, int eventData2)
{
switch (event)
{
case EVENT_CLOSE:
Dbg_Close();
QuitUserInterface(idDebugPanel);
break;
}
return 0;
}
The final result is that the dll does not get unloaded as I have some timers that are still ticking and they are not deactivated (normally Dbg_Close shuts them down). A person here that has more exeperience told me that it used to be different. When you called the debugger, it would not allow you to access the X to unload the dll, it would block the UI for the process that called it, that's why I it called it blocking. Is it possible that it works differently under CVI 8.5 that I am currently using?
I do not have any threads and I don't think I need them. Whatever I need the system to do can be achived with just one thread. I was thinking that a panel should behave like a modal dialog under Windows (it requires the user to interact with it before they can return to operating the parent application) . Can it be something wrong with the way I am calling it? Here's what the code looks like:
hDebugPanel = LoadPanelEx(0, "DebugPanel.uir", plDebugger, __CVIUserHInst);
Dbg_Init();
idDebugPanel = RunUserInterface();
DiscardPanel (hDebugPanel);
hDebugPanel = 0;
Thanks a bunch for your help again
J.
12-14-2007 04:11 PM
12-17-2007 08:00 AM
No, my test executive is not CVI based, it is Borland C++ based, so I do not have 2 panels loaded.
When I close the debugger panel EVENT_CLOSE event is being fired, as I call QuitUserInterface(0) inside EVENT_CLOSE handler EVENT_DISCARD event is fired. At least that's what I think the sequence of operation is. When I unload the dll, EVENT_CLOSE event is NOT fired, just EVENT_DISCARD. I tried putting my code in EVENT_DISCARD event handler but it crashes. I am thinking because it is too late, the interface is already distroyed, so my call to QuitUserInterface(0) crashes.
Yes, I am passing 0 to my LoadPanelEx call as I do not have a panel handle for my test executive, it is not CVI based.
Thanks for you help.
J.
12-17-2007 10:56 AM
12-17-2007 01:35 PM
12-17-2007 01:41 PM
I had a message box pop up in my handler:
switch (event)
{
case EVENT_DISCARD:
MessageBox(NULL,"EVENT_DISCARD","EVENT_DISCARD FIRED",MB_OK);
Dbg_Close();
QuitUserInterface(0);//The value passed to QuitUserInterface becomes the value returned by RunUserInterface
break;
case EVENT_CLOSE:
MessageBox(NULL,"EVENT_CLOSE","EVENT_CLOSE FIRED",MB_OK);
Dbg_Close();
QuitUserInterface(0);
break;
...
When I was closing my debugger I had EVENT_CLOSE first and then EVENT_DISCARD. When I was unloading it was just EVENT_DISCARD.
This may have something to do with how a particular application unloads a dll.
Thank you
J.
12-17-2007 03:22 PM
12-18-2007 08:04 AM
Hi Johnathan,
I think I have a native WIN32 message popup, I do not rememeber implementing anything custom.
As far as DLL_PROCESS_ATTACH for my DLLMain I cannot answer this question. Like I said it is an off-the-shelf test executive that we're using here, I do not have a source code and do not know how it handles dll load/unload.
I have a callback from my test executive on DLLUnload. Is there anything I can put there that could gracefully close the debugger (panel). If I can close it by pressing X in the right top corner I should also be able to close it programatically be calling a function.
Thanks for your help,
Jerry.