?
Solved

CImage::LoadImage() - preventing conflicts

Posted on 2006-05-25
13
Medium Priority
?
600 Views
Last Modified: 2013-11-20
I have an app that resides on two client computers (PC's), each having a mapped drive to a location where each app saves images to. They both talk to the same access database and place images into the same folder.

Generally it's working, except when both client apps end up trying to view the same image file at the same time.  

I use this to load an image into an HBITMAP:

m_hbmImage = (HBITMAP)::LoadImage(NULL, sPath,IMAGE_BITMAP,0,0,LR_CREATEDIBSECTION | LR_LOADFROMFILE);

How can I "wrap that" (or modify the paramaters some way I'm not aware of) so that if one client hasn't completed it's call to LoadImage on sPath, the other app won't try to until it's done?

I have a few ideas, not sure what's best or most appropriate.

One idea is to have a field "locked" in the database, and have each app lock/unlock before and after it loads, and check for a locked image first. That seems resource intensive, couldn't windows somehow tell if if a file is being accessed?

I also thought perhaps a Mutex or something, but that's for threads, and this is merely networked apps.

Can I somehow check the windows file attributes to see if it's being accessed?

thanks!

0
Comment
Question by:PMH4514
  • 6
  • 5
12 Comments
 
LVL 22

Expert Comment

by:mahesh1402
ID: 16761276
Have a look at LockFile() and LockFileEx() API functions..

http://msdn.microsoft.com/library/en-us/fileio/fs/lockfileex.asp?frame=true

-MAHESH
0
 
LVL 22

Expert Comment

by:mahesh1402
ID: 16761317
>>Can I somehow check the windows file attributes to see if it's being accessed?

One way is to first programatically create backup of your file.. then just try to delete that file if file is open and being accessed then due to sharing violation file will not get Deleted and your function will return false...otherwise file will get deleted as its not being accessed..then you may restore file from your backup.....

-MAHESH
0
 

Author Comment

by:PMH4514
ID: 16761357
thanks for the link. Your second response, seems kinda convoluted no? is that a standard practice?
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:PMH4514
ID: 16761381
I'm not sure the LockFile would work, or I'm just not understanding it.  The files themselves have read_only attributes on the storage computer. Each client is merely trying to call LoadFile with the pointing to it on a mapped drive (Each client maps to the same drive)
0
 
LVL 22

Expert Comment

by:mahesh1402
ID: 16761549
>>is that a standard practice?

NO obvisously thats not standard practise.....its just a way..

Trying to open file exclusively is probably the best way. If it's already open, your call will fail.

-MAHESH
0
 
LVL 22

Expert Comment

by:mahesh1402
ID: 16761602
One other way you can detect changes to a file such as access and last modified time by using FindFirstChangeNotification and FindNextChangeNotification. (These functions cause the calling thread to wait in an efficient wait state so it doesn't eat up CPU time.)  This doesn't really tell if the file is open.  

-MAHESH
0
 

Author Comment

by:PMH4514
ID: 16761925
how can I instruct LoadImage to attempt to open it exclusively?
0
 
LVL 22

Expert Comment

by:mahesh1402
ID: 16762377
what I mean to suggest is try to open that BITMAP file using CFile with CFile::shareExclusive mode if it fails that means File Is In Use.

'CFile::shareExclusive' mode Opens the file with exclusive mode, denying other processes both read and write access to the file. Construction fails if the file has been opened in any other mode for read or write access, even by the current process.

-MAHESH
0
 

Author Comment

by:PMH4514
ID: 16762496
"Construction fails if the file has been opened in any other mode for read or write access,"

even if that file is open by another computer all together?

If so that should work just fine.
0
 

Author Comment

by:PMH4514
ID: 16762900
I tried the following code,  and even when I had the bitmap file specified by a_sPath open in MS Paint, the first attempt at CFile::Open on it produced true.  Is Paint not a good test for having the file open??


      BOOL bOK = false;

      int timeOut = 5000;
      CFile sourceFile;

      while (!bOK && timeOut-- > 0 )
      {
            if (sourceFile.Open(a_sPath, CFile::shareExclusive))
                  bOK = true;

            Sleep(1);
      }

      sourceFile.Close();

      HBITMAP hBmp = (HBITMAP)::LoadImage(NULL, a_sPath,IMAGE_BITMAP,0,0,LR_CREATEDIBSECTION | LR_LOADFROMFILE);

0
 
LVL 45

Accepted Solution

by:
AndyAinscow earned 320 total points
ID: 16767474
Assuming that one call is failing (returning NULL from the LoadImage) because the other user is loading the bitmap just put it inside a loop.

m_hbmImage = (HBITMAP)::LoadImage(NULL, sPath,IMAGE_BITMAP,0,0,LR_CREATEDIBSECTION | LR_LOADFROMFILE);
int i = 5; //attempt five times
while(i && !m_hbmImage)
{
  m_hbmImage = (HBITMAP)::LoadImage(NULL, sPath,IMAGE_BITMAP,0,0,LR_CREATEDIBSECTION | LR_LOADFROMFILE);
  i--;
  sleep(5);  //wait a few milliseconds
}
if(!m_hbmImage)
{
  //tried multiple times to load it and still fails
  ...
}
0
 

Author Comment

by:PMH4514
ID: 17014852
whoops, was sure I closed this long ago. sorry!
0

Featured Post

Keep up with what's happening at Experts Exchange!

Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction: Displaying information on the statusbar.   Continuing from the third article about sudoku.   Open the project in visual studio. Status bar – let’s display the timestamp there.  We need to get the timestamp from the document s…
Introduction: Hints for the grid button.  Nested classes, templated collections.  Squash that darned bug! Continuing from the sixth article about sudoku.   Open the project in visual studio. First we will finish with the SUD_SETVALUE messa…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
Are you ready to place your question in front of subject-matter experts for more timely responses? With the release of Priority Question, Premium Members, Team Accounts and Qualified Experts can now identify the emergent level of their issue, signal…
Suggested Courses
Course of the Month17 days, 3 hours left to enroll

862 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question