XTBrowseEdit.cpp
上传用户:szled88
上传日期:2015-04-09
资源大小:43957k
文件大小:15k
源码类别:

对话框与窗口

开发平台:

Visual C++

  1. // XTBrowseEdit.cpp : implementation of the CXTBrowseEdit class.
  2. //
  3. // This file is a part of the XTREME CONTROLS MFC class library.
  4. // (c)1998-2008 Codejock Software, All Rights Reserved.
  5. //
  6. // THIS SOURCE FILE IS THE PROPERTY OF CODEJOCK SOFTWARE AND IS NOT TO BE
  7. // RE-DISTRIBUTED BY ANY MEANS WHATSOEVER WITHOUT THE EXPRESSED WRITTEN
  8. // CONSENT OF CODEJOCK SOFTWARE.
  9. //
  10. // THIS SOURCE CODE CAN ONLY BE USED UNDER THE TERMS AND CONDITIONS OUTLINED
  11. // IN THE XTREME TOOLKIT PRO LICENSE AGREEMENT. CODEJOCK SOFTWARE GRANTS TO
  12. // YOU (ONE SOFTWARE DEVELOPER) THE LIMITED RIGHT TO USE THIS SOFTWARE ON A
  13. // SINGLE COMPUTER.
  14. //
  15. // CONTACT INFORMATION:
  16. // support@codejock.com
  17. // http://www.codejock.com
  18. //
  19. /////////////////////////////////////////////////////////////////////////////
  20. #include "stdafx.h"
  21. #include "Resource.h"
  22. #include "Common/XTPVC80Helpers.h"  // Visual Studio 2005 helper functions
  23. #include "Common/XTPResourceManager.h"
  24. #include "Common/XTPDrawHelpers.h"
  25. #include "Common/XTPWinThemeWrapper.h"
  26. #include "Common/XTPSystemHelpers.h"
  27. #include "XTFunctions.h"
  28. #include "XTDefines.h"
  29. #include "XTUtil.h"
  30. #include "XTGlobal.h"
  31. #include "XTButton.h"
  32. #include "XTButtonTheme.h"
  33. #include "XTFlatComboBox.h"
  34. #include "XTBrowseEdit.h"
  35. #include "XTBrowseDialog.h"
  36. #ifdef _DEBUG
  37. #define new DEBUG_NEW
  38. #undef THIS_FILE
  39. static char THIS_FILE[] = __FILE__;
  40. #endif
  41. const int CX_BUTTON = (::GetSystemMetrics(SM_CXHTHUMB) +
  42. (::GetSystemMetrics(SM_CXEDGE) * 2));
  43. /////////////////////////////////////////////////////////////////////////////
  44. // CXTBrowseButton class
  45. /////////////////////////////////////////////////////////////////////////////
  46. CXTBrowseButton::CXTBrowseButton()
  47. {
  48. m_nBorderGap = 0;
  49. m_nImageGap = 0;
  50. m_dwBStyle = 0;
  51. m_pEditWnd = NULL;
  52. m_dwxStyle = BS_XT_SHOWFOCUS | BS_XT_WINXP_COMPAT;
  53. m_nID = 0;
  54. m_nMenu = 0;
  55. m_nSubMenuIndx = 0;
  56. SetTheme(new CXTDisabledButtonTheme);
  57. }
  58. CXTBrowseButton::~CXTBrowseButton()
  59. {
  60. }
  61. IMPLEMENT_DYNAMIC(CXTBrowseButton, CXTButton)
  62. BEGIN_MESSAGE_MAP(CXTBrowseButton, CXTButton)
  63. //{{AFX_MSG_MAP(CXTBrowseButton)
  64. ON_WM_ENABLE()
  65. ON_CONTROL_REFLECT(BN_CLICKED, OnBtnClicked)
  66. //}}AFX_MSG_MAP
  67. END_MESSAGE_MAP()
  68. BOOL CXTBrowseButton::Create(CXTBrowseEdit* pEditWnd, DWORD dwBStyle, UINT nID, UINT nMenu/*= -1*/, UINT nSubMenuIndx/*= -1*/)
  69. {
  70. ASSERT_VALID(pEditWnd);              // Must be valid
  71. ASSERT_VALID(pEditWnd->GetParent());
  72. // Set the pointers to the edit and edit parent windows.
  73. m_pEditWnd = pEditWnd;
  74. // Set the browse style and menu resource
  75. // ID information (if any).
  76. m_dwBStyle = dwBStyle;
  77. m_nMenu = nMenu;
  78. m_nSubMenuIndx = nSubMenuIndx;
  79. CString strButtonText;
  80. DWORD dwStyle = (m_pEditWnd->GetStyle() & WS_VISIBLE) |
  81. WS_CHILD | WS_TABSTOP | BS_CENTER | BS_VCENTER | BS_OWNERDRAW;
  82. if ((m_dwBStyle & BES_XT_POPUPMENU) == 0)
  83. {
  84. VERIFY(XTPResourceManager()->LoadString(&strButtonText, XT_IDS_DOT));
  85. }
  86. else
  87. {
  88. CImageList imageList;
  89. imageList.Create(11, 11, ILC_COLOR8 | ILC_MASK, 0, 1);
  90. CBitmap bmp;
  91. VERIFY(XTPResourceManager()->LoadBitmap(&bmp, XT_IDB_SCROLL_ARW));
  92. imageList.Add(&bmp, RGB(0xff, 0x00, 0xff));
  93. if (imageList.GetImageCount() == 8)
  94. {
  95. // extract the right arrow icon from the image list.
  96. m_hPopupIcon = imageList.ExtractIcon(4);
  97. ASSERT(m_hPopupIcon != NULL);
  98. // add the BS_ICON style to create flags.
  99. dwStyle |= BS_ICON;
  100. }
  101. }
  102. if (!CXTButton::Create(strButtonText, dwStyle, CRect(0, 0, 0, 0),
  103. m_pEditWnd->GetParent(), nID))
  104. {
  105. TRACE0("Failed to create browse edit button.n");
  106. return FALSE;
  107. }
  108. // Set the font for this control.
  109. if (!strButtonText.IsEmpty())
  110. SetFont(&XTAuxData().font);
  111. // set the arrow icon that is displayed on the button.
  112. if (NULL != (HICON)m_hPopupIcon)
  113. SetIcon(CSize(10, 10), m_hPopupIcon);
  114. // Enable the button using the parent's enabled state.
  115. EnableWindow(m_pEditWnd->IsWindowEnabled());
  116. return TRUE;
  117. }
  118. void CXTBrowseButton::SetBrowseStyle(DWORD dwxStyle)
  119. {
  120. m_dwBStyle = dwxStyle;
  121. if ((m_dwBStyle & BES_XT_POPUPMENU) == 0)
  122. {
  123. CString strButtonText;
  124. VERIFY(XTPResourceManager()->LoadString(&strButtonText, XT_IDS_DOT));
  125. SetWindowText(strButtonText);
  126. }
  127. else
  128. {
  129. CImageList imageList;
  130. imageList.Create(11, 11, ILC_COLOR8 | ILC_MASK, 0, 1);
  131. CBitmap bmp;
  132. VERIFY(XTPResourceManager()->LoadBitmap(&bmp, XT_IDB_SCROLL_ARW));
  133. imageList.Add(&bmp, RGB(0xff, 0x00, 0xff));
  134. if (imageList.GetImageCount() == 8)
  135. {
  136. // extract the right arrow icon from the image list.
  137. m_hPopupIcon = imageList.ExtractIcon(4);
  138. ASSERT(m_hPopupIcon != NULL);
  139. // add the BS_ICON style to create flags.
  140. ModifyStyle(0, BS_ICON);
  141. // set the arrow icon that is displayed on the button.
  142. if (NULL != (HICON)m_hPopupIcon)
  143. SetIcon(CSize(10, 10), m_hPopupIcon);
  144. }
  145. }
  146. }
  147. BOOL CXTBrowseButton::PreTranslateMessage(MSG* pMsg)
  148. {
  149. // activate if space or enter key pressed...
  150. if (pMsg->message == WM_KEYDOWN &&
  151. (pMsg->wParam == VK_RETURN || pMsg->wParam == VK_SPACE))
  152. {
  153. OnClicked();
  154. return TRUE; // eat message...
  155. }
  156. return CXTButton::PreTranslateMessage(pMsg);
  157. }
  158. void CXTBrowseButton::OnBtnClicked()
  159. {
  160. OnClicked();
  161. }
  162. void CXTBrowseButton::OnClicked()
  163. {
  164. if (m_pEditWnd)
  165. {
  166. m_pEditWnd->OnBrowse();
  167. }
  168. }
  169. void CXTBrowseButton::OnEnable(BOOL bEnable)
  170. {
  171. CXTButton::OnEnable(bEnable);
  172. Invalidate();
  173. }
  174. /////////////////////////////////////////////////////////////////////////////
  175. // CXTBrowseEdit class
  176. /////////////////////////////////////////////////////////////////////////////
  177. CXTBrowseEdit::CXTBrowseEdit()
  178. {
  179. m_nGap = ::GetSystemMetrics(SM_CXEDGE);
  180. m_dwBStyle = BES_XT_CHOOSEDIR;
  181. m_nMenu = 0;
  182. m_nSubMenuIndx = 0;
  183. m_strFileName = _T("");
  184. m_dwFlags = OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_EXPLORER;
  185. m_pParentWnd = NULL;
  186. m_pFileDialog = NULL;
  187. m_bOpenFileDialog = TRUE;
  188. m_bBrowsing = false;
  189. VERIFY(XTPResourceManager()->LoadString(&m_strDefExt, XT_IDS_DEFEXT));
  190. VERIFY(XTPResourceManager()->LoadString(&m_strFilter, XT_IDS_DEFFILT));
  191. VERIFY(XTPResourceManager()->LoadString(&m_strTitle, XT_IDS_DEFTITLE));
  192. }
  193. CXTBrowseEdit::~CXTBrowseEdit()
  194. {
  195. }
  196. IMPLEMENT_DYNAMIC(CXTBrowseEdit, CXTEdit)
  197. BEGIN_MESSAGE_MAP(CXTBrowseEdit, CXTEdit)
  198. //{{AFX_MSG_MAP(CXTBrowseEdit)
  199. ON_WM_ENABLE()
  200. ON_WM_SHOWWINDOW()
  201. ON_WM_WINDOWPOSCHANGED()
  202. //}}AFX_MSG_MAP
  203. END_MESSAGE_MAP()
  204. void CXTBrowseEdit::OnEnable(BOOL bEnable)
  205. {
  206. CXTEdit::OnEnable(bEnable);
  207. if (::IsWindow(m_btnBrowse.GetSafeHwnd()))
  208. m_btnBrowse.EnableWindow(bEnable);
  209. Invalidate();
  210. }
  211. void CXTBrowseEdit::OnShowWindow(BOOL bShow, UINT nStatus)
  212. {
  213. CXTEdit::OnShowWindow(bShow, nStatus);
  214. if (::IsWindow(m_btnBrowse.GetSafeHwnd()))
  215. m_btnBrowse.ShowWindow(bShow ? SW_SHOW : SW_HIDE);
  216. }
  217. bool CXTBrowseEdit::Initialize(CWnd* pParentWnd, DWORD dwBStyle, UINT nMenu/*= 0*/, int nSubMenuIndx/*= 0*/)
  218. {
  219. if (!CXTEdit::Initialize(pParentWnd))
  220. return false;
  221. // only create a browse button if one was specified.
  222. if (m_dwBStyle & (BES_XT_CHOOSEDIR | BES_XT_CHOOSEFILE | BES_XT_POPUPMENU | BES_XT_BROWSE))
  223. {
  224. // set browse edit style and menu indexes.
  225. m_dwBStyle = dwBStyle;
  226. m_nMenu = nMenu;
  227. m_nSubMenuIndx = nSubMenuIndx;
  228. // Create the browse button associated with the browse edit control.
  229. if (!m_btnBrowse.Create(this, m_dwBStyle, XT_IDC_BTN_BROWSE,
  230. m_nMenu, m_nSubMenuIndx))
  231. {
  232. TRACE1("Error creating browse button for ID %d.n", GetDlgCtrlID());
  233. return false;
  234. }
  235. CXTPWindowRect rcWindow(this);
  236. rcWindow.right -= CX_BUTTON + m_nGap;
  237. ASSERT_VALID(m_pParentWnd); // must be valid.
  238. m_pParentWnd->ScreenToClient(&rcWindow);
  239. // set the window position to accommodate for the browse button.
  240. ::SetWindowPos(m_hWnd, NULL, rcWindow.left, rcWindow.top,
  241. rcWindow.Width(), rcWindow.Height(), SWP_FRAMECHANGED | SWP_NOZORDER);
  242. // position browse button.
  243. PositionBrowseButton();
  244. }
  245. return true;
  246. }
  247. void CXTBrowseEdit::PositionBrowseButton()
  248. {
  249. if (::IsWindow(m_btnBrowse.GetSafeHwnd()))
  250. {
  251. CXTPWindowRect rcWindow(this);
  252. // construct the size of the browse button.
  253. CRect rcButton;
  254. rcButton.left = rcWindow.right + m_nGap;
  255. rcButton.right = rcButton.left + CX_BUTTON;
  256. rcButton.top = rcWindow.top;
  257. rcButton.bottom = rcWindow.top + rcWindow.Height();
  258. ASSERT_VALID(m_pParentWnd); // must be valid.
  259. m_pParentWnd->ScreenToClient(&rcButton);
  260. // set the window position and make sure tab order is correct.
  261. ::SetWindowPos(m_btnBrowse.m_hWnd, m_hWnd,
  262. rcButton.left, rcButton.top, rcButton.Width(), rcButton.Height(), SWP_FRAMECHANGED);
  263. // construct the area to be updated on the parent.
  264. CRect rcRedraw = rcWindow;
  265. rcRedraw.right = rcButton.right;
  266. // refresh parent window.
  267. m_pParentWnd->InvalidateRect(&rcRedraw);
  268. }
  269. }
  270. void CXTBrowseEdit::OnWindowPosChanged(WINDOWPOS FAR* lpwndpos)
  271. {
  272. CXTEdit::OnWindowPosChanged(lpwndpos);
  273. // position browse button.
  274. PositionBrowseButton();
  275. }
  276. void CXTBrowseEdit::ChooseDirectory()
  277. {
  278. m_bBrowsing = true;
  279. // Get the current (if any) text that is displayed in
  280. // the edit control, this will be the initial path for the
  281. // browse dialog to start from.
  282. CString strPath;
  283. GetWindowText(strPath);
  284. if (!DIRECTORYEXISTS_S(strPath) && !m_strInitialDir.IsEmpty())
  285. strPath = m_strInitialDir;
  286. // Instantiate a browse for folder dialog object
  287. CXTBrowseDialog browseDlg;
  288. browseDlg.SetOwner(GetParent()->GetSafeHwnd());
  289. browseDlg.SetTitle((TCHAR*)(LPCTSTR)m_strTitle);
  290. browseDlg.SetSelPath((TCHAR*)(LPCTSTR)strPath);
  291. if (browseDlg.DoModal() == IDOK)
  292. {
  293. SetWindowText(browseDlg.GetSelPath());
  294. }
  295. m_bBrowsing = false;
  296. }
  297. void CXTBrowseEdit::ChooseFile()
  298. {
  299. m_bBrowsing = true;
  300. if (m_pFileDialog)
  301. {
  302. if (m_pFileDialog->DoModal() == IDOK)
  303. SetWindowText(m_pFileDialog->GetPathName());
  304. }
  305. else
  306. {
  307. CFileDialog dlg(m_bOpenFileDialog, m_strDefExt, m_strFileName,
  308. m_dwFlags, m_strFilter, m_pParentWnd);
  309. if (!m_strInitialDir.IsEmpty())
  310. {
  311. dlg.m_ofn.lpstrInitialDir = (LPCTSTR)m_strInitialDir;
  312. }
  313. // Check to see if this is Windows 2000 or later, if so use the
  314. // Windows 2000 version of OPENFILENAME.
  315. if (sizeof(OPENFILENAME) < 88) if (XTOSVersionInfo()->IsWin2KOrGreater() && dlg.m_ofn.lStructSize < 88)
  316. {
  317. // Windows 2000 version of OPENFILENAME has three extra members,
  318. // this was copied from newer version of commdlg.h...
  319. struct OPENFILENAMEEX
  320. {
  321. void*  pvReserved; // 4 bytes
  322. DWORD  dwReserved; // 4 bytes
  323. DWORD  FlagsEx;    // 4 bytes
  324. };
  325. dlg.m_ofn.lStructSize += sizeof(OPENFILENAMEEX); // should equal an additional 12 bytes;
  326. }
  327. if (dlg.DoModal() == IDOK)
  328. {
  329. SetWindowText(dlg.GetPathName());
  330. }
  331. }
  332. m_bBrowsing = false;
  333. }
  334. void CXTBrowseEdit::PopupMenu()
  335. {
  336. if (m_bBrowsing)
  337. return;
  338. m_bBrowsing = true;
  339. ASSERT(m_nMenu != 0);
  340. if (::IsWindow(m_btnBrowse.GetSafeHwnd()))
  341. m_btnBrowse.SetState(TRUE);
  342. CRect rect;
  343. m_btnBrowse.GetWindowRect(&rect);
  344. // loading a user resource.
  345. CMenu menu;
  346. VERIFY(XTPResourceManager()->LoadMenu(&menu, m_nMenu));
  347. CMenu* pPopup = menu.GetSubMenu(m_nSubMenuIndx);
  348. ASSERT(pPopup != NULL);
  349. CWnd* pWndPopupOwner = this;
  350. while (pWndPopupOwner->GetStyle() & WS_CHILD)
  351. {
  352. pWndPopupOwner = pWndPopupOwner->GetParent();
  353. }
  354. XTFuncContextMenu(pPopup, TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_VERTICAL,
  355. rect.right, rect.top, pWndPopupOwner, 0);
  356. // Return the button state to normal.
  357. if (::IsWindow(m_btnBrowse.GetSafeHwnd()))
  358. m_btnBrowse.SetState(FALSE);
  359. m_bBrowsing = false;
  360. }
  361. void CXTBrowseEdit::OnBrowse()
  362. {
  363. // If this is a browse directory control.
  364. switch (m_dwBStyle & (BES_XT_CHOOSEDIR | BES_XT_CHOOSEFILE | BES_XT_POPUPMENU | BES_XT_BROWSE))
  365. {
  366. case BES_XT_CHOOSEDIR:
  367. ChooseDirectory();
  368. break;
  369. case BES_XT_CHOOSEFILE:
  370. ChooseFile();
  371. break;
  372. case BES_XT_POPUPMENU:
  373. PopupMenu();
  374. break;
  375. case BES_XT_BROWSE:
  376. GetParent()->SendMessage( WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(), LBN_XT_ONBROWSE), (LPARAM)m_hWnd );
  377. break;
  378. }
  379. if (::GetFocus() != m_hWnd)
  380. {
  381. SetSel(0, -1);
  382. SetFocus();
  383. }
  384. }
  385. /////////////////////////////////////////////////////////////////////////////
  386. // CXTItemEdit class
  387. /////////////////////////////////////////////////////////////////////////////
  388. CXTItemEdit::CXTItemEdit(CWnd* pParent, const CRect& rect, CString& strWindowText, DWORD dwBStyle/*= BES_XT_CHOOSEDIR*/, bool bAutoDelete/*= true*/)
  389. : m_strWindowText(strWindowText)
  390. , m_bClosePosted(false)
  391. , m_bModified(false)
  392. , m_bAutoDelete(bAutoDelete)
  393. , m_bEscapeKey(false)
  394. {
  395. // Initialize defaults
  396. m_nGap = 0;
  397. m_dwBStyle = dwBStyle;
  398. m_pParentWnd = pParent;
  399. // Create the edit control.
  400. if (!Create(WS_BORDER | WS_CHILD | WS_VISIBLE | ES_AUTOHSCROLL,
  401. rect, pParent, XT_IDC_LBOX_EDIT))
  402. return;
  403. // Initialize the edit control.
  404. if (!Initialize(pParent, dwBStyle))
  405. return;
  406. // Set the window text and select it.
  407. SetWindowText(m_strWindowText);
  408. SetSel(0, -1);
  409. SetFocus();
  410. }
  411. CXTItemEdit::~CXTItemEdit()
  412. {
  413. }
  414. IMPLEMENT_DYNAMIC(CXTItemEdit, CXTBrowseEdit)
  415. BEGIN_MESSAGE_MAP(CXTItemEdit, CXTBrowseEdit)
  416. //{{AFX_MSG_MAP(CXTItemEdit)
  417. ON_WM_KILLFOCUS()
  418. ON_WM_CHAR()
  419. //}}AFX_MSG_MAP
  420. END_MESSAGE_MAP()
  421. void CXTItemEdit::OnKillFocus(CWnd* pNewWnd)
  422. {
  423. CXTBrowseEdit::OnKillFocus(pNewWnd);
  424. if (!::IsWindow(m_btnBrowse.GetSafeHwnd()) || pNewWnd != &m_btnBrowse)
  425. {
  426. ASSERT_VALID(this);
  427. EndLabelEdit();
  428. }
  429. }
  430. void CXTItemEdit::PostNcDestroy()
  431. {
  432. if (m_bAutoDelete)
  433. {
  434. delete this;
  435. }
  436. }
  437. BOOL CXTItemEdit::PreTranslateMessage(MSG* pMsg)
  438. {
  439. if (pMsg->message == WM_KEYDOWN || pMsg->message == WM_KEYUP)
  440. {
  441. if ((pMsg->wParam == VK_RETURN) ||
  442. (pMsg->wParam == VK_ESCAPE))
  443. {
  444. if (pMsg->wParam == VK_ESCAPE)
  445. {
  446. m_bEscapeKey = true;
  447. }
  448. EndLabelEdit();
  449. return TRUE;
  450. }
  451. }
  452. return CXTBrowseEdit::PreTranslateMessage(pMsg);
  453. }
  454. void CXTItemEdit::EndLabelEdit()
  455. {
  456. if (m_bClosePosted) return;
  457. if (::IsWindow(m_btnBrowse.GetSafeHwnd()))
  458. m_btnBrowse.PostMessage(WM_CLOSE);
  459. if (::IsWindow(GetSafeHwnd()))
  460. PostMessage(WM_CLOSE);
  461. m_bClosePosted = true;
  462. if (m_bModified == false)
  463. {
  464. CWnd* pOwner = GetOwner();
  465. ASSERT_VALID(pOwner);
  466. if (m_bEscapeKey == false)
  467. {
  468. m_bModified = true;
  469. // get the window text and pass it on to the
  470. // notification window...
  471. GetWindowText(m_strWindowText);
  472. // Notify of label edit.
  473. pOwner->SendMessage(WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(),
  474. BEN_XT_LABELEDITEND), (LPARAM)GetSafeHwnd());
  475. }
  476. else
  477. {
  478. // Notify of label edit.
  479. pOwner->SendMessage(WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(),
  480. BEN_XT_LABELEDITCANCEL), (LPARAM)GetSafeHwnd());
  481. }
  482. }
  483. }
  484. void CXTItemEdit::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
  485. {
  486. if ((nChar == VK_RETURN) ||
  487. (nChar == VK_ESCAPE))
  488. {
  489. if (nChar == VK_ESCAPE)
  490. m_bEscapeKey = TRUE;
  491. EndLabelEdit();
  492. return;
  493. }
  494. CXTBrowseEdit::OnChar(nChar, nRepCnt, nFlags);
  495. }