C and C++

Moderators: None (Apply to moderate this forum)
Number of threads: 28629
Number of posts: 94611

This Forum Only
Post New Thread
Single Post View       Linear View       Threaded View      f

Report
Will try/catch work with API functions? Posted by Sephiroth on 16 Jan 2009 at 9:37 AM
In my current project I create a few menus on the fly and have a LOT of "if" statements to handle the API functions failing. Is it possible to group these into a big "try" block?
try
{
  AppendMenu(this->hFileMenu, MF_ENABLED | MF_STRING, 1001, L"&Import");
  AppendMenu(this->hFileMenu, MF_ENABLED | MF_STRING, 1002, L"&Export");
  AppendMenu(this->hFileMenu, MF_ENABLED | MF_STRING, 1003, L"&Backup");
  AppendMenu(this->hFileMenu, MF_ENABLED | MF_STRING, 1004, L"E&xit");
}
catch
{
  while(GetMenuItemCount(this->hFileMenu) > 0)
    DeleteMenu(this->hFileMenu, 0, MF_BYPOSITION);

  return false;
}

This will save a TON of checking if it works. Note that "AppendMenu()" is of type "BOOL", not "bool". That means that it is an integer return value, not a single bit.

-Sephiroth
Report
Re: Will try/catch work with API functions? Posted by anthrax11 on 16 Jan 2009 at 7:56 PM
You could make arrays with the ID numbers and names and then run a loop
to create the items, sort of like this:
int i, ret;
UINT ids[]={1001,1002,1003,1004,0};
TCHAR* names[]={L"&Import", L"&Export", L"&Backup", L"E&xit"};

i=0;
while(ids[i])
{
  ret = AppendMenu(this->hFileMenu, MF_ENABLED | MF_STRING, ids[i], names[i]);
  if (ret == 0)
  {
    while(GetMenuItemCount(this->hFileMenu) > 0)
      DeleteMenu(this->hFileMenu, 0, MF_BYPOSITION);
    break;
  }
  i++;
}

Afaik Winapi functions don't throw C++ exceptions, except when you
crash the function by passing it an invalid pointer or something like that,
but I'm not entirely sure of this.
Report
Re: Will try/catch work with API functions? Posted by AsmGuru62 on 17 Jan 2009 at 3:35 AM
Catching depends on compiler options. As an example - there are few "exceptional" options in VS 2005 (I am not sure if your compiler has it). One of the options is to use SEH and one of the others is to use C++ exceptions. The SEH option will usually catch exceptions with the following code:
try
{
}
catch (...)
{
}

On the other hand - no need really to delete menu items if anything fails - just delete the whole menu with DestroyMenu().
Report
Re: Will try/catch work with API functions? Posted by Sephiroth on 17 Jan 2009 at 10:48 AM
I know, I use DestroyMenu() now. The thing is, my current code looks like this:
  //Attempt to add the import option
  if(!AppendMenu(this->hFileMenu, MF_ENABLED | MF_STRING, IDM_IMPORT, L"&Import"))
  {
    DestroyMenu(this->hFileMenu);
    DestroyMenu(this->hMainMenu);
    return false;
  }

  //Attempt to add the export option
  if(!AppendMenu(this->hFileMenu, MF_ENABLED | MF_STRING, IDM_EXPORT, L"&Export"))
  {
    DestroyMenu(this->hFileMenu);
    DestroyMenu(this->hMainMenu);
    return false;
  }

  //Attempt to add a separator
  if(!AppendMenu(this->hFileMenu, MF_SEPARATOR, 0, 0))
  {
    DestroyMenu(this->hFileMenu);
    DestroyMenu(this->hMainMenu);
    return false;
  }

  //Attempt to add the backup now option
  if(!AppendMenu(this->hFileMenu, MF_ENABLED | MF_STRING, IDM_BACKUP, L"&Backup"))
  {
    DestroyMenu(this->hFileMenu);
    DestroyMenu(this->hMainMenu);
    return false;
  }

This is a waste of space and there has GOT to be a better way to check for a single menu failing without a thousand "if" checks. This is actually only part of the code, and it's about double that for everything.
-Sephiroth
Report
Re: Will try/catch work with API functions? Posted by AsmGuru62 on 18 Jan 2009 at 5:58 AM

You need to use the error checking wisely. For example, if you logically think - you will see that AppendMenu() call will not involve any hardware interaction - it can fail only for TWO reasons: no memory and wrong HMENU passed to it.

I never seen a program fail due to memory limits (not recently, anyhow). Also, if you check the HMENU you passing once for all calls, then you are SURE - it will not fail.

If you still have a need to check each of these calls - there is a trick. The failing value for this function is FALSE. Which is ZERO! That means if you create a string of return values - its length (string length) will be EXACTLY equal to the number of times you call AppendMenu():

char strCheck [32];

strCheck [0] = (char) AppendMenu (...);
strCheck [1] = (char) AppendMenu (...);
strCheck [2] = (char) AppendMenu (...);
strCheck [3] = (char) AppendMenu (...);
strCheck [4] = (char) AppendMenu (...);
strCheck [5] = (char) AppendMenu (...);
strCheck [6] = (char) AppendMenu (...);
strCheck [7] = (char) AppendMenu (...);
strCheck [8] = 0;

if (lstrlen (strCheck) != 8)
{
    // Something failed in that "string"  of calls!
}


That works nicely for BOOL return values. Beware of handles. If returned handle is, say: 0x0FD7A300 - this will turn to zero once turned into char type, so the trick will fail miserably.
Report
Re: Will try/catch work with API functions? Posted by anthrax11 on 18 Jan 2009 at 3:48 PM
This is also possible:
int i = 0;
i += AppendMenu (...);
i += AppendMenu (...);
i += AppendMenu (...);
i += AppendMenu (...);
i += AppendMenu (...);
i += AppendMenu (...);
i += AppendMenu (...);
i += AppendMenu (...);

// boolean TRUE == 1, so i should equal 8
if (i != 8)
{
    // Something failed and returned 0!
}

Though I still can't figure out why my original suggestion of looping
through an array of menu items and checking for failure once per
iteration is any worse than these tricks
Report
Re: Will try/catch work with API functions? Posted by AsmGuru62 on 19 Jan 2009 at 5:11 AM
Your idea was great! Even less code!
Report
Re: Will try/catch work with API functions? Posted by Sephiroth on 22 Jan 2009 at 2:23 PM
I like that idea. I'll implement it the next time I work on the backup utility. I am working on my windowing library right now, and enjoying some VERY nice new wallpapers I just grabbed in KDE. Yeah, I'm a Linux-lover, but I have to stay in Windows to play my games! >.<

-Sephiroth



 

Recent Jobs

Official Programmer's Heaven Blogs
Web Hosting | Browser and Social Games | Gadgets

Popular resources on Programmersheaven.com
Assembly | Basic | C | C# | C++ | Delphi | Flash | Java | JavaScript | Pascal | Perl | PHP | Python | Ruby | Visual Basic
© Copyright 2011 Programmersheaven.com - All rights reserved.
Reproduction in whole or in part, in any form or medium without express written permission is prohibited.
Violators of this policy may be subject to legal action. Please read our Terms Of Use and Privacy Statement for more information.
Operated by CommunityHeaven, a BootstrapLabs company.