Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1343 lines
39 KiB

  1. //////////////////////////////////////////////////////////////////////////
  2. //
  3. // dlgapp.cpp
  4. //
  5. // This file contains the main entry point into the application and
  6. // the implementation of the CDlgApp class.
  7. //
  8. // (C) Copyright 1997 by Microsoft Corporation. All rights reserved.
  9. //
  10. //////////////////////////////////////////////////////////////////////////
  11. #include <windows.h>
  12. #include <commctrl.h>
  13. #include <shlwapi.h> // for string compare functions
  14. #include <debug.h>
  15. #include <tchar.h>
  16. #include <winuser.h>
  17. #pragma hdrstop
  18. #include "autorun.h"
  19. #include "dlgapp.h"
  20. #include "dataitem.h"
  21. #include "resource.h"
  22. WNDPROC g_fnBtnProc; // the window proc for a button.
  23. //////////////////////////////////////////////////////////////////////////
  24. // #defines
  25. //////////////////////////////////////////////////////////////////////////
  26. // todo: generate these dynamically
  27. #define FLAG_HEIGHT 43
  28. #define FLAG_WIDTH 47
  29. #define HEADER_HEIGHT 48
  30. #define HEADER_WIDTH 48
  31. #define MENUICON_HEIGHT 29
  32. #define MENUICON_WIDTH 28
  33. //////////////////////////////////////////////////////////////////////////
  34. // Code
  35. //////////////////////////////////////////////////////////////////////////
  36. /**
  37. * This method is our contstructor for our class. It initialize all
  38. * of the instance data.
  39. */
  40. CDlgApp::CDlgApp()
  41. {
  42. m_fTaskRunning = FALSE;
  43. m_iSelectedItem = -1;
  44. g_fnBtnProc = NULL;
  45. m_hInstance = NULL;
  46. m_hwnd = NULL;
  47. m_fHighContrast = FALSE;
  48. m_hfontTitle = NULL;
  49. m_hfontHeader = NULL;
  50. m_hfontMenu = NULL;
  51. m_hbrTopPanel = NULL;
  52. m_hbrCenterPanel = NULL;
  53. m_hbrBottomPanel = NULL;
  54. m_szTitle[0] = NULL;
  55. m_szHeader[0] = NULL;
  56. // store desktop width
  57. RECT rcDesktop;
  58. SystemParametersInfo(SPI_GETWORKAREA,0, &rcDesktop, FALSE);
  59. m_cDesktopWidth = rcDesktop.right - rcDesktop.left;
  60. m_cDesktopHeight = rcDesktop.bottom - rcDesktop.top;
  61. if (m_cDesktopWidth >= 800)
  62. {
  63. m_f8by6 = TRUE;
  64. }
  65. else
  66. {
  67. m_f8by6 = FALSE;
  68. }
  69. m_hdcFlag = NULL;
  70. m_hdcHeader = NULL;
  71. m_hdcHeaderSub = NULL;
  72. m_hdcGradientTop = NULL;
  73. m_hdcGradientTop256 = NULL;
  74. m_hdcGradientBottom = NULL;
  75. m_hdcGradientBottom256 = NULL;
  76. m_hdcCloudsFlag = NULL;
  77. m_hdcCloudsFlag256 = NULL;
  78. m_hdcCloudsFlagRTL = NULL;
  79. m_hdcCloudsFlagRTL256 = NULL;
  80. for (int i = 0; i < ARRAYSIZE(m_rghdcArrows); i++)
  81. {
  82. for (int j = 0; j < ARRAYSIZE(m_rghdcArrows[0]); j++)
  83. {
  84. for (int k = 0; k < ARRAYSIZE(m_rghdcArrows[0][0]); k++)
  85. {
  86. m_rghdcArrows[i][j][k] = NULL;
  87. }
  88. }
  89. }
  90. m_hcurHand = NULL;
  91. m_dwScreen = SCREEN_MAIN;
  92. m_fLowColor = FALSE;
  93. m_iColors = -1;
  94. m_hpal = NULL;
  95. }
  96. CDlgApp::~CDlgApp()
  97. {
  98. DeleteObject(m_hfontTitle);
  99. DeleteObject(m_hfontHeader);
  100. DeleteObject(m_hfontMenu);
  101. DeleteObject(m_hbrTopPanel);
  102. DeleteObject(m_hbrCenterPanel);
  103. DeleteObject(m_hbrBottomPanel);
  104. DeleteDC(m_hdcFlag);
  105. DeleteDC(m_hdcHeader);
  106. DeleteDC(m_hdcHeaderSub);
  107. DeleteDC(m_hdcGradientTop);
  108. DeleteDC(m_hdcGradientTop256);
  109. DeleteDC(m_hdcGradientBottom);
  110. DeleteDC(m_hdcGradientBottom256);
  111. DeleteDC(m_hdcCloudsFlag);
  112. DeleteDC(m_hdcCloudsFlag256);
  113. DeleteDC(m_hdcCloudsFlagRTL);
  114. DeleteDC(m_hdcCloudsFlagRTL256);
  115. for (int i = 0; i < ARRAYSIZE(m_rghdcArrows); i++)
  116. {
  117. for (int j = 0; j < ARRAYSIZE(m_rghdcArrows[0]); j++)
  118. {
  119. for (int k = 0; k < ARRAYSIZE(m_rghdcArrows[0][0]); k++)
  120. {
  121. DeleteDC(m_rghdcArrows[i][j][k]);
  122. }
  123. }
  124. }
  125. }
  126. /**
  127. * This method will register our window class for the application.
  128. *
  129. * @param hInstance The application instance handle.
  130. *
  131. * @return No return value.
  132. */
  133. void CDlgApp::Register(HINSTANCE hInstance)
  134. {
  135. WNDCLASS wndclass;
  136. m_hInstance = hInstance;
  137. wndclass.style = CS_OWNDC | CS_DBLCLKS;
  138. wndclass.lpfnWndProc = s_WndProc;
  139. wndclass.cbClsExtra = 0;
  140. wndclass.cbWndExtra = 0;
  141. wndclass.hInstance = hInstance;
  142. wndclass.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WEBAPP));
  143. wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
  144. wndclass.hbrBackground = NULL;
  145. wndclass.lpszMenuName = NULL;
  146. wndclass.lpszClassName = WINDOW_CLASS;
  147. RegisterClass(&wndclass);
  148. }
  149. /**
  150. * This method will initialize the data object.
  151. *
  152. * @return No return value.
  153. */
  154. BOOL CDlgApp::InitializeData(LPSTR pszCommandLine)
  155. {
  156. HWND hwnd = GetDesktopWindow();
  157. HDC hdc = GetDC( hwnd );
  158. m_iColors = GetDeviceCaps( hdc, NUMCOLORS );
  159. m_fLowColor = ((m_iColors != -1) && (m_iColors <= 256));
  160. if ( m_fLowColor )
  161. {
  162. m_hpal = CreateHalftonePalette(hdc);
  163. }
  164. // Initialize the items from the INI file.
  165. if ( !m_DataSrc.Init(pszCommandLine) )
  166. {
  167. // this is a sign from the data source that we should exit
  168. return FALSE;
  169. }
  170. // Are we in accesibility mode? This call won't work on NT 4.0 because this flag wasn't known.
  171. HIGHCONTRAST hc;
  172. hc.cbSize = sizeof(HIGHCONTRAST);
  173. hc.dwFlags = 0; // avoid random result should SPI fail
  174. if ( SystemParametersInfo( SPI_GETHIGHCONTRAST, sizeof(HIGHCONTRAST), &hc, 0 ) )
  175. {
  176. m_fHighContrast = ( hc.dwFlags & HCF_HIGHCONTRASTON );
  177. }
  178. // 210679: go to HighContrast mode if we're in 16-color mode as well
  179. if ( m_fLowColor && (m_iColors <= 16))
  180. {
  181. m_fHighContrast = TRUE;
  182. }
  183. // Set the color table based on our HighContrast mode setting.
  184. _SetColorTable();
  185. // create the fonts that we need to use.
  186. _CreateFonts(hdc);
  187. // create the images
  188. _CreateBitmaps();
  189. _CreateArrowBitmaps();
  190. _CreateGradientBitmaps();
  191. // load the resource strings that we always need
  192. LoadStringAuto( m_hInstance, IDS_TITLE, m_szTitle, ARRAYSIZE(m_szTitle) );
  193. LoadStringAuto( m_hInstance, IDS_HEADER, m_szHeader, ARRAYSIZE(m_szHeader) );
  194. m_hcurHand = LoadCursor( m_hInstance, MAKEINTRESOURCE(IDC_BRHAND) );
  195. ReleaseDC( hwnd, hdc );
  196. return TRUE;
  197. }
  198. #if BUILD_SERVER_VERSION | BUILD_ADVANCED_SERVER_VERSION | BUILD_DATACENTER_VERSION | BUILD_BLADE_VERSION | BUILD_SMALL_BUSINESS_VERSION
  199. #define CENTER_RGB_VALUES RGB(122,131,137)
  200. #define PANEL_RGB_VALUES RGB(63,70,76)
  201. #define DISABLED_RGB_VALUES RGB(64, 64, 64)
  202. #else
  203. #define CENTER_RGB_VALUES RGB(90,126,220)
  204. #define PANEL_RGB_VALUES RGB(59,52,177)
  205. #define DISABLED_RGB_VALUES RGB(128, 128, 128)
  206. #endif
  207. #define TITLE_RGB_VALUES RGB(255, 255, 255)
  208. #define HEADER_RGB_VALUES RGB(214, 223, 245)
  209. #define SHADOW_RGB_VALUES RGB(52, 98, 189)
  210. #define TEXT_RGB_VALUES RGB(255, 255, 255)
  211. BOOL CDlgApp::_SetColorTable()
  212. {
  213. if ( m_fHighContrast )
  214. {
  215. // set to high contrast values
  216. m_hbrTopPanel = (HBRUSH)(COLOR_BTNFACE+1);
  217. m_hbrCenterPanel = (HBRUSH)(COLOR_WINDOW+1);
  218. m_hbrBottomPanel = (HBRUSH)(COLOR_BTNFACE+1);
  219. m_crNormalText = GetSysColor(COLOR_WINDOWTEXT);
  220. m_crTitleText = m_crNormalText;
  221. m_crHeaderText = m_crNormalText;
  222. m_crDisabledText = GetSysColor(COLOR_GRAYTEXT);
  223. m_crCenterPanel = GetSysColor(COLOR_WINDOW);
  224. m_crBottomPanel = GetSysColor(COLOR_WINDOW);
  225. }
  226. else
  227. {
  228. m_crTitleText = TITLE_RGB_VALUES;
  229. m_crHeaderText = HEADER_RGB_VALUES;
  230. m_crShadow = SHADOW_RGB_VALUES;
  231. m_crNormalText = TEXT_RGB_VALUES;
  232. m_crDisabledText = DISABLED_RGB_VALUES;
  233. m_crCenterPanel = CENTER_RGB_VALUES;
  234. m_crBottomPanel = PANEL_RGB_VALUES;
  235. if ( m_fLowColor )
  236. {
  237. HBITMAP hbmp;
  238. hbmp = (HBITMAP)LoadImage(m_hInstance, MAKEINTRESOURCE(IDB_TOP), IMAGE_BITMAP, 0,0, LR_CREATEDIBSECTION);
  239. if (hbmp)
  240. {
  241. m_hbrTopPanel = CreatePatternBrush(hbmp);
  242. DeleteObject(hbmp);
  243. }
  244. else
  245. m_hbrTopPanel = (HBRUSH)(COLOR_BTNFACE+1);
  246. hbmp = (HBITMAP)LoadImage(m_hInstance, MAKEINTRESOURCE(IDB_BOTTOM), IMAGE_BITMAP, 0,0, LR_CREATEDIBSECTION);
  247. if (hbmp)
  248. {
  249. m_hbrBottomPanel = CreatePatternBrush(hbmp);
  250. DeleteObject(hbmp);
  251. }
  252. else
  253. m_hbrBottomPanel = (HBRUSH)(COLOR_BTNFACE+1);
  254. hbmp = (HBITMAP)LoadImage(m_hInstance, MAKEINTRESOURCE(IDB_CENTER), IMAGE_BITMAP, 0,0, LR_CREATEDIBSECTION);
  255. if (hbmp)
  256. {
  257. m_hbrCenterPanel = CreatePatternBrush(hbmp);
  258. DeleteObject(hbmp);
  259. }
  260. else
  261. m_hbrCenterPanel = (HBRUSH)(COLOR_WINDOW+1);
  262. }
  263. else
  264. {
  265. m_hbrTopPanel = CreateSolidBrush( PANEL_RGB_VALUES );
  266. m_hbrCenterPanel = CreateSolidBrush( CENTER_RGB_VALUES );
  267. m_hbrBottomPanel= CreateSolidBrush ( PANEL_RGB_VALUES );
  268. }
  269. }
  270. return TRUE;
  271. }
  272. // this is called once for each font that matches the fonts we care about
  273. int CALLBACK FoundFont
  274. (
  275. ENUMLOGFONTEX *lpelfe, // logical-font data
  276. NEWTEXTMETRICEX *lpntme, // physical-font data
  277. DWORD FontType, // type of font
  278. LPARAM lParam // application-defined data
  279. )
  280. {
  281. *((BOOL*)lParam) = TRUE;
  282. return 0;
  283. }
  284. #define RGFONTDEX_LARGE 0
  285. #define RGFONTDEX_SMALL 1
  286. #define RGFONTDEX_TITLE 0
  287. #define RGFONTDEX_HEADER 1
  288. #define RGFONTDEX_MENU 2
  289. #define RGFONTDEX_FULL 0
  290. #define RGFONTDEX_BACKUP 1
  291. BOOL CDlgApp::_CreateFonts(HDC hdc)
  292. {
  293. // [in] array of IDs, arranged by {title, header, menu} x { nice font, backup font}
  294. const int rgFontID[3][2] =
  295. {{IDS_FONTFACE_TITLE, IDS_FONTFACE_TITLE_BACKUP},
  296. {IDS_FONTFACE_HEADER,IDS_FONTFACE_HEADER_BACKUP},
  297. {IDS_FONTFACE_MENU, IDS_FONTFACE_MENU_BACKUP}};
  298. // [in] array of heights, arranged by {large x small} x {title, header, menu} x { nice font, backup font}
  299. const int rgFontHeight[2][3][2] =
  300. {{{IDS_FONTCY_TITLE, IDS_FONTCY_TITLE_BACKUP},
  301. {IDS_FONTCY_HEADER, IDS_FONTCY_HEADER_BACKUP},
  302. {IDS_FONTCY_MENU, IDS_FONTCY_MENU_BACKUP}},
  303. {{IDS_FONTCY_TITLE_LIL, IDS_FONTCY_TITLE_BACKUP_LIL},
  304. {IDS_FONTCY_HEADER_LIL, IDS_FONTCY_HEADER_BACKUP_LIL},
  305. {IDS_FONTCY_MENU_LIL, IDS_FONTCY_MENU_BACKUP_LIL}}};
  306. // [out] array of pointers to the fonts
  307. HFONT* rgpFont[3] = {&m_hfontTitle, &m_hfontHeader, &m_hfontMenu};
  308. // [out] array of pointers heights of each font
  309. int* rgpcyFont[3] = {&m_cTitleFontHeight, &m_cHeaderFontHeight, &m_cMenuFontHeight};
  310. LOGFONT lf;
  311. CHARSETINFO csInfo;
  312. TCHAR szFontSize[6];
  313. for (int i = 0; i < ARRAYSIZE(rgpFont); i++)
  314. {
  315. ZeroMemory(&lf,sizeof(lf));
  316. lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
  317. lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
  318. lf.lfQuality = DEFAULT_QUALITY;
  319. lf.lfPitchAndFamily = DEFAULT_PITCH|FF_SWISS;
  320. LoadStringAuto( m_hInstance, rgFontID[i][RGFONTDEX_FULL], lf.lfFaceName, ARRAYSIZE(lf.lfFaceName) );
  321. // Set charset
  322. if (TranslateCharsetInfo((DWORD*)IntToPtr(GetACP()), &csInfo, TCI_SRCCODEPAGE) == 0)
  323. {
  324. csInfo.ciCharset = 0;
  325. }
  326. lf.lfCharSet = (BYTE)csInfo.ciCharset;
  327. LoadStringAuto( m_hInstance, rgFontHeight[m_f8by6 ? 0 : 1][i][RGFONTDEX_FULL], szFontSize, ARRAYSIZE(szFontSize) );
  328. *(rgpcyFont[i]) = _ttoi(szFontSize);
  329. lf.lfHeight = -(*(rgpcyFont[i]));
  330. BOOL fFound = FALSE;
  331. EnumFontFamiliesEx(hdc, &lf, (FONTENUMPROC)FoundFont, (LPARAM)&fFound, 0);
  332. if (!fFound)
  333. {
  334. LoadStringAuto( m_hInstance, rgFontID[i][RGFONTDEX_BACKUP], lf.lfFaceName, ARRAYSIZE(lf.lfFaceName) );
  335. LoadStringAuto( m_hInstance, rgFontHeight[m_f8by6 ? 0 : 1][i][RGFONTDEX_BACKUP], szFontSize, ARRAYSIZE(szFontSize) );
  336. *(rgpcyFont[i]) = _ttoi(szFontSize);
  337. lf.lfHeight = -(*(rgpcyFont[i]));
  338. }
  339. *(rgpFont[i]) = CreateFontIndirect(&lf);
  340. }
  341. return TRUE;
  342. }
  343. #define BITMAPTYPE_NORMAL 0x0
  344. #define BITMAPTYPE_LOWCOLOR 0x1
  345. BOOL CDlgApp::_CreateBitmaps()
  346. {
  347. const int rgiBitmapID[3][2] = {{ IDB_FLAG, IDB_FLAG_256},
  348. { IDB_HEADER, IDB_HEADER_256} ,
  349. { IDB_HEADERSUB, IDB_HEADERSUB_256} }; // [in]
  350. HDC* rgphdc[3] = {&m_hdcFlag, &m_hdcHeader, &m_hdcHeaderSub}; // [out]
  351. int iBitmapType = (m_fLowColor) ? BITMAPTYPE_LOWCOLOR : BITMAPTYPE_NORMAL;
  352. for (int i = 0; i < ARRAYSIZE(rgphdc); i++)
  353. {
  354. HBITMAP hbm;
  355. BITMAP bm;
  356. *(rgphdc[i]) = CreateCompatibleDC(NULL);
  357. hbm = (HBITMAP)LoadImage(m_hInstance, MAKEINTRESOURCE(rgiBitmapID[i][iBitmapType]), IMAGE_BITMAP, 0,0, LR_CREATEDIBSECTION);
  358. GetObject(hbm,sizeof(bm),&bm);
  359. SelectObject( *(rgphdc[i]), hbm );
  360. }
  361. return TRUE;
  362. }
  363. BOOL CDlgApp::_CreateArrowBitmaps()
  364. {
  365. const int rgiBitmapID[2][4][3] =
  366. {{{IDB_YELLOW, IDB_YELLOW_HOVER, IDB_YELLOW_DISABLED},
  367. {IDB_RED, IDB_RED_HOVER, IDB_RED_DISABLED},
  368. {IDB_GREEN, IDB_GREEN_HOVER, IDB_GREEN_DISABLED},
  369. {IDB_BLUE, IDB_BLUE_HOVER, IDB_BLUE_DISABLED}},
  370. {{IDB_YELLOW_256, IDB_YELLOW_HOVER_256, IDB_YELLOW_DISABLED_256},
  371. {IDB_RED_256, IDB_RED_HOVER_256, IDB_RED_DISABLED_256},
  372. {IDB_GREEN_256, IDB_GREEN_HOVER_256, IDB_GREEN_DISABLED_256},
  373. {IDB_BLUE_256, IDB_BLUE_HOVER_256, IDB_BLUE_DISABLED_256}}}; // [in]
  374. for (int i = 0; i < ARRAYSIZE(m_rghdcArrows); i++)
  375. {
  376. for (int j = 0; j < ARRAYSIZE(m_rghdcArrows[0]); j++)
  377. {
  378. for (int k = 0; k < ARRAYSIZE(m_rghdcArrows[0][0]); k++)
  379. {
  380. HBITMAP hbm;
  381. BITMAP bm;
  382. m_rghdcArrows[i][j][k] = CreateCompatibleDC(NULL);
  383. hbm = (HBITMAP)LoadImage(m_hInstance, MAKEINTRESOURCE(rgiBitmapID[i][j][k]), IMAGE_BITMAP, 0,0, LR_CREATEDIBSECTION);
  384. GetObject(hbm,sizeof(bm),&bm);
  385. SelectObject( m_rghdcArrows[i][j][k], hbm );
  386. }
  387. }
  388. }
  389. return TRUE;
  390. }
  391. BOOL CDlgApp::_CreateGradientBitmaps()
  392. {
  393. const int rgiBitmapID[8] = {IDB_GRADIENT_TOP, IDB_GRADIENT_TOP_256, IDB_GRADIENT_BOTTOM, IDB_GRADIENT_BOTTOM_256, IDB_CLOUDSFLAG, IDB_CLOUDSFLAG_256, IDB_CLOUDSFLAG_RTL, IDB_CLOUDSFLAG_RTL_256}; // [in]
  394. HDC* rgphdc[8] = {&m_hdcGradientTop, &m_hdcGradientTop256, &m_hdcGradientBottom, &m_hdcGradientBottom256, &m_hdcCloudsFlag, &m_hdcCloudsFlag256, &m_hdcCloudsFlagRTL, &m_hdcCloudsFlagRTL256}; // [out]
  395. for (int i = 0; i < ARRAYSIZE(rgphdc); i++)
  396. {
  397. HBITMAP hbm;
  398. BITMAP bm;
  399. *(rgphdc[i]) = CreateCompatibleDC(NULL);
  400. hbm = (HBITMAP)LoadImage(m_hInstance, MAKEINTRESOURCE(rgiBitmapID[i]), IMAGE_BITMAP, 0,0, LR_CREATEDIBSECTION);
  401. GetObject(hbm,sizeof(bm),&bm);
  402. SelectObject( *(rgphdc[i]), hbm );
  403. }
  404. return TRUE;
  405. }
  406. BOOL CDlgApp::_GetLargestStringWidth(HDC hdc, SIZE* psize)
  407. {
  408. SIZE sCurr = {0};
  409. psize->cx = 0;
  410. psize->cy = 0;
  411. for (int i = 0; i < MAX_OPTIONS; i++)
  412. {
  413. if (GetTextExtentPoint32(hdc, m_DataSrc[i].GetTitle(), lstrlen(m_DataSrc[i].GetTitle()), &sCurr))
  414. {
  415. if (sCurr.cx > psize->cx)
  416. {
  417. memcpy(psize, &sCurr, sizeof(SIZE));
  418. }
  419. }
  420. }
  421. return (psize->cx > 0);
  422. }
  423. #define MENUITEMCX(x) (m_f8by6 ? 270 : 210)
  424. #define MENUITEMCY(x) ((m_f8by6 ? 245 : 197) + ((x - 1) * (m_f8by6 ? 45 : 30)))
  425. #define MENUEXITCX(x) (m_f8by6 ? 75 : 63)
  426. #define MENUEXITCY(x) (m_f8by6 ? 540 : 406)
  427. BOOL CDlgApp::_AdjustToFitFonts()
  428. {
  429. HDC hdc = GetDC(m_hwnd);
  430. if (hdc)
  431. {
  432. SetMapMode(hdc,MM_TEXT);
  433. // don't check for error, if these fail we're totally screwed anyway
  434. SIZE sizeLargest, sizeExit = {0};
  435. _GetLargestStringWidth(hdc, &sizeLargest);
  436. GetTextExtentPoint32(hdc, m_DataSrc[0].GetTitle(), lstrlen(m_DataSrc[0].GetTitle()), &sizeExit);
  437. for (int i=0; i < MAX_MENUITEMS; i++ )
  438. {
  439. DWORD dwType = m_DataSrc[i].m_dwType;
  440. HWND hwnd = GetDlgItem(m_hwnd, IDM_MENUITEM0+i);
  441. SIZE* psize = (i == 0) ? &sizeExit: &sizeLargest;
  442. SetWindowPos(hwnd, NULL,
  443. (i == 0) ? MENUEXITCX(i) : MENUITEMCX(i),
  444. (i == 0) ? MENUEXITCY(i) : MENUITEMCY(i),
  445. (psize->cx * 3) / 2, (psize->cy * 3) / 2, SWP_NOZORDER );
  446. }
  447. ReleaseDC(m_hwnd, hdc);
  448. }
  449. return TRUE;
  450. }
  451. #define MENUARROWCX(x) (m_f8by6 ? 232 : 177)
  452. #define MENUARROWCY(x) ((m_f8by6 ? 244 : 194) + ((x - 1)* (m_f8by6 ? 45 : 30)))
  453. #define EXITARROWCX(x) (m_f8by6 ? 42 : 32)
  454. #define EXITARROWCY(x) (m_f8by6 ? 537 : 403)
  455. #define ARROWBITMAPSTUFF(rgarrows) if (WF_DISABLED & m_DataSrc[i].m_dwFlags) { phdcBitmap = &(rgarrows[2]); } else { phdcBitmap = (m_iSelectedItem == i) ? &(rgarrows[1]) : &(rgarrows[0]); }
  456. #define EXITARROWBITMAPSTUFF(rgarrows) {phdcBitmap = (m_iSelectedItem == i) ? &(rgarrows[1]) : &(rgarrows[0]);}
  457. BOOL CDlgApp::_DrawMenuIcons(BOOL fEraseBackground)
  458. {
  459. HDC hdc = GetDC(m_hwnd);
  460. if (hdc)
  461. {
  462. for (int i=0; i< m_DataSrc.m_iItems; i++ )
  463. {
  464. RECT rect;
  465. HDC* phdcBitmap;
  466. DWORD dwType = m_DataSrc[i].m_dwType;
  467. switch (dwType)
  468. {
  469. case INSTALL_WINNT: // special
  470. ARROWBITMAPSTUFF(m_rghdcArrows[m_fLowColor ? 1 : 0][2]);
  471. break;
  472. case EXIT_AUTORUN: // exit
  473. EXITARROWBITMAPSTUFF(m_rghdcArrows[m_fLowColor ? 1 : 0][1]);
  474. break;
  475. case BACK: // back icon
  476. ARROWBITMAPSTUFF(m_rghdcArrows[m_fLowColor ? 1 : 0][0]);
  477. break;
  478. default: // normal icon for everything else
  479. ARROWBITMAPSTUFF(m_rghdcArrows[m_fLowColor ? 1 : 0][3]);
  480. break;
  481. }
  482. rect.left = (i == 0) ? (EXITARROWCX(i)) : (MENUARROWCX(i));
  483. rect.top = (i == 0) ? (EXITARROWCY(i)) : (MENUARROWCY(i));
  484. rect.right = rect.left + MENUICON_WIDTH; // arrow width
  485. rect.bottom = rect.top + MENUICON_HEIGHT; // arrow height as well
  486. BitBlt( hdc, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, *phdcBitmap, 0,0, SRCCOPY );
  487. _InvalidateRectIntl(m_hwnd, &rect, FALSE);
  488. }
  489. ReleaseDC(m_hwnd, hdc);
  490. }
  491. // clear any old icons as well
  492. RECT rect;
  493. rect.left = MENUARROWCX(0);
  494. rect.right = rect.left + MENUICON_WIDTH; // arrow width
  495. rect.top = MENUARROWCY(0);
  496. rect.bottom = m_cyClient;
  497. _InvalidateRectIntl(m_hwnd, &rect, fEraseBackground);
  498. return TRUE;
  499. }
  500. void CDlgApp::_InvalidateRectIntl(HWND hwnd, RECT* pRect, BOOL fBackgroundClear)
  501. {
  502. RECT* pRectToUse = pRect; // default to normal case (don't flip)
  503. RECT rectRTL;
  504. if (pRect)
  505. {
  506. OSVERSIONINFO osvi;
  507. if (GetVersionEx(&osvi) &&
  508. (osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) &&
  509. Mirror_IsWindowMirroredRTL(hwnd)) // right to left on Win9X
  510. {
  511. rectRTL.top = pRect->top; rectRTL.bottom = pRect->bottom;
  512. rectRTL.right = m_cxClient - pRect->left;
  513. rectRTL.left = m_cxClient - pRect->right;
  514. pRectToUse = &rectRTL;
  515. }
  516. }
  517. InvalidateRect(hwnd, pRectToUse, fBackgroundClear);
  518. }
  519. /**
  520. * This method will create the application window.
  521. *
  522. * @return No return value.
  523. */
  524. void CDlgApp::Create(int nCmdShow)
  525. {
  526. //
  527. // load the window title from the resource.
  528. //
  529. TCHAR szTitle[MAX_PATH];
  530. LoadStringAuto(m_hInstance, IDS_TITLEBAR, szTitle, ARRAYSIZE(szTitle));
  531. DWORD dwStyle = WS_OVERLAPPED | WS_MINIMIZEBOX | WS_CAPTION | WS_SYSMENU | WS_BORDER | WS_CLIPCHILDREN;
  532. if (m_cDesktopWidth >= 800)
  533. {
  534. m_cxClient = 800;
  535. m_cyClient = 600;
  536. }
  537. else
  538. {
  539. m_cxClient = 640;
  540. m_cyClient = 480;
  541. }
  542. m_hwnd = CreateWindowEx(
  543. WS_EX_CONTROLPARENT,
  544. WINDOW_CLASS,
  545. szTitle,
  546. dwStyle,
  547. 0,
  548. 0,
  549. m_cxClient,
  550. m_cyClient,
  551. NULL,
  552. NULL,
  553. m_hInstance,
  554. this);
  555. // set the client area to a fixed size and center the window on screen
  556. RECT rect = {0};
  557. rect.left = (m_cDesktopWidth - m_cxClient) / 2;
  558. rect.top = (m_cDesktopHeight - m_cyClient) / 2;
  559. rect.right = m_cDesktopWidth - rect.left;
  560. rect.bottom = m_cDesktopHeight - rect.top;
  561. AdjustWindowRect( &rect, dwStyle, FALSE );
  562. SetWindowPos(m_hwnd, HWND_TOP, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, 0);
  563. ShowWindow(m_hwnd, SW_SHOW);
  564. m_cxTopPanel = m_f8by6 ? 80 : 64;
  565. m_cyBottomPanel = m_f8by6 ? 501 : 381;
  566. m_DataSrc.SetWindow( m_hwnd );
  567. _InvalidateRectIntl(m_hwnd, NULL, TRUE);
  568. UpdateWindow(m_hwnd);
  569. }
  570. /**
  571. * This method is our application message loop.
  572. *
  573. * @return No return value.
  574. */
  575. void CDlgApp::MessageLoop()
  576. {
  577. MSG msg;
  578. while (GetMessage(&msg, NULL, 0, 0))
  579. {
  580. // IsDialogMessage cannot understand the concept of ownerdraw default pushbuttons. It treats
  581. // these attributes as mutually exclusive. As a result, we handle this ourselves. We want
  582. // whatever control has focus to act as the default pushbutton.
  583. if ( (WM_KEYDOWN == msg.message) && (VK_RETURN == msg.wParam) )
  584. {
  585. HWND hwndFocus = GetFocus();
  586. if ( hwndFocus )
  587. {
  588. SendMessage(m_hwnd, WM_COMMAND, MAKELONG(GetDlgCtrlID(hwndFocus), BN_CLICKED), (LPARAM)hwndFocus);
  589. }
  590. continue;
  591. }
  592. if ( IsDialogMessage(m_hwnd, &msg) )
  593. continue;
  594. TranslateMessage(&msg);
  595. DispatchMessage(&msg);
  596. }
  597. }
  598. /**
  599. * This is the window procedure for the container application. It is used
  600. * to deal with all messages to our window.
  601. *
  602. * @param hwnd Window handle.
  603. * @param msg The window message.
  604. * @param wParam Window Parameter.
  605. * @param lParam Window Parameter.
  606. *
  607. * @return LRESULT
  608. */
  609. LRESULT CALLBACK CDlgApp::s_WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
  610. {
  611. CDlgApp *pThis = (CDlgApp *)GetWindowLongPtr(hwnd, GWLP_USERDATA);
  612. switch(msg)
  613. {
  614. case WM_NCCREATE:
  615. {
  616. CDlgApp* pThisCreate = (CDlgApp *)(((LPCREATESTRUCT)lParam)->lpCreateParams);
  617. SetWindowLongPtr(hwnd, GWLP_USERDATA, (LRESULT)pThisCreate);
  618. }
  619. break;
  620. case WM_CREATE:
  621. return pThis->OnCreate(hwnd);
  622. case WM_DESTROY:
  623. return pThis->OnDestroy();
  624. case WM_ACTIVATE:
  625. return pThis->OnActivate(wParam);
  626. case WM_PAINT:
  627. return pThis->OnPaint((HDC)wParam);
  628. case WM_ERASEBKGND:
  629. return pThis->OnEraseBkgnd((HDC)wParam);
  630. case WM_LBUTTONUP:
  631. return pThis->OnLButtonUp(LOWORD(lParam), HIWORD(lParam), (DWORD)wParam);
  632. case WM_MOUSEMOVE:
  633. return pThis->OnMouseMove(LOWORD(lParam), HIWORD(lParam), (DWORD)wParam);
  634. case WM_SETCURSOR:
  635. return pThis->OnSetCursor((HWND)wParam, LOWORD(lParam), HIWORD(lParam));
  636. case WM_COMMAND:
  637. case WM_SYSCOMMAND:
  638. if ( pThis->OnCommand(LOWORD(wParam)) )
  639. return 0;
  640. break;
  641. case WM_DRAWITEM:
  642. return pThis->OnDrawItem((UINT)wParam, (LPDRAWITEMSTRUCT)lParam);
  643. case WM_QUERYNEWPALETTE:
  644. return pThis->OnQueryNewPalette();
  645. case WM_PALETTECHANGED:
  646. return pThis->OnPaletteChanged((HWND)wParam);
  647. case ARM_CHANGESCREEN:
  648. return pThis->OnChangeScreen((DWORD)wParam);
  649. }
  650. return DefWindowProc(hwnd, msg, wParam, lParam);
  651. }
  652. /**
  653. * This method is called on WM_CREATE.
  654. *
  655. * @param hwnd Window handle for the application.
  656. *
  657. * @return No return value.
  658. */
  659. LRESULT CDlgApp::OnCreate(HWND hwnd)
  660. {
  661. m_hwnd = hwnd;
  662. _CreateMenu();
  663. _RedrawMenu();
  664. return 0;
  665. }
  666. void CDlgApp::_CreateMenu()
  667. {
  668. // Create one window for each button. These windows will get resized and moved
  669. // after we call AdjustToFitFonts.
  670. for (int i=0; i<MAX_MENUITEMS; i++)
  671. {
  672. HWND hwnd = CreateWindowEx(
  673. 0,
  674. TEXT("BUTTON"),
  675. TEXT(""),
  676. WS_CHILD|WS_VISIBLE|WS_TABSTOP|BS_PUSHBUTTON|BS_MULTILINE|BS_OWNERDRAW,
  677. 0,0,0,0,
  678. m_hwnd,
  679. NULL,
  680. m_hInstance,
  681. NULL );
  682. SetWindowLongPtr(hwnd, GWLP_ID, IDM_MENUITEM0 + i);
  683. SendMessage(hwnd, WM_SETFONT, (WPARAM)m_hfontMenu, 0);
  684. g_fnBtnProc = (WNDPROC)SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)s_ButtonWndProc);
  685. EnableWindow(hwnd, i < m_DataSrc.m_iItems);
  686. }
  687. // Set focus to first menu item
  688. SetFocus(GetDlgItem(m_hwnd, IDM_MENUITEM1));
  689. // We created the windows with zero size, now we adjust that size to take into
  690. // account for the selected font size, etc.
  691. _AdjustToFitFonts();
  692. }
  693. void CDlgApp::_RedrawMenu()
  694. {
  695. for (int i=0; i < MAX_MENUITEMS; i++)
  696. {
  697. // setting window text only actually sets the accelerator, real drawing of text is in OnDrawItem
  698. SetWindowText(GetDlgItem(m_hwnd, IDM_MENUITEM0+i), (i < m_DataSrc.m_iItems) ? m_DataSrc[i].GetTitle() : TEXT(""));
  699. EnableWindow(GetDlgItem(m_hwnd, IDM_MENUITEM0+i), (i < m_DataSrc.m_iItems));
  700. }
  701. }
  702. /**
  703. * This method handles the WM_DESTROY message.
  704. *
  705. * @return No return value.
  706. */
  707. LRESULT CDlgApp::OnDestroy()
  708. {
  709. // ensure this is the last message we care about
  710. SetWindowLongPtr(m_hwnd, GWLP_USERDATA, 0);
  711. PostQuitMessage(0);
  712. return 0;
  713. }
  714. LRESULT CDlgApp::OnActivate(WPARAM wParam)
  715. {
  716. return 0;
  717. }
  718. /**
  719. * This method handles the WM_PAINT message.
  720. *
  721. * @return No return value.
  722. */
  723. LRESULT CDlgApp::OnPaint(HDC hdc)
  724. {
  725. // this code makes the window look better when being dragged around
  726. PAINTSTRUCT ps;
  727. BeginPaint(m_hwnd,&ps);
  728. EndPaint(m_hwnd,&ps);
  729. return 0;
  730. }
  731. /**
  732. * This method handles the WM_ERASEBKGND message.
  733. *
  734. * @return No return value.
  735. */
  736. LRESULT CDlgApp::OnEraseBkgnd(HDC hdc)
  737. {
  738. RECT rect;
  739. HPALETTE hpalOld = NULL;
  740. if ( m_hpal )
  741. {
  742. hpalOld = SelectPalette(hdc, m_hpal, FALSE);
  743. RealizePalette(hdc);
  744. }
  745. SetMapMode(hdc, MM_TEXT);
  746. SetBkMode(hdc, TRANSPARENT);
  747. // Draw the top pane:
  748. rect.left = 0;
  749. rect.top = 0;
  750. rect.right = m_cxClient;
  751. rect.bottom = m_cxTopPanel;
  752. if (m_f8by6 && !m_fLowColor)
  753. {
  754. BitBlt( hdc, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, m_hdcGradientTop, 0,0, SRCCOPY );
  755. }
  756. else if (m_f8by6 && m_fLowColor && (m_iColors > 16))
  757. {
  758. BitBlt( hdc, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, m_hdcGradientTop256, 0,0, SRCCOPY );
  759. }
  760. else
  761. {
  762. FillRect(hdc, &rect, m_hbrTopPanel);
  763. }
  764. // Draw the center pane:
  765. rect.left = 0;
  766. rect.top = m_cxTopPanel;
  767. rect.right = m_cxClient;
  768. rect.bottom = m_cyBottomPanel;
  769. FillRect(hdc, &rect, m_hbrCenterPanel);
  770. // Drag the clouds/flag bitmap
  771. if (m_f8by6)
  772. {
  773. rect.left = 0;
  774. rect.top = m_cxTopPanel;
  775. rect.right = 397;
  776. rect.bottom = m_cxTopPanel + 180;
  777. HDC hdcCloudsFlag;
  778. if (Mirror_IsWindowMirroredRTL(m_hwnd))
  779. {
  780. hdcCloudsFlag = m_fLowColor? m_hdcCloudsFlagRTL256 : m_hdcCloudsFlagRTL;
  781. }
  782. else
  783. {
  784. hdcCloudsFlag = m_fLowColor? m_hdcCloudsFlag256 : m_hdcCloudsFlag;
  785. }
  786. BitBlt( hdc, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, hdcCloudsFlag , 0,0, SRCCOPY | NOMIRRORBITMAP);
  787. }
  788. // Draw the bottom pane:
  789. rect.left = 0;
  790. rect.top = m_cyBottomPanel;
  791. rect.right = m_cxClient;
  792. rect.bottom = m_cyClient;
  793. if (m_f8by6 && !m_fLowColor)
  794. {
  795. BitBlt( hdc, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top + 1, m_hdcGradientBottom, 0,0, SRCCOPY );
  796. }
  797. else if (m_f8by6 && m_fLowColor && (m_iColors > 16))
  798. {
  799. BitBlt( hdc, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top + 1, m_hdcGradientBottom256, 0,0, SRCCOPY );
  800. }
  801. else
  802. {
  803. FillRect(hdc, &rect, m_hbrBottomPanel);
  804. }
  805. // Draw the flag bitmap if in 640x480
  806. if (!m_f8by6)
  807. {
  808. rect.left = 20;
  809. rect.top = 80;
  810. rect.right = rect.left + FLAG_WIDTH;
  811. rect.bottom = rect.top + FLAG_HEIGHT;
  812. BitBlt( hdc, rect.left, rect.top, FLAG_WIDTH, FLAG_HEIGHT, m_hdcFlag, 0,0, SRCCOPY | NOMIRRORBITMAP); // don't mirror flag on RTL systems for trademark reasons
  813. }
  814. // Draw the header bitmap:
  815. _PaintHeaderBitmap();
  816. // draw menu icons
  817. _DrawMenuIcons(FALSE);
  818. // draw header text
  819. if (m_f8by6)
  820. {
  821. rect.left = 237;
  822. rect.top = 192;
  823. }
  824. else
  825. {
  826. rect.left = 197;
  827. rect.top = 142;
  828. }
  829. rect.right = rect.left + 400;
  830. rect.bottom = rect.top + m_cHeaderFontHeight;
  831. HFONT hfontOld = (HFONT)SelectObject(hdc,m_hfontHeader);
  832. if ( !m_fHighContrast )
  833. {
  834. SetTextColor(hdc,m_crShadow);
  835. DrawText(hdc,m_szHeader,-1,&rect,DT_NOCLIP|DT_WORDBREAK);
  836. }
  837. _InvalidateRectIntl(m_hwnd, &rect, FALSE);
  838. rect.left -= 2; rect.right -= 2; rect.top -= 2; rect.bottom -= 2;
  839. SetTextColor(hdc,m_crHeaderText);
  840. DrawText(hdc,m_szHeader,-1,&rect,DT_NOCLIP|DT_WORDBREAK);
  841. _InvalidateRectIntl(m_hwnd, &rect, FALSE);
  842. // draw title text
  843. if (m_f8by6)
  844. {
  845. rect.left = 97;
  846. rect.top = 105;
  847. }
  848. else
  849. {
  850. rect.left = 72;
  851. rect.top = 63;
  852. }
  853. rect.right = rect.left + 700;
  854. rect.bottom = rect.top + m_cTitleFontHeight;
  855. (HFONT)SelectObject(hdc,m_hfontTitle);
  856. if ( !m_fHighContrast )
  857. {
  858. SetTextColor(hdc,m_crShadow);
  859. DrawText(hdc,m_szTitle,-1,&rect,DT_NOCLIP|DT_WORDBREAK);
  860. }
  861. rect.left -= 2; rect.right -= 2; rect.top -= 2; rect.bottom -= 2;
  862. SetTextColor(hdc,m_crTitleText);
  863. DrawText(hdc,m_szTitle,-1,&rect,DT_NOCLIP|DT_WORDBREAK);
  864. // restore the DC to its original value
  865. SelectObject(hdc,hfontOld);
  866. if(hpalOld)
  867. SelectPalette(hdc, hpalOld, FALSE);
  868. return TRUE;
  869. }
  870. void CDlgApp::_PaintHeaderBitmap()
  871. {
  872. HDC hdc = GetDC(m_hwnd);
  873. if (hdc)
  874. {
  875. RECT rect;
  876. if (m_f8by6)
  877. {
  878. rect.left = 177;
  879. rect.top = 186;
  880. }
  881. else
  882. {
  883. rect.left = 137;
  884. rect.top = 133;
  885. }
  886. rect.right = rect.left + HEADER_WIDTH;
  887. rect.bottom = rect.top + HEADER_HEIGHT;
  888. BitBlt( hdc, rect.left, rect.top, HEADER_WIDTH, HEADER_HEIGHT, (SCREEN_MAIN == m_dwScreen) ? m_hdcHeader : m_hdcHeaderSub, 0,0, SRCCOPY );
  889. _InvalidateRectIntl(m_hwnd, &rect, FALSE);
  890. ReleaseDC(m_hwnd, hdc);
  891. }
  892. }
  893. LRESULT CDlgApp::OnMouseMove(int x, int y, DWORD fwKeys)
  894. {
  895. if (GetForegroundWindow() == m_hwnd) // only care if we have focus
  896. {
  897. POINT pt;
  898. pt.x = x;
  899. pt.y = y;
  900. for (int i=0; i<m_DataSrc.m_iItems; i++)
  901. {
  902. HWND hwnd = GetDlgItem(m_hwnd, IDM_MENUITEM0+i);
  903. RECT rect;
  904. rect.left = (i > 0) ? MENUARROWCX(i) : EXITARROWCX(i);
  905. rect.top = (i > 0) ? MENUARROWCY(i) : EXITARROWCY(i);
  906. rect.right = rect.left + MENUICON_WIDTH;
  907. rect.bottom = rect.top + MENUICON_HEIGHT;
  908. if (PtInRect(&rect, pt))
  909. {
  910. SetFocus(GetDlgItem(m_hwnd, IDM_MENUITEM0 + i));
  911. SetCursor(m_hcurHand);
  912. return 0;
  913. }
  914. }
  915. SetCursor(LoadCursor(NULL,IDC_ARROW));
  916. }
  917. return 0;
  918. }
  919. LRESULT CDlgApp::OnLButtonUp(int x, int y, DWORD fwKeys)
  920. {
  921. if (GetForegroundWindow() == m_hwnd) // only care if we have focus
  922. {
  923. POINT pt;
  924. pt.x = x;
  925. pt.y = y;
  926. for (int i=0; i<m_DataSrc.m_iItems; i++)
  927. {
  928. HWND hwnd = GetDlgItem(m_hwnd, IDM_MENUITEM0+i);
  929. RECT rect;
  930. rect.left = (i > 0) ? MENUARROWCX(i) : EXITARROWCX(i);
  931. rect.top = (i > 0) ? MENUARROWCY(i) : EXITARROWCY(i);
  932. rect.right = rect.left + MENUICON_WIDTH;
  933. rect.bottom = rect.top + MENUICON_HEIGHT;
  934. if (PtInRect(&rect, pt))
  935. {
  936. OnCommand(IDM_MENUITEM0 + i);
  937. return 0;
  938. }
  939. }
  940. }
  941. return 0;
  942. }
  943. LRESULT CDlgApp::OnSetCursor(HWND hwnd, int nHittest, int wMouseMsg)
  944. {
  945. if (GetForegroundWindow() == m_hwnd) // only care if we have focus
  946. {
  947. if ( !m_fTaskRunning )
  948. {
  949. if ( hwnd != m_hwnd )
  950. {
  951. SetCursor(m_hcurHand);
  952. return TRUE;
  953. }
  954. }
  955. SetCursor(LoadCursor(NULL,IDC_ARROW));
  956. }
  957. return TRUE;
  958. }
  959. LRESULT CDlgApp::OnChangeScreen(DWORD dwScreen)
  960. {
  961. static DWORD dwSelectedOld; // we store the last position on the main screen
  962. if (m_dwScreen != dwScreen)
  963. {
  964. m_dwScreen = dwScreen;
  965. _RedrawMenu();
  966. _DrawMenuIcons(TRUE);
  967. UpdateWindow(m_hwnd);
  968. _PaintHeaderBitmap();
  969. if (SCREEN_MAIN == dwScreen) // if switching back to main, restore selection
  970. {
  971. m_iSelectedItem = dwSelectedOld;
  972. }
  973. else // otherwise default to the first item in the selection
  974. {
  975. dwSelectedOld = m_iSelectedItem;
  976. m_iSelectedItem = 1;
  977. }
  978. SetFocus(GetDlgItem(m_hwnd, IDM_MENUITEM0 + m_iSelectedItem));
  979. }
  980. return TRUE;
  981. }
  982. LRESULT CDlgApp::OnCommand(int wID)
  983. {
  984. if ( !m_fTaskRunning )
  985. {
  986. int iNewSelectedItem = m_iSelectedItem;
  987. BOOL fRun = FALSE;
  988. switch(wID)
  989. {
  990. case IDM_MENUITEM0:
  991. PostQuitMessage( 0 );
  992. break;
  993. case IDM_MENUITEM1:
  994. case IDM_MENUITEM2:
  995. case IDM_MENUITEM3:
  996. case IDM_MENUITEM4:
  997. case IDM_MENUITEM5:
  998. case IDM_MENUITEM6:
  999. case IDM_MENUITEM7:
  1000. fRun = TRUE;
  1001. m_iSelectedItem = wID - IDM_MENUITEM0;
  1002. // m_iSelectedItem should be a real menu item now, but just to make sure:
  1003. ASSERT( (m_iSelectedItem < m_DataSrc.m_iItems) && (m_iSelectedItem >= 0) );
  1004. break;
  1005. default:
  1006. // When we hit this then this isn't a message we care about. We return FALSE which
  1007. // tells our WndProc to call DefWndProc which makes everything happy.
  1008. return FALSE;
  1009. }
  1010. if ( fRun )
  1011. {
  1012. m_fTaskRunning = TRUE;
  1013. m_DataSrc.Invoke( m_iSelectedItem, m_hwnd );
  1014. m_fTaskRunning = FALSE;
  1015. }
  1016. }
  1017. else
  1018. {
  1019. // currently the only commands that are valid while another task is running are
  1020. // IDM_SHOWCHECK and anything that goes to the default handler above. Everything
  1021. // else will come to here and cause a message beep
  1022. MessageBeep(0);
  1023. }
  1024. return TRUE;
  1025. }
  1026. LRESULT CDlgApp::OnQueryNewPalette()
  1027. {
  1028. if ( m_hpal )
  1029. {
  1030. HDC hdc = GetDC(m_hwnd);
  1031. if (hdc)
  1032. {
  1033. HPALETTE hpalOld = SelectPalette(hdc, m_hpal, FALSE);
  1034. UnrealizeObject(m_hpal);
  1035. RealizePalette(hdc);
  1036. UpdateWindow(m_hwnd);
  1037. if(hpalOld)
  1038. SelectPalette(hdc, hpalOld, FALSE);
  1039. ReleaseDC(m_hwnd, hdc);
  1040. }
  1041. return TRUE;
  1042. }
  1043. return FALSE;
  1044. }
  1045. LRESULT CDlgApp::OnPaletteChanged(HWND hwnd)
  1046. {
  1047. if ( m_hpal && (m_hwnd != hwnd) )
  1048. {
  1049. HDC hdc = GetDC(m_hwnd);
  1050. if (hdc)
  1051. {
  1052. HPALETTE hpalOld = SelectPalette(hdc, m_hpal, FALSE);
  1053. RealizePalette(hdc);
  1054. UpdateColors(hdc);
  1055. if (hpalOld)
  1056. SelectPalette(hdc, hpalOld, FALSE);
  1057. ReleaseDC(m_hwnd, hdc);
  1058. }
  1059. }
  1060. return TRUE;
  1061. }
  1062. LRESULT CDlgApp::OnDrawItem(UINT iCtlID, LPDRAWITEMSTRUCT pdis)
  1063. {
  1064. int i = iCtlID - IDM_MENUITEM0;
  1065. RECT rect = pdis->rcItem;
  1066. HPALETTE hpalOld = NULL;
  1067. if ( m_hpal )
  1068. {
  1069. hpalOld = SelectPalette(pdis->hDC, m_hpal, FALSE);
  1070. RealizePalette(pdis->hDC);
  1071. }
  1072. FillRect( pdis->hDC, &rect, (i > 0) ? m_hbrCenterPanel : m_hbrBottomPanel);
  1073. if (i < m_DataSrc.m_iItems)
  1074. {
  1075. SetBkMode(pdis->hDC, TRANSPARENT);
  1076. SetTextColor(
  1077. pdis->hDC,
  1078. ((m_DataSrc[i].m_dwFlags&WF_ALTERNATECOLOR)?m_crDisabledText:m_crNormalText));
  1079. DrawText(pdis->hDC,m_DataSrc[i].GetTitle(),-1,&rect,DT_NOCLIP|DT_WORDBREAK);
  1080. if ( pdis->itemState & ODS_FOCUS )
  1081. {
  1082. if ( m_fHighContrast )
  1083. {
  1084. rect.left -= 1;
  1085. rect.top -= 2;
  1086. rect.right += 1;
  1087. rect.bottom -= 2;
  1088. DrawFocusRect(pdis->hDC,&rect);
  1089. }
  1090. }
  1091. }
  1092. if ( hpalOld )
  1093. {
  1094. SelectPalette(pdis->hDC, hpalOld, FALSE);
  1095. }
  1096. _DrawMenuIcons(FALSE);
  1097. return TRUE;
  1098. }
  1099. LRESULT CALLBACK CDlgApp::s_ButtonWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  1100. {
  1101. CDlgApp *pThis = (CDlgApp *)GetWindowLongPtr(GetParent(hwnd), GWLP_USERDATA);
  1102. switch (uMsg)
  1103. {
  1104. case WM_ERASEBKGND:
  1105. return TRUE;
  1106. break;
  1107. case WM_MOUSEMOVE:
  1108. if (GetForegroundWindow() == GetParent(hwnd))
  1109. {
  1110. if ( !pThis->m_fTaskRunning )
  1111. {
  1112. int iID = ((int)GetWindowLongPtr(hwnd, GWLP_ID)) - IDM_MENUITEM0;
  1113. if ( iID != pThis->m_iSelectedItem )
  1114. {
  1115. SetFocus(hwnd);
  1116. }
  1117. }
  1118. }
  1119. else
  1120. {
  1121. return FALSE;
  1122. }
  1123. break;
  1124. case WM_SETFOCUS:
  1125. if (GetForegroundWindow() == GetParent(hwnd))
  1126. {
  1127. if ( !pThis->m_fTaskRunning )
  1128. {
  1129. int iID = ((int)GetWindowLongPtr(hwnd, GWLP_ID)) - IDM_MENUITEM0;
  1130. if ( iID != pThis->m_iSelectedItem )
  1131. {
  1132. pThis->m_iSelectedItem = iID;
  1133. SetFocus(GetDlgItem(GetParent(hwnd), IDM_MENUITEM0+iID));
  1134. }
  1135. }
  1136. }
  1137. else
  1138. {
  1139. return FALSE;
  1140. }
  1141. break;
  1142. }
  1143. return CallWindowProc(g_fnBtnProc, hwnd, uMsg, wParam, lParam);
  1144. }