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.

451 lines
9.9 KiB

  1. /*************************************************************************
  2. **
  3. ** OLE 2 Sample Code
  4. **
  5. ** heading.c
  6. **
  7. ** This file contains functions and support for OutlineDoc's row and
  8. ** column headings.
  9. **
  10. ** (c) Copyright Microsoft Corp. 1992 - 1993 All Rights Reserved
  11. **
  12. *************************************************************************/
  13. #include "outline.h"
  14. extern LPOUTLINEAPP g_lpApp;
  15. BOOL Heading_Create(LPHEADING lphead, HWND hWndParent, HINSTANCE hInst)
  16. {
  17. HDC hDC;
  18. TEXTMETRIC tm;
  19. if (!lphead || !hWndParent || !hInst)
  20. return FALSE;
  21. hDC = GetDC(hWndParent);
  22. if (!hDC)
  23. return FALSE;
  24. if (!GetTextMetrics(hDC, (TEXTMETRIC FAR*)&tm))
  25. return FALSE;
  26. lphead->m_colhead.m_uHeight = tm.tmHeight;
  27. lphead->m_rowhead.m_uWidth = 4 * tm.tmAveCharWidth;
  28. lphead->m_fShow = TRUE;
  29. ReleaseDC(hWndParent, hDC);
  30. lphead->m_hfont = CreateFont(
  31. tm.tmHeight,
  32. 0,0,0,0,0,0,0,0,
  33. OUT_TT_PRECIS, // use TrueType
  34. CLIP_DEFAULT_PRECIS,
  35. DEFAULT_QUALITY,
  36. DEFAULT_PITCH | FF_DONTCARE,
  37. HEADING_FONT
  38. );
  39. if (!lphead->m_hfont)
  40. return FALSE;
  41. lphead->m_colhead.m_hWnd = CreateWindow(
  42. "listbox",
  43. "Column Heading",
  44. WS_VISIBLE | WS_CHILD | WS_DISABLED | LBS_OWNERDRAWVARIABLE |
  45. LBS_NOINTEGRALHEIGHT,
  46. 0,0,0,0, // any values
  47. hWndParent,
  48. (HMENU)IDC_COLHEADING,
  49. hInst,
  50. NULL);
  51. if (!lphead->m_colhead.m_hWnd)
  52. return FALSE;
  53. // add a dummy line to get WM_DRAWITEM message
  54. SendMessage(lphead->m_colhead.m_hWnd, LB_ADDSTRING, 0,
  55. MAKELPARAM(lphead->m_colhead.m_uHeight,0));
  56. lphead->m_rowhead.m_hWnd = CreateWindow(
  57. "listbox",
  58. "Row Heading",
  59. WS_VISIBLE | WS_CHILD | WS_DISABLED | LBS_OWNERDRAWVARIABLE,
  60. 0,0,0,0, // any values
  61. hWndParent,
  62. (HMENU)IDC_ROWHEADING,
  63. hInst,
  64. NULL);
  65. if (!lphead->m_rowhead.m_hWnd)
  66. return FALSE;
  67. SendMessage(lphead->m_rowhead.m_hWnd, LB_ADDSTRING, 0,
  68. MAKELPARAM(lphead->m_colhead.m_uHeight,0));
  69. lphead->m_rowhead.m_WndProc =
  70. (FARPROC) GetWindowLongPtr(lphead->m_rowhead.m_hWnd, GWLP_WNDPROC );
  71. SetWindowLongPtr(lphead->m_rowhead.m_hWnd, GWLP_WNDPROC,
  72. (LONG_PTR) RowHeadWndProc);
  73. lphead->m_hwndButton = CreateWindow(
  74. "button",
  75. NULL,
  76. WS_VISIBLE | WS_CHILD,
  77. 0,0,0,0, // any values
  78. hWndParent,
  79. (HMENU)IDC_BUTTON,
  80. hInst,
  81. NULL);
  82. if (!lphead->m_hwndButton)
  83. return FALSE;
  84. return TRUE;
  85. }
  86. void Heading_Destroy(LPHEADING lphead)
  87. {
  88. if (!lphead)
  89. return;
  90. if (IsWindow(lphead->m_colhead.m_hWnd)) {
  91. DestroyWindow(lphead->m_colhead.m_hWnd);
  92. lphead->m_colhead.m_hWnd = NULL;
  93. }
  94. if (IsWindow(lphead->m_rowhead.m_hWnd)) {
  95. DestroyWindow(lphead->m_rowhead.m_hWnd);
  96. lphead->m_rowhead.m_hWnd = NULL;
  97. }
  98. if (IsWindow(lphead->m_hwndButton)) {
  99. DestroyWindow(lphead->m_hwndButton);
  100. lphead->m_hwndButton = NULL;
  101. }
  102. #ifdef WIN32
  103. if (GetObjectType(lphead->m_hfont)) {
  104. #else
  105. if (IsGDIObject(lphead->m_hfont)) {
  106. #endif
  107. DeleteObject(lphead->m_hfont);
  108. lphead->m_hfont = NULL;
  109. }
  110. }
  111. void Heading_Move(LPHEADING lphead, HWND hwndDoc, LPSCALEFACTOR lpscale)
  112. {
  113. int nOffsetX;
  114. int nOffsetY;
  115. RECT rcDoc;
  116. if (!lphead || !hwndDoc || !lpscale)
  117. return;
  118. if (!lphead->m_fShow)
  119. return;
  120. nOffsetX = (int) Heading_RH_GetWidth(lphead, lpscale);
  121. nOffsetY = (int) Heading_CH_GetHeight(lphead, lpscale);
  122. GetClientRect(hwndDoc, (LPRECT)&rcDoc);
  123. MoveWindow(lphead->m_hwndButton, 0, 0, nOffsetX, nOffsetY, TRUE);
  124. MoveWindow(
  125. lphead->m_colhead.m_hWnd,
  126. nOffsetX, 0,
  127. rcDoc.right-rcDoc.left-nOffsetX, nOffsetY,
  128. TRUE
  129. );
  130. MoveWindow(lphead->m_rowhead.m_hWnd, 0, nOffsetY, nOffsetX,
  131. rcDoc.bottom-rcDoc.top-nOffsetY, TRUE);
  132. }
  133. void Heading_Show(LPHEADING lphead, BOOL fShow)
  134. {
  135. int nCmdShow;
  136. if (!lphead)
  137. return;
  138. lphead->m_fShow = fShow;
  139. nCmdShow = fShow ? SW_SHOW : SW_HIDE;
  140. ShowWindow(lphead->m_hwndButton, nCmdShow);
  141. ShowWindow(lphead->m_colhead.m_hWnd, nCmdShow);
  142. ShowWindow(lphead->m_rowhead.m_hWnd, nCmdShow);
  143. }
  144. void Heading_ReScale(LPHEADING lphead, LPSCALEFACTOR lpscale)
  145. {
  146. UINT uHeight;
  147. if (!lphead || !lpscale)
  148. return;
  149. // Row heading is scaled with the LineList_Rescale. So, only
  150. // Column heading needed to be scaled here.
  151. uHeight = (UINT)(lphead->m_colhead.m_uHeight * lpscale->dwSyN /
  152. lpscale->dwSyD);
  153. SendMessage(lphead->m_colhead.m_hWnd, LB_SETITEMHEIGHT, 0,
  154. MAKELPARAM(uHeight, 0));
  155. }
  156. void Heading_CH_Draw(LPHEADING lphead, LPDRAWITEMSTRUCT lpdis, LPRECT lprcScreen, LPRECT lprcObject)
  157. {
  158. HPEN hpenOld;
  159. HPEN hpen;
  160. HBRUSH hbr;
  161. HFONT hfOld;
  162. int nTabInPix;
  163. char letter;
  164. int i;
  165. int nOldMapMode;
  166. RECT rcWindowOld;
  167. RECT rcViewportOld;
  168. POINT point;
  169. if (!lpdis || !lphead)
  170. return;
  171. hbr = GetStockObject(LTGRAY_BRUSH);
  172. FillRect(lpdis->hDC, (LPRECT)&lpdis->rcItem, hbr);
  173. nOldMapMode = SetDCToAnisotropic(lpdis->hDC, lprcScreen, lprcObject,
  174. (LPRECT)&rcWindowOld, (LPRECT)&rcViewportOld);
  175. hfOld = SelectObject(lpdis->hDC, lphead->m_hfont);
  176. hpen = GetStockObject(BLACK_PEN);
  177. hpenOld = SelectObject(lpdis->hDC, hpen);
  178. nTabInPix = XformWidthInHimetricToPixels(lpdis->hDC, TABWIDTH);
  179. SetBkMode(lpdis->hDC, TRANSPARENT);
  180. letter = COLUMN_LETTER;
  181. MoveToEx(lpdis->hDC, lprcObject->left, lprcObject->bottom,&point);
  182. LineTo(lpdis->hDC, lprcObject->left, lprcObject->top);
  183. for (i = 0; i < COLUMN; i++) {
  184. lprcObject->right = lprcObject->left + nTabInPix;
  185. DrawText(lpdis->hDC, (LPCSTR)&letter, 1, lprcObject,
  186. DT_SINGLELINE | DT_CENTER | DT_VCENTER);
  187. MoveToEx(lpdis->hDC, lprcObject->right, lprcObject->bottom, &point);
  188. LineTo(lpdis->hDC, lprcObject->right, lprcObject->top);
  189. letter++;
  190. lprcObject->left += nTabInPix;
  191. }
  192. SelectObject(lpdis->hDC, hpenOld);
  193. SelectObject(lpdis->hDC, hfOld);
  194. ResetOrigDC(lpdis->hDC, nOldMapMode, (LPRECT)&rcWindowOld,
  195. (LPRECT)&rcViewportOld);
  196. }
  197. void Heading_CH_SetHorizontalExtent(LPHEADING lphead, HWND hwndListBox)
  198. {
  199. RECT rcLL;
  200. RECT rcCH;
  201. int nLLWidth;
  202. int nCHWidth;
  203. int nHorizExtent;
  204. if (!lphead || !hwndListBox)
  205. return;
  206. nHorizExtent=(int)SendMessage(hwndListBox, LB_GETHORIZONTALEXTENT, 0, 0L);
  207. GetClientRect(hwndListBox, (LPRECT)&rcLL);
  208. GetClientRect(lphead->m_colhead.m_hWnd, (LPRECT)&rcCH);
  209. nLLWidth = rcLL.right - rcLL.left;
  210. nCHWidth = rcCH.right - rcCH.left;
  211. nHorizExtent += nCHWidth - nLLWidth;
  212. SendMessage(lphead->m_colhead.m_hWnd, LB_SETHORIZONTALEXTENT,
  213. nHorizExtent, 0L);
  214. }
  215. UINT Heading_CH_GetHeight(LPHEADING lphead, LPSCALEFACTOR lpscale)
  216. {
  217. if (!lphead || !lpscale)
  218. return 0;
  219. if (lphead->m_fShow)
  220. return (UINT)(lphead->m_colhead.m_uHeight * lpscale->dwSyN /
  221. lpscale->dwSyD);
  222. else
  223. return 0;
  224. }
  225. LRESULT Heading_CH_SendMessage(LPHEADING lphead, UINT msg, WPARAM wParam, LPARAM lParam)
  226. {
  227. if (!lphead)
  228. return 0;
  229. if (lphead->m_colhead.m_hWnd)
  230. return SendMessage(lphead->m_colhead.m_hWnd, msg, wParam, lParam);
  231. }
  232. void Heading_CH_ForceRedraw(LPHEADING lphead, BOOL fErase)
  233. {
  234. if (!lphead)
  235. return;
  236. InvalidateRect(lphead->m_colhead.m_hWnd, NULL, fErase);
  237. }
  238. void Heading_RH_ForceRedraw(LPHEADING lphead, BOOL fErase)
  239. {
  240. if (!lphead)
  241. return;
  242. InvalidateRect(lphead->m_rowhead.m_hWnd, NULL, fErase);
  243. }
  244. void Heading_RH_Draw(LPHEADING lphead, LPDRAWITEMSTRUCT lpdis)
  245. {
  246. char cBuf[5];
  247. HPEN hpenOld;
  248. HPEN hpen;
  249. HBRUSH hbrOld;
  250. HBRUSH hbr;
  251. HFONT hfOld;
  252. RECT rc;
  253. RECT rcWindowOld;
  254. RECT rcViewportOld;
  255. int nMapModeOld;
  256. if (!lpdis || !lphead)
  257. return;
  258. lpdis->rcItem;
  259. rc.left = 0;
  260. rc.bottom = 0;
  261. rc.top = (int)lpdis->itemData;
  262. rc.right = lphead->m_rowhead.m_uWidth;
  263. nMapModeOld = SetDCToAnisotropic(lpdis->hDC, &lpdis->rcItem, &rc,
  264. (LPRECT)&rcWindowOld, (LPRECT)&rcViewportOld);
  265. hpen = GetStockObject(BLACK_PEN);
  266. hpenOld = SelectObject(lpdis->hDC, hpen);
  267. hbr = GetStockObject(LTGRAY_BRUSH);
  268. hbrOld = SelectObject(lpdis->hDC, hbr);
  269. Rectangle(lpdis->hDC, rc.left, rc.top, rc.right,
  270. rc.bottom);
  271. hfOld = SelectObject(lpdis->hDC, lphead->m_hfont);
  272. SetBkMode(lpdis->hDC, TRANSPARENT);
  273. wsprintf(cBuf, "%d", lpdis->itemID + 1);
  274. DrawText(lpdis->hDC, (LPSTR)cBuf, lstrlen(cBuf), (LPRECT)&rc,
  275. DT_SINGLELINE | DT_CENTER | DT_VCENTER);
  276. SelectObject(lpdis->hDC, hfOld);
  277. SelectObject(lpdis->hDC, hpenOld);
  278. SelectObject(lpdis->hDC, hbrOld);
  279. ResetOrigDC(lpdis->hDC, nMapModeOld, (LPRECT)&rcWindowOld,
  280. (LPRECT)&rcViewportOld);
  281. }
  282. LRESULT Heading_RH_SendMessage(LPHEADING lphead, UINT msg, WPARAM wParam, LPARAM lParam)
  283. {
  284. if (!lphead)
  285. return 0;
  286. if (lphead->m_rowhead.m_hWnd)
  287. return SendMessage(lphead->m_rowhead.m_hWnd, msg, wParam, lParam);
  288. }
  289. UINT Heading_RH_GetWidth(LPHEADING lphead, LPSCALEFACTOR lpscale)
  290. {
  291. if (!lphead || !lpscale)
  292. return 0;
  293. if (lphead->m_fShow)
  294. return (UINT)(lphead->m_rowhead.m_uWidth * lpscale->dwSxN /
  295. lpscale->dwSxD);
  296. else
  297. return 0;
  298. }
  299. void Heading_RH_Scroll(LPHEADING lphead, HWND hwndListBox)
  300. {
  301. int nTopLL;
  302. int nTopRH;
  303. if (!lphead || !hwndListBox)
  304. return;
  305. nTopLL = (int)SendMessage(hwndListBox, LB_GETTOPINDEX, 0, 0L);
  306. nTopRH = (int)SendMessage(
  307. lphead->m_rowhead.m_hWnd, LB_GETTOPINDEX, 0, 0L);
  308. if (nTopLL != nTopRH)
  309. SendMessage(
  310. lphead->m_rowhead.m_hWnd,LB_SETTOPINDEX,(WPARAM)nTopLL,0L);
  311. }
  312. LRESULT FAR PASCAL RowHeadWndProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam)
  313. {
  314. HWND hwndParent = GetParent (hWnd);
  315. LPOUTLINEDOC lpDoc = (LPOUTLINEDOC)GetWindowLongPtr(hwndParent, 0);
  316. LPHEADING lphead = OutlineDoc_GetHeading(lpDoc);
  317. switch (Message) {
  318. case WM_PAINT:
  319. {
  320. LPLINELIST lpLL = OutlineDoc_GetLineList(lpDoc);
  321. PAINTSTRUCT ps;
  322. // If there is no line in listbox, trap the message and draw the
  323. // background gray. Without this, the background will be painted
  324. // as default color.
  325. if (!LineList_GetCount(lpLL)) {
  326. BeginPaint(hWnd, &ps);
  327. EndPaint(hWnd, &ps);
  328. return 0;
  329. }
  330. break;
  331. }
  332. case WM_ERASEBKGND:
  333. {
  334. HDC hDC = (HDC)wParam;
  335. RECT rc;
  336. GetClientRect(hWnd, (LPRECT)&rc);
  337. FillRect(hDC, (LPRECT)&rc, GetStockObject(GRAY_BRUSH));
  338. return 1;
  339. }
  340. }
  341. return CallWindowProc(
  342. (WNDPROC)lphead->m_rowhead.m_WndProc,
  343. hWnd,
  344. Message,
  345. wParam,
  346. lParam
  347. );
  348. }