Source code of Windows XP (NT5)
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.

425 lines
12 KiB

  1. #include "priv.h"
  2. #ifdef ENABLE_CHANNELS
  3. #include "sccls.h"
  4. #include "resource.h"
  5. #include "mshtmhst.h"
  6. #include "deskbar.h"
  7. #include "bands.h"
  8. #define WANT_CBANDSITE_CLASS
  9. #include "bandsite.h"
  10. #include "chanbar.h"
  11. #ifdef UNIX
  12. #include <mainwin.h>
  13. #endif
  14. #include "mluisupp.h"
  15. #define TBHEIGHT 20 // default height of the toolbar inside channel bar
  16. #define TBWIDTH 20 // default width of the toolbar inside channel bar
  17. CChannelDeskBarApp::CChannelDeskBarApp() : _hwndDummy(NULL)
  18. {
  19. }
  20. CChannelDeskBarApp::~CChannelDeskBarApp()
  21. {
  22. if (IsWindow(_hwndDummy))
  23. {
  24. DestroyWindow(_hwndDummy);
  25. }
  26. }
  27. void CChannelDeskBarApp::_OnCreate()
  28. {
  29. CDeskBarApp::_OnCreate();
  30. // remember screen resolution
  31. _cxScreen = GetSystemMetrics(SM_CXSCREEN);
  32. _cyScreen = GetSystemMetrics(SM_CYSCREEN);
  33. // create the dummy for receiving and forwarding broadcast messages
  34. if (!_hwndDummy)
  35. {
  36. _hwndDummy = SHCreateWorkerWindow(DummyWndProc, 0, 0, 0, 0, this);
  37. }
  38. if (_hwndDummy)
  39. {
  40. // make sure we so a select a realize of a palette in this
  41. // window so that we will get palette change notifications..
  42. HDC hdc = GetDC( _hwndDummy );
  43. if (hdc)
  44. {
  45. HPALETTE hpal = SHCreateShellPalette( hdc );
  46. if (hpal)
  47. {
  48. HPALETTE hpalOld = SelectPalette( hdc, hpal, TRUE );
  49. RealizePalette( hdc );
  50. // now select the old one back in
  51. SelectPalette( hdc, hpalOld, TRUE );
  52. DeletePalette( hpal );
  53. }
  54. ReleaseDC( _hwndDummy, hdc );
  55. }
  56. }
  57. }
  58. void CChannelDeskBarApp::_OnDisplayChange()
  59. {
  60. // do not use lParam, since it may give us (0,0).
  61. UINT cxScreen = GetSystemMetrics(SM_CXSCREEN);
  62. UINT cyScreen = GetSystemMetrics(SM_CYSCREEN);
  63. UINT cxOldScreen = _cxScreen;
  64. UINT cyOldScreen = _cyScreen;
  65. _cxScreen = cxScreen;
  66. _cyScreen = cyScreen;
  67. if (_hwnd) {
  68. RECT rc;
  69. GetWindowRect(_hwnd, &rc);
  70. if (cxOldScreen)
  71. rc.left = (rc.left * _cxScreen) / cxOldScreen;
  72. if (cyOldScreen)
  73. rc.top = (rc.top * _cyScreen) / cyOldScreen;
  74. SetWindowPos(_hwnd, NULL, rc.left, rc.top, 0, 0,
  75. SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
  76. // we need to change the cached pos/size.
  77. OffsetRect(&_rcFloat, rc.left - _rcFloat.left, rc.top - _rcFloat.top);
  78. }
  79. }
  80. LRESULT CChannelDeskBarApp::v_WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  81. {
  82. LRESULT lRes = 0;
  83. switch (uMsg) {
  84. case WM_CONTEXTMENU: // disable context menu MENU_DESKBARAPP
  85. case WM_NCRBUTTONUP: // disable context menu MENU_WEBBAR
  86. break;
  87. case WM_GETMINMAXINFO: // prevent it from getting too small
  88. ((MINMAXINFO *)lParam)->ptMinTrackSize.x = TBWIDTH + 10;
  89. ((MINMAXINFO *)lParam)->ptMinTrackSize.y = TBHEIGHT + 10;
  90. break;
  91. default:
  92. lRes = CDeskBarApp::v_WndProc(hwnd, uMsg, wParam, lParam);
  93. if (_hwnd) { // If our window is still alive
  94. switch (uMsg) {
  95. case WM_DISPLAYCHANGE:
  96. _OnDisplayChange(); // reposition when window resolution changes
  97. break;
  98. case WM_EXITSIZEMOVE:
  99. _PersistState(); // persist pos/size
  100. break;
  101. }
  102. }
  103. }
  104. return lRes;
  105. }
  106. LRESULT CALLBACK CChannelDeskBarApp::DummyWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  107. {
  108. CChannelDeskBarApp* pcba = (CChannelDeskBarApp*)GetWindowPtr0(hwnd);
  109. switch (uMsg) {
  110. case WM_PALETTECHANGED :
  111. return SendMessage(pcba->_hwnd, uMsg, wParam, lParam );
  112. case WM_DISPLAYCHANGE :
  113. // this message must be sent to the channel bar itself
  114. PostMessage(pcba->_hwnd, uMsg, wParam, lParam);
  115. // fall through ;
  116. case WM_WININICHANGE :
  117. case WM_SYSCOLORCHANGE :
  118. PropagateMessage(pcba->_hwnd, uMsg, wParam, lParam, InSendMessage());
  119. // fall through ;
  120. default:
  121. return DefWindowProcWrap(hwnd, uMsg, wParam, lParam);
  122. }
  123. }
  124. // overload CDeskBarApp::_UpdateCaptionTitle() to set title to "ChanApp"
  125. void CChannelDeskBarApp::_UpdateCaptionTitle()
  126. {
  127. SetWindowText(_hwnd, TEXT("ChanApp"));
  128. }
  129. // create the close button
  130. void CChannelDeskBarApp::_CreateToolbar()
  131. {
  132. _hwndTB = CreateWindowEx(WS_EX_TOOLWINDOW, TOOLBARCLASSNAME, NULL,
  133. WS_VISIBLE |
  134. WS_CHILD | TBSTYLE_FLAT | TBSTYLE_TRANSPARENT | TBSTYLE_CUSTOMERASE |
  135. WS_CLIPCHILDREN |
  136. WS_CLIPSIBLINGS | CCS_NODIVIDER | CCS_NOMOVEY | CCS_NOPARENTALIGN |
  137. CCS_NORESIZE,
  138. 0, 2, TBWIDTH, TBHEIGHT, _hwnd, 0, HINST_THISDLL, NULL);
  139. if (_hwndTB) {
  140. static const TBBUTTON tb[] =
  141. {
  142. { 1, IDM_AB_CLOSE, TBSTATE_ENABLED, TBSTYLE_BUTTON, {0,0}, 0, 0 }
  143. };
  144. #ifndef UNIX
  145. HIMAGELIST himl = ImageList_LoadImage(HINST_THISDLL,
  146. MAKEINTRESOURCE(IDB_BROWSERTOOLBAR),
  147. 13, 0, RGB(255,0,255),
  148. IMAGE_BITMAP, LR_CREATEDIBSECTION);
  149. #else
  150. HIMAGELIST himl;
  151. COLORREF crTextColor = GetSysColor( COLOR_BTNTEXT );
  152. crTextColor = MwGetTrueRGBValue( crTextColor );
  153. himl = ImageList_LoadImage(HINST_THISDLL,
  154. crTextColor == RGB(255,255,255) ?
  155. MAKEINTRESOURCE(IDB_WHITEBROWSERTOOLBAR) :
  156. MAKEINTRESOURCE(IDB_BROWSERTOOLBAR),
  157. 13, 0, RGB(255,0,255),
  158. IMAGE_BITMAP, LR_CREATEDIBSECTION);
  159. #endif
  160. ImageList_SetBkColor(himl, RGB(0,0,0));
  161. SendMessage(_hwndTB, TB_SETIMAGELIST, 0, (LPARAM)himl);
  162. SendMessage(_hwndTB, TB_BUTTONSTRUCTSIZE, SIZEOF(TBBUTTON), 0);
  163. SendMessage(_hwndTB, TB_ADDBUTTONS, ARRAYSIZE(tb), (LPARAM)tb);
  164. SendMessage(_hwndTB, TB_SETINDENT, (WPARAM)0, 0);
  165. _SizeTB();
  166. }
  167. }
  168. HRESULT CChannelDeskBarApp::ShowDW(BOOL fShow)
  169. {
  170. if (fShow && !_hwndTB) {
  171. _CreateToolbar();
  172. }
  173. HRESULT hres = CDeskBarApp::ShowDW(fShow);
  174. return hres;
  175. }
  176. void CChannelDeskBarApp::_PositionTB()
  177. {
  178. // position the toolbar
  179. if (_hwndTB) {
  180. // always put the close restore at the top right of the floater window
  181. RECT rc;
  182. RECT rcTB;
  183. GetClientRect(_hwnd, &rc);
  184. GetWindowRect(_hwndTB, &rcTB);
  185. rc.left = rc.right - RECTWIDTH(rcTB) - 2;
  186. SetWindowPos(_hwndTB, HWND_TOP, rc.left, 2, 0, 0, SWP_NOSIZE | SWP_NOACTIVATE);
  187. }
  188. }
  189. void CChannelDeskBarApp::_SizeTB()
  190. {
  191. RECT rc;
  192. GetWindowRect(_hwndTB, &rc);
  193. LRESULT lButtonSize = SendMessage(_hwndTB, TB_GETBUTTONSIZE, 0, 0L);
  194. SetWindowPos(_hwndTB, NULL, 0, 0, LOWORD(lButtonSize),
  195. RECTHEIGHT(rc), SWP_NOMOVE | SWP_NOACTIVATE);
  196. _PositionTB();
  197. }
  198. void CChannelDeskBarApp::_OnSize()
  199. {
  200. RECT rc, rcTB;
  201. if (!_hwndChild)
  202. return;
  203. ASSERT(IsWindow(_hwndChild));
  204. GetClientRect(_hwnd, &rc);
  205. if (_hwndTB) {
  206. GetWindowRect(_hwndTB, &rcTB);
  207. SetWindowPos(_hwndTB, HWND_TOP, rc.right - RECTWIDTH(rcTB) - 2, 2, 0, 0,
  208. SWP_NOSIZE | SWP_NOACTIVATE);
  209. SetWindowPos(_hwndChild, 0, rc.left, rc.top + RECTHEIGHT(rcTB) + 3,
  210. RECTWIDTH(rc), RECTHEIGHT(rc), SWP_NOACTIVATE|SWP_NOZORDER);
  211. }
  212. else {
  213. // how could there be no toolbar?
  214. ASSERT(0);
  215. SetWindowPos(_hwndChild, 0, rc.left, rc.top + TBHEIGHT + 3,
  216. RECTWIDTH(rc), RECTHEIGHT(rc), SWP_NOACTIVATE|SWP_NOZORDER);
  217. }
  218. rc.bottom = rc.top + TBHEIGHT + 3;
  219. InvalidateRect(_hwnd, &rc, TRUE);
  220. }
  221. #define ABS(i) (((i) < 0) ? -(i) : (i))
  222. LRESULT CChannelDeskBarApp::_OnCommand(UINT uMsg, WPARAM wParam, LPARAM lParam)
  223. {
  224. UINT idCmd = GET_WM_COMMAND_ID(wParam, lParam);
  225. HWND hwnd = GET_WM_COMMAND_HWND(wParam, lParam);
  226. if (hwnd == _hwndTB) {
  227. switch (idCmd) {
  228. case IDM_AB_CLOSE:
  229. Exec(&CGID_DeskBarClient, DBCID_EMPTY, 0, NULL, NULL);
  230. break;
  231. }
  232. } else {
  233. return CDeskBarApp::_OnCommand(uMsg, wParam, lParam);
  234. }
  235. return 0;
  236. }
  237. BOOL CChannelDeskBarApp::_OnCloseBar(BOOL fConfirm)
  238. {
  239. return CDeskBarApp::_OnCloseBar(FALSE);
  240. }
  241. HRESULT CChannelDeskBarApp::CloseDW(DWORD dwReserved)
  242. {
  243. // close the toolbar window
  244. if (_hwndTB) {
  245. HIMAGELIST himl = (HIMAGELIST)SendMessage(_hwndTB, TB_SETIMAGELIST, 0, 0);
  246. ImageList_Destroy(himl);
  247. DestroyWindow(_hwndTB);
  248. _hwndTB = NULL;
  249. }
  250. if (_hwnd) {
  251. CDeskBarApp::CloseDW(dwReserved);
  252. // Check the active desktop is ON. If so, do not ask for the confirmation.
  253. // we need to kill the channel bar silently.
  254. if (WhichPlatform() == PLATFORM_INTEGRATED) // SHGetSetSettings is not supported in IE3
  255. {
  256. SHELLSTATE ss = { 0 };
  257. SHGetSetSettings(&ss, SSF_DESKTOPHTML, FALSE); // Get the setting
  258. if (ss.fDesktopHTML) //Active desktop is ON. Die silently.
  259. return S_OK;
  260. }
  261. // set AutoLaunch reg value --
  262. // decide whether to launch channel bar when machine is rebooted next time
  263. int iRes = MLShellMessageBox(_hwnd,
  264. MAKEINTRESOURCE(IDS_CHANBAR_SHORTCUT_MSG),
  265. MAKEINTRESOURCE(IDS_CHANBAR_SHORTCUT_TITLE),
  266. MB_YESNO | MB_SETFOREGROUND);
  267. ChanBarSetAutoLaunchRegValue(iRes == IDYES);
  268. }
  269. return S_OK;
  270. }
  271. // store position and size to registry
  272. void CChannelDeskBarApp::_PersistState()
  273. {
  274. if (_hwnd) {
  275. CISSTRUCT cis;
  276. cis.iVer = 1;
  277. GetWindowRect(_hwnd, &cis.rc);
  278. SHRegSetUSValue(SZ_REGKEY_CHANBAR, SZ_REGVALUE_CHANBAR, REG_BINARY,
  279. (LPVOID)&cis, sizeof(CISSTRUCT), SHREGSET_HKCU | SHREGSET_FORCE_HKCU );
  280. }
  281. }
  282. void ChanBarSetAutoLaunchRegValue(BOOL fAutoLaunch)
  283. {
  284. SHRegSetUSValue(TEXT("Software\\Microsoft\\Internet Explorer\\Main"),
  285. TEXT("Show_ChannelBand"), REG_SZ,
  286. fAutoLaunch ? TEXT("yes") : TEXT("no"),
  287. sizeof(fAutoLaunch ? TEXT("yes") : TEXT("no")),
  288. SHREGSET_HKCU | SHREGSET_FORCE_HKCU);
  289. }
  290. //***
  291. // NOTES
  292. // REARCHITECT: nuke this, fold it into CChannelDeskBarApp_CreateInstance
  293. HRESULT ChannelDeskBarApp_Create(IUnknown** ppunk, IUnknown** ppbs)
  294. {
  295. HRESULT hres;
  296. *ppunk = NULL;
  297. if (ppbs)
  298. *ppbs = NULL;
  299. CChannelDeskBarApp *pdb = new CChannelDeskBarApp();
  300. if (!pdb)
  301. return E_OUTOFMEMORY;
  302. CBandSite *pcbs = new CBandSite(NULL);
  303. if (pcbs)
  304. {
  305. IDeskBarClient *pdbc = SAFECAST(pcbs, IDeskBarClient*);
  306. hres = pdb->SetClient(pdbc);
  307. if (SUCCEEDED(hres))
  308. {
  309. if (ppbs) {
  310. *ppbs = pdbc;
  311. pdbc->AddRef();
  312. }
  313. pdb->_pbs = pcbs;
  314. pcbs->AddRef();
  315. *ppunk = SAFECAST(pdb, IDeskBar*);
  316. }
  317. pdbc->Release();
  318. }
  319. else
  320. {
  321. hres = E_OUTOFMEMORY;
  322. }
  323. if (FAILED(hres))
  324. {
  325. pdb->Release();
  326. }
  327. return hres;
  328. }
  329. HRESULT CChannelDeskBarApp::Load(IPropertyBag *pPropBag, IErrorLog *pErrorLog)
  330. {
  331. HRESULT hres = CDeskBarApp::Load(pPropBag, pErrorLog);
  332. BANDSITEINFO bsinfo;
  333. bsinfo.dwMask = BSIM_STYLE;
  334. bsinfo.dwStyle = BSIS_NOGRIPPER | BSIS_NODROPTARGET;
  335. _pbs->SetBandSiteInfo(&bsinfo);
  336. return hres;
  337. }
  338. #endif // ENABLE_CHANNELS