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.

1147 lines
39 KiB

  1. /* commctrl.h : Interfaces for the Windows Common Controls.
  2. * Copyright (C) Microsoft 1991-1992
  3. */
  4. /*REVIEW: this stuff needs Windows style in many places; find all REVIEWs. */
  5. #ifndef _INC_COMMCTRL
  6. #define _INC_COMMCTRL
  7. #ifdef __cplusplus
  8. extern "C" {
  9. #endif
  10. /* Users of this header may define any number of these constants to avoid
  11. * the definitions of each functional group.
  12. * NOTOOLBAR Customizable bitmap-button toolbar control.
  13. * NOUPDOWN Up and Down arrow increment/decrement control.
  14. * NOSTATUSBAR Status bar and header bar controls.
  15. * NOMENUHELP APIs to help manage menus, especially with a status bar.
  16. * NOTRACKBAR Customizable column-width tracking control.
  17. * NOBTNLIST A control which is a list of bitmap buttons.
  18. * NODRAGLIST APIs to make a listbox source and sink drag&drop actions.
  19. * NOPROGRESS Progress gas gauge.
  20. */
  21. /*/////////////////////////////////////////////////////////////////////////*/
  22. /* InitCommonControls:
  23. * Any application requiring the use of any common control should call this
  24. * API upon application startup. There is no required shutdown.
  25. */
  26. void WINAPI InitCommonControls();
  27. /*/////////////////////////////////////////////////////////////////////////*/
  28. #ifndef NOTOOLBAR
  29. #define TOOLBARCLASSNAME "MCIWndToolbar"
  30. /* Note that LOWORD(dwData) is at the same offset as idsHelp in the old
  31. ** structure, since it was never used anyway.
  32. */
  33. typedef struct tagTBBUTTON
  34. {
  35. /*REVIEW: index, command, flag words, resource ids should be UINT */
  36. int iBitmap; /* index into bitmap of this button's picture */
  37. int idCommand; /* WM_COMMAND menu ID that this button sends */
  38. BYTE fsState; /* button's state */
  39. BYTE fsStyle; /* button's style */
  40. DWORD dwData; /* app defined data */
  41. int iString; /* index into string list */
  42. } TBBUTTON;
  43. typedef TBBUTTON NEAR* PTBBUTTON;
  44. typedef TBBUTTON FAR* LPTBBUTTON;
  45. typedef const TBBUTTON FAR* LPCTBBUTTON;
  46. /*REVIEW: is this internal? if not, call it TBADJUSTINFO, prefix tba */
  47. typedef struct tagADJUSTINFO
  48. {
  49. TBBUTTON tbButton;
  50. char szDescription[1];
  51. } ADJUSTINFO;
  52. typedef ADJUSTINFO NEAR* PADJUSTINFO;
  53. typedef ADJUSTINFO FAR* LPADJUSTINFO;
  54. /*REVIEW: is this internal? if not, call it TBCOLORMAP, prefix tbc */
  55. typedef struct tagCOLORMAP
  56. {
  57. COLORREF from;
  58. COLORREF to;
  59. } COLORMAP;
  60. typedef COLORMAP NEAR* PCOLORMAP;
  61. typedef COLORMAP FAR* LPCOLORMAP;
  62. /* This is likely to change several times in the near future. */
  63. HWND WINAPI CreateToolbarEx(HWND hwnd, DWORD ws, WORD wID, int nBitmaps,
  64. HINSTANCE hBMInst, WORD wBMID, LPCTBBUTTON lpButtons,
  65. int iNumButtons, int dxButton, int dyButton,
  66. int dxBitmap, int dyBitmap, UINT uStructSize);
  67. /*REVIEW: idBitmap, iNumMaps should be UINT */
  68. HBITMAP WINAPI CreateMappedBitmap(HINSTANCE hInstance, int idBitmap,
  69. WORD wFlags, LPCOLORMAP lpColorMap,
  70. int iNumMaps);
  71. #define CMB_DISCARDABLE 0x01 /* create bitmap as discardable */
  72. #define CMB_MASKED 0x02 /* create image/mask pair in bitmap */
  73. /*REVIEW: TBSTATE_* should be TBF_* (for Flags) */
  74. #define TBSTATE_CHECKED 0x01 /* radio button is checked */
  75. #define TBSTATE_PRESSED 0x02 /* button is being depressed (any style) */
  76. #define TBSTATE_ENABLED 0x04 /* button is enabled */
  77. #define TBSTATE_HIDDEN 0x08 /* button is hidden */
  78. #define TBSTATE_INDETERMINATE 0x10 /* button is indeterminate */
  79. /* (needs to be endabled, too) */
  80. /*REVIEW: TBSTYLE_* should be TBS_* (for Style) */
  81. #define TBSTYLE_BUTTON 0x00 /* this entry is button */
  82. #define TBSTYLE_SEP 0x01 /* this entry is a separator */
  83. #define TBSTYLE_CHECK 0x02 /* this is a check button (it stays down) */
  84. #define TBSTYLE_GROUP 0x04 /* this is a check button (it stays down) */
  85. #define TBSTYLE_CHECKGROUP (TBSTYLE_GROUP | TBSTYLE_CHECK) /* this group is a member of a group radio group */
  86. /*REVIEW: ifdef _INC_WINDOWSX, should we provide message crackers? */
  87. #define TB_ENABLEBUTTON (WM_USER + 1)
  88. /* wParam: UINT, button ID
  89. ** lParam: BOOL LOWORD, enable if nonzero; HIWORD not used, 0
  90. ** return: not used
  91. */
  92. #define TB_CHECKBUTTON (WM_USER + 2)
  93. /* wParam: UINT, button ID
  94. ** lParam: BOOL LOWORD, check if nonzero; HIWORD not used, 0
  95. ** return: not used
  96. */
  97. #define TB_PRESSBUTTON (WM_USER + 3)
  98. /* wParam: UINT, button ID
  99. ** lParam: BOOL LOWORD, press if nonzero; HIWORD not used, 0
  100. ** return: not used
  101. */
  102. #define TB_HIDEBUTTON (WM_USER + 4)
  103. /* wParam: UINT, button ID
  104. ** lParam: BOOL LOWORD, hide if nonzero; HIWORD not used, 0
  105. ** return: not used
  106. */
  107. #define TB_INDETERMINATE (WM_USER + 5)
  108. /* wParam: UINT, button ID
  109. ** lParam: BOOL LOWORD, make indeterminate if nonzero; HIWORD not used, 0
  110. ** return: not used
  111. */
  112. /*REVIEW: Messages up to WM_USER+8 are reserved until we define more state bits */
  113. #define TB_ISBUTTONENABLED (WM_USER + 9)
  114. /* wParam: UINT, button ID
  115. ** lParam: not used, 0
  116. ** return: BOOL LOWORD, enabled if nonzero; HIWORD not used
  117. */
  118. #define TB_ISBUTTONCHECKED (WM_USER + 10)
  119. /* wParam: UINT, button ID
  120. ** lParam: not used, 0
  121. ** return: BOOL LOWORD, checked if nonzero; HIWORD not used
  122. */
  123. #define TB_ISBUTTONPRESSED (WM_USER + 11)
  124. /* wParam: UINT, button ID
  125. ** lParam: not used, 0
  126. ** return: BOOL LOWORD, pressed if nonzero; HIWORD not used
  127. */
  128. #define TB_ISBUTTONHIDDEN (WM_USER + 12)
  129. /* wParam: UINT, button ID
  130. ** lParam: not used, 0
  131. ** return: BOOL LOWORD, hidden if nonzero; HIWORD not used
  132. */
  133. #define TB_ISBUTTONINDETERMINATE (WM_USER + 13)
  134. /* wParam: UINT, button ID
  135. ** lParam: not used, 0
  136. ** return: BOOL LOWORD, indeterminate if nonzero; HIWORD not used
  137. */
  138. /*REVIEW: Messages up to WM_USER+16 are reserved until we define more state bits */
  139. #define TB_SETSTATE (WM_USER + 17)
  140. /* wParam: UINT, button ID
  141. ** lParam: UINT LOWORD, state bits; HIWORD not used, 0
  142. ** return: not used
  143. */
  144. #define TB_GETSTATE (WM_USER + 18)
  145. /* wParam: UINT, button ID
  146. ** lParam: not used, 0
  147. ** return: UINT LOWORD, state bits; HIWORD not used
  148. */
  149. #define TB_ADDBITMAP (WM_USER + 19)
  150. /* wParam: UINT, number of button graphics in bitmap
  151. ** lParam: one of:
  152. ** HINSTANCE LOWORD, module handle; UINT HIWORD, resource id
  153. ** HINSTANCE LOWORD, NULL; HBITMAP HIWORD, bitmap handle
  154. ** return: one of:
  155. ** int LOWORD, index for first new button; HIWORD not used
  156. ** int LOWORD, -1 indicating error; HIWORD not used
  157. */
  158. #define TB_ADDBUTTONS (WM_USER + 20)
  159. /* wParam: UINT, number of buttons to add
  160. ** lParam: LPTBBUTTON, pointer to array of TBBUTTON structures
  161. ** return: not used
  162. */
  163. #define TB_INSERTBUTTON (WM_USER + 21)
  164. /* wParam: UINT, index for insertion (appended if index doesn't exist)
  165. ** lParam: LPTBBUTTON, pointer to one TBBUTTON structure
  166. ** return: not used
  167. */
  168. #define TB_DELETEBUTTON (WM_USER + 22)
  169. /* wParam: UINT, index of button to delete
  170. ** lParam: not used, 0
  171. ** return: not used
  172. */
  173. #define TB_GETBUTTON (WM_USER + 23)
  174. /* wParam: UINT, index of button to get
  175. ** lParam: LPTBBUTTON, pointer to TBBUTTON buffer to receive button
  176. ** return: not used
  177. */
  178. #define TB_BUTTONCOUNT (WM_USER + 24)
  179. /* wParam: not used, 0
  180. ** lParam: not used, 0
  181. ** return: UINT LOWORD, number of buttons; HIWORD not used
  182. */
  183. #define TB_COMMANDTOINDEX (WM_USER + 25)
  184. /* wParam: UINT, command id
  185. ** lParam: not used, 0
  186. ** return: UINT LOWORD, index of button (-1 if command not found);
  187. ** HIWORD not used
  188. **/
  189. #define TB_SAVERESTORE (WM_USER + 26)
  190. /* wParam: BOOL, save state if nonzero (otherwise restore)
  191. ** lParam: LPSTR FAR*, pointer to two LPSTRs:
  192. ** (LPSTR FAR*)(lParam)[0]: ini section name
  193. ** (LPSTR FAR*)(lParam)[1]: ini file name or NULL for WIN.INI
  194. ** return: not used
  195. */
  196. #define TB_CUSTOMIZE (WM_USER + 27)
  197. /* wParam: not used, 0
  198. ** lParam: not used, 0
  199. ** return: not used
  200. */
  201. #define TB_ADDSTRING (WM_USER + 28)
  202. /* wParam: UINT, 0 if no resource; HINSTANCE, module handle
  203. ** lParam: LPSTR, null-terminated strings with double-null at end
  204. ** UINT LOWORD, resource id
  205. ** return: one of:
  206. ** int LOWORD, index for first new string; HIWORD not used
  207. ** int LOWORD, -1 indicating error; HIWORD not used
  208. */
  209. #define TB_GETITEMRECT (WM_USER + 29)
  210. /* wParam: UINT, index of toolbar item whose rect to retrieve
  211. ** lParam: LPRECT, pointer to a RECT struct to fill
  212. ** return: Non-zero, if the RECT is successfully filled
  213. ** Zero, otherwise (item did not exist or was hidden)
  214. */
  215. #define TB_BUTTONSTRUCTSIZE (WM_USER + 30)
  216. /* wParam: UINT, size of the TBBUTTON structure. This is used
  217. ** as a version check.
  218. ** lParam: not used
  219. ** return: not used
  220. **
  221. ** This is required before any buttons are added to the toolbar if
  222. ** the toolbar is created using CreateWindow, but is implied when
  223. ** using CreateToolbar and is a parameter to CreateToolbarEx.
  224. */
  225. #define TB_SETBUTTONSIZE (WM_USER + 31)
  226. /* wParam: not used, 0
  227. ** lParam: UINT LOWORD, button width
  228. ** UINT HIWORD, button height
  229. ** return: not used
  230. **
  231. ** The button size can only be set before any buttons are
  232. ** added. A default size of 24x22 is assumed if the size
  233. ** is not set explicitly.
  234. */
  235. #define TB_SETBITMAPSIZE (WM_USER + 32)
  236. /* wParam: not used, 0
  237. ** lParam: UINT LOWORD, bitmap width
  238. ** UINT HIWORD, bitmap height
  239. ** return: not used
  240. **
  241. ** The bitmap size can only be set before any bitmaps are
  242. ** added. A default size of 16x15 is assumed if the size
  243. ** is not set explicitly.
  244. */
  245. #define TB_AUTOSIZE (WM_USER + 33)
  246. /* wParam: not used, 0
  247. ** lParam: not used, 0
  248. ** return: not used
  249. **
  250. ** Application should call this after causing the toolbar size
  251. ** to change by either setting the button or bitmap size or
  252. ** by adding strings for the first time.
  253. */
  254. #define TB_SETBUTTONTYPE (WM_USER + 34)
  255. /* wParam: WORD, frame control style of button (DFC_*)
  256. ** lParam: not used, 0
  257. ** return: not used
  258. */
  259. #endif /* NOTOOLBAR */
  260. /*/////////////////////////////////////////////////////////////////////////*/
  261. #ifndef NOSTATUSBAR
  262. /*REVIEW: Here exists the only known documentation for status bars. */
  263. /* DrawStatusText:
  264. * This is used if the app wants to draw status in its client rect,
  265. * instead of just creating a window. Note that this same function is
  266. * used internally in the status bar window's WM_PAINT message.
  267. * hDC is the DC to draw to. The font that is selected into hDC will
  268. * be used. The RECT lprc is the only portion of hDC that will be drawn
  269. * to: the outer edge of lprc will have the highlights (the area outside
  270. * of the highlights will not be drawn in the BUTTONFACE color: the app
  271. * must handle that). The area inside the highlights will be erased
  272. * properly when drawing the text.
  273. */
  274. /*REVIEW: szText should be LPCSTR */
  275. void WINAPI DrawStatusText(HDC hDC, LPRECT lprc, LPSTR szText, UINT uFlags);
  276. /* CreateStatusWindow:
  277. * CreateHeaderWindow:
  278. * These create a "default" status or header window. This will have the
  279. * default borders around the text, the default font, and only one pane.
  280. * It may also automatically resize and move itself (depending on the SBS_*
  281. * flags).
  282. *
  283. * The style should contain WS_CHILD, and can contain WS_BORDER and
  284. * WS_VISIBLE, plus any of the SBS_* styles described below. I don't know
  285. * about other WS_* styles.
  286. *
  287. * The lpszText is the initial text for the first pane.
  288. * hwndParent is the window the status bar exists in, and should not be NULL.
  289. * wID is the child window ID of the window.
  290. * hInstance is the instance handle of the application using this.
  291. * Note that the app can also just call CreateWindow with
  292. * STATUSCLASSNAME/HEADERCLASSNAME to create a window of a specific size.
  293. *
  294. * Note the user can change the font used by setting win.ini [Desktop]:
  295. * StatusBarFaceName=Arial
  296. * StatusBarFaceHeight=10
  297. */
  298. /*REVIEW: style should be DWORD, lpszText should be LPCSTR */
  299. HWND WINAPI CreateStatusWindow(LONG style, LPSTR lpszText,
  300. HWND hwndParent, WORD wID);
  301. HWND WINAPI CreateHeaderWindow(LONG style, LPSTR lpszText,
  302. HWND hwndParent, WORD wID);
  303. /*REVIEW: should be STATUSBAR_CLASS, HEADERBAR_CLASS */
  304. #define STATUSCLASSNAME "msctls_statusbar"
  305. /* This is the name of the status bar class (it will probably change later
  306. * so use the #define here).
  307. */
  308. #define HEADERCLASSNAME "msctls_headerbar"
  309. /* This is the name of the status bar class (it will probably change later
  310. * so use the #define here).
  311. */
  312. #define SB_SETTEXT (WM_USER+1)
  313. #define SB_GETTEXT (WM_USER+2)
  314. #define SB_GETTEXTLENGTH (WM_USER+3)
  315. /* Just like WM_?ETTEXT*, with wParam specifying the pane that is referenced
  316. * (at most 255).
  317. * Note that you can use the WM_* versions to reference the 0th pane (this
  318. * is useful if you want to treat a "default" status bar like a static text
  319. * control).
  320. * For SETTEXT, wParam is the pane or'ed with SBT_* style bits (defined below).
  321. * If the text is "normal" (not OWNERDRAW), then a single pane may have left,
  322. * center, and right justified text by separating the parts with a single tab,
  323. * plus if lParam is NULL, then the pane has no text. The pane will be
  324. * invalidated, but not draw until the next PAINT message.
  325. * For GETTEXT and GETTEXTLENGTH, the LOWORD of the return will be the length,
  326. * and the HIWORD will be the SBT_* style bits.
  327. */
  328. #define SB_SETPARTS (WM_USER+4)
  329. /* wParam is the number of panes, and lParam points to an array of points
  330. * specifying the right hand side of each pane. A right hand side of -1 means
  331. * it goes all the way to the right side of the control minus the X border
  332. */
  333. #define SB_SETBORDERS (WM_USER+5)
  334. /* lParam points to an array of 3 integers: X border, Y border, between pane
  335. * border. If any is less than 0, the default will be used for that one.
  336. */
  337. #define SB_GETPARTS (WM_USER+6)
  338. /* lParam is a pointer to an array of integers that will get filled in with
  339. * the right hand side of each pane and wParam is the size (in integers)
  340. * of the lParam array (so we do not go off the end of it).
  341. * Returns the number of panes.
  342. */
  343. #define SB_GETBORDERS (WM_USER+7)
  344. /* lParam is a pointer to an array of 3 integers that will get filled in with
  345. * the X border, the Y border, and the between pane border.
  346. */
  347. #define SB_SETMINHEIGHT (WM_USER+8)
  348. /* wParam is the minimum height of the status bar "drawing" area. This is
  349. * the area inside the highlights. This is most useful if a pane is used
  350. * for an OWNERDRAW item, and is ignored if the SBS_NORESIZE flag is set.
  351. * Note that WM_SIZE (wParam=0, lParam=0L) must be sent to the control for
  352. * any size changes to take effect.
  353. */
  354. #define SB_SIMPLE (WM_USER+9)
  355. /* wParam specifies whether to set (non-zero) or unset (zero) the "simple"
  356. * mode of the status bar. In simple mode, only one pane is displayed, and
  357. * its text is set with LOWORD(wParam)==255 in the SETTEXT message.
  358. * OWNERDRAW is not allowed, but other styles are.
  359. * The pane gets invalidated, but not painted until the next PAINT message,
  360. * so you can set new text without flicker (I hope).
  361. * This can be used with the WM_INITMENU and WM_MENUSELECT messages to
  362. * implement help text when scrolling through a menu.
  363. */
  364. #define HB_SAVERESTORE (WM_USER+256)
  365. /* This gets a header bar to read or write its state to or from an ini file.
  366. * wParam is 0 for reading, non-zero for writing. lParam is a pointer to
  367. * an array of two LPSTR's: the section and file respectively.
  368. * Note that the correct number of partitions must be set before calling this.
  369. */
  370. #define HB_ADJUST (WM_USER+257)
  371. /* This puts the header bar into "adjust" mode, for changing column widths
  372. * with the keyboard.
  373. */
  374. #define HB_SETWIDTHS SB_SETPARTS
  375. /* Set the widths of the header columns. Note that "springy" columns only
  376. * have a minumum width, and negative width are assumed to be hidden columns.
  377. * This works just like SB_SETPARTS.
  378. */
  379. #define HB_GETWIDTHS SB_GETPARTS
  380. /* Get the widths of the header columns. Note that "springy" columns only
  381. * have a minumum width. This works just like SB_GETPARTS.
  382. */
  383. #define HB_GETPARTS (WM_USER+258)
  384. /* Get a list of the right-hand sides of the columns, for use when drawing the
  385. * actual columns for which this is a header.
  386. * lParam is a pointer to an array of integers that will get filled in with
  387. * the right hand side of each pane and wParam is the size (in integers)
  388. * of the lParam array (so we do not go off the end of it).
  389. * Returns the number of panes.
  390. */
  391. #define HB_SHOWTOGGLE (WM_USER+259)
  392. /* Toggle the hidden state of a column. wParam is the 0-based index of the
  393. * column to toggle.
  394. */
  395. #define SBT_OWNERDRAW 0x1000
  396. /* The lParam of the SB_SETTEXT message will be returned in the DRAWITEMSTRUCT
  397. * of the WM_DRAWITEM message. Note that the fields CtlType, itemAction, and
  398. * itemState of the DRAWITEMSTRUCT are undefined for a status bar.
  399. * The return value for GETTEXT will be the itemData.
  400. */
  401. #define SBT_NOBORDERS 0x0100
  402. /* No borders will be drawn for the pane.
  403. */
  404. #define SBT_POPOUT 0x0200
  405. /* The text pops out instead of in
  406. */
  407. #define HBT_SPRING 0x0400
  408. /* this means that the item is "springy", meaning that it has a minimum
  409. * width, but will grow if there is extra room in the window. Note that
  410. * multiple springs are allowed, and the extra room will be distributed
  411. * among them.
  412. */
  413. /* Here's a simple dialog function that uses a default status bar to display
  414. * the mouse position in the given window.
  415. *
  416. * extern HINSTANCE hInst;
  417. *
  418. * BOOL CALLBACK MyWndProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
  419. * {
  420. * switch (msg)
  421. * {
  422. * case WM_INITDIALOG:
  423. * CreateStatusWindow(WS_CHILD|WS_BORDER|WS_VISIBLE, "", hDlg,
  424. * IDC_STATUS, hInst);
  425. * break;
  426. *
  427. * case WM_SIZE: //REVIEW: simulating fake WM_SIZE may not be wise
  428. * SendDlgItemMessage(hDlg, IDC_STATUS, WM_SIZE, 0, 0L);
  429. * break;
  430. *
  431. * case WM_MOUSEMOVE:
  432. * wsprintf(szBuf, "%d,%d", LOWORD(lParam), HIWORD(lParam));
  433. * SendDlgItemMessage(hDlg, IDC_STATUS, SB_SETTEXT, 0,
  434. * (LPARAM)(LPSTR)szBuf);
  435. * break;
  436. *
  437. * default:
  438. * break;
  439. * }
  440. * return(FALSE);
  441. * }
  442. */
  443. #endif /* NOSTATUSBAR */
  444. /*/////////////////////////////////////////////////////////////////////////*/
  445. #ifndef NOMENUHELP
  446. /*REVIEW: iMessage should be UINT */
  447. void WINAPI MenuHelp(WORD iMessage, WPARAM wParam, LPARAM lParam,
  448. HMENU hMainMenu, HINSTANCE hInst, HWND hwndStatus, LPWORD lpwIDs);
  449. BOOL WINAPI ShowHideMenuCtl(HWND hWnd, UINT uFlags, LPINT lpInfo);
  450. void WINAPI GetEffectiveClientRect(HWND hWnd, LPRECT lprc, LPINT lpInfo);
  451. /*REVIEW: is this internal? */
  452. #define MINSYSCOMMAND SC_SIZE
  453. #endif /* NOMENUHELP */
  454. /*/////////////////////////////////////////////////////////////////////////*/
  455. #ifndef NOBTNLIST
  456. /*
  457. * BUTTON LISTBOX CONTROL
  458. *
  459. * The Button Listbox control creates an array of buttons that behaves
  460. * similar to both a button and a listbox: the array may be scrollable
  461. * like a listbox and each listbox item is behaves like a pushbutton
  462. * control
  463. *
  464. *
  465. * SPECIFYING A BUTTONLISTBOX IN THE DIALOG TEMPLATE
  466. *
  467. * The CONTROL statement in the dialog template specifies the
  468. * dimensions of each individual button in the x, y, width and height
  469. * parameters. The low order byte in the style field specifies the
  470. * number of buttons that will be displayed; the actual size of the
  471. * displayed control is determined by the number of buttons specified.
  472. *
  473. * For a standard control--no other style bits set--the width of the
  474. * control in dialog base units will be
  475. * CX = cx * (n + 2/3) + 2
  476. * where cx is the width of the button and n is number of buttons
  477. * specified. (The 2/3 is for displaying partially visible buttons for
  478. * scrolling plus 2 for the control borders.) The control will also be
  479. * augmented in the cy direction by the height of the horizontal scroll
  480. * bar.
  481. *
  482. * If the BLS_NOSCROLL style is set, no scroll bar will appear and the
  483. * button listbox will be limited to displaying the number of buttons
  484. * specified and no more. In this case, the width of the control will
  485. * be
  486. * CX = cx * n + 2
  487. *
  488. * If the BLS_VERTICAL style is set, the entire control goes vertical
  489. * and cy should be substituted in the above calculations to determine
  490. * CY, the actual height of the displayed control.
  491. *
  492. * The statement
  493. *
  494. * CONTROL "", IDD_BUTTONLIST, "buttonlistbox", 0x0005 | WS_TABSTOP,
  495. * 4, 128, 34, 24
  496. *
  497. * creates a scrollable horizontal list of 5 buttons at the position
  498. * (4,128) with each button having dimensions (34,24). The entire control
  499. * has the tabstop style.
  500. *
  501. *
  502. * ADDING BUTTONS TO A BUTTONLISTBOX CONTROL
  503. *
  504. * Buttons are added to the listbox in the same manner that items are
  505. * added to a standard listbox; however, the messages BL_ADDBUTTON and
  506. * BL_INSERTBUTTON must be passed a pointer to a CREATELISTBUTTON
  507. * structure in the lParam.
  508. *
  509. * Example:
  510. *
  511. * {
  512. * CREATELISTBUTTON clb;
  513. * const int numColors = 1;
  514. * COLORMAP colorMap;
  515. *
  516. * colorMap.from = BUTTON_MAP_COLOR; // your background color
  517. * colorMap.to = GetSysColor(COLOR_BTNFACE);
  518. *
  519. * clb.cbSize = sizeof(clb);
  520. * clb.dwItemData = BUTTON_1;
  521. * clb.hBitmap = CreateMappedBitmap(hInst,BMP_BUTTON,FALSE,
  522. * &colorMap,numColors);
  523. * clb.lpszText = "Button 1";
  524. * SendMessage(GetDlgItem(hDlg,IDD_BUTTONLIST),
  525. * BL_ADDBUTTON, 0,
  526. * (LPARAM)(CREATELISTBUTTON FAR*)&clb);
  527. * DeleteObject(clb.hBitmap);
  528. * }
  529. *
  530. * Note that the caller must delete any memory for objects passed in
  531. * the CREATELISTBUTTON structure. Also, the CreateMappedBitmap API is
  532. * useful for mapping the background color of the button bitmap to the
  533. * system color COLOR_BTNFACE for a cleaner visual appearance.
  534. *
  535. * The BL_ADDBUTTON message causes the listbox to be sorted by the
  536. * button text whereas the BL_INSERTBUTTON does not cause the list to
  537. * be sorted.
  538. *
  539. * The button listbox sends a WM_DELETEITEM message to the control parent
  540. * when a button is deleted so that any item data can be cleaned up.
  541. *
  542. */
  543. /*REVIEW: should be BUTTONLIST_CLASS */
  544. #define BUTTONLISTBOX "ButtonListBox"
  545. /* Button List Box Styles */
  546. #define BLS_NUMBUTTONS 0x00FF
  547. #define BLS_VERTICAL 0x0100
  548. #define BLS_NOSCROLL 0x0200
  549. /* Button List Box Messages */
  550. #define BL_ADDBUTTON (WM_USER+1)
  551. #define BL_DELETEBUTTON (WM_USER+2)
  552. #define BL_GETCARETINDEX (WM_USER+3)
  553. #define BL_GETCOUNT (WM_USER+4)
  554. #define BL_GETCURSEL (WM_USER+5)
  555. #define BL_GETITEMDATA (WM_USER+6)
  556. #define BL_GETITEMRECT (WM_USER+7)
  557. #define BL_GETTEXT (WM_USER+8)
  558. #define BL_GETTEXTLEN (WM_USER+9)
  559. #define BL_GETTOPINDEX (WM_USER+10)
  560. #define BL_INSERTBUTTON (WM_USER+11)
  561. #define BL_RESETCONTENT (WM_USER+12)
  562. #define BL_SETCARETINDEX (WM_USER+13)
  563. #define BL_SETCURSEL (WM_USER+14)
  564. #define BL_SETITEMDATA (WM_USER+15)
  565. #define BL_SETTOPINDEX (WM_USER+16)
  566. #define BL_MSGMAX (WM_USER+17) /* ;Internal */
  567. /* Button listbox notification codes send in WM_COMMAND */
  568. #define BLN_ERRSPACE (-2)
  569. #define BLN_SELCHANGE 1
  570. #define BLN_CLICKED 2
  571. #define BLN_SELCANCEL 3
  572. #define BLN_SETFOCUS 4
  573. #define BLN_KILLFOCUS 5
  574. /* Message return values */
  575. #define BL_OKAY 0
  576. #define BL_ERR (-1)
  577. #define BL_ERRSPACE (-2)
  578. /* Create structure for
  579. * BL_ADDBUTTON and
  580. * BL_INSERTBUTTON
  581. * lpCLB = (LPCREATELISTBUTTON)lParam
  582. */
  583. typedef struct tagCREATELISTBUTTON
  584. {
  585. UINT cbSize; /* size of structure */
  586. DWORD dwItemData; /* user defined item data */
  587. /* for LB_GETITEMDATA and LB_SETITEMDATA */
  588. HBITMAP hBitmap; /* button bitmap */
  589. LPCSTR lpszText; /* button text */
  590. } CREATELISTBUTTON;
  591. typedef CREATELISTBUTTON FAR* LPCREATELISTBUTTON;
  592. #endif /* NOBTNLIST */
  593. /*/////////////////////////////////////////////////////////////////////////*/
  594. #ifndef NOTRACKBAR
  595. /*
  596. This control keeps its ranges in LONGs. but for
  597. convienence and symetry with scrollbars
  598. WORD parameters are are used for some messages.
  599. if you need a range in LONGs don't use any messages
  600. that pack values into loword/hiword pairs
  601. The trackbar messages:
  602. message wParam lParam return
  603. TBM_GETPOS ------ ------ Current logical position of trackbar.
  604. TBM_GETRANGEMIN ------ ------ Current logical minimum position allowed.
  605. TBM_GETRANGEMAX ------ ------ Current logical maximum position allowed.
  606. TBM_SETTIC
  607. TBM_SETPOS
  608. TBM_SETRANGEMIN
  609. TBM_SETRANGEMAX
  610. */
  611. #define TRACKBAR_CLASS "MCIWndTrackbar"
  612. /* Trackbar styles */
  613. /* add ticks automatically on TBM_SETRANGE message */
  614. #define TBS_AUTOTICKS 0x0001L
  615. /* Trackbar messages */
  616. /* returns current position (LONG) */
  617. #define TBM_GETPOS (WM_USER)
  618. /* set the min of the range to LPARAM */
  619. #define TBM_GETRANGEMIN (WM_USER+1)
  620. /* set the max of the range to LPARAM */
  621. #define TBM_GETRANGEMAX (WM_USER+2)
  622. /* wParam is index of tick to get (ticks are in the range of min - max) */
  623. #define TBM_GETTIC (WM_USER+3)
  624. /* wParam is index of tick to set */
  625. #define TBM_SETTIC (WM_USER+4)
  626. /* set the position to the value of lParam (wParam is the redraw flag) */
  627. #define TBM_SETPOS (WM_USER+5)
  628. /* LOWORD(lParam) = min, HIWORD(lParam) = max, wParam == fRepaint */
  629. #define TBM_SETRANGE (WM_USER+6)
  630. /* lParam is range min (use this to keep LONG precision on range) */
  631. #define TBM_SETRANGEMIN (WM_USER+7)
  632. /* lParam is range max (use this to keep LONG precision on range) */
  633. #define TBM_SETRANGEMAX (WM_USER+8)
  634. /* remove the ticks */
  635. #define TBM_CLEARTICS (WM_USER+9)
  636. /* select a range LOWORD(lParam) min, HIWORD(lParam) max */
  637. #define TBM_SETSEL (WM_USER+10)
  638. /* set selection rang (LONG form) */
  639. #define TBM_SETSELSTART (WM_USER+11)
  640. #define TBM_SETSELEND (WM_USER+12)
  641. // #define TBM_SETTICTOK (WM_USER+13)
  642. /* return a pointer to the list of tics (DWORDS) */
  643. #define TBM_GETPTICS (WM_USER+14)
  644. /* get the pixel position of a given tick */
  645. #define TBM_GETTICPOS (WM_USER+15)
  646. /* get the number of tics */
  647. #define TBM_GETNUMTICS (WM_USER+16)
  648. /* get the selection range */
  649. #define TBM_GETSELSTART (WM_USER+17)
  650. #define TBM_GETSELEND (WM_USER+18)
  651. /* clear the selection */
  652. #define TBM_CLEARSEL (WM_USER+19)
  653. /*REVIEW: these match the SB_ (scroll bar messages); define them that way? */
  654. #define TB_LINEUP 0
  655. #define TB_LINEDOWN 1
  656. #define TB_PAGEUP 2
  657. #define TB_PAGEDOWN 3
  658. #define TB_THUMBPOSITION 4
  659. #define TB_THUMBTRACK 5
  660. #define TB_TOP 6
  661. #define TB_BOTTOM 7
  662. #define TB_ENDTRACK 8
  663. #endif
  664. /*/////////////////////////////////////////////////////////////////////////*/
  665. #ifndef NODRAGLIST
  666. typedef struct
  667. {
  668. UINT uNotification;
  669. HWND hWnd;
  670. POINT ptCursor;
  671. } DRAGLISTINFO, FAR *LPDRAGLISTINFO;
  672. #define DL_BEGINDRAG (LB_MSGMAX+100)
  673. #define DL_DRAGGING (LB_MSGMAX+101)
  674. #define DL_DROPPED (LB_MSGMAX+102)
  675. #define DL_CANCELDRAG (LB_MSGMAX+103)
  676. #define DL_CURSORSET 0
  677. #define DL_STOPCURSOR 1
  678. #define DL_COPYCURSOR 2
  679. #define DL_MOVECURSOR 3
  680. #define DRAGLISTMSGSTRING "commctrl_DragListMsg"
  681. BOOL WINAPI MakeDragList(HWND hLB);
  682. int WINAPI LBItemFromPt(HWND hLB, POINT pt, BOOL bAutoScroll);
  683. void WINAPI DrawInsert(HWND handParent, HWND hLB, int nItem);
  684. #endif /* NODRAGLIST */
  685. /*/////////////////////////////////////////////////////////////////////////*/
  686. #ifndef NOUPDOWN
  687. /*
  688. // OVERVIEW:
  689. //
  690. // The UpDown control is a simple pair of buttons which increment or
  691. // decrement an integer value. The operation is similar to a vertical
  692. // scrollbar; except that the control only has line-up and line-down
  693. // functionality, and changes the current position automatically.
  694. //
  695. // The control also can be linked with a companion control, usually an
  696. // "edit" control, to simplify dialog-box management. This companion is
  697. // termed a "buddy" in this documentation. Any sibling HWND may be
  698. // assigned as the control's buddy, or the control may be allowed to
  699. // choose one automatically. Once chosen, the UpDown can size itself to
  700. // match the buddy's right or left border, and/or automatically set the
  701. // text of the buddy control to make the current position visible.
  702. //
  703. // ADDITIONAL NOTES:
  704. //
  705. // The "upper" and "lower" limits must not cover a range larger than 32,767
  706. // positions. It is acceptable to have the range inverted, i.e., to have
  707. // (lower > upper). The upper button always moves the current position
  708. // towards the "upper" number, and the lower button always moves towards the
  709. // "lower" number. If the range is zero (lower == upper), or the control
  710. // is disabled (EnableWindow(hCtrl, FALSE)), the control draws grayed
  711. // arrows in both buttons. The UDS_WRAP style makes the range cyclic; that
  712. // is, the numbers will wrap once one end of the range is reached.
  713. //
  714. // The buddy window must have the same parent as the UpDown control.
  715. //
  716. // If the buddy window resizes, and the UDS_ALIGN* styles are used, it
  717. // is necessary to send the UDM_SETBUDDY message to re-anchor the UpDown
  718. // control on the appropriate border of the buddy window.
  719. //
  720. // The UDS_AUTOBUDDY style uses GetWindow(hCtrl, GW_HWNDPREV) to pick
  721. // the best buddy window. In the case of a DIALOG resource, this will
  722. // choose the previous control listed in the resource script. If the
  723. // windows will change in Z-order, sending UDM_SETBUDDY with a NULL handle
  724. // will pick a new buddy; otherwise the original auto-buddy choice is
  725. // maintained.
  726. //
  727. // The UDS_SETBUDDYINT style uses its own SetDlgItemInt-style
  728. // functionality to set the caption text of the buddy. All WIN.INI [Intl]
  729. // values are honored by this routine.
  730. //
  731. // The UDS_ARROWKEYS style will subclass the buddy window, in order to steal
  732. // the VK_UP and VK_DOWN arrow key messages.
  733. */
  734. /*/////////////////////////////////////////////////////////////////////////*/
  735. /* Structures */
  736. typedef struct tagUDACCEL
  737. {
  738. UINT nSec;
  739. UINT nInc;
  740. } UDACCEL, FAR *LPUDACCEL;
  741. #define UD_MAXVAL 0x7fff
  742. #define UD_MINVAL (-UD_MAXVAL)
  743. /* STYLE BITS */
  744. #define UDS_WRAP 0x0001
  745. #define UDS_SETBUDDYINT 0x0002
  746. #define UDS_ALIGNRIGHT 0x0004
  747. #define UDS_ALIGNLEFT 0x0008
  748. #define UDS_AUTOBUDDY 0x0010
  749. #define UDS_ARROWKEYS 0x0020
  750. /* MESSAGES */
  751. #define UDM_SETRANGE (WM_USER+101)
  752. /* wParam: not used, 0
  753. // lParam: short LOWORD, new upper; short HIWORD, new lower limit
  754. // return: not used
  755. */
  756. #define UDM_GETRANGE (WM_USER+102)
  757. /* wParam: not used, 0
  758. // lParam: not used, 0
  759. // return: short LOWORD, upper; short HIWORD, lower limit
  760. */
  761. #define UDM_SETPOS (WM_USER+103)
  762. /* wParam: not used, 0
  763. // lParam: short LOWORD, new pos; HIWORD not used, 0
  764. // return: short LOWORD, old pos; HIWORD not used
  765. */
  766. #define UDM_GETPOS (WM_USER+104)
  767. /* wParam: not used, 0
  768. // lParam: not used, 0
  769. // return: short LOWORD, current pos; HIWORD not used
  770. */
  771. #define UDM_SETBUDDY (WM_USER+105)
  772. /* wParam: HWND, new buddy
  773. // lParam: not used, 0
  774. // return: HWND LOWORD, old buddy; HIWORD not used
  775. */
  776. #define UDM_GETBUDDY (WM_USER+106)
  777. /* wParam: not used, 0
  778. // lParam: not used, 0
  779. // return: HWND LOWORD, current buddy; HIWORD not used
  780. */
  781. #define UDM_SETACCEL (WM_USER+107)
  782. /* wParam: UINT, number of acceleration steps
  783. // lParam: LPUDACCEL, pointer to array of UDACCEL elements
  784. // Elements should be sorted in increasing nSec order.
  785. // return: BOOL LOWORD, nonzero if successful; HIWORD not used
  786. */
  787. #define UDM_GETACCEL (WM_USER+108)
  788. /* wParam: UINT, number of elements in the UDACCEL array
  789. // lParam: LPUDACCEL, pointer to UDACCEL buffer to receive array
  790. // return: UINT LOWORD, number of elements returned in buffer
  791. */
  792. #define UDM_SETBASE (WM_USER+109)
  793. /* wParam: UINT, new radix base (10 for decimal, 16 for hex, etc.)
  794. // lParam: not used, 0
  795. // return: not used
  796. */
  797. #define UDM_GETBASE (WM_USER+110)
  798. /* wParam: not used, 0
  799. // lParam: not used, 0
  800. // return: UINT LOWORD, current radix base; HIWORD not used
  801. */
  802. /* NOTIFICATIONS */
  803. /* WM_VSCROLL
  804. // Note that unlike a scrollbar, the position is automatically changed by
  805. // the control, and the LOWORD(lParam) is always the new position. Only
  806. // SB_THUMBTRACK and SB_THUMBPOSITION scroll codes are sent in the wParam.
  807. */
  808. /* HELPER APIs */
  809. #define UPDOWN_CLASS "msctls_updown"
  810. HWND WINAPI CreateUpDownControl(DWORD dwStyle, int x, int y, int cx, int cy,
  811. HWND hParent, int nID, HINSTANCE hInst,
  812. HWND hBuddy,
  813. int nUpper, int nLower, int nPos);
  814. /* Does the CreateWindow call followed by setting the various
  815. // state information:
  816. // hBuddy The companion control (usually an "edit").
  817. // nUpper The range limit corresponding to the upper button.
  818. // nLower The range limit corresponding to the lower button.
  819. // nPos The initial position.
  820. // Returns the handle to the control or NULL on failure.
  821. */
  822. #endif /* NOUPDOWN */
  823. /*/////////////////////////////////////////////////////////////////////////*/
  824. #ifndef NOPROGRESS
  825. /*
  826. // OVERVIEW:
  827. //
  828. // The progress bar control is a "gas gauge" that can be used to show the
  829. // progress of a lengthy operation.
  830. //
  831. // The application sets the range and current position (similar to a
  832. // scrollbar) and has the ability to advance the current position in
  833. // a variety of ways.
  834. //
  835. // Text can be displayed in the progress bar as either a percentage
  836. // of the entire range (using the PBS_SHOWPERCENT style) or as the
  837. // value of the current position (using the PBS_SHOWPOS style). If
  838. // neither bit is set, no text is shown in the bar.
  839. //
  840. // When PBM_STEPIT is used to advance the current position, the gauge
  841. // will wrap when it reaches the end and start again at the start.
  842. // The position is clamped at either end in other cases.
  843. //
  844. */
  845. /*/////////////////////////////////////////////////////////////////////////*/
  846. /* STYLE BITS */
  847. #define PBS_SHOWPERCENT 0x01
  848. #define PBS_SHOWPOS 0x02
  849. /* MESSAGES */
  850. #define PBM_SETRANGE (WM_USER+1)
  851. /* wParam: not used, 0
  852. // lParam: int LOWORD, bottom of range; int HIWORD top of range
  853. // return: int LOWORD, previous bottom; int HIWORD old top
  854. */
  855. #define PBM_SETPOS (WM_USER+2)
  856. /* wParam: int new position
  857. // lParam: not used, 0
  858. // return: int LOWORD, previous position; HIWORD not used
  859. */
  860. #define PBM_DELTAPOS (WM_USER+3)
  861. /* wParam: int amount to advance current position
  862. // lParam: not used, 0
  863. // return: int LOWORD, previous position; HIWORD not used
  864. */
  865. #define PBM_SETSTEP (WM_USER+4)
  866. /* wParam: int new step
  867. // lParam: not used, 0
  868. // return: int LOWORD, previous step; HIWORD not used
  869. */
  870. #define PBM_STEPIT (WM_USER+5)
  871. /* advance current position by current step
  872. // wParam: not used 0
  873. // lParam: not used, 0
  874. // return: int LOWORD, previous position; HIWORD not used
  875. */
  876. #define PROGRESS_CLASS "msctls_progress"
  877. #endif /* NOPROGRESS */
  878. /*/////////////////////////////////////////////////////////////////////////*/
  879. /*REVIEW: move these to their appropriate control sections. */
  880. /* Note that the set of HBN_* and TBN_* defines must be a disjoint set so
  881. * that MenuHelp can tell them apart.
  882. */
  883. /* These are in the HIWORD of lParam in WM_COMMAND messages sent from a
  884. * header bar when the user adjusts the headers with the mouse or keyboard.
  885. */
  886. #define HBN_BEGINDRAG 0x0101
  887. #define HBN_DRAGGING 0x0102
  888. #define HBN_ENDDRAG 0x0103
  889. /* These are in the HIWORD of lParam in WM_COMMAND messages sent from a
  890. * header bar when the user adjusts the headers with the keyboard.
  891. */
  892. #define HBN_BEGINADJUST 0x0111
  893. #define HBN_ENDADJUST 0x0112
  894. /* These are in the HIWORD of lParam in WM_COMMAND messages sent from a
  895. * tool bar. If the left button is pressed and then released in a single
  896. * "button" of a tool bar, then a WM_COMMAND message will be sent with wParam
  897. * being the id of the button.
  898. */
  899. #define TBN_BEGINDRAG 0x0201
  900. #define TBN_ENDDRAG 0x0203
  901. /* These are in the HIWORD of lParam in WM_COMMAND messages sent from a
  902. * tool bar. The TBN_BEGINADJUST message is sent before the "insert"
  903. * dialog appears. The app must return a handle (which will
  904. * NOT be freed by the toolbar) to an ADJUSTINFO struct for the TBN_ADJUSTINFO
  905. * message; the LOWORD of lParam is the index of the button whose info should
  906. * be retrieved. The app can clean up in the TBN_ENDADJUST message.
  907. * The app should reset the toolbar on the TBN_RESET message.
  908. */
  909. #define TBN_BEGINADJUST 0x0204
  910. #define TBN_ADJUSTINFO 0x0205
  911. #define TBN_ENDADJUST 0x0206
  912. #define TBN_RESET 0x0207
  913. /* These are in the HIWORD of lParam in WM_COMMAND messages sent from a
  914. * tool bar. The LOWORD is the index where the button is or will be.
  915. * If the app returns FALSE from either of these during a button move, then
  916. * the button will not be moved. If the app returns FALSE to the INSERT
  917. * when the toolbar tries to add buttons, then the insert dialog will not
  918. * come up. TBN_TOOLBARCHANGE is sent whenever any button is added, moved,
  919. * or deleted from the toolbar by the user, so the app can do stuff.
  920. */
  921. #define TBN_QUERYINSERT 0x0208
  922. #define TBN_QUERYDELETE 0x0209
  923. #define TBN_TOOLBARCHANGE 0x020a
  924. /* This is in the HIWORD of lParam in a WM_COMMAND message. It notifies the
  925. * parent of a toolbar that the HELP button was pressed in the toolbar
  926. * customize dialog. The dialog window handle is in the LOWORD of lParam.
  927. */
  928. #define TBN_CUSTHELP 0x020b
  929. /* Note that the following flags are checked every time the window gets a
  930. * WM_SIZE message, so the style of the window can be changed "on-the-fly".
  931. * If NORESIZE is set, then the app is responsible for all control placement
  932. * and sizing. If NOPARENTALIGN is set, then the app is responsible for
  933. * placement. If neither is set, the app just needs to send a WM_SIZE
  934. * message for the window to be positioned and sized correctly whenever the
  935. * parent window size changes.
  936. * Note that for STATUS bars, CCS_BOTTOM is the default, for HEADER bars,
  937. * CCS_NOMOVEY is the default, and for TOOL bars, CCS_TOP is the default.
  938. */
  939. #define CCS_TOP 0x00000001L
  940. /* This flag means the status bar should be "top" aligned. If the
  941. * NOPARENTALIGN flag is set, then the control keeps the same top, left, and
  942. * width measurements, but the height is adjusted to the default, otherwise
  943. * the status bar is positioned at the top of the parent window such that
  944. * its client area is as wide as the parent window and its client origin is
  945. * the same as its parent.
  946. * Similarly, if this flag is not set, the control is bottom-aligned, either
  947. * with its original rect or its parent rect, depending on the NOPARENTALIGN
  948. * flag.
  949. */
  950. #define CCS_NOMOVEY 0x00000002L
  951. /* This flag means the control may be resized and moved horizontally (if the
  952. * CCS_NORESIZE flag is not set), but it will not move vertically when a
  953. * WM_SIZE message comes through.
  954. */
  955. #define CCS_BOTTOM 0x00000003L
  956. /* Same as CCS_TOP, only on the bottom.
  957. */
  958. #define CCS_NORESIZE 0x00000004L
  959. /* This flag means that the size given when creating or resizing is exact,
  960. * and the control should not resize itself to the default height or width
  961. */
  962. #define CCS_NOPARENTALIGN 0x00000008L
  963. /* This flag means that the control should not "snap" to the top or bottom
  964. * or the parent window, but should keep the same placement it was given
  965. */
  966. #define CCS_NOHILITE 0x00000010L
  967. /* Don't draw the one pixel highlight at the top of the control
  968. */
  969. #define CCS_ADJUSTABLE 0x00000020L
  970. /* This allows a toolbar (header bar?) to be configured by the user.
  971. */
  972. #define CCS_NODIVIDER 0x00000040L
  973. /* Don't draw the 2 pixel highlight at top of control (toolbar)
  974. */
  975. /*/////////////////////////////////////////////////////////////////////////*/
  976. #ifdef __cplusplus
  977. } /* end of 'extern "C" {' */
  978. #endif
  979. #endif /* _INC_COMMCTRL */