Source code of Windows XP (NT5)
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.

499 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. GetSystemDirectory(path, _MAX_PATH);
  250. _tcscat(path, _T("\\cmd.exe"));
  251. if (!CreateProcess(
  252. path, _T("cmd /c echo hello"),
  253. NULL, NULL,
  254. FALSE,
  255. CREATE_NEW_CONSOLE | NORMAL_PRIORITY_CLASS,
  256. NULL,
  257. NULL,
  258. &startupInfo,
  259. &processInfo)) {
  260. DWORD err = GetLastError();
  261. TRACE1("error code = %d\n", err);
  262. AfxMessageBox(_T("Could not run cmd.exe"));
  263. return false;
  264. }
  265. CloseHandle(processInfo.hProcess);
  266. CloseHandle(processInfo.hThread);
  267. return true;
  268. }
  269. bool CCustconDlg::Update()
  270. {
  271. CConRegistry reg;
  272. //
  273. // To cheat the registry manager to skip the write when
  274. // values match, set the opposite value first and then
  275. // set the right one.
  276. //
  277. DWORD dwUseExKey = IsDlgButtonChecked(IDC_USE_EXTENDED_EDIT_KEY);
  278. if (!reg.WriteMode(!dwUseExKey) || !reg.WriteMode(dwUseExKey)) {
  279. return false;
  280. }
  281. if (!reg.WriteTrimLeadingZeros(IsDlgButtonChecked(IDC_TRIM_LEADING_ZEROS)))
  282. return false;
  283. //
  284. // Write custom extended keys
  285. //
  286. ExtKeyDefBuf value;
  287. memset(&value, 0, sizeof value);
  288. CmdExeFunctions cmdExeFunctions = { 0, };
  289. DWORD cmdFilenameCompletion = 0;
  290. for (int i = 0; i <= 'Z' - 'A'; ++i) {
  291. CComboBox* combo = (CComboBox*)GetDlgItem(IDC_A + i);
  292. if (combo == NULL)
  293. continue;
  294. int n = combo->GetCurSel();
  295. ASSERT(n >= 0);
  296. const InternalKeyDef* ikeydef = (const InternalKeyDef*)combo->GetItemDataPtr(n);
  297. ASSERT(ikeydef);
  298. switch (ikeydef->cmd) {
  299. case CMD_NOTCMDCOMMAND:
  300. value.table[i].keys[0].wMod = ikeydef->mod;
  301. value.table[i].keys[0].wVirKey = ikeydef->vkey;
  302. if (value.table[i].keys[0].wVirKey == VK_BACK && value.table[i].keys[0].wMod) {
  303. value.table[i].keys[0].wUnicodeChar = EXTKEY_ERASE_PREV_WORD; // for back space special !
  304. }
  305. if (value.table[i].keys[0].wVirKey) {
  306. value.table[i].keys[1].wMod = LEFT_CTRL_PRESSED;
  307. value.table[i].keys[1].wVirKey = value.table[i].keys[0].wVirKey;
  308. }
  309. break;
  310. case CMD_FILENAME_COMPLETION:
  311. cmdExeFunctions.dwFilenameCompletion = i + 1; // Ctrl + something
  312. break;
  313. }
  314. }
  315. BYTE* lpb = (BYTE*)&value.table[0];
  316. ASSERT(value.dwCheckSum == 0);
  317. for (i = 0; i < sizeof value.table; ++i) {
  318. value.dwCheckSum += lpb[i];
  319. }
  320. if (!reg.WriteCustom(&value) || !reg.WriteCmdFunctions(&cmdExeFunctions)) {
  321. return false;
  322. }
  323. CString buf;
  324. GetDlgItem(IDC_WORD_DELIM)->GetWindowText(buf);
  325. reg.WriteWordDelim(buf);
  326. EnableApply(FALSE);
  327. return RunCmd();
  328. }
  329. //
  330. // Control exclusive selection etc.
  331. //
  332. void CCustconDlg::OnSelChange(UINT id)
  333. {
  334. CComboBox* myself = (CComboBox*)GetDlgItem(id);
  335. ASSERT(myself);
  336. const InternalKeyDef* mykeydef = (const InternalKeyDef*)myself->GetItemDataPtr(myself->GetCurSel());
  337. if (mykeydef->cmd != CMD_NOTCMDCOMMAND) {
  338. for (unsigned i = 0; i <= 'Z' - 'A'; ++i) {
  339. if (IDC_A + i != id) {
  340. CComboBox* combo = (CComboBox*)GetDlgItem(IDC_A + i);
  341. if (combo == NULL)
  342. continue;
  343. int n = combo->GetCurSel();
  344. ASSERT(n >= 0);
  345. const InternalKeyDef* ikeydef = (const InternalKeyDef*)combo->GetItemDataPtr(n);
  346. ASSERT(ikeydef);
  347. switch (ikeydef->cmd) {
  348. case CMD_NOTCMDCOMMAND:
  349. break;
  350. default:
  351. if (ikeydef->cmd == mykeydef->cmd) {
  352. //
  353. // Cmd function is exclusive.
  354. //
  355. combo->SetCurSel(0);
  356. }
  357. break;
  358. }
  359. }
  360. }
  361. }
  362. EnableApply();
  363. }
  364. //
  365. // Enable or disable Apply button, if it's not yet.
  366. //
  367. void CCustconDlg::EnableApply(BOOL fEnable)
  368. {
  369. CWnd* apply = GetDlgItem(IDC_APPLY);
  370. ASSERT(apply);
  371. if (apply->IsWindowEnabled() != fEnable)
  372. apply->EnableWindow(fEnable);
  373. }
  374. //
  375. // "Apply" button hanlder.
  376. //
  377. // Firstly check and write the registry entry,
  378. // then invoke dummy console window to let console know
  379. // the change and let it update itself.
  380. //
  381. void CCustconDlg::OnApply()
  382. {
  383. if (!Update())
  384. return;
  385. CWnd* wnd = GetDlgItem(IDCANCEL);
  386. ASSERT(wnd);
  387. wnd->EnableWindow(FALSE);
  388. CButton* ok = (CButton*)GetDlgItem(IDOK);
  389. ASSERT(ok);
  390. ok->SetWindowText(_T("Cl&ose"));
  391. }
  392. void CCustconDlg::OnDefaultValue()
  393. {
  394. InitContents(TRUE);
  395. EnableApply();
  396. }
  397. //
  398. // If user changes the setttings, enable "Apply" button
  399. //
  400. void CCustconDlg::OnChangeWordDelim()
  401. {
  402. if (!m_cWordDelimChanging)
  403. EnableApply();
  404. }
  405. void CCustconDlg::OnUseExtendedEditKey()
  406. {
  407. EnableApply();
  408. }
  409. void CCustconDlg::OnTrimLeadingZeros()
  410. {
  411. EnableApply();
  412. }
  413. void CCustconDlg::OnReset()
  414. {
  415. for (UINT id = IDC_A; id <= IDC_Z; ++id) {
  416. CComboBox* combo = (CComboBox*)GetDlgItem(id);
  417. if (combo) {
  418. combo->SetCurSel(0);
  419. }
  420. }
  421. GetDlgItem(IDC_WORD_DELIM)->SetWindowText(_T(""));
  422. CheckDlgButton(IDC_USE_EXTENDED_EDIT_KEY, 0);
  423. CheckDlgButton(IDC_TRIM_LEADING_ZEROS, 0);
  424. }