LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

Bitmap: out of memory error

I've searched this forum and found some others who have similar issues, but none of the fixes I've tried actually work. We're running a sequential test program that prompts the user at each step to make connections, adjust the scope, etc. We're now trying to upgrade a little to show images instead of just text. I have added a panel with a "picture" control. Here's the code:

 

promptPanel = LoadPanel (0,"test.uir",PROMPT);
errorCode = GetBitmapFromFile(pathName,&promptBitmap);
SetCtrlBitmap(promptPanel,PROMPT_PICTURE,0,promptBitmap);
DiscardBitmap(promptBitmap);
SetCtrlVal(promptPanel,PROMPT_ERROR,errorCode);
InstallPopup(promptPanel);

MessagePopup("...","...");

RemovePopup(promptPanel);

 

 As suggested in a post here, I tried the following at the end of the test sequence:

 

promptBitmap = NewPanel(0,"",0,0,10,10);
DiscardPanel(promptBitmap);

 

What happens is that the test runs through about twice with no problems, then GetBitmapFromFile() returns -12 every time afterwards. It works fine again after stopping and restarting the program, for about 2 cycles. I ran Process Explorer to watch the memory usage through 3 trials. The attached zip file contains screen shots of the graphs. The vertical red line on each graph indicates the first bitmap load that failed.

 

Are there any better tools for diagnosing what's happening? The program displays the same images repeatedly, so the images that failed the last time through worked fine the first few times. 

 

The image files are .jpg, ranging in size from 0.7 to about 1.5MB

 

0 Kudos
Message 1 of 7
(4,124 Views)
Actually, I figured out what's going on. I was creating an instance of the panel every time and never discarding it. When I replace RemovePopup() with DiscardPanel(), everything works fine.
0 Kudos
Message 2 of 7
(4,122 Views)

Since the image doesn't change frome time to time, you may additionally improve program behaviour avoiding the continuous loading and discarding of the prompt panel but using HidePanel and DisplayPanel instead: this will reduce disk access to load the image.

What I am thinking of is a procedure like this:

 

Start of the program

   Preparing the equipment

   Revising testing parameters

   ...

Start of testing session:

   Load prompt panel and image from disk

 Execute test 1

   InstallPopup (promptpanel);

   MessagePopup (..., ...);

   HidePanel (promptpanel);

 Execute test 2

   InstallPopup (promptpanel);

   MessagePopup (..., ...);

   HidePanel (promptpanel);

.

.

.

 Execute test n

   InstallPopup (promptpanel);

   MessagePopup (..., ...);

   HidePanel (promptpanel);

End of testing session

   DiscardPanel (promptpanel);

.

.

.

End of program



Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
0 Kudos
Message 3 of 7
(4,106 Views)

Additionally, instead of InstallPopup - MessagePopup - RemovePopup sequence you may consider to add the text of MessagePopup to the panel with the image together with a single "Ok" button without associated callback and execute the following:

 

InstallPopup (promptpanel);

GetUserEvent (1, 0, 0);

RemovePopup (0);

 

This will avoid to show both the popup image and the popup message on the screen one on top of the other.



Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
0 Kudos
Message 4 of 7
(4,105 Views)

My first attempt used a similar process to what Roberto suggested, just without the GetUserEvent. I figured that a popup panel would work similarly to a MessagePopup, but I was wrong. I have sort of combined several replies here:

 

 

if(!promptPanel)loadPromptPanel(); ... SetCtrlBitmap(promptPanel,PROMPT_PICTURE,0,promptBitmap); DiscardBitmap(promptBitmap); ResetTextBox(promptPanel,PROMPT_TEXT,"MessageHere"); DisplayPanel(promptPanel); GetUserEvent(1,0,0); HidePanel(promptPanel);

 This works pretty well. There is a command button on promptPanel that has no callback routine but generates an event to satisfy GetUserEvent. The panel is loaded once and just updated each time it's called.

 

Thank you for all the suggestions!

 

 

0 Kudos
Message 5 of 7
(4,058 Views)

I encountered a problem with this code today. The firt prompt would immediately disappear, as though the user had clicked on it. I created some variables to pass into the function for the panel and control return values and set a breakpoint on the HidePanel() line. It turns out that one of the textboxes on the main panel was receiving an event. The way this code works, the user enters 2 serial numbers into textboxes on the main panel and clicks a "Begin Tests" button. That button's callback routine does a few housekeeping things and then starts the test routine. The first user prompt is one of the first things the test routine does. I suspect that the textbox's "LostFocus" event is being delayed somehow, so that it satisfies the GetUserEvent(1,0,0) function. When I set the breakpoint, I saw that the integer returned for the control that initiated the event matched whichever text box had focus when "Begin Tests" was clicked. I inserted a loop which seems to have fixed the problem by verifying that the "OK" button on the prompt panel is what triggered the event:

 

DisplayPanel(promptPanel); wait = 1; while(wait) { GetUserEvent(1,&eventPanel,&eventControl); if((eventPanel == promptPanel) && (eventControl == PROMPT_PromptOK))wait = 0; } HidePanel(promptPanel);

 

Is it normal for a "Lost Focus" event to behave this way or am I off track here? It seemed to work fine yesterday without the while loop but not today.

 

 

0 Kudos
Message 6 of 7
(4,037 Views)
GetUserEvent only receives the commit events, it is not reactive to lost focus and other events. If you want a control to be active but do not fire the commit event set its mode to 'normal'. What may be happening if your controls are in the default hot state is that the user fills the first texbox and when he presses the enter key or switches to another control the textbox fires a commit event that is trapped by GetUserEvent. Setting it to normal prevent the commit event to be fired.


Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
0 Kudos
Message 7 of 7
(4,033 Views)