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.

529 lines
16 KiB

  1. /*-----------------------------------------------------------------------------+
  2. | TOOLBAR.C |
  3. | |
  4. | Contains the code which implements the toolbar and its buttons. |
  5. | |
  6. | (C) Copyright Microsoft Corporation 1991. All rights reserved. |
  7. | |
  8. | Revision History |
  9. | Oct-1992 MikeTri Ported to WIN32 / WIN16 common code |
  10. | |
  11. +-----------------------------------------------------------------------------*/
  12. #include <windows.h>
  13. #include <string.h>
  14. #include <shellapi.h>
  15. #include "toolbar.h"
  16. #include "mpole.h"
  17. #include "mplayer.h"
  18. #ifndef COLOR_BTNFACE
  19. #define COLOR_BTNFACE 15
  20. #define COLOR_BTNSHADOW 16
  21. #define COLOR_BTNTEXT 18
  22. #endif
  23. extern void FAR cdecl dprintf(LPSTR szFormat, ...);
  24. extern HWND ghwndApp;
  25. extern HWND ghwndToolbar;
  26. extern HWND ghwndFSArrows;
  27. /*
  28. Variables
  29. */
  30. HBRUSH hbrGray = NULL; // Gray for text
  31. HBRUSH hbrButtonFace;
  32. HBRUSH hbrButtonShadow;
  33. HBRUSH hbrButtonText;
  34. HBRUSH hbrButtonHighLight;
  35. HBRUSH hbrWindowFrame;
  36. HBRUSH hbrWindowColour;
  37. DWORD rgbButtonHighLight;
  38. DWORD rgbButtonFocus;
  39. DWORD rgbButtonFace;
  40. DWORD rgbButtonText;
  41. DWORD rgbButtonShadow;
  42. DWORD rgbWindowFrame;
  43. DWORD rgbWindowColour;
  44. TBBUTTON tbBtns[TB_NUM_BTNS + MARK_NUM_BTNS + ARROW_NUM_BTNS] =
  45. {
  46. {BTN_PLAY, IDT_PLAY, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0},
  47. {BTN_PAUSE, IDT_PAUSE, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0},
  48. {BTN_STOP, IDT_STOP, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0},
  49. {BTN_EJECT, IDT_EJECT, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0},
  50. {BTN_HOME, IDT_HOME, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0},
  51. {BTN_RWD, IDT_RWD, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0},
  52. {BTN_FWD, IDT_FWD, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0},
  53. {BTN_END, IDT_END, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0},
  54. {-1, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0},
  55. {BTN_MARKIN, IDT_MARKIN, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0},
  56. {BTN_MARKOUT, IDT_MARKOUT, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0},
  57. {ARROW_PREV, IDT_ARROWPREV, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0},
  58. {ARROW_NEXT, IDT_ARROWNEXT, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0}
  59. };
  60. int BtnIndex[TB_NUM_BTNS + MARK_NUM_BTNS + ARROW_NUM_BTNS];
  61. static int iBtnOffset[3] = {0,TB_NUM_BTNS, TB_NUM_BTNS+MARK_NUM_BTNS};
  62. WNDPROC fnTBWndProc = NULL;
  63. WNDPROC fnStatusWndProc = NULL;
  64. /*
  65. ControlInit( hInst )
  66. This is called when the application is first loaded into
  67. memory. It performs all initialization.
  68. Arguments:
  69. hInst instance handle of current instance
  70. Returns:
  71. TRUE if successful, FALSE if not
  72. */
  73. BOOL
  74. FAR PASCAL
  75. ControlInit(
  76. HANDLE hInst)
  77. {
  78. long patGray[4];
  79. HBITMAP hbmGray;
  80. int i;
  81. /* initialize the brushes */
  82. for (i=0; i < 4; i++)
  83. patGray[i] = 0xAAAA5555L; // 0x11114444L; // lighter gray
  84. hbmGray = CreateBitmap(8, 8, 1, 1, patGray);
  85. hbrGray = CreatePatternBrush(hbmGray);
  86. if (hbmGray)
  87. DeleteObject(hbmGray);
  88. rgbButtonFace = GetSysColor(COLOR_BTNFACE);
  89. rgbButtonShadow = GetSysColor(COLOR_BTNSHADOW);
  90. rgbButtonText = GetSysColor(COLOR_BTNTEXT);
  91. rgbButtonHighLight = GetSysColor(COLOR_BTNHIGHLIGHT);
  92. rgbButtonFocus = GetSysColor(COLOR_BTNTEXT);
  93. rgbWindowFrame = GetSysColor(COLOR_WINDOWFRAME);
  94. rgbWindowColour = GetSysColor(COLOR_WINDOW);
  95. if (rgbButtonFocus == rgbButtonFace)
  96. rgbButtonFocus = rgbButtonText;
  97. hbrButtonFace = CreateSolidBrush(rgbButtonFace);
  98. hbrButtonShadow = CreateSolidBrush(rgbButtonShadow);
  99. hbrButtonText = CreateSolidBrush(rgbButtonText);
  100. hbrButtonHighLight = CreateSolidBrush(rgbButtonHighLight);
  101. hbrWindowFrame = CreateSolidBrush(rgbWindowFrame);
  102. hbrWindowColour = CreateSolidBrush(rgbWindowColour);
  103. if (((UINT_PTR)hbrWindowFrame & // fail if any of them are NULL ???
  104. (UINT_PTR)hbrButtonShadow &
  105. (UINT_PTR)hbrButtonText &
  106. (UINT_PTR)hbrButtonHighLight &
  107. (UINT_PTR)hbrWindowFrame) == (UINT_PTR)0)
  108. return FALSE;
  109. return TRUE;
  110. }
  111. /*
  112. ControlCleanup()
  113. Delete the brushes we've been using
  114. */
  115. void FAR PASCAL ControlCleanup(void)
  116. {
  117. DeleteObject(hbrGray);
  118. DeleteObject(hbrButtonFace);
  119. DeleteObject(hbrButtonShadow);
  120. DeleteObject(hbrButtonText);
  121. DeleteObject(hbrButtonHighLight);
  122. DeleteObject(hbrWindowFrame);
  123. DeleteObject(hbrWindowColour);
  124. #if 0
  125. DeleteObject(hbTBMain);
  126. DeleteObject(hbTBMark);
  127. DeleteObject(hbTBArrows);
  128. #endif
  129. }
  130. BOOL FAR PASCAL toolbarInit(void)
  131. {
  132. int i;
  133. InitCommonControls();
  134. for(i = 0; i < TB_NUM_BTNS + MARK_NUM_BTNS + ARROW_NUM_BTNS; i++)
  135. BtnIndex[i] = -1;
  136. return TRUE;
  137. }
  138. LONG_PTR FAR PASCAL SubClassedTBWndProc(HWND hwnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
  139. {
  140. switch(wMsg)
  141. {
  142. case WM_SIZE:
  143. return 0;
  144. case WM_STARTTRACK:
  145. switch(wParam)
  146. {
  147. case IDT_RWD:
  148. case IDT_FWD:
  149. case IDT_ARROWPREV:
  150. case IDT_ARROWNEXT:
  151. PostMessage(ghwndApp, WM_COMMAND, wParam, REPEAT_ID);
  152. SetTimer(hwnd, (UINT_PTR)ghwndApp, MSEC_BUTTONREPEAT, NULL);
  153. }
  154. return 0;
  155. case WM_ENDTRACK:
  156. switch(wParam)
  157. {
  158. case IDT_RWD:
  159. case IDT_FWD:
  160. case IDT_ARROWPREV:
  161. case IDT_ARROWNEXT:
  162. KillTimer(hwnd, wParam);
  163. SendMessage(ghwndApp, WM_HSCROLL, (WPARAM)TB_ENDTRACK, (LPARAM)hwnd);
  164. }
  165. return 0;
  166. case WM_TIMER:
  167. {
  168. WPARAM cmd;
  169. if (wParam != (WPARAM)ghwndApp)
  170. break;
  171. if (hwnd == ghwndToolbar)
  172. {
  173. if(SendMessage(hwnd, TB_ISBUTTONPRESSED, tbBtns[BTN_RWD].idCommand, 0L))
  174. cmd = IDT_RWD;
  175. else if(SendMessage(hwnd, TB_ISBUTTONPRESSED, tbBtns[BTN_FWD].idCommand, 0L))
  176. cmd = IDT_FWD;
  177. else
  178. return 0;
  179. PostMessage(ghwndApp, WM_COMMAND, cmd, REPEAT_ID);
  180. return 0;
  181. }
  182. else
  183. if (hwnd == ghwndFSArrows)
  184. {
  185. if(SendMessage(hwnd, TB_ISBUTTONPRESSED, tbBtns[TB_NUM_BTNS+MARK_NUM_BTNS+ARROW_PREV].idCommand, 0L))
  186. cmd = IDT_ARROWPREV;
  187. else if(SendMessage(hwnd, TB_ISBUTTONPRESSED, tbBtns[TB_NUM_BTNS+MARK_NUM_BTNS+ARROW_NEXT].idCommand, 0L))
  188. cmd = IDT_ARROWNEXT;
  189. else
  190. return 0;
  191. PostMessage(ghwndApp, WM_COMMAND, cmd, REPEAT_ID);
  192. return 0;
  193. }
  194. KillTimer(hwnd, wParam);
  195. return 0;
  196. }
  197. }
  198. return CallWindowProc(fnTBWndProc, hwnd, wMsg, wParam, lParam);
  199. }
  200. void SubClassTBWindow(HWND hwnd)
  201. {
  202. if (!fnTBWndProc)
  203. fnTBWndProc = (WNDPROC)GetWindowLongPtr(hwnd, GWLP_WNDPROC);
  204. if (hwnd)
  205. SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)SubClassedTBWndProc);
  206. }
  207. #ifndef CCS_NODIVIDER
  208. /* For NT: */
  209. #define CCS_NODIVIDER 0
  210. #endif
  211. HWND FAR PASCAL toolbarCreateMain(HWND hwndParent)
  212. {
  213. HWND hwnd;
  214. hwnd = CreateToolbarEx(hwndParent,
  215. WS_VISIBLE|WS_CHILD|WS_CLIPSIBLINGS|TBSTYLE_BUTTON|TBSTYLE_TOOLTIPS|
  216. CCS_NODIVIDER,
  217. IDT_TBMAINCID, 8,
  218. ghInst, IDR_TOOLBAR, NULL, 0, 16, 16, 16, 16, sizeof(TBBUTTON));
  219. if (hwnd)
  220. SubClassTBWindow(hwnd);
  221. return hwnd;
  222. }
  223. HWND FAR PASCAL toolbarCreateMark(HWND hwndParent)
  224. {
  225. HWND hwnd;
  226. hwnd = CreateToolbarEx(hwndParent,
  227. WS_VISIBLE|WS_CHILD|WS_CLIPSIBLINGS|TBSTYLE_BUTTON|TBSTYLE_TOOLTIPS|
  228. CCS_NODIVIDER,
  229. IDT_TBMARKCID, 2,
  230. ghInst, IDR_MARK, NULL, 0, 17, 16, 17, 16, sizeof(TBBUTTON));
  231. if (hwnd)
  232. SubClassTBWindow(hwnd);
  233. return hwnd;
  234. }
  235. HWND FAR PASCAL toolbarCreateArrows(HWND hwndParent)
  236. {
  237. HWND hwnd;
  238. hwnd = CreateToolbarEx(hwndParent,
  239. WS_VISIBLE|WS_CHILD|WS_CLIPSIBLINGS|TBSTYLE_BUTTON|TBSTYLE_TOOLTIPS|
  240. CCS_NODIVIDER,
  241. IDT_TBARROWSCID,
  242. 2,
  243. ghInst,
  244. IDR_ARROWS,
  245. NULL,
  246. 0,
  247. 4,
  248. 7,
  249. 4,
  250. 7,
  251. sizeof(TBBUTTON));
  252. if (hwnd)
  253. SubClassTBWindow(hwnd);
  254. return hwnd;
  255. }
  256. /***************************************************************************/
  257. /* toolbarStateFromButton: This fn is called by the parent application */
  258. /* to get the state of a button. It will only */
  259. /* return DOWN, or UP or GRAYED as opposed to */
  260. /* toolbarFullStateFromButton which could return */
  261. /* FULLDOWN. */
  262. /***************************************************************************/
  263. BOOL FAR PASCAL toolbarStateFromButton(HWND hwnd, int iButton, int tbIndex)
  264. {
  265. int idBtn;
  266. int pos;
  267. pos = BtnIndex[iBtnOffset[tbIndex] + iButton];
  268. if (pos == -1)
  269. return FALSE;
  270. idBtn = tbBtns[iBtnOffset[tbIndex] + iButton].idCommand;
  271. return (BOOL)SendMessage(hwnd, TB_ISBUTTONENABLED, (WPARAM)idBtn, 0L);
  272. }
  273. /***************************************************************************/
  274. /* toolbarAddTool: Add a button to this toolbar. Sort them by leftmost */
  275. /* position in the window (for tabbing order). */
  276. /* Return FALSE for an error. */
  277. /***************************************************************************/
  278. BOOL FAR PASCAL toolbarAddTool(HWND hwnd, int iButton, int tbIndex, int iState)
  279. {
  280. TBBUTTON tb;
  281. tb = tbBtns[iBtnOffset[tbIndex] + iButton];
  282. if (iState)
  283. tb.fsState |= TBSTATE_ENABLED;
  284. else
  285. tb.fsState &= ~TBSTATE_ENABLED;
  286. if(!SendMessage(hwnd, TB_ADDBUTTONS, (WPARAM)1, (LPARAM)(const TBBUTTON FAR *)&tb))
  287. return FALSE;
  288. BtnIndex[iBtnOffset[tbIndex] + iButton] =
  289. (int)SendMessage(hwnd, TB_BUTTONCOUNT, 0, 0L) - 1;
  290. return TRUE;
  291. }
  292. BOOL FAR PASCAL toolbarSwapTools(HWND hwnd, int iButton, int jButton, int tbIndex)
  293. {
  294. int pos;
  295. TBBUTTON tb;
  296. int newBut, oldBut;
  297. pos = BtnIndex[iBtnOffset[tbIndex] + iButton];
  298. if (pos == -1)
  299. {
  300. pos = BtnIndex[iBtnOffset[tbIndex] + jButton];
  301. if (pos == -1)
  302. return FALSE;
  303. newBut = iButton;
  304. oldBut = jButton;
  305. }
  306. else
  307. {
  308. newBut = jButton;
  309. oldBut = iButton;
  310. }
  311. SendMessage(hwnd, TB_DELETEBUTTON, (WPARAM)pos, 0L);
  312. BtnIndex[iBtnOffset[tbIndex] + oldBut] = -1;
  313. tb = tbBtns[iBtnOffset[tbIndex] + newBut];
  314. if(!SendMessage(hwnd, TB_INSERTBUTTON, (WPARAM)pos, (LPARAM)(const TBBUTTON FAR *)&tb))
  315. return FALSE;
  316. BtnIndex[iBtnOffset[tbIndex] + newBut] = pos;
  317. return TRUE;
  318. }
  319. /***************************************************************************/
  320. /* toolbarModifyState: Given a button ID on the toolbar, change its */
  321. /* state. */
  322. /* returns FALSE for an error or if no such button */
  323. /***************************************************************************/
  324. BOOL FAR PASCAL toolbarModifyState(HWND hwnd, int iButton, int tbIndex, int iState)
  325. {
  326. int idBtn;
  327. int pos;
  328. pos = BtnIndex[iBtnOffset[tbIndex] + iButton];
  329. if (pos == -1)
  330. return FALSE;
  331. idBtn = tbBtns[iBtnOffset[tbIndex] + iButton].idCommand;
  332. SendMessage(hwnd, TB_PRESSBUTTON, (WPARAM)idBtn, 0L); //unpress button first. commctrl bug
  333. if (idBtn == IDT_STOP)
  334. {
  335. SendMessage(hwnd, TB_PRESSBUTTON, (WPARAM)IDT_HOME, 0L);
  336. SendMessage(hwnd, TB_PRESSBUTTON, (WPARAM)IDT_END, 0L);
  337. SendMessage(hwnd, TB_PRESSBUTTON, (WPARAM)IDT_FWD, 0L);
  338. SendMessage(hwnd, TB_PRESSBUTTON, (WPARAM)IDT_RWD, 0L);
  339. }
  340. if (!iState)
  341. SendMessage(hwnd, TB_PRESSBUTTON, (WPARAM)IDT_EJECT, 0L);
  342. SendMessage(hwnd, TB_ENABLEBUTTON, (WPARAM)idBtn, (LPARAM)MAKELONG(iState, 0));
  343. return TRUE;
  344. }
  345. /***************************************************************************/
  346. /* toolbarSetFocus : Set the focus in the toolbar to the specified button.*/
  347. /* If it's gray, it'll set focus to next ungrayed btn. */
  348. /***************************************************************************/
  349. BOOL FAR PASCAL toolbarSetFocus(HWND hwnd, int iButton)
  350. {
  351. int pos;
  352. if ((hwnd != ghwndToolbar) || (iButton != BTN_PLAY && iButton != BTN_PAUSE))
  353. return TRUE;
  354. pos = BtnIndex[iButton];
  355. if (pos != -1)
  356. return TRUE;
  357. toolbarSwapTools(hwnd, iButton, 1-iButton, TBINDEX_MAIN);
  358. return TRUE;
  359. }
  360. LONG_PTR FAR PASCAL SubClassedStatusWndProc(HWND hwnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
  361. {
  362. switch(wMsg)
  363. {
  364. case WM_SIZE:
  365. return 0;
  366. }
  367. return CallWindowProc(fnStatusWndProc, hwnd, wMsg, wParam, lParam);
  368. }
  369. void SubClassStatusWindow(HWND hwnd)
  370. {
  371. if (!fnStatusWndProc)
  372. fnStatusWndProc = (WNDPROC)GetWindowLongPtr(hwnd, GWLP_WNDPROC);
  373. if (hwnd)
  374. SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)SubClassedStatusWndProc);
  375. }
  376. /* SBS_SIZEGRIP isn't defined for NT!! */
  377. #ifndef SBS_SIZEGRIP
  378. #define SBS_SIZEGRIP 0
  379. #endif
  380. HWND CreateStaticStatusWindow(HWND hwndParent, BOOL fSizeGrip)
  381. {
  382. HWND hwnd;
  383. hwnd = CreateStatusWindow(WS_CHILD|WS_VISIBLE|(fSizeGrip ? 0 : CCS_NOMOVEY),
  384. TEXT(""), hwndParent, IDT_STATUSWINDOWCID);
  385. if (hwnd)
  386. SubClassStatusWindow(hwnd);
  387. return hwnd;
  388. }
  389. BOOL WriteStatusMessage(HWND hwnd, LPTSTR szMsg)
  390. {
  391. TCHAR Text[64];
  392. SIZE StatusTextExtent;
  393. LONG StatusTextWidth;
  394. BOOL rc;
  395. Text[0] = TEXT('\0');
  396. GetWindowText(hwnd, Text, CHAR_COUNT(Text));
  397. if (lstrcmp(szMsg, Text) == 0)
  398. return TRUE;
  399. GetStatusTextExtent(ghwndStatic, &StatusTextExtent);
  400. StatusTextWidth = StatusTextExtent.cy;
  401. rc = (BOOL)SendMessage(hwnd, SB_SETTEXT, (WPARAM)0, (LPARAM)szMsg);
  402. GetStatusTextExtent(ghwndStatic, &StatusTextExtent);
  403. if (StatusTextWidth != StatusTextExtent.cy)
  404. Layout();
  405. return rc;
  406. }
  407. BOOL GetStatusTextExtent(HWND hwnd, LPSIZE pTextExtent)
  408. {
  409. HDC hdc;
  410. HFONT hfontOld;
  411. TCHAR Text[64];
  412. hdc = GetDC(NULL);
  413. if (hdc == NULL)
  414. return FALSE;
  415. Text[0] = TEXT('\0');
  416. GetWindowText(hwnd, Text, CHAR_COUNT(Text));
  417. hfontOld = SelectObject(hdc, (HFONT)SendMessage(hwnd, WM_GETFONT, 0, 0));
  418. GetTextExtentPoint32(hdc, Text, STRLEN(Text), pTextExtent);
  419. SelectObject(hdc, hfontOld);
  420. ReleaseDC(NULL, hdc);
  421. return TRUE;
  422. }
  423.