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.

640 lines
15 KiB

  1. //#--------------------------------------------------------------
  2. //
  3. // File: SADataEntryCtrl.cpp
  4. //
  5. // Synopsis: This file holds the implmentation of the
  6. // CSADataEntryCtrl class
  7. //
  8. // History: 12/15/2000 serdarun Created
  9. //
  10. // Copyright (C) 1999-2000 Microsoft Corporation
  11. // All rights reserved.
  12. //
  13. //#--------------------------------------------------------------
  14. #include "stdafx.h"
  15. #include "LocalUIControls.h"
  16. #include "HostName.h"
  17. #include "satrace.h"
  18. //
  19. // registry path for LCID value
  20. //
  21. const WCHAR LOCALIZATION_MANAGER_REGISTRY_PATH [] =
  22. L"SOFTWARE\\Microsoft\\ServerAppliance\\LocalizationManager\\resources";
  23. const WCHAR LANGID_VALUE [] = L"LANGID";
  24. /////////////////////////////////////////////////////////////////////////////
  25. // CSADataEntryCtrl
  26. //++--------------------------------------------------------------
  27. //
  28. // Function: get_TextValue
  29. //
  30. // Synopsis: This is the ISADataEntryCtrl interface method
  31. // through which data entry is retrieved
  32. //
  33. // Arguments: BSTR *pVal
  34. //
  35. // Returns: HRESULT - success/failure
  36. //
  37. // History: serdarun Created 12/15/2000
  38. //
  39. //----------------------------------------------------------------
  40. STDMETHODIMP CSADataEntryCtrl::get_TextValue(BSTR *pVal)
  41. {
  42. WCHAR strTextValue[SADataEntryCtrlMaxSize+1];
  43. int iFirstIndex = 0;
  44. int iSecondIndex = 0;
  45. BOOL bCopiedFirstChar = FALSE;
  46. if (pVal == NULL)
  47. {
  48. return E_POINTER;
  49. }
  50. //
  51. // trim the beginning spaces and copy until next space
  52. //
  53. while ( iFirstIndex < m_lMaxSize+1 )
  54. {
  55. if ( m_strTextValue[iFirstIndex] == ' ' )
  56. {
  57. //
  58. // this is one of the trailing spaces, stop copying
  59. //
  60. if ( bCopiedFirstChar )
  61. {
  62. break;
  63. }
  64. }
  65. else
  66. {
  67. bCopiedFirstChar = TRUE;
  68. strTextValue[iSecondIndex] = m_strTextValue[iFirstIndex];
  69. iSecondIndex++;
  70. }
  71. iFirstIndex++;
  72. }
  73. strTextValue[iSecondIndex] = 0;
  74. *pVal = SysAllocString(strTextValue);
  75. if (*pVal)
  76. {
  77. return S_OK;
  78. }
  79. return E_OUTOFMEMORY;
  80. } // end of CSADataEntryCtrl::get_TextValue method
  81. //++--------------------------------------------------------------
  82. //
  83. // Function: put_TextValue
  84. //
  85. // Synopsis: This is the ISADataEntryCtrl interface method
  86. // through which data entry is set
  87. //
  88. // Arguments: BSTR newVal
  89. //
  90. // Returns: HRESULT - success/failure
  91. //
  92. // History: serdarun Created 12/15/2000
  93. //
  94. //----------------------------------------------------------------
  95. STDMETHODIMP CSADataEntryCtrl::put_TextValue(BSTR newVal)
  96. {
  97. if (newVal == NULL)
  98. {
  99. return E_POINTER;
  100. }
  101. //
  102. // reset the focus position
  103. //
  104. m_iPositionFocus = 0;
  105. //
  106. // must have at least one character
  107. //
  108. int iLength = wcslen(newVal);
  109. if (iLength == 0)
  110. {
  111. return E_INVALIDARG;
  112. }
  113. int iIndex = 0;
  114. while ( (iIndex < m_lMaxSize ) )
  115. {
  116. if ( iIndex < iLength )
  117. {
  118. m_strTextValue[iIndex] = newVal[iIndex];
  119. }
  120. else
  121. {
  122. m_strTextValue[iIndex] = ' ';
  123. }
  124. iIndex++;
  125. }
  126. m_strTextValue[iIndex] = 0;
  127. _wcsupr(m_strTextValue);
  128. //
  129. // draw the control again
  130. //
  131. FireViewChange();
  132. return S_OK;
  133. } // end of CSADataEntryCtrl::put_TextValue method
  134. //++--------------------------------------------------------------
  135. //
  136. // Function: put_MaxSize
  137. //
  138. // Synopsis: This is the ISADataEntryCtrl interface method
  139. // through which size of the data entry is set
  140. //
  141. // Arguments: LONG lMaxSize
  142. //
  143. // Returns: HRESULT - success/failure
  144. //
  145. // History: serdarun Created 12/15/2000
  146. //
  147. //----------------------------------------------------------------
  148. STDMETHODIMP CSADataEntryCtrl::put_MaxSize(LONG lMaxSize)
  149. {
  150. if (lMaxSize <= 0)
  151. {
  152. return E_INVALIDARG;
  153. }
  154. if (lMaxSize > SADataEntryCtrlMaxSize)
  155. {
  156. m_lMaxSize = SADataEntryCtrlMaxSize;
  157. }
  158. //
  159. // reset the focus position
  160. //
  161. m_iPositionFocus = 0;
  162. m_lMaxSize = lMaxSize;
  163. //
  164. // add and remove characters from current value based on max size
  165. //
  166. int iIndex = wcslen(m_strTextValue);
  167. if (iIndex < m_lMaxSize+1)
  168. {
  169. while (iIndex < m_lMaxSize)
  170. {
  171. m_strTextValue[iIndex] = ' ';
  172. iIndex++;
  173. }
  174. m_strTextValue[iIndex] = 0;
  175. }
  176. else if (iIndex > m_lMaxSize)
  177. {
  178. while (iIndex > m_lMaxSize)
  179. {
  180. m_strTextValue[iIndex] = 0;
  181. iIndex--;
  182. }
  183. }
  184. //
  185. // draw the control again
  186. //
  187. FireViewChange();
  188. return S_OK;
  189. } // end of CSADataEntryCtrl::put_MaxSize method
  190. //++--------------------------------------------------------------
  191. //
  192. // Function: put_TextCharSet
  193. //
  194. // Synopsis: This is the ISADataEntryCtrl interface method
  195. // through which character set is set
  196. //
  197. // Arguments: BSTR newVal
  198. //
  199. // Returns: HRESULT - success/failure
  200. //
  201. // History: serdarun Created 12/15/2000
  202. //
  203. //----------------------------------------------------------------
  204. STDMETHODIMP CSADataEntryCtrl::put_TextCharSet(BSTR newVal)
  205. {
  206. if (newVal == NULL)
  207. {
  208. return E_POINTER;
  209. }
  210. m_szTextCharSet = newVal;
  211. return S_OK;
  212. } // end of CSADataEntryCtrl::put_TextCharSet method
  213. //++--------------------------------------------------------------
  214. //
  215. // Function: FinalConstruct
  216. //
  217. // Synopsis: Called just after the constructor,
  218. // creates the font
  219. //
  220. // Arguments: none
  221. //
  222. // Returns: HRESULT - success/failure
  223. //
  224. // History: serdarun Created 04/18/2001
  225. //
  226. //----------------------------------------------------------------
  227. STDMETHODIMP CSADataEntryCtrl::FinalConstruct(void)
  228. {
  229. //
  230. // set the font now
  231. //
  232. LOGFONT logfnt;
  233. ::memset (&logfnt, 0, sizeof (logfnt));
  234. logfnt.lfOutPrecision = OUT_TT_PRECIS;
  235. logfnt.lfClipPrecision = CLIP_DEFAULT_PRECIS;
  236. logfnt.lfQuality = PROOF_QUALITY;
  237. logfnt.lfPitchAndFamily = FF_SWISS | VARIABLE_PITCH;
  238. logfnt.lfHeight = 12;
  239. logfnt.lfCharSet = GetCharacterSet ();
  240. //
  241. // we chose the fontface for Japanese and let GDI
  242. // decide for the rest
  243. //
  244. if (SHIFTJIS_CHARSET == logfnt.lfCharSet)
  245. {
  246. lstrcpy(logfnt.lfFaceName, TEXT("MS UI Gothic"));
  247. }
  248. else
  249. {
  250. lstrcpy(logfnt.lfFaceName, TEXT("Arial"));
  251. }
  252. m_hFont = ::CreateFontIndirect(&logfnt);
  253. return S_OK;
  254. }
  255. //++--------------------------------------------------------------
  256. //
  257. // Function: FinalRelease
  258. //
  259. // Synopsis: Called just after the destructor,
  260. // deletes the font
  261. //
  262. // Arguments: none
  263. //
  264. // Returns: HRESULT - success/failure
  265. //
  266. // History: serdarun Created 04/18/2001
  267. //
  268. //----------------------------------------------------------------
  269. STDMETHODIMP CSADataEntryCtrl::FinalRelease(void)
  270. {
  271. if (m_hFont)
  272. {
  273. DeleteObject(m_hFont);
  274. }
  275. return S_OK;
  276. }
  277. //++--------------------------------------------------------------
  278. //
  279. // Function: GetCharacterSet
  280. //
  281. // Synopsis: This is method used to get the character set to use
  282. // for the FONTS
  283. // Arguments:
  284. //
  285. // Returns: BYTE - CharacterSet
  286. //
  287. // History: serdarun Created 04/18/2001
  288. //
  289. // Called By: FinalConstruct method
  290. //
  291. //----------------------------------------------------------------
  292. BYTE CSADataEntryCtrl::GetCharacterSet ()
  293. {
  294. HKEY hOpenKey = NULL;
  295. BYTE byCharSet = DEFAULT_CHARSET;
  296. do
  297. {
  298. DWORD dwLangId = 0;
  299. //
  300. // open the local machine registry
  301. //
  302. LONG lRetVal = ::RegOpenKeyEx (
  303. HKEY_LOCAL_MACHINE,
  304. LOCALIZATION_MANAGER_REGISTRY_PATH,
  305. NULL, //reserved
  306. KEY_QUERY_VALUE,
  307. &hOpenKey
  308. );
  309. if (ERROR_SUCCESS == lRetVal)
  310. {
  311. DWORD dwBufferSize = sizeof (dwLangId);
  312. //
  313. // get the LANGID now
  314. //
  315. lRetVal = ::RegQueryValueEx (
  316. hOpenKey,
  317. LANGID_VALUE,
  318. NULL, //reserved
  319. NULL,
  320. (LPBYTE) &dwLangId,
  321. &dwBufferSize
  322. );
  323. if (ERROR_SUCCESS == lRetVal)
  324. {
  325. SATracePrintf (
  326. "CSADataEntryCtrl got the language ID:%d",
  327. dwLangId
  328. );
  329. }
  330. else
  331. {
  332. SATraceFailure (
  333. "CSADataEntryCtrl unable to get language ID",
  334. GetLastError()
  335. );
  336. }
  337. }
  338. else
  339. {
  340. SATraceFailure (
  341. "CSADataEntryCtrl failed to open registry to get language id",
  342. GetLastError());
  343. }
  344. switch (dwLangId)
  345. {
  346. case 0x401:
  347. // Arabic
  348. byCharSet = ARABIC_CHARSET;
  349. break;
  350. case 0x404:
  351. //Chinese (Taiwan)
  352. byCharSet = CHINESEBIG5_CHARSET;
  353. break;
  354. case 0x804:
  355. //Chinese (PRC)
  356. byCharSet = GB2312_CHARSET;
  357. break;
  358. case 0x408:
  359. //Greek
  360. byCharSet = GREEK_CHARSET;
  361. break;
  362. case 0x40D:
  363. //Hebrew
  364. byCharSet = HEBREW_CHARSET;
  365. break;
  366. case 0x411:
  367. //Japanese
  368. byCharSet = SHIFTJIS_CHARSET;
  369. break;
  370. case 0x419:
  371. //Russian
  372. byCharSet = RUSSIAN_CHARSET;
  373. break;
  374. case 0x41E:
  375. //Thai
  376. byCharSet = THAI_CHARSET;
  377. break;
  378. case 0x41F:
  379. //Turkish
  380. byCharSet = TURKISH_CHARSET;
  381. break;
  382. default:
  383. byCharSet = ANSI_CHARSET;
  384. break;
  385. }
  386. }
  387. while (false);
  388. if (hOpenKey) {::RegCloseKey (hOpenKey);}
  389. SATracePrintf ("CSADataEntryCtrl using Character Set:%d", byCharSet);
  390. return (byCharSet);
  391. } // end of CSADataEntryCtrl::GetCharacterSet method
  392. //++--------------------------------------------------------------
  393. //
  394. // Function: OnDraw
  395. //
  396. // Synopsis: This is the public method of CSADataEntryCtrl
  397. // which handles paint messages
  398. //
  399. // Arguments: ATL_DRAWINFO& di
  400. //
  401. // Returns: HRESULT - success/failure
  402. //
  403. // History: serdarun Created 12/15/2000
  404. //
  405. //----------------------------------------------------------------
  406. HRESULT CSADataEntryCtrl::OnDraw(ATL_DRAWINFO& di)
  407. {
  408. HFONT hOldFont;
  409. //
  410. // select this font
  411. //
  412. if (m_hFont)
  413. {
  414. hOldFont = (HFONT) ::SelectObject(di.hdcDraw, m_hFont);
  415. }
  416. //
  417. // get the drawing rectangle
  418. //
  419. RECT& rc = *(RECT*)di.prcBounds;
  420. WCHAR strTextValue[SADataEntryCtrlMaxSize+2];
  421. int iIndex = 0;
  422. int iDestIndex = 0;
  423. int iLength = wcslen(m_strTextValue);
  424. while (iIndex < m_lMaxSize)
  425. {
  426. if (iIndex == m_iPositionFocus)
  427. {
  428. strTextValue[iDestIndex] = '&';
  429. iDestIndex++;
  430. }
  431. strTextValue[iDestIndex] = m_strTextValue[iIndex];
  432. iDestIndex++;
  433. iIndex++;
  434. }
  435. strTextValue[iDestIndex] = 0;
  436. DrawText(
  437. di.hdcDraw,
  438. strTextValue,
  439. wcslen(strTextValue),
  440. &rc,
  441. DT_VCENTER|DT_LEFT
  442. );
  443. if (m_hFont)
  444. {
  445. SelectObject(di.hdcDraw, hOldFont);
  446. }
  447. return S_OK;
  448. }// end of CSADataEntryCtrl::OnDraw method
  449. //++--------------------------------------------------------------
  450. //
  451. // Function: OnKeyDown
  452. //
  453. // Synopsis: This is the public method of CSADataEntryCtrl
  454. // to handle keydown messages
  455. //
  456. // Arguments: windows message arguments
  457. //
  458. // Returns: HRESULT - success/failure
  459. //
  460. // History: serdarun Created 12/15/2000
  461. //
  462. //----------------------------------------------------------------
  463. LRESULT CSADataEntryCtrl::OnKeyDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  464. {
  465. //
  466. // notify the container about any key press
  467. //
  468. Fire_KeyPressed();
  469. //
  470. // Enter key received, notify the container
  471. //
  472. if (wParam == VK_RETURN)
  473. {
  474. Fire_DataEntered();
  475. return 0;
  476. }
  477. //
  478. // Escape key received, notify the container
  479. //
  480. if (wParam == VK_ESCAPE)
  481. {
  482. Fire_OperationCanceled();
  483. return 0;
  484. }
  485. if (wParam == VK_RIGHT)
  486. {
  487. m_iPositionFocus++;
  488. if (m_iPositionFocus >= m_lMaxSize)
  489. {
  490. m_iPositionFocus--;
  491. }
  492. }
  493. else if (wParam == VK_LEFT)
  494. {
  495. m_iPositionFocus--;
  496. if (m_iPositionFocus < 0)
  497. {
  498. m_iPositionFocus = 0;
  499. }
  500. }
  501. else if (wParam == VK_UP)
  502. {
  503. WCHAR * pwStrCurrentValue = NULL;
  504. pwStrCurrentValue = wcschr(m_szTextCharSet, m_strTextValue[m_iPositionFocus]);
  505. if (NULL == pwStrCurrentValue)
  506. {
  507. m_strTextValue[m_iPositionFocus] = m_szTextCharSet[0];
  508. }
  509. else
  510. {
  511. pwStrCurrentValue++;
  512. if (*pwStrCurrentValue != NULL)
  513. {
  514. m_strTextValue[m_iPositionFocus] = m_szTextCharSet[pwStrCurrentValue-m_szTextCharSet];
  515. }
  516. else
  517. {
  518. m_strTextValue[m_iPositionFocus] = m_szTextCharSet[0];
  519. }
  520. }
  521. }
  522. else if (wParam == VK_DOWN)
  523. {
  524. WCHAR * pwStrCurrentValue = NULL;
  525. pwStrCurrentValue = wcschr(m_szTextCharSet, m_strTextValue[m_iPositionFocus]);
  526. if (NULL == pwStrCurrentValue)
  527. {
  528. m_strTextValue[m_iPositionFocus] = m_szTextCharSet[0];
  529. }
  530. else
  531. {
  532. if (pwStrCurrentValue == m_szTextCharSet)
  533. {
  534. m_strTextValue[m_iPositionFocus] = m_szTextCharSet[wcslen(m_szTextCharSet)-1];
  535. }
  536. else
  537. {
  538. m_strTextValue[m_iPositionFocus] = m_szTextCharSet[pwStrCurrentValue-m_szTextCharSet-1];
  539. }
  540. }
  541. }
  542. FireViewChange();
  543. return 0;
  544. }// end of CSADataEntryCtrl::OnKeyDown method