BCMenu.cpp 85 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069
  1. #include "stdafx.h" // Standard windows header file
  2. #include "BCMenu.h" // BCMenu class declaration
  3. #include <afxpriv.h> //SK: makes A2W and other spiffy AFX macros work
  4. #ifdef _DEBUG
  5. #define new DEBUG_NEW
  6. #undef THIS_FILE
  7. static char THIS_FILE[] = __FILE__;
  8. #endif
  9. #define BCMENU_GAP 1
  10. #ifndef OBM_CHECK
  11. #define OBM_CHECK 32760 // from winuser.h
  12. #endif
  13. #if _MFC_VER <0x400
  14. #error This code does not work on Versions of MFC prior to 4.0
  15. #endif
  16. static CPINFO CPInfo;
  17. // how the menu's are drawn in win9x/NT/2000
  18. UINT BCMenu::original_drawmode = BCMENU_DRAWMODE_ORIGINAL;
  19. BOOL BCMenu::original_select_disabled = TRUE;
  20. // how the menu's are drawn in winXP
  21. UINT BCMenu::xp_drawmode = BCMENU_DRAWMODE_XP;
  22. BOOL BCMenu::xp_select_disabled = FALSE;
  23. BOOL BCMenu::xp_draw_3D_bitmaps = TRUE;
  24. CImageList BCMenu::m_AllImages;
  25. CArray<int, int&> BCMenu::m_AllImagesID;
  26. enum Win32Type {
  27. Win32s,
  28. WinNT3,
  29. Win95,
  30. Win98,
  31. WinME,
  32. WinNT4,
  33. Win2000,
  34. WinXP
  35. };
  36. Win32Type IsShellType()
  37. {
  38. Win32Type ShellType;
  39. DWORD winVer;
  40. OSVERSIONINFO *osvi;
  41. winVer = GetVersion();
  42. if (winVer < 0x80000000) {/*NT */
  43. ShellType = WinNT3;
  44. osvi = (OSVERSIONINFO *)malloc(sizeof(OSVERSIONINFO));
  45. if (osvi != NULL) {
  46. memset(osvi, 0, sizeof(OSVERSIONINFO));
  47. osvi->dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  48. GetVersionEx(osvi);
  49. if (osvi->dwMajorVersion == 4L)ShellType = WinNT4;
  50. else if (osvi->dwMajorVersion == 5L && osvi->dwMinorVersion == 0L)ShellType = Win2000;
  51. else if (osvi->dwMajorVersion == 5L && osvi->dwMinorVersion == 1L)ShellType = WinXP;
  52. free(osvi);
  53. }
  54. }
  55. else if (LOBYTE(LOWORD(winVer)) < 4)
  56. ShellType = Win32s;
  57. else {
  58. ShellType = Win95;
  59. osvi = (OSVERSIONINFO *)malloc(sizeof(OSVERSIONINFO));
  60. if (osvi != NULL) {
  61. memset(osvi, 0, sizeof(OSVERSIONINFO));
  62. osvi->dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  63. GetVersionEx(osvi);
  64. if (osvi->dwMajorVersion == 4L && osvi->dwMinorVersion == 10L)ShellType = Win98;
  65. else if (osvi->dwMajorVersion == 4L && osvi->dwMinorVersion == 90L)ShellType = WinME;
  66. free(osvi);
  67. }
  68. }
  69. return ShellType;
  70. }
  71. static Win32Type g_Shell = IsShellType();
  72. void BCMenuData::SetAnsiString(LPCSTR szAnsiString)
  73. {
  74. USES_CONVERSION;
  75. SetWideString(A2W(szAnsiString)); //SK: see MFC Tech Note 059
  76. }
  77. CString BCMenuData::GetString(void)//returns the menu text in ANSI or UNICODE
  78. //depending on the MFC-Version we are using
  79. {
  80. CString strText;
  81. if (m_szMenuText)
  82. {
  83. #ifdef UNICODE
  84. strText = m_szMenuText;
  85. #else
  86. USES_CONVERSION;
  87. strText = W2A(m_szMenuText); //SK: see MFC Tech Note 059
  88. #endif
  89. }
  90. return strText;
  91. }
  92. CTypedPtrArray<CPtrArray, HMENU> BCMenu::m_AllSubMenus; // Stores list of all sub-menus
  93. IMPLEMENT_DYNAMIC(BCMenu, CMenu)
  94. /*
  95. ===============================================================================
  96. BCMenu::BCMenu()
  97. BCMenu::~BCMenu()
  98. -----------------
  99. Constructor and Destructor.
  100. ===============================================================================
  101. */
  102. BCMenu::BCMenu()
  103. {
  104. m_bDynIcons = FALSE; // O.S. - no dynamic icons by default
  105. disable_old_style = FALSE;
  106. m_iconX = 16; // Icon sizes default to 16 x 16
  107. m_iconY = 15; // ...
  108. m_selectcheck = -1;
  109. m_unselectcheck = -1;
  110. checkmaps = NULL;
  111. checkmapsshare = FALSE;
  112. // set the color used for the transparent background in all bitmaps
  113. m_bitmapBackground = RGB(192, 192, 192); //gray
  114. m_bitmapBackgroundFlag = FALSE;
  115. GetCPInfo(CP_ACP, &CPInfo);
  116. m_loadmenu = FALSE;
  117. }
  118. BCMenu::~BCMenu()
  119. {
  120. DestroyMenu();
  121. }
  122. BOOL BCMenu::IsNewShell()
  123. {
  124. return (g_Shell >= Win95);
  125. }
  126. BOOL BCMenu::IsWinXPLuna()
  127. {
  128. if (g_Shell == WinXP) {
  129. if (IsWindowsClassicTheme())return(FALSE);
  130. else return(TRUE);
  131. }
  132. return(FALSE);
  133. }
  134. BOOL BCMenu::IsLunaMenuStyle()
  135. {
  136. if (IsWinXPLuna()) {
  137. if (xp_drawmode == BCMENU_DRAWMODE_XP)return(TRUE);
  138. }
  139. else {
  140. if (original_drawmode == BCMENU_DRAWMODE_XP)return(TRUE);
  141. }
  142. return(FALSE);
  143. }
  144. BCMenuData::~BCMenuData()
  145. {
  146. if (bitmap)
  147. delete(bitmap);
  148. delete[] m_szMenuText; //Need not check for NULL because ANSI X3J16 allows "delete NULL"
  149. }
  150. void BCMenuData::SetWideString(const wchar_t *szWideString)
  151. {
  152. delete[] m_szMenuText;//Need not check for NULL because ANSI X3J16 allows "delete NULL"
  153. if (szWideString)
  154. {
  155. m_szMenuText = new wchar_t[sizeof(wchar_t)*(wcslen(szWideString) + 1)];
  156. if (m_szMenuText)
  157. wcscpy(m_szMenuText, szWideString);
  158. }
  159. else
  160. m_szMenuText = NULL;//set to NULL so we need not bother about dangling non-NULL Ptrs
  161. }
  162. BOOL BCMenu::IsMenu(CMenu *submenu)
  163. {
  164. int m;
  165. int numSubMenus = m_AllSubMenus.GetUpperBound();
  166. for (m = 0; m <= numSubMenus; ++m) {
  167. if (submenu->m_hMenu == m_AllSubMenus[m])return(TRUE);
  168. }
  169. return(FALSE);
  170. }
  171. BOOL BCMenu::IsMenu(HMENU submenu)
  172. {
  173. int m;
  174. int numSubMenus = m_AllSubMenus.GetUpperBound();
  175. for (m = 0; m <= numSubMenus; ++m) {
  176. if (submenu == m_AllSubMenus[m])return(TRUE);
  177. }
  178. return(FALSE);
  179. }
  180. BOOL BCMenu::DestroyMenu()
  181. {
  182. // Destroy Sub menus:
  183. int m, n;
  184. int numAllSubMenus = m_AllSubMenus.GetUpperBound();
  185. for (n = numAllSubMenus; n >= 0; n--) {
  186. if (m_AllSubMenus[n] == this->m_hMenu)m_AllSubMenus.RemoveAt(n);
  187. }
  188. int numSubMenus = m_SubMenus.GetUpperBound();
  189. for (m = numSubMenus; m >= 0; m--) {
  190. numAllSubMenus = m_AllSubMenus.GetUpperBound();
  191. for (n = numAllSubMenus; n >= 0; n--) {
  192. if (m_AllSubMenus[n] == m_SubMenus[m])m_AllSubMenus.RemoveAt(n);
  193. }
  194. CMenu *ptr = FromHandle(m_SubMenus[m]);
  195. BOOL flag = ptr->IsKindOf(RUNTIME_CLASS(BCMenu));
  196. if (flag)delete((BCMenu *)ptr);
  197. }
  198. m_SubMenus.RemoveAll();
  199. // Destroy menu data
  200. int numItems = m_MenuList.GetUpperBound();
  201. for (m = 0; m <= numItems; m++)delete(m_MenuList[m]);
  202. m_MenuList.RemoveAll();
  203. if (checkmaps && !checkmapsshare) {
  204. delete checkmaps;
  205. checkmaps = NULL;
  206. }
  207. // Call base-class implementation last:
  208. return(CMenu::DestroyMenu());
  209. };
  210. int BCMenu::GetMenuDrawMode(void)
  211. {
  212. if (IsWinXPLuna())return(xp_drawmode);
  213. return(original_drawmode);
  214. }
  215. BOOL BCMenu::GetSelectDisableMode(void)
  216. {
  217. if (IsLunaMenuStyle())return(xp_select_disabled);
  218. return(original_select_disabled);
  219. }
  220. /*
  221. ==========================================================================
  222. void BCMenu::DrawItem(LPDRAWITEMSTRUCT)
  223. ---------------------------------------
  224. Called by the framework when a particular item needs to be drawn. We
  225. overide this to draw the menu item in a custom-fashion, including icons
  226. and the 3D rectangle bar.
  227. ==========================================================================
  228. */
  229. void BCMenu::DrawItem(LPDRAWITEMSTRUCT lpDIS)
  230. {
  231. ASSERT(lpDIS != NULL);
  232. CDC* pDC = CDC::FromHandle(lpDIS->hDC);
  233. if (pDC->GetDeviceCaps(RASTERCAPS) & RC_PALETTE)DrawItem_Win9xNT2000(lpDIS);
  234. else {
  235. if (IsWinXPLuna()) {
  236. if (xp_drawmode == BCMENU_DRAWMODE_XP) DrawItem_WinXP(lpDIS);
  237. else DrawItem_Win9xNT2000(lpDIS);
  238. }
  239. else {
  240. if (original_drawmode == BCMENU_DRAWMODE_XP) DrawItem_WinXP(lpDIS);
  241. else DrawItem_Win9xNT2000(lpDIS);
  242. }
  243. }
  244. }
  245. void BCMenu::DrawItem_Win9xNT2000(LPDRAWITEMSTRUCT lpDIS)
  246. {
  247. ASSERT(lpDIS != NULL);
  248. CDC* pDC = CDC::FromHandle(lpDIS->hDC);
  249. CRect rect;
  250. UINT state = (((BCMenuData*)(lpDIS->itemData))->nFlags);
  251. CBrush m_brBackground;
  252. COLORREF m_clrBack;
  253. if (IsWinXPLuna())m_clrBack = GetSysColor(COLOR_3DFACE);
  254. else m_clrBack = GetSysColor(COLOR_MENU);
  255. m_brBackground.CreateSolidBrush(m_clrBack);
  256. // remove the selected bit if it's grayed out
  257. if (lpDIS->itemState & ODS_GRAYED && !original_select_disabled) {
  258. if (lpDIS->itemState & ODS_SELECTED)lpDIS->itemState = lpDIS->itemState & ~ODS_SELECTED;
  259. }
  260. if (state & MF_SEPARATOR) {
  261. rect.CopyRect(&lpDIS->rcItem);
  262. pDC->FillRect(rect, &m_brBackground);
  263. rect.top += (rect.Height() >> 1);
  264. pDC->DrawEdge(&rect, EDGE_ETCHED, BF_TOP);
  265. }
  266. else {
  267. CRect rect2;
  268. BOOL standardflag = FALSE, selectedflag = FALSE, disableflag = FALSE;
  269. BOOL checkflag = FALSE;
  270. COLORREF crText = GetSysColor(COLOR_MENUTEXT);
  271. CBrush m_brSelect;
  272. CPen m_penBack;
  273. int x0, y0, dy;
  274. int nIconNormal = -1, xoffset = -1, global_offset = -1;
  275. CImageList *bitmap = NULL;
  276. // set some colors
  277. m_penBack.CreatePen(PS_SOLID, 0, m_clrBack);
  278. m_brSelect.CreateSolidBrush(GetSysColor(COLOR_HIGHLIGHT));
  279. // draw the colored rectangle portion
  280. rect.CopyRect(&lpDIS->rcItem);
  281. rect2 = rect;
  282. // draw the up/down/focused/disabled state
  283. UINT state = lpDIS->itemState;
  284. CString strText;
  285. if (lpDIS->itemData != NULL) {
  286. nIconNormal = (((BCMenuData*)(lpDIS->itemData))->menuIconNormal);
  287. xoffset = (((BCMenuData*)(lpDIS->itemData))->xoffset);
  288. global_offset = (((BCMenuData*)(lpDIS->itemData))->global_offset);
  289. bitmap = (((BCMenuData*)(lpDIS->itemData))->bitmap);
  290. strText = ((BCMenuData*)(lpDIS->itemData))->GetString();
  291. if (nIconNormal < 0 && global_offset >= 0) {
  292. xoffset = global_offset;
  293. nIconNormal = 0;
  294. bitmap = &m_AllImages;
  295. }
  296. if (state&ODS_CHECKED && nIconNormal < 0) {
  297. if (state&ODS_SELECTED && m_selectcheck > 0)checkflag = TRUE;
  298. else if (m_unselectcheck > 0) checkflag = TRUE;
  299. }
  300. else if (nIconNormal != -1) {
  301. standardflag = TRUE;
  302. if (state&ODS_SELECTED && !(state&ODS_GRAYED))selectedflag = TRUE;
  303. else if (state&ODS_GRAYED) disableflag = TRUE;
  304. }
  305. }
  306. else {
  307. strText.Empty();
  308. }
  309. if (state&ODS_SELECTED) { // draw the down edges
  310. CPen *pOldPen = pDC->SelectObject(&m_penBack);
  311. // You need only Text highlight and thats what you get
  312. if (checkflag || standardflag || selectedflag || disableflag || state & ODS_CHECKED)
  313. rect2.SetRect(rect.left + m_iconX + 4 + BCMENU_GAP, rect.top, rect.right, rect.bottom);
  314. pDC->FillRect(rect2, &m_brSelect);
  315. pDC->SelectObject(pOldPen);
  316. crText = GetSysColor(COLOR_HIGHLIGHTTEXT);
  317. }
  318. else {
  319. CPen *pOldPen = pDC->SelectObject(&m_penBack);
  320. pDC->FillRect(rect, &m_brBackground);
  321. pDC->SelectObject(pOldPen);
  322. // draw the up edges
  323. pDC->Draw3dRect(rect, m_clrBack, m_clrBack);
  324. }
  325. // draw the text if there is any
  326. //We have to paint the text only if the image is nonexistant
  327. dy = (rect.Height() - 4 - m_iconY) / 2;
  328. dy = dy < 0 ? 0 : dy;
  329. if (checkflag || standardflag || selectedflag || disableflag) {
  330. rect2.SetRect(rect.left + 1, rect.top + 1 + dy, rect.left + m_iconX + 3,
  331. rect.top + m_iconY + 3 + dy);
  332. pDC->Draw3dRect(rect2, m_clrBack, m_clrBack);
  333. if (checkflag && checkmaps) {
  334. pDC->FillRect(rect2, &m_brBackground);
  335. rect2.SetRect(rect.left, rect.top + dy, rect.left + m_iconX + 4,
  336. rect.top + m_iconY + 4 + dy);
  337. pDC->Draw3dRect(rect2, m_clrBack, m_clrBack);
  338. CPoint ptImage(rect.left + 2, rect.top + 2 + dy);
  339. if (state&ODS_SELECTED)checkmaps->Draw(pDC, 1, ptImage, ILD_TRANSPARENT);
  340. else checkmaps->Draw(pDC, 0, ptImage, ILD_TRANSPARENT);
  341. }
  342. else if (disableflag) {
  343. if (!selectedflag) {
  344. CBitmap bitmapstandard;
  345. GetBitmapFromImageList(pDC, bitmap, xoffset, bitmapstandard);
  346. rect2.SetRect(rect.left, rect.top + dy, rect.left + m_iconX + 4,
  347. rect.top + m_iconY + 4 + dy);
  348. pDC->Draw3dRect(rect2, m_clrBack, m_clrBack);
  349. if (disable_old_style)
  350. DitherBlt(lpDIS->hDC, rect.left + 2, rect.top + 2 + dy, m_iconX, m_iconY,
  351. (HBITMAP)(bitmapstandard), 0, 0, m_clrBack);
  352. else
  353. DitherBlt2(pDC, rect.left + 2, rect.top + 2 + dy, m_iconX, m_iconY,
  354. bitmapstandard, 0, 0, m_clrBack);
  355. bitmapstandard.DeleteObject();
  356. }
  357. }
  358. else if (selectedflag) {
  359. pDC->FillRect(rect2, &m_brBackground);
  360. rect2.SetRect(rect.left, rect.top + dy, rect.left + m_iconX + 4,
  361. rect.top + m_iconY + 4 + dy);
  362. if (IsNewShell()) {
  363. if (state&ODS_CHECKED)
  364. pDC->Draw3dRect(rect2, GetSysColor(COLOR_3DSHADOW),
  365. GetSysColor(COLOR_3DHILIGHT));
  366. else
  367. pDC->Draw3dRect(rect2, GetSysColor(COLOR_3DHILIGHT),
  368. GetSysColor(COLOR_3DSHADOW));
  369. }
  370. CPoint ptImage(rect.left + 2, rect.top + 2 + dy);
  371. if (bitmap)bitmap->Draw(pDC, xoffset, ptImage, ILD_TRANSPARENT);
  372. }
  373. else {
  374. if (state&ODS_CHECKED) {
  375. CBrush brush;
  376. COLORREF col = m_clrBack;
  377. col = LightenColor(col, 0.6);
  378. brush.CreateSolidBrush(col);
  379. pDC->FillRect(rect2, &brush);
  380. brush.DeleteObject();
  381. rect2.SetRect(rect.left, rect.top + dy, rect.left + m_iconX + 4,
  382. rect.top + m_iconY + 4 + dy);
  383. if (IsNewShell())
  384. pDC->Draw3dRect(rect2, GetSysColor(COLOR_3DSHADOW),
  385. GetSysColor(COLOR_3DHILIGHT));
  386. }
  387. else {
  388. pDC->FillRect(rect2, &m_brBackground);
  389. rect2.SetRect(rect.left, rect.top + dy, rect.left + m_iconX + 4,
  390. rect.top + m_iconY + 4 + dy);
  391. pDC->Draw3dRect(rect2, m_clrBack, m_clrBack);
  392. }
  393. CPoint ptImage(rect.left + 2, rect.top + 2 + dy);
  394. if (bitmap)bitmap->Draw(pDC, xoffset, ptImage, ILD_TRANSPARENT);
  395. }
  396. }
  397. if (nIconNormal < 0 && state&ODS_CHECKED && !checkflag) {
  398. rect2.SetRect(rect.left + 1, rect.top + 2 + dy, rect.left + m_iconX + 1,
  399. rect.top + m_iconY + 2 + dy);
  400. CMenuItemInfo info;
  401. info.fMask = MIIM_CHECKMARKS;
  402. ::GetMenuItemInfo((HMENU)lpDIS->hwndItem, lpDIS->itemID,
  403. MF_BYCOMMAND, &info);
  404. if (state&ODS_CHECKED || info.hbmpUnchecked) {
  405. Draw3DCheckmark(pDC, rect2, state&ODS_SELECTED,
  406. state&ODS_CHECKED ? info.hbmpChecked :
  407. info.hbmpUnchecked);
  408. }
  409. }
  410. //This is needed always so that we can have the space for check marks
  411. x0 = rect.left; y0 = rect.top;
  412. rect.left = rect.left + m_iconX + 8 + BCMENU_GAP;
  413. if (!strText.IsEmpty()) {
  414. CRect rectt(rect.left, rect.top - 1, rect.right, rect.bottom - 1);
  415. // Find tabs
  416. CString leftStr, rightStr;
  417. leftStr.Empty(); rightStr.Empty();
  418. int tablocr = strText.ReverseFind(_T('\t'));
  419. if (tablocr != -1) {
  420. rightStr = strText.Mid(tablocr + 1);
  421. leftStr = strText.Left(strText.Find(_T('\t')));
  422. rectt.right -= m_iconX;
  423. }
  424. else leftStr = strText;
  425. int iOldMode = pDC->GetBkMode();
  426. pDC->SetBkMode(TRANSPARENT);
  427. // Draw the text in the correct colour:
  428. UINT nFormat = DT_LEFT | DT_SINGLELINE | DT_VCENTER;
  429. UINT nFormatr = DT_RIGHT | DT_SINGLELINE | DT_VCENTER;
  430. if (!(lpDIS->itemState & ODS_GRAYED)) {
  431. pDC->SetTextColor(crText);
  432. pDC->DrawText(leftStr, rectt, nFormat);
  433. if (tablocr != -1) pDC->DrawText(rightStr, rectt, nFormatr);
  434. }
  435. else {
  436. // Draw the disabled text
  437. if (!(state & ODS_SELECTED)) {
  438. RECT offset = *rectt;
  439. offset.left += 1;
  440. offset.right += 1;
  441. offset.top += 1;
  442. offset.bottom += 1;
  443. pDC->SetTextColor(GetSysColor(COLOR_BTNHILIGHT));
  444. pDC->DrawText(leftStr, &offset, nFormat);
  445. if (tablocr != -1) pDC->DrawText(rightStr, &offset, nFormatr);
  446. pDC->SetTextColor(GetSysColor(COLOR_GRAYTEXT));
  447. pDC->DrawText(leftStr, rectt, nFormat);
  448. if (tablocr != -1) pDC->DrawText(rightStr, rectt, nFormatr);
  449. }
  450. else {
  451. // And the standard Grey text:
  452. pDC->SetTextColor(m_clrBack);
  453. pDC->DrawText(leftStr, rectt, nFormat);
  454. if (tablocr != -1) pDC->DrawText(rightStr, rectt, nFormatr);
  455. }
  456. }
  457. pDC->SetBkMode(iOldMode);
  458. }
  459. m_penBack.DeleteObject();
  460. m_brSelect.DeleteObject();
  461. }
  462. m_brBackground.DeleteObject();
  463. }
  464. COLORREF BCMenu::LightenColor(COLORREF col, double factor)
  465. {
  466. if (factor > 0.0&&factor <= 1.0) {
  467. BYTE red, green, blue, lightred, lightgreen, lightblue;
  468. red = GetRValue(col);
  469. green = GetGValue(col);
  470. blue = GetBValue(col);
  471. lightred = (BYTE)((factor*(255 - red)) + red);
  472. lightgreen = (BYTE)((factor*(255 - green)) + green);
  473. lightblue = (BYTE)((factor*(255 - blue)) + blue);
  474. col = RGB(lightred, lightgreen, lightblue);
  475. }
  476. return(col);
  477. }
  478. COLORREF BCMenu::DarkenColor(COLORREF col, double factor)
  479. {
  480. if (factor > 0.0&&factor <= 1.0) {
  481. BYTE red, green, blue, lightred, lightgreen, lightblue;
  482. red = GetRValue(col);
  483. green = GetGValue(col);
  484. blue = GetBValue(col);
  485. lightred = (BYTE)(red - (factor*red));
  486. lightgreen = (BYTE)(green - (factor*green));
  487. lightblue = (BYTE)(blue - (factor*blue));
  488. col = RGB(lightred, lightgreen, lightblue);
  489. }
  490. return(col);
  491. }
  492. void BCMenu::DrawItem_WinXP(LPDRAWITEMSTRUCT lpDIS)
  493. {
  494. ASSERT(lpDIS != NULL);
  495. CDC* pDC = CDC::FromHandle(lpDIS->hDC);
  496. #ifdef BCMENU_USE_MEMDC
  497. BCMenuMemDC *pMemDC = NULL;
  498. #endif
  499. CRect rect, rect2;
  500. UINT state = (((BCMenuData*)(lpDIS->itemData))->nFlags);
  501. COLORREF m_newclrBack = GetSysColor(COLOR_3DFACE);
  502. COLORREF m_clrBack = GetSysColor(COLOR_WINDOW);
  503. CFont m_fontMenu, *pFont = NULL;
  504. LOGFONT m_lf;
  505. if (!IsWinXPLuna())m_newclrBack = LightenColor(m_newclrBack, 0.25);
  506. CBrush m_newbrBackground, m_brBackground;
  507. m_brBackground.CreateSolidBrush(m_clrBack);
  508. m_newbrBackground.CreateSolidBrush(m_newclrBack);
  509. int BCMENU_PAD = 4;
  510. if (xp_draw_3D_bitmaps)BCMENU_PAD = 7;
  511. int barwidth = m_iconX + BCMENU_PAD;
  512. // remove the selected bit if it's grayed out
  513. if (lpDIS->itemState & ODS_GRAYED && !xp_select_disabled) {
  514. if (lpDIS->itemState & ODS_SELECTED)lpDIS->itemState = lpDIS->itemState & ~ODS_SELECTED;
  515. #ifdef BCMENU_USE_MEMDC
  516. pMemDC = new BCMenuMemDC(pDC, &lpDIS->rcItem);
  517. pDC = pMemDC;
  518. ZeroMemory((PVOID)&m_lf, sizeof(LOGFONT));
  519. NONCLIENTMETRICS nm;
  520. nm.cbSize = sizeof(NONCLIENTMETRICS);
  521. VERIFY(SystemParametersInfo(SPI_GETNONCLIENTMETRICS, nm.cbSize, &nm, 0));
  522. m_lf = nm.lfMenuFont;
  523. m_fontMenu.CreateFontIndirect(&m_lf);
  524. pFont = pDC->SelectObject(&m_fontMenu);
  525. #endif
  526. }
  527. if (state & MF_SEPARATOR) {
  528. rect.CopyRect(&lpDIS->rcItem);
  529. pDC->FillRect(rect, &m_brBackground);
  530. rect2.SetRect(rect.left, rect.top, rect.left + barwidth, rect.bottom);
  531. rect.top += rect.Height() >> 1;
  532. rect.left = rect2.right + BCMENU_PAD;
  533. pDC->DrawEdge(&rect, EDGE_ETCHED, BF_TOP);
  534. pDC->FillRect(rect2, &m_newbrBackground);
  535. pDC->Draw3dRect(rect2, m_newclrBack, m_newclrBack);
  536. }
  537. else {
  538. BOOL standardflag = FALSE, selectedflag = FALSE, disableflag = FALSE;
  539. BOOL checkflag = FALSE;
  540. COLORREF crText = GetSysColor(COLOR_MENUTEXT);
  541. COLORREF crSelect = GetSysColor(COLOR_HIGHLIGHT);
  542. COLORREF crSelectFill;
  543. if (!IsWinXPLuna())crSelectFill = LightenColor(crSelect, 0.85);
  544. else crSelectFill = LightenColor(crSelect, 0.7);
  545. CBrush m_brSelect;
  546. CPen m_penBack;
  547. int x0, y0, dx, dy;
  548. int nIconNormal = -1, xoffset = -1, global_offset = -1;
  549. int faded_offset = 1, shadow_offset = 2;
  550. CImageList *bitmap = NULL;
  551. BOOL CanDraw3D = FALSE;
  552. // set some colors
  553. m_penBack.CreatePen(PS_SOLID, 0, m_clrBack);
  554. m_brSelect.CreateSolidBrush(crSelectFill);
  555. // draw the colored rectangle portion
  556. rect.CopyRect(&lpDIS->rcItem);
  557. rect2 = rect;
  558. // draw the up/down/focused/disabled state
  559. UINT state = lpDIS->itemState;
  560. CString strText;
  561. if (lpDIS->itemData != NULL) {
  562. nIconNormal = (((BCMenuData*)(lpDIS->itemData))->menuIconNormal);
  563. xoffset = (((BCMenuData*)(lpDIS->itemData))->xoffset);
  564. bitmap = (((BCMenuData*)(lpDIS->itemData))->bitmap);
  565. strText = ((BCMenuData*)(lpDIS->itemData))->GetString();
  566. global_offset = (((BCMenuData*)(lpDIS->itemData))->global_offset);
  567. if (xoffset == 0 && xp_draw_3D_bitmaps&&bitmap&&bitmap->GetImageCount() > 2)CanDraw3D = TRUE;
  568. if (nIconNormal < 0 && xoffset < 0 && global_offset >= 0) {
  569. xoffset = global_offset;
  570. nIconNormal = 0;
  571. bitmap = &m_AllImages;
  572. if (xp_draw_3D_bitmaps&&CanDraw3DImageList(global_offset)) {
  573. CanDraw3D = TRUE;
  574. faded_offset = global_offset + 1;
  575. shadow_offset = global_offset + 2;
  576. }
  577. }
  578. if (state&ODS_CHECKED && nIconNormal < 0) {
  579. if (state&ODS_SELECTED && m_selectcheck > 0)checkflag = TRUE;
  580. else if (m_unselectcheck > 0) checkflag = TRUE;
  581. }
  582. else if (nIconNormal != -1) {
  583. standardflag = TRUE;
  584. if (state&ODS_SELECTED && !(state&ODS_GRAYED))selectedflag = TRUE;
  585. else if (state&ODS_GRAYED) disableflag = TRUE;
  586. }
  587. }
  588. else {
  589. strText.Empty();
  590. }
  591. if (state&ODS_SELECTED) { // draw the down edges
  592. CPen *pOldPen = pDC->SelectObject(&m_penBack);
  593. pDC->FillRect(rect, &m_brSelect);
  594. pDC->Draw3dRect(rect, crSelect, crSelect);
  595. pDC->SelectObject(pOldPen);
  596. }
  597. else {
  598. rect2.SetRect(rect.left, rect.top, rect.left + barwidth, rect.bottom);
  599. CPen *pOldPen = pDC->SelectObject(&m_penBack);
  600. pDC->FillRect(rect, &m_brBackground);
  601. pDC->FillRect(rect2, &m_newbrBackground);
  602. pDC->SelectObject(pOldPen);
  603. // draw the up edges
  604. pDC->Draw3dRect(rect, m_clrBack, m_clrBack);
  605. pDC->Draw3dRect(rect2, m_newclrBack, m_newclrBack);
  606. }
  607. // draw the text if there is any
  608. //We have to paint the text only if the image is nonexistant
  609. dy = (int)(0.5 + (rect.Height() - m_iconY) / 2.0);
  610. dy = dy < 0 ? 0 : dy;
  611. dx = (int)(0.5 + (barwidth - m_iconX) / 2.0);
  612. dx = dx < 0 ? 0 : dx;
  613. if (checkflag || standardflag || selectedflag || disableflag) {
  614. rect2.SetRect(rect.left + 1, rect.top + 1, rect.left + barwidth - 1,
  615. rect.bottom - 1);
  616. if (checkflag && checkmaps) {
  617. pDC->FillRect(rect2, &m_newbrBackground);
  618. CPoint ptImage(rect.left + dx, rect.top + dy);
  619. if (state&ODS_SELECTED)checkmaps->Draw(pDC, 1, ptImage, ILD_TRANSPARENT);
  620. else checkmaps->Draw(pDC, 0, ptImage, ILD_TRANSPARENT);
  621. }
  622. else if (disableflag) {
  623. if (!selectedflag) {
  624. CBitmap bitmapstandard;
  625. GetBitmapFromImageList(pDC, bitmap, xoffset, bitmapstandard);
  626. COLORREF transparentcol = m_newclrBack;
  627. if (state&ODS_SELECTED)transparentcol = crSelectFill;
  628. if (disable_old_style)
  629. DitherBlt(lpDIS->hDC, rect.left + dx, rect.top + dy, m_iconX, m_iconY,
  630. (HBITMAP)(bitmapstandard), 0, 0, transparentcol);
  631. else
  632. DitherBlt2(pDC, rect.left + dx, rect.top + dy, m_iconX, m_iconY,
  633. bitmapstandard, 0, 0, transparentcol);
  634. if (state&ODS_SELECTED)pDC->Draw3dRect(rect, crSelect, crSelect);
  635. bitmapstandard.DeleteObject();
  636. }
  637. }
  638. else if (selectedflag) {
  639. pDC->FillRect(rect2, &m_brSelect);
  640. CPoint ptImage(rect.left + dx, rect.top + dy);
  641. if (state&ODS_CHECKED) {
  642. pDC->Draw3dRect(rect2, crSelect, crSelect);
  643. ptImage.x -= 1; ptImage.y -= 1;
  644. }
  645. if (bitmap) {
  646. if (CanDraw3D && !(state&ODS_CHECKED)) {
  647. CPoint ptImage1(ptImage.x + 1, ptImage.y + 1);
  648. CPoint ptImage2(ptImage.x - 1, ptImage.y - 1);
  649. bitmap->Draw(pDC, shadow_offset, ptImage1, ILD_TRANSPARENT);
  650. bitmap->Draw(pDC, xoffset, ptImage2, ILD_TRANSPARENT);
  651. }
  652. else bitmap->Draw(pDC, xoffset, ptImage, ILD_TRANSPARENT);
  653. }
  654. }
  655. else {
  656. if (state&ODS_CHECKED) {
  657. CBrush brushin;
  658. brushin.CreateSolidBrush(LightenColor(crSelect, 0.85));
  659. pDC->FillRect(rect2, &brushin);
  660. brushin.DeleteObject();
  661. pDC->Draw3dRect(rect2, crSelect, crSelect);
  662. CPoint ptImage(rect.left + dx - 1, rect.top + dy - 1);
  663. if (bitmap)bitmap->Draw(pDC, xoffset, ptImage, ILD_TRANSPARENT);
  664. }
  665. else {
  666. pDC->FillRect(rect2, &m_newbrBackground);
  667. pDC->Draw3dRect(rect2, m_newclrBack, m_newclrBack);
  668. CPoint ptImage(rect.left + dx, rect.top + dy);
  669. if (bitmap) {
  670. if (CanDraw3D)
  671. bitmap->Draw(pDC, faded_offset, ptImage, ILD_TRANSPARENT);
  672. else
  673. bitmap->Draw(pDC, xoffset, ptImage, ILD_TRANSPARENT);
  674. }
  675. }
  676. }
  677. }
  678. if (nIconNormal < 0 && state&ODS_CHECKED && !checkflag) {
  679. dy = (int)(0.5 + (rect.Height() - 16) / 2.0);
  680. dy = dy < 0 ? 0 : dy;
  681. dx = (int)(0.5 + (barwidth - 16) / 2.0);
  682. dx = dx < 0 ? 0 : dx;
  683. CMenuItemInfo info;
  684. info.fMask = MIIM_CHECKMARKS;
  685. ::GetMenuItemInfo((HMENU)lpDIS->hwndItem, lpDIS->itemID,
  686. MF_BYCOMMAND, &info);
  687. if (state&ODS_CHECKED || info.hbmpUnchecked) {
  688. rect2.SetRect(rect.left + dx, rect.top + dy, rect.left + dx + 16, rect.top + dy + 16);
  689. DrawXPCheckmark(pDC, rect2, state&ODS_CHECKED ? info.hbmpChecked :
  690. info.hbmpUnchecked, crSelect);
  691. }
  692. }
  693. //This is needed always so that we can have the space for check marks
  694. x0 = rect.left; y0 = rect.top;
  695. rect.left = rect.left + barwidth + 8;
  696. if (!strText.IsEmpty()) {
  697. CRect rectt(rect.left, rect.top - 1, rect.right, rect.bottom - 1);
  698. // Find tabs
  699. CString leftStr, rightStr;
  700. leftStr.Empty(); rightStr.Empty();
  701. int tablocr = strText.ReverseFind(_T('\t'));
  702. if (tablocr != -1) {
  703. rightStr = strText.Mid(tablocr + 1);
  704. leftStr = strText.Left(strText.Find(_T('\t')));
  705. rectt.right -= m_iconX;
  706. }
  707. else leftStr = strText;
  708. int iOldMode = pDC->GetBkMode();
  709. pDC->SetBkMode(TRANSPARENT);
  710. // Draw the text in the correct colour:
  711. UINT nFormat = DT_LEFT | DT_SINGLELINE | DT_VCENTER;
  712. UINT nFormatr = DT_RIGHT | DT_SINGLELINE | DT_VCENTER;
  713. if (!(lpDIS->itemState & ODS_GRAYED)) {
  714. pDC->SetTextColor(crText);
  715. pDC->DrawText(leftStr, rectt, nFormat);
  716. if (tablocr != -1) pDC->DrawText(rightStr, rectt, nFormatr);
  717. }
  718. else {
  719. RECT offset = *rectt;
  720. offset.left += 1;
  721. offset.right += 1;
  722. offset.top += 1;
  723. offset.bottom += 1;
  724. if (!IsWinXPLuna()) {
  725. COLORREF graycol = GetSysColor(COLOR_GRAYTEXT);
  726. if (!(state&ODS_SELECTED))graycol = LightenColor(graycol, 0.4);
  727. pDC->SetTextColor(graycol);
  728. }
  729. else pDC->SetTextColor(GetSysColor(COLOR_GRAYTEXT));
  730. pDC->DrawText(leftStr, rectt, nFormat);
  731. if (tablocr != -1) pDC->DrawText(rightStr, rectt, nFormatr);
  732. }
  733. pDC->SetBkMode(iOldMode);
  734. }
  735. m_penBack.DeleteObject();
  736. m_brSelect.DeleteObject();
  737. }
  738. m_brBackground.DeleteObject();
  739. m_newbrBackground.DeleteObject();
  740. #ifdef BCMENU_USE_MEMDC
  741. if (pFont)pDC->SelectObject(pFont); //set it to the old font
  742. m_fontMenu.DeleteObject();
  743. if (pMemDC)delete pMemDC;
  744. #endif
  745. }
  746. BOOL BCMenu::GetBitmapFromImageList(CDC* pDC, CImageList *imglist, int nIndex, CBitmap &bmp)
  747. {
  748. HICON hIcon = imglist->ExtractIcon(nIndex);
  749. CDC dc;
  750. dc.CreateCompatibleDC(pDC);
  751. bmp.CreateCompatibleBitmap(pDC, m_iconX, m_iconY);
  752. CBitmap* pOldBmp = dc.SelectObject(&bmp);
  753. CBrush brush;
  754. COLORREF m_newclrBack;
  755. m_newclrBack = GetSysColor(COLOR_3DFACE);
  756. brush.CreateSolidBrush(m_newclrBack);
  757. ::DrawIconEx(
  758. dc.GetSafeHdc(),
  759. 0,
  760. 0,
  761. hIcon,
  762. m_iconX,
  763. m_iconY,
  764. 0,
  765. (HBRUSH)brush,
  766. DI_NORMAL
  767. );
  768. dc.SelectObject(pOldBmp);
  769. dc.DeleteDC();
  770. // the icon is not longer needed
  771. ::DestroyIcon(hIcon);
  772. return(TRUE);
  773. }
  774. /*
  775. ==========================================================================
  776. void BCMenu::MeasureItem(LPMEASUREITEMSTRUCT)
  777. ---------------------------------------------
  778. Called by the framework when it wants to know what the width and height
  779. of our item will be. To accomplish this we provide the width of the
  780. icon plus the width of the menu text, and then the height of the icon.
  781. ==========================================================================
  782. */
  783. void BCMenu::MeasureItem(LPMEASUREITEMSTRUCT lpMIS)
  784. {
  785. UINT state = (((BCMenuData*)(lpMIS->itemData))->nFlags);
  786. int BCMENU_PAD = 4;
  787. if (IsLunaMenuStyle() && xp_draw_3D_bitmaps)BCMENU_PAD = 7;
  788. if (state & MF_SEPARATOR) {
  789. lpMIS->itemWidth = 0;
  790. int temp = GetSystemMetrics(SM_CYMENU) >> 1;
  791. lpMIS->itemHeight = temp > (m_iconY + BCMENU_PAD) / 2 ? temp : (m_iconY + BCMENU_PAD) / 2;
  792. }
  793. else {
  794. CFont m_fontMenu;
  795. LOGFONT m_lf;
  796. ZeroMemory((PVOID)&m_lf, sizeof(LOGFONT));
  797. NONCLIENTMETRICS nm;
  798. nm.cbSize = sizeof(NONCLIENTMETRICS);
  799. VERIFY(SystemParametersInfo(SPI_GETNONCLIENTMETRICS,
  800. nm.cbSize, &nm, 0));
  801. m_lf = nm.lfMenuFont;
  802. m_fontMenu.CreateFontIndirect(&m_lf);
  803. // Obtain the width of the text:
  804. CWnd *pWnd = AfxGetMainWnd(); // Get main window
  805. if (pWnd == NULL) pWnd = CWnd::GetDesktopWindow();
  806. CDC *pDC = pWnd->GetDC(); // Get device context
  807. CFont* pFont = NULL; // Select menu font in...
  808. if (IsNewShell())
  809. pFont = pDC->SelectObject(&m_fontMenu);// Select menu font in...
  810. //Get pointer to text SK
  811. const wchar_t *lpstrText = ((BCMenuData*)(lpMIS->itemData))->GetWideString();//SK: we use const to prevent misuse
  812. SIZE size;
  813. size.cx = size.cy = 0;
  814. if (Win32s != g_Shell)
  815. VERIFY(::GetTextExtentPoint32W(pDC->m_hDC, lpstrText,
  816. wcslen(lpstrText), &size)); //SK should also work on 95
  817. #ifndef UNICODE //can't be UNICODE for Win32s
  818. else {//it's Win32suckx
  819. RECT rect;
  820. rect.left = rect.top = 0;
  821. size.cy = DrawText(pDC->m_hDC, (LPCTSTR)lpstrText,
  822. wcslen(lpstrText), &rect,
  823. DT_SINGLELINE | DT_LEFT | DT_VCENTER | DT_CALCRECT);
  824. //+3 makes at least three pixels space to the menu border
  825. size.cx = rect.right - rect.left + 3;
  826. size.cx += 3 * (size.cx / wcslen(lpstrText));
  827. }
  828. #endif
  829. CSize t = CSize(size);
  830. if (IsNewShell())
  831. pDC->SelectObject(pFont); // Select old font in
  832. pWnd->ReleaseDC(pDC); // Release the DC
  833. // Set width and height:
  834. if (IsLunaMenuStyle())lpMIS->itemWidth = m_iconX + BCMENU_PAD + 8 + t.cx;
  835. else lpMIS->itemWidth = m_iconX + t.cx + m_iconX + BCMENU_GAP;
  836. int temp = GetSystemMetrics(SM_CYMENU);
  837. lpMIS->itemHeight = temp > m_iconY + BCMENU_PAD ? temp : m_iconY + BCMENU_PAD;
  838. m_fontMenu.DeleteObject();
  839. }
  840. }
  841. void BCMenu::SetIconSize(int width, int height)
  842. {
  843. m_iconX = width;
  844. m_iconY = height;
  845. }
  846. BOOL BCMenu::AppendODMenuA(LPCSTR lpstrText, UINT nFlags, UINT nID,
  847. int nIconNormal)
  848. {
  849. USES_CONVERSION;
  850. return AppendODMenuW(A2W(lpstrText), nFlags, nID, nIconNormal);//SK: See MFC Tech Note 059
  851. }
  852. BOOL BCMenu::AppendODMenuW(wchar_t *lpstrText, UINT nFlags, UINT nID,
  853. int nIconNormal)
  854. {
  855. // Add the MF_OWNERDRAW flag if not specified:
  856. if (!nID) {
  857. if (nFlags&MF_BYPOSITION)nFlags = MF_SEPARATOR | MF_OWNERDRAW | MF_BYPOSITION;
  858. else nFlags = MF_SEPARATOR | MF_OWNERDRAW;
  859. }
  860. else if (!(nFlags & MF_OWNERDRAW))nFlags |= MF_OWNERDRAW;
  861. if (nFlags & MF_POPUP) {
  862. m_AllSubMenus.Add((HMENU)nID);
  863. m_SubMenus.Add((HMENU)nID);
  864. }
  865. BCMenuData *mdata = new BCMenuData;
  866. m_MenuList.Add(mdata);
  867. mdata->SetWideString(lpstrText); //SK: modified for dynamic allocation
  868. mdata->menuIconNormal = -1;
  869. mdata->xoffset = -1;
  870. if (nIconNormal >= 0) {
  871. CImageList bitmap;
  872. int xoffset = 0;
  873. LoadFromToolBar(nID, nIconNormal, xoffset);
  874. if (mdata->bitmap) {
  875. mdata->bitmap->DeleteImageList();
  876. mdata->bitmap = NULL;
  877. }
  878. bitmap.Create(m_iconX, m_iconY, ILC_COLORDDB | ILC_MASK, 1, 1);
  879. if (AddBitmapToImageList(&bitmap, nIconNormal)) {
  880. mdata->global_offset = AddToGlobalImageList(&bitmap, xoffset, nID);
  881. }
  882. }
  883. else mdata->global_offset = GlobalImageListOffset(nID);
  884. mdata->nFlags = nFlags;
  885. mdata->nID = nID;
  886. BOOL returnflag = CMenu::AppendMenu(nFlags, nID, (LPCTSTR)mdata);
  887. if (m_loadmenu)RemoveTopLevelOwnerDraw();
  888. return(returnflag);
  889. }
  890. BOOL BCMenu::AppendODMenuA(LPCSTR lpstrText, UINT nFlags, UINT nID,
  891. CImageList *il, int xoffset)
  892. {
  893. USES_CONVERSION;
  894. return AppendODMenuW(A2W(lpstrText), nFlags, nID, il, xoffset);
  895. }
  896. BOOL BCMenu::AppendODMenuW(wchar_t *lpstrText, UINT nFlags, UINT nID,
  897. CImageList *il, int xoffset)
  898. {
  899. // Add the MF_OWNERDRAW flag if not specified:
  900. if (!nID) {
  901. if (nFlags&MF_BYPOSITION)nFlags = MF_SEPARATOR | MF_OWNERDRAW | MF_BYPOSITION;
  902. else nFlags = MF_SEPARATOR | MF_OWNERDRAW;
  903. }
  904. else if (!(nFlags & MF_OWNERDRAW))nFlags |= MF_OWNERDRAW;
  905. if (nFlags & MF_POPUP) {
  906. m_AllSubMenus.Add((HMENU)nID);
  907. m_SubMenus.Add((HMENU)nID);
  908. }
  909. BCMenuData *mdata = new BCMenuData;
  910. m_MenuList.Add(mdata);
  911. mdata->SetWideString(lpstrText); //SK: modified for dynamic allocation
  912. if (il) {
  913. mdata->menuIconNormal = 0;
  914. mdata->xoffset = 0;
  915. if (mdata->bitmap)mdata->bitmap->DeleteImageList();
  916. else mdata->bitmap = new(CImageList);
  917. ImageListDuplicate(il, xoffset, mdata->bitmap);
  918. }
  919. else {
  920. mdata->menuIconNormal = -1;
  921. mdata->xoffset = -1;
  922. }
  923. mdata->nFlags = nFlags;
  924. mdata->nID = nID;
  925. return(CMenu::AppendMenu(nFlags, nID, (LPCTSTR)mdata));
  926. }
  927. BOOL BCMenu::InsertODMenuA(UINT nPosition, LPCSTR lpstrText, UINT nFlags, UINT nID,
  928. int nIconNormal)
  929. {
  930. USES_CONVERSION;
  931. return InsertODMenuW(nPosition, A2W(lpstrText), nFlags, nID, nIconNormal);
  932. }
  933. BOOL BCMenu::InsertODMenuW(UINT nPosition, wchar_t *lpstrText, UINT nFlags, UINT nID,
  934. int nIconNormal)
  935. {
  936. if (!(nFlags & MF_BYPOSITION)) {
  937. int iPosition = 0;
  938. BCMenu* pMenu = FindMenuOption(nPosition, iPosition);
  939. if (pMenu) {
  940. return(pMenu->InsertODMenuW(iPosition, lpstrText, nFlags | MF_BYPOSITION, nID, nIconNormal));
  941. }
  942. else return(FALSE);
  943. }
  944. if (!nID)nFlags = MF_SEPARATOR | MF_OWNERDRAW | MF_BYPOSITION;
  945. else if (!(nFlags & MF_OWNERDRAW))nFlags |= MF_OWNERDRAW;
  946. int menustart = 0;
  947. if (nFlags & MF_POPUP) {
  948. if (m_loadmenu) {
  949. menustart = GetMenuStart();
  950. if (nPosition < (UINT)menustart)menustart = 0;
  951. }
  952. m_AllSubMenus.Add((HMENU)nID);
  953. m_SubMenus.InsertAt(nPosition, (HMENU)nID);
  954. }
  955. //Stephane Clog suggested adding this, believe it or not it's in the help
  956. if (nPosition == (UINT)-1)nPosition = GetMenuItemCount();
  957. BCMenuData *mdata = new BCMenuData;
  958. m_MenuList.InsertAt(nPosition - menustart, mdata);
  959. mdata->SetWideString(lpstrText); //SK: modified for dynamic allocation
  960. mdata->menuIconNormal = nIconNormal;
  961. mdata->xoffset = -1;
  962. if (nIconNormal >= 0) {
  963. CImageList bitmap;
  964. int xoffset = 0;
  965. LoadFromToolBar(nID, nIconNormal, xoffset);
  966. if (mdata->bitmap) {
  967. mdata->bitmap->DeleteImageList();
  968. mdata->bitmap = NULL;
  969. }
  970. bitmap.Create(m_iconX, m_iconY, ILC_COLORDDB | ILC_MASK, 1, 1);
  971. if (AddBitmapToImageList(&bitmap, nIconNormal)) {
  972. mdata->global_offset = AddToGlobalImageList(&bitmap, xoffset, nID);
  973. }
  974. }
  975. else mdata->global_offset = GlobalImageListOffset(nID);
  976. mdata->nFlags = nFlags;
  977. mdata->nID = nID;
  978. BOOL returnflag = CMenu::InsertMenu(nPosition, nFlags, nID, (LPCTSTR)mdata);
  979. if (m_loadmenu)RemoveTopLevelOwnerDraw();
  980. return(returnflag);
  981. }
  982. BOOL BCMenu::InsertODMenuA(UINT nPosition, LPCSTR lpstrText, UINT nFlags, UINT nID,
  983. CImageList *il, int xoffset)
  984. {
  985. USES_CONVERSION;
  986. return InsertODMenuW(nPosition, A2W(lpstrText), nFlags, nID, il, xoffset);
  987. }
  988. BOOL BCMenu::InsertODMenuW(UINT nPosition, wchar_t *lpstrText, UINT nFlags, UINT nID,
  989. CImageList *il, int xoffset)
  990. {
  991. if (!(nFlags & MF_BYPOSITION)) {
  992. int iPosition = 0;
  993. BCMenu* pMenu = FindMenuOption(nPosition, iPosition);
  994. if (pMenu) {
  995. return(pMenu->InsertODMenuW(iPosition, lpstrText, nFlags | MF_BYPOSITION, nID, il, xoffset));
  996. }
  997. else return(FALSE);
  998. }
  999. if (!nID)nFlags = MF_SEPARATOR | MF_OWNERDRAW | MF_BYPOSITION;
  1000. else if (!(nFlags & MF_OWNERDRAW))nFlags |= MF_OWNERDRAW;
  1001. if (nFlags & MF_POPUP) {
  1002. m_AllSubMenus.Add((HMENU)nID);
  1003. m_SubMenus.InsertAt(nPosition, (HMENU)nID);
  1004. }
  1005. //Stephane Clog suggested adding this, believe it or not it's in the help
  1006. if (nPosition == (UINT)-1)nPosition = GetMenuItemCount();
  1007. BCMenuData *mdata = new BCMenuData;
  1008. m_MenuList.InsertAt(nPosition, mdata);
  1009. mdata->SetWideString(lpstrText); //SK: modified for dynamic allocation
  1010. mdata->menuIconNormal = -1;
  1011. mdata->xoffset = -1;
  1012. if (il) {
  1013. if (mdata->bitmap) {
  1014. mdata->bitmap->DeleteImageList();
  1015. mdata->bitmap = NULL;
  1016. }
  1017. mdata->global_offset = AddToGlobalImageList(il, xoffset, nID);
  1018. }
  1019. mdata->nFlags = nFlags;
  1020. mdata->nID = nID;
  1021. return(CMenu::InsertMenu(nPosition, nFlags, nID, (LPCTSTR)mdata));
  1022. }
  1023. BOOL BCMenu::ModifyODMenuA(const char * lpstrText, UINT nID, int nIconNormal)
  1024. {
  1025. USES_CONVERSION;
  1026. return ModifyODMenuW(A2W(lpstrText), nID, nIconNormal);//SK: see MFC Tech Note 059
  1027. }
  1028. BOOL BCMenu::ModifyODMenuW(wchar_t *lpstrText, UINT nID, int nIconNormal)
  1029. {
  1030. int nLoc;
  1031. BCMenuData *mdata;
  1032. CArray<BCMenu*, BCMenu*>bcsubs;
  1033. CArray<int, int&>bclocs;
  1034. // Find the old BCMenuData structure:
  1035. BCMenu *psubmenu = FindMenuOption(nID, nLoc);
  1036. do {
  1037. if (psubmenu && nLoc >= 0)mdata = psubmenu->m_MenuList[nLoc];
  1038. else {
  1039. // Create a new BCMenuData structure:
  1040. mdata = new BCMenuData;
  1041. m_MenuList.Add(mdata);
  1042. }
  1043. ASSERT(mdata);
  1044. if (lpstrText)
  1045. mdata->SetWideString(lpstrText); //SK: modified for dynamic allocation
  1046. mdata->menuIconNormal = -1;
  1047. mdata->xoffset = -1;
  1048. if (nIconNormal >= 0) {
  1049. CImageList bitmap;
  1050. int xoffset = 0;
  1051. LoadFromToolBar(nID, nIconNormal, xoffset);
  1052. if (mdata->bitmap) {
  1053. mdata->bitmap->DeleteImageList();
  1054. mdata->bitmap = NULL;
  1055. }
  1056. bitmap.Create(m_iconX, m_iconY, ILC_COLORDDB | ILC_MASK, 1, 1);
  1057. if (AddBitmapToImageList(&bitmap, nIconNormal)) {
  1058. mdata->global_offset = AddToGlobalImageList(&bitmap, xoffset, nID);
  1059. }
  1060. }
  1061. else mdata->global_offset = GlobalImageListOffset(nID);
  1062. mdata->nFlags &= ~(MF_BYPOSITION);
  1063. mdata->nFlags |= MF_OWNERDRAW;
  1064. mdata->nID = nID;
  1065. bcsubs.Add(psubmenu);
  1066. bclocs.Add(nLoc);
  1067. if (psubmenu && nLoc >= 0)psubmenu = FindAnotherMenuOption(nID, nLoc, bcsubs, bclocs);
  1068. else psubmenu = NULL;
  1069. } while (psubmenu);
  1070. return (CMenu::ModifyMenu(nID, mdata->nFlags, nID, (LPCTSTR)mdata));
  1071. }
  1072. BOOL BCMenu::ModifyODMenuA(const char * lpstrText, UINT nID, CImageList *il, int xoffset)
  1073. {
  1074. USES_CONVERSION;
  1075. return ModifyODMenuW(A2W(lpstrText), nID, il, xoffset);
  1076. }
  1077. BOOL BCMenu::ModifyODMenuW(wchar_t *lpstrText, UINT nID, CImageList *il, int xoffset)
  1078. {
  1079. int nLoc;
  1080. BCMenuData *mdata;
  1081. CArray<BCMenu*, BCMenu*>bcsubs;
  1082. CArray<int, int&>bclocs;
  1083. // Find the old BCMenuData structure:
  1084. BCMenu *psubmenu = FindMenuOption(nID, nLoc);
  1085. do {
  1086. if (psubmenu && nLoc >= 0)mdata = psubmenu->m_MenuList[nLoc];
  1087. else {
  1088. // Create a new BCMenuData structure:
  1089. mdata = new BCMenuData;
  1090. m_MenuList.Add(mdata);
  1091. }
  1092. ASSERT(mdata);
  1093. if (lpstrText)
  1094. mdata->SetWideString(lpstrText); //SK: modified for dynamic allocation
  1095. mdata->menuIconNormal = -1;
  1096. mdata->xoffset = -1;
  1097. if (il) {
  1098. if (mdata->bitmap) {
  1099. mdata->bitmap->DeleteImageList();
  1100. mdata->bitmap = NULL;
  1101. }
  1102. mdata->global_offset = AddToGlobalImageList(il, xoffset, nID);
  1103. }
  1104. mdata->nFlags &= ~(MF_BYPOSITION);
  1105. mdata->nFlags |= MF_OWNERDRAW;
  1106. mdata->nID = nID;
  1107. bcsubs.Add(psubmenu);
  1108. bclocs.Add(nLoc);
  1109. if (psubmenu && nLoc >= 0)psubmenu = FindAnotherMenuOption(nID, nLoc, bcsubs, bclocs);
  1110. else psubmenu = NULL;
  1111. } while (psubmenu);
  1112. return (CMenu::ModifyMenu(nID, mdata->nFlags, nID, (LPCTSTR)mdata));
  1113. }
  1114. BOOL BCMenu::ModifyODMenuA(const char * lpstrText, UINT nID, CBitmap *bmp)
  1115. {
  1116. USES_CONVERSION;
  1117. return ModifyODMenuW(A2W(lpstrText), nID, bmp);
  1118. }
  1119. BOOL BCMenu::ModifyODMenuW(wchar_t *lpstrText, UINT nID, CBitmap *bmp)
  1120. {
  1121. if (bmp) {
  1122. CImageList temp;
  1123. temp.Create(m_iconX, m_iconY, ILC_COLORDDB | ILC_MASK, 1, 1);
  1124. if (m_bitmapBackgroundFlag)temp.Add(bmp, m_bitmapBackground);
  1125. else temp.Add(bmp, GetSysColor(COLOR_3DFACE));
  1126. return ModifyODMenuW(lpstrText, nID, &temp, 0);
  1127. }
  1128. return ModifyODMenuW(lpstrText, nID, NULL, 0);
  1129. }
  1130. // courtesy of Warren Stevens
  1131. BOOL BCMenu::ModifyODMenuA(const char * lpstrText, UINT nID, COLORREF fill, COLORREF border, int hatchstyle, CSize *pSize)
  1132. {
  1133. USES_CONVERSION;
  1134. return ModifyODMenuW(A2W(lpstrText), nID, fill, border, hatchstyle, pSize);
  1135. }
  1136. BOOL BCMenu::ModifyODMenuW(wchar_t *lpstrText, UINT nID, COLORREF fill, COLORREF border, int hatchstyle, CSize *pSize)
  1137. {
  1138. CWnd *pWnd = AfxGetMainWnd(); // Get main window
  1139. CDC *pDC = pWnd->GetDC(); // Get device context
  1140. SIZE sz;
  1141. if (!pSize) {
  1142. sz.cx = m_iconX;
  1143. sz.cy = m_iconY;
  1144. }
  1145. else {
  1146. sz.cx = pSize->cx;
  1147. sz.cy = pSize->cy;
  1148. }
  1149. CSize bitmap_size(sz);
  1150. CSize icon_size(m_iconX, m_iconY);
  1151. CBitmap bmp;
  1152. ColorBitmap(pDC, bmp, bitmap_size, icon_size, fill, border, hatchstyle);
  1153. pWnd->ReleaseDC(pDC);
  1154. return ModifyODMenuW(lpstrText, nID, &bmp);
  1155. }
  1156. BOOL BCMenu::ModifyODMenuA(const char *lpstrText, const char *OptionText,
  1157. int nIconNormal)
  1158. {
  1159. USES_CONVERSION;
  1160. return ModifyODMenuW(A2W(lpstrText), A2W(OptionText), nIconNormal);//SK: see MFC Tech Note 059
  1161. }
  1162. BOOL BCMenu::ModifyODMenuW(wchar_t *lpstrText, wchar_t *OptionText,
  1163. int nIconNormal)
  1164. {
  1165. BCMenuData *mdata;
  1166. // Find the old BCMenuData structure:
  1167. mdata = FindMenuOption(OptionText);
  1168. if (mdata) {
  1169. if (lpstrText)
  1170. mdata->SetWideString(lpstrText);//SK: modified for dynamic allocation
  1171. mdata->menuIconNormal = nIconNormal;
  1172. mdata->xoffset = -1;
  1173. if (nIconNormal >= 0) {
  1174. mdata->xoffset = 0;
  1175. if (mdata->bitmap)mdata->bitmap->DeleteImageList();
  1176. else mdata->bitmap = new(CImageList);
  1177. mdata->bitmap->Create(m_iconX, m_iconY, ILC_COLORDDB | ILC_MASK, 1, 1);
  1178. if (!AddBitmapToImageList(mdata->bitmap, nIconNormal)) {
  1179. mdata->bitmap->DeleteImageList();
  1180. delete mdata->bitmap;
  1181. mdata->bitmap = NULL;
  1182. mdata->menuIconNormal = nIconNormal = -1;
  1183. mdata->xoffset = -1;
  1184. }
  1185. }
  1186. return(TRUE);
  1187. }
  1188. return(FALSE);
  1189. }
  1190. BCMenuData *BCMenu::NewODMenu(UINT pos, UINT nFlags, UINT nID, CString string)
  1191. {
  1192. BCMenuData *mdata;
  1193. mdata = new BCMenuData;
  1194. mdata->menuIconNormal = -1;
  1195. mdata->xoffset = -1;
  1196. #ifdef UNICODE
  1197. mdata->SetWideString((LPCTSTR)string);//SK: modified for dynamic allocation
  1198. #else
  1199. mdata->SetAnsiString(string);
  1200. #endif
  1201. mdata->nFlags = nFlags;
  1202. mdata->nID = nID;
  1203. // if(nFlags & MF_POPUP)m_AllSubMenus.Add((HMENU)nID);
  1204. if (nFlags&MF_OWNERDRAW) {
  1205. ASSERT(!(nFlags&MF_STRING));
  1206. ModifyMenu(pos, nFlags, nID, (LPCTSTR)mdata);
  1207. }
  1208. else if (nFlags&MF_STRING) {
  1209. ASSERT(!(nFlags&MF_OWNERDRAW));
  1210. ModifyMenu(pos, nFlags, nID, mdata->GetString());
  1211. }
  1212. else {
  1213. ASSERT(nFlags&MF_SEPARATOR);
  1214. ModifyMenu(pos, nFlags, nID);
  1215. }
  1216. return(mdata);
  1217. };
  1218. BOOL BCMenu::LoadToolbars(const UINT *arID, int n)
  1219. {
  1220. ASSERT(arID);
  1221. BOOL returnflag = TRUE;
  1222. for (int i = 0; i < n; ++i) {
  1223. if (!LoadToolbar(arID[i]))returnflag = FALSE;
  1224. }
  1225. return(returnflag);
  1226. }
  1227. BOOL BCMenu::LoadToolbar(UINT nToolBar)
  1228. {
  1229. UINT nID, nStyle;
  1230. BOOL returnflag = FALSE;
  1231. BCMenuToolBar bar;
  1232. int xoffset = -1, xset;
  1233. int iconx, icony;
  1234. CWnd* pWnd = AfxGetMainWnd();
  1235. if (pWnd == NULL)pWnd = CWnd::GetDesktopWindow();
  1236. bar.Create(pWnd);
  1237. if (bar.LoadToolBar(nToolBar)) {
  1238. bar.GetIconSize(iconx, icony);
  1239. if (iconx > m_iconX)m_iconX = iconx;
  1240. if (icony > m_iconY)m_iconY = icony;
  1241. CImageList imglist;
  1242. imglist.Create(m_iconX, m_iconY, ILC_COLORDDB | ILC_MASK, 1, 1);
  1243. if (AddBitmapToImageList(&imglist, nToolBar)) {
  1244. returnflag = TRUE;
  1245. for (int i = 0; i < bar.GetCount(); ++i) {
  1246. nID = bar.GetItemID(i);
  1247. if (nID && GetMenuState(nID, MF_BYCOMMAND)
  1248. != 0xFFFFFFFF) {
  1249. xoffset = bar.CommandToIndex(nID);
  1250. if (xoffset >= 0) {
  1251. bar.GetButtonInfo(xoffset, nID, nStyle, xset);
  1252. if (xset > 0)xoffset = xset;
  1253. }
  1254. ModifyODMenu(NULL, nID, &imglist, xoffset);
  1255. }
  1256. }
  1257. }
  1258. }
  1259. return(returnflag);
  1260. }
  1261. BOOL BCMenu::LoadFromToolBar(UINT nID, UINT nToolBar, int& xoffset)
  1262. {
  1263. int xset, offset;
  1264. UINT nStyle;
  1265. BOOL returnflag = FALSE;
  1266. CToolBar bar;
  1267. CWnd* pWnd = AfxGetMainWnd();
  1268. if (pWnd == NULL)pWnd = CWnd::GetDesktopWindow();
  1269. bar.Create(pWnd);
  1270. if (bar.LoadToolBar(nToolBar)) {
  1271. offset = bar.CommandToIndex(nID);
  1272. if (offset >= 0) {
  1273. bar.GetButtonInfo(offset, nID, nStyle, xset);
  1274. if (xset > 0)xoffset = xset;
  1275. returnflag = TRUE;
  1276. }
  1277. }
  1278. return(returnflag);
  1279. }
  1280. // O.S.
  1281. BCMenuData *BCMenu::FindMenuItem(UINT nID)
  1282. {
  1283. BCMenuData *pData = NULL;
  1284. int i;
  1285. for (i = 0; i <= m_MenuList.GetUpperBound(); i++) {
  1286. if (m_MenuList[i]->nID == nID) {
  1287. pData = m_MenuList[i];
  1288. break;
  1289. }
  1290. }
  1291. if (!pData) {
  1292. int loc;
  1293. BCMenu *pMenu = FindMenuOption(nID, loc);
  1294. ASSERT(pMenu != this);
  1295. if (loc >= 0) {
  1296. return pMenu->FindMenuItem(nID);
  1297. }
  1298. }
  1299. return pData;
  1300. }
  1301. BCMenu *BCMenu::FindAnotherMenuOption(int nId, int& nLoc, CArray<BCMenu*, BCMenu*>&bcsubs,
  1302. CArray<int, int&>&bclocs)
  1303. {
  1304. int i, numsubs, j;
  1305. BCMenu *psubmenu, *pgoodmenu;
  1306. BOOL foundflag;
  1307. for (i = 0; i < (int)(GetMenuItemCount()); ++i) {
  1308. #ifdef _CPPRTTI
  1309. psubmenu = dynamic_cast<BCMenu *>(GetSubMenu(i));
  1310. #else
  1311. psubmenu = (BCMenu *)GetSubMenu(i);
  1312. #endif
  1313. if (psubmenu) {
  1314. pgoodmenu = psubmenu->FindAnotherMenuOption(nId, nLoc, bcsubs, bclocs);
  1315. if (pgoodmenu)return(pgoodmenu);
  1316. }
  1317. else if (nId == (int)GetMenuItemID(i)) {
  1318. numsubs = bcsubs.GetSize();
  1319. foundflag = TRUE;
  1320. for (j = 0; j < numsubs; ++j) {
  1321. if (bcsubs[j] == this&&bclocs[j] == i) {
  1322. foundflag = FALSE;
  1323. break;
  1324. }
  1325. }
  1326. if (foundflag) {
  1327. nLoc = i;
  1328. return(this);
  1329. }
  1330. }
  1331. }
  1332. nLoc = -1;
  1333. return(NULL);
  1334. }
  1335. BCMenu *BCMenu::FindMenuOption(int nId, int& nLoc)
  1336. {
  1337. int i;
  1338. BCMenu *psubmenu, *pgoodmenu;
  1339. for (i = 0; i < (int)(GetMenuItemCount()); ++i) {
  1340. #ifdef _CPPRTTI
  1341. psubmenu = dynamic_cast<BCMenu *>(GetSubMenu(i));
  1342. #else
  1343. psubmenu = (BCMenu *)GetSubMenu(i);
  1344. #endif
  1345. if (psubmenu) {
  1346. pgoodmenu = psubmenu->FindMenuOption(nId, nLoc);
  1347. if (pgoodmenu)return(pgoodmenu);
  1348. }
  1349. else if (nId == (int)GetMenuItemID(i)) {
  1350. nLoc = i;
  1351. return(this);
  1352. }
  1353. }
  1354. nLoc = -1;
  1355. return(NULL);
  1356. }
  1357. BCMenuData *BCMenu::FindMenuOption(wchar_t *lpstrText)
  1358. {
  1359. int i, j;
  1360. BCMenu *psubmenu;
  1361. BCMenuData *pmenulist;
  1362. for (i = 0; i < (int)(GetMenuItemCount()); ++i) {
  1363. #ifdef _CPPRTTI
  1364. psubmenu = dynamic_cast<BCMenu *>(GetSubMenu(i));
  1365. #else
  1366. psubmenu = (BCMenu *)GetSubMenu(i);
  1367. #endif
  1368. if (psubmenu) {
  1369. pmenulist = psubmenu->FindMenuOption(lpstrText);
  1370. if (pmenulist)return(pmenulist);
  1371. }
  1372. else {
  1373. const wchar_t *szWide;//SK: we use const to prevent misuse of this Ptr
  1374. for (j = 0; j <= m_MenuList.GetUpperBound(); ++j) {
  1375. szWide = m_MenuList[j]->GetWideString();
  1376. if (szWide && !wcscmp(lpstrText, szWide))//SK: modified for dynamic allocation
  1377. return(m_MenuList[j]);
  1378. }
  1379. }
  1380. }
  1381. return(NULL);
  1382. }
  1383. BOOL BCMenu::LoadMenu(int nResource)
  1384. {
  1385. return(BCMenu::LoadMenu(MAKEINTRESOURCE(nResource)));
  1386. };
  1387. BOOL BCMenu::LoadMenu(LPCTSTR lpszResourceName)
  1388. {
  1389. ASSERT_VALID(this);
  1390. ASSERT(lpszResourceName != NULL);
  1391. // Find the Menu Resource:
  1392. HINSTANCE hInst = AfxFindResourceHandle(lpszResourceName, RT_MENU);
  1393. HRSRC hRsrc = ::FindResource(hInst, lpszResourceName, RT_MENU);
  1394. if (hRsrc == NULL) {
  1395. hInst = NULL;
  1396. hRsrc = ::FindResource(hInst, lpszResourceName, RT_MENU);
  1397. }
  1398. if (hRsrc == NULL)return FALSE;
  1399. // Load the Menu Resource:
  1400. HGLOBAL hGlobal = LoadResource(hInst, hRsrc);
  1401. if (hGlobal == NULL)return FALSE;
  1402. // first destroy the menu if we're trying to loadmenu again
  1403. DestroyMenu();
  1404. // Attempt to create us as a menu...
  1405. if (!CMenu::CreateMenu())return FALSE;
  1406. // Get Item template Header, and calculate offset of MENUITEMTEMPLATES
  1407. MENUITEMTEMPLATEHEADER *pTpHdr =
  1408. (MENUITEMTEMPLATEHEADER*)LockResource(hGlobal);
  1409. BYTE* pTp = (BYTE*)pTpHdr +
  1410. (sizeof(MENUITEMTEMPLATEHEADER) + pTpHdr->offset);
  1411. // Variables needed during processing of Menu Item Templates:
  1412. int j = 0;
  1413. WORD dwFlags = 0; // Flags of the Menu Item
  1414. WORD dwID = 0; // ID of the Menu Item
  1415. UINT uFlags; // Actual Flags.
  1416. wchar_t *szCaption = NULL;
  1417. int nLen = 0; // Length of caption
  1418. CTypedPtrArray<CPtrArray, BCMenu*> m_Stack; // Popup menu stack
  1419. CArray<BOOL, BOOL> m_StackEnd; // Popup menu stack
  1420. m_Stack.Add(this); // Add it to this...
  1421. m_StackEnd.Add(FALSE);
  1422. do {
  1423. // Obtain Flags and (if necessary), the ID...
  1424. memcpy(&dwFlags, pTp, sizeof(WORD)); pTp += sizeof(WORD);// Obtain Flags
  1425. if (!(dwFlags & MF_POPUP)) {
  1426. memcpy(&dwID, pTp, sizeof(WORD)); // Obtain ID
  1427. pTp += sizeof(WORD);
  1428. }
  1429. else dwID = 0;
  1430. uFlags = (UINT)dwFlags; // Remove MF_END from the flags that will
  1431. if (uFlags & MF_END) // be passed to the Append(OD)Menu functions.
  1432. uFlags -= MF_END;
  1433. // Obtain Caption (and length)
  1434. nLen = 0;
  1435. szCaption = new wchar_t[wcslen((wchar_t *)pTp) + 1];
  1436. wcscpy(szCaption, (wchar_t *)pTp);
  1437. pTp = &pTp[(wcslen((wchar_t *)pTp) + 1) * sizeof(wchar_t)];//modified SK
  1438. // Handle popup menus first....
  1439. //WideCharToMultiByte
  1440. if (dwFlags & MF_POPUP) {
  1441. if (dwFlags & MF_END)m_StackEnd.SetAt(m_Stack.GetUpperBound(), TRUE);
  1442. BCMenu* pSubMenu = new BCMenu;
  1443. pSubMenu->m_unselectcheck = m_unselectcheck;
  1444. pSubMenu->m_selectcheck = m_selectcheck;
  1445. pSubMenu->checkmaps = checkmaps;
  1446. pSubMenu->checkmapsshare = TRUE;
  1447. pSubMenu->CreatePopupMenu();
  1448. // Append it to the top of the stack:
  1449. m_Stack[m_Stack.GetUpperBound()]->AppendODMenuW(szCaption, uFlags,
  1450. (UINT)pSubMenu->m_hMenu, -1);
  1451. m_Stack.Add(pSubMenu);
  1452. m_StackEnd.Add(FALSE);
  1453. }
  1454. else {
  1455. m_Stack[m_Stack.GetUpperBound()]->AppendODMenuW(szCaption, uFlags,
  1456. dwID, -1);
  1457. if (dwFlags & MF_END)m_StackEnd.SetAt(m_Stack.GetUpperBound(), TRUE);
  1458. j = m_Stack.GetUpperBound();
  1459. while (j >= 0 && m_StackEnd.GetAt(j)) {
  1460. m_Stack[m_Stack.GetUpperBound()]->InsertSpaces();
  1461. m_Stack.RemoveAt(j);
  1462. m_StackEnd.RemoveAt(j);
  1463. --j;
  1464. }
  1465. }
  1466. delete[] szCaption;
  1467. } while (m_Stack.GetUpperBound() != -1);
  1468. for (int i = 0; i < (int)GetMenuItemCount(); ++i) {
  1469. CString str = m_MenuList[i]->GetString();
  1470. if (GetSubMenu(i)) {
  1471. m_MenuList[i]->nFlags = MF_POPUP | MF_BYPOSITION;
  1472. ModifyMenu(i, MF_POPUP | MF_BYPOSITION,
  1473. (UINT)GetSubMenu(i)->m_hMenu, str);
  1474. }
  1475. else {
  1476. m_MenuList[i]->nFlags = MF_STRING | MF_BYPOSITION;
  1477. ModifyMenu(i, MF_STRING | MF_BYPOSITION, m_MenuList[i]->nID, str);
  1478. }
  1479. }
  1480. m_loadmenu = TRUE;
  1481. return(TRUE);
  1482. }
  1483. int BCMenu::GetMenuStart(void)
  1484. {
  1485. if (!m_loadmenu)return(0);
  1486. CString name, str;
  1487. int menuloc = -1, listloc = -1, menustart = 0, i = 0, j = 0;
  1488. int nummenulist = m_MenuList.GetSize();
  1489. int nummenu = (int)GetMenuItemCount();
  1490. while (i < nummenu&&menuloc == -1) {
  1491. GetMenuString(i, name, MF_BYPOSITION);
  1492. if (name.GetLength() > 0) {
  1493. for (j = 0; j < nummenulist; ++j) {
  1494. str = m_MenuList[j]->GetString();
  1495. if (name == str) {
  1496. menuloc = i;
  1497. listloc = j;
  1498. break;
  1499. }
  1500. }
  1501. }
  1502. ++i;
  1503. }
  1504. if (menuloc >= 0 && listloc >= 0 && menuloc >= listloc)menustart = menuloc - listloc;
  1505. return(menustart);
  1506. }
  1507. void BCMenu::RemoveTopLevelOwnerDraw(void)
  1508. {
  1509. CString str;
  1510. int i = 0, j = 0;
  1511. int nummenulist = m_MenuList.GetSize(), menustart;
  1512. menustart = GetMenuStart();
  1513. for (i = menustart, j = 0; i < (int)GetMenuItemCount(); ++i, ++j) {
  1514. if (j < nummenulist) {
  1515. str = m_MenuList[j]->GetString();
  1516. if (GetSubMenu(i)) {
  1517. m_MenuList[j]->nFlags = MF_POPUP | MF_BYPOSITION;
  1518. ModifyMenu(i, MF_POPUP | MF_BYPOSITION,
  1519. (UINT)GetSubMenu(i)->m_hMenu, str);
  1520. }
  1521. }
  1522. }
  1523. }
  1524. void BCMenu::InsertSpaces(void)
  1525. {
  1526. int i, j, numitems, maxlength;
  1527. CString string, newstring;
  1528. CSize t;
  1529. CFont m_fontMenu;
  1530. LOGFONT m_lf;
  1531. ZeroMemory((PVOID)&m_lf, sizeof(LOGFONT));
  1532. NONCLIENTMETRICS nm;
  1533. nm.cbSize = sizeof(NONCLIENTMETRICS);
  1534. VERIFY(SystemParametersInfo(SPI_GETNONCLIENTMETRICS, nm.cbSize, &nm, 0));
  1535. m_lf = nm.lfMenuFont;
  1536. m_fontMenu.CreateFontIndirect(&m_lf);
  1537. CWnd *pWnd = AfxGetMainWnd();
  1538. if (pWnd == NULL)pWnd = CWnd::GetDesktopWindow();
  1539. CDC *pDC = pWnd->GetDC();
  1540. CFont* pFont = pDC->SelectObject(&m_fontMenu);
  1541. numitems = GetMenuItemCount();
  1542. maxlength = -1;
  1543. for (i = 0; i < numitems; ++i) {
  1544. string = m_MenuList[i]->GetString();
  1545. j = string.Find((char)9);
  1546. newstring.Empty();
  1547. if (j != -1)newstring = string.Left(j);
  1548. else newstring = string;
  1549. newstring += _T(" ");//SK: modified for Unicode correctness.
  1550. LPCTSTR lpstrText = (LPCTSTR)newstring;
  1551. t = pDC->GetTextExtent(lpstrText, _tcslen(lpstrText));
  1552. if (t.cx > maxlength)maxlength = t.cx;
  1553. }
  1554. for (i = 0; i < numitems; ++i) {
  1555. string = m_MenuList[i]->GetString();
  1556. j = string.Find((char)9);
  1557. if (j != -1) {
  1558. newstring.Empty();
  1559. newstring = string.Left(j);
  1560. LPCTSTR lpstrText = (LPCTSTR)(newstring);
  1561. t = pDC->GetTextExtent(lpstrText, _tcslen(lpstrText));
  1562. while (t.cx < maxlength) {
  1563. newstring += _T(' ');//SK: modified for Unicode correctness
  1564. LPCTSTR lpstrText = (LPCTSTR)(newstring);
  1565. t = pDC->GetTextExtent(lpstrText, _tcslen(lpstrText));
  1566. }
  1567. newstring += string.Mid(j);
  1568. #ifdef UNICODE
  1569. m_MenuList[i]->SetWideString(newstring);//SK: modified for dynamic allocation
  1570. #else
  1571. m_MenuList[i]->SetAnsiString(newstring);
  1572. #endif
  1573. }
  1574. }
  1575. pDC->SelectObject(pFont); // Select old font in
  1576. pWnd->ReleaseDC(pDC); // Release the DC
  1577. m_fontMenu.DeleteObject();
  1578. }
  1579. void BCMenu::LoadCheckmarkBitmap(int unselect, int select)
  1580. {
  1581. if (unselect > 0 && select > 0) {
  1582. m_selectcheck = select;
  1583. m_unselectcheck = unselect;
  1584. if (checkmaps)checkmaps->DeleteImageList();
  1585. else checkmaps = new(CImageList);
  1586. checkmaps->Create(m_iconX, m_iconY, ILC_MASK, 2, 1);
  1587. BOOL flag1 = AddBitmapToImageList(checkmaps, unselect);
  1588. BOOL flag2 = AddBitmapToImageList(checkmaps, select);
  1589. if (!flag1 || !flag2) {
  1590. checkmaps->DeleteImageList();
  1591. delete checkmaps;
  1592. checkmaps = NULL;
  1593. }
  1594. }
  1595. }
  1596. //--------------------------------------------------------------------------
  1597. //[18.06.99 rj]
  1598. BOOL BCMenu::GetMenuText(UINT id, CString& string, UINT nFlags/*= MF_BYPOSITION*/)
  1599. {
  1600. BOOL returnflag = FALSE;
  1601. if (MF_BYPOSITION&nFlags) {
  1602. UINT numMenuItems = m_MenuList.GetUpperBound();
  1603. if (id <= numMenuItems) {
  1604. string = m_MenuList[id]->GetString();
  1605. returnflag = TRUE;
  1606. }
  1607. }
  1608. else {
  1609. int uiLoc;
  1610. BCMenu* pMenu = FindMenuOption(id, uiLoc);
  1611. if (NULL != pMenu) returnflag = pMenu->GetMenuText(uiLoc, string);
  1612. }
  1613. return(returnflag);
  1614. }
  1615. void BCMenu::DrawRadioDot(CDC *pDC, int x, int y, COLORREF color)
  1616. {
  1617. CRect rcDot(x, y, x + 6, y + 6);
  1618. CBrush brush;
  1619. CPen pen;
  1620. brush.CreateSolidBrush(color);
  1621. pen.CreatePen(PS_SOLID, 0, color);
  1622. CBrush *pOldBrush = pDC->SelectObject(&brush);
  1623. CPen *pOldPen = pDC->SelectObject(&pen);
  1624. pDC->Ellipse(&rcDot);
  1625. pDC->SelectObject(pOldBrush);
  1626. pDC->SelectObject(pOldPen);
  1627. pen.DeleteObject();
  1628. brush.DeleteObject();
  1629. }
  1630. void BCMenu::DrawCheckMark(CDC* pDC, int x, int y, COLORREF color)
  1631. {
  1632. CPen m_penBack;
  1633. m_penBack.CreatePen(PS_SOLID, 0, color);
  1634. CPen *pOldPen = pDC->SelectObject(&m_penBack);
  1635. pDC->MoveTo(x, y + 2);
  1636. pDC->LineTo(x, y + 5);
  1637. pDC->MoveTo(x + 1, y + 3);
  1638. pDC->LineTo(x + 1, y + 6);
  1639. pDC->MoveTo(x + 2, y + 4);
  1640. pDC->LineTo(x + 2, y + 7);
  1641. pDC->MoveTo(x + 3, y + 3);
  1642. pDC->LineTo(x + 3, y + 6);
  1643. pDC->MoveTo(x + 4, y + 2);
  1644. pDC->LineTo(x + 4, y + 5);
  1645. pDC->MoveTo(x + 5, y + 1);
  1646. pDC->LineTo(x + 5, y + 4);
  1647. pDC->MoveTo(x + 6, y);
  1648. pDC->LineTo(x + 6, y + 3);
  1649. pDC->SelectObject(pOldPen);
  1650. m_penBack.DeleteObject();
  1651. }
  1652. BCMenuData *BCMenu::FindMenuList(UINT nID)
  1653. {
  1654. for (int i = 0; i <= m_MenuList.GetUpperBound(); ++i) {
  1655. if (m_MenuList[i]->nID == nID && !m_MenuList[i]->syncflag) {
  1656. m_MenuList[i]->syncflag = 1;
  1657. return(m_MenuList[i]);
  1658. }
  1659. }
  1660. return(NULL);
  1661. }
  1662. void BCMenu::InitializeMenuList(int value)
  1663. {
  1664. for (int i = 0; i <= m_MenuList.GetUpperBound(); ++i)
  1665. m_MenuList[i]->syncflag = value;
  1666. }
  1667. void BCMenu::DeleteMenuList(void)
  1668. {
  1669. for (int i = 0; i <= m_MenuList.GetUpperBound(); ++i) {
  1670. if (!m_MenuList[i]->syncflag) {
  1671. delete m_MenuList[i];
  1672. }
  1673. }
  1674. }
  1675. void BCMenu::SynchronizeMenu(void)
  1676. {
  1677. CTypedPtrArray<CPtrArray, BCMenuData*> temp;
  1678. BCMenuData *mdata;
  1679. CString string;
  1680. UINT submenu, nID = 0, state, j;
  1681. InitializeMenuList(0);
  1682. for (j = 0; j < GetMenuItemCount(); ++j) {
  1683. mdata = NULL;
  1684. state = GetMenuState(j, MF_BYPOSITION);
  1685. if (state&MF_POPUP) {
  1686. submenu = (UINT)GetSubMenu(j)->m_hMenu;
  1687. mdata = FindMenuList(submenu);
  1688. GetMenuString(j, string, MF_BYPOSITION);
  1689. if (!mdata)mdata = NewODMenu(j,
  1690. (state & 0xFF) | MF_BYPOSITION | MF_POPUP | MF_OWNERDRAW, submenu, string);
  1691. else if (string.GetLength() > 0)
  1692. #ifdef UNICODE
  1693. mdata->SetWideString(string); //SK: modified for dynamic allocation
  1694. #else
  1695. mdata->SetAnsiString(string);
  1696. #endif
  1697. }
  1698. else if (state&MF_SEPARATOR) {
  1699. mdata = FindMenuList(0);
  1700. if (!mdata)mdata = NewODMenu(j,
  1701. state | MF_BYPOSITION | MF_SEPARATOR | MF_OWNERDRAW, 0, _T(""));//SK: modified for Unicode correctness
  1702. else ModifyMenu(j, mdata->nFlags, nID, (LPCTSTR)mdata);
  1703. }
  1704. else {
  1705. nID = GetMenuItemID(j);
  1706. mdata = FindMenuList(nID);
  1707. GetMenuString(j, string, MF_BYPOSITION);
  1708. if (!mdata)mdata = NewODMenu(j, state | MF_BYPOSITION | MF_OWNERDRAW,
  1709. nID, string);
  1710. else {
  1711. mdata->nFlags = state | MF_BYPOSITION | MF_OWNERDRAW;
  1712. if (string.GetLength() > 0)
  1713. #ifdef UNICODE
  1714. mdata->SetWideString(string);//SK: modified for dynamic allocation
  1715. #else
  1716. mdata->SetAnsiString(string);
  1717. #endif
  1718. ModifyMenu(j, mdata->nFlags, nID, (LPCTSTR)mdata);
  1719. }
  1720. }
  1721. if (mdata)temp.Add(mdata);
  1722. }
  1723. DeleteMenuList();
  1724. m_MenuList.RemoveAll();
  1725. m_MenuList.Append(temp);
  1726. temp.RemoveAll();
  1727. }
  1728. void BCMenu::UpdateMenu(CMenu *pmenu)
  1729. {
  1730. #ifdef _CPPRTTI
  1731. BCMenu *psubmenu = dynamic_cast<BCMenu *>(pmenu);
  1732. #else
  1733. BCMenu *psubmenu = (BCMenu *)pmenu;
  1734. #endif
  1735. if (psubmenu)psubmenu->SynchronizeMenu();
  1736. }
  1737. LRESULT BCMenu::FindKeyboardShortcut(UINT nChar, UINT nFlags,
  1738. CMenu *pMenu)
  1739. {
  1740. #ifdef _CPPRTTI
  1741. BCMenu *pBCMenu = dynamic_cast<BCMenu *>(pMenu);
  1742. #else
  1743. BCMenu *pBCMenu = (BCMenu *)pMenu;
  1744. #endif
  1745. if (pBCMenu && nFlags&MF_POPUP) {
  1746. CString key(_T('&'), 2);//SK: modified for Unicode correctness
  1747. key.SetAt(1, (TCHAR)nChar);
  1748. key.MakeLower();
  1749. CString menutext;
  1750. int menusize = (int)pBCMenu->GetMenuItemCount();
  1751. if (menusize != (pBCMenu->m_MenuList.GetUpperBound() + 1))
  1752. pBCMenu->SynchronizeMenu();
  1753. for (int i = 0; i < menusize; ++i) {
  1754. if (pBCMenu->GetMenuText(i, menutext)) {
  1755. menutext.MakeLower();
  1756. if (menutext.Find(key) >= 0)return(MAKELRESULT(i, 2));
  1757. }
  1758. }
  1759. }
  1760. return(0);
  1761. }
  1762. void BCMenu::DitherBlt(HDC hdcDest, int nXDest, int nYDest, int nWidth,
  1763. int nHeight, HBITMAP hbm, int nXSrc, int nYSrc,
  1764. COLORREF bgcolor)
  1765. {
  1766. ASSERT(hdcDest && hbm);
  1767. ASSERT(nWidth > 0 && nHeight > 0);
  1768. // Create a generic DC for all BitBlts
  1769. HDC hDC = CreateCompatibleDC(hdcDest);
  1770. ASSERT(hDC);
  1771. if (hDC)
  1772. {
  1773. // Create a DC for the monochrome DIB section
  1774. HDC bwDC = CreateCompatibleDC(hDC);
  1775. ASSERT(bwDC);
  1776. if (bwDC)
  1777. {
  1778. // Create the monochrome DIB section with a black and white palette
  1779. struct {
  1780. BITMAPINFOHEADER bmiHeader;
  1781. RGBQUAD bmiColors[2];
  1782. } RGBBWBITMAPINFO = {
  1783. { // a BITMAPINFOHEADER
  1784. sizeof(BITMAPINFOHEADER), // biSize
  1785. nWidth, // biWidth;
  1786. nHeight, // biHeight;
  1787. 1, // biPlanes;
  1788. 1, // biBitCount
  1789. BI_RGB, // biCompression;
  1790. 0, // biSizeImage;
  1791. 0, // biXPelsPerMeter;
  1792. 0, // biYPelsPerMeter;
  1793. 0, // biClrUsed;
  1794. 0 // biClrImportant;
  1795. },
  1796. {
  1797. { 0x00, 0x00, 0x00, 0x00 }, { 0xFF, 0xFF, 0xFF, 0x00 }
  1798. }
  1799. };
  1800. VOID *pbitsBW;
  1801. HBITMAP hbmBW = CreateDIBSection(bwDC,
  1802. (LPBITMAPINFO)&RGBBWBITMAPINFO, DIB_RGB_COLORS, &pbitsBW, NULL, 0);
  1803. ASSERT(hbmBW);
  1804. if (hbmBW)
  1805. {
  1806. // Attach the monochrome DIB section and the bitmap to the DCs
  1807. HBITMAP olddib = (HBITMAP)SelectObject(bwDC, hbmBW);
  1808. HBITMAP hdcolddib = (HBITMAP)SelectObject(hDC, hbm);
  1809. // BitBlt the bitmap into the monochrome DIB section
  1810. BitBlt(bwDC, 0, 0, nWidth, nHeight, hDC, nXSrc, nYSrc, SRCCOPY);
  1811. // Paint the destination rectangle in gray
  1812. FillRect(hdcDest, CRect(nXDest, nYDest, nXDest + nWidth, nYDest +
  1813. nHeight), GetSysColorBrush(bgcolor));
  1814. //SK: looks better on the old shell
  1815. // BitBlt the black bits in the monochrome bitmap into COLOR_3DHILIGHT
  1816. // bits in the destination DC
  1817. // The magic ROP comes from the Charles Petzold's book
  1818. HBRUSH hb = CreateSolidBrush(GetSysColor(COLOR_3DHILIGHT));
  1819. HBRUSH oldBrush = (HBRUSH)SelectObject(hdcDest, hb);
  1820. BitBlt(hdcDest, nXDest + 1, nYDest + 1, nWidth, nHeight, bwDC, 0, 0, 0xB8074A);
  1821. // BitBlt the black bits in the monochrome bitmap into COLOR_3DSHADOW
  1822. // bits in the destination DC
  1823. hb = CreateSolidBrush(GetSysColor(COLOR_3DSHADOW));
  1824. DeleteObject(SelectObject(hdcDest, hb));
  1825. BitBlt(hdcDest, nXDest, nYDest, nWidth, nHeight, bwDC, 0, 0, 0xB8074A);
  1826. DeleteObject(SelectObject(hdcDest, oldBrush));
  1827. VERIFY(DeleteObject(SelectObject(bwDC, olddib)));
  1828. SelectObject(hDC, hdcolddib);
  1829. }
  1830. VERIFY(DeleteDC(bwDC));
  1831. }
  1832. VERIFY(DeleteDC(hDC));
  1833. }
  1834. }
  1835. void BCMenu::GetFadedBitmap(CBitmap &bmp)
  1836. {
  1837. CDC ddc;
  1838. COLORREF bgcol, col;
  1839. BITMAP BitMap;
  1840. bmp.GetBitmap(&BitMap);
  1841. ddc.CreateCompatibleDC(NULL);
  1842. CBitmap * pddcOldBmp = ddc.SelectObject(&bmp);
  1843. // use this to get the background color, takes into account color shifting
  1844. CDC ddc2;
  1845. CBrush brush;
  1846. CBitmap bmp2;
  1847. ddc2.CreateCompatibleDC(NULL);
  1848. bmp2.CreateCompatibleBitmap(&ddc, BitMap.bmWidth, BitMap.bmHeight);
  1849. col = GetSysColor(COLOR_3DFACE);
  1850. brush.CreateSolidBrush(col);
  1851. CBitmap * pddcOldBmp2 = ddc2.SelectObject(&bmp2);
  1852. CRect rect(0, 0, BitMap.bmWidth, BitMap.bmHeight);
  1853. ddc2.FillRect(rect, &brush);
  1854. bgcol = ddc2.GetPixel(1, 1);
  1855. brush.DeleteObject();
  1856. ddc2.SelectObject(pddcOldBmp2);
  1857. for (int i = 0; i < BitMap.bmWidth; ++i) {
  1858. for (int j = 0; j < BitMap.bmHeight; ++j) {
  1859. col = ddc.GetPixel(i, j);
  1860. if (col != bgcol)ddc.SetPixel(i, j, LightenColor(col, 0.3));
  1861. }
  1862. }
  1863. ddc.SelectObject(pddcOldBmp);
  1864. }
  1865. void BCMenu::GetShadowBitmap(CBitmap &bmp)
  1866. {
  1867. CDC ddc;
  1868. COLORREF bgcol, col, shadowcol = GetSysColor(COLOR_BTNSHADOW);
  1869. BITMAP BitMap;
  1870. if (!IsWinXPLuna())shadowcol = LightenColor(shadowcol, 0.49);
  1871. bmp.GetBitmap(&BitMap);
  1872. ddc.CreateCompatibleDC(NULL);
  1873. CBitmap * pddcOldBmp = ddc.SelectObject(&bmp);
  1874. // use this to get the background color, takes into account color shifting
  1875. CDC ddc2;
  1876. CBrush brush;
  1877. CBitmap bmp2;
  1878. ddc2.CreateCompatibleDC(NULL);
  1879. bmp2.CreateCompatibleBitmap(&ddc, BitMap.bmWidth, BitMap.bmHeight);
  1880. col = GetSysColor(COLOR_3DFACE);
  1881. brush.CreateSolidBrush(col);
  1882. CBitmap * pddcOldBmp2 = ddc2.SelectObject(&bmp2);
  1883. CRect rect(0, 0, BitMap.bmWidth, BitMap.bmHeight);
  1884. ddc2.FillRect(rect, &brush);
  1885. bgcol = ddc2.GetPixel(1, 1);
  1886. brush.DeleteObject();
  1887. ddc2.SelectObject(pddcOldBmp2);
  1888. for (int i = 0; i < BitMap.bmWidth; ++i) {
  1889. for (int j = 0; j < BitMap.bmHeight; ++j) {
  1890. col = ddc.GetPixel(i, j);
  1891. if (col != bgcol)ddc.SetPixel(i, j, shadowcol);
  1892. }
  1893. }
  1894. ddc.SelectObject(pddcOldBmp);
  1895. }
  1896. BOOL BCMenu::AddBitmapToImageList(CImageList *bmplist, UINT nResourceID)
  1897. {
  1898. BOOL bReturn = FALSE;
  1899. // O.S.
  1900. if (m_bDynIcons) {
  1901. bmplist->Add((HICON)nResourceID);
  1902. bReturn = TRUE;
  1903. }
  1904. else {
  1905. HBITMAP hbmp = LoadSysColorBitmap(nResourceID);
  1906. if (hbmp) {
  1907. CBitmap bmp;
  1908. bmp.Attach(hbmp);
  1909. if (m_bitmapBackgroundFlag) {
  1910. if (bmplist->Add(&bmp, m_bitmapBackground) >= 0)bReturn = TRUE;
  1911. }
  1912. else {
  1913. if (bmplist->Add(&bmp, GetSysColor(COLOR_3DFACE)) >= 0)bReturn = TRUE;
  1914. }
  1915. bmp.Detach();
  1916. DeleteObject(hbmp);
  1917. }
  1918. else {
  1919. CBitmap mybmp;
  1920. if (mybmp.LoadBitmap(nResourceID)) {
  1921. if (m_bitmapBackgroundFlag) {
  1922. if (bmplist->Add(&mybmp, m_bitmapBackground) >= 0)bReturn = TRUE;
  1923. }
  1924. else {
  1925. if (bmplist->Add(&mybmp, GetSysColor(COLOR_3DFACE)) >= 0)bReturn = TRUE;
  1926. }
  1927. }
  1928. }
  1929. }
  1930. if (bReturn&&IsLunaMenuStyle() && xp_draw_3D_bitmaps) {
  1931. CWnd *pWnd = AfxGetMainWnd(); // Get main window
  1932. if (pWnd == NULL) pWnd = CWnd::GetDesktopWindow();
  1933. CDC *pDC = pWnd->GetDC(); // Get device context
  1934. CBitmap bmp, bmp2;
  1935. GetBitmapFromImageList(pDC, bmplist, 0, bmp);
  1936. GetFadedBitmap(bmp);
  1937. bmplist->Add(&bmp, GetSysColor(COLOR_3DFACE));
  1938. GetBitmapFromImageList(pDC, bmplist, 0, bmp2);
  1939. GetShadowBitmap(bmp2);
  1940. bmplist->Add(&bmp2, GetSysColor(COLOR_3DFACE));
  1941. pWnd->ReleaseDC(pDC); // Release the DC
  1942. }
  1943. return(bReturn);
  1944. }
  1945. void BCMenu::SetBitmapBackground(COLORREF color)
  1946. {
  1947. m_bitmapBackground = color;
  1948. m_bitmapBackgroundFlag = TRUE;
  1949. }
  1950. void BCMenu::UnSetBitmapBackground(void)
  1951. {
  1952. m_bitmapBackgroundFlag = FALSE;
  1953. }
  1954. // Given a toolbar, append all the options from it to this menu
  1955. // Passed a ptr to the toolbar object and the toolbar ID
  1956. // Author : Robert Edward Caldecott
  1957. void BCMenu::AddFromToolBar(CToolBar* pToolBar, int nResourceID)
  1958. {
  1959. for (int i = 0; i < pToolBar->GetCount(); i++) {
  1960. UINT nID = pToolBar->GetItemID(i);
  1961. // See if this toolbar option
  1962. // appears as a command on this
  1963. // menu or is a separator
  1964. if (nID == 0 || GetMenuState(nID, MF_BYCOMMAND) == 0xFFFFFFFF)
  1965. continue; // Item doesn't exist
  1966. UINT nStyle;
  1967. int nImage;
  1968. // Get the toolbar button info
  1969. pToolBar->GetButtonInfo(i, nID, nStyle, nImage);
  1970. // OK, we have the command ID of the toolbar
  1971. // option, and the tollbar bitmap offset
  1972. int nLoc;
  1973. BCMenuData* pData;
  1974. BCMenu *pSubMenu = FindMenuOption(nID, nLoc);
  1975. if (pSubMenu && nLoc >= 0)pData = pSubMenu->m_MenuList[nLoc];
  1976. else {
  1977. // Create a new BCMenuData structure
  1978. pData = new BCMenuData;
  1979. m_MenuList.Add(pData);
  1980. }
  1981. // Set some default structure members
  1982. pData->menuIconNormal = nResourceID;
  1983. pData->nID = nID;
  1984. pData->nFlags = MF_BYCOMMAND | MF_OWNERDRAW;
  1985. pData->xoffset = nImage;
  1986. if (pData->bitmap)pData->bitmap->DeleteImageList();
  1987. else pData->bitmap = new CImageList;
  1988. pData->bitmap->Create(m_iconX, m_iconY, ILC_COLORDDB | ILC_MASK, 1, 1);
  1989. if (!AddBitmapToImageList(pData->bitmap, nResourceID)) {
  1990. pData->bitmap->DeleteImageList();
  1991. delete pData->bitmap;
  1992. pData->bitmap = NULL;
  1993. pData->menuIconNormal = -1;
  1994. pData->xoffset = -1;
  1995. }
  1996. // Modify our menu
  1997. ModifyMenu(nID, pData->nFlags, nID, (LPCTSTR)pData);
  1998. }
  1999. }
  2000. BOOL BCMenu::Draw3DCheckmark(CDC *dc, const CRect& rc,
  2001. BOOL bSelected, HBITMAP hbmCheck)
  2002. {
  2003. CRect rcDest = rc;
  2004. CBrush brush;
  2005. COLORREF col;
  2006. if (IsWinXPLuna())col = GetSysColor(COLOR_3DFACE);
  2007. else col = GetSysColor(COLOR_MENU);
  2008. if (!bSelected)col = LightenColor(col, 0.6);
  2009. brush.CreateSolidBrush(col);
  2010. dc->FillRect(rcDest, &brush);
  2011. brush.DeleteObject();
  2012. if (IsNewShell()) //SK: looks better on the old shell
  2013. dc->DrawEdge(&rcDest, BDR_SUNKENOUTER, BF_RECT);
  2014. if (!hbmCheck)DrawCheckMark(dc, rc.left + 4, rc.top + 4, GetSysColor(COLOR_MENUTEXT));
  2015. else DrawRadioDot(dc, rc.left + 5, rc.top + 4, GetSysColor(COLOR_MENUTEXT));
  2016. return TRUE;
  2017. }
  2018. BOOL BCMenu::DrawXPCheckmark(CDC *dc, const CRect& rc, HBITMAP hbmCheck, COLORREF &colorout)
  2019. {
  2020. CBrush brushin;
  2021. brushin.CreateSolidBrush(LightenColor(colorout, 0.85));
  2022. dc->FillRect(rc, &brushin);
  2023. brushin.DeleteObject();
  2024. dc->Draw3dRect(rc, colorout, colorout);
  2025. if (!hbmCheck)DrawCheckMark(dc, rc.left + 5, rc.top + 4, GetSysColor(COLOR_MENUTEXT));
  2026. else DrawRadioDot(dc, rc.left + 5, rc.top + 4, GetSysColor(COLOR_MENUTEXT));
  2027. return TRUE;
  2028. }
  2029. void BCMenu::DitherBlt2(CDC *drawdc, int nXDest, int nYDest, int nWidth,
  2030. int nHeight, CBitmap &bmp, int nXSrc, int nYSrc,
  2031. COLORREF bgcolor)
  2032. {
  2033. // create a monochrome memory DC
  2034. CDC ddc;
  2035. ddc.CreateCompatibleDC(0);
  2036. CBitmap bwbmp;
  2037. bwbmp.CreateCompatibleBitmap(&ddc, nWidth, nHeight);
  2038. CBitmap * pddcOldBmp = ddc.SelectObject(&bwbmp);
  2039. CDC dc;
  2040. dc.CreateCompatibleDC(0);
  2041. CBitmap * pdcOldBmp = dc.SelectObject(&bmp);
  2042. // build a mask
  2043. ddc.PatBlt(0, 0, nWidth, nHeight, WHITENESS);
  2044. dc.SetBkColor(GetSysColor(COLOR_BTNFACE));
  2045. ddc.BitBlt(0, 0, nWidth, nHeight, &dc, nXSrc, nYSrc, SRCCOPY);
  2046. dc.SetBkColor(GetSysColor(COLOR_BTNHILIGHT));
  2047. ddc.BitBlt(0, 0, nWidth, nHeight, &dc, nXSrc, nYSrc, SRCPAINT);
  2048. // Copy the image from the toolbar into the memory DC
  2049. // and draw it (grayed) back into the toolbar.
  2050. dc.FillSolidRect(0, 0, nWidth, nHeight, bgcolor);
  2051. //SK: Looks better on the old shell
  2052. dc.SetBkColor(RGB(0, 0, 0));
  2053. dc.SetTextColor(RGB(255, 255, 255));
  2054. CBrush brShadow, brHilight;
  2055. brHilight.CreateSolidBrush(GetSysColor(COLOR_BTNHILIGHT));
  2056. brShadow.CreateSolidBrush(GetSysColor(COLOR_BTNSHADOW));
  2057. CBrush * pOldBrush = dc.SelectObject(&brHilight);
  2058. dc.BitBlt(0, 0, nWidth, nHeight, &ddc, 0, 0, 0x00E20746L);
  2059. drawdc->BitBlt(nXDest + 1, nYDest + 1, nWidth, nHeight, &dc, 0, 0, SRCCOPY);
  2060. dc.BitBlt(1, 1, nWidth, nHeight, &ddc, 0, 0, 0x00E20746L);
  2061. dc.SelectObject(&brShadow);
  2062. dc.BitBlt(0, 0, nWidth, nHeight, &ddc, 0, 0, 0x00E20746L);
  2063. drawdc->BitBlt(nXDest, nYDest, nWidth, nHeight, &dc, 0, 0, SRCCOPY);
  2064. // reset DCs
  2065. ddc.SelectObject(pddcOldBmp);
  2066. ddc.DeleteDC();
  2067. dc.SelectObject(pOldBrush);
  2068. dc.SelectObject(pdcOldBmp);
  2069. dc.DeleteDC();
  2070. brShadow.DeleteObject();
  2071. brHilight.DeleteObject();
  2072. bwbmp.DeleteObject();
  2073. }
  2074. void BCMenu::SetDisableOldStyle(void)
  2075. {
  2076. disable_old_style = TRUE;
  2077. }
  2078. void BCMenu::UnSetDisableOldStyle(void)
  2079. {
  2080. disable_old_style = FALSE;
  2081. }
  2082. BOOL BCMenu::GetDisableOldStyle(void)
  2083. {
  2084. return(disable_old_style);
  2085. }
  2086. WORD BCMenu::NumBitmapColors(LPBITMAPINFOHEADER lpBitmap)
  2087. {
  2088. if (lpBitmap->biClrUsed != 0)
  2089. return (WORD)lpBitmap->biClrUsed;
  2090. switch (lpBitmap->biBitCount) {
  2091. case 1:
  2092. return 2;
  2093. case 4:
  2094. return 16;
  2095. case 8:
  2096. return 256;
  2097. default:
  2098. return 0;
  2099. }
  2100. return 0;
  2101. }
  2102. HBITMAP BCMenu::LoadSysColorBitmap(int nResourceId)
  2103. {
  2104. HINSTANCE hInst =
  2105. AfxFindResourceHandle(MAKEINTRESOURCE(nResourceId), RT_BITMAP);
  2106. HRSRC hRsrc =
  2107. ::FindResource(hInst, MAKEINTRESOURCE(nResourceId), RT_BITMAP);
  2108. if (hRsrc == NULL) {
  2109. hInst = NULL;
  2110. hRsrc = ::FindResource(hInst, MAKEINTRESOURCE(nResourceId), RT_BITMAP);
  2111. }
  2112. if (hRsrc == NULL)return NULL;
  2113. // determine how many colors in the bitmap
  2114. HGLOBAL hglb;
  2115. if ((hglb = LoadResource(hInst, hRsrc)) == NULL)
  2116. return NULL;
  2117. LPBITMAPINFOHEADER lpBitmap = (LPBITMAPINFOHEADER)LockResource(hglb);
  2118. if (lpBitmap == NULL)return NULL;
  2119. WORD numcol = NumBitmapColors(lpBitmap);
  2120. ::FreeResource(hglb);
  2121. if (numcol != 16)return(NULL);
  2122. return AfxLoadSysColorBitmap(hInst, hRsrc, FALSE);
  2123. }
  2124. BOOL BCMenu::RemoveMenu(UINT uiId, UINT nFlags)
  2125. {
  2126. if (MF_BYPOSITION&nFlags) {
  2127. UINT uint = GetMenuState(uiId, MF_BYPOSITION);
  2128. if (uint&MF_SEPARATOR && !(uint&MF_POPUP)) {
  2129. delete m_MenuList.GetAt(uiId);
  2130. m_MenuList.RemoveAt(uiId);
  2131. }
  2132. else {
  2133. BCMenu* pSubMenu = (BCMenu*)GetSubMenu(uiId);
  2134. if (NULL == pSubMenu) {
  2135. UINT uiCommandId = GetMenuItemID(uiId);
  2136. for (int i = 0; i < m_MenuList.GetSize(); i++) {
  2137. if (m_MenuList[i]->nID == uiCommandId) {
  2138. delete m_MenuList.GetAt(i);
  2139. m_MenuList.RemoveAt(i);
  2140. break;
  2141. }
  2142. }
  2143. }
  2144. else {
  2145. int numSubMenus = m_SubMenus.GetUpperBound();
  2146. for (int m = numSubMenus; m >= 0; m--) {
  2147. if (m_SubMenus[m] == pSubMenu->m_hMenu) {
  2148. int numAllSubMenus = m_AllSubMenus.GetUpperBound();
  2149. for (int n = numAllSubMenus; n >= 0; n--) {
  2150. if (m_AllSubMenus[n] == m_SubMenus[m])m_AllSubMenus.RemoveAt(n);
  2151. }
  2152. m_SubMenus.RemoveAt(m);
  2153. }
  2154. }
  2155. int num = pSubMenu->GetMenuItemCount();
  2156. for (int i = num - 1; i >= 0; --i)pSubMenu->RemoveMenu(i, MF_BYPOSITION);
  2157. for (int i = m_MenuList.GetUpperBound(); i >= 0; i--) {
  2158. if (m_MenuList[i]->nID == (UINT)pSubMenu->m_hMenu) {
  2159. delete m_MenuList.GetAt(i);
  2160. m_MenuList.RemoveAt(i);
  2161. break;
  2162. }
  2163. }
  2164. delete pSubMenu;
  2165. }
  2166. }
  2167. }
  2168. else {
  2169. int iPosition = 0;
  2170. BCMenu* pMenu = FindMenuOption(uiId, iPosition);
  2171. // bug fix RIA 14th September 2000
  2172. // failed to return correct value on call to remove menu as the item was
  2173. // removed twice. The second time its not found
  2174. // so a value of 0 was being returned
  2175. if (pMenu) return pMenu->RemoveMenu(iPosition, MF_BYPOSITION); // added return
  2176. }
  2177. return CMenu::RemoveMenu(uiId, nFlags);
  2178. }
  2179. BOOL BCMenu::DeleteMenu(UINT uiId, UINT nFlags)
  2180. {
  2181. if (MF_BYPOSITION&nFlags) {
  2182. UINT uint = GetMenuState(uiId, MF_BYPOSITION);
  2183. if (uint&MF_SEPARATOR && !(uint&MF_POPUP)) {
  2184. // make sure it's a separator
  2185. int menulistsize = m_MenuList.GetSize();
  2186. if (uiId < (UINT)menulistsize) {
  2187. CString str = m_MenuList[uiId]->GetString();
  2188. if (str == "") {
  2189. delete m_MenuList.GetAt(uiId);
  2190. m_MenuList.RemoveAt(uiId);
  2191. }
  2192. }
  2193. }
  2194. else {
  2195. BCMenu* pSubMenu = (BCMenu*)GetSubMenu(uiId);
  2196. if (NULL == pSubMenu) {
  2197. UINT uiCommandId = GetMenuItemID(uiId);
  2198. for (int i = 0; i < m_MenuList.GetSize(); i++) {
  2199. if (m_MenuList[i]->nID == uiCommandId) {
  2200. delete m_MenuList.GetAt(i);
  2201. m_MenuList.RemoveAt(i);
  2202. break;
  2203. }
  2204. }
  2205. }
  2206. else {
  2207. int numSubMenus = m_SubMenus.GetUpperBound();
  2208. for (int m = numSubMenus; m >= 0; m--) {
  2209. if (m_SubMenus[m] == pSubMenu->m_hMenu) {
  2210. int numAllSubMenus = m_AllSubMenus.GetUpperBound();
  2211. for (int n = numAllSubMenus; n >= 0; n--) {
  2212. if (m_AllSubMenus[n] == m_SubMenus[m])m_AllSubMenus.RemoveAt(n);
  2213. }
  2214. m_SubMenus.RemoveAt(m);
  2215. }
  2216. }
  2217. int num = pSubMenu->GetMenuItemCount();
  2218. for (int i = num - 1; i >= 0; --i)pSubMenu->DeleteMenu(i, MF_BYPOSITION);
  2219. for (int i = m_MenuList.GetUpperBound(); i >= 0; i--) {
  2220. if (m_MenuList[i]->nID == (UINT)pSubMenu->m_hMenu) {
  2221. delete m_MenuList.GetAt(i);
  2222. m_MenuList.RemoveAt(i);
  2223. break;
  2224. }
  2225. }
  2226. delete pSubMenu;
  2227. }
  2228. }
  2229. }
  2230. else {
  2231. int iPosition = 0;
  2232. BCMenu* pMenu = FindMenuOption(uiId, iPosition);
  2233. if (pMenu)return pMenu->DeleteMenu(iPosition, MF_BYPOSITION);
  2234. }
  2235. return(CMenu::DeleteMenu(uiId, nFlags));
  2236. }
  2237. BOOL BCMenu::AppendMenuA(UINT nFlags, UINT nIDNewItem, const char *lpszNewItem, int nIconNormal)
  2238. {
  2239. USES_CONVERSION;
  2240. return AppendMenuW(nFlags, nIDNewItem, A2W(lpszNewItem), nIconNormal);
  2241. }
  2242. BOOL BCMenu::AppendMenuW(UINT nFlags, UINT nIDNewItem, wchar_t *lpszNewItem, int nIconNormal)
  2243. {
  2244. return AppendODMenuW(lpszNewItem, nFlags, nIDNewItem, nIconNormal);
  2245. }
  2246. BOOL BCMenu::AppendMenuA(UINT nFlags, UINT nIDNewItem, const char *lpszNewItem, CImageList *il, int xoffset)
  2247. {
  2248. USES_CONVERSION;
  2249. return AppendMenuW(nFlags, nIDNewItem, A2W(lpszNewItem), il, xoffset);
  2250. }
  2251. BOOL BCMenu::AppendMenuW(UINT nFlags, UINT nIDNewItem, wchar_t *lpszNewItem, CImageList *il, int xoffset)
  2252. {
  2253. return AppendODMenuW(lpszNewItem, nFlags, nIDNewItem, il, xoffset);
  2254. }
  2255. BOOL BCMenu::AppendMenuA(UINT nFlags, UINT nIDNewItem, const char *lpszNewItem, CBitmap *bmp)
  2256. {
  2257. USES_CONVERSION;
  2258. return AppendMenuW(nFlags, nIDNewItem, A2W(lpszNewItem), bmp);
  2259. }
  2260. BOOL BCMenu::AppendMenuW(UINT nFlags, UINT nIDNewItem, wchar_t *lpszNewItem, CBitmap *bmp)
  2261. {
  2262. if (bmp) {
  2263. CImageList temp;
  2264. temp.Create(m_iconX, m_iconY, ILC_COLORDDB | ILC_MASK, 1, 1);
  2265. if (m_bitmapBackgroundFlag)temp.Add(bmp, m_bitmapBackground);
  2266. else temp.Add(bmp, GetSysColor(COLOR_3DFACE));
  2267. return AppendODMenuW(lpszNewItem, nFlags, nIDNewItem, &temp, 0);
  2268. }
  2269. return AppendODMenuW(lpszNewItem, nFlags, nIDNewItem, NULL, 0);
  2270. }
  2271. BOOL BCMenu::InsertMenuA(UINT nPosition, UINT nFlags, UINT nIDNewItem, const char *lpszNewItem, int nIconNormal)
  2272. {
  2273. USES_CONVERSION;
  2274. return InsertMenuW(nPosition, nFlags, nIDNewItem, A2W(lpszNewItem), nIconNormal);
  2275. }
  2276. BOOL BCMenu::InsertMenuW(UINT nPosition, UINT nFlags, UINT nIDNewItem, wchar_t *lpszNewItem, int nIconNormal)
  2277. {
  2278. return InsertODMenuW(nPosition, lpszNewItem, nFlags, nIDNewItem, nIconNormal);
  2279. }
  2280. BOOL BCMenu::InsertMenuA(UINT nPosition, UINT nFlags, UINT nIDNewItem, const char *lpszNewItem, CImageList *il, int xoffset)
  2281. {
  2282. USES_CONVERSION;
  2283. return InsertMenuW(nPosition, nFlags, nIDNewItem, A2W(lpszNewItem), il, xoffset);
  2284. }
  2285. BOOL BCMenu::InsertMenuW(UINT nPosition, UINT nFlags, UINT nIDNewItem, wchar_t *lpszNewItem, CImageList *il, int xoffset)
  2286. {
  2287. return InsertODMenuW(nPosition, lpszNewItem, nFlags, nIDNewItem, il, xoffset);
  2288. }
  2289. BOOL BCMenu::InsertMenuA(UINT nPosition, UINT nFlags, UINT nIDNewItem, const char *lpszNewItem, CBitmap *bmp)
  2290. {
  2291. USES_CONVERSION;
  2292. return InsertMenuW(nPosition, nFlags, nIDNewItem, A2W(lpszNewItem), bmp);
  2293. }
  2294. BOOL BCMenu::InsertMenuW(UINT nPosition, UINT nFlags, UINT nIDNewItem, wchar_t *lpszNewItem, CBitmap *bmp)
  2295. {
  2296. if (bmp) {
  2297. CImageList temp;
  2298. temp.Create(m_iconX, m_iconY, ILC_COLORDDB | ILC_MASK, 1, 1);
  2299. if (m_bitmapBackgroundFlag)temp.Add(bmp, m_bitmapBackground);
  2300. else temp.Add(bmp, GetSysColor(COLOR_3DFACE));
  2301. return InsertODMenuW(nPosition, lpszNewItem, nFlags, nIDNewItem, &temp, 0);
  2302. }
  2303. return InsertODMenuW(nPosition, lpszNewItem, nFlags, nIDNewItem, NULL, 0);
  2304. }
  2305. //--------------------------------------------------------------------------
  2306. //[21.06.99 rj]
  2307. BCMenu* BCMenu::AppendODPopupMenuW(wchar_t *lpstrText)
  2308. {
  2309. BCMenu* pSubMenu = new BCMenu;
  2310. pSubMenu->m_unselectcheck = m_unselectcheck;
  2311. pSubMenu->m_selectcheck = m_selectcheck;
  2312. pSubMenu->checkmaps = checkmaps;
  2313. pSubMenu->checkmapsshare = TRUE;
  2314. pSubMenu->CreatePopupMenu();
  2315. AppendODMenuW(lpstrText, MF_POPUP, (UINT)pSubMenu->m_hMenu, -1);
  2316. return pSubMenu;
  2317. }
  2318. //--------------------------------------------------------------------------
  2319. //[21.06.99 rj]
  2320. BCMenu* BCMenu::AppendODPopupMenuA(LPCSTR lpstrText)
  2321. {
  2322. USES_CONVERSION;
  2323. return AppendODPopupMenuW(A2W(lpstrText));
  2324. }
  2325. BOOL BCMenu::ImageListDuplicate(CImageList *il, int xoffset, CImageList *newlist)
  2326. {
  2327. if (il == NULL || newlist == NULL || xoffset < 0) return FALSE;
  2328. HICON hIcon = il->ExtractIcon(xoffset);
  2329. int cx, cy;
  2330. ImageList_GetIconSize(il->m_hImageList, &cx, &cy);
  2331. newlist->Create(cx, cy, ILC_COLORDDB | ILC_MASK, 1, 1);
  2332. newlist->Add(hIcon);
  2333. ::DestroyIcon(hIcon);
  2334. if (IsLunaMenuStyle() && xp_draw_3D_bitmaps) {
  2335. CWnd *pWnd = AfxGetMainWnd(); // Get main window
  2336. if (pWnd == NULL) pWnd = CWnd::GetDesktopWindow();
  2337. CDC *pDC = pWnd->GetDC(); // Get device context
  2338. CBitmap bmp, bmp2;
  2339. GetBitmapFromImageList(pDC, newlist, 0, bmp);
  2340. GetFadedBitmap(bmp);
  2341. newlist->Add(&bmp, GetSysColor(COLOR_3DFACE));
  2342. GetBitmapFromImageList(pDC, newlist, 0, bmp2);
  2343. GetShadowBitmap(bmp2);
  2344. newlist->Add(&bmp2, GetSysColor(COLOR_3DFACE));
  2345. pWnd->ReleaseDC(pDC); // Release the DC
  2346. }
  2347. return TRUE;
  2348. }
  2349. // 2001-07-12, Damir Valiulin:
  2350. // Added GetSubMenu (LPCTSTR lpszSubMenuName) function
  2351. //
  2352. CMenu* BCMenu::GetSubMenu(int nPos)
  2353. {
  2354. return CMenu::GetSubMenu(nPos);
  2355. }
  2356. CMenu* BCMenu::GetSubMenu(LPCTSTR lpszSubMenuName)
  2357. {
  2358. int num = GetMenuItemCount();
  2359. CString name;
  2360. for (int i = 0; i < num; i++)
  2361. {
  2362. GetMenuString(i, name, MF_BYPOSITION);
  2363. if (name.Compare(lpszSubMenuName) == 0)
  2364. {
  2365. return CMenu::GetSubMenu(i);
  2366. }
  2367. }
  2368. return NULL;
  2369. }
  2370. BCMenu* BCMenu::GetSubBCMenu(char* pText)
  2371. {
  2372. USES_CONVERSION;
  2373. return GetSubBCMenu(A2W(pText));
  2374. }
  2375. BCMenu* BCMenu::GetSubBCMenu(wchar_t* lpszSubMenuName)
  2376. {
  2377. BCMenuData *mdata;
  2378. mdata = FindMenuOption(lpszSubMenuName);
  2379. if (mdata) {
  2380. HMENU bchmenu = (HMENU)mdata->nID;
  2381. CMenu *ptr = FromHandle(bchmenu);
  2382. BOOL flag = ptr->IsKindOf(RUNTIME_CLASS(BCMenu));
  2383. if (flag)return((BCMenu *)ptr);
  2384. }
  2385. return NULL;
  2386. }
  2387. // Tongzhe Cui, Functions to remove a popup menu based on its name. Seperators
  2388. // before and after the popup menu can also be removed if they exist.
  2389. int BCMenu::GetMenuPosition(char* pText)
  2390. {
  2391. USES_CONVERSION;
  2392. return GetMenuPosition(A2W(pText));
  2393. }
  2394. int BCMenu::GetMenuPosition(wchar_t* pText)
  2395. {
  2396. int i, j;
  2397. BCMenu* psubmenu;
  2398. for (i = 0; i < (int)(GetMenuItemCount()); ++i)
  2399. {
  2400. psubmenu = (BCMenu *)GetSubMenu(i);
  2401. if (!psubmenu)
  2402. {
  2403. const wchar_t *szWide;//SK: we use const to prevent misuse of this Ptr
  2404. for (j = 0; j <= m_MenuList.GetUpperBound(); ++j)
  2405. {
  2406. szWide = m_MenuList[j]->GetWideString();
  2407. if (szWide && !wcscmp(pText, szWide))//SK: modified for dynamic allocation
  2408. return j;
  2409. }
  2410. }
  2411. }
  2412. // means no found;
  2413. return -1;
  2414. }
  2415. int BCMenu::RemoveMenu(char* pText, BC_Seperator sPos)
  2416. {
  2417. USES_CONVERSION;
  2418. return RemoveMenu(A2W(pText), sPos);
  2419. }
  2420. int BCMenu::RemoveMenu(wchar_t* pText, BC_Seperator sPos)
  2421. {
  2422. int nPos = GetMenuPosition(pText);
  2423. if (nPos != -1)
  2424. {
  2425. RemoveMenu(nPos, MF_BYPOSITION);
  2426. }
  2427. if (sPos == BCMENU_HEAD)
  2428. {
  2429. ASSERT(nPos - 1 >= 0);
  2430. RemoveMenu(nPos - 1, MF_BYPOSITION);
  2431. }
  2432. else if (sPos == BCMENU_TAIL)
  2433. {
  2434. RemoveMenu(nPos - 1, MF_BYPOSITION);
  2435. }
  2436. else if (sPos == BCMENU_BOTH)
  2437. {
  2438. // remove the end first;
  2439. RemoveMenu(nPos - 1, MF_BYPOSITION);
  2440. // remove the head;
  2441. ASSERT(nPos - 1 >= 0);
  2442. RemoveMenu(nPos - 1, MF_BYPOSITION);
  2443. }
  2444. return nPos;
  2445. }
  2446. int BCMenu::DeleteMenu(char* pText, BC_Seperator sPos)
  2447. {
  2448. USES_CONVERSION;
  2449. return DeleteMenu(A2W(pText), sPos);
  2450. }
  2451. int BCMenu::DeleteMenu(wchar_t* pText, BC_Seperator sPos)
  2452. {
  2453. int nPos = GetMenuPosition(pText);
  2454. if (nPos != -1)
  2455. {
  2456. DeleteMenu(nPos, MF_BYPOSITION);
  2457. }
  2458. if (sPos == BCMENU_HEAD)
  2459. {
  2460. ASSERT(nPos - 1 >= 0);
  2461. DeleteMenu(nPos - 1, MF_BYPOSITION);
  2462. }
  2463. else if (sPos == BCMENU_TAIL)
  2464. {
  2465. DeleteMenu(nPos - 1, MF_BYPOSITION);
  2466. }
  2467. else if (sPos == BCMENU_BOTH)
  2468. {
  2469. // remove the end first;
  2470. DeleteMenu(nPos - 1, MF_BYPOSITION);
  2471. // remove the head;
  2472. ASSERT(nPos - 1 >= 0);
  2473. DeleteMenu(nPos - 1, MF_BYPOSITION);
  2474. }
  2475. return nPos;
  2476. }
  2477. // Larry Antram
  2478. BOOL BCMenu::SetMenuText(UINT id, CString string, UINT nFlags/*= MF_BYPOSITION*/)
  2479. {
  2480. BOOL returnflag = FALSE;
  2481. if (MF_BYPOSITION&nFlags)
  2482. {
  2483. UINT numMenuItems = m_MenuList.GetUpperBound();
  2484. if (id <= numMenuItems) {
  2485. #ifdef UNICODE
  2486. m_MenuList[id]->SetWideString((LPCTSTR)string);
  2487. #else
  2488. m_MenuList[id]->SetAnsiString(string);
  2489. #endif
  2490. returnflag = TRUE;
  2491. }
  2492. }
  2493. else {
  2494. int uiLoc;
  2495. BCMenu* pMenu = FindMenuOption(id, uiLoc);
  2496. if (NULL != pMenu) returnflag = pMenu->SetMenuText(uiLoc, string);
  2497. }
  2498. return(returnflag);
  2499. }
  2500. // courtesy of Warren Stevens
  2501. void BCMenu::ColorBitmap(CDC* pDC, CBitmap& bmp, CSize bitmap_size, CSize icon_size, COLORREF fill, COLORREF border, int hatchstyle)
  2502. {
  2503. CDC bmpdc;
  2504. COLORREF m_newclrBack;
  2505. int x1 = 0, y1 = 0, x2 = bitmap_size.cx, y2 = bitmap_size.cy;
  2506. if (IsWinXPLuna())m_newclrBack = GetSysColor(COLOR_3DFACE);
  2507. else m_newclrBack = GetSysColor(COLOR_MENU);
  2508. bmpdc.CreateCompatibleDC(pDC);
  2509. bmp.CreateCompatibleBitmap(pDC, icon_size.cx, icon_size.cy);
  2510. CBitmap* pOldBitmap = bmpdc.SelectObject(&bmp);
  2511. if (bitmap_size != icon_size) {
  2512. CBrush background_brush;
  2513. background_brush.CreateSolidBrush(m_newclrBack);
  2514. CRect rect(0, 0, icon_size.cx, icon_size.cy);
  2515. bmpdc.FillRect(rect, &background_brush);
  2516. x1 = (icon_size.cx - bitmap_size.cx) / 2;
  2517. y1 = (icon_size.cy - bitmap_size.cy) / 2;
  2518. x2 = x1 + bitmap_size.cx;
  2519. y2 = y1 + bitmap_size.cy;
  2520. background_brush.DeleteObject();
  2521. }
  2522. CPen border_pen(PS_SOLID, 1, border);
  2523. CBrush fill_brush;
  2524. if (hatchstyle != -1) { fill_brush.CreateHatchBrush(hatchstyle, fill); }
  2525. else { fill_brush.CreateSolidBrush(fill); }
  2526. CPen* pOldPen = bmpdc.SelectObject(&border_pen);
  2527. CBrush* pOldBrush = bmpdc.SelectObject(&fill_brush);
  2528. bmpdc.Rectangle(x1, y1, x2, y2);
  2529. if (NULL != pOldBrush) { bmpdc.SelectObject(pOldBrush); }
  2530. if (NULL != pOldPen) { bmpdc.SelectObject(pOldPen); }
  2531. if (NULL != pOldBitmap) { bmpdc.SelectObject(pOldBitmap); }
  2532. }
  2533. BOOL BCMenu::IsWindowsClassicTheme(void)
  2534. {
  2535. TCHAR Buf[_MAX_PATH + 10];
  2536. HKEY hKey;
  2537. DWORD size, type;
  2538. long lRetCode;
  2539. static BOOL XPTheme_returnflag = FALSE;
  2540. static BOOL XPTheme_checkflag = FALSE;
  2541. if (XPTheme_checkflag)return(XPTheme_returnflag);
  2542. XPTheme_checkflag = TRUE;
  2543. lRetCode = RegOpenKeyEx(HKEY_CURRENT_USER,
  2544. _T("Software\\Microsoft\\Plus!\\Themes\\Current"),
  2545. 0, KEY_READ, &hKey);
  2546. if (lRetCode == ERROR_SUCCESS) {
  2547. size = _MAX_PATH; type = REG_SZ;
  2548. lRetCode = ::RegQueryValueEx(hKey, NULL, NULL, &type,
  2549. (unsigned char *)Buf, &size);
  2550. if (lRetCode == ERROR_SUCCESS) {
  2551. TCHAR szClassicTheme[] = _T("Windows Classic.theme");
  2552. int len = lstrlen(Buf);
  2553. if (len >= lstrlen(szClassicTheme)) {
  2554. if (!lstrcmpi(&Buf[len - lstrlen(szClassicTheme)], szClassicTheme)) {
  2555. XPTheme_returnflag = TRUE;
  2556. }
  2557. }
  2558. }
  2559. RegCloseKey(hKey);
  2560. }
  2561. return(XPTheme_returnflag);
  2562. }
  2563. int BCMenu::GlobalImageListOffset(int nID)
  2564. {
  2565. int numcurrent = m_AllImagesID.GetSize();
  2566. int existsloc = -1;
  2567. for (int i = 0; i < numcurrent; ++i) {
  2568. if (m_AllImagesID[i] == nID) {
  2569. existsloc = i;
  2570. break;
  2571. }
  2572. }
  2573. return existsloc;
  2574. }
  2575. BOOL BCMenu::CanDraw3DImageList(int offset)
  2576. {
  2577. BOOL retflag = FALSE;
  2578. int numcurrent = m_AllImagesID.GetSize();
  2579. if (offset + 1 < numcurrent&&offset + 2 < numcurrent) {
  2580. int nID = m_AllImagesID[offset];
  2581. if (m_AllImagesID[offset + 1] == nID && m_AllImagesID[offset + 2] == nID)retflag = TRUE;
  2582. }
  2583. return(retflag);
  2584. }
  2585. int BCMenu::AddToGlobalImageList(CImageList *il, int xoffset, int nID)
  2586. {
  2587. int loc = -1;
  2588. HIMAGELIST hImageList = m_AllImages.m_hImageList;
  2589. if (!hImageList) {
  2590. m_AllImages.Create(m_iconX, m_iconY, ILC_COLORDDB | ILC_MASK, 1, 1);
  2591. }
  2592. HICON hIcon = il->ExtractIcon(xoffset);
  2593. if (hIcon) {
  2594. CBitmap bmp, bmp2;
  2595. if (IsLunaMenuStyle() && xp_draw_3D_bitmaps) {
  2596. CWnd *pWnd = AfxGetMainWnd(); // Get main window
  2597. if (pWnd == NULL) pWnd = CWnd::GetDesktopWindow();
  2598. CDC *pDC = pWnd->GetDC(); // Get device context
  2599. GetBitmapFromImageList(pDC, il, xoffset, bmp);
  2600. GetFadedBitmap(bmp);
  2601. GetBitmapFromImageList(pDC, il, xoffset, bmp2);
  2602. GetShadowBitmap(bmp2);
  2603. pWnd->ReleaseDC(pDC); // Release the DC
  2604. }
  2605. int numcurrent = m_AllImagesID.GetSize();
  2606. int existsloc = -1;
  2607. for (int i = 0; i < numcurrent; ++i) {
  2608. if (m_AllImagesID[i] == nID) {
  2609. existsloc = i;
  2610. break;
  2611. }
  2612. }
  2613. if (existsloc >= 0) {
  2614. m_AllImages.Replace(existsloc, hIcon);
  2615. loc = existsloc;
  2616. if (IsLunaMenuStyle() && xp_draw_3D_bitmaps) {
  2617. if (existsloc + 1 < numcurrent&&m_AllImagesID[existsloc + 1] == nID) {
  2618. if (existsloc + 2 < numcurrent&&m_AllImagesID[existsloc + 2] == nID) {
  2619. CImageList il2;
  2620. il2.Create(m_iconX, m_iconY, ILC_COLORDDB | ILC_MASK, 1, 1);
  2621. il2.Add(&bmp, GetSysColor(COLOR_3DFACE));
  2622. HICON hIcon2 = il2.ExtractIcon(0);
  2623. m_AllImages.Replace(existsloc + 1, hIcon2);
  2624. il2.Add(&bmp2, GetSysColor(COLOR_3DFACE));
  2625. HICON hIcon3 = il2.ExtractIcon(1);
  2626. m_AllImages.Replace(existsloc + 2, hIcon3);
  2627. ::DestroyIcon(hIcon2);
  2628. ::DestroyIcon(hIcon3);
  2629. }
  2630. }
  2631. }
  2632. }
  2633. else {
  2634. m_AllImages.Add(hIcon);
  2635. m_AllImagesID.Add(nID);
  2636. loc = numcurrent;
  2637. if (IsLunaMenuStyle() && xp_draw_3D_bitmaps) {
  2638. m_AllImages.Add(&bmp, GetSysColor(COLOR_3DFACE));
  2639. m_AllImages.Add(&bmp2, GetSysColor(COLOR_3DFACE));
  2640. m_AllImagesID.Add(nID);
  2641. m_AllImagesID.Add(nID);
  2642. }
  2643. }
  2644. ::DestroyIcon(hIcon);
  2645. }
  2646. return(loc);
  2647. }
  2648. //*************************************************************************
  2649. /////////////////////////////////////////////////////////////////////////////
  2650. // Toolbar for loading images
  2651. /////////////////////////////////////////////////////////////////////////////
  2652. struct CToolBarData
  2653. {
  2654. WORD wVersion;
  2655. WORD wWidth;
  2656. WORD wHeight;
  2657. WORD wItemCount;
  2658. WORD* items() {
  2659. return (WORD*)(this + 1);
  2660. }
  2661. };
  2662. BOOL BCMenuToolBar::LoadToolBar(LPCTSTR lpszResourceName)
  2663. {
  2664. ASSERT_VALID(this);
  2665. ASSERT(lpszResourceName != NULL);
  2666. HINSTANCE hInst = AfxFindResourceHandle(lpszResourceName, RT_TOOLBAR);
  2667. HRSRC hRsrc = ::FindResource(hInst, lpszResourceName, RT_TOOLBAR);
  2668. if (hRsrc == NULL) {
  2669. hInst = NULL;
  2670. hRsrc = ::FindResource(hInst, lpszResourceName, RT_TOOLBAR);
  2671. }
  2672. if (hRsrc == NULL)
  2673. return FALSE;
  2674. HGLOBAL hGlobal = ::LoadResource(hInst, hRsrc);
  2675. if (hGlobal == NULL)
  2676. return FALSE;
  2677. CToolBarData* pData = (CToolBarData*)::LockResource(hGlobal);
  2678. if (pData == NULL)
  2679. return FALSE;
  2680. ASSERT(pData->wVersion == 1);
  2681. UINT* pItems = new UINT[pData->wItemCount];
  2682. for (int i = 0; i < pData->wItemCount; i++)
  2683. pItems[i] = pData->items()[i];
  2684. BOOL bResult = SetButtons(pItems, pData->wItemCount);
  2685. delete[] pItems;
  2686. if (bResult) {
  2687. CSize sizeImage(pData->wWidth, pData->wHeight);
  2688. CSize sizeButton(pData->wWidth + 7, pData->wHeight + 7);
  2689. SetSizes(sizeButton, sizeImage);
  2690. m_iconX = pData->wWidth;
  2691. m_iconY = pData->wHeight;
  2692. bResult = LoadBitmap(lpszResourceName);
  2693. }
  2694. ::UnlockResource(hGlobal);
  2695. ::FreeResource(hGlobal);
  2696. return bResult;
  2697. }
  2698. BOOL BCMenuToolBar::LoadBitmap(LPCTSTR lpszResourceName)
  2699. {
  2700. ASSERT_VALID(this);
  2701. ASSERT(lpszResourceName != NULL);
  2702. HINSTANCE hInstImageWell = AfxFindResourceHandle(lpszResourceName, RT_BITMAP);
  2703. HRSRC hRsrcImageWell = ::FindResource(hInstImageWell, lpszResourceName, RT_BITMAP);
  2704. if (hRsrcImageWell == NULL) {
  2705. hInstImageWell = NULL;
  2706. hRsrcImageWell = ::FindResource(hInstImageWell, lpszResourceName, RT_BITMAP);
  2707. }
  2708. if (hRsrcImageWell == NULL)
  2709. return FALSE;
  2710. HBITMAP hbmImageWell;
  2711. hbmImageWell = AfxLoadSysColorBitmap(hInstImageWell, hRsrcImageWell);
  2712. if (!AddReplaceBitmap(hbmImageWell))
  2713. return FALSE;
  2714. m_hInstImageWell = hInstImageWell;
  2715. m_hRsrcImageWell = hRsrcImageWell;
  2716. return TRUE;
  2717. }