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.

468 lines
11 KiB

  1. /*****************************************************************************
  2. *
  3. * Component: sndvol32.exe
  4. * File: dlg.c
  5. * Purpose: dialog template aggregator
  6. *
  7. * Copyright (c) 1985-1998 Microsoft Corporation
  8. *
  9. *****************************************************************************/
  10. #include <windows.h>
  11. #include <windowsx.h>
  12. #include <string.h>
  13. #include "dlg.h"
  14. #include <winuserp.h>
  15. /*
  16. * DlgLoadResource
  17. *
  18. * */
  19. HGLOBAL Dlg_LoadResource(
  20. HINSTANCE hModule,
  21. LPCTSTR lpszName,
  22. DWORD *pcbSize)
  23. {
  24. HRSRC hrsrc;
  25. HGLOBAL hres;
  26. HGLOBAL hlock;
  27. hrsrc = FindResource(hModule, lpszName, RT_DIALOG);
  28. if (!hrsrc)
  29. return NULL;
  30. hres = LoadResource(hModule, hrsrc);
  31. if (!hres)
  32. return NULL;
  33. hlock = LockResource(hres);
  34. if (pcbSize)
  35. {
  36. if (hlock)
  37. *pcbSize = SizeofResource(hModule, hrsrc);
  38. else
  39. *pcbSize = 0L;
  40. }
  41. return hlock;
  42. }
  43. /*
  44. * DlgHorizAttach
  45. * - Attaches a dialog template horizontally to another dialog
  46. * - if lpMain == NULL allocs a new dialog copy.
  47. *
  48. * */
  49. LPBYTE Dlg_HorizAttach(
  50. LPBYTE lpMain,
  51. DWORD cbMain,
  52. LPBYTE lpAdd,
  53. DWORD cbAdd,
  54. WORD wIdOffset,
  55. DWORD *pcbNew)
  56. {
  57. LPBYTE lpDst;
  58. LPBYTE lpDstOffset;
  59. LPBYTE lpSrcOffset;
  60. DWORD cbDst;
  61. DWORD cbOffset = 0L, cbAddOffset;
  62. int idit;
  63. BOOL bDialogEx;
  64. int iditCount;
  65. DLGTEMPLATE * lpdtDst;
  66. DLGTEMPLATE * lpdtAdd;
  67. DLGTEMPLATE2 * lpdtDst2;
  68. DLGTEMPLATE2 * lpdtAdd2;
  69. if (lpMain)
  70. {
  71. cbDst = cbMain + cbAdd;
  72. lpDst = GlobalReAllocPtr(lpMain, cbDst, GHND);
  73. }
  74. else
  75. {
  76. // no dialog to append to, so just make a copy
  77. lpDst = Dlg_HorizDupe(lpAdd, cbAdd, 1, &cbDst);
  78. if (!lpDst)
  79. {
  80. if (pcbNew)
  81. *pcbNew = 0L;
  82. return NULL;
  83. }
  84. *pcbNew = cbDst;
  85. return lpDst;
  86. }
  87. if (!lpDst)
  88. {
  89. if (pcbNew)
  90. *pcbNew = 0L;
  91. return NULL;
  92. }
  93. // advance to end of dlgitemtemplates already there
  94. if(((DLGTEMPLATE2 *)lpDst)->wSignature == 0xffff)
  95. {
  96. //
  97. // We assume lpdtDst and lpdtAdd are both the same type of
  98. // template, either DIALOG or DIALOGEX
  99. //
  100. lpdtDst2 = (DLGTEMPLATE2 *)lpDst;
  101. iditCount = lpdtDst2->cDlgItems;
  102. bDialogEx = TRUE;
  103. }
  104. else
  105. {
  106. lpdtDst = (DLGTEMPLATE *)lpDst;
  107. iditCount = lpdtDst->cdit;
  108. bDialogEx = FALSE;
  109. }
  110. cbOffset = Dlg_CopyDLGTEMPLATE(NULL, lpDst, bDialogEx);
  111. for (idit = 0; idit < iditCount; idit++)
  112. {
  113. DWORD cbDIT;
  114. lpDstOffset = lpDst + cbOffset;
  115. cbDIT = Dlg_CopyDLGITEMTEMPLATE(NULL
  116. , lpDstOffset
  117. , (WORD)0
  118. , (short)0
  119. , (short)0
  120. , bDialogEx);
  121. cbOffset += cbDIT;
  122. }
  123. // advance to the start of the dlgitemtemplates to add
  124. if (bDialogEx)
  125. {
  126. lpdtAdd2 = (DLGTEMPLATE2 *)lpAdd;
  127. iditCount = lpdtAdd2->cDlgItems;
  128. }
  129. else
  130. {
  131. lpdtAdd = (DLGTEMPLATE *)lpAdd;
  132. iditCount = lpdtAdd->cdit;
  133. }
  134. cbAddOffset = Dlg_CopyDLGTEMPLATE(NULL, lpAdd, bDialogEx);
  135. // add the new dialog templates
  136. for (idit = 0; idit < iditCount; idit++)
  137. {
  138. DWORD cbDIT;
  139. short cx = bDialogEx ? lpdtDst2->cx : lpdtDst->cx;
  140. lpDstOffset = lpDst + cbOffset;
  141. lpSrcOffset = lpAdd + cbAddOffset;
  142. cbDIT = Dlg_CopyDLGITEMTEMPLATE(lpDstOffset
  143. , lpSrcOffset
  144. , (WORD)wIdOffset
  145. , cx
  146. , (short)0
  147. , bDialogEx);
  148. cbOffset += cbDIT;
  149. cbAddOffset += cbDIT;
  150. }
  151. if (bDialogEx)
  152. {
  153. lpdtDst2->cDlgItems += lpdtAdd2->cDlgItems;
  154. lpdtDst2->cx += lpdtAdd2->cx;
  155. lpdtDst2->cy = max(lpdtAdd2->cy, lpdtDst2->cy);
  156. }
  157. else
  158. {
  159. lpdtDst->cdit += lpdtAdd->cdit;
  160. lpdtDst->cx += lpdtAdd->cx;
  161. lpdtDst->cy = max(lpdtAdd->cy, lpdtDst->cy);
  162. }
  163. if (pcbNew)
  164. *pcbNew = cbOffset;
  165. return lpDst;
  166. }
  167. /*
  168. * Dlg_HorizSize
  169. *
  170. * Returns width of dialog box in dlu's.
  171. *
  172. * */
  173. DWORD Dlg_HorizSize(
  174. LPBYTE lpDlg)
  175. {
  176. if(((DLGTEMPLATE2 *)lpDlg)->wSignature == 0xffff)
  177. {
  178. return (((DLGTEMPLATE2 *)lpDlg)->cx - 2); // Compensate for right side trimming
  179. }
  180. else
  181. {
  182. return (((DLGTEMPLATE *)lpDlg)->cx - 2); // Compensate for right side trimming
  183. }
  184. }
  185. /*
  186. * DlgHorizDupe
  187. *
  188. * */
  189. LPBYTE Dlg_HorizDupe(
  190. LPBYTE lpSrc,
  191. DWORD cbSrc,
  192. int cDups,
  193. DWORD *pcbNew)
  194. {
  195. int idit;
  196. int iDup;
  197. DWORD cbOffset;
  198. DWORD cbDTOffset;
  199. DWORD cbDT0Offset;
  200. LPBYTE lpDst;
  201. DLGTEMPLATE * lpdt;
  202. DLGTEMPLATE2 * lpdt2;
  203. LPBYTE lpDstOffset;
  204. LPBYTE lpSrcOffset;
  205. DWORD cbSize;
  206. int iCount;
  207. BOOL bDialogEx;
  208. cbSize = cDups * cbSrc;
  209. //DWORD align
  210. cbSize = (cbSize + 3)&~3;
  211. lpDst = GlobalAllocPtr(GHND, cbSize);
  212. if (!lpDst)
  213. return NULL;
  214. if(((DLGTEMPLATE2 *)lpSrc)->wSignature == 0xffff)
  215. {
  216. lpdt2 = (DLGTEMPLATE2 *)lpDst;
  217. iCount = ((DLGTEMPLATE2 *)lpSrc)->cDlgItems;
  218. bDialogEx = TRUE;
  219. }
  220. else
  221. {
  222. lpdt = (DLGTEMPLATE *)lpDst;
  223. iCount = ((DLGTEMPLATE *)lpSrc)->cdit;
  224. bDialogEx = FALSE;
  225. }
  226. cbDT0Offset = cbDTOffset = cbOffset = Dlg_CopyDLGTEMPLATE(lpDst,lpSrc, bDialogEx);
  227. for (iDup = 0; iDup < cDups; iDup++)
  228. {
  229. // reset the DTOffset to the first DIT
  230. cbDTOffset = cbDT0Offset;
  231. for (idit = 0; idit < iCount; idit++)
  232. {
  233. DWORD cbDIT;
  234. short cx = bDialogEx ? lpdt2->cx : lpdt->cx;
  235. lpDstOffset = lpDst + cbOffset;
  236. lpSrcOffset = lpSrc + cbDTOffset;
  237. cbDIT = Dlg_CopyDLGITEMTEMPLATE(lpDstOffset
  238. , lpSrcOffset
  239. , (WORD)(iDup * IDOFFSET) // all id increments are by IDOFFSET
  240. , (short)(iDup * cx)
  241. , (short)0 // no y increments
  242. , bDialogEx);
  243. cbOffset += cbDIT;
  244. cbDTOffset += cbDIT;
  245. }
  246. }
  247. // adjust template width and number of items
  248. if (bDialogEx)
  249. {
  250. lpdt2->cDlgItems *= (WORD)cDups;
  251. lpdt2->cx *= (short)cDups;
  252. }
  253. else
  254. {
  255. lpdt->cdit *= (WORD)cDups;
  256. lpdt->cx *= (short)cDups;
  257. }
  258. if (pcbNew)
  259. *pcbNew = cbOffset;
  260. return lpDst;
  261. }
  262. /*
  263. * DlgCopyDLGITEMTEMPLATE
  264. *
  265. * if lpDst == NULL only returns offset into lpSrc of next dlgitemtemplate
  266. * */
  267. DWORD Dlg_CopyDLGITEMTEMPLATE(
  268. LPBYTE lpDst,
  269. LPBYTE lpSrc,
  270. WORD wIdOffset,
  271. short xOffset,
  272. short yOffset,
  273. BOOL bDialogEx)
  274. {
  275. LPBYTE lpOffset;
  276. DWORD cbDlg=bDialogEx ? sizeof(DLGITEMTEMPLATE2):sizeof(DLGITEMTEMPLATE);
  277. DLGITEMTEMPLATE * lpdit;
  278. DLGITEMTEMPLATE2 * lpdit2;
  279. if (bDialogEx)
  280. {
  281. lpdit2= (DLGITEMTEMPLATE2 *)lpDst;
  282. }
  283. else
  284. {
  285. lpdit = (DLGITEMTEMPLATE *)lpDst;
  286. }
  287. // Control class
  288. lpOffset = lpSrc + cbDlg;
  289. if (*(LPWORD)lpOffset == 0xFFFF)
  290. {
  291. cbDlg += 2*sizeof(WORD);
  292. }
  293. else
  294. {
  295. cbDlg += (wcslen((LPWSTR)lpOffset) + 1) * sizeof(WCHAR);
  296. }
  297. lpOffset = lpSrc + cbDlg;
  298. if (*(LPWORD)lpOffset == 0xFFFF)
  299. {
  300. cbDlg += 2*sizeof(WORD);
  301. }
  302. else
  303. {
  304. cbDlg += (wcslen((LPWSTR)lpOffset) + 1) * sizeof(WCHAR);
  305. }
  306. cbDlg += sizeof(WORD);
  307. // DWORD align.
  308. cbDlg = (cbDlg + 3)&~3;
  309. if (lpDst)
  310. {
  311. CopyMemory(lpDst, lpSrc, cbDlg);
  312. if (bDialogEx)
  313. {
  314. lpdit2->x += xOffset;
  315. lpdit2->y += yOffset;
  316. // id offset only if the control isn't static
  317. if (lpdit2->dwID != -1)
  318. lpdit2->dwID += wIdOffset;
  319. }
  320. else
  321. {
  322. lpdit->x += xOffset;
  323. lpdit->y += yOffset;
  324. // id offset only if the control isn't static
  325. if (lpdit->id != -1)
  326. lpdit->id += wIdOffset;
  327. }
  328. }
  329. return cbDlg;
  330. }
  331. /*
  332. * DlgCopyDLGTEMPLATE
  333. *
  334. * if lpDst == NULL only returns offset into lpSrc to first dlgitemtemplate
  335. *
  336. * */
  337. DWORD Dlg_CopyDLGTEMPLATE(
  338. LPBYTE lpDst,
  339. LPBYTE lpSrc,
  340. BOOL bDialogEx)
  341. {
  342. LPBYTE lpOffset;
  343. UINT uiStyle;
  344. DWORD cbDlg = bDialogEx ? sizeof(DLGTEMPLATE2) : sizeof(DLGTEMPLATE);
  345. // Menu description
  346. lpOffset = lpSrc + cbDlg;
  347. if (*(LPWORD)lpOffset == 0xFFFF)
  348. {
  349. cbDlg += 2*sizeof(WORD);
  350. }
  351. else if (*(LPWORD)lpOffset == 0x0000)
  352. {
  353. cbDlg += sizeof(WORD);
  354. }
  355. else
  356. {
  357. cbDlg += (wcslen((LPWSTR)lpOffset) + 1)*sizeof(WCHAR);
  358. }
  359. // Window class
  360. lpOffset = lpSrc + cbDlg;
  361. if (*(LPWORD)lpOffset == 0xFFFF)
  362. {
  363. cbDlg += 2*sizeof(WORD);
  364. }
  365. else if (*(LPWORD)lpOffset == 0x0000)
  366. {
  367. cbDlg += sizeof(WORD);
  368. }
  369. else
  370. {
  371. cbDlg += (wcslen((LPWSTR)lpOffset) + 1) * sizeof(WCHAR);
  372. }
  373. // Title
  374. lpOffset = lpSrc + cbDlg;
  375. cbDlg += (wcslen((LPWSTR)lpOffset) + 1) * sizeof(WCHAR);
  376. // Font
  377. if (bDialogEx)
  378. {
  379. uiStyle = ((DLGTEMPLATE2 * )lpSrc)->style;
  380. }
  381. else
  382. {
  383. uiStyle = ((DLGTEMPLATE * )lpSrc)->style;
  384. }
  385. if (uiStyle & DS_SETFONT)
  386. {
  387. cbDlg += sizeof(WORD);
  388. if (bDialogEx)
  389. {
  390. cbDlg += sizeof(WORD);
  391. cbDlg += sizeof(BYTE);
  392. cbDlg += sizeof(BYTE);
  393. }
  394. lpOffset = lpSrc + cbDlg;
  395. cbDlg += (wcslen((LPWSTR)lpOffset) + 1) *sizeof(WCHAR);
  396. }
  397. // DWORD align
  398. cbDlg = (cbDlg + 3)&~3;
  399. // copy the dlgtemplate into the destination.
  400. if (lpDst)
  401. CopyMemory(lpDst, lpSrc, cbDlg);
  402. return cbDlg;
  403. }