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.

538 lines
14 KiB

  1. //
  2. // dlgbase.cpp: base class for dialogs
  3. //
  4. #include "stdafx.h"
  5. #include "dlgbase.h"
  6. #include "atlwarn.h"
  7. BEGIN_EXTERN_C
  8. #define TRC_GROUP TRC_GROUP_UI
  9. #define TRC_FILE "dlgbase"
  10. #include <atrcapi.h>
  11. END_EXTERN_C
  12. #define DLG_WND_CLASSNAME _T("axtscdlg")
  13. #ifndef OS_WINCE //CE_FIXNOTE: Needs to be ported to CE
  14. CDlgBase::CDlgBase(HWND hwndOwner, HINSTANCE hInst, INT dlgResId) :
  15. _hwndOwner(hwndOwner), _hInstance(hInst), _dlgResId(dlgResId)
  16. {
  17. _hwndDlg = NULL;
  18. _startupLeft = _startupTop = 0;
  19. }
  20. CDlgBase::~CDlgBase()
  21. {
  22. }
  23. //
  24. // Name: DialogBoxProc
  25. //
  26. // Purpose: Provides message handling for basic operation
  27. //
  28. // Returns: TRUE - if message dealt with
  29. // FALSE otherwise
  30. //
  31. // Params: See windows documentation
  32. //
  33. //
  34. INT_PTR CALLBACK CDlgBase::DialogBoxProc(HWND hwndDlg,
  35. UINT uMsg,
  36. WPARAM wParam,
  37. LPARAM lParam)
  38. {
  39. INT_PTR rc = FALSE;
  40. DC_BEGIN_FN("DialogBoxProc");
  41. DC_IGNORE_PARAMETER(lParam);
  42. //
  43. // Handle dialog messages
  44. //
  45. switch(uMsg)
  46. {
  47. case WM_INITDIALOG:
  48. {
  49. SetDialogAppIcon(hwndDlg);
  50. rc = TRUE;
  51. }
  52. break;
  53. case WM_COMMAND:
  54. {
  55. switch(DC_GET_WM_COMMAND_ID(wParam))
  56. {
  57. case IDCANCEL:
  58. {
  59. //
  60. // Closes the dialog
  61. //
  62. TRC_NRM((TB, _T("Close dialog")));
  63. if(hwndDlg)
  64. {
  65. EndDialog(hwndDlg, IDCANCEL);
  66. }
  67. rc = TRUE;
  68. }
  69. break;
  70. default:
  71. {
  72. //
  73. // Do Nothing
  74. //
  75. }
  76. break;
  77. }
  78. }
  79. break;
  80. case WM_CLOSE:
  81. {
  82. //
  83. // Closes the dialog
  84. //
  85. TRC_NRM((TB, _T("Close dialog")));
  86. if(IsWindow(hwndDlg))
  87. {
  88. EndDialog(hwndDlg, IDCANCEL);
  89. }
  90. rc = 0;
  91. }
  92. break;
  93. default:
  94. {
  95. //
  96. // Do Nothing
  97. //
  98. }
  99. break;
  100. }
  101. DC_END_FN();
  102. return(rc);
  103. } // DialogBoxProc
  104. //
  105. // Name: SetDialogAppIcon
  106. //
  107. // Purpose: Sets the icon for the dialog to the application icon
  108. //
  109. // Returns: Yes, it does
  110. //
  111. // Params: IN HWND the dialog for which we want to set the icon
  112. //
  113. //
  114. //
  115. void CDlgBase::SetDialogAppIcon(HWND hwndDlg)
  116. {
  117. #ifdef OS_WINCE
  118. DC_IGNORE_PARAMETER(hwndDlg);
  119. #else // !OS_WINCE
  120. HICON hIcon = NULL;
  121. hIcon = LoadIcon(_hInstance, MAKEINTRESOURCE(UI_IDI_ICON));
  122. if(hIcon)
  123. {
  124. #ifdef OS_WIN32
  125. SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)hIcon);
  126. #else //OS_WIN32
  127. SetClassWord(hwndDlg, GCW_HICON, (WORD)hIcon);
  128. #endif //OS_WIN32
  129. }
  130. #endif // OS_WINCE
  131. } // UISetDialogAppIcon
  132. //
  133. // Name: EnableDlgItem
  134. //
  135. // Purpose: Enables or disables a specified dialog control
  136. //
  137. // Returns: Nothing.
  138. //
  139. // Params:
  140. // dlgItemId - dialog control id
  141. // enabled - TRUE enables the control, FALSE disables it
  142. //
  143. //
  144. DCVOID CDlgBase::EnableDlgItem(UINT dlgItemId,
  145. BOOL enabled )
  146. {
  147. HWND hwndDlgItem = NULL;
  148. DC_BEGIN_FN("EnableDlgItem");
  149. if(_hwndDlg)
  150. {
  151. hwndDlgItem = GetDlgItem(_hwndDlg, dlgItemId);
  152. }
  153. if(hwndDlgItem)
  154. {
  155. EnableWindow(hwndDlgItem, enabled);
  156. }
  157. DC_END_FN();
  158. return;
  159. }
  160. //
  161. // Name: CenterWindowOnParent
  162. //
  163. // Purpose: Center a window inside another
  164. //
  165. // Returns: None
  166. //
  167. // Params: HWND hwndCenterOn (window to center on)
  168. // xRatio - horizontal centering factor e.g 2 for (1/2)
  169. // yRatio - vertical centering factor e.g 3 for (1/3)
  170. //
  171. //
  172. //
  173. VOID CDlgBase::CenterWindow(HWND hwndCenterOn,
  174. INT xRatio,
  175. INT yRatio)
  176. {
  177. RECT childRect;
  178. RECT parentRect;
  179. INT xPos;
  180. INT yPos;
  181. LONG desktopX = GetSystemMetrics(SM_CXSCREEN);
  182. LONG desktopY = GetSystemMetrics(SM_CYSCREEN);
  183. BOOL center = TRUE;
  184. DC_BEGIN_FN("CenterWindowOnParent");
  185. TRC_ASSERT(_hwndDlg, (TB, _T("_hwndDlg is NULL...was it set in WM_INITDIALOG?\n")));
  186. if (!_hwndDlg)
  187. {
  188. TRC_ALT((TB, _T("Window doesn't exist")));
  189. DC_QUIT;
  190. }
  191. if (!xRatio)
  192. {
  193. xRatio = 2;
  194. }
  195. if (!yRatio)
  196. {
  197. yRatio = 2;
  198. }
  199. #ifndef OS_WINCE
  200. if(!hwndCenterOn)
  201. {
  202. hwndCenterOn = GetDesktopWindow();
  203. }
  204. GetWindowRect(hwndCenterOn, &parentRect);
  205. #else //OS_WINCE
  206. if(!hwndCenterOn)
  207. {
  208. //
  209. // WinCE doesn't have GetDesktopWindow()
  210. //
  211. /* CE_FIXNOTE: fix this for CE, pickup g_CEConfig
  212. but do it without the use of globals (since the control)
  213. can run multi-instance.
  214. if (g_CEConfig != CE_CONFIG_WBT)
  215. {
  216. SystemParametersInfo(SPI_GETWORKAREA, 0, (PVOID)&parentRect, 0);
  217. }
  218. else
  219. {
  220. parentRect.left = 0;
  221. parentRect.top = 0;
  222. parentRect.right = desktopX;
  223. parentRect.bottom = desktopY;
  224. }
  225. */
  226. }
  227. else
  228. {
  229. GetWindowRect(hwndCenterOn, &parentRect);
  230. }
  231. #endif//OS_WINCE
  232. GetWindowRect(_hwndDlg, &childRect);
  233. //
  234. // Calculate the top left - centered in the parent window.
  235. //
  236. xPos = ( (parentRect.right + parentRect.left) -
  237. (childRect.right - childRect.left)) / xRatio;
  238. yPos = ( (parentRect.bottom + parentRect.top) -
  239. (childRect.bottom - childRect.top)) / yRatio;
  240. //
  241. // Constrain to the desktop
  242. //
  243. if (xPos < 0)
  244. {
  245. xPos = 0;
  246. }
  247. else if (xPos > (desktopX - (childRect.right - childRect.left)))
  248. {
  249. xPos = desktopX - (childRect.right - childRect.left);
  250. }
  251. if (yPos < 0)
  252. {
  253. yPos = 0;
  254. }
  255. else if (yPos > (desktopY - (childRect.bottom - childRect.top)))
  256. {
  257. yPos = desktopY - (childRect.bottom - childRect.top);
  258. }
  259. TRC_DBG((TB, _T("Set dialog position to %u %u"), xPos, yPos));
  260. SetWindowPos(_hwndDlg,
  261. NULL,
  262. xPos, yPos,
  263. 0, 0,
  264. SWP_NOSIZE | SWP_NOACTIVATE);
  265. DC_EXIT_POINT:
  266. DC_END_FN();
  267. return;
  268. } // CenterWindowOnParent
  269. //
  270. // Retreive current dialog position
  271. //
  272. BOOL CDlgBase::GetPosition(int* pLeft, int* pTop)
  273. {
  274. if(!pLeft || !pTop)
  275. {
  276. return FALSE;
  277. }
  278. if(!_hwndDlg)
  279. {
  280. return FALSE;
  281. }
  282. WINDOWPLACEMENT wndPlc;
  283. wndPlc.length = sizeof(WINDOWPLACEMENT);
  284. if(GetWindowPlacement(_hwndDlg, &wndPlc))
  285. {
  286. *pLeft = wndPlc.rcNormalPosition.left;
  287. *pTop = wndPlc.rcNormalPosition.top;
  288. return TRUE;
  289. }
  290. return FALSE;
  291. }
  292. BOOL CDlgBase::SetPosition(int left, int top)
  293. {
  294. if(!_hwndDlg)
  295. {
  296. return FALSE;
  297. }
  298. if(!::SetWindowPos(_hwndDlg,
  299. NULL,
  300. left,
  301. top,
  302. 0,
  303. 0,
  304. SWP_NOZORDER | SWP_NOSIZE))
  305. {
  306. return FALSE;
  307. }
  308. return TRUE;
  309. }
  310. INT_PTR CALLBACK CDlgBase::StaticDialogBoxProc(HWND hwndDlg,
  311. UINT uMsg,
  312. WPARAM wParam,
  313. LPARAM lParam)
  314. {
  315. CDlgBase* pDlg = NULL;
  316. DC_BEGIN_FN("StaticDialogBoxProc");
  317. if(WM_INITDIALOG == uMsg)
  318. {
  319. //
  320. // lParam contains this pointer (passed in DialogBoxParam)
  321. //
  322. pDlg = (CDlgBase*) lParam;
  323. TRC_ASSERT(pDlg,(TB,_T("Got null instance pointer (lParam) in WM_INITDIALOG")));
  324. if(!pDlg)
  325. {
  326. return 0;
  327. }
  328. //
  329. // Store the dialog pointer in the windowclass
  330. //
  331. SetLastError(0);
  332. if(!SetWindowLongPtr( hwndDlg, GWLP_USERDATA, (LONG_PTR)pDlg))
  333. {
  334. if(GetLastError())
  335. {
  336. TRC_ERR((TB,_T("SetWindowLongPtr failed 0x%x"),
  337. GetLastError()));
  338. return 0;
  339. }
  340. }
  341. if (pDlg)
  342. {
  343. pDlg->_hwndDlg = hwndDlg;
  344. }
  345. }
  346. else
  347. {
  348. //
  349. // Need to retreive the instance pointer from the window class
  350. //
  351. pDlg = (CDlgBase*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
  352. }
  353. //
  354. // Some early messages e.g WM_SETFONT
  355. // come in before the WM_INITDIALOG those
  356. // will just be discarded because we won't have an instance
  357. // pointer yet.
  358. //
  359. if(pDlg)
  360. {
  361. return pDlg->DialogBoxProc( hwndDlg, uMsg, wParam, lParam);
  362. }
  363. DC_END_FN();
  364. return 0;
  365. }
  366. INT CDlgBase::CreateModalDialog(LPCTSTR lpTemplateName)
  367. {
  368. INT retVal;
  369. DC_BEGIN_FN("CreateModalDialog");
  370. TRC_ASSERT(lpTemplateName,(TB,_T("lpTemplateName is NULL")));
  371. //
  372. // Dialogs derived from CDlgBase use a window class with extra space
  373. // for an instance pointer...register it if it is not already registered
  374. //
  375. WNDCLASS wc;
  376. if(!GetClassInfo(_hInstance, DLG_WND_CLASSNAME, &wc))
  377. {
  378. wc.style = CS_DBLCLKS | CS_SAVEBITS | CS_BYTEALIGNWINDOW;
  379. wc.lpfnWndProc = DefDlgProc;
  380. wc.cbClsExtra = 0;
  381. wc.cbWndExtra = DLGWINDOWEXTRA + sizeof(void*);
  382. wc.hInstance = _hInstance;
  383. wc.hIcon = LoadIcon(_hInstance, MAKEINTRESOURCE(UI_IDI_ICON));
  384. wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  385. wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
  386. wc.lpszMenuName = NULL;
  387. wc.lpszClassName = DLG_WND_CLASSNAME;
  388. retVal = RegisterClass(&wc);
  389. if(!retVal)
  390. {
  391. //
  392. // It is ok if the call failed because the class already
  393. // exists (it may have been created on some other thread
  394. // after the GetClassInfo call
  395. //
  396. if(ERROR_CLASS_ALREADY_EXISTS != GetLastError())
  397. {
  398. return 0;
  399. }
  400. else
  401. {
  402. TRC_ABORT((TB,_T("Unable to register wndclass for dialog")));
  403. }
  404. }
  405. }
  406. retVal = DialogBoxParam(_hInstance, lpTemplateName, _hwndOwner,
  407. StaticDialogBoxProc, (LPARAM) this);
  408. TRC_ASSERT((retVal != 0 && retVal != -1), (TB, _T("DialogBoxParam failed\n")));
  409. //
  410. // FixFix free the wnd class
  411. //
  412. DC_END_FN();
  413. return retVal;
  414. }
  415. //
  416. // Move the dialog controls
  417. //
  418. void CDlgBase::RepositionControls(int moveDeltaX, int moveDeltaY, UINT* ctlIDs, int numID)
  419. {
  420. if(_hwndDlg)
  421. {
  422. for(int i=0; i< numID; i++)
  423. {
  424. HWND hwndCtrl = GetDlgItem(_hwndDlg, ctlIDs[i]);
  425. if( hwndCtrl)
  426. {
  427. RECT rc;
  428. GetWindowRect( hwndCtrl, &rc);
  429. MapWindowPoints( NULL, _hwndDlg, (LPPOINT)&rc, 2);
  430. OffsetRect( &rc, moveDeltaX, moveDeltaY);
  431. SetWindowPos( hwndCtrl, NULL, rc.left, rc.top, 0, 0,
  432. SWP_NOZORDER | SWP_NOSIZE);
  433. }
  434. }
  435. }
  436. }
  437. //
  438. // Shows+enable or Hide+disable controls
  439. //
  440. void CDlgBase::EnableControls(UINT* ctlIDs, int numID, BOOL bEnable)
  441. {
  442. if(_hwndDlg)
  443. {
  444. for(int i=0; i< numID; i++)
  445. {
  446. HWND hwndCtrl = GetDlgItem(_hwndDlg, ctlIDs[i]);
  447. if( hwndCtrl)
  448. {
  449. EnableWindow( hwndCtrl, bEnable);
  450. ShowWindow(hwndCtrl, bEnable ? SW_SHOW : SW_HIDE);
  451. }
  452. }
  453. }
  454. }
  455. //
  456. // DoLockDlgRes - loads and locks a dialog template
  457. // returns address of locked resource
  458. // lpszResName - name of resource
  459. //
  460. DLGTEMPLATE* CDlgBase::DoLockDlgRes(LPCTSTR lpszResName)
  461. {
  462. HRSRC hrsrc = FindResource(NULL, lpszResName, RT_DIALOG);
  463. if(!hrsrc)
  464. {
  465. return NULL;
  466. }
  467. HGLOBAL hglb = LoadResource( _hInstance, hrsrc);
  468. return (DLGTEMPLATE*) LockResource(hglb);
  469. }
  470. #endif //OS_WINCE