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.

1033 lines
33 KiB

  1. //-------------------------------------------------------------------------//
  2. // main.cpp
  3. //-------------------------------------------------------------------------//
  4. #include "pch.h"
  5. #include "resource.h"
  6. #include "main.h"
  7. #include "pageinfo.h"
  8. #include "tmreg.h"
  9. #include "themeldr.h"
  10. //-------------------------------------------------------------------------//
  11. #define MAX_LOADSTRING 100
  12. #define THEMESEL_WNDCLASS TEXT("ThemeSelWnd")
  13. //-------------------------------------------------------------------------//
  14. class CWndBase
  15. //-------------------------------------------------------------------------//
  16. {
  17. public:
  18. CWndBase() { Detach(); }
  19. virtual ~CWndBase() { Detach(); }
  20. BOOL Attach( HWND hwnd );
  21. void Detach() { _hwnd = NULL; }
  22. operator HWND() { return _hwnd; }
  23. virtual void RepositionChildren( BOOL fCalcScroll, int cx = -1, int cy = -1) {}
  24. protected:
  25. HWND _hwnd;
  26. };
  27. //-------------------------------------------------------------------------//
  28. inline BOOL CWndBase::Attach( HWND hwnd ) {
  29. if( IsWindow( hwnd ) ) {
  30. _hwnd = hwnd;
  31. return TRUE;
  32. }
  33. return FALSE;
  34. };
  35. //-------------------------------------------------------------------------//
  36. class CChildTabWnd : public CWndBase
  37. //-------------------------------------------------------------------------//
  38. {
  39. public:
  40. CChildTabWnd()
  41. : _prgPages(0),
  42. _cPages(0),
  43. _iCurPage(-1),
  44. _rghwndPages(NULL),
  45. _rgrcPages(NULL) {}
  46. ~CChildTabWnd() { delete [] _rghwndPages; delete [] _rgrcPages; }
  47. HWND Create( DWORD dwExStyle, DWORD dwStyle,
  48. const RECT& rc, HWND hwndParent, UINT nID,
  49. HINSTANCE hInst, LPVOID pvParam );
  50. int CreatePages( const PAGEINFO rgPages[], int cPages );
  51. BOOL ShowPage( int iPage );
  52. HWND GetCurPage();
  53. BOOL GetCurPageRect( LPRECT prc );
  54. BOOL GetExtent( SIZE* psizeExtent );
  55. BOOL HandleNotify( NMHDR* pnmh, LRESULT* plRet );
  56. BOOL TranslateAccelerator( HWND, LPMSG );
  57. virtual void RepositionChildren( BOOL fCalcScroll, int cx = -1, int cy = -1);
  58. private:
  59. const PAGEINFO* _prgPages;
  60. HWND* _rghwndPages; // page HWNDs
  61. RECT* _rgrcPages; // native page window size
  62. int _cPages;
  63. int _iCurPage;
  64. };
  65. //-------------------------------------------------------------------------//
  66. class CMainWnd : public CWndBase
  67. //-------------------------------------------------------------------------//
  68. {
  69. public:
  70. CMainWnd()
  71. {
  72. ZeroMemory( &_siVert, sizeof(_siVert) );
  73. ZeroMemory( &_siHorz, sizeof(_siHorz) );
  74. }
  75. ~CMainWnd() {}
  76. static LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
  77. void RepositionChildren( BOOL fCalcScroll, int cx = -1, int cy = -1);
  78. void Scroll( WPARAM wParam, int nBar );
  79. BOOL TranslateAccelerator( HWND hwnd, LPMSG pmsg) {
  80. return _wndTab.TranslateAccelerator( hwnd, pmsg );
  81. }
  82. CChildTabWnd _wndTab;
  83. SCROLLINFO _siVert;
  84. SCROLLINFO _siHorz;
  85. } _wndMain;
  86. //-------------------------------------------------------------------------//
  87. // Foward declarations of functions included in this code module:
  88. ATOM _RegisterWndClasses(HINSTANCE hInstance);
  89. BOOL _InitInstance(HINSTANCE, int);
  90. BOOL _InitThemeOptions( HINSTANCE, LPCTSTR lpCmdLine, BOOL* pfDone );
  91. BOOL _FoundPrevInstance( LPCWSTR lpCmdLine );
  92. LRESULT CALLBACK _MainWndProc(HWND, UINT, WPARAM, LPARAM);
  93. INT_PTR CALLBACK _NilDlgProc( HWND, UINT, WPARAM, LPARAM);
  94. INT_PTR CALLBACK _AboutDlgProc(HWND, UINT, WPARAM, LPARAM);
  95. INT_PTR CALLBACK _SyntaxDlgProc(HWND, UINT, WPARAM, LPARAM);
  96. //-------------------------------------------------------------------------//
  97. // Global vars:
  98. HINSTANCE g_hInst = NULL; // module handle
  99. TCHAR g_szAppTitle[MAX_LOADSTRING] = {0}; // app title
  100. int g_iCurPage = -1;
  101. HWND g_hwndMain = NULL;
  102. THEMESEL_OPTIONS g_options = {0};
  103. BOOL g_fHide = FALSE;
  104. BOOL g_fMinimize = FALSE;
  105. UINT WM_THEMESEL_COMMUNICATION =
  106. RegisterWindowMessage(_TEXT("WM_THEMESEL_COMMUNICATION"));
  107. // module static data
  108. COLORREF s_Colors[TM_COLORCOUNT];
  109. BOOL s_fFlatMenus;
  110. BOOL s_fDropShadows;
  111. //-------------------------------------------------------------------------//
  112. typedef BOOL (WINAPI *PFN_TMINIT)(HINSTANCE hInst);
  113. //-------------------------------------------------------------------------//
  114. BOOL InitThemeManager(BOOL fPreventInitTheme)
  115. {
  116. if (fPreventInitTheme)
  117. {
  118. //---- easy way: just turn off reg key ----
  119. SetCurrentUserThemeInt(THEMEPROP_THEMEACTIVE, 0);
  120. }
  121. //---= if theme manager is already running, don't start our local guy ----
  122. if (FindWindow(L"ThemeManagerWindowClass", NULL))
  123. return TRUE;
  124. //---- load msgina (theme manager) ----
  125. HINSTANCE hInstMsgina = LoadLibraryW(L"msgina.dll");
  126. if (! hInstMsgina)
  127. {
  128. MessageBox(NULL, L"Could not load msgina.dll", L"Fatal Error", MB_OK);
  129. return FALSE;
  130. }
  131. //---- find TMInitialize() ----
  132. PFN_TMINIT pfnTmInit = (PFN_TMINIT) GetProcAddress(hInstMsgina, (LPCSTR)49);
  133. // TM_Initialize is only exported as ordinal 49 at this point (9/27/00)
  134. if (! pfnTmInit)
  135. pfnTmInit = (PFN_TMINIT) GetProcAddress(hInstMsgina, (LPCSTR) 49);
  136. if (! pfnTmInit)
  137. {
  138. MessageBox(NULL, L"Could not find msgina entrypoint: TM_Initialize", L"Fatal Error", MB_OK);
  139. return FALSE;
  140. }
  141. //---- initialize theme manager ----
  142. pfnTmInit(hInstMsgina);
  143. return TRUE;
  144. }
  145. //-------------------------------------------------------------------------//
  146. EXTERN_C APIENTRY _tWinMain(
  147. HINSTANCE hInstance,
  148. HINSTANCE hPrevInstance,
  149. LPTSTR lpCmdLine,
  150. int nCmdShow)
  151. {
  152. //---- initialize globals in themeldr.lib ----
  153. ThemeLibStartUp(FALSE);
  154. //---- initialize our globals ----
  155. g_hInst = hInstance; // Store instance handle in our global variable
  156. MSG msg;
  157. HACCEL hAccelTable;
  158. if (_FoundPrevInstance( lpCmdLine ))
  159. return 0;
  160. _SaveSystemSettings( );
  161. // Perform application initialization:
  162. BOOL fDone;
  163. if( !_InitThemeOptions( hInstance, lpCmdLine, &fDone ) )
  164. return 1;
  165. //---- turn off theme mgr for now, until msgina supports this again ----
  166. //if (! InitThemeManager(g_options.fPreventInitTheming))
  167. // return 1;
  168. if (fDone) // completed cmdline task OK
  169. return 0;
  170. if (g_fHide)
  171. nCmdShow = SW_HIDE;
  172. else if (g_fMinimize)
  173. nCmdShow = SW_MINIMIZE;
  174. if( !_InitInstance( hInstance, nCmdShow ))
  175. return 1;
  176. hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_THEMESEL));
  177. // Main message loop:
  178. while (GetMessage(&msg, NULL, 0, 0))
  179. {
  180. if (TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
  181. continue;
  182. if (msg.message == WM_THEMECHANGED)
  183. {
  184. //Log(LOG_TMCHANGE, L"MessageLoop: WM_THEMECHANGED on hwnd=0x%x (IsWindow()=%d)",
  185. //msg.hwnd, IsWindow(msg.hwnd));
  186. }
  187. //if( _wndMain.TranslateAccelerator( msg.hwnd, &msg ) )
  188. // continue;
  189. TranslateMessage(&msg);
  190. DispatchMessage(&msg);
  191. }
  192. return (int)msg.wParam;
  193. }
  194. //-------------------------------------------------------------------------//
  195. ATOM _RegisterWndClasses(HINSTANCE hInstance)
  196. {
  197. WNDCLASSEX wcex;
  198. INITCOMMONCONTROLSEX icc;
  199. icc.dwSize = sizeof(icc);
  200. icc.dwICC = ICC_TAB_CLASSES;
  201. InitCommonControlsEx( &icc );
  202. wcex.cbSize = sizeof(WNDCLASSEX);
  203. wcex.style = CS_HREDRAW | CS_VREDRAW;
  204. wcex.lpfnWndProc = CMainWnd::WndProc;
  205. wcex.cbClsExtra = 0;
  206. wcex.cbWndExtra = 0;
  207. wcex.hInstance = hInstance;
  208. wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_THEMESEL));
  209. wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
  210. wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
  211. wcex.lpszMenuName = MAKEINTRESOURCE(IDC_THEMESEL);
  212. wcex.lpszClassName = THEMESEL_WNDCLASS;
  213. wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
  214. return RegisterClassEx(&wcex);
  215. }
  216. //-------------------------------------------------------------------------//
  217. HWND CChildTabWnd::Create(
  218. DWORD dwExStyle,
  219. DWORD dwStyle,
  220. const RECT& rc,
  221. HWND hwndParent,
  222. UINT nID,
  223. HINSTANCE hInst,
  224. LPVOID pvParam )
  225. {
  226. _hwnd = CreateWindowEx( dwExStyle, WC_TABCONTROL, TEXT(""),
  227. dwStyle | (WS_CHILD|WS_CLIPSIBLINGS|WS_CLIPCHILDREN|TCS_MULTILINE|TCS_HOTTRACK),
  228. rc.left, rc.top, RECTWIDTH(&rc), RECTHEIGHT(&rc),
  229. hwndParent, IntToPtr_(HMENU, nID), hInst, pvParam );
  230. return _hwnd;
  231. }
  232. #define VALIDPAGE(iPage,cPages) (((iPage) >=0) && ((iPage) < (cPages)))
  233. //-------------------------------------------------------------------------//
  234. int CChildTabWnd::CreatePages( const PAGEINFO rgPages[], int cPages )
  235. {
  236. _cPages = 0;
  237. _prgPages = NULL;
  238. delete [] _rghwndPages;
  239. delete [] _rgrcPages;
  240. _rghwndPages = NULL;
  241. _rgrcPages = NULL;
  242. for( int i = 0; i < cPages; i++ )
  243. {
  244. TCITEM tci;
  245. TCHAR szText[MAX_LOADSTRING];
  246. ZeroMemory( &tci, sizeof(tci) );
  247. tci.mask = (rgPages[i].nIDSTitle ? TCIF_TEXT : 0);
  248. LoadString( g_hInst, rgPages[i].nIDSTitle, szText, ARRAYSIZE(szText) );
  249. tci.pszText = szText;
  250. if( SendMessage( _hwnd, TCM_INSERTITEM, _cPages, (LPARAM)&tci ) == _cPages )
  251. _cPages++;
  252. }
  253. if( _cPages )
  254. _prgPages = rgPages;
  255. if( (_rghwndPages = new HWND[_cPages]) != NULL )
  256. ZeroMemory( _rghwndPages, _cPages * sizeof(HWND) );
  257. if( (_rgrcPages = new RECT[_cPages]) != NULL )
  258. ZeroMemory( _rgrcPages, _cPages * sizeof(RECT) );
  259. return _cPages;
  260. }
  261. //-------------------------------------------------------------------------//
  262. HWND CChildTabWnd::GetCurPage()
  263. {
  264. if( VALIDPAGE( _iCurPage, _cPages ) &&
  265. IsWindow(_rghwndPages[_iCurPage]) )
  266. return _rghwndPages[_iCurPage];
  267. return NULL;
  268. }
  269. //-------------------------------------------------------------------------//
  270. BOOL CChildTabWnd::GetCurPageRect( LPRECT prc )
  271. {
  272. if( VALIDPAGE( _iCurPage, _cPages ) &&
  273. !IsRectEmpty(_rgrcPages + _iCurPage) )
  274. {
  275. *prc = _rgrcPages[_iCurPage];
  276. return TRUE;
  277. }
  278. return FALSE;
  279. }
  280. //-------------------------------------------------------------------------//
  281. BOOL CChildTabWnd::GetExtent( SIZE* pext )
  282. {
  283. RECT rc;
  284. if( GetCurPageRect( &rc ) )
  285. {
  286. SendMessage( _hwnd, TCM_ADJUSTRECT, TRUE, (LPARAM)&rc );
  287. pext->cx = RECTWIDTH(&rc);
  288. pext->cy = RECTHEIGHT(&rc);
  289. return TRUE;
  290. }
  291. return FALSE;
  292. }
  293. //-------------------------------------------------------------------------//
  294. BOOL CChildTabWnd::ShowPage( int iPage )
  295. {
  296. if( iPage == _iCurPage )
  297. return TRUE;
  298. HWND hwndCurPage = GetCurPage();
  299. BOOL bInit = FALSE;
  300. if( hwndCurPage )
  301. {
  302. ShowWindow( hwndCurPage, SW_HIDE );
  303. EnableWindow( hwndCurPage, FALSE );
  304. }
  305. else
  306. bInit = TRUE;
  307. if( VALIDPAGE( iPage, _cPages ) )
  308. {
  309. if( !IsWindow(_rghwndPages[iPage]) )
  310. _rghwndPages[iPage] = _prgPages[iPage].pfnCreateInstance( _hwnd );
  311. if( IsWindow( _rghwndPages[iPage] ) )
  312. {
  313. _iCurPage = iPage;
  314. hwndCurPage = GetCurPage();
  315. if( hwndCurPage )
  316. {
  317. if( bInit )
  318. {
  319. // Set tab font
  320. HFONT hf = (HFONT)SendMessage( hwndCurPage, WM_GETFONT, 0, 0L );
  321. if( hf )
  322. SendMessage( _hwnd, WM_SETFONT, (WPARAM)hf, 0L );
  323. }
  324. if( IsRectEmpty( _rgrcPages + iPage ) )
  325. {
  326. // Initialize native page rect.
  327. GetWindowRect( _rghwndPages[iPage], _rgrcPages + iPage );
  328. OffsetRect( _rgrcPages + iPage,
  329. -_rgrcPages[iPage].left, -_rgrcPages[iPage].top );
  330. // Position page using TCM_ADJUSTRECT.
  331. // note: ignore width, height when we reposition, as TCM_ADJUSTRECT
  332. // might have clipped them to its current client area)
  333. RECT rcPage ;
  334. GetWindowRect( _hwnd, &rcPage );
  335. OffsetRect( &rcPage, -rcPage.left, -rcPage.top );
  336. SendMessage( _hwnd, TCM_ADJUSTRECT, FALSE, (LPARAM)&rcPage );
  337. SetWindowPos( hwndCurPage, NULL, rcPage.left, rcPage.top,
  338. RECTWIDTH(_rgrcPages + iPage), RECTHEIGHT(_rgrcPages + iPage),
  339. SWP_NOACTIVATE|SWP_NOZORDER );
  340. }
  341. // Inform parent of new scroll limits
  342. _wndMain.RepositionChildren( TRUE );
  343. ShowWindow( hwndCurPage, SW_SHOW );
  344. EnableWindow( hwndCurPage, TRUE );
  345. SetFocus( hwndCurPage );
  346. }
  347. }
  348. }
  349. return _iCurPage == iPage;
  350. }
  351. //-------------------------------------------------------------------------//
  352. void CChildTabWnd::RepositionChildren( BOOL fCalcScroll, int cx, int cy )
  353. {
  354. SIZE sizeDlg;
  355. HWND hwndDlg = GetCurPage();
  356. if( IsWindow( hwndDlg ) && GetExtent( &sizeDlg ) )
  357. {
  358. RECT rcPage;
  359. if( cx < 0 || cy < 0 )
  360. {
  361. GetWindowRect( _hwnd, &rcPage );
  362. OffsetRect( &rcPage, -rcPage.left, -rcPage.top );
  363. }
  364. else
  365. {
  366. SetRect( &rcPage, 0, 0, cx, cy );
  367. }
  368. SendMessage( _hwnd, TCM_ADJUSTRECT, FALSE, (LPARAM)&rcPage );
  369. SetWindowPos( hwndDlg, NULL, rcPage.left, rcPage.top,
  370. min(RECTWIDTH(&rcPage), sizeDlg.cx),
  371. min(RECTHEIGHT(&rcPage), sizeDlg.cy),
  372. SWP_NOACTIVATE|SWP_NOZORDER );
  373. }
  374. }
  375. //-------------------------------------------------------------------------//
  376. BOOL CChildTabWnd::TranslateAccelerator( HWND hwnd, LPMSG pmsg)
  377. {
  378. HWND hwndCurPage = GetCurPage();
  379. if( hwndCurPage || IsChild( hwndCurPage, hwnd ) )
  380. return IsDialogMessage( hwndCurPage, pmsg );
  381. return FALSE;
  382. }
  383. //-------------------------------------------------------------------------//
  384. BOOL CChildTabWnd::HandleNotify( NMHDR* pnmh, LRESULT* plRet )
  385. {
  386. *plRet = 0;
  387. switch( pnmh->code )
  388. {
  389. case TCN_SELCHANGE:
  390. {
  391. ShowPage( TabCtrl_GetCurSel( _hwnd ) );
  392. return TRUE;
  393. }
  394. }
  395. return FALSE;
  396. }
  397. //-------------------------------------------------------------------------//
  398. BOOL _InitInstance(HINSTANCE hInstance, int nCmdShow)
  399. {
  400. if( _RegisterWndClasses(hInstance) )
  401. {
  402. if( LoadString(hInstance, IDS_APP_TITLE, g_szAppTitle, MAX_LOADSTRING) )
  403. {
  404. CreateWindowEx( WS_EX_CLIENTEDGE,
  405. THEMESEL_WNDCLASS, g_szAppTitle,
  406. WS_OVERLAPPEDWINDOW|WS_HSCROLL|WS_VSCROLL,
  407. CW_USEDEFAULT, CW_USEDEFAULT, 800, 560,
  408. NULL, NULL, hInstance, NULL);
  409. if( IsWindow( _wndMain ) )
  410. {
  411. g_hwndMain = _wndMain;
  412. ShowWindow(_wndMain, nCmdShow);
  413. UpdateWindow(_wndMain);
  414. }
  415. }
  416. }
  417. return TRUE;
  418. }
  419. //-------------------------------------------------------------------------//
  420. HRESULT _ProcessFileName( LPCTSTR pszThemeFile, LPCWSTR pszColor, LPCWSTR pszSize, BOOL* pfDone )
  421. {
  422. HRESULT hr;
  423. *pfDone = FALSE;
  424. hr = S_OK;
  425. if (pszThemeFile)
  426. hr = _ApplyTheme(pszThemeFile, pszColor, pszSize, pfDone);
  427. return hr;
  428. }
  429. //-------------------------------------------------------------------------//
  430. void ShowThemeError(HRESULT hr)
  431. {
  432. WCHAR szBuff[2*MAX_PATH];
  433. if (THEME_PARSING_ERROR(hr))
  434. {
  435. PARSE_ERROR_INFO Info = {sizeof(Info)};
  436. HRESULT hr2 = GetThemeParseErrorInfo(&Info);
  437. if (SUCCEEDED(hr2))
  438. {
  439. StringCchCopy(szBuff, ARRAYSIZE(szBuff), Info.szMsg);
  440. }
  441. else
  442. {
  443. StringCchPrintfW(szBuff, ARRAYSIZE(szBuff), L"Unknown parsing error");
  444. }
  445. }
  446. else
  447. {
  448. // normal win32 error
  449. FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, hr, 0, szBuff, ARRAYSIZE(szBuff), NULL);
  450. }
  451. MessageBoxW(NULL, szBuff, L"Error Loading Theme", MB_OK);
  452. }
  453. //-------------------------------------------------------------------------//
  454. HRESULT _ApplyTheme( LPCTSTR pszThemeFile, LPCWSTR pszColor, LPCWSTR pszSize, BOOL* pfDone )
  455. {
  456. HRESULT hr = E_FAIL;
  457. if (pfDone)
  458. *pfDone = FALSE;
  459. if (pszThemeFile && *pszThemeFile)
  460. {
  461. HTHEMEFILE htf;
  462. //---- OpenThemeFile needs filename fully qualified ----
  463. TCHAR szFullName[MAX_PATH];
  464. GetFullPathName(pszThemeFile, ARRAYSIZE(szFullName), szFullName, NULL);
  465. if (g_options.hwndPreviewTarget) // if not preview
  466. {
  467. hr = OpenThemeFile(szFullName, pszColor, pszSize, &htf, TRUE);
  468. if (FAILED(hr))
  469. ShowThemeError(hr);
  470. else
  471. {
  472. //---- apply theme ----
  473. hr = ApplyTheme(htf, 0, g_options.hwndPreviewTarget);
  474. if (hr)
  475. ShowThemeError(hr);
  476. CloseThemeFile(htf); // we don't need to hold open anymore
  477. }
  478. }
  479. else
  480. {
  481. hr = SetSystemVisualStyle(szFullName, pszColor, pszSize, AT_LOAD_SYSMETRICS);
  482. }
  483. }
  484. return hr;
  485. }
  486. //-------------------------------------------------------------------------//
  487. BOOL _FoundPrevInstance( LPCWSTR lpCmdLine )
  488. {
  489. HWND hwndPrev = FindWindow(THEMESEL_WNDCLASS, NULL);
  490. if (! hwndPrev)
  491. return FALSE;
  492. //---- find out what we are trying to do with this 2nd version ----
  493. LPCWSTR p = lpCmdLine;
  494. BOOL fUnload = FALSE;
  495. if ((*p == '-') || (*p == '/'))
  496. {
  497. p++;
  498. if ((*p == 'u') || (*p == 'U'))
  499. fUnload = TRUE;
  500. }
  501. //---- send a special msg and exit ----
  502. BOOL fGotIt = (BOOL)SendMessage(hwndPrev, WM_THEMESEL_COMMUNICATION, fUnload, 0);
  503. return fGotIt;
  504. }
  505. //-------------------------------------------------------------------------//
  506. BOOL _InitThemeOptions( HINSTANCE hInstance, LPCTSTR lpCmdLine, BOOL *pfDone )
  507. {
  508. LPCTSTR pszThemeFile = NULL;
  509. if( 0 == g_options.cbSize )
  510. {
  511. g_options.cbSize = sizeof(g_options);
  512. g_options.fEnableFrame = TRUE;
  513. g_options.fEnableDialog = TRUE;
  514. g_options.fPreventInitTheming = FALSE;
  515. g_options.fUserSwitch = FALSE;
  516. g_options.fExceptTarget = FALSE;
  517. g_options.hwndPreviewTarget = NULL;
  518. *g_options.szTargetApp = 0;
  519. }
  520. //---- other cmd line switches ----
  521. // -a<appname> (to set targeted app)
  522. // -t (to set themesel as target app)
  523. // -l (to load "Professional" theme and exit)
  524. // -u (to clear theme and exit)
  525. while (*lpCmdLine) // process cmd line args
  526. {
  527. while (isspace(*lpCmdLine))
  528. lpCmdLine++;
  529. if ((*lpCmdLine == '-') || (*lpCmdLine == '/'))
  530. {
  531. lpCmdLine++;
  532. WCHAR lowp = towlower(*lpCmdLine);
  533. if (lowp == '?')
  534. {
  535. DialogBox( g_hInst, MAKEINTRESOURCE(IDD_SYNTAX), NULL, _SyntaxDlgProc );
  536. return FALSE;
  537. }
  538. else if (lowp == 'f')
  539. g_options.fEnableFrame = FALSE;
  540. else if (lowp == 'd')
  541. g_options.fEnableDialog = FALSE;
  542. else if (lowp == 'p')
  543. g_options.fPreventInitTheming = TRUE;
  544. else if ((lowp == 'a') || (lowp == 'x'))
  545. {
  546. g_options.fExceptTarget = (lowp == 'x');
  547. lpCmdLine++;;
  548. LPCTSTR q = lpCmdLine;
  549. while ((*lpCmdLine) && (! isspace(*lpCmdLine)))
  550. lpCmdLine++;
  551. *g_options.szTargetApp = 0;
  552. ULONG cch = (ULONG)(lpCmdLine - q);
  553. ULONG cchCopy = min( (ULONG)(ARRAYSIZE(g_options.szTargetApp) - 1), cch);
  554. if (cchCopy > 0)
  555. {
  556. CopyMemory(g_options.szTargetApp, q, cchCopy * sizeof(WCHAR));
  557. }
  558. g_options.szTargetApp[cchCopy] = 0;
  559. continue;
  560. }
  561. else if (lowp == 't')
  562. StringCchCopy(g_options.szTargetApp, ARRAYSIZE(g_options.szTargetApp), L"ThemeSel");
  563. else if (lowp == 'l') // load "business" theme and minimize
  564. {
  565. pszThemeFile = DEFAULT_THEME;
  566. g_fMinimize = TRUE;
  567. }
  568. else if (lowp == 'z') // load "business" theme and hide
  569. {
  570. pszThemeFile = DEFAULT_THEME;
  571. g_fHide = TRUE;
  572. }
  573. else if (lowp == 'u') // just unload theme & exit
  574. {
  575. //---- turn off theme from previous run, if any ----
  576. ApplyTheme(NULL, 0, NULL);
  577. return FALSE; // exit
  578. }
  579. else
  580. {
  581. MessageBox(NULL, L"Unrecognized switch", L"Error", MB_OK);
  582. return FALSE;
  583. }
  584. lpCmdLine++; // skip over switch letter
  585. }
  586. else
  587. {
  588. pszThemeFile = lpCmdLine;
  589. break;
  590. }
  591. }
  592. return SUCCEEDED(_ProcessFileName( pszThemeFile, NULL, NULL, pfDone ));
  593. }
  594. //-------------------------------------------------------------------------//
  595. LRESULT CALLBACK CMainWnd::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  596. {
  597. LRESULT lRet = 0L;
  598. switch (uMsg)
  599. {
  600. case WM_NCCREATE:
  601. lRet = DefWindowProc( hwnd, uMsg, wParam, lParam );
  602. _wndMain.Attach( hwnd );
  603. break;
  604. case WM_NCDESTROY:
  605. lRet = DefWindowProc( hwnd, uMsg, wParam, lParam );
  606. _wndMain.Detach();
  607. break;
  608. case WM_CREATE:
  609. {
  610. RECT rc;
  611. GetClientRect( hwnd, &rc );
  612. if( !_wndMain._wndTab.Create( 0, WS_VISIBLE, rc, _wndMain, 0, g_hInst, 0 ) )
  613. return -1;
  614. if( _wndMain._wndTab.CreatePages( g_rgPageInfo, g_cPageInfo ) )
  615. _wndMain._wndTab.ShowPage(0);
  616. break;
  617. }
  618. case WM_HSCROLL:
  619. case WM_VSCROLL:
  620. _wndMain.Scroll( wParam, uMsg == WM_VSCROLL ? SB_VERT : SB_HORZ );
  621. break;
  622. case WM_COMMAND:
  623. {
  624. int wmId = LOWORD(wParam);
  625. int wmEvent = HIWORD(wParam);
  626. BOOL fFake;
  627. // Parse the menu selections:
  628. switch (wmId)
  629. {
  630. case IDM_ABOUT:
  631. DialogBox(g_hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hwnd, _AboutDlgProc);
  632. break;
  633. case IDM_APPLY:
  634. GeneralPage_OnTestButton(g_hwndGeneralPage, 0, NULL, NULL, fFake);
  635. break;
  636. case IDM_DUMP:
  637. GeneralPage_OnDumpTheme();
  638. break;
  639. case IDM_REMOVE:
  640. GeneralPage_OnClearButton(g_hwndGeneralPage, 0, NULL, NULL, fFake);
  641. break;
  642. case IDM_EXIT:
  643. DestroyWindow(hwnd);
  644. break;
  645. default:
  646. lRet = DefWindowProc(hwnd, uMsg, wParam, lParam);
  647. }
  648. break;
  649. }
  650. case WM_ERASEBKGND:
  651. return 1L;
  652. case WM_DESTROY:
  653. _ShutDown( FALSE );
  654. PostQuitMessage(0);
  655. break;
  656. case WM_SIZE:
  657. {
  658. POINTS pts = MAKEPOINTS(lParam);
  659. lRet = DefWindowProc( hwnd, uMsg, wParam, lParam );
  660. _wndMain.RepositionChildren( TRUE, pts.x, pts.y );
  661. break;
  662. }
  663. case WM_NOTIFY:
  664. {
  665. if( ((NMHDR*)lParam)->hwndFrom == _wndMain._wndTab )
  666. {
  667. if( _wndMain._wndTab.HandleNotify( (NMHDR*)lParam, &lRet ) )
  668. return lRet;
  669. }
  670. break;
  671. }
  672. default:
  673. if (uMsg == WM_THEMESEL_COMMUNICATION) // msg from another instance of themesel
  674. {
  675. if (wParam == 1) // exit
  676. _ShutDown( TRUE );
  677. else
  678. ShowWindow(g_hwndMain, SW_NORMAL);
  679. return 1;
  680. }
  681. lRet = DefWindowProc(hwnd, uMsg, wParam, lParam);
  682. }
  683. return lRet;
  684. }
  685. //-------------------------------------------------------------------------//
  686. void CMainWnd::RepositionChildren( BOOL fCalcScroll, int cx, int cy )
  687. {
  688. if( IsWindow( _wndTab ) )
  689. {
  690. RECT rcClient = {0};
  691. if( cx < 0 || cy < 0 )
  692. {
  693. GetClientRect( _hwnd, &rcClient );
  694. cx = RECTWIDTH(&rcClient);
  695. cy = RECTHEIGHT(&rcClient);
  696. }
  697. else
  698. {
  699. rcClient.right = cx;
  700. rcClient.bottom = cy;
  701. }
  702. SIZE sizeMin;
  703. if( _wndTab.GetExtent(&sizeMin) )
  704. {
  705. if( fCalcScroll )
  706. {
  707. POINT pos;
  708. pos.x = _siHorz.nPos;
  709. pos.y = _siVert.nPos;
  710. _siHorz.fMask = _siVert.fMask = (SIF_RANGE|SIF_PAGE);
  711. _siHorz.nPage = cx; // thumb width
  712. _siVert.nPage = cy; // thumb height
  713. SIZE sizeDelta; // difference between what we have to show and what is shown.
  714. sizeDelta.cx = sizeMin.cx - _siHorz.nPage;
  715. sizeDelta.cy = sizeMin.cy - _siVert.nPage;
  716. // establish maximum scroll positions
  717. _siHorz.nMax = sizeDelta.cx > 0 ? sizeMin.cx - 1 : 0;
  718. _siVert.nMax = sizeDelta.cy > 0 ? sizeMin.cy - 1 : 0;
  719. // establish horizontal scroll pos
  720. if( sizeDelta.cx <= 0 )
  721. _siHorz.nPos = 0; // scroll to extreme left if we're removing scroll bar
  722. else if( sizeDelta.cx < _siHorz.nPos )
  723. _siHorz.nPos = sizeDelta.cx; // remove right-hand vacancy
  724. if( _siHorz.nPos != pos.x )
  725. _siHorz.fMask |= SIF_POS;
  726. // establish vertical scroll pos
  727. if( sizeDelta.cy <= 0 )
  728. _siVert.nPos = 0; // scroll to top if we're removing scroll bar
  729. else if( sizeDelta.cy < _siVert.nPos )
  730. _siVert.nPos = sizeDelta.cy; // remove lower-portion vacancy
  731. if( _siVert.nPos != pos.y )
  732. _siVert.fMask |= SIF_POS;
  733. // Note: can't call SetScrollInfo here, as it may generate
  734. // a WM_SIZE and recurse back to this function before we had a
  735. // chance to SetWindowPos() our subdlg. So defer it until after
  736. // we've done this.
  737. }
  738. SetWindowPos( _wndTab, NULL, -_siHorz.nPos, -_siVert.nPos,
  739. _siHorz.nPos + max(cx, sizeMin.cx),
  740. _siVert.nPos + max(cy, sizeMin.cy),
  741. SWP_NOZORDER|SWP_NOACTIVATE );
  742. _wndTab.RepositionChildren( FALSE );
  743. if( fCalcScroll )
  744. {
  745. SetScrollInfo( _hwnd, SB_HORZ, &_siHorz, TRUE );
  746. SetScrollInfo( _hwnd, SB_VERT, &_siVert, TRUE );
  747. }
  748. }
  749. }
  750. }
  751. //-------------------------------------------------------------------------//
  752. void CMainWnd::Scroll( WPARAM wParam, int nBar )
  753. {
  754. SCROLLINFO* psi = SB_VERT == nBar ? &_siVert :
  755. SB_HORZ == nBar ? &_siHorz : NULL;
  756. const LONG nLine = 15;
  757. UINT uSBCode = LOWORD(wParam);
  758. int nNewPos = HIWORD(wParam);
  759. int nDeltaMax = (psi->nMax - psi->nPage) + 1;
  760. if( !psi )
  761. {
  762. _ASSERTE(FALSE);
  763. return;
  764. }
  765. switch( uSBCode )
  766. {
  767. case SB_LEFT:
  768. psi->nPos--;
  769. break;
  770. case SB_RIGHT:
  771. psi->nPos++;
  772. break;
  773. case SB_LINELEFT:
  774. psi->nPos = max( psi->nPos - nLine, 0 );
  775. break;
  776. case SB_LINERIGHT:
  777. psi->nPos = min( psi->nPos + nLine, nDeltaMax );
  778. break;
  779. case SB_PAGELEFT:
  780. psi->nPos = max( psi->nPos - (int)psi->nPage, 0 );
  781. break;
  782. case SB_PAGERIGHT:
  783. psi->nPos = min( psi->nPos + (int)psi->nPage, nDeltaMax );
  784. break;
  785. case SB_THUMBTRACK:
  786. psi->nPos = nNewPos;
  787. break;
  788. case SB_THUMBPOSITION:
  789. psi->nPos = nNewPos;
  790. break;
  791. case SB_ENDSCROLL:
  792. return;
  793. }
  794. psi->fMask = SIF_POS;
  795. SetScrollInfo( _hwnd, nBar, psi, TRUE );
  796. RepositionChildren( FALSE );
  797. }
  798. //-------------------------------------------------------------------------//
  799. INT_PTR CALLBACK _NilDlgProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
  800. {
  801. switch (uMsg)
  802. {
  803. case WM_INITDIALOG:
  804. return TRUE;
  805. case WM_COMMAND:
  806. if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
  807. {
  808. EndDialog(hDlg, LOWORD(wParam));
  809. return TRUE;
  810. }
  811. break;
  812. }
  813. return FALSE;
  814. }
  815. //-------------------------------------------------------------------------//
  816. INT_PTR CALLBACK _AboutDlgProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
  817. {
  818. return _NilDlgProc( hDlg, uMsg, wParam, lParam );
  819. }
  820. //-------------------------------------------------------------------------//
  821. INT_PTR CALLBACK _SyntaxDlgProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
  822. {
  823. return _NilDlgProc( hDlg, uMsg, wParam, lParam );
  824. }
  825. //---------------------------------------------------------------------------
  826. void _SaveSystemSettings( )
  827. {
  828. //---- save off system colors for later restoration ----
  829. for (int i=0; i < TM_COLORCOUNT; i++)
  830. s_Colors[i] = GetSysColor(i);
  831. //---- save off "flatmenu" and "dropshadows" settings ---
  832. SystemParametersInfo(SPI_GETFLATMENU, 0, (PVOID)&s_fFlatMenus, 0);
  833. SystemParametersInfo(SPI_GETDROPSHADOW, 0, (PVOID)&s_fDropShadows, 0);
  834. }
  835. //---------------------------------------------------------------------------
  836. void _RestoreSystemSettings(HWND hwndGeneralPage, BOOL fUnloadOneOnly)
  837. {
  838. //---- turn off current Theme ----
  839. HWND hwndPreview = hwndGeneralPage ? GetPreviewHwnd(hwndGeneralPage) : NULL;
  840. if (fUnloadOneOnly) // remove the "active" theme
  841. {
  842. if (hwndPreview)
  843. {
  844. ApplyTheme(NULL, 0, hwndPreview);
  845. return;
  846. }
  847. else
  848. {
  849. //---- fall thru & restore sys metrics ----
  850. ApplyTheme(NULL, 0, NULL);
  851. }
  852. }
  853. else
  854. {
  855. ApplyTheme(NULL, 0, hwndPreview);
  856. }
  857. //---- restore system colors ----
  858. int iIndexes[TM_COLORCOUNT];
  859. for (int i=0; i < TM_COLORCOUNT; i++)
  860. iIndexes[i] = i;
  861. SetSysColors(TM_COLORCOUNT, iIndexes, s_Colors);
  862. //---- restore "flatmenu" and "dropshadows" settings ---
  863. SystemParametersInfo(SPI_SETFLATMENU, 0, IntToPtr(s_fFlatMenus), SPIF_SENDCHANGE);
  864. SystemParametersInfo(SPI_SETDROPSHADOW, 0, IntToPtr(s_fFlatMenus), SPIF_SENDCHANGE);
  865. }
  866. //---------------------------------------------------------------------------
  867. void _ShutDown( BOOL bQuit )
  868. {
  869. if( bQuit )
  870. PostQuitMessage(0);
  871. }
  872. //---------------------------------------------------------------------------