00001
00002
00003
00004
00005
00011 #ifndef HMENU_H
00012 # define HMENU_H
00013
00014 #ifndef HWIDGET_H
00015 # include <HWidget.h>
00016 #endif
00017
00018
00019
00032 class HMenu : public HWidget,
00033 public HID
00034 {
00035 typedef HWidget base_class;
00036 static StringPtr ClassName(void) { return "HMenu"; }
00037
00038 protected:
00039 friend class HMenuBar;
00040 typedef widget_menu_item * MenuItemPtr;
00041 typedef HMap<int32, MenuItemPtr> MenuItemMap;
00042
00043
00044
00045 protected:
00046 MenuItemMap m_items;
00047
00048
00049
00050 public:
00051 HMenu(int32 id = 0) : HWidget(), HID(id)
00052 { }
00053
00054 virtual
00055 ~HMenu(void)
00056 { Destroy(); }
00057
00058
00059
00060 public:
00072 ErrCode
00073 AddItem(int32 nCmd, StringPtr pstrLabel, uint32 uFlags = 0, bool bEnabled = true)
00074 {
00075 widget_menu_item dummy;
00076 const uint32 kMaxItemLen = sizeof(dummy.text);
00077
00078 ErrCode ec = HError::NoError();
00079 MenuItemPtr pItem = NULL;
00080 Text szItem[kMaxItemLen+1];
00081
00082 try
00083 {
00084 if (!IsValid())
00085 HError::Throw(ERR_NOT_INITIALIZED, __FILE__, __LINE__);
00086
00087 if (STR_EMPTY(pstrLabel))
00088 HError::Throw(ERR_BAD_PARAMETER, __FILE__, __LINE__);
00089
00090 if (nCmd && getMenuItem(nCmd) != NULL)
00091 {
00092 DEBUG_LOG("HMenu::AddItem() => item ID#%ld already in menu #%ld.\n", nCmd, m_id);
00093 HError::Throw(ERR_DUPLICATE, __FILE__, __LINE__);
00094 }
00095
00096 STR_NCPY(szItem, pstrLabel, kMaxItemLen);
00097 pItem = GI_create_menu_item(TEXT(szItem), nCmd, uFlags, bEnabled);
00098 if (NULL_PTR(pItem))
00099 HError::Throw(ERR_API_ERROR, __FILE__, __LINE__);
00100
00101 if (GI_add_menu_item(GetMenuPtr(), pItem) != S_OK)
00102 HError::Throw(ERR_API_ERROR, __FILE__, __LINE__);
00103
00104 m_items[nCmd] = pItem;
00105 }
00106 catch (const std::exception & e)
00107 {
00108 DEBUG_LOG("HMenu::AddItem() => caught %s\n", e.what());
00109
00110 if ((ec = ErrCode( HError::GetLastError() )) == NO_ERROR)
00111 ec = HError::Set(ERR_STL_EXCEPTION, __FILE__, __LINE__);
00112
00113 if (GOOD_PTR(pItem))
00114 (void) GI_destroy_window( reinterpret_cast<s_window *>(pItem) );
00115 }
00116
00117 return ec;
00118 }
00124 ErrCode
00125 AddSeparator(void)
00126 {
00127 ErrCode ec = HError::NoError();
00128 MenuItemPtr pItem = NULL;
00129
00130 try
00131 {
00132 if (!IsValid())
00133 HError::Throw(ERR_NOT_INITIALIZED, __FILE__, __LINE__);
00134
00135 pItem = GI_create_menu_item(TEXT(kStrEmpty), 0, MENU_SEPERATOR, false);
00136 if (NULL_PTR(pItem))
00137 HError::Throw(ERR_API_ERROR, __FILE__, __LINE__);
00138
00139 if (GI_add_menu_item(GetMenuPtr(), pItem) != S_OK)
00140 HError::Throw(ERR_API_ERROR, __FILE__, __LINE__);
00141 }
00142 catch (const std::exception & e)
00143 {
00144 DEBUG_LOG("HMenu::AddSeparator() => caught %s\n", e.what());
00145
00146 if ((ec = ErrCode( HError::GetLastError() )) == NO_ERROR)
00147 ec = HError::Set(ERR_STL_EXCEPTION, __FILE__, __LINE__);
00148
00149 if (GOOD_PTR(pItem))
00150 (void) GI_destroy_window( reinterpret_cast<s_window *>(pItem) );
00151 }
00152
00153 return ec;
00154 }
00164 ErrCode
00165 Create(int32 nID, HANDLE hWnd = NULL)
00166 {
00167 ErrCode ec = HError::NoError();
00168
00169 if (GOOD_HND(m_hMe))
00170 ec = HError::Set(ERR_DUPLICATE, __FILE__, __LINE__);
00171 else
00172 {
00173 m_hMe = reinterpret_cast<HANDLE>( GI_create_menu(hWnd) );
00174 if (NULL_HND(m_hMe))
00175 ec = HError::Set(ERR_API_ERROR, __FILE__, __LINE__);
00176 else
00177 {
00178 m_id = nID;
00179 DEBUG_LOG( "HMenu[%p]::Create() => 0x%08lX\n",
00180 this, int32(m_hMe));
00181 }
00182 }
00183
00184 return ec;
00185 }
00193 ErrCode
00194 EnableItem(int32 nCmd, bool bEnable = true)
00195 {
00196 ErrCode ec = HError::NoError();
00197 MenuItemPtr pItem = getMenuItem(nCmd);
00198
00199 if (GOOD_PTR(pItem))
00200 {
00201
00202
00203
00204 if ((!bEnable && pItem->enabled) || (bEnable && !(pItem->enabled)) &&
00205 GI_widget_menu_item_enable(HANDLE(pItem), (bEnable ? 1 : 0)) != S_OK)
00206 {
00207 ec = HError::Set(ERR_API_ERROR, __FILE__, __LINE__);
00208 }
00209 }
00210 else
00211 ec = HError::Set(ERR_NOT_FOUND, __FILE__, __LINE__);
00212
00213 return ec;
00214 }
00215
00216
00217
00218 public:
00221 widget_menu * GetMenuPtr(void) const
00222 { return reinterpret_cast<widget_menu *>( m_hMe ); }
00230 ErrCode SetItemText(int32 nCmd, StringPtr pstrLabel)
00231 {
00232 ErrCode ec = HError::NoError();
00233 MenuItemPtr pItem = getMenuItem(nCmd);
00234
00235 if (GOOD_PTR(pItem))
00236 {
00237 if (STR_VALID(pstrLabel))
00238 STR_NCPY(TextPtr(pItem->text), pstrLabel, sizeof(pItem->text));
00239 else
00240 ec = HError::Set(ERR_BAD_PARAMETER, __FILE__, __LINE__);
00241 }
00242 else
00243 ec = HError::Set(ERR_NOT_FOUND, __FILE__, __LINE__);
00244
00245 return ec;
00246 }
00247 protected:
00250 MenuItemPtr getMenuItem(int32 nCmd)
00251 {
00252 MenuItemPtr pItem = NULL;
00253
00254 return (m_items.Get(nCmd, pItem) == NO_ERROR) ? pItem : NULL;
00255 }
00256 };
00257
00258 typedef HMenu * HMenuPtr;
00259
00260
00261
00271 class HMenuBar : public HMenu
00272 {
00273 typedef HMenu base_class;
00274 static StringPtr ClassName(void) { return "HMenuBar"; }
00275
00276 protected:
00277 typedef std::map<int32, HMenuPtr> HMenuMap;
00278
00279
00280
00281 protected:
00282 HMenuMap m_menus;
00283
00284
00285
00286 public:
00287 HMenuBar(void) : HMenu()
00288 { }
00289
00290 virtual
00291 ~HMenuBar(void)
00292 { (void) Destroy(); }
00293
00294
00295
00296 public:
00309 ErrCode
00310 AddMenu(int32 nID, StringPtr pstrLabel, HMenuPtr & pMenu)
00311 {
00312 widget_menu_item dummy;
00313 const uint32 kMaxItemLen = sizeof(dummy.text);
00314
00315 ErrCode ec = HError::NoError();
00316 MenuItemPtr pItem = NULL;
00317 Text szLabel[kMaxItemLen+1];
00318
00319 pMenu = NULL;
00320
00321 try
00322 {
00323 if (nID == 0)
00324 HError::Throw(ERR_BAD_PARAMETER, __FILE__, __LINE__);
00325
00326
00327
00328 if (GetMenu(nID) != NULL)
00329 {
00330 DEBUG_LOG("HMenuBar::AddMenu() => menu #%ld already in menu bar\n", nID);
00331 HError::Throw(ERR_DUPLICATE, __FILE__, __LINE__);
00332 }
00333
00334
00335
00336 pMenu = new HMenu;
00337 ASSERT_PTR(pMenu);
00338
00339 if ((ec = pMenu->Create(nID)) != NO_ERROR)
00340 throw HError::GetLastError();
00341
00342 STR_NCPY(szLabel, pstrLabel, kMaxItemLen);
00343 pItem = GI_create_menu_item(TEXT(szLabel), nID, 0, true);
00344 if (NULL_PTR(pItem))
00345 HError::Throw(ERR_API_ERROR, __FILE__, __LINE__);
00346
00347 if (GI_add_menu_sub(GetMenuPtr(), pItem, pMenu->GetMenuPtr()) != S_OK)
00348 HError::Throw(ERR_API_ERROR, __FILE__, __LINE__);
00349
00350 m_menus[nID] = pMenu;
00351 }
00352 catch (const std::exception & e)
00353 {
00354 DEBUG_LOG("HMenuBar::AddMenu() => caught %s\n", e.what());
00355
00356 if ((ec = ErrCode( HError::GetLastError() )) == NO_ERROR)
00357 ec = HError::Set(ERR_STL_EXCEPTION, __FILE__, __LINE__);
00358
00359 pMenu->m_bAutoDestruct = false;
00360 delete pMenu;
00361 pMenu = NULL;
00362 }
00363
00364 return ec;
00365 }
00373 ErrCode
00374 Destroy(void)
00375 {
00376 ErrCode ec = HError::NoError();
00377
00378 try
00379 {
00380 for (HMenuMap::iterator it = m_menus.begin(); it != m_menus.end(); ++it)
00381 {
00382 ASSERT(it != NULL);
00383 delete it->second;
00384 }
00385
00386 m_menus.erase(m_menus.begin(), m_menus.end());
00387 ec = base_class::Destroy();
00388 }
00389 catch (const std::exception & e)
00390 {
00391 DEBUG_LOG("HMenuBar::Destroy() => caught %s\n", e.what());
00392
00393 if ((ec = ErrCode( HError::GetLastError() )) == NO_ERROR)
00394 ec = HError::Set(ERR_STL_EXCEPTION, __FILE__, __LINE__);
00395 }
00396
00397 return ec;
00398 }
00408 ErrCode
00409 RemoveMenu(int32 nID)
00410 {
00411 ErrCode ec = HError::NoError();
00412 HMenuMap::iterator it;
00413
00414 try
00415 {
00416 if ((it = m_menus.find(nID)) != m_menus.end())
00417 {
00418 ASSERT( it != NULL );
00419 delete it->second;
00420 m_menus.erase(it);
00421 DEBUG_LOG("HMenuBar::RemoveMenu() => removed menu #%ld\n", nID);
00422 }
00423 else
00424 ec = HError::Set(ERR_NOT_FOUND, __FILE__, __LINE__);
00425 }
00426 catch (const std::exception & e)
00427 {
00428 DEBUG_LOG("HMenuBar::RemoveMenu() => caught %s\n", e.what());
00429
00430 if ((ec = ErrCode( HError::GetLastError() )) == NO_ERROR)
00431 ec = HError::Set(ERR_STL_EXCEPTION, __FILE__, __LINE__);
00432 }
00433
00434 return ec;
00435 }
00436
00437
00438
00439 public:
00450 HMenuPtr GetMenu(int32 nID)
00451 {
00452 HMenuMap::iterator it = m_menus.find(nID);
00453
00454 if (it == m_menus.end())
00455 return NULL;
00456
00457 ASSERT(it != NULL);
00458 return it-> second;
00459 }
00464 int32 GetMenuCount(void) const
00465 { return m_menus.size(); }
00477 HMenuPtr GetMenuByCommand(int32 nCmd)
00478 {
00479 for (HMenuMap::iterator it = m_menus.begin(); it != m_menus.end(); ++it)
00480 {
00481 HMenuPtr pMenu = it->second;
00482
00483 if (GOOD_PTR(pMenu) &&
00484 pMenu->getMenuItem(nCmd) != NULL)
00485 {
00486 return pMenu;
00487 }
00488 }
00489
00490 return NULL;
00491 }
00500 HMenuPtr GetNthMenu(int32 index)
00501 {
00502 for (HMenuMap::iterator it = m_menus.begin(); it != m_menus.end(); ++it)
00503 if (index-- == 0)
00504 {
00505 ASSERT(it != NULL);
00506 return it->second;
00507 }
00508
00509 return NULL;
00510 }
00511 };
00512 #endif // HMENU_H
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544