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.

501 lines
14 KiB

  1. //////////////////////////////////////////////////////////////////////
  2. //
  3. // custconDlg.cpp : Implementation file
  4. // 1998 Jun, Hiro Yamamoto
  5. //
  6. //
  7. #include "stdafx.h"
  8. #include "custcon.h"
  9. #include "custconDlg.h"
  10. #include "Registry.h"
  11. #include "AboutDlg.h"
  12. #include "KeyDef.h"
  13. #ifdef _DEBUG
  14. #define new DEBUG_NEW
  15. #undef THIS_FILE
  16. static char THIS_FILE[] = __FILE__;
  17. #endif
  18. #define IDC_CTRL_END IDC_PAUSE
  19. /////////////////////////////////////////////////////////////////////////////
  20. // CCustconDlg �_�C�A���O
  21. CCustconDlg::CCustconDlg(CWnd* pParent /*=NULL*/)
  22. : CDialog(CCustconDlg::IDD, pParent)
  23. {
  24. //{{AFX_DATA_INIT(CCustconDlg)
  25. //}}AFX_DATA_INIT
  26. m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
  27. m_cWordDelimChanging = 0;
  28. }
  29. void CCustconDlg::DoDataExchange(CDataExchange* pDX)
  30. {
  31. CDialog::DoDataExchange(pDX);
  32. //{{AFX_DATA_MAP(CCustconDlg)
  33. DDX_Control(pDX, IDC_WORD_DELIM, m_wordDelimCtrl);
  34. //}}AFX_DATA_MAP
  35. }
  36. BEGIN_MESSAGE_MAP(CCustconDlg, CDialog)
  37. //{{AFX_MSG_MAP(CCustconDlg)
  38. ON_WM_SYSCOMMAND()
  39. ON_WM_PAINT()
  40. ON_WM_QUERYDRAGICON()
  41. ON_BN_CLICKED(IDC_APPLY, OnApply)
  42. ON_BN_CLICKED(IDC_DEFAULT_VALUE, OnDefaultValue)
  43. ON_EN_CHANGE(IDC_WORD_DELIM, OnChangeWordDelim)
  44. ON_BN_CLICKED(IDC_USE_EXTENDED_EDIT_KEY, OnUseExtendedEditKey)
  45. ON_BN_CLICKED(IDC_TRIM_LEADING_ZEROS, OnTrimLeadingZeros)
  46. ON_BN_CLICKED(IDC_RESET, OnReset)
  47. //}}AFX_MSG_MAP
  48. ON_CONTROL_RANGE(CBN_SELCHANGE, IDC_A, IDC_Z, OnSelChange)
  49. END_MESSAGE_MAP()
  50. /////////////////////////////////////////////////////////////////////////////
  51. // CCustconDlg members
  52. BOOL CCustconDlg::OnInitDialog()
  53. {
  54. CDialog::OnInitDialog();
  55. // "�o�[�W��������..." ���j���[���ڂ��V�X�e�� ���j���[�֒lj����܂��B
  56. // IDM_ABOUTBOX �̓R�}���h ���j���[�͈̔͂łȂ����΂Ȃ��܂����B
  57. ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
  58. ASSERT(IDM_ABOUTBOX < 0xF000);
  59. CMenu* pSysMenu = GetSystemMenu(FALSE);
  60. if (pSysMenu != NULL)
  61. {
  62. CString strAboutMenu;
  63. strAboutMenu.LoadString(IDS_ABOUTBOX);
  64. if (!strAboutMenu.IsEmpty())
  65. {
  66. pSysMenu->AppendMenu(MF_SEPARATOR);
  67. pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
  68. }
  69. }
  70. // ���̃_�C�A���O�p�̃A�C�R�����ݒ肵�܂��B�t���[�����[�N�̓A�v���P�[�V�����̃��C��
  71. // �E�B���h�E���_�C�A���O�łȂ����͎����I�ɐݒ肵�܂����B
  72. SetIcon(m_hIcon, TRUE); // �傫���A�C�R�����ݒ�
  73. SetIcon(m_hIcon, FALSE); // �������A�C�R�����ݒ�
  74. InitContents(FALSE); // use default value
  75. ASSERT(m_wordDelimCtrl.GetSafeHwnd());
  76. m_wordDelimCtrl.LimitText(63);
  77. CWnd* wnd = GetDlgItem(IDC_WORD_DELIM);
  78. ASSERT(wnd);
  79. CFont* font = wnd->GetFont();
  80. LOGFONT lf;
  81. VERIFY( font->GetLogFont(&lf) );
  82. _tcscpy(lf.lfFaceName, _T("Courier New"));
  83. VERIFY( m_font.CreateFontIndirect(&lf) );
  84. wnd->SetFont(&m_font);
  85. return TRUE; // TRUE ���Ԃ��ƃR���g���[���ɐݒ肵���t�H�[�J�X�͎������܂����B
  86. }
  87. void CCustconDlg::OnSysCommand(UINT nID, LPARAM lParam)
  88. {
  89. if ((nID & 0xFFF0) == IDM_ABOUTBOX)
  90. {
  91. CAboutDlg dlgAbout;
  92. dlgAbout.DoModal();
  93. }
  94. else
  95. {
  96. CDialog::OnSysCommand(nID, lParam);
  97. }
  98. }
  99. // �����_�C�A���O�{�b�N�X�ɍŏ����{�^�����lj������Ȃ��΁A�A�C�R�����`�悷��
  100. // �R�[�h���ȉ��ɋL�q�����K�v�������܂��BMFC �A�v���P�[�V������ document/view
  101. // ���f�����g���Ă����̂ŁA���̏����̓t���[�����[�N�ɂ��莩���I�ɏ��������܂��B
  102. void CCustconDlg::OnPaint()
  103. {
  104. if (IsIconic())
  105. {
  106. CPaintDC dc(this); // �`���p�̃f�o�C�X �R���e�L�X�g
  107. SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
  108. // �N���C�A���g�̋��`�̈����̒���
  109. int cxIcon = GetSystemMetrics(SM_CXICON);
  110. int cyIcon = GetSystemMetrics(SM_CYICON);
  111. CRect rect;
  112. GetClientRect(&rect);
  113. int x = (rect.Width() - cxIcon + 1) / 2;
  114. int y = (rect.Height() - cyIcon + 1) / 2;
  115. // �A�C�R�����`�悵�܂��B
  116. dc.DrawIcon(x, y, m_hIcon);
  117. }
  118. else
  119. {
  120. CDialog::OnPaint();
  121. }
  122. }
  123. // �V�X�e���́A���[�U�[���ŏ����E�B���h�E���h���b�O���Ă����ԁA
  124. // �J�[�\�����\�����邽�߂ɂ������Ăяo���܂��B
  125. HCURSOR CCustconDlg::OnQueryDragIcon()
  126. {
  127. return (HCURSOR) m_hIcon;
  128. }
  129. void CCustconDlg::OnOK()
  130. {
  131. if (!Update()) {
  132. GetDlgItem(IDCANCEL)->EnableWindow();
  133. return;
  134. }
  135. CDialog::OnOK();
  136. }
  137. void CCustconDlg::OnCancel()
  138. {
  139. if (GetDlgItem(IDCANCEL)->IsWindowEnabled())
  140. CDialog::OnCancel();
  141. }
  142. enum {
  143. CMD_NOTCMDCOMMAND = 0,
  144. CMD_FILENAME_COMPLETION = 1,
  145. } CmdExeFunction;
  146. static const struct InternalKeyDef {
  147. LPCTSTR text;
  148. WORD mod;
  149. BYTE vkey;
  150. BYTE cmd; // not zero if this functionality is actually of cmd.exe.
  151. } texts[] = {
  152. { _T(" "), 0, 0, },
  153. { _T("Left"), 0, VK_LEFT, },
  154. { _T("Right"), 0, VK_RIGHT, },
  155. { _T("Up"), 0, VK_UP, },
  156. { _T("Down"), 0, VK_DOWN, },
  157. { _T("Beginning of line"), 0, VK_HOME, },
  158. { _T("End of line"), 0, VK_END, },
  159. { _T("Del char fwd"), 0, VK_DELETE, },
  160. { _T("Del char bwd"), 0, VK_BACK, },
  161. { _T("Del line"), 0, VK_ESCAPE, },
  162. { _T("Pause"), 0, VK_PAUSE, },
  163. { _T("History call"), 0, VK_F8, },
  164. { _T("Word left"), LEFT_CTRL_PRESSED, VK_LEFT, },
  165. { _T("Word right"), LEFT_CTRL_PRESSED, VK_RIGHT, },
  166. { _T("Del line bwd"), LEFT_CTRL_PRESSED, VK_HOME, },
  167. { _T("Del line fwd"), LEFT_CTRL_PRESSED, VK_END, },
  168. { _T("Del word bwd"), LEFT_CTRL_PRESSED, VK_BACK, },
  169. { _T("Del word fwd"), LEFT_CTRL_PRESSED, VK_DELETE, },
  170. { _T("Complete(*) filename"),
  171. LEFT_CTRL_PRESSED, _T('I'), CMD_FILENAME_COMPLETION, },
  172. };
  173. #define COMPLETION_TEXT_INDEX (array_size(texts) - 1)
  174. void CCustconDlg::InitContents(BOOL isDefault)
  175. {
  176. static bool is1st = true;
  177. CConRegistry reg;
  178. UINT chkByDefault = gExMode ? 1 : 0;
  179. CheckDlgButton(IDC_USE_EXTENDED_EDIT_KEY, isDefault ? chkByDefault : reg.ReadMode() != 0);
  180. CheckDlgButton(IDC_TRIM_LEADING_ZEROS, isDefault ? chkByDefault : reg.ReadTrimLeadingZeros() != 0);
  181. if (is1st) {
  182. //
  183. // Setup comobo boxes
  184. //
  185. for (UINT id = IDC_A; id <= IDC_Z; ++id) {
  186. CComboBox* combo = (CComboBox*)GetDlgItem(id);
  187. if (combo) {
  188. for (int i = 0; i < array_size(texts); ++i) {
  189. int n = combo->AddString(texts[i].text);
  190. combo->SetItemDataPtr(n, (void*)&texts[i]);
  191. }
  192. }
  193. }
  194. }
  195. const ExtKeyDef* pKeyDef = gExMode == 0 ? gaDefaultKeyDef : gaDefaultKeyDef2;
  196. ExtKeyDefBuf regKeyDef;
  197. CmdExeFunctions cmdExeFunctions = { 0x9, };
  198. if (!isDefault) {
  199. if (reg.ReadCustom(&regKeyDef))
  200. pKeyDef = regKeyDef.table;
  201. reg.ReadCmdFunctions(&cmdExeFunctions);
  202. }
  203. for (UINT i = 0; i <= 'Z' - 'A'; ++i, ++pKeyDef) {
  204. CComboBox* combo = (CComboBox*)GetDlgItem(i + IDC_A);
  205. if (combo == NULL)
  206. continue;
  207. if (cmdExeFunctions.dwFilenameCompletion == i + 1) {
  208. //
  209. // If this is filename completion key
  210. //
  211. TRACE1("i=%d matches.\n", i);
  212. VERIFY( combo->SelectString(-1, texts[COMPLETION_TEXT_INDEX].text) >= 0);
  213. }
  214. else {
  215. for (int j = 0; j < array_size(texts); ++j) {
  216. if (pKeyDef->keys[0].wVirKey == texts[j].vkey && pKeyDef->keys[0].wMod == texts[j].mod) {
  217. VERIFY( combo->SelectString(-1, texts[j].text) >= 0);
  218. }
  219. }
  220. }
  221. }
  222. static const TCHAR defaultDelim[] = _T("\\" L"+!:=/.<>[];|&");
  223. LPCTSTR p = defaultDelim;
  224. CString delimInReg;
  225. if (!isDefault) {
  226. delimInReg = reg.ReadWordDelim();
  227. if (delimInReg != CConRegistry::m_err)
  228. p = delimInReg;
  229. }
  230. ++m_cWordDelimChanging;
  231. m_wordDelimCtrl.SetWindowText(p);
  232. --m_cWordDelimChanging;
  233. is1st = false;
  234. }
  235. bool RunCmd()
  236. {
  237. STARTUPINFO startupInfo = {
  238. sizeof startupInfo,
  239. NULL, /*lpDesktop=*/NULL, /*lpTitle=*/_T("Update cmd"),
  240. 0, 0, 0, 0,
  241. /*dwXCountChars=*/10, /*dwYCountChars=*/10,
  242. /*dwFillAttribute=*/0,
  243. /*dwFlags=*/STARTF_USEFILLATTRIBUTE | STARTF_USECOUNTCHARS | STARTF_USESHOWWINDOW,
  244. /*wShowWindow=*/SW_HIDE,
  245. /*cbReserved2=*/0,
  246. };
  247. PROCESS_INFORMATION processInfo;
  248. TCHAR path[_MAX_PATH];
  249. TCHAR cmd[] = _T("cmd /c echo hello");
  250. GetSystemDirectory(path, _MAX_PATH);
  251. _tcscat(path, _T("\\cmd.exe"));
  252. if (!CreateProcess(
  253. path,
  254. cmd,
  255. NULL, NULL,
  256. FALSE,
  257. CREATE_NEW_CONSOLE | NORMAL_PRIORITY_CLASS,
  258. NULL,
  259. NULL,
  260. &startupInfo,
  261. &processInfo)) {
  262. DWORD err = GetLastError();
  263. TRACE1("error code = %d\n", err);
  264. AfxMessageBox(_T("Could not run cmd.exe"));
  265. return false;
  266. }
  267. CloseHandle(processInfo.hProcess);
  268. CloseHandle(processInfo.hThread);
  269. return true;
  270. }
  271. bool CCustconDlg::Update()
  272. {
  273. CConRegistry reg;
  274. //
  275. // To cheat the registry manager to skip the write when
  276. // values match, set the opposite value first and then
  277. // set the right one.
  278. //
  279. DWORD dwUseExKey = IsDlgButtonChecked(IDC_USE_EXTENDED_EDIT_KEY);
  280. if (!reg.WriteMode(!dwUseExKey) || !reg.WriteMode(dwUseExKey)) {
  281. return false;
  282. }
  283. if (!reg.WriteTrimLeadingZeros(IsDlgButtonChecked(IDC_TRIM_LEADING_ZEROS)))
  284. return false;
  285. //
  286. // Write custom extended keys
  287. //
  288. ExtKeyDefBuf value;
  289. memset(&value, 0, sizeof value);
  290. CmdExeFunctions cmdExeFunctions = { 0, };
  291. DWORD cmdFilenameCompletion = 0;
  292. for (int i = 0; i <= 'Z' - 'A'; ++i) {
  293. CComboBox* combo = (CComboBox*)GetDlgItem(IDC_A + i);
  294. if (combo == NULL)
  295. continue;
  296. int n = combo->GetCurSel();
  297. ASSERT(n >= 0);
  298. const InternalKeyDef* ikeydef = (const InternalKeyDef*)combo->GetItemDataPtr(n);
  299. ASSERT(ikeydef);
  300. switch (ikeydef->cmd) {
  301. case CMD_NOTCMDCOMMAND:
  302. value.table[i].keys[0].wMod = ikeydef->mod;
  303. value.table[i].keys[0].wVirKey = ikeydef->vkey;
  304. if (value.table[i].keys[0].wVirKey == VK_BACK && value.table[i].keys[0].wMod) {
  305. value.table[i].keys[0].wUnicodeChar = EXTKEY_ERASE_PREV_WORD; // for back space special !
  306. }
  307. if (value.table[i].keys[0].wVirKey) {
  308. value.table[i].keys[1].wMod = LEFT_CTRL_PRESSED;
  309. value.table[i].keys[1].wVirKey = value.table[i].keys[0].wVirKey;
  310. }
  311. break;
  312. case CMD_FILENAME_COMPLETION:
  313. cmdExeFunctions.dwFilenameCompletion = i + 1; // Ctrl + something
  314. break;
  315. }
  316. }
  317. BYTE* lpb = (BYTE*)&value.table[0];
  318. ASSERT(value.dwCheckSum == 0);
  319. for (i = 0; i < sizeof value.table; ++i) {
  320. value.dwCheckSum += lpb[i];
  321. }
  322. if (!reg.WriteCustom(&value) || !reg.WriteCmdFunctions(&cmdExeFunctions)) {
  323. return false;
  324. }
  325. CString buf;
  326. GetDlgItem(IDC_WORD_DELIM)->GetWindowText(buf);
  327. reg.WriteWordDelim(buf);
  328. EnableApply(FALSE);
  329. return RunCmd();
  330. }
  331. //
  332. // Control exclusive selection etc.
  333. //
  334. void CCustconDlg::OnSelChange(UINT id)
  335. {
  336. CComboBox* myself = (CComboBox*)GetDlgItem(id);
  337. ASSERT(myself);
  338. const InternalKeyDef* mykeydef = (const InternalKeyDef*)myself->GetItemDataPtr(myself->GetCurSel());
  339. if (mykeydef->cmd != CMD_NOTCMDCOMMAND) {
  340. for (unsigned i = 0; i <= 'Z' - 'A'; ++i) {
  341. if (IDC_A + i != id) {
  342. CComboBox* combo = (CComboBox*)GetDlgItem(IDC_A + i);
  343. if (combo == NULL)
  344. continue;
  345. int n = combo->GetCurSel();
  346. ASSERT(n >= 0);
  347. const InternalKeyDef* ikeydef = (const InternalKeyDef*)combo->GetItemDataPtr(n);
  348. ASSERT(ikeydef);
  349. switch (ikeydef->cmd) {
  350. case CMD_NOTCMDCOMMAND:
  351. break;
  352. default:
  353. if (ikeydef->cmd == mykeydef->cmd) {
  354. //
  355. // Cmd function is exclusive.
  356. //
  357. combo->SetCurSel(0);
  358. }
  359. break;
  360. }
  361. }
  362. }
  363. }
  364. EnableApply();
  365. }
  366. //
  367. // Enable or disable Apply button, if it's not yet.
  368. //
  369. void CCustconDlg::EnableApply(BOOL fEnable)
  370. {
  371. CWnd* apply = GetDlgItem(IDC_APPLY);
  372. ASSERT(apply);
  373. if (apply->IsWindowEnabled() != fEnable)
  374. apply->EnableWindow(fEnable);
  375. }
  376. //
  377. // "Apply" button hanlder.
  378. //
  379. // Firstly check and write the registry entry,
  380. // then invoke dummy console window to let console know
  381. // the change and let it update itself.
  382. //
  383. void CCustconDlg::OnApply()
  384. {
  385. if (!Update())
  386. return;
  387. CWnd* wnd = GetDlgItem(IDCANCEL);
  388. ASSERT(wnd);
  389. wnd->EnableWindow(FALSE);
  390. CButton* ok = (CButton*)GetDlgItem(IDOK);
  391. ASSERT(ok);
  392. ok->SetWindowText(_T("Cl&ose"));
  393. }
  394. void CCustconDlg::OnDefaultValue()
  395. {
  396. InitContents(TRUE);
  397. EnableApply();
  398. }
  399. //
  400. // If user changes the setttings, enable "Apply" button
  401. //
  402. void CCustconDlg::OnChangeWordDelim()
  403. {
  404. if (!m_cWordDelimChanging)
  405. EnableApply();
  406. }
  407. void CCustconDlg::OnUseExtendedEditKey()
  408. {
  409. EnableApply();
  410. }
  411. void CCustconDlg::OnTrimLeadingZeros()
  412. {
  413. EnableApply();
  414. }
  415. void CCustconDlg::OnReset()
  416. {
  417. for (UINT id = IDC_A; id <= IDC_Z; ++id) {
  418. CComboBox* combo = (CComboBox*)GetDlgItem(id);
  419. if (combo) {
  420. combo->SetCurSel(0);
  421. }
  422. }
  423. GetDlgItem(IDC_WORD_DELIM)->SetWindowText(_T(""));
  424. CheckDlgButton(IDC_USE_EXTENDED_EDIT_KEY, 0);
  425. CheckDlgButton(IDC_TRIM_LEADING_ZEROS, 0);
  426. }